use of io.realm.internal.network.AuthenticateResponse 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);
}
}
use of io.realm.internal.network.AuthenticateResponse in project realm-java by realm.
the class SyncSession method authenticateRealm.
// Authenticate by getting access tokens for the specific Realm
private void authenticateRealm(final AuthenticationServer authServer) {
if (networkRequest != null) {
networkRequest.cancel();
}
clearScheduledAccessTokenRefresh();
// Authenticate in a background thread. This allows incremental backoff and retries in a safe manner.
Future<?> task = SyncManager.NETWORK_POOL_EXECUTOR.submit(new ExponentialBackoffTask<AuthenticateResponse>() {
@Override
protected AuthenticateResponse execute() {
if (!isClosed && !Thread.currentThread().isInterrupted()) {
return authServer.loginToRealm(//refresh token in fact
getUser().getAccessToken(), configuration.getServerUrl(), getUser().getSyncUser().getAuthenticationUrl());
}
return null;
}
@Override
protected void onSuccess(AuthenticateResponse response) {
RealmLog.debug("Session[%s]: Access token acquired", configuration.getPath());
if (!isClosed && !Thread.currentThread().isInterrupted()) {
ObjectServerUser.AccessDescription desc = new ObjectServerUser.AccessDescription(response.getAccessToken(), configuration.getPath(), configuration.shouldDeleteRealmOnLogout());
getUser().getSyncUser().addRealm(configuration.getServerUrl(), desc);
// schedule a token refresh before it expires
if (nativeRefreshAccessToken(configuration.getPath(), getUser().getSyncUser().getAccessToken(configuration.getServerUrl()).value(), configuration.getServerUrl().toString())) {
scheduleRefreshAccessToken(authServer, response.getAccessToken().expiresMs());
} else {
// token not applied, no refresh will be scheduled
onGoingAccessTokenQuery.set(false);
}
}
}
@Override
protected void onError(AuthenticateResponse response) {
onGoingAccessTokenQuery.set(false);
RealmLog.debug("Session[%s]: Failed to get access token (%d)", configuration.getPath(), response.getError().getErrorCode());
if (!isClosed && !Thread.currentThread().isInterrupted()) {
errorHandler.onError(SyncSession.this, response.getError());
}
}
});
networkRequest = new RealmAsyncTaskImpl(task, SyncManager.NETWORK_POOL_EXECUTOR);
}
use of io.realm.internal.network.AuthenticateResponse in project realm-java by realm.
the class SyncSession method refreshAccessToken.
// Authenticate by getting access tokens for the specific Realm
private void refreshAccessToken(final AuthenticationServer authServer) {
// Authenticate in a background thread. This allows incremental backoff and retries in a safe manner.
clearScheduledAccessTokenRefresh();
Future<?> task = SyncManager.NETWORK_POOL_EXECUTOR.submit(new ExponentialBackoffTask<AuthenticateResponse>() {
@Override
protected AuthenticateResponse execute() {
if (!isClosed && !Thread.currentThread().isInterrupted()) {
return authServer.refreshUser(getUser().getSyncUser().getUserToken(), configuration.getServerUrl(), getUser().getSyncUser().getAuthenticationUrl());
}
return null;
}
@Override
protected void onSuccess(AuthenticateResponse response) {
synchronized (SyncSession.this) {
if (!isClosed && !Thread.currentThread().isInterrupted()) {
RealmLog.debug("Access Token refreshed successfully, Sync URL: " + configuration.getServerUrl());
if (nativeRefreshAccessToken(configuration.getPath(), response.getAccessToken().value(), configuration.getUser().getAuthenticationUrl().toString())) {
// replaced the user old access_token
ObjectServerUser.AccessDescription desc = new ObjectServerUser.AccessDescription(response.getAccessToken(), configuration.getPath(), configuration.shouldDeleteRealmOnLogout());
getUser().getSyncUser().addRealm(configuration.getServerUrl(), desc);
// schedule the next refresh
scheduleRefreshAccessToken(authServer, response.getAccessToken().expiresMs());
}
}
}
}
@Override
protected void onError(AuthenticateResponse response) {
if (!isClosed && !Thread.currentThread().isInterrupted()) {
onGoingAccessTokenQuery.set(false);
RealmLog.error("Unrecoverable error, while refreshing the access Token (" + response.getError().toString() + ") reschedule will not happen");
}
}
});
refreshTokenNetworkRequest = new RealmAsyncTaskImpl(task, SyncManager.NETWORK_POOL_EXECUTOR);
}
use of io.realm.internal.network.AuthenticateResponse 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;
}
Aggregations