github.com/phrase/openapi@v0.0.0-20240514140800-49e8a106740e/openapi-generator/templates/java/libraries/feign/auth/OAuth.mustache (about)

     1  package {{invokerPackage}}.auth;
     2  
     3  import java.io.IOException;
     4  import java.util.Collection;
     5  import java.util.Map;
     6  import java.util.Map.Entry;
     7  
     8  import org.apache.oltu.oauth2.client.HttpClient;
     9  import org.apache.oltu.oauth2.client.OAuthClient;
    10  import org.apache.oltu.oauth2.client.request.OAuthClientRequest;
    11  import org.apache.oltu.oauth2.client.request.OAuthClientRequest.AuthenticationRequestBuilder;
    12  import org.apache.oltu.oauth2.client.request.OAuthClientRequest.TokenRequestBuilder;
    13  import org.apache.oltu.oauth2.client.response.OAuthClientResponse;
    14  import org.apache.oltu.oauth2.client.response.OAuthClientResponseFactory;
    15  import org.apache.oltu.oauth2.client.response.OAuthJSONAccessTokenResponse;
    16  import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
    17  import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
    18  import org.apache.oltu.oauth2.common.message.types.GrantType;
    19  import org.apache.oltu.oauth2.common.token.BasicOAuthToken;
    20  
    21  import feign.Client;
    22  {{#useFeign10}}
    23  import feign.Request.HttpMethod;
    24  {{/useFeign10}}
    25  import feign.Request.Options;
    26  import feign.RequestInterceptor;
    27  import feign.RequestTemplate;
    28  import feign.Response;
    29  import feign.RetryableException;
    30  import feign.Util;
    31  import {{invokerPackage}}.StringUtil;
    32  
    33  
    34  public class OAuth implements RequestInterceptor {
    35  
    36      static final int MILLIS_PER_SECOND = 1000;
    37  
    38      public interface AccessTokenListener {
    39          void notify(BasicOAuthToken token);
    40      }
    41  
    42      private volatile String accessToken;
    43      private Long expirationTimeMillis;
    44      private OAuthClient oauthClient;
    45      private TokenRequestBuilder tokenRequestBuilder;
    46      private AuthenticationRequestBuilder authenticationRequestBuilder;
    47      private AccessTokenListener accessTokenListener;
    48  
    49      public OAuth(Client client, TokenRequestBuilder requestBuilder) {
    50          this.oauthClient = new OAuthClient(new OAuthFeignClient(client));
    51          this.tokenRequestBuilder = requestBuilder;
    52      }
    53  
    54      public OAuth(Client client, OAuthFlow flow, String authorizationUrl, String tokenUrl, String scopes) {
    55          this(client, OAuthClientRequest.tokenLocation(tokenUrl).setScope(scopes));
    56  
    57          switch(flow) {
    58          case accessCode:
    59          case implicit:
    60              tokenRequestBuilder.setGrantType(GrantType.AUTHORIZATION_CODE);
    61              break;
    62          case password:
    63              tokenRequestBuilder.setGrantType(GrantType.PASSWORD);
    64              break;
    65          case application:
    66              tokenRequestBuilder.setGrantType(GrantType.CLIENT_CREDENTIALS);
    67              break;
    68          default:
    69              break;
    70          }
    71          authenticationRequestBuilder = OAuthClientRequest.authorizationLocation(authorizationUrl);
    72      }
    73  
    74      public OAuth(OAuthFlow flow, String authorizationUrl, String tokenUrl, String scopes) {
    75          this(new Client.Default(null, null), flow, authorizationUrl, tokenUrl, scopes);
    76      }
    77  
    78      @Override
    79      public void apply(RequestTemplate template) {
    80          // If the request already have an authorization (eg. Basic auth), do nothing
    81          if (template.headers().containsKey("Authorization")) {
    82              return;
    83          }
    84          // If first time, get the token
    85          if (expirationTimeMillis == null || System.currentTimeMillis() >= expirationTimeMillis) {
    86              updateAccessToken(template);
    87          }
    88          if (getAccessToken() != null) {
    89              template.header("Authorization", "Bearer " + getAccessToken());
    90          }
    91      }
    92  
    93      public synchronized void updateAccessToken(RequestTemplate template) {
    94          OAuthJSONAccessTokenResponse accessTokenResponse;
    95          try {
    96              accessTokenResponse = oauthClient.accessToken(tokenRequestBuilder.buildBodyMessage());
    97          } catch (Exception e) {
    98              {{#useFeign10}}
    99              throw new RetryableException(0, e.getMessage(), HttpMethod.POST, e, null, template.request());
   100              {{/useFeign10}}
   101              {{^useFeign10}}
   102              throw new RetryableException(e.getMessage(), e,null);
   103              {{/useFeign10}}
   104          }
   105          if (accessTokenResponse != null && accessTokenResponse.getAccessToken() != null) {
   106              setAccessToken(accessTokenResponse.getAccessToken(), accessTokenResponse.getExpiresIn());
   107              if (accessTokenListener != null) {
   108                  accessTokenListener.notify((BasicOAuthToken) accessTokenResponse.getOAuthToken());
   109              }
   110          }
   111      }
   112  
   113      public synchronized void registerAccessTokenListener(AccessTokenListener accessTokenListener) {
   114          this.accessTokenListener = accessTokenListener;
   115      }
   116  
   117      public synchronized String getAccessToken() {
   118          return accessToken;
   119      }
   120  
   121      public synchronized void setAccessToken(String accessToken, Long expiresIn) {
   122          this.accessToken = accessToken;
   123          this.expirationTimeMillis = expiresIn == null ? null : System.currentTimeMillis() + expiresIn * MILLIS_PER_SECOND;
   124      }
   125  
   126      public TokenRequestBuilder getTokenRequestBuilder() {
   127          return tokenRequestBuilder;
   128      }
   129  
   130      public void setTokenRequestBuilder(TokenRequestBuilder tokenRequestBuilder) {
   131          this.tokenRequestBuilder = tokenRequestBuilder;
   132      }
   133  
   134      public AuthenticationRequestBuilder getAuthenticationRequestBuilder() {
   135          return authenticationRequestBuilder;
   136      }
   137  
   138      public void setAuthenticationRequestBuilder(AuthenticationRequestBuilder authenticationRequestBuilder) {
   139          this.authenticationRequestBuilder = authenticationRequestBuilder;
   140      }
   141  
   142      public OAuthClient getOauthClient() {
   143          return oauthClient;
   144      }
   145  
   146      public void setOauthClient(OAuthClient oauthClient) {
   147          this.oauthClient = oauthClient;
   148      }
   149  
   150      public void setOauthClient(Client client) {
   151          this.oauthClient = new OAuthClient( new OAuthFeignClient(client));
   152      }
   153  
   154      public static class OAuthFeignClient implements HttpClient {
   155  
   156          private Client client;
   157  
   158          public OAuthFeignClient() {
   159              this.client = new Client.Default(null, null);
   160          }
   161  
   162          public OAuthFeignClient(Client client) {
   163              this.client = client;
   164          }
   165  
   166          public <T extends OAuthClientResponse> T execute(OAuthClientRequest request, Map<String, String> headers,
   167                  String requestMethod, Class<T> responseClass)
   168                          throws OAuthSystemException, OAuthProblemException {
   169  
   170              RequestTemplate req = new RequestTemplate()
   171                      .append(request.getLocationUri())
   172                      .method(requestMethod)
   173                      .body(request.getBody());
   174  
   175              for (Entry<String, String> entry : headers.entrySet()) {
   176                  req.header(entry.getKey(), entry.getValue());
   177              }
   178              Response feignResponse;
   179              String body = "";
   180              try {
   181                  feignResponse = client.execute(req.request(), new Options());
   182                  body = Util.toString(feignResponse.body().asReader());
   183              } catch (IOException e) {
   184                  throw new OAuthSystemException(e);
   185              }
   186  
   187              String contentType = null;
   188              Collection<String> contentTypeHeader =  feignResponse.headers().get("Content-Type");
   189              if(contentTypeHeader != null) {
   190                  contentType = StringUtil.join(contentTypeHeader.toArray(new String[0]), ";");
   191              }
   192  
   193              return OAuthClientResponseFactory.createCustomResponse(
   194                      body,
   195                      contentType,
   196                      feignResponse.status(),
   197                      responseClass
   198              );
   199          }
   200  
   201          public void shutdown() {
   202              // Nothing to do here
   203          }
   204      }
   205  }