HaloAuthenticator implements Authenticator { @Override public synchronized Request authenticate(Route route, Response response) throws IOException { HaloSession session = mSessionManager.getSession(HALO_SESSION_NAME); try { if (session == null || session.isSessionExpired() || session.mayBeServerExpired()) { flushSession(); Token token = null; if (!response.request().url().toString().endsWith(TokenRemoteDatasource.URL_GET_CLIENT_TOKEN) && !response.request().url().toString().endsWith(TokenRemoteDatasource.URL_GET_USER_TOKEN)) { token = requestToken(); if (token != null) { session = new Session(token); } } } } catch (Exception e) { Halog.e(getClass(), "The token could not be obtained. " + e.getMessage()); throw e; } if (session != null) { if(getCredentials().getLoginType()==Credentials.CLIENT_BASED_LOGIN) { if (mAuthenticationRecover != null && !mAuthenticationRecover.recoverStatus()) { mAuthenticationRecover.recoverAccount(); } } mSessionManager.setSession(HALO_SESSION_NAME, session); return response.request() .newBuilder() .header(AUTHENTICATION_HEADER, session.getSessionAuthentication()) .build(); } return null; } HaloAuthenticator(@NonNull HaloFramework framework,
                             @NonNull HaloManagerApi managerApi,
                             @NonNull HaloSessionManager sessionManager,
                             @NonNull Credentials credentials); @Override synchronized Request authenticate(Route route, Response response); void setAuthenticationRecover(@NonNull AuthenticationRecover authenticationRecover); @Nullable AuthenticationRecover getAuthenticationRecover(); synchronized void setCredentials(@NonNull Credentials credentials); void logout(); @NonNull synchronized Credentials getCredentials(); void flushSession(); HaloSessionManager getSessionManager(); @Keep
    static final String HALO_SESSION_NAME; static final String AUTHENTICATION_HEADER; }
@Test public void thatExpiredTokenRefreshAfterARequest() throws IOException { enqueueServerFile(mMockServer, AUTHENTICATE); Response response = givenA200Response(); Token expiredToken = givenAExpiredToken(); Session session = new Session(expiredToken); mSessionManager.setSession(HaloAuthenticator.HALO_SESSION_NAME, session); Request newRequest = mAuthenticator.authenticate(null, response); assertThat(newRequest).isNotNull(); assertThat(newRequest.header("Authorization")).contains("Bearer LSD4fw4NLBTESfF18tTVEST6q9vsaLW8tMfEGLJa"); }
@Test public void thatARefreshTokenRenewSession() throws IOException { Response response = givenA200Response(); Token token = givenARefreshToken(); Session newSession = new Session(token); mSessionManager.setSession(HaloAuthenticator.HALO_SESSION_NAME, newSession); Request newRequest = mAuthenticator.authenticate(null, response); assertThat(newRequest).isNotNull(); assertThat(newRequest.header("Authorization")).isEqualTo(token.getAuthorization()); }
@Test public void thatCanAuthenticateNewTokenSessionWhenRefreshToken() throws IOException { Token token = givenARefreshToken(); Response response = givenA200Response(); Session session = new Session(token); mSessionManager.setSession(HaloAuthenticator.HALO_SESSION_NAME, session); Request newRequest = mAuthenticator.authenticate(null, response); assertThat(newRequest).isNotNull(); assertThat(newRequest.header("Authorization")).isEqualTo(token.getAuthorization()); }
@Test public void thatCanAuthenticateANewTokenAndSessionIfSessionIsExpired() throws IOException { enqueueServerError(mMockServer, 401); Token token = givenAToken(); Session newSession = new Session(token); Response response = givenA200Response(); mSessionManager.setSession(HaloAuthenticator.HALO_SESSION_NAME, newSession); Request newRequest = mAuthenticator.authenticate(null, response); assertThat(newRequest).isNotNull(); assertThat(newRequest.header("Authorization")).isEqualTo(token.getAuthorization()); }
@Test public void thatRenewTokenIsNotCalledToAvoidLoopWithClientToken() throws IOException { enqueueServerError(mMockServer, 401); Response response = givenA401ClientTokenResponse(); Request newRequest = mAuthenticator.authenticate(null, response); assertThat(newRequest).isNull(); }
@Test public void thatRenewTokenIsNotCalledToAvoidLoopWithUserToken() throws IOException { enqueueServerError(mMockServer, 401); Response response = givenA401UserTokenResponse(); Request newRequest = mAuthenticator.authenticate(null, response); assertThat(newRequest).isNull(); }