Refactor the extraction of access tokens Change-Id: Ib7bfaac995d53cd8fe5e730f5e17abcc2c6cc20f Signed-off-by: Michael Ochmann <michael.ochmann@sap.com>
diff --git a/src/main/java/com/googlesource/gerrit/plugins/cfoauth/UAAClient.java b/src/main/java/com/googlesource/gerrit/plugins/cfoauth/UAAClient.java index 611f317..e2ccc02 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/cfoauth/UAAClient.java +++ b/src/main/java/com/googlesource/gerrit/plugins/cfoauth/UAAClient.java
@@ -124,7 +124,12 @@ throw new UAAClientException(MessageFormat.format( "POST /oauth/token failed with status {0}", response.getCode())); } - return parseAccessTokenResponse(response.getBody()); + String tokenResponse = response.getBody(); + if (Strings.isNullOrEmpty(tokenResponse)) { + throw new UAAClientException( + "POST /oauth/token failed: invalid access token response"); + } + return parseAccessTokenResponse(tokenResponse); } /** @@ -181,44 +186,41 @@ @VisibleForTesting AccessToken parseAccessTokenResponse(String tokenResponse) throws UAAClientException { - if (Strings.isNullOrEmpty(tokenResponse)) { - throw new UAAClientException( - "Can't extract a token from an empty string"); - } - JsonObject json = getAsJsonObject(tokenResponse); - String accessToken = getAttribute(json, ACCESS_TOKEN_ATTRIBUTE); - if (accessToken == null) { - throw new UAAClientException( - "Can't extract a token: missing or invalid 'access_token' attribute"); - } - return toAccessToken(accessToken); + return toAccessToken(getAccessTokenAttribute(tokenResponse)); } @VisibleForTesting - JsonObject toJsonWebToken(String accessToken) - throws UAAClientException { + JsonObject toJsonWebToken(String accessToken) throws UAAClientException { + String[] segments = getSegments(accessToken); + if (verifySignatures) { + verifySignature(segments); + } + return getAsJsonObject(decodeBase64(segments[1])); + } + + private String[] getSegments(String accessToken) throws UAAClientException { String[] segments = accessToken.split("\\."); if (segments.length != 3) { throw new UAAClientException( "Invalid token: must be of the form 'header.token.signature'"); } - String claims = decodeBase64(segments[1]); - if (verifySignatures) { - String header = decodeBase64(segments[0]); - String alg = getAttribute(getAsJsonObject(header), ALG_ATTRIBUTE); - if (Strings.isNullOrEmpty(alg)) { - throw new UAAClientException("Invalid token: missing \"alg\" attribute"); - } - String signature = segments[2]; - String signedContent = segments[0] + "." + segments[1]; - verifySignature(signedContent, signature, alg); + return segments; + } + + private void verifySignature(String[] segments) throws UAAClientException { + String header = decodeBase64(segments[0]); + String alg = getAttribute(getAsJsonObject(header), ALG_ATTRIBUTE); + if (Strings.isNullOrEmpty(alg)) { + throw new UAAClientException("Invalid token: missing \"alg\" attribute"); } - return getAsJsonObject(claims); + String signature = segments[2]; + String signedContent = segments[0] + "." + segments[1]; + verifySignature(signedContent, signature, alg); } @VisibleForTesting - void verifySignature(String signedContent, String signature, - String alg) throws UAAClientException { + void verifySignature(String signedContent, String signature, String alg) + throws UAAClientException { SignatureVerifier verifier = getSignatureVerifier(alg, false); if (!verifier.verify(signedContent, signature)) { // If the signature is invalid, maybe the secret has changed @@ -277,6 +279,17 @@ return prim != null && prim.isString() ? prim.getAsString() : null; } + private String getAccessTokenAttribute(String tokenResponse) + throws UAAClientException { + JsonObject json = getAsJsonObject(tokenResponse); + String accessToken = getAttribute(json, ACCESS_TOKEN_ATTRIBUTE); + if (accessToken == null) { + throw new UAAClientException( + "Can't extract a token: missing or invalid 'access_token' attribute"); + } + return accessToken; + } + @VisibleForTesting long getLongAttribute(JsonObject json, String name, long defaultValue) { JsonPrimitive prim = getAsJsonPrimitive(json, name);