@POST @Path("/renew/{apiKeyId}") @Produces({MediaType.APPLICATION_JSON}) public String renewConnectorTokens(@PathParam("apiKeyId") long apiKeyId) throws Exception { final ApiKey apiKey = guestService.getApiKey(apiKeyId); ConnectorInfo connectorInfo = sysService.getConnectorInfo(apiKey.getConnector().getName()); JSONObject renewInfo = new JSONObject(); final String renewTokensUrlTemplate = connectorInfo.renewTokensUrlTemplate; final String renewTokensUrl = String.format(renewTokensUrlTemplate, apiKey.getId()); renewInfo.accumulate("redirectTo", env.get("homeBaseUrl") + renewTokensUrl); return renewInfo.toString(); }
private long getLatestData(ApiKey apiKey) { if (!apiKey.getConnector().hasFacets()) return Long.MAX_VALUE; final ObjectType[] objectTypes = apiKey.getConnector().objectTypes(); if (objectTypes == null || objectTypes.length == 0) { final String maxTimeAtt = guestService.getApiKeyAttribute(apiKey, ApiKeyAttribute.MAX_TIME_KEY); // only return the ApiKey's maxTime if we have it cached as an attribute if (maxTimeAtt != null && StringUtils.isNotEmpty(maxTimeAtt)) { final DateTime dateTime = ISODateTimeFormat.dateHourMinuteSecondFraction() .withZoneUTC() .parseDateTime(maxTimeAtt); return dateTime.getMillis(); } } else { long maxTime = Long.MIN_VALUE; for (ObjectType objectType : objectTypes) { final String maxTimeAtt = guestService.getApiKeyAttribute( apiKey, objectType.getApiKeyAttributeName(ApiKeyAttribute.MAX_TIME_KEY)); if (maxTimeAtt != null && StringUtils.isNotEmpty(maxTimeAtt)) { final DateTime dateTime = ISODateTimeFormat.dateHourMinuteSecondFraction() .withZoneUTC() .parseDateTime(maxTimeAtt); final long maxObjectTypeTime = dateTime.getMillis(); if (maxObjectTypeTime > maxTime) maxTime = maxObjectTypeTime; } } // only return the ApiKey's maxTime if we have it cached as an attribute for any its // connector's objectTypes if (maxTime > Long.MIN_VALUE) return maxTime; } // fall back to old method of querying the facets table AbstractFacet facet = null; // apiDataService.getLatestApiDataFacet(apiKey, null); return facet == null ? Long.MAX_VALUE : facet.end; }
private long getLastSync(ApiKey apiKey) { if (!apiKey.getConnector().hasFacets()) return Long.MAX_VALUE; final String lastSyncTimeAtt = guestService.getApiKeyAttribute(apiKey, ApiKeyAttribute.LAST_SYNC_TIME_KEY); // only return the ApiKey's lastSyncTime if we have it cached as an attribute if (lastSyncTimeAtt != null && StringUtils.isNotEmpty(lastSyncTimeAtt)) { final DateTime dateTime = ISODateTimeFormat.dateHourMinuteSecondFraction() .withZoneUTC() .parseDateTime(lastSyncTimeAtt); return dateTime.getMillis(); } // fall back to old method of querying the ApiUpdates table ApiUpdate update = null; // connectorUpdateService.getLastSuccessfulUpdate(apiKey); return update != null ? update.ts : Long.MAX_VALUE; }
@POST @Path("/{connector}/channels") @Produces({MediaType.APPLICATION_JSON}) public String setConnectorChannels( @PathParam("connector") String connectorName, @FormParam("channels") String channels) { StatusModel result; Guest guest = AuthHelper.getGuest(); // If no guest is logged in, return empty array if (guest == null) return "{}"; try { ApiKey apiKey = guestService.getApiKey(guest.getId(), Connector.getConnector(connectorName)); settingsService.setChannelsForConnector( guest.getId(), apiKey.getConnector(), channels.split(",")); result = new StatusModel(true, "Successfully updated channels for " + connectorName + "."); StringBuilder sb = new StringBuilder("module=API component=connectorStore action=setConnectorChannels") .append(" connector=") .append(connectorName) .append(" channels=") .append(channels) .append(" guestId=") .append(guest.getId()); logger.info(sb.toString()); } catch (Exception e) { StringBuilder sb = new StringBuilder("module=API component=connectorStore action=setConnectorChannels") .append(" connector=") .append(connectorName) .append(" guestId=") .append(guest.getId()) .append(" stackTrace=<![CDATA[") .append(Utils.stackTrace(e)) .append("]]>"); logger.warn(sb.toString()); result = new StatusModel(false, "Failed to set channels for " + connectorName + "."); } return gson.toJson(result); }
@GET @Path("/{objectTypeName}/data") @Produces({MediaType.APPLICATION_JSON}) public String getData( @PathParam("objectTypeName") String objectTypeName, @QueryParam("start") long start, @QueryParam("end") long end, @QueryParam("value") String value) { Guest guest = AuthHelper.getGuest(); if (guest == null) return "[]"; CoachingBuddy coachee; try { coachee = AuthHelper.getCoachee(); } catch (CoachRevokedException e) { return gson.toJson( new StatusModel( false, "Sorry, permission to access this data has been revoked. Please reload your browser window")); } if (coachee != null) { guest = guestService.getGuestById(coachee.guestId); } String[] objectTypeNameParts = objectTypeName.split("-"); ApiKey apiKey = guestService .getApiKeys(guest.getId(), Connector.getConnector(objectTypeNameParts[0])) .get(0); Connector connector = apiKey.getConnector(); final AbstractBodytrackResponder bodytrackResponder = connector.getBodytrackResponder(beanFactory); return gson.toJson( bodytrackResponder.getFacetVOs( settingsService.getSettings(guest.getId()), apiKey, objectTypeName, start, end, value)); }
private Calendar getCalendar(final ApiKey apiKey) throws UpdateFailedException { HttpTransport httpTransport = new NetHttpTransport(); JacksonFactory jsonFactory = new JacksonFactory(); // Get all the attributes for this connector's oauth token from the stored attributes final String accessToken = guestService.getApiKeyAttribute(apiKey, "accessToken"); final String refreshToken = guestService.getApiKeyAttribute(apiKey, "refreshToken"); final String clientId = guestService.getApiKeyAttribute(apiKey, "google.client.id"); final String clientSecret = guestService.getApiKeyAttribute(apiKey, "google.client.secret"); final GoogleCredential.Builder builder = new GoogleCredential.Builder(); builder.setTransport(httpTransport); builder.setJsonFactory(jsonFactory); builder.setClientSecrets(clientId, clientSecret); GoogleCredential credential = builder.build(); final Long tokenExpires = Long.valueOf(guestService.getApiKeyAttribute(apiKey, "tokenExpires")); credential.setExpirationTimeMilliseconds(tokenExpires); credential.setAccessToken(accessToken); credential.setRefreshToken(refreshToken); try { if (tokenExpires < System.currentTimeMillis()) { boolean tokenRefreshed = false; // Don't worry about checking if we are running on a mirrored test instance. // Refreshing tokens independently on both the main server and a mirrored instance // seems to work just fine. // Try to swap the expired access token for a fresh one. tokenRefreshed = credential.refreshToken(); if (tokenRefreshed) { Long newExpireTime = credential.getExpirationTimeMilliseconds(); logger.info( "google calendar token has been refreshed, new expire time = " + newExpireTime); // Update stored expire time guestService.setApiKeyAttribute(apiKey, "accessToken", credential.getAccessToken()); guestService.setApiKeyAttribute(apiKey, "tokenExpires", newExpireTime.toString()); } } } catch (TokenResponseException e) { logger.warn( "module=GoogleCalendarUpdater component=background_updates action=refreshToken" + " connector=" + apiKey.getConnector().getName() + " guestId=" + apiKey.getGuestId() + " status=permanently failed"); // Notify the user that the tokens need to be manually renewed notificationsService.addNamedNotification( apiKey.getGuestId(), Notification.Type.WARNING, connector().statusNotificationName(), "Heads Up. We failed in our attempt to automatically refresh your Google Calendar authentication tokens.<br>" + "Please head to <a href=\"javascript:App.manageConnectors()\">Manage Connectors</a>,<br>" + "scroll to the Google Calendar connector, and renew your tokens (look for the <i class=\"icon-resize-small icon-large\"></i> icon)"); // Record permanent update failure since this connector is never // going to succeed guestService.setApiKeyStatus( apiKey.getId(), ApiKey.Status.STATUS_PERMANENT_FAILURE, Utils.stackTrace(e)); throw new UpdateFailedException( "refresh token attempt permanently failed due to a bad token refresh response", e, true); } catch (IOException e) { logger.warn( "module=GoogleCalendarUpdater component=background_updates action=refreshToken" + " connector=" + apiKey.getConnector().getName() + " guestId=" + apiKey.getGuestId() + " status=temporarily failed"); // Notify the user that the tokens need to be manually renewed throw new UpdateFailedException("refresh token attempt failed", e, true); } final Calendar.Builder calendarBuilder = new Calendar.Builder(httpTransport, jsonFactory, credential); final Calendar calendar = calendarBuilder.build(); return calendar; }