Esempio n. 1
0
 @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();
 }
Esempio n. 2
0
 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;
 }
Esempio n. 3
0
 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;
 }
Esempio n. 4
0
 @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);
 }
Esempio n. 5
0
  @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;
  }