Accessing Google Sheets API via Service Account Key - java

I am working on Google Sheets <-> Salesforce integration and developing it in Salesforce programming language - Apex on Force.com platform.
Currently I am attempting to connect to Google Sheets API. I am using Service Account Key, so Salesforce can pull the data from Google Sheets without the requirement for manual authorisation every time it sends out a query.
I am at the point where I set up the Service Account Key and I am successfully sending a request to it to obtain the access_code.
Then I am attempting to query the API, using the following class:
/****** API CALLOUT *******/
public static HttpResponse googleSheetsCallout (){
//the below line provides a string containing access token to google
string accessCode = getAccessToken();
//I found this endpoint structure online, this may be why my script
//isn't working. However, I am struggling to find the alternative.
string endpoint = 'https://sheets.googleapis.com/v4/spreadsheets/params=[SPREADSHEET ID GOES HERE]/values/[RANGE GOES HERE]?access_token=';
httpRequest req = new httpRequest();
req.setEndpoint(endpoint+accessCode);
req.setMethod('GET');
req.setTimeout(120000);
httpResponse res = new http().send(req);
System.debug ('res is ' +res);
return res;
}
When I run the function this is what the log returns:
|CALLOUT_RESPONSE|[71]|System.HttpResponse[Status=Forbidden, StatusCode=403]
|USER_DEBUG|[72]|DEBUG|res is System.HttpResponse[Status=Forbidden, StatusCode=403]
I enabled Google Sheets access in the google developer console menu, and what's interesting is when loking at the console it appears that Google notices API requests being sent out (they are appearing on the activity chart).

I solved it, and the issue was not the code itself.
The problem was sharing my sheet. To allow read/edit access to your sheet from the service account it must be shared with the Service Account ID email address, the same way it's shared with any other user. If this isn't done the script will produce 403 error.

Related

Azure Java SDK - how to retrieve RBAC roles of an User

We have a requirement to check the Authorization permissions of an User before executing business logic. I am not able to find an example or tutorial to retrieve the Roles of an User, using Azure Java SDK.
We have Rest API by which we can retrieve all roles assigned to a subscription. Using HTTP request we can retrieve all the role assignments and then we can search for user
Code:
String api = "https://management.azure.com/subscriptions/{subscriptionId}/providers/Microsoft.Authorization/roleAssignments?api-version=2015-07-01" ;
// Here substitute the SubstriptionID
System._out_.println( "Hello World!" );
HttpClient client = HttpClient._newHttpClient_();
HttpRequest request = HttpRequest._newBuilder_()
.GET()
.uri(URI._create_(api))
.build();
HttpResponse<String> response = client.send(request , HttpResponse.BodyHandlers._ofString_());
System._out_.print(response.body());
// The following the has to parsed to find whether the user is present or not
Here are the few related Microsoft Documents for complete information.
Role Assignments - List - REST API (Azure Authorization) | Microsoft Docs
Use the Azure SDK for Java | Microsoft Docs

How is it a php programm runs in an online server

I have some php files that freely run on my online PHP,MySQL server.
As an example if it concern about addUser.php (here is that code)
<?php
if($_SERVER['REQUEST_METHOD']=='POST'){
$name = $_POST['name'];
$email = $_POST['email'];
...
$sql = "INSERT INTO users (name,email,...) VALUES ('$name','$email',...)";
require_once('DbConnect.php');
if(mysqli_query($con,$sql)){
echo 'User Added Successfully';
}else{
echo 'Could Not Add User';
}
mysqli_close($con);
}
I have coded my ANDROID Application to access this type of php file by StringRequest using URL
http://www.***.com/addUser.php
and pass the parameters using HashMaps
So, I want to know how is this php file runs when android user access it, and what will occur when thousands of android users started accessing this php file and started to insert data into my online server Database concurrently.
And if there is a problem occur what is the solution for it?
I just want to know is it a problem occur when many users try the same php file at same time?? I mean we use synchronizing in multi-threading to prevent occuring a problem when many users use the same at sametime. As in that way is there will a problem occur when thousands of users adding data through this php file
Lets assume you're going to keep using this script.
You must stop duplicate emails being inserted
Run a select * from users where email = '$email' before inserting the user. If the results.length == 0, insert the user, if not return an error.
Validate the incoming POST data
Here you should do some basic validation:
$name = $_POST['name'];
$email = $_POST['email'];
// Do some checks here which will validate the email
See the following page for a more in depth look into validating:
http://php.net/manual/en/filter.examples.validation.php
Other than that there are some floors
You should make users use a password
The password should also be hashed
SQL injection
See the following question -> How can I prevent SQL injection in PHP?
One more thing, maybe have a look at other examples. E.g
http://www.tutorialspoint.com/php/php_login_example.htm
Edit:
Seems like you want to implement a google login (based on your comment).
Here's how I'd do it:
On the client (app), the user would login to there google acc.
In return we would get there accountId and an OAUTH token
We would then send the token + OAUTH token to our PHP server.
The php server would then use a google php library to validate the OAUTH token that we retrieved from the client.
The library would then return information on that user including there google id and other relevant information that was requested.
Check to see if the user has an account by cross checking the google id returned against our database.
Select * from dbTABLENAME where googleId =
IF there was nothing returned in step 6, we would then store the googleId + other information (email) in our own database, IF THERE WAS something returned in step 6, we'd return some sort of token to the client that would be used to validate all other requests
This link will help ->
http://phppot.com/php/php-google-oauth-login/
Seems you have developed an API for your android application for inserting data. I suggest you to put an authentication layer before inserting data. Such as you can generate token using 'Hashing' or 'Salt' algorithm for your application user. If they request with that token, in your API you have to decide whether you will accept the request or reject.

