Google Contacts v3 API & OAuth v2, in Java - 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 (...) { ... }
}

Related

What is Instagram's "code" and "redirect url"?

I'm developing an application with Instagram integration. For this I use the GitHub project jInstagram (https://github.com/sachin-handiekar/jInstagram).
If you want to log in to Instagram you have to set a redirect url. My first question is: What is this URL for? I didn't find detailed information about this. The code in jInstagram looks like this:
InstagramService service = new InstagramAuthService()
.apiKey("your_client_id")
.apiSecret("your_client_secret")
.callback("your_callback_url")
.build();
Source: https://github.com/sachin-handiekar/jInstagram/wiki/jInstagram-Usage
To get the access token I have to create a verifier and generate an access token from this. In jInstagram's Usage the only information about this verifier is this:
Verifier verifier = new Verifier("verifier you get from the user");
Token accessToken = service.getAccessToken(EMPTY_TOKEN, verifier);
Source: https://github.com/sachin-handiekar/jInstagram/wiki/jInstagram-Usage
What do I have to pass to the verifier's constructor? I searched for an answer and discovered that I have to pass a request parameter named "code" in the code example: https://github.com/sachinhandiekar/jInstagramexamples/blob/master/src/main/java/com/sachinhandiekar/examples/InstagramTokenHandler.java
private static final String CODE = "code";
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws javax.servlet.ServletException, IOException {
String code = request.getParameter(CODE);
InstagramService service = (InstagramService) request.getServletContext().getAttribute(Constants.INSTAGRAM_SERVICE);
Verifier verifier = new Verifier(code);
Token accessToken = service.getAccessToken(verifier);
Instagram instagram = new Instagram(accessToken);
HttpSession session = request.getSession();
session.setAttribute(Constants.INSTAGRAM_OBJECT, instagram);
System.out.println(request.getContextPath());
// Redirect to User Profile page.
response.sendRedirect(request.getContextPath() + "/profile.jsp");
}
What is this code? How do I get in possession of it?
Thank you for reading this question. I'm looking forward to get answers.

Having trouble implementing Stormpath form Login/Authentication alongside REST oAuth authentication in the same application

