Search in sources :

Example 1 with AuthenticationServer

use of io.realm.internal.network.AuthenticationServer in project realm-java by realm.

the class SyncUser method logout.

/**
     * Logs out the user from the Realm Object Server. Once the Object Server has confirmed the logout any registered
     * {@link AuthenticationListener} will be notified and user credentials will be deleted from this device.
     *
     * @throws IllegalStateException if any Realms owned by this user is still open. They should be closed before
     *         logging out.
     */
/* FIXME: Add this back to the javadoc when enable SyncConfiguration.Builder#deleteRealmOnLogout()
     <p>
     Any Realms owned by the user will be deleted if {@link SyncConfiguration.Builder#deleteRealmOnLogout()} is
     also set.
     */
public void logout() {
    // Acquire lock to prevent users creating new instances
    synchronized (Realm.class) {
        if (!syncUser.isLoggedIn()) {
            // Already local/global logout status
            return;
        }
        // Ensure that we can log out. If any Realm file is still open we should abort before doing anything
        // else.
        Collection<SyncSession> sessions = syncUser.getSessions();
        for (SyncSession session : sessions) {
            SyncConfiguration config = session.getConfiguration();
            if (Realm.getGlobalInstanceCount(config) > 0) {
                throw new IllegalStateException("A Realm controlled by this user is still open. Close all Realms " + "before logging out: " + config.getPath());
            }
        }
        SyncManager.getUserStore().remove(syncUser.getIdentity());
        // Delete all Realms if needed.
        for (ObjectServerUser.AccessDescription desc : syncUser.getRealms()) {
            // disabled. Make sure this works for Realm opened in the client thread/other processes.
            if (desc.deleteOnLogout) {
                File realmFile = new File(desc.localPath);
                if (realmFile.exists() && !Util.deleteRealm(desc.localPath, realmFile.getParentFile(), realmFile.getName())) {
                    RealmLog.error("Could not delete Realm when user logged out: " + desc.localPath);
                }
            }
        }
        // Remove all local tokens, preventing further connections.
        final Token userToken = syncUser.getUserToken();
        syncUser.clearTokens();
        syncUser.localLogout();
        // Finally revoke server token. The local user is logged out in any case.
        final AuthenticationServer server = SyncManager.getAuthServer();
        ThreadPoolExecutor networkPoolExecutor = SyncManager.NETWORK_POOL_EXECUTOR;
        networkPoolExecutor.submit(new ExponentialBackoffTask<LogoutResponse>() {

            @Override
            protected LogoutResponse execute() {
                return server.logout(userToken, syncUser.getAuthenticationUrl());
            }

            @Override
            protected void onSuccess(LogoutResponse response) {
                SyncManager.notifyUserLoggedOut(SyncUser.this);
            }

            @Override
            protected void onError(LogoutResponse response) {
                RealmLog.error("Failed to log user out.\n" + response.getError().toString());
            }
        });
    }
}
Also used : LogoutResponse(io.realm.internal.network.LogoutResponse) Token(io.realm.internal.objectserver.Token) AuthenticationServer(io.realm.internal.network.AuthenticationServer) ObjectServerUser(io.realm.internal.objectserver.ObjectServerUser) ThreadPoolExecutor(java.util.concurrent.ThreadPoolExecutor) File(java.io.File)

Example 2 with AuthenticationServer

use of io.realm.internal.network.AuthenticationServer in project realm-java by realm.

the class SyncUserTests method login_withAccessToken.

// Test that a login with an access token logs the user in directly without touching the network
@Test
public void login_withAccessToken() {
    AuthenticationServer authServer = Mockito.mock(AuthenticationServer.class);
    when(authServer.loginUser(any(SyncCredentials.class), any(URL.class))).thenThrow(new AssertionError("Server contacted."));
    AuthenticationServer originalServer = SyncManager.getAuthServer();
    SyncManager.setAuthServerImpl(authServer);
    try {
        SyncCredentials credentials = SyncCredentials.accessToken("foo", "bar");
        SyncUser user = SyncUser.login(credentials, "http://ros.realm.io/auth");
        assertTrue(user.isValid());
    } finally {
        SyncManager.setAuthServerImpl(originalServer);
    }
}
Also used : AuthenticationServer(io.realm.internal.network.AuthenticationServer) URL(java.net.URL) Test(org.junit.Test)

Example 3 with AuthenticationServer

use of io.realm.internal.network.AuthenticationServer in project realm-java by realm.

the class SyncUser method login.

/**
     * Logs in the user to the Realm Object Server. This is done synchronously, so calling this method on the Android
     * UI thread will always crash. A logged in user is required to be able to create a {@link SyncConfiguration}.
     *
     * @param credentials credentials to use.
     * @param authenticationUrl server that can authenticate against.
     * @throws ObjectServerError if the login failed.
     * @throws IllegalArgumentException if the URL is malformed.
     */