Android OAuth with valid "CONSUMER_KEY" and "CONSUMER_SECRET"

I have a valid consumer_key and consumer_secret for my app to access resources on a certain website.
I create the consumer like this:
private void createConsumer(){
mConsumer = new CommonsHttpOAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET);
}
I create the provider like this:
private void createProvider(){
mProvider = new CommonsHttpOAuthProvider(REQUEST_TOKEN_URL, ACCESS_TOKEN_URL,
AUTHORIZE_URL);
}
I then use an AsyncTask to retrieve what I assume is a valid AccessToken from the server.
mAccessTokenUrl = mProvider.retrieveRequestToeken(mConsumer, CALL_BACK_URL);
with this call I get something similar to this:
``http://www.mygarden.org/oauth/authorize?/oauth_token=XXXXXXXXXXXXXXhs343sjd&oauth_callback=http%3A%2F%2Flocalhost
I'm assuming the token is correct because if I test this with the incorrect credentials I don't get anything back.
Question 1:
Is this callback url corrent, because on the site it does not specify a callback url, just the app's website; and how should I use it on the android app?
Question 2:
How do I now use the Access Token to consume certain services on the website, for example to get all the plants I should use this link: http://api.mygarden.org/activities/all which should return certain data in xml/json format
Extra information is that all calls to the API should use the http GET method unless specified otherwise. I do not want the user to first register on the site, I just want to consume the services they provide using my app's access credentials. If user credentials are necessary, could I embed them within the URL and grant the user access automatically?
The website is: http://www.mygarden.org
Thanks for your help.
To get a list of all the plants you don't need to authenticate a user. This is only necessary for user related actions, like posting status updates or adding plants to your garden.
So you only have to send a call to oauth/request_token and then oauth/access_token, after that you're ready to get some data from the API
Answer for Question 1:
If your developing an android application you don't need the callback url, this is needed when you want to authenticate a user trough a website. Make sure you select Client in the app settings on mygarden.org
Answer for Question 2:
To get all the plants you need plants/all. If you're using a standard oauth library, all the required oauth parameters are automatically added to your query
I'm a developer at mygarden.org, you can always contact our support ;)

Magento customer authentication via API

