Android Google Sheets API V4 - Update public sheet without OAuth - java

I'm trying to programmatically update a public spreadsheet (set to anyone can edit) via the API but it fails with
401 - "The request does not have valid authentication credentials."
I would expect to not need "valid authentication credentials" since it's a publicly editable spreadsheet. I can GET data from the sheet just fine, although I had to generate a "browser" API Key since apparently using an Android Key doesn't work.
Anyone know if there is a trick to getting an update to work, or is this not possible with the API?
Sample code I'm hacking together:
// Don't think I even need this?
GoogleCredential credential = new GoogleCredential();
credential.createScoped(Collections.singleton(SheetsScopes.SPREADSHEETS));
HttpTransport transport = AndroidHttp.newCompatibleTransport();
JsonFactory factory = JacksonFactory.getDefaultInstance();
final Sheets sheets = new Sheets.Builder(transport, factory, credential)
.setApplicationName("My Awesome App")
.build();
final String sheetID = "[ID Of Valid Public Spreadsheet Here]";
final String range = "A:S";
final ValueRange content = new ValueRange();
content.set("Column A Name", "Some Value to Set");
new Thread() {
#Override
public void run() {
try {
UpdateValuesResponse valueRange = sheets.spreadsheets().values()
.update(sheetID, range, content)
.setKey("My-Valid-Browser-Api-Key")
.execute();
mLog.D("Got values: " + valueRange);
}
catch (IOException e) {
mLog.E("Sheets failed", e);
}
}
}.start();

The Sheets V4 API today does not allow anonymous edits, even for sheets that allow it. (It does allow anonymous reads for sheets that allow it.)

Related

How do I find an Azure policy definition by name using the Java SDK?

