|
31 | 31 | import java.io.IOException; |
32 | 32 | import java.util.HashMap; |
33 | 33 | import java.util.Map; |
| 34 | +import java.util.logging.Logger; |
34 | 35 |
|
35 | 36 | /** |
36 | 37 | * {@link Beta} <br/> |
|
40 | 41 | */ |
41 | 42 | @Beta |
42 | 43 | public class MockTokenServerTransport extends MockHttpTransport { |
| 44 | + /** Old URL of Google's token server (for backwards compatibility) */ |
| 45 | + private static final String LEGACY_TOKEN_SERVER_URL = |
| 46 | + "https://accounts.google.com/o/oauth2/token"; |
| 47 | + |
| 48 | + private static final Logger LOGGER = Logger.getLogger(MockTokenServerTransport.class.getName()); |
| 49 | + |
43 | 50 | static final String EXPECTED_GRANT_TYPE = "urn:ietf:params:oauth:grant-type:jwt-bearer"; |
44 | 51 | static final JsonFactory JSON_FACTORY = new JacksonFactory(); |
45 | 52 | final String tokenServerUrl; |
@@ -70,64 +77,71 @@ public void addRefreshToken(String refreshToken, String accessTokenToReturn) { |
70 | 77 | @Override |
71 | 78 | public LowLevelHttpRequest buildRequest(String method, String url) throws IOException { |
72 | 79 | if (url.equals(tokenServerUrl)) { |
73 | | - MockLowLevelHttpRequest request = new MockLowLevelHttpRequest(url) { |
74 | | - @Override |
75 | | - public LowLevelHttpResponse execute() throws IOException { |
76 | | - String content = this.getContentAsString(); |
77 | | - Map<String, String> query = TestUtils.parseQuery(content); |
78 | | - String accessToken = null; |
79 | | - |
80 | | - String foundId = query.get("client_id"); |
81 | | - if (foundId != null) { |
82 | | - if (!clients.containsKey(foundId)) { |
83 | | - throw new IOException("Client ID not found."); |
84 | | - } |
85 | | - String foundSecret = query.get("client_secret"); |
86 | | - String expectedSecret = clients.get(foundId); |
87 | | - if (foundSecret == null || !foundSecret.equals(expectedSecret)) { |
88 | | - throw new IOException("Client secret not found."); |
89 | | - } |
90 | | - String foundRefresh = query.get("refresh_token"); |
91 | | - if (!refreshTokens.containsKey(foundRefresh)) { |
92 | | - throw new IOException("Refresh Token not found."); |
93 | | - } |
94 | | - accessToken = refreshTokens.get(foundRefresh); |
95 | | - } else if (query.containsKey("grant_type")) { |
96 | | - String grantType = query.get("grant_type"); |
97 | | - if (!EXPECTED_GRANT_TYPE.equals(grantType)) { |
98 | | - throw new IOException("Unexpected Grant Type."); |
99 | | - } |
100 | | - String assertion = query.get("assertion"); |
101 | | - JsonWebSignature signature = JsonWebSignature.parse(JSON_FACTORY, assertion); |
102 | | - String foundEmail = signature.getPayload().getIssuer(); |
103 | | - if (!serviceAccounts.containsKey(foundEmail)) { |
104 | | - throw new IOException("Service Account Email not found as issuer."); |
105 | | - } |
106 | | - accessToken = serviceAccounts.get(foundEmail); |
107 | | - String foundScopes = (String) signature.getPayload().get("scope"); |
108 | | - if (foundScopes == null || foundScopes.length() == 0) { |
109 | | - throw new IOException("Scopes not found."); |
110 | | - } |
111 | | - } else { |
112 | | - throw new IOException("Unknown token type."); |
| 80 | + return buildTokenRequest(url); |
| 81 | + } else if (url.equals(LEGACY_TOKEN_SERVER_URL)) { |
| 82 | + LOGGER.warning("Your configured token_uri is using a legacy endpoint. You may want to " |
| 83 | + + "redownload your credentials."); |
| 84 | + return buildTokenRequest(url); |
| 85 | + } |
| 86 | + return super.buildRequest(method, url); |
| 87 | + } |
| 88 | + |
| 89 | + private MockLowLevelHttpRequest buildTokenRequest(String url) { |
| 90 | + return new MockLowLevelHttpRequest(url) { |
| 91 | + @Override |
| 92 | + public LowLevelHttpResponse execute() throws IOException { |
| 93 | + String content = this.getContentAsString(); |
| 94 | + Map<String, String> query = TestUtils.parseQuery(content); |
| 95 | + String accessToken = null; |
| 96 | + |
| 97 | + String foundId = query.get("client_id"); |
| 98 | + if (foundId != null) { |
| 99 | + if (!clients.containsKey(foundId)) { |
| 100 | + throw new IOException("Client ID not found."); |
| 101 | + } |
| 102 | + String foundSecret = query.get("client_secret"); |
| 103 | + String expectedSecret = clients.get(foundId); |
| 104 | + if (foundSecret == null || !foundSecret.equals(expectedSecret)) { |
| 105 | + throw new IOException("Client secret not found."); |
113 | 106 | } |
| 107 | + String foundRefresh = query.get("refresh_token"); |
| 108 | + if (!refreshTokens.containsKey(foundRefresh)) { |
| 109 | + throw new IOException("Refresh Token not found."); |
| 110 | + } |
| 111 | + accessToken = refreshTokens.get(foundRefresh); |
| 112 | + } else if (query.containsKey("grant_type")) { |
| 113 | + String grantType = query.get("grant_type"); |
| 114 | + if (!EXPECTED_GRANT_TYPE.equals(grantType)) { |
| 115 | + throw new IOException("Unexpected Grant Type."); |
| 116 | + } |
| 117 | + String assertion = query.get("assertion"); |
| 118 | + JsonWebSignature signature = JsonWebSignature.parse(JSON_FACTORY, assertion); |
| 119 | + String foundEmail = signature.getPayload().getIssuer(); |
| 120 | + if (!serviceAccounts.containsKey(foundEmail)) { |
| 121 | + throw new IOException("Service Account Email not found as issuer."); |
| 122 | + } |
| 123 | + accessToken = serviceAccounts.get(foundEmail); |
| 124 | + String foundScopes = (String) signature.getPayload().get("scope"); |
| 125 | + if (foundScopes == null || foundScopes.length() == 0) { |
| 126 | + throw new IOException("Scopes not found."); |
| 127 | + } |
| 128 | + } else { |
| 129 | + throw new IOException("Unknown token type."); |
| 130 | + } |
114 | 131 |
|
115 | | - // Create the JSon response |
116 | | - GenericJson refreshContents = new GenericJson(); |
117 | | - refreshContents.setFactory(JSON_FACTORY); |
118 | | - refreshContents.put("access_token", accessToken); |
119 | | - refreshContents.put("expires_in", 3600); |
120 | | - refreshContents.put("token_type", "Bearer"); |
121 | | - String refreshText = refreshContents.toPrettyString(); |
| 132 | + // Create the JSon response |
| 133 | + GenericJson refreshContents = new GenericJson(); |
| 134 | + refreshContents.setFactory(JSON_FACTORY); |
| 135 | + refreshContents.put("access_token", accessToken); |
| 136 | + refreshContents.put("expires_in", 3600); |
| 137 | + refreshContents.put("token_type", "Bearer"); |
| 138 | + String refreshText = refreshContents.toPrettyString(); |
122 | 139 |
|
123 | | - MockLowLevelHttpResponse response = new MockLowLevelHttpResponse() |
| 140 | + MockLowLevelHttpResponse response = new MockLowLevelHttpResponse() |
124 | 141 | .setContentType(Json.MEDIA_TYPE) |
125 | 142 | .setContent(refreshText); |
126 | | - return response; |
127 | | - } |
128 | | - }; |
129 | | - return request; |
130 | | - } |
131 | | - return super.buildRequest(method, url); |
| 143 | + return response; |
| 144 | + } |
| 145 | + }; |
132 | 146 | } |
133 | 147 | } |
0 commit comments