
com.threewks.spring.gmail.GmailAdminController Maven / Gradle / Ivy
Show all versions of spring-gae-gmail Show documentation
package com.threewks.spring.gmail;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
import com.google.api.client.googleapis.auth.oauth2.GoogleTokenResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.view.RedirectView;
import java.io.IOException;
import static java.util.Arrays.asList;
import static org.springframework.web.bind.annotation.RequestMethod.GET;
@Controller
@RequestMapping("${gmail.AdminRootPath:/system/gmail}")
public class GmailAdminController {
private static final Logger LOGGER = LoggerFactory.getLogger(GmailSender.class);
private final GoogleAuthorizationCodeFlow flow;
private final String callbackUrl;
public GmailAdminController(GoogleAuthorizationCodeFlow gmailAuthorizationCodeFlow, String host, String adminRootPath) {
this.flow = gmailAuthorizationCodeFlow;
this.callbackUrl = String.format("%s%s", host, String.format("%s/setup/oauth2callback", adminRootPath));
}
/**
* Starts the OAuth process and redirects user to googles permission page with access type offline and force approval prompt
*
* @param credentialId the id that will be saved on the {@link com.google.api.client.auth.oauth2.StoredCredential} object. If not provided we
* default the id to {@link GmailSender#CREDENTIAL_USER_ID}. To handle multiple credentials to google you should pass
* in unique credentialIds.
* @return the redirect url which is page that prompts you for google account details.
*/
@RequestMapping(method = GET, path = "/setup")
public RedirectView setup(@RequestParam(required = false) String credentialId) {
String callBackUrlWithParams = addQueryParamCredential(callbackUrl, credentialId);
String url = flow.newAuthorizationUrl()
.setRedirectUri(callBackUrlWithParams)
.setResponseTypes(asList("code"))
.setAccessType("offline")
.setApprovalPrompt("force")
.build();
return new RedirectView(url);
}
private String addQueryParamCredential(String callbackUrl, String credentialId) {
return StringUtils.isEmpty(credentialId) ?
callbackUrl :
String.format("%s?credentialId=%s", callbackUrl, credentialId);
}
/**
* Endpoint for google to call back to once authentication has been verified.
* This requires the callback to be defined in Google API Console under the Authorized redirect URIs
* otherwise google will not be able to redirect back this endpoint
*
* If using credentialId you will need to make sure your callbackUrl and credentialId=paramValue is included.
* otherwise it won't match.
*
* @param code the oauth callback code
* @param credentialId the credential ID
* @return a string view indicating successful setup
* @throws IOException if there is a problem retrieving or storing the credentials
*/
@RequestMapping(method = GET, path = "/setup/oauth2callback")
@ResponseBody
public String oauthCallback(@RequestParam String code, @RequestParam(required = false) String credentialId) throws IOException {
LOGGER.info("credentialId %s and code %s", credentialId, code);
String callBackUrlWithCredentialId = StringUtils.isEmpty(credentialId) ?
callbackUrl:
addQueryParamCredential(callbackUrl, credentialId);
GoogleTokenResponse tokenResponse = flow.newTokenRequest(code)
.setRedirectUri(callBackUrlWithCredentialId)
.execute();
credentialId = (StringUtils.isEmpty(credentialId) ?
GmailSender.CREDENTIAL_USER_ID : credentialId).toLowerCase();
flow.createAndStoreCredential(tokenResponse, credentialId);
return "Gmail setup complete";
}
}