token = JSONObject.fromObject(fetched);
} catch(Throwable e) {
token = null;
}
ApiKey apiKey;
final boolean isRenewToken = request.getSession().getAttribute(APIKEYID_ATTRIBUTE) != null;
if (isRenewToken) {
String apiKeyId = (String)request.getSession().getAttribute(APIKEYID_ATTRIBUTE);
apiKey = guestService.getApiKey(Long.valueOf(apiKeyId));
if (apiKey==null) {
Exception e = new Exception();
String stackTrace = ExceptionUtils.getStackTrace(e);
String errorMessage = "no apiKey with id '%s'... It looks like you are trying to renew the tokens of a non-existing Connector (/ApiKey)";
return errorController.handleError(500, errorMessage, stackTrace);
}
if (token == null || !token.has("refresh_token")) {
String message = (new StringBuilder("<p>We couldn't get your oauth2 refresh token. "))
.append("Something went wrong.</p>")
.append("<p>You'll have to surf to your ")
.append("<a target='_new' href='https://accounts.google.com/b/0/IssuedAuthSubTokens'>token mgmt page at Google</a> ")
.append("and hit \"Revoke Access\" next to \"").append(brandName).append(" — ").append(getGooglePrettyName(scopedApi)).append("\"</p>")
.append("<p>Then please, head to <a href=\"javascript:App.manageConnectors()\">Manage Connectors</a> ")
.append("and renew your tokens (look for the <i class=\"icon-resize-small icon-large\"></i> icon)</p>")
.append("<p>We apologize for the inconvenience</p>").toString();
notificationsService.addNamedNotification(guest.getId(),
Notification.Type.ERROR,
apiKey.getConnector().statusNotificationName(),
message);
// Record permanent failure since this connector won't work again until
// it is reauthenticated
guestService.setApiKeyStatus(apiKey.getId(), ApiKey.Status.STATUS_PERMANENT_FAILURE, null, ApiKey.PermanentFailReason.NEEDS_REAUTH);
return new ModelAndView("redirect:/app");
}
// Remove oauth1 keys if upgrading from previous connector version.
// Remember whether or not we're upgrading from previous connector version.
// If so, do a full history update. Otherwise don't force a full
// history update and allow the update to be whatever it normally would be
boolean upgradeFromOauth1 = false;
if (guestService.getApiKeyAttribute(apiKey, "googleConsumerKey")!=null) {
guestService.removeApiKeyAttribute(apiKey.getId(), "googleConsumerKey");
upgradeFromOauth1 = true;
}
if (guestService.getApiKeyAttribute(apiKey, "googleConsumerSecret")!=null) {
guestService.removeApiKeyAttribute(apiKey.getId(), "googleConsumerSecret");
upgradeFromOauth1 = true;
}
// If upgradeFromOauth1 reset the connector to force a full reimport on google calendar,
// otherwise just do a normal update
if (apiKey.getConnector().getName().equals("google_calendar")) {
connectorUpdateService.flushUpdateWorkerTasks(apiKey, upgradeFromOauth1);
}
} else {
apiKey = guestService.createApiKey(guest.getId(), scopedApi);
}
// We need to store google.client.id and google.client.secret with the
// apiKeyAttributes in either the case of original creation of the key
// or token renewal. createApiKey actually handles the former case, but
// not the latter. Do it in all cases here.
guestService.setApiKeyAttribute(apiKey, "google.client.id", env.get("google.client.id"));
guestService.setApiKeyAttribute(apiKey, "google.client.secret", env.get("google.client.secret"));
final String refresh_token = token.getString("refresh_token");
guestService.setApiKeyAttribute(apiKey,
"accessToken", token.getString("access_token"));
guestService.setApiKeyAttribute(apiKey,
"tokenExpires", String.valueOf(System.currentTimeMillis() + (token.getLong("expires_in")*1000)));
guestService.setApiKeyAttribute(apiKey,
"refreshToken", refresh_token);
final String encodedRefreshToken = URLEncoder.encode(refresh_token, "UTF-8");
guestService.setApiKeyAttribute(apiKey,
"refreshTokenRemoveURL",
"https://accounts.google.com/o/oauth2/revoke?token="
+ encodedRefreshToken);
// Record this connector as having status up
guestService.setApiKeyStatus(apiKey.getId(), ApiKey.Status.STATUS_UP, null, null);
// Schedule an update for this connector
connectorUpdateService.updateConnector(apiKey, false);
if (isRenewToken) {
request.getSession().removeAttribute(APIKEYID_ATTRIBUTE);