Package org.fluxtream.connectors.bodymedia

Source Code of org.fluxtream.connectors.bodymedia.BodymediaController

package org.fluxtream.connectors.bodymedia;

import java.io.IOException;
import java.net.URLDecoder;
import java.security.NoSuchAlgorithmException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import org.fluxtream.core.Configuration;
import org.fluxtream.core.auth.AuthHelper;
import org.fluxtream.core.connectors.Connector;
import org.fluxtream.connectors.controllers.ControllerSupport;
import org.fluxtream.core.connectors.updaters.UpdateFailedException;
import org.fluxtream.core.connectors.updaters.UpdateInfo;
import org.fluxtream.core.domain.ApiKey;
import org.fluxtream.core.domain.Guest;
import org.fluxtream.core.domain.Notification;
import org.fluxtream.core.services.ConnectorUpdateService;
import org.fluxtream.core.services.GuestService;
import org.fluxtream.core.services.NotificationsService;
import oauth.signpost.OAuthConsumer;
import oauth.signpost.OAuthProvider;
import oauth.signpost.basic.DefaultOAuthConsumer;
import oauth.signpost.commonshttp.CommonsHttpOAuthProvider;
import oauth.signpost.exception.OAuthCommunicationException;
import oauth.signpost.exception.OAuthExpectationFailedException;
import oauth.signpost.exception.OAuthMessageSignerException;
import oauth.signpost.exception.OAuthNotAuthorizedException;
import oauth.signpost.http.HttpParameters;
import org.apache.http.client.HttpClient;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping(value = "/bodymedia")
public class BodymediaController {

  @Autowired
  GuestService guestService;

  @Autowired
  Configuration env;

    @Autowired
    NotificationsService notificationsService;

    @Autowired
    ConnectorUpdateService connectorUpdateService;

    static final Logger logger = Logger.getLogger(BodymediaController.class);

  private static final String BODYMEDIA_OAUTH_CONSUMER = "bodymediaOAuthConsumer";
  private static final String BODYMEDIA_OAUTH_PROVIDER = "bodymediaOAuthProvider";

  @RequestMapping(value = "/token")
  public String getToken(HttpServletRequest request) throws IOException, ServletException,
      OAuthMessageSignerException, OAuthNotAuthorizedException,
      OAuthExpectationFailedException, OAuthCommunicationException {

    String oauthCallback = ControllerSupport.getLocationBase(request, env) + "bodymedia/upgradeToken";
    if (request.getParameter("guestId") != null)
      oauthCallback += "?guestId=" + request.getParameter("guestId");
        if (request.getParameter("apiKeyId") != null)
            oauthCallback += "?apiKeyId=" + request.getParameter("apiKeyId");

        String apiKey = env.get("bodymediaConsumerKey");
    OAuthConsumer consumer = new DefaultOAuthConsumer(
        apiKey,
        env.get("bodymediaConsumerSecret"));
    HttpParameters additionalParameter = new HttpParameters();
    additionalParameter.put("api_key", apiKey);
    consumer.setAdditionalParameters(additionalParameter);

    HttpClient httpClient = env.getHttpClient();

    OAuthProvider provider = new CommonsHttpOAuthProvider(
        "https://api.bodymedia.com/oauth/request_token?api_key="+apiKey,
        "https://api.bodymedia.com/oauth/access_token?api_key="+apiKey,
        "https://api.bodymedia.com/oauth/authorize?api_key="+apiKey, httpClient);

    request.getSession().setAttribute(BODYMEDIA_OAUTH_CONSUMER, consumer);
    request.getSession().setAttribute(BODYMEDIA_OAUTH_PROVIDER, provider);

        String approvalPageUrl = null;
        try {
            approvalPageUrl = provider.retrieveRequestToken(consumer,
                    oauthCallback);
        } catch (Throwable t) {
            logger.error("Couldn't retrieve BodyMedia request token.");
            t.printStackTrace();
            notificationsService.addNamedNotification(AuthHelper.getGuestId(),
                                                      Notification.Type.ERROR, connector().statusNotificationName(),
                                                      "Oops. There was an error with the BodyMedia API. " +
                                                      "Hang tight, we are working on it.");
            // TODO: Should we record permanent failure since an existing connector won't work again until
            // it is reauthenticated?  We would need to get hold of the apiKey and do:
            //  guestService.setApiKeyStatus(apiKey.getId(), ApiKey.Status.STATUS_PERMANENT_FAILURE, null);

            return "redirect:/app/";
        }
   
    System.out.println("the token secret is: " + consumer.getTokenSecret());
    approvalPageUrl+="&oauth_api=" + apiKey;
    approvalPageUrl = URLDecoder.decode(approvalPageUrl, "UTF-8");

    return "redirect:" + approvalPageUrl;
  }

