1 /* 2 * Copyright 2015, Google Inc. All rights reserved. 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 Inc. 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 org.junit.Assert.assertEquals; 35 import static org.junit.Assert.assertFalse; 36 import static org.junit.Assert.assertNull; 37 import static org.junit.Assert.assertSame; 38 import static org.junit.Assert.fail; 39 40 import com.google.auth.TestUtils; 41 import java.io.IOException; 42 import java.net.URI; 43 import java.net.URL; 44 import java.util.Arrays; 45 import java.util.Date; 46 import java.util.HashMap; 47 import java.util.List; 48 import java.util.Map; 49 import org.junit.Test; 50 import org.junit.runner.RunWith; 51 import org.junit.runners.JUnit4; 52 53 /** Unit Tests for UserAuthorizer */ 54 @RunWith(JUnit4.class) 55 public class UserAuthorizerTest { 56 private static final String CLIENT_ID_VALUE = "ya29.1.AADtN_UtlxN3PuGAxrN2XQnZTVRvDyVWnYq4I6dws"; 57 private static final String CLIENT_SECRET = "jakuaL9YyieakhECKL2SwZcu"; 58 private static final String REFRESH_TOKEN = "1/Tl6awhpFjkMkSJoj1xsli0H2eL5YsMgU_NKPY2TyGWY"; 59 private static final String ACCESS_TOKEN_VALUE = "1/MkSJoj1xsli0AccessToken_NKPY2"; 60 private static final List<String> GRANTED_SCOPES = Arrays.asList("scope1", "scope2"); 61 private static final String GRANTED_SCOPES_STRING = String.join(" ", GRANTED_SCOPES); 62 private static final String DUMMY_SCOPE = "dummy_scope"; 63 private static final List<String> DUMMY_SCOPES = Arrays.asList(DUMMY_SCOPE); 64 private static final Long EXPIRATION_TIME = 504000300L; 65 private static final AccessToken ACCESS_TOKEN = 66 AccessToken.newBuilder() 67 .setTokenValue(ACCESS_TOKEN_VALUE) 68 .setExpirationTime(new Date(EXPIRATION_TIME)) 69 .setScopes(GRANTED_SCOPES) 70 .build(); 71 private static final ClientId CLIENT_ID = ClientId.of(CLIENT_ID_VALUE, CLIENT_SECRET); 72 private static final String USER_ID = "foo@bar.com"; 73 private static final URI CALLBACK_URI = URI.create("/testcallback"); 74 private static final String CODE = "thisistheend"; 75 private static final URI BASE_URI = URI.create("http://example.com/foo"); 76 private static final PKCEProvider pkce = new DefaultPKCEProvider(); 77 78 @Test constructorMinimum()79 public void constructorMinimum() { 80 TokenStore store = new MemoryTokensStorage(); 81 82 UserAuthorizer authorizer = 83 UserAuthorizer.newBuilder() 84 .setClientId(CLIENT_ID) 85 .setScopes(DUMMY_SCOPES) 86 .setTokenStore(store) 87 .build(); 88 89 assertSame(CLIENT_ID, authorizer.getClientId()); 90 assertSame(store, authorizer.getTokenStore()); 91 assertEquals(DUMMY_SCOPES, authorizer.getScopes()); 92 assertEquals(UserAuthorizer.DEFAULT_CALLBACK_URI, authorizer.getCallbackUri()); 93 } 94 95 @Test constructorCommon()96 public void constructorCommon() { 97 TokenStore store = new MemoryTokensStorage(); 98 99 UserAuthorizer authorizer = 100 UserAuthorizer.newBuilder() 101 .setClientId(CLIENT_ID) 102 .setScopes(DUMMY_SCOPES) 103 .setTokenStore(store) 104 .setCallbackUri(CALLBACK_URI) 105 .build(); 106 107 assertSame(CLIENT_ID, authorizer.getClientId()); 108 assertSame(store, authorizer.getTokenStore()); 109 assertEquals(DUMMY_SCOPES, authorizer.getScopes()); 110 assertEquals(CALLBACK_URI, authorizer.getCallbackUri()); 111 } 112 113 @Test(expected = NullPointerException.class) constructorCommon_nullClientId_throws()114 public void constructorCommon_nullClientId_throws() { 115 UserAuthorizer.newBuilder().setScopes(DUMMY_SCOPES).setCallbackUri(CALLBACK_URI).build(); 116 } 117 118 @Test(expected = NullPointerException.class) constructorCommon_nullScopes_throws()119 public void constructorCommon_nullScopes_throws() { 120 UserAuthorizer.newBuilder().setClientId(CLIENT_ID).build(); 121 } 122 123 @Test getCallbackUri_relativeToBase()124 public void getCallbackUri_relativeToBase() { 125 final URI callbackURI = URI.create("/bar"); 126 final URI expectedCallbackURI = URI.create("http://example.com/bar"); 127 UserAuthorizer authorizer = 128 UserAuthorizer.newBuilder() 129 .setClientId(CLIENT_ID) 130 .setScopes(DUMMY_SCOPES) 131 .setCallbackUri(callbackURI) 132 .build(); 133 134 URI absoluteCallbackURI = authorizer.getCallbackUri(BASE_URI); 135 136 assertEquals(expectedCallbackURI, absoluteCallbackURI); 137 } 138 139 @Test getAuthorizationUrl()140 public void getAuthorizationUrl() throws IOException { 141 final String CUSTOM_STATE = "custom_state"; 142 final String PROTOCOL = "https"; 143 final String HOST = "accounts.test.com"; 144 final String PATH = "/o/o/oauth2/auth"; 145 final URI AUTH_URI = URI.create(PROTOCOL + "://" + HOST + PATH); 146 final String EXPECTED_CALLBACK = "http://example.com" + CALLBACK_URI.toString(); 147 UserAuthorizer authorizer = 148 UserAuthorizer.newBuilder() 149 .setClientId(CLIENT_ID) 150 .setScopes(DUMMY_SCOPES) 151 .setCallbackUri(CALLBACK_URI) 152 .setUserAuthUri(AUTH_URI) 153 .setPKCEProvider(pkce) 154 .build(); 155 156 URL authorizationUrl = authorizer.getAuthorizationUrl(USER_ID, CUSTOM_STATE, BASE_URI); 157 158 assertEquals(PROTOCOL, authorizationUrl.getProtocol()); 159 assertEquals(-1, authorizationUrl.getPort()); 160 assertEquals(PATH, authorizationUrl.getPath()); 161 assertEquals(HOST, authorizationUrl.getHost()); 162 String query = authorizationUrl.getQuery(); 163 Map<String, String> parameters = TestUtils.parseQuery(query); 164 assertEquals(CUSTOM_STATE, parameters.get("state")); 165 assertEquals(USER_ID, parameters.get("login_hint")); 166 assertEquals(EXPECTED_CALLBACK, parameters.get("redirect_uri")); 167 assertEquals(CLIENT_ID_VALUE, parameters.get("client_id")); 168 assertEquals(DUMMY_SCOPE, parameters.get("scope")); 169 assertEquals("code", parameters.get("response_type")); 170 assertEquals(pkce.getCodeChallenge(), parameters.get("code_challenge")); 171 assertEquals(pkce.getCodeChallengeMethod(), parameters.get("code_challenge_method")); 172 } 173 174 @Test getAuthorizationUrl_additionalParameters()175 public void getAuthorizationUrl_additionalParameters() throws IOException { 176 final String CUSTOM_STATE = "custom_state"; 177 final String PROTOCOL = "https"; 178 final String HOST = "accounts.test.com"; 179 final String PATH = "/o/o/oauth2/auth"; 180 final URI AUTH_URI = URI.create(PROTOCOL + "://" + HOST + PATH); 181 final String EXPECTED_CALLBACK = "http://example.com" + CALLBACK_URI.toString(); 182 UserAuthorizer authorizer = 183 UserAuthorizer.newBuilder() 184 .setClientId(CLIENT_ID) 185 .setScopes(DUMMY_SCOPES) 186 .setCallbackUri(CALLBACK_URI) 187 .setUserAuthUri(AUTH_URI) 188 .build(); 189 Map<String, String> additionalParameters = new HashMap<String, String>(); 190 additionalParameters.put("param1", "value1"); 191 additionalParameters.put("param2", "value2"); 192 193 // Verify that the authorization URL doesn't include the additional parameters if they are not 194 // passed in. 195 URL authorizationUrl = authorizer.getAuthorizationUrl(USER_ID, CUSTOM_STATE, BASE_URI); 196 String query = authorizationUrl.getQuery(); 197 Map<String, String> parameters = TestUtils.parseQuery(query); 198 assertFalse(parameters.containsKey("param1")); 199 assertFalse(parameters.containsKey("param2")); 200 201 // Verify that the authorization URL includes the additional parameters if they are passed in. 202 authorizationUrl = 203 authorizer.getAuthorizationUrl(USER_ID, CUSTOM_STATE, BASE_URI, additionalParameters); 204 query = authorizationUrl.getQuery(); 205 parameters = TestUtils.parseQuery(query); 206 assertEquals("value1", parameters.get("param1")); 207 assertEquals("value2", parameters.get("param2")); 208 209 // Verify that the authorization URL doesn't include the additional parameters passed in the 210 // previous call to the authorizer 211 authorizationUrl = authorizer.getAuthorizationUrl(USER_ID, CUSTOM_STATE, BASE_URI); 212 query = authorizationUrl.getQuery(); 213 parameters = TestUtils.parseQuery(query); 214 assertFalse(parameters.containsKey("param1")); 215 assertFalse(parameters.containsKey("param2")); 216 } 217 218 @Test getCredentials_noCredentials_returnsNull()219 public void getCredentials_noCredentials_returnsNull() throws IOException { 220 UserAuthorizer authorizer = 221 UserAuthorizer.newBuilder() 222 .setClientId(CLIENT_ID) 223 .setScopes(DUMMY_SCOPES) 224 .setTokenStore(new MemoryTokensStorage()) 225 .build(); 226 227 UserCredentials credentials = authorizer.getCredentials(USER_ID); 228 229 assertNull(credentials); 230 } 231 232 @Test getCredentials_storedCredentials_returnsStored()233 public void getCredentials_storedCredentials_returnsStored() throws IOException { 234 TokenStore tokenStore = new MemoryTokensStorage(); 235 236 UserCredentials initialCredentials = 237 UserCredentials.newBuilder() 238 .setClientId(CLIENT_ID_VALUE) 239 .setClientSecret(CLIENT_SECRET) 240 .setRefreshToken(REFRESH_TOKEN) 241 .setAccessToken(ACCESS_TOKEN) 242 .build(); 243 244 UserAuthorizer authorizer = 245 UserAuthorizer.newBuilder() 246 .setClientId(CLIENT_ID) 247 .setScopes(DUMMY_SCOPES) 248 .setTokenStore(tokenStore) 249 .build(); 250 authorizer.storeCredentials(USER_ID, initialCredentials); 251 252 UserCredentials credentials = authorizer.getCredentials(USER_ID); 253 254 assertEquals(REFRESH_TOKEN, credentials.getRefreshToken()); 255 assertEquals(ACCESS_TOKEN_VALUE, credentials.getAccessToken().getTokenValue()); 256 assertEquals(EXPIRATION_TIME, credentials.getAccessToken().getExpirationTimeMillis()); 257 assertEquals(GRANTED_SCOPES, credentials.getAccessToken().getScopes()); 258 } 259 260 @Test(expected = NullPointerException.class) getCredentials_nullUserId_throws()261 public void getCredentials_nullUserId_throws() throws IOException { 262 TokenStore tokenStore = new MemoryTokensStorage(); 263 UserAuthorizer authorizer = 264 UserAuthorizer.newBuilder() 265 .setClientId(CLIENT_ID) 266 .setScopes(DUMMY_SCOPES) 267 .setTokenStore(tokenStore) 268 .build(); 269 270 authorizer.getCredentials(null); 271 } 272 273 @Test getCredentials_refreshedToken_stored()274 public void getCredentials_refreshedToken_stored() throws IOException { 275 final String accessTokenValue1 = "1/MkSJoj1xsli0AccessToken_NKPY2"; 276 final String accessTokenValue2 = "2/MkSJoj1xsli0AccessToken_NKPY2"; 277 AccessToken accessToken1 = 278 AccessToken.newBuilder() 279 .setTokenValue(accessTokenValue1) 280 .setExpirationTime(new Date(EXPIRATION_TIME)) 281 .setScopes(GRANTED_SCOPES) 282 .build(); 283 MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory(); 284 transportFactory.transport.addClient(CLIENT_ID_VALUE, CLIENT_SECRET); 285 transportFactory.transport.addRefreshToken( 286 REFRESH_TOKEN, accessTokenValue2, GRANTED_SCOPES_STRING); 287 TokenStore tokenStore = new MemoryTokensStorage(); 288 UserAuthorizer authorizer = 289 UserAuthorizer.newBuilder() 290 .setClientId(CLIENT_ID) 291 .setScopes(DUMMY_SCOPES) 292 .setTokenStore(tokenStore) 293 .setHttpTransportFactory(transportFactory) 294 .build(); 295 296 UserCredentials originalCredentials = 297 UserCredentials.newBuilder() 298 .setClientId(CLIENT_ID_VALUE) 299 .setClientSecret(CLIENT_SECRET) 300 .setRefreshToken(REFRESH_TOKEN) 301 .setAccessToken(accessToken1) 302 .setHttpTransportFactory(transportFactory) 303 .build(); 304 305 authorizer.storeCredentials(USER_ID, originalCredentials); 306 307 UserCredentials credentials1 = authorizer.getCredentials(USER_ID); 308 309 assertEquals(REFRESH_TOKEN, credentials1.getRefreshToken()); 310 assertEquals(accessTokenValue1, credentials1.getAccessToken().getTokenValue()); 311 assertEquals(GRANTED_SCOPES, credentials1.getAccessToken().getScopes()); 312 313 // Refresh the token to get update from token server 314 credentials1.refresh(); 315 assertEquals(REFRESH_TOKEN, credentials1.getRefreshToken()); 316 assertEquals(accessTokenValue2, credentials1.getAccessToken().getTokenValue()); 317 assertEquals(GRANTED_SCOPES, credentials1.getAccessToken().getScopes()); 318 319 // Load a second credentials instance 320 UserCredentials credentials2 = authorizer.getCredentials(USER_ID); 321 322 // Verify that token refresh stored the updated tokens 323 assertEquals(REFRESH_TOKEN, credentials2.getRefreshToken()); 324 assertEquals(accessTokenValue2, credentials2.getAccessToken().getTokenValue()); 325 assertEquals(GRANTED_SCOPES, credentials2.getAccessToken().getScopes()); 326 } 327 328 @Test getCredentials_refreshedToken_different_granted_scopes()329 public void getCredentials_refreshedToken_different_granted_scopes() throws IOException { 330 final String accessTokenValue1 = "1/MkSJoj1xsli0AccessToken_NKPY2"; 331 final String accessTokenValue2 = "2/MkSJoj1xsli0AccessToken_NKPY2"; 332 final List<String> grantedRefreshScopes = Arrays.asList("scope3"); 333 AccessToken accessToken1 = 334 AccessToken.newBuilder() 335 .setTokenValue(accessTokenValue1) 336 .setExpirationTime(new Date(EXPIRATION_TIME)) 337 .setScopes(GRANTED_SCOPES) 338 .build(); 339 MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory(); 340 transportFactory.transport.addClient(CLIENT_ID_VALUE, CLIENT_SECRET); 341 transportFactory.transport.addRefreshToken(REFRESH_TOKEN, accessTokenValue2, "scope3"); 342 TokenStore tokenStore = new MemoryTokensStorage(); 343 UserAuthorizer authorizer = 344 UserAuthorizer.newBuilder() 345 .setClientId(CLIENT_ID) 346 .setScopes(DUMMY_SCOPES) 347 .setTokenStore(tokenStore) 348 .setHttpTransportFactory(transportFactory) 349 .build(); 350 351 UserCredentials originalCredentials = 352 UserCredentials.newBuilder() 353 .setClientId(CLIENT_ID_VALUE) 354 .setClientSecret(CLIENT_SECRET) 355 .setRefreshToken(REFRESH_TOKEN) 356 .setAccessToken(accessToken1) 357 .setHttpTransportFactory(transportFactory) 358 .build(); 359 360 authorizer.storeCredentials(USER_ID, originalCredentials); 361 362 UserCredentials credentials1 = authorizer.getCredentials(USER_ID); 363 364 assertEquals(REFRESH_TOKEN, credentials1.getRefreshToken()); 365 assertEquals(accessTokenValue1, credentials1.getAccessToken().getTokenValue()); 366 assertEquals(GRANTED_SCOPES, credentials1.getAccessToken().getScopes()); 367 368 // Refresh the token to get update from token server 369 credentials1.refresh(); 370 assertEquals(REFRESH_TOKEN, credentials1.getRefreshToken()); 371 assertEquals(accessTokenValue2, credentials1.getAccessToken().getTokenValue()); 372 assertEquals(grantedRefreshScopes, credentials1.getAccessToken().getScopes()); 373 374 // Load a second credentials instance 375 UserCredentials credentials2 = authorizer.getCredentials(USER_ID); 376 377 // Verify that token refresh stored the updated tokens 378 assertEquals(REFRESH_TOKEN, credentials2.getRefreshToken()); 379 assertEquals(accessTokenValue2, credentials2.getAccessToken().getTokenValue()); 380 assertEquals(grantedRefreshScopes, credentials2.getAccessToken().getScopes()); 381 } 382 383 @Test getCredentialsFromCode_conevertsCodeToTokens()384 public void getCredentialsFromCode_conevertsCodeToTokens() throws IOException { 385 MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory(); 386 transportFactory.transport.addClient(CLIENT_ID_VALUE, CLIENT_SECRET); 387 transportFactory.transport.addAuthorizationCode( 388 CODE, REFRESH_TOKEN, ACCESS_TOKEN_VALUE, GRANTED_SCOPES_STRING, null); 389 TokenStore tokenStore = new MemoryTokensStorage(); 390 UserAuthorizer authorizer = 391 UserAuthorizer.newBuilder() 392 .setClientId(CLIENT_ID) 393 .setScopes(DUMMY_SCOPES) 394 .setTokenStore(tokenStore) 395 .setHttpTransportFactory(transportFactory) 396 .build(); 397 398 UserCredentials credentials = authorizer.getCredentialsFromCode(CODE, BASE_URI); 399 400 assertEquals(REFRESH_TOKEN, credentials.getRefreshToken()); 401 assertEquals(ACCESS_TOKEN_VALUE, credentials.getAccessToken().getTokenValue()); 402 assertEquals(GRANTED_SCOPES, credentials.getAccessToken().getScopes()); 403 } 404 405 @Test getCredentialsFromCode_additionalParameters()406 public void getCredentialsFromCode_additionalParameters() throws IOException { 407 MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory(); 408 transportFactory.transport.addClient(CLIENT_ID_VALUE, CLIENT_SECRET); 409 410 Map<String, String> additionalParameters = new HashMap<String, String>(); 411 additionalParameters.put("param1", "value1"); 412 additionalParameters.put("param2", "value2"); 413 414 String code2 = "code2"; 415 String refreshToken2 = "refreshToken2"; 416 String accessTokenValue2 = "accessTokenValue2"; 417 418 transportFactory.transport.addAuthorizationCode( 419 CODE, REFRESH_TOKEN, ACCESS_TOKEN_VALUE, GRANTED_SCOPES_STRING, null); 420 transportFactory.transport.addAuthorizationCode( 421 code2, refreshToken2, accessTokenValue2, GRANTED_SCOPES_STRING, additionalParameters); 422 423 TokenStore tokenStore = new MemoryTokensStorage(); 424 UserAuthorizer authorizer = 425 UserAuthorizer.newBuilder() 426 .setClientId(CLIENT_ID) 427 .setScopes(DUMMY_SCOPES) 428 .setTokenStore(tokenStore) 429 .setHttpTransportFactory(transportFactory) 430 .build(); 431 432 // Verify that the additional parameters are not attached to the post body when not specified 433 UserCredentials credentials = authorizer.getCredentialsFromCode(CODE, BASE_URI); 434 assertEquals(REFRESH_TOKEN, credentials.getRefreshToken()); 435 assertEquals(ACCESS_TOKEN_VALUE, credentials.getAccessToken().getTokenValue()); 436 assertEquals(GRANTED_SCOPES, credentials.getAccessToken().getScopes()); 437 438 // Verify that the additional parameters are attached to the post body when specified 439 credentials = authorizer.getCredentialsFromCode(code2, BASE_URI, additionalParameters); 440 assertEquals(refreshToken2, credentials.getRefreshToken()); 441 assertEquals(accessTokenValue2, credentials.getAccessToken().getTokenValue()); 442 assertEquals(GRANTED_SCOPES, credentials.getAccessToken().getScopes()); 443 444 // Verify that the additional parameters from previous request are not attached to the post body 445 credentials = authorizer.getCredentialsFromCode(CODE, BASE_URI); 446 assertEquals(REFRESH_TOKEN, credentials.getRefreshToken()); 447 assertEquals(ACCESS_TOKEN_VALUE, credentials.getAccessToken().getTokenValue()); 448 assertEquals(GRANTED_SCOPES, credentials.getAccessToken().getScopes()); 449 } 450 451 @Test(expected = NullPointerException.class) getCredentialsFromCode_nullCode_throws()452 public void getCredentialsFromCode_nullCode_throws() throws IOException { 453 UserAuthorizer authorizer = 454 UserAuthorizer.newBuilder() 455 .setClientId(CLIENT_ID) 456 .setScopes(DUMMY_SCOPES) 457 .setTokenStore(new MemoryTokensStorage()) 458 .build(); 459 460 authorizer.getCredentialsFromCode(null, BASE_URI); 461 } 462 463 @Test getAndStoreCredentialsFromCode_getAndStoresCredentials()464 public void getAndStoreCredentialsFromCode_getAndStoresCredentials() throws IOException { 465 final String accessTokenValue1 = "1/MkSJoj1xsli0AccessToken_NKPY2"; 466 final String accessTokenValue2 = "2/MkSJoj1xsli0AccessToken_NKPY2"; 467 MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory(); 468 transportFactory.transport.addClient(CLIENT_ID_VALUE, CLIENT_SECRET); 469 transportFactory.transport.addAuthorizationCode( 470 CODE, REFRESH_TOKEN, accessTokenValue1, GRANTED_SCOPES_STRING, null); 471 TokenStore tokenStore = new MemoryTokensStorage(); 472 UserAuthorizer authorizer = 473 UserAuthorizer.newBuilder() 474 .setClientId(CLIENT_ID) 475 .setScopes(DUMMY_SCOPES) 476 .setTokenStore(tokenStore) 477 .setHttpTransportFactory(transportFactory) 478 .build(); 479 480 UserCredentials credentials1 = 481 authorizer.getAndStoreCredentialsFromCode(USER_ID, CODE, BASE_URI); 482 483 assertEquals(REFRESH_TOKEN, credentials1.getRefreshToken()); 484 assertEquals(GRANTED_SCOPES, credentials1.getAccessToken().getScopes()); 485 assertEquals(accessTokenValue1, credentials1.getAccessToken().getTokenValue()); 486 487 // Refresh the token to get update from token server 488 transportFactory.transport.addRefreshToken(REFRESH_TOKEN, accessTokenValue2); 489 credentials1.refresh(); 490 assertEquals(REFRESH_TOKEN, credentials1.getRefreshToken()); 491 assertEquals(accessTokenValue2, credentials1.getAccessToken().getTokenValue()); 492 493 // Load a second credentials instance 494 UserCredentials credentials2 = authorizer.getCredentials(USER_ID); 495 496 // Verify that token refresh stored the updated tokens 497 assertEquals(REFRESH_TOKEN, credentials2.getRefreshToken()); 498 assertEquals(GRANTED_SCOPES, credentials2.getAccessToken().getScopes()); 499 assertEquals(accessTokenValue2, credentials2.getAccessToken().getTokenValue()); 500 } 501 502 @Test(expected = NullPointerException.class) getAndStoreCredentialsFromCode_nullCode_throws()503 public void getAndStoreCredentialsFromCode_nullCode_throws() throws IOException { 504 UserAuthorizer authorizer = 505 UserAuthorizer.newBuilder() 506 .setClientId(CLIENT_ID) 507 .setScopes(DUMMY_SCOPES) 508 .setTokenStore(new MemoryTokensStorage()) 509 .build(); 510 511 authorizer.getAndStoreCredentialsFromCode(USER_ID, null, BASE_URI); 512 } 513 514 @Test(expected = NullPointerException.class) getAndStoreCredentialsFromCode_nullUserId_throws()515 public void getAndStoreCredentialsFromCode_nullUserId_throws() throws IOException { 516 UserAuthorizer authorizer = 517 UserAuthorizer.newBuilder() 518 .setClientId(CLIENT_ID) 519 .setScopes(DUMMY_SCOPES) 520 .setTokenStore(new MemoryTokensStorage()) 521 .build(); 522 523 authorizer.getAndStoreCredentialsFromCode(null, CODE, BASE_URI); 524 } 525 526 @Test revokeAuthorization_revokesAndClears()527 public void revokeAuthorization_revokesAndClears() throws IOException { 528 TokenStore tokenStore = new MemoryTokensStorage(); 529 MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory(); 530 transportFactory.transport.addClient(CLIENT_ID_VALUE, CLIENT_SECRET); 531 transportFactory.transport.addRefreshToken( 532 REFRESH_TOKEN, ACCESS_TOKEN_VALUE, GRANTED_SCOPES_STRING); 533 UserCredentials initialCredentials = 534 UserCredentials.newBuilder() 535 .setClientId(CLIENT_ID_VALUE) 536 .setClientSecret(CLIENT_SECRET) 537 .setRefreshToken(REFRESH_TOKEN) 538 .setAccessToken(ACCESS_TOKEN) 539 .build(); 540 541 UserAuthorizer authorizer = 542 UserAuthorizer.newBuilder() 543 .setClientId(CLIENT_ID) 544 .setScopes(DUMMY_SCOPES) 545 .setTokenStore(tokenStore) 546 .setHttpTransportFactory(transportFactory) 547 .build(); 548 549 authorizer.storeCredentials(USER_ID, initialCredentials); 550 551 UserCredentials credentials1 = authorizer.getCredentials(USER_ID); 552 553 assertEquals(REFRESH_TOKEN, credentials1.getRefreshToken()); 554 credentials1.refresh(); 555 assertEquals(ACCESS_TOKEN_VALUE, credentials1.getAccessToken().getTokenValue()); 556 assertEquals(GRANTED_SCOPES, credentials1.getAccessToken().getScopes()); 557 558 authorizer.revokeAuthorization(USER_ID); 559 560 try { 561 credentials1.refresh(); 562 fail("Credentials should not refresh after revoke."); 563 } catch (IOException expected) { 564 // Expected 565 } 566 UserCredentials credentials2 = authorizer.getCredentials(USER_ID); 567 assertNull(credentials2); 568 } 569 570 @Test(expected = IllegalArgumentException.class) nullCodeVerifierPKCEProvider()571 public void nullCodeVerifierPKCEProvider() { 572 PKCEProvider pkce = 573 new PKCEProvider() { 574 @Override 575 public String getCodeVerifier() { 576 return null; 577 } 578 579 @Override 580 public String getCodeChallengeMethod() { 581 return "dummy string"; 582 } 583 584 @Override 585 public String getCodeChallenge() { 586 return "dummy string"; 587 } 588 }; 589 590 UserAuthorizer authorizer = 591 UserAuthorizer.newBuilder() 592 .setClientId(CLIENT_ID) 593 .setScopes(DUMMY_SCOPES) 594 .setTokenStore(new MemoryTokensStorage()) 595 .setPKCEProvider(pkce) 596 .build(); 597 } 598 599 @Test(expected = IllegalArgumentException.class) nullCodeChallengePKCEProvider()600 public void nullCodeChallengePKCEProvider() { 601 PKCEProvider pkce = 602 new PKCEProvider() { 603 @Override 604 public String getCodeVerifier() { 605 return "dummy string"; 606 } 607 608 @Override 609 public String getCodeChallengeMethod() { 610 return "dummy string"; 611 } 612 613 @Override 614 public String getCodeChallenge() { 615 return null; 616 } 617 }; 618 619 UserAuthorizer authorizer = 620 UserAuthorizer.newBuilder() 621 .setClientId(CLIENT_ID) 622 .setScopes(DUMMY_SCOPES) 623 .setTokenStore(new MemoryTokensStorage()) 624 .setPKCEProvider(pkce) 625 .build(); 626 } 627 628 @Test(expected = IllegalArgumentException.class) nullCodeChallengeMethodPKCEProvider()629 public void nullCodeChallengeMethodPKCEProvider() { 630 PKCEProvider pkce = 631 new PKCEProvider() { 632 @Override 633 public String getCodeVerifier() { 634 return "dummy string"; 635 } 636 637 @Override 638 public String getCodeChallengeMethod() { 639 return null; 640 } 641 642 @Override 643 public String getCodeChallenge() { 644 return "dummy string"; 645 } 646 }; 647 648 UserAuthorizer authorizer = 649 UserAuthorizer.newBuilder() 650 .setClientId(CLIENT_ID) 651 .setScopes(DUMMY_SCOPES) 652 .setTokenStore(new MemoryTokensStorage()) 653 .setPKCEProvider(pkce) 654 .build(); 655 } 656 } 657