I am using Magento with a 3rd party Java Web Application.
My application is "connected" to Magento via Magento SOAP API V2.
How can I perform a Customer Authentication from my Java aplication (outside of Magento) via api?
Any help would be appreciated.
I came up to a solution on how to login a customer via SOAP API and I will post it here so it can be helpful for others.Here is what I did to make it work:
I created a custom module in Magento with a custom method that login a customer and retuns the sessionID that is set on server side.
Mage::app()->setCurrentStore($website);
// Init a Magento session. This is super ultra important
Mage::getSingleton('core/session');
// $customer Mage_Customer_Model_Customer
// We get an instance of the customer model for the actual website
$customer = Mage::getModel('customer/customer')
->setWebsiteId(Mage::app()->getStore()->getWebsiteId());
// Load the client with the appropriate email
$customer->loadByEmail($email);
// Get a customer session
$session = Mage::getSingleton('customer/session');
$session->loginById($customer->getId());
if ($session->isLoggedIn()) {
return $session->getSessionId();
} else {
return null;
}
I created a Magento Custom Api so I can call my login method via SOAP.
Call the login method from my JAVA app, get the sessionId, then set the cookies on the browser, based on received sessionId.
http://yourmagentohost/setCookies.php?sessionId=your_session_id
And inside setCookies.php you have: setcookie("frontend", $_GET["sessionId"] , time()+3600);
That's it, now you have a logged in customer.
How can I perform a Customer Authentication from my Java aplication
(outside of Magento) via api? SOAP API V2
Clarification:
API Users (at least Soap) and Customer's are two user types. If you have a pre-existing userlist, and are looking to find out if they exist as user's inside of Magento, you may retrieve email account's and their related attributes and corresponding password hash's (CE: md5:salt , or CE/EE: sha:salt) all via SOAP. If you are looking to do comparative operations, you will need to implement the same Hashing against your password's to do 1:1 comparisons. If you are looking to have your Application use SOAP to directly perform operations, I would make sure that there is a layer of abstraction, as your app could be used nefariously targeting other user id's all depending on the SOAP Role and ACL set in Magento's Admin.
Moving on...
V2: You'll have to swap to Java, ex: PHP.
$username 'yourUsername';
$password = 'yourApiKeyPlainText';
$proxy = new SoapClient('https://www.yourdomain.com/magento/api/v2_soap?wsdl=1');
$sessionId = $proxy->login($username, $password);
//Get a Full customer List from Magento
$customerList = $proxy->customerCustomerList($sessionId);
//get back a list
//Target a user from your List, Compare Details against your App
$customerInfo = $proxy->customerCustomerInfo($sessionId, '2'); //Customer Id
Remote operations, like Checkout, can be rather involved. The question remains, what do you wish to do next to, or on behalf of the user with your app?
References:
http://www.magentocommerce.com/api/soap/customer/customer.list.html
http://www.magentocommerce.com/api/soap/customer/customer.info.html
Cheers,
Your code example does not use SOAP. Magento SOAP accesses actually look like the following:
$client = new SoapClient('http://magentohost/soap/api/?wsdl');
// If somestuff requires api authentification,
// then get a session token
$session = $client->login('apiUser', 'apiKey');
Have a look at the API documentation: http://www.magentocommerce.com/api/soap/introduction.html

Google Client Login Handling AuthToken

I have a non-gae, gwt application and it have a module that allows users to create documents online via google docs api.
To do that, i first ask user to enter the name and type of the document, than create a new document via google docs api with the given parameters and onSucces part of that servlet returns edit link which is used in client side to open a new page to edit the created document.
Problem that, eachtime i try to open that editLink user have to enter login informations. To solve this i try to use Google Client Login but i am totally lost i think.
First i have username and password of user and can directly use them, after searching i tried some examples which usually returns a token like this and that. Now what should i do with token? How can it be used to complete login process or should totally find another way to do login? All those oauth1,oauth2 and etc. documentations confused me a little bit.
here are my steps;
Server side;
LinkedHashMap<String, String> hashMap = new LinkedHashMap<String, String>();
// Login
DocumentList docList = new DocumentList("document");
docList.login(ServletUtil.googleDocsLoginInfo().get("username"), ServletUtil.googleDocsLoginInfo().get("password"));
//Create document with a unique suffix
String docName= parameterName+ "-Created-" + new Date();
docList.createNew(docName, dosyaTur);
// Find the created document and store editLink
DocumentListFeed feed = docList.getDocsListFeed("all");
for (final DocumentListEntry entry : feed.getEntries()) {
if (entry.getTitle().getPlainText().equals(docName)) {
hashMap.put("editlink", entry.getDocumentLink().getHref());
}
}
return hashMap;
And Client side;
#Override
public void onSuccess(LinkedHashMap<String, String> result) {
String editLink = result.get("editlink");
Window.open(editLink,"newwindow","locationno");
}
Thanks for your helps.
If I may suggest using OAuth instead of Client Login, which is outdated and less secure.
The functionality is basically the same (for OAuth 2.0 there are more ways to handle the login).
I know, trying to understand how to access the api via OAuth is very confusing, so I try to break it down a little:
If you use OAuth 2.0 you may want to use a library like this one or you can try out my own (although I wrote it for Android, this could work with other Java Apps including Web Apps)
This is what happens when a user logs in the first time with your app:
> Your App sends an authorization request containing some information about your app - for example your app needs to be registered with google and therefore has a special application key
< The Server sends you a url, open it in a new browser window and let the user login. There he will be asked to allow your app to access his account (or some parts of it) - when he confirms he will be prompted an Authorization Code which he needs to copy
> The user gets back to your app, where you will ask him for the authorization code. After he gave it, your app connects again with the server and sends the code as some kind of authorization grant of the user.
< The Server answers with a access token
All you need to do is use this access token (also called a bearer token) in all your requests to the server hidden in the header message.
I am sorry I can't give you a more precise answer right now, since I never used GWT. All I can say is, try using OAuth2, it is actually very simple (after you learn what all this confusing things like authorization flow, bearer token etc are) and really comfortable for your user, once the he has done the first login.

Categories