  @RequestMapping(value = "/upgradeToken")
  public String upgradeToken(HttpServletRequest request) throws NoSuchAlgorithmException, IOException, OAuthMessageSignerException,
      OAuthNotAuthorizedException, OAuthExpectationFailedException,
      OAuthCommunicationException {

    OAuthConsumer consumer = (OAuthConsumer) request.getSession()
        .getAttribute(BODYMEDIA_OAUTH_CONSUMER);
    OAuthProvider provider = (OAuthProvider) request.getSession()
        .getAttribute(BODYMEDIA_OAUTH_PROVIDER);
    String verifier = request.getParameter("oauth_verifier");
    provider.retrieveAccessToken(consumer, verifier);
    Guest guest = AuthHelper.getGuest();

        ApiKey apiKey;
        if (request.getParameter("apiKeyId")!=null) {
            long apiKeyId = Long.valueOf(request.getParameter("apiKeyId"));
            apiKey = guestService.getApiKey(apiKeyId);
        } else
            apiKey = guestService.createApiKey(guest.getId(), connector());

        guestService.setApiKeyAttribute(apiKey, "api_key", env.get("bodymediaConsumerKey"));
    guestService.setApiKeyAttribute(apiKey,
        "accessToken", consumer.getToken());
    guestService.setApiKeyAttribute(apiKey,
        "tokenSecret", consumer.getTokenSecret());
        guestService.setApiKeyAttribute(apiKey,
                "tokenExpiration", provider.getResponseParameters().get("xoauth_token_expiration_time").first());

        // Store the OAuth server keys used for the token upgrade, which are the ones currently in oauth.properties
        // into ApiKeyAttributes.  The values in oauth.properties may change over time, so we need to preserve
        // the values used for the token creation with the ApiKey itself.
        guestService.setApiKeyAttribute(apiKey, "bodymediaConsumerKey", env.get("bodymediaConsumerKey"));
        guestService.setApiKeyAttribute(apiKey, "bodymediaConsumerSecret", env.get("bodymediaConsumerSecret"));

        // If bodymediaRateDelayMs is specified in oauth.properties store it with the attributes
        // This should be 1000/Calls per second for the associated key.  The default is 2 calls per second,
        // which is bodymediaRateDelayMs=500
        String bodymediaRateDelayMs = env.get("bodymediaRateDelayMs");

        if(bodymediaRateDelayMs==null) {
            bodymediaRateDelayMs="500";
        }
        guestService.setApiKeyAttribute(apiKey, "bodymediaRateDelayMs", bodymediaRateDelayMs);

        request.getSession().removeAttribute(BODYMEDIA_OAUTH_CONSUMER);
        request.getSession().removeAttribute(BODYMEDIA_OAUTH_PROVIDER);

        if (request.getParameter("apiKeyId")!=null)
        return "redirect:/app/tokenRenewed/" + connector().getName();
        else
            return "redirect:/app/from/" + connector().getName();
  }

  private Connector connector() {
    return Connector.getConnector("bodymedia");
  }