Azure's Policy service comes with many built-in policies. They can be accessed using Azure's Java SDK and the Azure Resource Manager. The definition of a specific policy can be acquired using the getByName() method in the SDK.
The code looks like this:
AzureResourceManager azureResourceManager = AzureResourceManager
.authenticate(credential, profile)
.withSubscription("<my-subscription-id>");
PolicyDefinition policyDefinition = azureResourceManager.policyDefinitions().getByName("<name>");
To test this code, I went to the console to find the name of a pre-built policy. I found two different names, one in the text:
and a different one in the definition:
However, trying to retrieve the policy definition using either of these names results in the same error:
Status code 404, The policy definition 'Audit VMs that do not use managed disks' could not be found.
and
Status code 404, The policy definition '06a78e20-9358-41c9-923c-fb736d382a4d' could not be found
Question: What name is this method looking for? Or is there a better way to retrieve a policy definition?
If you want to get one build_in policy in java application, you can use the method PolicyClientImpl.getPolicyDefinitions().getBuiltIn() in the package com.azure.resourcemanager.resources. Besides, please note that the name of build-in policy is guide.
For example
install sdk
<dependency>
<groupId>com.azure.resourcemanager</groupId>
<artifactId>azure-resourcemanager-resources</artifactId>
<version>2.1.0</version>
</dependency>
Code
String clientId="";
String clientSecret="";
String tenant="";
String subId="";
AzureProfile profile = new AzureProfile(tenant,subId, AzureEnvironment.AZURE);
TokenCredential credential = new ClientSecretCredentialBuilder()
.clientId(clientId)
.clientSecret(clientSecret)
.authorityHost(profile.getEnvironment().getActiveDirectoryEndpoint())
.tenantId(tenant)
.build();
PolicyClientImpl policyClient= new PolicyClientBuilder()
.pipeline(HttpPipelineProvider.buildHttpPipeline(credential,profile))
.endpoint(profile.getEnvironment().getResourceManagerEndpoint())
.subscriptionId(profile.getSubscriptionId())
.buildClient();
PolicyDefinitionInner policy = policyClient.getPolicyDefinitions().getBuiltIn("04d53d87-841c-4f23-8a5b-21564380b55e");
System.out.println(policy.policyType());
System.out.println(policy.description());
In the end, I wound up using the REST API to get the policy definition when I all know is the policy definition name. Note that I had to use a one call to get built-in policies and another to get custom policies, which is painful since I didn't know a priori which type I had. I used OkHttpClient to handle the heavy lifting. Here's my solution:
Boolean itMightBeACustomPolicy = false;
OkHttpClient builtinPolicyDefinitionHttpClient = new OkHttpClient();
String builtinPolicyDefinitionUrl = "https://management.azure.com/providers/Microsoft.Authorization/policyDefinitions/"
+ policyState.getString("policyDefinitionName") // This is what I know
+ "?api-version=2020-09-01";
Request builtinPolicyDefinitionRequest = new Request.Builder()
.url(builtinPolicyDefinitionUrl)
.addHeader("Authorization", "Bearer " + token)
.get()
.build();
String policyDefinitionJson = "";
try
{
Response builtinPolicyDefinitionResponse = builtinPolicyDefinitionHttpClient.newCall(builtinPolicyDefinitionRequest).execute();
if(builtinPolicyDefinitionResponse.isSuccessful())
{
// It's a built-in policy definition
policyDefinitionJson = builtinPolicyDefinitionResponse.body().string();
}
else
{
// Let's try for a custom definition
// I do this separately to keep the try..catch unique.
itMightBeACustomPolicy = true;
}
}
catch (IOException e)
{
e.printStackTrace(); // TODO Handle this...
}
if(itMightBeACustomPolicy)
{
OkHttpClient customPolicyDefinitionHttpClient = new OkHttpClient();
String customPolicyDefinitionUrl = "https://management.azure.com/subscriptions/"
+ subscriptionId
+ "/providers/Microsoft.Authorization/policyDefinitions/"
+ policyState.getString("policyDefinitionName") // This is what I know
+ "?api-version=2020-09-01";
Request customPolicyDefinitionRequest = new Request.Builder()
.url(customPolicyDefinitionUrl)
.addHeader("Authorization", "Bearer " + token)
.get()
.build();
try
{
Response customPolicyDefinitionResponse = customPolicyDefinitionHttpClient.newCall(customPolicyDefinitionRequest).execute();
if(customPolicyDefinitionResponse.isSuccessful())
{
policyDefinitionJson = customPolicyDefinitionResponse.body().string();
}
else
{
// Not sure what it is. Let's assume there are no policy definitions available.
// So do nothing here for now.
}
}
catch (IOException e)
{
e.printStackTrace(); // TODO Handle this...
}
}
// Wherever we got the policy definition from, let's parse it and gather data.
// NOTE: This design assumes that the JSON for built-in and custom are (nearly) identical.
// That might be wrong.
if(!policyDefinitionJson.isEmpty())
{
JSONObject policyDefinitionRootObject = new JSONObject(policyDefinitionJson);
// Do something with the resulting JSON
System.out.println(policyDefinitionRootObject.getJSONObject("properties").getString("policyType"));
System.out.println(policyDefinitionRootObject.getJSONObject("properties").getString("description"));
System.out.println(policyDefinitionRootObject.getJSONObject("properties").getString("displayName"));
}
Note: "OkHttp performs best when you create a single OkHttpClient instance and reuse it for all of your HTTP calls." So I need to do some re-factoring still to avoid creating multiple clients.

Regarding google +domain api ............ getting an error 403 forbidden while listing the circle using installed application

