diff --git a/.gitignore b/.gitignore index 0be1402..7ae48a0 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ # Package Files # *.war *.ear +/target diff --git a/pom.xml b/pom.xml index 6170b09..466b950 100644 --- a/pom.xml +++ b/pom.xml @@ -26,17 +26,22 @@ limitations under the License. - - com.google.apis - google-api-services-mirror - v1-rev26-1.17.0-rc - + + com.google.apis + google-api-services-mirror + v1-rev46-1.18.0-rc + com.google.http-client google-http-client-jackson2 - 1.17.0-rc + 1.18.0-rc - + + + com.google.api-client + google-api-client-appengine + 1.18.0-rc + org.mortbay.jetty diff --git a/src/main/java/com/google/glassware/AuthServlet.java b/src/main/java/com/google/glassware/AuthServlet.java index db123d2..a8704ab 100644 --- a/src/main/java/com/google/glassware/AuthServlet.java +++ b/src/main/java/com/google/glassware/AuthServlet.java @@ -55,7 +55,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse res) throws IOE .setRedirectUri(WebUtil.buildUrl(req, "/oauth2callback")).execute(); // Extract the Google User ID from the ID token in the auth response - String userId = ((GoogleTokenResponse) tokenResponse).parseIdToken().getPayload().getUserId(); + String userId = ((GoogleTokenResponse) tokenResponse).parseIdToken().getPayload().getSubject(); LOG.info("Code exchange worked. User " + userId + " logged in."); diff --git a/src/main/java/com/google/glassware/AuthUtil.java b/src/main/java/com/google/glassware/AuthUtil.java index d4cdcd4..7fb7fb4 100644 --- a/src/main/java/com/google/glassware/AuthUtil.java +++ b/src/main/java/com/google/glassware/AuthUtil.java @@ -15,18 +15,12 @@ */ package com.google.glassware; -import com.google.api.client.auth.oauth2.AuthorizationCodeFlow; -import com.google.api.client.auth.oauth2.Credential; -import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow; -import com.google.api.client.http.javanet.NetHttpTransport; - -import com.google.api.client.json.jackson2.JacksonFactory; - import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.net.URISyntaxException; import java.net.URL; +import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Properties; @@ -35,19 +29,45 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; +import com.google.api.client.auth.oauth2.AuthorizationCodeFlow; +import com.google.api.client.auth.oauth2.Credential; +import com.google.api.client.auth.oauth2.StoredCredential; +import com.google.api.client.extensions.appengine.datastore.AppEngineDataStoreFactory; +import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow; +import com.google.api.client.googleapis.extensions.appengine.auth.oauth2.AppIdentityCredential; +import com.google.api.client.http.HttpTransport; +import com.google.api.client.http.javanet.NetHttpTransport; +import com.google.api.client.json.jackson2.JacksonFactory; +import com.google.api.client.util.store.DataStore; +import com.google.api.services.mirror.Mirror; +import com.google.api.services.mirror.model.Account; +import com.google.api.services.mirror.model.AuthToken; + /** * A collection of utility functions that simplify common authentication and * user identity tasks * * @author Jenny Murphy - http://google.com/+JennyMurphy */ + public class AuthUtil { - public static ListableMemoryCredentialStore store = new ListableMemoryCredentialStore(); public static final String GLASS_SCOPE = "https://www.googleapis.com/auth/glass.timeline " + "https://www.googleapis.com/auth/glass.location " + "https://www.googleapis.com/auth/userinfo.profile"; private static final Logger LOG = Logger.getLogger(AuthUtil.class.getSimpleName()); + public static DataStore getDataStore() { + DataStore store = null; + try { + AppEngineDataStoreFactory.getDefaultInstance().getDataStore(StoredCredential.DEFAULT_DATA_STORE_ID); + } catch (IOException e) { + //TODO: handle this exception + e.printStackTrace(); + throw new RuntimeException(e); + } + return store; + } + /** * Creates and returns a new {@link AuthorizationCodeFlow} for this app. */ @@ -70,7 +90,7 @@ public static AuthorizationCodeFlow newAuthorizationCodeFlow() throws IOExceptio return new GoogleAuthorizationCodeFlow.Builder(new NetHttpTransport(), new JacksonFactory(), clientId, clientSecret, Collections.singleton(GLASS_SCOPE)).setAccessType("offline") - .setCredentialStore(store).build(); + .setDataStoreFactory(AppEngineDataStoreFactory.getDefaultInstance()).build(); } /** @@ -91,7 +111,8 @@ public static void setUserId(HttpServletRequest request, String userId) { public static void clearUserId(HttpServletRequest request) throws IOException { // Delete the credential in the credential store String userId = getUserId(request); - store.delete(userId, getCredential(userId)); + getDataStore().delete(userId); + //getDataStore().delete(userId, getCredential(userId)); // Remove their ID from the local session request.getSession().removeAttribute("userId"); @@ -109,7 +130,59 @@ public static Credential getCredential(HttpServletRequest req) throws IOExceptio return AuthUtil.newAuthorizationCodeFlow().loadCredential(getUserId(req)); } - public static List getAllUserIds() { - return store.listAllUsers(); + @SuppressWarnings("unchecked") +public static List getAllUserIds() { + try { + return (List) getDataStore().keySet(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return null; + } + + /** + * {see #installMirrorAccount} + * + * @param applicationName + * @return + */ +public static Mirror getServerToServerMirror(String applicationName) { + List scopes = new ArrayList(); + scopes.add("https://www.googleapis.com/auth/glass.thirdpartyauth"); + AppIdentityCredential credential = new AppIdentityCredential(scopes); + HttpTransport httpTransport = new NetHttpTransport(); + JacksonFactory jsonFactory = new JacksonFactory(); + Mirror service = new Mirror.Builder(httpTransport, jsonFactory, null) + .setApplicationName(applicationName) + .setHttpRequestInitializer(credential).build(); + return service; + } + + + /** + * Uses {see #getServerToServerMirror} + * This method creates a mirror account to support authentication of your GDK application. {@see https://developers.google.com/glass/develop/gdk/authentication} + * @param userToken -- the userToken provided by MyGlass + * @param authTokenType + * @param accountType + * @param authToken -- application specific auth token + * @param appUserId -- application specific user id + * @param applicationName -- the name of your application + * @throws IOException + */ +public static void installMirrorAccount(String userToken, String authTokenType, String accountType, String authToken, String appUserId, String applicationName) throws IOException { + try { + Account account = new Account(); + List authTokens = new ArrayList(); + authTokens.add(new AuthToken().setType(authTokenType).setAuthToken(authToken)); + account.setAuthTokens(authTokens); + getServerToServerMirror(applicationName).accounts().insert( + userToken, accountType, appUserId, account).execute(); + } catch (IOException e) { + LOG.warning("Failed to save to mirror: " + e.getMessage()); + e.printStackTrace(); + } } + } diff --git a/src/main/java/com/google/glassware/ListableMemoryCredentialStore.java b/src/main/java/com/google/glassware/ListableMemoryCredentialStore.java index 58e5543..173a001 100644 --- a/src/main/java/com/google/glassware/ListableMemoryCredentialStore.java +++ b/src/main/java/com/google/glassware/ListableMemoryCredentialStore.java @@ -30,6 +30,13 @@ * * @author Jenny Murphy - http://google.com/+JennyMurphy */ + +/* + * This is no longer used. The credential store is now using AppEngineDataStore and StoredCredential per latest App Engine API + */ + + +@Deprecated public class ListableMemoryCredentialStore implements CredentialStore { /**