    public void replaceToken(UpdateInfo updateInfo) throws OAuthExpectationFailedException, OAuthMessageSignerException,
                                                           OAuthCommunicationException, OAuthNotAuthorizedException,
                                                           UpdateFailedException {
        // Check to see if we are running on a mirrored test instance
        // and should therefore refrain from swapping tokens lest we
        // invalidate an existing token instance
        String disableTokenSwap = env.get("disableTokenSwap");
        if(disableTokenSwap!=null && disableTokenSwap.equals("true")) {
            String msg = "**** Skipping refreshToken for bodymedia connector instance because disableTokenSwap is set on this server";
                                            ;
            StringBuilder sb2 = new StringBuilder("module=BodymediaController component=BodymediaController action=replaceToken apiKeyId=" + updateInfo.apiKey.getId())
                      .append(" message=\"").append(msg).append("\"");
            logger.info(sb2.toString());
            System.out.println(msg);

             // Notify the user that the tokens need to be manually renewed
            notificationsService.addNamedNotification(updateInfo.getGuestId(), Notification.Type.WARNING, connector().statusNotificationName(),
                                                      "Heads Up. This server cannot automatically refresh your authentication tokens.<br>" +
                                                      "Please head to <a href=\"javascript:App.manageConnectors()\">Manage Connectors</a>,<br>" +
                                                      "scroll to the BodyMedia connector, and renew your tokens (look for the <i class=\"icon-resize-small icon-large\"></i> icon)");

            // Record permanent failure since this connector won't work again until
            // it is reauthenticated
            guestService.setApiKeyStatus(updateInfo.apiKey.getId(), ApiKey.Status.STATUS_PERMANENT_FAILURE, null, ApiKey.PermanentFailReason.NEEDS_REAUTH);
            throw new UpdateFailedException("requires token reauthorization",true, ApiKey.PermanentFailReason.NEEDS_REAUTH);
        }

        // We're not on a mirrored test server.  Try to swap the expired
        // access token for a fresh one.

        // First, retrieve the OAuth server keys used when this key was created.  These are automatically stored
        // in the ApiKeyAttribute table at the time of creation based on the values present in
        // oauth.properties.
        String bodymediaConsumerKey = guestService.getApiKeyAttribute(updateInfo.apiKey, "bodymediaConsumerKey");
        String bodymediaConsumerSecret = guestService.getApiKeyAttribute(updateInfo.apiKey, "bodymediaConsumerSecret");

        OAuthConsumer consumer = new DefaultOAuthConsumer(
                bodymediaConsumerKey,
                bodymediaConsumerSecret);

        String accessToken = guestService.getApiKeyAttribute(updateInfo.apiKey, "accessToken");
        consumer.setTokenWithSecret(accessToken,
                guestService.getApiKeyAttribute(updateInfo.apiKey, "tokenSecret"));
        HttpParameters additionalParameter = new HttpParameters();
        additionalParameter.put("api_key", bodymediaConsumerKey);
        additionalParameter.put("oauth_token",
                                accessToken);
        consumer.setAdditionalParameters(additionalParameter);

        HttpClient httpClient = env.getHttpClient();

        OAuthProvider provider = new CommonsHttpOAuthProvider(
                "https://api.bodymedia.com/oauth/request_token?api_key="+bodymediaConsumerKey,
                "https://api.bodymedia.com/oauth/access_token?api_key="+bodymediaConsumerKey,
                "https://api.bodymedia.com/oauth/authorize?api_key="+bodymediaConsumerKey, httpClient);

        try {
            provider.retrieveAccessToken(consumer, null);

            guestService.setApiKeyAttribute(updateInfo.apiKey,
                                            "accessToken", consumer.getToken());
            guestService.setApiKeyAttribute(updateInfo.apiKey,
                                            "tokenSecret", consumer.getTokenSecret());
            guestService.setApiKeyAttribute(updateInfo.apiKey,
                                            "tokenExpiration", provider.getResponseParameters().get("xoauth_token_expiration_time").first());

            // Record this connector as having status up
            guestService.setApiKeyStatus(updateInfo.apiKey.getId(), ApiKey.Status.STATUS_UP, null, null);
            // Schedule an update for this connector
            connectorUpdateService.updateConnector(updateInfo.apiKey, false);

        } catch (Throwable t) {
            // Notify the user that the tokens need to be manually renewed
            notificationsService.addNamedNotification(updateInfo.getGuestId(), Notification.Type.WARNING, connector().statusNotificationName(),
                                                      "Heads Up. We failed in our attempt to automatically refresh your authentication tokens.<br>" +
                                                      "Please head to <a href=\"javascript:App.manageConnectors()\">Manage Connectors</a>,<br>" +
                                                      "scroll to the BodyMedia connector, and renew your tokens (look for the <i class=\"icon-resize-small icon-large\"></i> icon)");
            // Record permanent failure since this connector won't work again until
            // it is reauthenticated
            guestService.setApiKeyStatus(updateInfo.apiKey.getId(), ApiKey.Status.STATUS_PERMANENT_FAILURE, null, ApiKey.PermanentFailReason.NEEDS_REAUTH);
            throw new UpdateFailedException("refresh token attempt failed", t, true, ApiKey.PermanentFailReason.NEEDS_REAUTH);
        }
    }
}
TOP

Related Classes of org.fluxtream.connectors.bodymedia.BodymediaController

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.