i have just listing down the circle name in my google+domain api but getting an error of
i have used installed application-> other option while making the application in google developer console
I am developing a small installed application wherein I am integrating with Google+ Domain API's. I am using OAuth2 authentication.I have generated client_id and client_secret for my Installed application from Google API console. Using Google+ Domain API's, I am able to generate the access token.
Also I am using ---some----#gmail.com using gmail account
my code is as :-
enter code here
private static final String CLIENT_ID = "xyxxxxxxxx something in there";
private static final String CLIENT_SECRET = "Fhh1LYQ__UTso48snXHyqSQ2";
public static void main(String[] args) throws IOException {
// List the scopes your app requires:
try{
List<String> SCOPE = Arrays.asList(
"https://www.googleapis.com/auth/plus.me",
"https://www.googleapis.com/auth/plus.stream.write",
"https://www.googleapis.com/auth/plus.circles.read");
final String REDIRECT_URI = "urn:ietf:wg:oauth:2.0:oob";
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
new NetHttpTransport(),
new JacksonFactory(),
CLIENT_ID, // This comes from your Developers Console project
CLIENT_SECRET, // This, as well
SCOPE)
.setApprovalPrompt("force")
// Set the access type to offline so that the token can be refreshed.
// By default, the library will automatically refresh tokens when it
// can, but this can be turned off by setting
// dfp.api.refreshOAuth2Token=false in your ads.properties file.
.setAccessType("offline").build();
// This command-line se`enter code here`rver-side flow example requires the user to open the
// authentication URL in their browser to complete the process. In most
// cases, your app will use a browser-based server-side flow and your
// user will not need to copy and paste the authorization code. In this
// type of app, you would be able to skip the next 5 lines.
// You can also look at the client-side and one-time-code flows for other
// options at https://developers.google.com/+/web/signin/
String url = flow.newAuthorizationUrl().setRedirectUri(REDIRECT_URI).build();
System.out.println("Please open the following URL in your browser then " +
"type the authorization code:");
System.out.println(" " + url);
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String code = br.readLine();
// End of command line prompt for the authorization code.
GoogleTokenResponse tokenResponse = flow.newTokenRequest(code)
.setRedirectUri(REDIRECT_URI).execute();
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(new NetHttpTransport())
.setJsonFactory(new JacksonFactory())
.setClientSecrets(CLIENT_ID, CLIENT_SECRET)
.addRefreshListener(new CredentialRefreshListener() {
#Override
public void onTokenResponse(Credential credential, TokenResponse tokenResponse) {
// Handle success.
System.out.println("Credential was refreshed successfully.");
}
#Override
public void onTokenErrorResponse(Credential credential,
TokenErrorResponse tokenErrorResponse) {
// Handle error.
System.err.println("Credential was not refreshed successfully. "
+ "Redirect to error page or login screen.");
}
})
// You can also add a credential store listener to have credentials
// stored automatically.
//.addRefreshListener(new CredentialStoreRefreshListener(userId, credentialStore))
.build();
// Set authorized credentials.
credential.setFromTokenResponse(tokenResponse);
// Though not necessary when first created, you can manually refresh the
// token, which is needed after 60 minutes.
credential.refreshToken();
// Create a new authorized API client
PlusDomains service = new PlusDomains.Builder(new NetHttpTransport(), new JacksonFactory(), credential).setApplicationName("Get-me").setRootUrl("https://www.googleapis.com/").build();
PlusDomains.Circles.List listCircles = service.circles().list("me");
listCircles.setMaxResults(5L);
CircleFeed circleFeed = listCircles.execute();
List<Circle> circles = circleFeed.getItems();
// Loop until no additional pages of results are available.
while (circles != null) {
for (Circle circle : circles) {
System.out.println(circle.getDisplayName());
}
// When the next page token is null, there are no additional pages of
// results. If this is the case, break.
if (circleFeed.getNextPageToken() != null) {
// Prepare the next page of results
listCircles.setPageToken(circleFeed.getNextPageToken());
// Execute and process the next page request
circleFeed = listCircles.execute();
circles = circleFeed.getItems();
} else {
circles = null;
}
}
}catch(Exception e)
{
System.out.println("Exception "+e);
}
}
Its an INSTAlled Application -> other Options........ in google developer console
i get the below error:---
Exception com.google.api.client.googleapis.json.GoogleJsonResponseException: 403 Forbidden
{
"code" : 403,
"errors" : [ {
"domain" : "global",
"message" : "Forbidden",
"reason" : "forbidden"
} ],
"message" : "Forbidden"
}
Note: I have also enabled Google+ Domain API in my Google API Console.
REDIRECT_URI ="urn:ietf:wg:oauth:2.0:oob" since it's a Installed app. Any Suggestions?
Please help me out guys
See this other answer: the Google+ Domains API is only "for people who use Google Apps at college, at work, or at home." It appears that Google does not currently allow apps to list circles for regular Google+ accounts.

How to Add new column dynamically to already existed table in bigquery..?

I created a csv file with three columns in a row..in google bigquery in created a dataset with one table with csv file ....for this i completed my java code...but now i have to add a new column to existed row dynamically in java code..?
// Main method for data print.
#SuppressWarnings({ "rawtypes", "unchecked" })
public static void main(String[] args) throws IOException, InterruptedException {
// Create a new BigQuery client authorized via OAuth 2.0 protocol
Bigquery bigquery = createAuthorizedClient();
TableRow row = new TableRow();
row.set("Column1", "Sample23");
row.set("Column2", 7);
row.set("Column3", "Sample25");
TableDataInsertAllRequest.Rows rows = new TableDataInsertAllRequest.Rows();
rows.setJson(row);
List rowList = new ArrayList();
rowList.add(rows);
TableDataInsertAllRequest content =
new TableDataInsertAllRequest().setRows(rowList);
TableDataInsertAllResponse response = bigquery.tabledata().insertAll(PROJECT_ID, DATASET_ID, TABLE_ID, content).execute();
System.out.println("Final response = " + response);
}
There are two table operations Update and Patch.
You need to use the Update command, to add new columns to your schema.
Important side notes:
order is important. If you change the ordering, it will look like an incompatible schema.
you can only add new fields at the end of the table. On the old columns, you have the option to change required to nullable.
you cannot add a required field to an existing schema.
you cannot remove old fields, once a table's schema has been specified you cannot change it without first deleting all the of the data associated with it. If you want to change a table's schema, you must specify a writeDisposition of WRITE_TRUNCATE. For more information, see the Jobs resource.
Here is an example of a curl session that adds fields to a schema. It should be relatively easy to adapt to Java. It uses auth.py from here
When using Table.Update(), you must include the full table schema again. If you don't provide an exact matching schema you can get: Provided Schema does not match Table. For example I didn't paid attention to details and in one of my update calls I didn't include an old field like created and it failed.
Actually I didn't use any jobs in my java code. I simply created a dataset with one table with a row in three columns. Now I have to add new column at java code not in csv file. I am posting my complete source code:
public class BigQueryJavaGettingStarted {
// Define required variables.
private static final String PROJECT_ID = "nvjsnsb";
private static final String DATASET_ID = "nvjjvv";
private static final String TABLE_ID = "sampledata";
private static final String CLIENTSECRETS_LOCATION = "client_secrets.json";
static GoogleClientSecrets clientSecrets = loadClientSecrets(CLIENTSECRETS_LOCATION);
// Static variables for API scope, callback URI, and HTTP/JSON functions
private static final List<String> SCOPES = Arrays.asList(BigqueryScopes.BIGQUERY);
private static final String REDIRECT_URI = "https://www.example.com/oauth2callback";
// Global instances of HTTP transport and JSON factory objects.
private static final HttpTransport TRANSPORT = new NetHttpTransport();
private static final JsonFactory JSON_FACTORY = new JacksonFactory();
private static GoogleAuthorizationCodeFlow flow = null;
// Main method for data print.
#SuppressWarnings({ "rawtypes", "unchecked" })
public static void main(String[] args) throws IOException, InterruptedException {
// Create a new BigQuery client authorized via OAuth 2.0 protocol
Bigquery bigquery = createAuthorizedClient();
TableRow row = new TableRow();
row.set("Column1", "OneMoreCol1");
row.set("Column2", 79);
row.set("Column3", "OneMoreCol2");
TableDataInsertAllRequest.Rows rows = new TableDataInsertAllRequest.Rows();
rows.setJson(row);
List rowList = new ArrayList();
rowList.add(rows);
TableDataInsertAllRequest content = new TableDataInsertAllRequest().setRows(rowList);
TableDataInsertAllResponse response = bigquery.tabledata().insertAll(PROJECT_ID, DATASET_ID, TABLE_ID, content).execute();
System.out.println("Final response = " + response);
}
// Create Authorized client.
public static Bigquery createAuthorizedClient() throws IOException {
String authorizeUrl = new GoogleAuthorizationCodeRequestUrl(
clientSecrets,
REDIRECT_URI,
SCOPES).setState("").build();
System.out.println("Paste this URL into a web browser to authorize BigQuery Access:\n" + authorizeUrl);
System.out.println("... and type the code you received here: ");
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String authorizationCode = in.readLine();
// Exchange the auth code for an access token and refresh token
Credential credential = exchangeCode(authorizationCode);
return new Bigquery(TRANSPORT, JSON_FACTORY, credential);
}
// Exchange code method.
static Credential exchangeCode(String authorizationCode) throws IOException {
GoogleAuthorizationCodeFlow flow = getFlow();
GoogleTokenResponse response =
flow.newTokenRequest(authorizationCode).setRedirectUri(REDIRECT_URI).execute();
return flow.createAndStoreCredential(response, null);
}
// Get flow.
static GoogleAuthorizationCodeFlow getFlow() {
if (flow == null) {
HttpTransport httpTransport = new NetHttpTransport();
JacksonFactory jsonFactory = new JacksonFactory();
flow = new GoogleAuthorizationCodeFlow.Builder(httpTransport,
jsonFactory,
clientSecrets,
SCOPES)
.setAccessType("offline").setApprovalPrompt("force").build();
}
return flow;
}
// Load client secrets.
private static GoogleClientSecrets loadClientSecrets(String clientSecretsLocation) {
try {
clientSecrets = GoogleClientSecrets.load(new JacksonFactory(),
new InputStreamReader(BigQueryJavaGettingStarted.class.getResourceAsStream(clientSecretsLocation)));
} catch (Exception e) {
System.out.println("Could not load client_secrets.json");
e.printStackTrace();
}
return clientSecrets;
}
}

