
com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow Maven / Gradle / Ivy
/*
* Copyright (c) 2012 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.api.client.googleapis.auth.oauth2;
import com.google.api.client.auth.oauth2.AuthorizationCodeFlow;
import com.google.api.client.auth.oauth2.BearerToken;
import com.google.api.client.auth.oauth2.ClientParametersAuthentication;
import com.google.api.client.auth.oauth2.Credential.AccessMethod;
import com.google.api.client.auth.oauth2.CredentialRefreshListener;
import com.google.api.client.auth.oauth2.CredentialStore;
import com.google.api.client.auth.oauth2.StoredCredential;
import com.google.api.client.auth.oauth2.TokenResponse;
import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpExecuteInterceptor;
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.util.Beta;
import com.google.api.client.util.Clock;
import com.google.api.client.util.Preconditions;
import com.google.api.client.util.store.DataStore;
import com.google.api.client.util.store.DataStoreFactory;
import java.io.IOException;
import java.util.Collection;
/**
* Thread-safe Google OAuth 2.0 authorization code flow that manages and persists end-user
* credentials.
*
*
* This is designed to simplify the flow in which an end-user authorizes the application to access
* their protected data, and then the application has access to their data based on an access token
* and a refresh token to refresh that access token when it expires.
*
*
*
* The first step is to call {@link #loadCredential(String)} based on the known user ID to check if
* the end-user's credentials are already known. If not, call {@link #newAuthorizationUrl()} and
* direct the end-user's browser to an authorization page. The web browser will then redirect to the
* redirect URL with a {@code "code"} query parameter which can then be used to request an access
* token using {@link #newTokenRequest(String)}. Finally, use
* {@link #createAndStoreCredential(TokenResponse, String)} to store and obtain a credential for
* accessing protected resources.
*
*
*
* The default for the {@code approval_prompt} and {@code access_type} parameters is {@code null}.
* For web applications that means {@code "approval_prompt=auto&access_type=online"} and for
* installed applications that means {@code "approval_prompt=force&access_type=offline"}. To
* override the default, you need to explicitly call {@link Builder#setApprovalPrompt(String)} and
* {@link Builder#setAccessType(String)}.
*
*
* @author Yaniv Inbar
* @since 1.7
*/
@SuppressWarnings("deprecation")
public class GoogleAuthorizationCodeFlow extends AuthorizationCodeFlow {
/**
* Prompt for consent behavior ({@code "auto"} to request auto-approval or {@code "force"} to
* force the approval UI to show) or {@code null} for the default behavior.
*/
private final String approvalPrompt;
/**
* Access type ({@code "online"} to request online access or {@code "offline"} to request offline
* access) or {@code null} for the default behavior.
*/
private final String accessType;
/**
* @param transport HTTP transport
* @param jsonFactory JSON factory
* @param clientId client identifier
* @param clientSecret client secret
* @param scopes collection of scopes to be joined by a space separator
*
* @since 1.15
*/
public GoogleAuthorizationCodeFlow(HttpTransport transport, JsonFactory jsonFactory,
String clientId, String clientSecret, Collection scopes) {
this(new Builder(transport, jsonFactory, clientId, clientSecret, scopes));
}
/**
* @param builder Google authorization code flow builder
*
* @since 1.14
*/
protected GoogleAuthorizationCodeFlow(Builder builder) {
super(builder);
accessType = builder.accessType;
approvalPrompt = builder.approvalPrompt;
}
@Override
public GoogleAuthorizationCodeTokenRequest newTokenRequest(String authorizationCode) {
// don't need to specify clientId & clientSecret because specifying clientAuthentication
// don't want to specify redirectUri to give control of it to user of this class
return new GoogleAuthorizationCodeTokenRequest(getTransport(), getJsonFactory(),
getTokenServerEncodedUrl(), "", "", authorizationCode, "").setClientAuthentication(
getClientAuthentication())
.setRequestInitializer(getRequestInitializer()).setScopes(getScopes());
}
@Override
public GoogleAuthorizationCodeRequestUrl newAuthorizationUrl() {
// don't want to specify redirectUri to give control of it to user of this class
return new GoogleAuthorizationCodeRequestUrl(
getAuthorizationServerEncodedUrl(), getClientId(), "", getScopes()).setAccessType(
accessType).setApprovalPrompt(approvalPrompt);
}
/**
* Returns the approval prompt behavior ({@code "auto"} to request auto-approval or
* {@code "force"} to force the approval UI to show) or {@code null} for the default behavior of
* {@code "auto"}.
*/
public final String getApprovalPrompt() {
return approvalPrompt;
}
/**
* Returns the access type ({@code "online"} to request online access or {@code "offline"} to
* request offline access) or {@code null} for the default behavior of {@code "online"}.
*/
public final String getAccessType() {
return accessType;
}
/**
* Google authorization code flow builder.
*
*
* Implementation is not thread-safe.
*
*/
public static class Builder extends AuthorizationCodeFlow.Builder {
/**
* Prompt for consent behavior ({@code "auto"} to request auto-approval or {@code "force"} to
* force the approval UI to show) or {@code null} for the default behavior.
*/
String approvalPrompt;
/**
* Access type ({@code "online"} to request online access or {@code "offline"} to request
* offline access) or {@code null} for the default behavior.
*/
String accessType;
/**
*
* @param transport HTTP transport
* @param jsonFactory JSON factory
* @param clientId client identifier
* @param clientSecret client secret
* @param scopes collection of scopes to be joined by a space separator (or a single value
* containing multiple space-separated scopes)
*
* @since 1.15
*/
public Builder(HttpTransport transport, JsonFactory jsonFactory, String clientId,
String clientSecret, Collection scopes) {
super(BearerToken.authorizationHeaderAccessMethod(), transport, jsonFactory, new GenericUrl(
GoogleOAuthConstants.TOKEN_SERVER_URL), new ClientParametersAuthentication(
clientId, clientSecret), clientId, GoogleOAuthConstants.AUTHORIZATION_SERVER_URL);
setScopes(scopes);
}
/**
* @param transport HTTP transport
* @param jsonFactory JSON factory
* @param clientSecrets Google client secrets
* @param scopes collection of scopes to be joined by a space separator
*
* @since 1.15
*/
public Builder(HttpTransport transport, JsonFactory jsonFactory,
GoogleClientSecrets clientSecrets, Collection scopes) {
super(BearerToken.authorizationHeaderAccessMethod(), transport, jsonFactory, new GenericUrl(
GoogleOAuthConstants.TOKEN_SERVER_URL), new ClientParametersAuthentication(
clientSecrets.getDetails().getClientId(), clientSecrets.getDetails().getClientSecret()),
clientSecrets.getDetails().getClientId(), GoogleOAuthConstants.AUTHORIZATION_SERVER_URL);
setScopes(scopes);
}
@Override
public GoogleAuthorizationCodeFlow build() {
return new GoogleAuthorizationCodeFlow(this);
}
@Override
public Builder setDataStoreFactory(DataStoreFactory dataStore) throws IOException {
return (Builder) super.setDataStoreFactory(dataStore);
}
@Override
public Builder setCredentialDataStore(DataStore typedDataStore) {
return (Builder) super.setCredentialDataStore(typedDataStore);
}
@Override
public Builder setCredentialCreatedListener(
CredentialCreatedListener credentialCreatedListener) {
return (Builder) super.setCredentialCreatedListener(credentialCreatedListener);
}
@Beta
@Override
@Deprecated
public Builder setCredentialStore(CredentialStore credentialStore) {
return (Builder) super.setCredentialStore(credentialStore);
}
@Override
public Builder setRequestInitializer(HttpRequestInitializer requestInitializer) {
return (Builder) super.setRequestInitializer(requestInitializer);
}
@Override
public Builder setScopes(Collection scopes) {
Preconditions.checkState(!scopes.isEmpty());
return (Builder) super.setScopes(scopes);
}
/**
* @since 1.11
*/
@Override
public Builder setMethod(AccessMethod method) {
return (Builder) super.setMethod(method);
}
/**
* @since 1.11
*/
@Override
public Builder setTransport(HttpTransport transport) {
return (Builder) super.setTransport(transport);
}
/**
* @since 1.11
*/
@Override
public Builder setJsonFactory(JsonFactory jsonFactory) {
return (Builder) super.setJsonFactory(jsonFactory);
}
/**
* @since 1.11
*/
@Override
public Builder setTokenServerUrl(GenericUrl tokenServerUrl) {
return (Builder) super.setTokenServerUrl(tokenServerUrl);
}
/**
* @since 1.11
*/
@Override
public Builder setClientAuthentication(HttpExecuteInterceptor clientAuthentication) {
return (Builder) super.setClientAuthentication(clientAuthentication);
}
/**
* @since 1.11
*/
@Override
public Builder setClientId(String clientId) {
return (Builder) super.setClientId(clientId);
}
/**
* @since 1.11
*/
@Override
public Builder setAuthorizationServerEncodedUrl(String authorizationServerEncodedUrl) {
return (Builder) super.setAuthorizationServerEncodedUrl(authorizationServerEncodedUrl);
}
/**
* @since 1.11
*/
@Override
public Builder setClock(Clock clock) {
return (Builder) super.setClock(clock);
}
@Override
public Builder addRefreshListener(CredentialRefreshListener refreshListener) {
return (Builder) super.addRefreshListener(refreshListener);
}
@Override
public Builder setRefreshListeners(Collection refreshListeners) {
return (Builder) super.setRefreshListeners(refreshListeners);
}
/**
* Sets the approval prompt behavior ({@code "auto"} to request auto-approval or {@code "force"}
* to force the approval UI to show) or {@code null} for the default behavior ({@code "auto"}
* for web applications and {@code "force"} for installed applications).
*
*
* By default this has the value {@code null}.
*
*
*
* Overriding is only supported for the purpose of calling the super implementation and changing
* the return type, but nothing else.
*
*/
public Builder setApprovalPrompt(String approvalPrompt) {
this.approvalPrompt = approvalPrompt;
return this;
}
/**
* Returns the approval prompt behavior ({@code "auto"} to request auto-approval or
* {@code "force"} to force the approval UI to show) or {@code null} for the default behavior of
* {@code "auto"}.
*/
public final String getApprovalPrompt() {
return approvalPrompt;
}
/**
* Sets the access type ({@code "online"} to request online access or {@code "offline"} to
* request offline access) or {@code null} for the default behavior ({@code "online"} for web
* applications and {@code "offline"} for installed applications).
*
*
* By default this has the value {@code null}.
*
*
*
* Overriding is only supported for the purpose of calling the super implementation and changing
* the return type, but nothing else.
*
*/
public Builder setAccessType(String accessType) {
this.accessType = accessType;
return this;
}
/**
* Returns the access type ({@code "online"} to request online access or {@code "offline"} to
* request offline access) or {@code null} for the default behavior of {@code "online"}.
*/
public final String getAccessType() {
return accessType;
}
}
}