• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2021 Google LLC
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  *    * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *    * Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *
15  *    * Neither the name of Google LLC nor the names of its
16  * contributors may be used to endorse or promote products derived from
17  * this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 package com.google.auth.oauth2;
33 
34 import static com.google.common.base.Preconditions.checkNotNull;
35 
36 import com.google.errorprone.annotations.CanIgnoreReturnValue;
37 import java.io.IOException;
38 
39 /**
40  * A refreshable alternative to {@link OAuth2Credentials}.
41  *
42  * <p>To enable automatic token refreshes, you must provide an {@link OAuth2RefreshHandler}.
43  */
44 public class OAuth2CredentialsWithRefresh extends OAuth2Credentials {
45 
46   /** Interface for the refresh handler. */
47   public interface OAuth2RefreshHandler {
refreshAccessToken()48     AccessToken refreshAccessToken() throws IOException;
49   }
50 
51   private final OAuth2RefreshHandler refreshHandler;
52 
OAuth2CredentialsWithRefresh(Builder builder)53   protected OAuth2CredentialsWithRefresh(Builder builder) {
54     super(builder.getAccessToken(), builder.getRefreshMargin(), builder.getExpirationMargin());
55     // An expiration time must be provided.
56     if (builder.getAccessToken() != null && builder.getAccessToken().getExpirationTime() == null) {
57       throw new IllegalArgumentException(
58           "The provided access token must contain the expiration time.");
59     }
60     this.refreshHandler = checkNotNull(builder.refreshHandler);
61   }
62 
OAuth2CredentialsWithRefresh( AccessToken accessToken, OAuth2RefreshHandler refreshHandler)63   protected OAuth2CredentialsWithRefresh(
64       AccessToken accessToken, OAuth2RefreshHandler refreshHandler) {
65     super(accessToken);
66 
67     // If no expirationTime is provided, the token will never be refreshed.
68     if (accessToken != null && accessToken.getExpirationTime() == null) {
69       throw new IllegalArgumentException(
70           "The provided access token must contain the expiration time.");
71     }
72 
73     this.refreshHandler = checkNotNull(refreshHandler);
74   }
75 
76   /** Refreshes the access token using the provided {@link OAuth2RefreshHandler}. */
77   @Override
refreshAccessToken()78   public AccessToken refreshAccessToken() throws IOException {
79     // Delegate refresh to the provided refresh handler.
80     return refreshHandler.refreshAccessToken();
81   }
82 
83   /** Returns the provided {@link OAuth2RefreshHandler}. */
getRefreshHandler()84   public OAuth2RefreshHandler getRefreshHandler() {
85     return refreshHandler;
86   }
87 
newBuilder()88   public static Builder newBuilder() {
89     return new Builder();
90   }
91 
92   public static class Builder extends OAuth2Credentials.Builder {
93 
94     private OAuth2RefreshHandler refreshHandler;
95 
Builder()96     private Builder() {}
97 
98     /**
99      * Sets the {@link AccessToken} to be consumed. It must contain an expiration time otherwise an
100      * {@link IllegalArgumentException} will be thrown.
101      */
102     @Override
103     @CanIgnoreReturnValue
setAccessToken(AccessToken token)104     public Builder setAccessToken(AccessToken token) {
105       super.setAccessToken(token);
106       return this;
107     }
108 
109     /** Sets the {@link OAuth2RefreshHandler} to be used for token refreshes. */
110     @CanIgnoreReturnValue
setRefreshHandler(OAuth2RefreshHandler handler)111     public Builder setRefreshHandler(OAuth2RefreshHandler handler) {
112       this.refreshHandler = handler;
113       return this;
114     }
115 
116     @Override
build()117     public OAuth2CredentialsWithRefresh build() {
118       return new OAuth2CredentialsWithRefresh(this);
119     }
120   }
121 }
122