Google Contacts v3 API & OAuth v2, in Java

For the last few days i've been trying to get a list of google contacts using the above APIs.
Needles to say, unsuccessfully.
Google documentation (which is a total mess if i may say) has not been very helpful regarding my problem.
The thing is, i have no idea how to authorize the ContactsService object using OAuth v2 API.
I've already downloaded Google OAuth2.0 library which, again, has no proper documentation and/or no proper examples for total beginners like myself.
So to sum it up, does anyone have any working "Hello world" type of examples or any kind of "guidance" for the above problem?
As a side note, i did managed to get the contacts using the Scribe API, but as you may know, the response is in the xml/json format which needs to be parsed first and that's not what i want.
Thank you
It seems i have finally made some progress.
The problem, apparently, was that there are bunch of different OAuth2 libraries out there, some of them are either deprecated or just won't work with Contacts v3, that is, generated access token will be invalid (that's what i concluded).
So for authorization and generating access token i've used Google API Client 1.14.1 (beta), and my code is as follows:
Servlet 1 (generating auth URL):
protected void processRequest(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
GoogleAuthorizationCodeRequestUrl authorizationCodeURL=new GoogleAuthorizationCodeRequestUrl(CLIENT_ID, REDIRECT_URL, SCOPES);
authorizationCodeURL.setAccessType("offline");//For future compatibility
String authorizationURL=authorizationCodeURL.build();
System.out.println("AUTHORIZATION URL: "+authorizationURL);
response.sendRedirect(new URL(authorizationURL).toString());
}
Servlet 2 (dealing with access token)
protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head>");
out.println("<title>Servlet SignInFinished</title>");
out.println("</head>");
out.println("<body>");
HttpTransport transport = new NetHttpTransport();
JsonFactory jsonFactory = new JacksonFactory();
GoogleAuthorizationCodeTokenRequest authorizationTokenRequest = new GoogleAuthorizationCodeTokenRequest(transport, jsonFactory, CLIENT_ID, CLIENT_SECRET, request.getParameter("code"), REDIRECT_URL);
GoogleTokenResponse tokenResponse = authorizationTokenRequest.execute();
out.println("OAuth2 Access Token: " + tokenResponse.getAccessToken());
GoogleCredential gc = new GoogleCredential();
gc.setAccessToken(tokenResponse.getAccessToken());
ContactsService contactsService = new ContactsService("Lasso Project");
contactsService.setOAuth2Credentials(gc);
try {
URL feedUrl = new URL("https://www.google.com/m8/feeds/contacts/default/full");
Query myQuery = new Query(feedUrl);
myQuery.setMaxResults(1000);
ContactFeed resultFeed = contactsService.query(myQuery, ContactFeed.class);
for (int i = 0; i < resultFeed.getEntries().size(); i++) {
out.println(resultFeed.getEntries().get(i).getTitle().getPlainText() + "<br/>");
}
} catch (Exception e) {
System.out.println(e);
}
out.println("</body>");
out.println("</html>");
}
NOTE:
If you are using Client ID for Web Applications, REDIRECT_URL must be one of Redirect URLs you entered when registering application via Google console.
Well, I hope this'll be helpful to some of you :).
I had trouble as well trying to retrieve google contacts.
With OAuth2.0, you first need to get an access token.
Then it gets easy, you can request for the id of the group you are looking for :
import com.google.gdata.client.contacts.ContactsService;
import com.google.gdata.data.contacts.ContactEntry;
import com.google.gdata.data.contacts.ContactFeed;
import com.google.gdata.data.contacts.ContactGroupEntry;
import com.google.gdata.data.contacts.ContactGroupFeed;
private static final String GROUPS_URL = "https://www.google.com/m8/feeds/groups/default/full";
private int getIdOfMyGroup() {
ContactsService contactsService = new ContactsService("MY_PRODUCT_NAME");
contactsService.setHeader("Authorization", "Bearer " + MY_ACCESS_TOKEN);
try {
URL feedUrl = new URL(GROUPS_URL);
ContactGroupFeed resultFeed = contactsService.getFeed(feedUrl, ContactGroupFeed.class);
// "My Contacts" group id will always be the first one in the answer
ContactGroupEntry entry = resultFeed.getEntries().get(0);
return entry.getId();
} catch (...) { ... }
}
Eventually you will be able with the group id to request its contacts :
private static final String CONTACTS_URL = "https://www.google.com/m8/feeds/contacts/default/full";
private static final int MAX_NB_CONTACTS = 1000;
private List<ContactEntry> getContacts() {
ContactsService contactsService = new ContactsService("MY_PRODUCT_NAME");
contactsService.setHeader("Authorization", "Bearer " + MY_ACCESS_TOKEN);
try {
URL feedUrl = new URL(CONTACTS_URL);
Query myQuery = new Query(feedUrl);
// to retrieve contacts of the group I found just above
myQuery.setStringCustomParameter("group", group);
myQuery.setMaxResults(MAX_NB_CONTACTS);
ContactFeed resultFeed = contactsService.query(myQuery, ContactFeed.class);
List<ContactEntry> contactEntries = resultFeed.getEntries();
return contactEntries;
} catch (...) { ... }
}

