Java tutorial
// ------------------------------------------------------------------------------ // Copyright (c) 2014 Microsoft Corporation // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // ------------------------------------------------------------------------------ package com.microsoft.services.msa; import java.util.Map; import org.json.JSONException; import org.json.JSONObject; import android.text.TextUtils; /** * OAuthSuccessfulResponse represents a successful response form an OAuth server. */ class OAuthSuccessfulResponse implements OAuthResponse { /** * Builder is a utility class that is used to build a new OAuthSuccessfulResponse. * It must be constructed with the required fields, and can add on the optional ones. */ public static class Builder { private final String accessToken; private String authenticationToken; private int expiresIn = UNINITIALIZED; private String refreshToken; private String scope; private final OAuth.TokenType tokenType; public Builder(String accessToken, OAuth.TokenType tokenType) { if (accessToken == null) throw new AssertionError(); if (TextUtils.isEmpty(accessToken)) throw new AssertionError(); if (tokenType == null) throw new AssertionError(); this.accessToken = accessToken; this.tokenType = tokenType; } public Builder authenticationToken(String authenticationToken) { this.authenticationToken = authenticationToken; return this; } /** * @return a new instance of an OAuthSuccessfulResponse with the given * parameters passed into the builder. */ public OAuthSuccessfulResponse build() { return new OAuthSuccessfulResponse(this); } public Builder expiresIn(int expiresIn) { this.expiresIn = expiresIn; return this; } public Builder refreshToken(String refreshToken) { this.refreshToken = refreshToken; return this; } public Builder scope(String scope) { this.scope = scope; return this; } } /** Used to declare expiresIn uninitialized */ private static final int UNINITIALIZED = -1; public static OAuthSuccessfulResponse createFromFragment(Map<String, String> fragmentParameters) throws LiveAuthException { String accessToken = fragmentParameters.get(OAuth.ACCESS_TOKEN); String tokenTypeString = fragmentParameters.get(OAuth.TOKEN_TYPE); // must have accessToken and tokenTypeString to be a valid OAuthSuccessfulResponse if (accessToken == null) throw new AssertionError(); if (tokenTypeString == null) throw new AssertionError(); OAuth.TokenType tokenType; try { tokenType = OAuth.TokenType.valueOf(tokenTypeString.toUpperCase()); } catch (IllegalArgumentException e) { throw new LiveAuthException(ErrorMessages.SERVER_ERROR, e); } Builder builder = new Builder(accessToken, tokenType); String authenticationToken = fragmentParameters.get(OAuth.AUTHENTICATION_TOKEN); if (authenticationToken != null) { builder.authenticationToken(authenticationToken); } String expiresInString = fragmentParameters.get(OAuth.EXPIRES_IN); if (expiresInString != null) { final int expiresIn; try { expiresIn = Integer.parseInt(expiresInString); } catch (final NumberFormatException e) { throw new LiveAuthException(ErrorMessages.SERVER_ERROR, e); } builder.expiresIn(expiresIn); } String scope = fragmentParameters.get(OAuth.SCOPE); if (scope != null) { builder.scope(scope); } return builder.build(); } /** * Static constructor used to create a new OAuthSuccessfulResponse from an * OAuth server's JSON response. * * @param response from an OAuth server that is used to create the object. * @return a new instance of OAuthSuccessfulResponse that is created from the given JSONObject * @throws LiveAuthException if there is a JSONException or the token_type is unknown. */ public static OAuthSuccessfulResponse createFromJson(JSONObject response) throws LiveAuthException { if (!validOAuthSuccessfulResponse(response)) throw new AssertionError(); final String accessToken; try { accessToken = response.getString(OAuth.ACCESS_TOKEN); } catch (final JSONException e) { throw new LiveAuthException(ErrorMessages.SERVER_ERROR, e); } final String tokenTypeString; try { tokenTypeString = response.getString(OAuth.TOKEN_TYPE); } catch (final JSONException e) { throw new LiveAuthException(ErrorMessages.SERVER_ERROR, e); } final OAuth.TokenType tokenType; try { tokenType = OAuth.TokenType.valueOf(tokenTypeString.toUpperCase()); } catch (final IllegalArgumentException e) { throw new LiveAuthException(ErrorMessages.SERVER_ERROR, e); } catch (final NullPointerException e) { throw new LiveAuthException(ErrorMessages.SERVER_ERROR, e); } final Builder builder = new Builder(accessToken, tokenType); if (response.has(OAuth.AUTHENTICATION_TOKEN)) { final String authenticationToken; try { authenticationToken = response.getString(OAuth.AUTHENTICATION_TOKEN); } catch (final JSONException e) { throw new LiveAuthException(ErrorMessages.CLIENT_ERROR, e); } builder.authenticationToken(authenticationToken); } if (response.has(OAuth.REFRESH_TOKEN)) { final String refreshToken; try { refreshToken = response.getString(OAuth.REFRESH_TOKEN); } catch (final JSONException e) { throw new LiveAuthException(ErrorMessages.CLIENT_ERROR, e); } builder.refreshToken(refreshToken); } if (response.has(OAuth.EXPIRES_IN)) { final int expiresIn; try { expiresIn = response.getInt(OAuth.EXPIRES_IN); } catch (final JSONException e) { throw new LiveAuthException(ErrorMessages.CLIENT_ERROR, e); } builder.expiresIn(expiresIn); } if (response.has(OAuth.SCOPE)) { final String scope; try { scope = response.getString(OAuth.SCOPE); } catch (final JSONException e) { throw new LiveAuthException(ErrorMessages.CLIENT_ERROR, e); } builder.scope(scope); } return builder.build(); } /** * @param response * @return true if the given JSONObject has the required fields to construct an * OAuthSuccessfulResponse (i.e., has access_token and token_type) */ public static boolean validOAuthSuccessfulResponse(JSONObject response) { return response.has(OAuth.ACCESS_TOKEN) && response.has(OAuth.TOKEN_TYPE); } /** REQUIRED. The access token issued by the authorization server. */ private final String accessToken; private final String authenticationToken; /** * OPTIONAL. The lifetime in seconds of the access token. For * example, the value "3600" denotes that the access token will * expire in one hour from the time the response was generated. */ private final int expiresIn; /** * OPTIONAL. The refresh token which can be used to obtain new * access tokens using the same authorization grant. */ private final String refreshToken; /** OPTIONAL. */ private final String scope; /** REQUIRED. */ private final OAuth.TokenType tokenType; /** * Private constructor to enforce the user of the builder. * @param builder to use to construct the object from. */ private OAuthSuccessfulResponse(Builder builder) { this.accessToken = builder.accessToken; this.authenticationToken = builder.authenticationToken; this.tokenType = builder.tokenType; this.refreshToken = builder.refreshToken; this.expiresIn = builder.expiresIn; this.scope = builder.scope; } @Override public void accept(OAuthResponseVisitor visitor) { visitor.visit(this); } public String getAccessToken() { return this.accessToken; } public String getAuthenticationToken() { return this.authenticationToken; } public int getExpiresIn() { return this.expiresIn; } public String getRefreshToken() { return this.refreshToken; } public String getScope() { return this.scope; } public OAuth.TokenType getTokenType() { return this.tokenType; } public boolean hasAuthenticationToken() { return this.authenticationToken != null && !TextUtils.isEmpty(this.authenticationToken); } public boolean hasExpiresIn() { return this.expiresIn != UNINITIALIZED; } public boolean hasRefreshToken() { return this.refreshToken != null && !TextUtils.isEmpty(this.refreshToken); } public boolean hasScope() { return this.scope != null && !TextUtils.isEmpty(this.scope); } @Override public String toString() { return String.format( "OAuthSuccessfulResponse [accessToken=%s, authenticationToken=%s, tokenType=%s, refreshToken=%s, expiresIn=%s, scope=%s]", this.accessToken, this.authenticationToken, this.tokenType, this.refreshToken, this.expiresIn, this.scope); } }