Skip to content

Instantly share code, notes, and snippets.

@NSergeyI
Created August 14, 2019 09:29
Show Gist options
  • Save NSergeyI/389fa45fd1d876c1bdf4cc5de11ad83d to your computer and use it in GitHub Desktop.
Save NSergeyI/389fa45fd1d876c1bdf4cc5de11ad83d to your computer and use it in GitHub Desktop.
CredManager
package server.auth;
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.auth.oauth2.DataStoreCredentialRefreshListener;
import com.google.api.client.auth.oauth2.StoredCredential;
import com.google.api.client.extensions.appengine.datastore.AppEngineDataStoreFactory;
import com.google.api.client.googleapis.auth.oauth2.*;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.util.store.DataStore;
import com.google.api.services.admin.directory.DirectoryScopes;
import com.google.api.services.drive.DriveScopes;
import com.google.api.services.gmail.Gmail;
import com.google.api.services.gmail.GmailScopes;
import com.google.api.services.oauth2.Oauth2Scopes;
import domain.AppUser;
import java.io.*;
import java.net.URISyntaxException;
import java.security.GeneralSecurityException;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import server.utils.ServerUtils;
public class CredentialManager {
public static final HttpTransport TRANSPORT = new NetHttpTransport();
public static final JsonFactory JSON_FACTORY = new JacksonFactory();
public static final String APPLICATION_NAME = "abuse-guard";
public static final String CLIENT_SECRETS_FILE_PRODUCTION_PATH = "client_secrets.json";
public static final String CLIENT_SECRETS_FILE_DEVELOPMENT_PATH = "client_secrets_dev.json";
public static final List<String> SCOPES =
Arrays.asList("openid", Oauth2Scopes.USERINFO_EMAIL, Oauth2Scopes.USERINFO_PROFILE);
private static final Collection<String> SCOPES_FOR_SEND_EMAILS =
Arrays.asList(GmailScopes.GMAIL_SEND);
private static final Collection<String> SCOPES_FOR_READ_EMAILS =
Arrays.asList(GmailScopes.GMAIL_READONLY);
// TODO: add later
private static final String SERVICE_ACCOUNT_EMAIL = "";
private static final String SERVICE_ACCOUNT_PKC12_FILE_NAME = "";
private static GoogleClientSecrets clientSecrets;
private static AppEngineDataStoreFactory appEngineDataStoreFactory =
new AppEngineDataStoreFactory();
private static DataStore<StoredCredential> credentialStore;
static {
try {
clientSecrets = getClientSecrets();
credentialStore =
appEngineDataStoreFactory.getDataStore(StoredCredential.DEFAULT_DATA_STORE_ID);
} catch (URISyntaxException | IOException e) {
e.printStackTrace();
}
}
private static Credential buildEmpty() {
return new GoogleCredential.Builder()
.setClientSecrets(clientSecrets)
.setTransport(TRANSPORT)
.setJsonFactory(JSON_FACTORY)
.build();
}
public static Credential getCredential(Long id) throws IOException {
if (id == null) {
return null;
}
return getCredential(id.toString());
}
public static Credential getCredential(String id) throws IOException {
if (id == null) {
return null;
}
StoredCredential storedCredential = credentialStore.get(id);
if (storedCredential == null) {
return null;
}
return new GoogleCredential.Builder()
.setTransport(TRANSPORT)
.setJsonFactory(JSON_FACTORY)
.setClientSecrets(clientSecrets)
.addRefreshListener(new DataStoreCredentialRefreshListener(id, credentialStore))
.build()
.setAccessToken(storedCredential.getAccessToken())
.setRefreshToken(storedCredential.getRefreshToken())
.setExpirationTimeMilliseconds(storedCredential.getExpirationTimeMilliseconds());
}
public static void saveCredential(String userId, Credential credential) throws IOException {
StoredCredential storedCredential = credentialStore.get(userId);
if (storedCredential == null) {
storedCredential = new StoredCredential(credential);
} else {
storedCredential.setAccessToken(credential.getAccessToken());
storedCredential.setExpirationTimeMilliseconds(credential.getExpirationTimeMilliseconds());
if (credential.getRefreshListeners() != null) {
storedCredential.setRefreshToken(credential.getRefreshToken());
}
}
credentialStore.set(userId, storedCredential);
}
public void deleteCredential(String userId) throws IOException {
credentialStore.delete(userId);
}
public static String getAuthorizationUrl(boolean needToForce) {
GoogleAuthorizationCodeRequestUrl urlBuilder =
new GoogleAuthorizationCodeRequestUrl(
clientSecrets.getWeb().getClientId(),
clientSecrets.getWeb().getRedirectUris().get(0),
SCOPES)
.setApprovalPrompt(needToForce ? "force" : "auto")
.setAccessType("offline");
return urlBuilder.build();
}
public static Credential retrieveCredential(String code) {
try {
GoogleTokenResponse response =
new GoogleAuthorizationCodeTokenRequest(
TRANSPORT,
JSON_FACTORY,
clientSecrets.getWeb().getClientId(),
clientSecrets.getWeb().getClientSecret(),
code,
clientSecrets.getWeb().getRedirectUris().get(0))
.execute();
Credential credential =
buildEmpty()
.setAccessToken(response.getAccessToken())
.setExpirationTimeMilliseconds(response.getExpiresInSeconds())
.setRefreshToken(response.getRefreshToken());
return credential;
} catch (IOException e) {
new RuntimeException("An unknown problem occured while retrieving token");
}
return null;
}
private static GoogleClientSecrets getClientSecrets()
throws URISyntaxException, FileNotFoundException {
String fileName =
ServerUtils.isProduction()
? CLIENT_SECRETS_FILE_PRODUCTION_PATH
: CLIENT_SECRETS_FILE_DEVELOPMENT_PATH;
System.out.println(
"File name = " + AbstractAuthServlet.class.getResource("/" + fileName).toURI());
InputStreamReader streamReader =
new InputStreamReader(
new FileInputStream(
new File(AbstractAuthServlet.class.getResource("/" + fileName).toURI())));
try {
return GoogleClientSecrets.load(JSON_FACTORY, streamReader);
} catch (IOException e) {
throw new RuntimeException("No client_secrets.json found");
}
}
public static GoogleCredential getServiceAccountCredential(String userEmail)
throws GeneralSecurityException, IOException, URISyntaxException {
GoogleCredential credential =
new GoogleCredential.Builder()
.setTransport(TRANSPORT)
.setJsonFactory(JSON_FACTORY)
.setServiceAccountId(SERVICE_ACCOUNT_EMAIL)
.setServiceAccountScopes(
Arrays.asList(
DriveScopes.DRIVE,
DirectoryScopes.ADMIN_DIRECTORY_USER,
DirectoryScopes.ADMIN_DIRECTORY_ORGUNIT))
.setServiceAccountUser(userEmail)
.setServiceAccountPrivateKeyFromP12File(
new File(
AbstractAuthServlet.class
.getResource("/" + SERVICE_ACCOUNT_PKC12_FILE_NAME)
.toURI()))
.build();
return credential;
}
public static Gmail buildGmailService(AppUser user) throws IOException {
return new Gmail.Builder(TRANSPORT, JSON_FACTORY, getCredential(user.getId()))
.setApplicationName(APPLICATION_NAME)
.build();
}
public static String getAuthorizationUrlForSendEmail(boolean needToForce) {
GoogleAuthorizationCodeRequestUrl urlBuilder =
new GoogleAuthorizationCodeRequestUrl(
clientSecrets.getWeb().getClientId(),
clientSecrets.getWeb().getRedirectUris().get(0),
SCOPES_FOR_SEND_EMAILS)
.setApprovalPrompt(needToForce ? "force" : "auto")
.setAccessType("offline")
.set("include_granted_scopes", true);
return urlBuilder.build();
}
public static String getAuthorizationUrlForReadEmail(boolean needToForce) {
GoogleAuthorizationCodeRequestUrl urlBuilder =
new GoogleAuthorizationCodeRequestUrl(
clientSecrets.getWeb().getClientId(),
clientSecrets.getWeb().getRedirectUris().get(0),
SCOPES_FOR_READ_EMAILS)
.setApprovalPrompt(needToForce ? "force" : "auto")
.setAccessType("offline")
.set("include_granted_scopes", true);
return urlBuilder.build();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment