private Map<String, String> getAuthData(String authType) { return getAuthData().get(authType); }
/** * Indicates whether this user is linked with a third party authentication source. * <p/> * <strong>Note:</strong> This shouldn't be called directly unless developing a third party authentication * library. * * @param authType The name of the third party authentication source. * @return {@code true} if linked, otherwise {@code false}. * @see AuthenticationCallback */ public boolean isLinked(String authType) { Map<String, Map<String, String>> authData = getAuthData(); return authData.containsKey(authType) && authData.get(authType) != null; }
private void removeAuthData(String authType) { synchronized (mutex) { Map<String, Map<String, String>> newAuthData = getAuthData(); newAuthData.remove(authType); performPut(KEY_AUTH_DATA, newAuthData); } }
/* package */ void putAuthData(String authType, Map<String, String> authData) { synchronized (mutex) { Map<String, Map<String, String>> newAuthData = getAuthData(); newAuthData.put(authType, authData); performPut(KEY_AUTH_DATA, newAuthData); } }
/** * Ensures that all auth sources have auth data (e.g. access tokens, etc.) that matches this * user. */ /* package */ Task<Void> synchronizeAllAuthDataAsync() { Map<String, Map<String, String>> authData; synchronized (mutex) { if (!isCurrentUser()) { return Task.forResult(null); } authData = getAuthData(); } List<Task<Void>> tasks = new ArrayList<>(authData.size()); for (String authType : authData.keySet()) { tasks.add(synchronizeAuthDataAsync(authType)); } return Task.whenAll(tasks); }
/** * Unlinks this user from a third party authentication source. * <p/> * <strong>Note:</strong> This shouldn't be called directly unless developing a third party authentication * library. * * @param authType The name of the third party authentication source. * @return A {@code Task} is resolved when unlinking completes. * @see AuthenticationCallback */ public Task<Void> unlinkFromInBackground(final String authType) { if (authType == null) { return Task.forResult(null); } synchronized (mutex) { if (!getAuthData().containsKey(authType)) { return Task.forResult(null); } putAuthData(authType, null); } return saveInBackground(); }
/* package */ Task<Void> synchronizeAuthDataAsync(String authType) { Map<String, String> authData; synchronized (mutex) { if (!isCurrentUser()) { return Task.forResult(null); } authData = getAuthData(authType); } return synchronizeAuthDataAsync(getAuthenticationManager(), authType, authData); }
@Override /* package */ void setState(ParseObject.State newState) { if (isCurrentUser()) { State.Builder newStateBuilder = newState.newBuilder(); // Avoid clearing sessionToken when updating the current user's State via ParseQuery result if (getSessionToken() != null && newState.get(KEY_SESSION_TOKEN) == null) { newStateBuilder.put(KEY_SESSION_TOKEN, getSessionToken()); } // Avoid clearing authData when updating the current user's State via ParseQuery result if (getAuthData().size() > 0 && newState.get(KEY_AUTH_DATA) == null) { newStateBuilder.put(KEY_AUTH_DATA, getAuthData()); } newState = newStateBuilder.build(); } super.setState(newState); }
/* package */ Task<Void> logOutAsync(boolean revoke) { ParseAuthenticationManager controller = getAuthenticationManager(); List<Task<Void>> tasks = new ArrayList<>(); final String oldSessionToken; synchronized (mutex) { oldSessionToken = getState().sessionToken(); for (Map.Entry<String, Map<String, String>> entry : getAuthData().entrySet()) { tasks.add(controller.deauthenticateAsync(entry.getKey())); } State newState = getState().newBuilder() .sessionToken(null) .isNew(false) .build(); isCurrentUser = false; setState(newState); } if (revoke) { tasks.add(ParseSession.revokeAsync(oldSessionToken)); } return Task.whenAll(tasks); }
private Task<Void> linkWithAsync( final String authType, final Map<String, String> authData, final Task<Void> toAwait, final String sessionToken) { synchronized (mutex) { final boolean isLazy = isLazy(); final Map<String, String> oldAnonymousData = getAuthData(ParseAnonymousUtils.AUTH_TYPE); stripAnonymity(); putAuthData(authType, authData); return saveAsync(sessionToken, isLazy, toAwait).continueWithTask(new Continuation<Void, Task<Void>>() { @Override public Task<Void> then(Task<Void> task) { synchronized (mutex) { if (task.isFaulted() || task.isCancelled()) { removeAuthData(authType); restoreAnonymity(oldAnonymousData); return task; } return synchronizeAuthDataAsync(authType); } } }); } }
.saveAsync(eq("sessionTokenAgain"), eq(false), Matchers.<Task<Void>>any()); assertSame(anonymousAuthData, partialMockUser.getAuthData().get(ParseAnonymousUtils.AUTH_TYPE)); assertNull(partialMockUser.getAuthData().get("facebook"));
@Test public void testLoginWithAsyncWithLinkedLazyUser() throws Exception { // Register a mock currentUserController to make getCurrentUser work ParseUser currentUser = new ParseUser(); currentUser.putAuthData(ParseAnonymousUtils.AUTH_TYPE, new HashMap<String, String>()); setLazy(currentUser); ParseUser partialMockCurrentUser = spy(currentUser); when(partialMockCurrentUser.getSessionToken()).thenReturn("oldSessionToken"); doReturn(Task.<ParseUser>forResult(null)) .when(partialMockCurrentUser) .resolveLazinessAsync(Matchers.<Task<Void>>any()); ParseCurrentUserController currentUserController = mock(ParseCurrentUserController.class); when(currentUserController.getAsync(false)).thenReturn(Task.forResult(partialMockCurrentUser)); ParseCorePlugins.getInstance().registerCurrentUserController(currentUserController); String authType = "facebook"; Map<String, String> authData = new HashMap<>(); authData.put("token", "123"); ParseUser userAfterLogin = ParseTaskUtils.wait(ParseUser.logInWithInBackground(authType, authData)); // Make sure we stripAnonymity assertNull(userAfterLogin.getAuthData().get(ParseAnonymousUtils.AUTH_TYPE)); // Make sure we update authData assertEquals(authData, userAfterLogin.getAuthData().get("facebook")); // Make sure we resolveLaziness verify(partialMockCurrentUser, times(1)).resolveLazinessAsync(Matchers.<Task<Void>>any()); }
@Test public void testLoginWithAsyncWithLinkedLazyUseAndResolveLazinessFailure() throws Exception { // Register a mock currentUserController to make getCurrentUser work ParseUser currentUser = new ParseUser(); Map<String, String> oldAnonymousAuthData = new HashMap<>(); oldAnonymousAuthData.put("oldKey", "oldToken"); currentUser.putAuthData(ParseAnonymousUtils.AUTH_TYPE, oldAnonymousAuthData); ParseUser partialMockCurrentUser = spy(currentUser); when(partialMockCurrentUser.getSessionToken()).thenReturn("oldSessionToken"); doReturn(Task.<ParseUser>forError(new Exception())) .when(partialMockCurrentUser) .resolveLazinessAsync(Matchers.<Task<Void>>any()); ParseCurrentUserController currentUserController = mock(ParseCurrentUserController.class); when(currentUserController.getAsync(false)).thenReturn(Task.forResult(partialMockCurrentUser)); ParseCorePlugins.getInstance().registerCurrentUserController(currentUserController); String authType = "facebook"; Map<String, String> authData = new HashMap<>(); authData.put("token", "123"); Task<ParseUser> loginTask = ParseUser.logInWithInBackground(authType, authData); loginTask.waitForCompletion(); // Make sure we try to resolveLaziness verify(partialMockCurrentUser, times(1)).resolveLazinessAsync(Matchers.<Task<Void>>any()); // Make sure we do not save new authData assertNull(partialMockCurrentUser.getAuthData().get("facebook")); // Make sure we restore anonymity after resolve laziness failure assertEquals(oldAnonymousAuthData, partialMockCurrentUser.getAuthData() .get(ParseAnonymousUtils.AUTH_TYPE)); // Make sure task fails assertTrue(loginTask.isFaulted()); }
@Test public void testUnlinkFromAsyncWithAuthType() throws Exception { // Register a mock currentUserController to make getAsync work ParseUser mockUser = mock(ParseUser.class); when(mockUser.getSessionToken()).thenReturn("sessionToken"); ParseCurrentUserController currentUserController = mock(ParseCurrentUserController.class); when(currentUserController.getAsync()).thenReturn(Task.forResult(mockUser)); ParseCorePlugins.getInstance().registerCurrentUserController(currentUserController); // Set user initial state String authType = "facebook"; Map<String, String> authData = new HashMap<>(); authData.put("facebookToken", "facebookTest"); ParseUser.State userState = new ParseUser.State.Builder() .objectId("test") .putAuthData(authType, authData) .build(); ParseUser user = ParseObject.from(userState); ParseUser partialMockUser = spy(user); doReturn(Task.<Void>forResult(null)) .when(partialMockUser) .saveAsync(anyString(), Matchers.<Task<Void>>any()); ParseTaskUtils.wait(partialMockUser.unlinkFromInBackground(authType)); // Verify we delete authData assertNull(user.getAuthData().get("facebook")); // Verify we save the user verify(partialMockUser, times(1)).saveAsync(eq("sessionToken"), Matchers.<Task<Void>>any()); }
assertNull(partialMockUser.getAuthData().get(ParseAnonymousUtils.AUTH_TYPE)); assertSame(authData, partialMockUser.getAuthData().get("facebook"));
when(currentUser.isLinked(ParseAnonymousUtils.AUTH_TYPE)).thenReturn(true); when(currentUser.getSessionToken()).thenReturn("oldSessionToken"); when(currentUser.getAuthData()).thenReturn(new HashMap<String, Map<String, String>>()); when(currentUser.saveAsync(anyString(), eq(false), Matchers.<Task<Void>>any())) .thenReturn(Task.<Void>forResult(null));
@Test public void testSaveAsyncWithLazyAndCurrentUser() throws Exception { // Register a mock currentUserController to make setCurrentUser work ParseCurrentUserController currentUserController = mock(ParseCurrentUserController.class); when(currentUserController.setAsync(any(ParseUser.class))) .thenReturn(Task.<Void>forResult(null)); ParseCorePlugins.getInstance().registerCurrentUserController(currentUserController); // Set facebook authData to null to verify cleanAuthData() ParseUser.State userState = new ParseUser.State.Builder() .putAuthData("facebook", null) .build(); ParseUser user = ParseObject.from(userState); setLazy(user); user.setIsCurrentUser(true); ParseUser partialMockUser = spy(user); doReturn(Task.<Void>forResult(null)) .when(partialMockUser) .resolveLazinessAsync(Matchers.<Task<Void>>any()); ParseTaskUtils.wait(partialMockUser.saveAsync("sessionToken", Task.<Void>forResult(null))); // Make sure we clean authData assertFalse(partialMockUser.getAuthData().containsKey("facebook")); // Make sure we save new currentUser verify(currentUserController, times(1)).setAsync(partialMockUser); }
@Test public void testSaveAsyncWithLazyAndNotCurrentUser() throws Exception { // Register a mock currentUserController to make setCurrentUser work ParseCurrentUserController currentUserController = mock(ParseCurrentUserController.class); when(currentUserController.setAsync(any(ParseUser.class))) .thenReturn(Task.<Void>forResult(null)); ParseCorePlugins.getInstance().registerCurrentUserController(currentUserController); // Set facebook authData to null to verify cleanAuthData() ParseUser.State userState = new ParseUser.State.Builder() .putAuthData("facebook", null) .build(); ParseUser user = ParseObject.from(userState); setLazy(user); user.setIsCurrentUser(false); ParseUser partialMockUser = spy(user); doReturn(Task.<Void>forResult(null)) .when(partialMockUser) .resolveLazinessAsync(Matchers.<Task<Void>>any()); ParseTaskUtils.wait(partialMockUser.saveAsync("sessionToken", Task.<Void>forResult(null))); // Make sure we do not clean authData assertTrue(partialMockUser.getAuthData().containsKey("facebook")); // Make sure we do not save new currentUser verify(currentUserController, never()).setAsync(partialMockUser); }
@Test public void testSetCurrentUserStateWithoutAuthData() { // Set user initial state String authType = "facebook"; Map<String, String> authData = new HashMap<>(); authData.put("facebookToken", "facebookTest"); ParseUser.State userState = new ParseUser.State.Builder() .objectId("test") .put("oldKey", "oldValue") .put("key", "value") .putAuthData(authType, authData) .build(); ParseUser user = ParseObject.from(userState); user.setIsCurrentUser(true); // Build new state ParseUser.State newUserState = new ParseUser.State.Builder() .objectId("testAgain") .put("key", "valueAgain") .build(); user.setState(newUserState); // Make sure we keep the authData assertEquals(1, user.getAuthData().size()); assertEquals(authData, user.getAuthData().get(authType)); // Make sure old state is replaced assertFalse(user.has("oldKey")); // Make sure new state is set assertEquals("testAgain", user.getObjectId()); assertEquals("valueAgain", user.get("key")); }
@Test public void testSetStateDoesNotAddNonExistentAuthData() { // Set user initial state ParseUser.State userState = new ParseUser.State.Builder() .objectId("test") .put("oldKey", "oldValue") .put("key", "value") .build(); ParseUser user = ParseObject.from(userState); user.setIsCurrentUser(true); // Build new state ParseUser.State newUserState = new ParseUser.State.Builder() .objectId("testAgain") .put("key", "valueAgain") .build(); user.setState(newUserState); // Make sure we do not add authData when it did not exist before assertFalse(user.keySet().contains("authData")); assertEquals(1, user.keySet().size()); assertEquals(0, user.getAuthData().size()); // Make sure old state is replaced assertFalse(user.has("oldKey")); // Make sure new state is set assertEquals("testAgain", user.getObjectId()); assertEquals("valueAgain", user.get("key")); }