public static SyncUser login(final SyncCredentials credentials, final String authenticationUrl) throws ObjectServerError {
    final URL authUrl;
    try {
        authUrl = new URL(authenticationUrl);
    } catch (MalformedURLException e) {
        throw new IllegalArgumentException("Invalid URL " + authenticationUrl + ".", e);
    }
    ObjectServerError error;
    try {
        AuthenticateResponse result;
        if (credentials.getIdentityProvider().equals(SyncCredentials.IdentityProvider.ACCESS_TOKEN)) {
            // Credentials using ACCESS_TOKEN as IdentityProvider are optimistically assumed to be valid already.
            // So log them in directly without contacting the authentication server. This is done by mirroring
            // the JSON response expected from the server.
            String userIdentifier = credentials.getUserIdentifier();
            String token = (String) credentials.getUserInfo().get("_token");
            result = AuthenticateResponse.createValidResponseWithUser(userIdentifier, token);
        } else {
            final AuthenticationServer server = SyncManager.getAuthServer();
            result = server.loginUser(credentials, authUrl);
        }
        if (result.isValid()) {
            ObjectServerUser syncUser = new ObjectServerUser(result.getRefreshToken(), authUrl);
            SyncUser user = new SyncUser(syncUser);
            RealmLog.info("Succeeded authenticating user.\n%s", user);
            SyncManager.getUserStore().put(user);
            SyncManager.notifyUserLoggedIn(user);
            return user;
        } else {
            RealmLog.info("Failed authenticating user.\n%s", result.getError());
            error = result.getError();
        }
    } catch (Throwable e) {
        throw new ObjectServerError(ErrorCode.UNKNOWN, e);
    }
    throw error;
}
Also used : AuthenticateResponse(io.realm.internal.network.AuthenticateResponse) MalformedURLException(java.net.MalformedURLException) AuthenticationServer(io.realm.internal.network.AuthenticationServer) ObjectServerUser(io.realm.internal.objectserver.ObjectServerUser) URL(java.net.URL)

Example 4 with AuthenticationServer

use of io.realm.internal.network.AuthenticationServer in project realm-java by realm.

the class AuthenticateRequestTests method errorsNotWrapped.

@Test
public void errorsNotWrapped() {
    AuthenticationServer originalAuthServer = SyncManager.getAuthServer();
    AuthenticationServer authServer = Mockito.mock(AuthenticationServer.class);
    when(authServer.loginUser(any(SyncCredentials.class), any(URL.class))).thenReturn(SyncTestUtils.createErrorResponse(ErrorCode.ACCESS_DENIED));
    SyncManager.setAuthServerImpl(authServer);
    try {
        SyncUser.login(SyncCredentials.facebook("foo"), "http://foo.bar/auth");
        fail();
    } catch (ObjectServerError e) {
        assertEquals(ErrorCode.ACCESS_DENIED, e.getErrorCode());
    } finally {
        // Reset the auth server implementation for other tests.
        SyncManager.setAuthServerImpl(originalAuthServer);
    }
}
Also used : AuthenticationServer(io.realm.internal.network.AuthenticationServer) URL(java.net.URL) Test(org.junit.Test)

Example 5 with AuthenticationServer

use of io.realm.internal.network.AuthenticationServer in project realm-java by realm.

the class SyncUserTests method currentUser_throwsIfMultipleUsersLoggedIn.

@Test
public void currentUser_throwsIfMultipleUsersLoggedIn() {
    AuthenticationServer originalAuthServer = SyncManager.getAuthServer();
    AuthenticationServer authServer = Mockito.mock(AuthenticationServer.class);
    SyncManager.setAuthServerImpl(authServer);
    try {
        // 1. Login two random users
        when(authServer.loginUser(any(SyncCredentials.class), any(URL.class))).thenAnswer(new Answer<AuthenticateResponse>() {

            @Override
            public AuthenticateResponse answer(InvocationOnMock invocationOnMock) throws Throwable {
                return getNewRandomUser();
            }
        });
        SyncUser.login(SyncCredentials.facebook("foo"), "http:/test.realm.io/auth");
        SyncUser.login(SyncCredentials.facebook("foo"), "http:/test.realm.io/auth");
        // 2. Verify currentUser() now throws
        try {
            SyncUser.currentUser();
            fail();
        } catch (IllegalStateException ignore) {
        }
    } finally {
        SyncManager.setAuthServerImpl(originalAuthServer);
    }
}
Also used : AuthenticateResponse(io.realm.internal.network.AuthenticateResponse) AuthenticationServer(io.realm.internal.network.AuthenticationServer) InvocationOnMock(org.mockito.invocation.InvocationOnMock) URL(java.net.URL) Test(org.junit.Test)

Aggregations

AuthenticationServer (io.realm.internal.network.AuthenticationServer)5 URL (java.net.URL)4 Test (org.junit.Test)3 AuthenticateResponse (io.realm.internal.network.AuthenticateResponse)2 ObjectServerUser (io.realm.internal.objectserver.ObjectServerUser)2 LogoutResponse (io.realm.internal.network.LogoutResponse)1 Token (io.realm.internal.objectserver.Token)1 File (java.io.File)1 MalformedURLException (java.net.MalformedURLException)1 ThreadPoolExecutor (java.util.concurrent.ThreadPoolExecutor)1 InvocationOnMock (org.mockito.invocation.InvocationOnMock)1