We're using stormpath with Java & also trying to combine form Login with REST API authentication on the same application.
I've setup stormpath servlet plugin as described here https://docs.stormpath.com/java/servlet-plugin/quickstart.html... This works very fine.
Now, on the same application, we have APIs where I've implemented oAuth authentication with stormpath see here http://docs.stormpath.com/guides/api-key-management/
The first request for an access-token works fine by sending Basic Base64(keyId:keySecret) in the request header and grant_type = client_credentials in the body. Access tokens are being returned nicely. However trying to authenticate subsequent requests with the header Bearer <the-obtained-access-token> does not even hit the application before
returning the following json error message...
{
"error": "invalid_client",
"error_description": "access_token is invalid."
}
This is confusing because I've set breakpoints all over the application and I'm pretty sure that the API request doesn't hit the anywhere within the application before stormpath kicks in and returns this error. And even if stormpath somehow intercepts the request before getting to the REST interface, this message doesn't make any sense to me because i'm certainly making the subsequent API calls with a valid access-token obtained from the first call to get access-token.
I have run out of ideas why this could be happening but i'm suspecting that it may have something to do with stormpath config especially with a combination
of form Login/Authentication for web views and oAuth Athentication for REST endpoints. With that said, here's what my stormpath.properties looks like. Hope this could help point at anything I may be doing wrong.
stormpath.application.href=https://api.stormpath.com/v1/applications/[app-id]
stormpath.web.filters.authr=com.app.security.AuthorizationFilter
stormpath.web.request.event.listener = com.app.security.AuthenticationListener
stormpath.web.uris./resources/**=anon
stormpath.web.uris./assets/**=anon
stormpath.web.uris./v1.0/**=anon
stormpath.web.uris./** = authc,authr
stormpath.web.uris./**/**=authc,authr
Help with this would be highly appreciated.
The problem might be related to an incorrect request.
Is it possible for you to try this code in your app?:
private boolean verify(String accessToken) throws OauthAuthenticationException {
HttpRequest request = createRequestForOauth2AuthenticatedOperation(accessToken);
AccessTokenResult result = Applications.oauthRequestAuthenticator(application)
.authenticate(request);
System.out.println(result.getAccount().getEmail() + " was successfully verified, you can allow your protect operation to continue");
return true;
}
private HttpRequest createRequestForOauth2AuthenticatedOperation(String token) {
try {
Map<String, String[]> headers = new LinkedHashMap<String, String[]>();
headers.put("Accept", new String[]{"application/json"});
headers.put("Authorization", new String[]{"Bearer " + token});
HttpRequest request = HttpRequests.method(HttpMethod.GET)
.headers(headers)
.build();
return request;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
I've prepared an example that demonstrates oauth token creation as well as authorized access to protected pages using access tokens.
It builds off of the servlet example in the Stormpath SDK. The repo can be found here: https://github.com/stormpath/stormpath-java-oauth-servlet-sample
It demonstrates running a servlet application and having an out-of-band program get and use oauth tokens to access protected resources.
The core of the oauth part is in TokenAuthTest.java:
public class TokenAuthTest {
public static void main(String[] args) throws Exception {
String command = System.getProperty("command");
if (command == null || !("getToken".equals(command) || "getPage".equals(command))) {
System.err.println("Must supply a command:");
System.err.println("\t-Dcommand=getToken OR");
System.err.println("\t-Dcommand=getPage OR");
System.exit(1);
}
if ("getToken".equals(command)) {
getToken();
} else {
getPage();
}
}
private static final String APP_URL = "http://localhost:8080";
private static final String OAUTH_URI = "/oauth/token";
private static final String PROTECTED_URI = "/dashboard";
private static void getToken() throws Exception {
String username = System.getProperty("username");
String password = System.getProperty("password");
if (username == null || password == null) {
System.err.println("Must supply -Dusername=<username> -Dpassword=<password> on the command line");
System.exit(1);
}
PostMethod method = new PostMethod(APP_URL + OAUTH_URI);
method.setRequestHeader("Origin", APP_URL);
method.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
method.addParameter("grant_type", "password");
method.addParameter("username", username);
method.addParameter("password", password);
HttpClient client = new HttpClient();
client.executeMethod(method);
BufferedReader br = new BufferedReader(new InputStreamReader(method.getResponseBodyAsStream()));
String readLine;
while(((readLine = br.readLine()) != null)) {
System.out.println(readLine);
}
}
private static void getPage() throws Exception {
String token = System.getProperty("token");
if (token == null) {
System.err.println("Must supply -Dtoken=<access token> on the command line");
System.exit(1);
}
GetMethod method = new GetMethod(APP_URL + PROTECTED_URI);
HttpClient client = new HttpClient();
System.out.println("Attempting to retrieve " + PROTECTED_URI + " without token...");
int returnCode = client.executeMethod(method);
System.out.println("return code: " + returnCode);
System.out.println();
System.out.println("Attempting to retrieve " + PROTECTED_URI + " with token...");
method.addRequestHeader("Authorization", "Bearer " + token);
returnCode = client.executeMethod(method);
System.out.println("return code: " + returnCode);
}
}

How to use Google task API ?Initialize Tasks Get TaskList etc.?

I want to use google task api and want to get tasklist,update,delete,add etc.. and I found this link https://developers.google.com/google-apps/tasks/oauth-and-tasks-on-android where step by step procedure is given on that link the library which are given are deprecated.
That's why I have downloaded latetst library google-api-java-client-1.12.0-beta from here http://code.google.com/p/google-api-java-client/downloads/detail?name=google-api-java-client-1.12.0-beta.zip&can=2&q= and google-api-services-tasks-v1-rev5-java-1.12.0-beta from here http://code.google.com/p/google-api-java-client/wiki/APIs#Tasks_API and try the code given and similar to it but no luck not get anything i am successfully get accesstoken but not get anything and in the latest libs most of method are changes so how to inialize the Tasks and get TaskList,create,delete etc...... Not a single document i found related to updated library.
Hope for your regards.
Thanks.
This solution is for Server to server communication using OAuth 2.0
It is a three step process
Authenticate using OAuth 2.0
Get the com.google.api.services.tasks.Tasks service object
Get the required Task or TaskList
In this sample code it uses the domain id "abc.com" and the user is "user1#abc.com". For gmail users, please provide the gmailid (abc#gmail.com) as consumerkey and leave "xoauth_requestor_id" as gmailid
import com.google.api.client.http.*;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.jackson.JacksonFactory;
import com.google.api.services.tasks.*;
import com.google.api.client.auth.oauth.OAuthHmacSigner;
import com.google.api.client.auth.oauth.OAuthParameters;
public class GoogleConnection {
public Tasks setup() throws Exception {
com.google.api.services.tasks.Tasks tasks = null;
HttpRequestFactory httpRequestFactory = null;
HttpRequestInitializer httpRequestInitializer = null;
OAuthHmacSigner signer = new OAuthHmacSigner();
HttpTransport httpTransport = new NetHttpTransport();
OAuthParameters oauthParameters = new OAuthParameters();
final ArrayMap<String, Object> customKeys = new ArrayMap<String, Object>();
customKeys.add("xoauth_requestor_id", "user1#abc.com");
signer.clientSharedSecret = "secret_key_received_from_google";
oauthParameters.version = "2.0";
oauthParameters.consumerKey = "abc.com";
oauthParameters.signer = signer;
httpRequestFactory = createRequestFactory(httpTransport, oauthParameters, "20000", "20000");
httpRequestInitializer = httpRequestFactory.getInitializer();
tasks = new com.google.api.services.tasks.Tasks.Builder(httpTransport, new JacksonFactory(), httpRequestInitializer)
.setTasksRequestInitializer(new TasksRequestInitializer() {
#Override
public void initializeTasksRequest(TasksRequest<?> request) throws IOException {
#SuppressWarnings("rawtypes")
TasksRequest tasksRequest = (TasksRequest) request;
tasksRequest.setUnknownKeys(customKeys);
tasksRequest.setKey("keyapi_received_from_google_by_registering_your_app");
}
})
.setApplicationName("")
.build();
return tasks;
}
}
Getting Tasks from a Task List
Instantiate GoogleConnection class
public List<com.google.api.services.tasks.model.Task> getTasksFromTaskList(String taskListId) throws Exception {
com.google.api.services.tasks.Tasks tasksService = googleConnection.setup();
com.google.api.services.tasks.model.Tasks result = tasksService .tasks().list(taskListId).execute();
return result.getItems();
}

Google Calendar API: Get events as JSON

I've been working through the documentation for hours, but I just can't figure it out. I need only access to my own calendar. So what steps do I have to take? How does the authentication work?
Thanks,
Joe
I used the this code to access the calendar list i.e., this returns the details of the calendars that I created. I hope it helps. I am using OAuth 2.0 draft 12 and Google Calendar API v3
#RequestMapping(value="/authenticate.do" , method={ RequestMethod.GET , RequestMethod.POST })
public void authenticate(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
List <String> scopes = new LinkedList<String>();
scopes.add(scope);
AuthorizationCodeRequestUrl authorize = new GoogleAuthorizationCodeRequestUrl(client_id, redirect_uri, scopes);
authorize.setRedirectUri(redirect_uri);
String authorize_url = authorize.build();
log.info(authorize_url);
response.sendRedirect(authorize_url);
}
The function above takes care of the OAuth authentication and directs the user to the screen where they allow or deny. If they allow they are redirected to this function.
#RequestMapping(value="/importCalendar.do", method={ RequestMethod.GET , RequestMethod.POST })
public void importCalendarList(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
PrintWriter p = response.getWriter();
String code = request.getParameter("code");
HttpTransport transport = new NetHttpTransport();
JsonFactory jsonFactory = new JacksonFactory();
GoogleTokenResponse res = new GoogleAuthorizationCodeTokenRequest(transport, jsonFactory, client_id, client_secret, code, redirect_uri).execute();
String accessToken = res.getAccessToken();
Calendar.Builder builder = new Calendar.Builder(transport, jsonFactory, null);
builder.setCalendarRequestInitializer(new CalendarRequestInitializer(accessToken));
Calendar calendarService = builder.build();
Calendar.CalendarList.List list = calendarService.calendarList().list();
list.setOauthToken(accessToken);
List <CalendarListEntry>list1=list.execute().getItems();
String id = list1.get(0).getId();
p.write(id);
for(CalendarListEntry temp:list1) {
p.println(temp.getSummary());
temp.getId();
}
}
This function importCalendarList lists the names of all the calendars that the user has. The List of type CalendarListEntry is the Object representation of your calendars. So from getters you can get, for instance, the uniqueid of one of the calendars or the time zone of a calendar.
I wrote this program for knowing calendar api. Before I started writing I went to google api console to set these things up.
client id, redirect uri, scope and client secret. Set these up and use them in the program. This just shows the calendar list however you can also get, add, update and delete events from/to a calendar or do all these operations on a calendar itself. The comprehensive documentation for Google Calendar API is found here:
https://google-api-client-libraries.appspot.com/documentation/calendar/v3/java/latest/index.html
and one last note. I did this from a web application. Hope this helps.

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