Using Oauth and Gdata to build a simple application in Java

I am trying to create a simple app on the app engine where users log
in through their Google account, and then it adds an event to their
calendar.
And I am using Java along with Eclipse for this. I have found a simple
code online:
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// Create an instance of GoogleOAuthParameters
GoogleOAuthParameters oauthParameters = new GoogleOAuthParameters();
oauthParameters.setOAuthConsumerKey(CONSUMER_KEY);
oauthParameters.setOAuthConsumerSecret(CONSUMER_SECRET);
oauthParameters.setScope("http://docs.google.com/feeds/");
GoogleOAuthHelper oauthHelper = new GoogleOAuthHelper(
new OAuthHmacSha1Signer());
// Remember the token secret that we stashed? Let's get it back
// now. We need to add it to oauthParameters
String oauthTokenSecret = (String) req.getSession().getAttribute(
"oauthTokenSecret");
oauthParameters.setOAuthTokenSecret(oauthTokenSecret);
// The query string should contain the oauth token, so we can just
// pass the query string to our helper object to correctly
// parse and add the parameters to our instance of oauthParameters
oauthHelper.getOAuthParametersFromCallback(req.getQueryString(),
oauthParameters);
try {
// Now that we have all the OAuth parameters we need, we can
// generate an access token and access token secret. These
// are the values we want to keep around, as they are
// valid for all API calls in the future until a user revokes
// our access.
String accessToken = oauthHelper.getAccessToken(oauthParameters);
String accessTokenSecret = oauthParameters.getOAuthTokenSecret();
// In a real application, we want to redirect the user to a new
// servlet that makes API calls. For the safe of clarity and simplicity,
// we'll just reuse this servlet for making API calls.
oauthParameters = new GoogleOAuthParameters();
oauthParameters.setOAuthConsumerKey(CONSUMER_KEY);
oauthParameters.setOAuthConsumerSecret(CONSUMER_SECRET);
// This is interesting: we set the OAuth token and the token secret
// to the values extracted by oauthHelper earlier. These values are
// already in scope in this example code, but they can be populated
// from reading from the datastore or some other persistence mechanism.
oauthParameters.setOAuthToken(accessToken);
oauthParameters.setOAuthTokenSecret(accessTokenSecret);
oauthParameters.setOAuthCallback("http://www.facebook.com");
oauthHelper.getUnauthorizedRequestToken(oauthParameters);
// Create an instance of the DocsService to make API calls
DocsService client = new DocsService("Malware Inc.");
// Use our newly built oauthParameters
client.setOAuthCredentials(oauthParameters, new OAuthHmacSha1Signer());
URL feedUrl = new URL("https://docs.google.com/feeds/default/private/full");
DocumentListFeed resultFeed = client.getFeed(feedUrl,
DocumentListFeed.class);
for (DocumentListEntry entry : resultFeed.getEntries()) {
resp.getWriter().println(entry.getTitle().getPlainText());
}
} catch (OAuthException e) {
// Something went wrong. Usually, you'll end up here if we have invalid
// oauth tokens
resp.getWriter().println("Here is the problem");
//Server shows 500 problem
} catch (ServiceException e) {
// Handle this exception
}
}
I have registered my application and added the KEY and Secret above
the function, but when I deploy it to the app engine it gives a 500
server error.
Could someone post a simple java program that uses gdata and oauth to
log in a Google user and print the contacts on the screen?
Thanks.
-Manoj
I was facing the same problem, and it took me a while to figure it out.
Actually, the problem is that your are missing some parts in the OAuth authorization process.
As you may know, it a 3-legged process:
Get an unauthorized request token
Authorize the request token
Exchange the authorized request token for an access token and make calls to Google Data with it.
In your case, you are doing step 3 directly.
So before you can call the servlet you described above, and effectively retrieve user's Google Data,
the user must have grant access to your application, by browsing to an authorization URL from his web browser.
You need a first servlet , for example accessible at http://yourapp.com/RequestAccess
public void doGet(HttpServletRequest req, HttpServletResponse resp) {
GoogleOAuthParameters oauthParameters = new GoogleOAuthParameters();
oauthParameters.setOAuthConsumerKey(YOUR_CONSUMER_KEY);
oauthParameters.setOAuthConsumerSecret(YOUR_CONSUMER_SECRET);
OAuthHmacSha1Signer signer = new OAuthHmacSha1Signer();
GoogleOAuthHelper oauthHelper = new GoogleOAuthHelper(signer);
oauthParameters.setScope(FEED_SCOPE);
try {
oauthHelper.getUnauthorizedRequestToken(oauthParameters);
//GET THE UNAUTHORIZED TOKENS
String oauthRequestToken = oauthParameters.getOAuthToken();
String oauthTokenSecret = oauthParameters.getOAuthTokenSecret();
//SAVE THEM SOMEWEHERE (FOR EXAMPLE IN THE SESSION LIKE YOU DID)
// ....
//GET THE AUHTORIZATION URL
String authorizationURL= oauthHelper.createUserAuthorizationUrl(oauthParameters);
// YOU NOW HAVE THE AUHTORIZATION URL, SEND IT BACK TO THE USER SOMEHOW
// ( FOR EXAMPLE BY REDIRECTING THE REQUEST TO THAT URL)
// ...
} catch (OAuthException e1) {
LOGGER.error("error while getting unauthorized request token '{}' ", e1);
}
}
Once the user has navigate to that URL, and grant acces, you can now call your second servlet and it should work.
More info can be found on Google OAuth page here
Hope it helps!

Categories

Resources