@Override /* package */ Task<Void> saveAsync(String sessionToken, Task<Void> toAwait) { return saveAsync(sessionToken, isLazy(), toAwait); }
@SuppressWarnings("unchecked") @Override /* package */ <T extends ParseObject> Task<T> fetchFromLocalDatastoreAsync() { // Same as #fetch() if (isLazy()) { return Task.forResult((T) this); } return super.fetchFromLocalDatastoreAsync(); }
/** * Set whether the given user is allowed to read this object. */ public void setReadAccess(ParseUser user, boolean allowed) { if (user.getObjectId() == null) { if (user.isLazy()) { setUnresolvedReadAccess(user, allowed); return; } throw new IllegalArgumentException("cannot setReadAccess for a user with null id"); } setReadAccess(user.getObjectId(), allowed); }
/** * Set whether the given user is allowed to write this object. */ public void setWriteAccess(ParseUser user, boolean allowed) { if (user.getObjectId() == null) { if (user.isLazy()) { setUnresolvedWriteAccess(user, allowed); return; } throw new IllegalArgumentException("cannot setWriteAccess for a user with null id"); } setWriteAccess(user.getObjectId(), allowed); }
/** * Whether the ParseUser has been authenticated on this device. This will be true if the ParseUser * was obtained via a logIn or signUp method. Only an authenticated ParseUser can be saved (with * altered attributes) and deleted. */ public boolean isAuthenticated() { synchronized (mutex) { ParseUser current = ParseUser.getCurrentUser(); return isLazy() || (getState().sessionToken() != null && current != null && getObjectId().equals(current.getObjectId())); } }
/** * Get whether the given user id is *explicitly* allowed to write this object. Even if this * returns {@code false}, the user may still be able to write it if getPublicWriteAccess returns * {@code true} or a role that the user belongs to has write access. */ public boolean getWriteAccess(ParseUser user) { if (isUnresolvedUser(user)) { return getWriteAccess(UNRESOLVED_KEY); } if (user.isLazy()) { return false; } if (user.getObjectId() == null) { throw new IllegalArgumentException("cannot getWriteAccess for a user with null id"); } return getWriteAccess(user.getObjectId()); }
/** * Get whether the given user id is *explicitly* allowed to read this object. Even if this returns * {@code false}, the user may still be able to access it if getPublicReadAccess returns * {@code true} or a role that the user belongs to has read access. */ public boolean getReadAccess(ParseUser user) { if (isUnresolvedUser(user)) { return getReadAccess(UNRESOLVED_KEY); } if (user.isLazy()) { return false; } if (user.getObjectId() == null) { throw new IllegalArgumentException("cannot getReadAccess for a user with null id"); } return getReadAccess(user.getObjectId()); }
@Test public void testGetUserWriteAccessWithLazyUser() { ParseACL acl = new ParseACL(); ParseUser user = mock(ParseUser.class); when(user.isLazy()).thenReturn(true); assertFalse(acl.getWriteAccess(user)); }
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); } } }); } }
@Test public void testSetUserReadAccessWithLazyUser() { ParseUser unresolvedUser = mock(ParseUser.class); when(unresolvedUser.isLazy()).thenReturn(true); ParseACL acl = new ParseACL(); acl.setReadAccess(unresolvedUser, true); assertSame(unresolvedUser, acl.getUnresolvedUser()); verify(unresolvedUser, times(1)).registerSaveListener(any(GetCallback.class)); assertTrue(acl.getPermissionsById().containsKey(UNRESOLVED_KEY)); assertTrue(acl.getReadAccess(unresolvedUser)); assertEquals(1, acl.getPermissionsById().size()); }
@Test public void testSetUserWriteAccessWithLazyUser() { ParseUser user = mock(ParseUser.class); when(user.isLazy()).thenReturn(true); ParseACL acl = new ParseACL(); acl.setWriteAccess(user, true); assertSame(user, acl.getUnresolvedUser()); verify(user, times(1)).registerSaveListener(any(GetCallback.class)); assertTrue(acl.getPermissionsById().containsKey(UNRESOLVED_KEY)); assertTrue(acl.getWriteAccess(user)); assertEquals(1, acl.getPermissionsById().size()); } //endregion
@SuppressWarnings("unchecked") @Override /* package */ <T extends ParseObject> Task<T> fetchAsync( String sessionToken, Task<Void> toAwait) { //TODO (grantland): It doesn't seem like we should do this.. Why don't we error like we do // when fetching an unsaved ParseObject? if (isLazy()) { return Task.forResult((T) this); } Task<T> task = super.fetchAsync(sessionToken, toAwait); if (isCurrentUser()) { return task.onSuccessTask(new Continuation<T, Task<Void>>() { @Override public Task<Void> then(final Task<T> fetchAsyncTask) { return cleanUpAuthDataAsync(); } }).onSuccessTask(new Continuation<Void, Task<Void>>() { @Override public Task<Void> then(Task<Void> task) { return saveCurrentUserAsync(ParseUser.this); } }).onSuccess(new Continuation<Void, T>() { @Override public T then(Task<Void> task) { return (T) ParseUser.this; } }); } return task; }
@Test public void testGetAsyncLazyAnonymousUser() throws Exception { ParseUser.State state = new ParseUser.State.Builder() .putAuthData(ParseAnonymousUtils.AUTH_TYPE, new HashMap<String, String>()) .build(); ParseObjectStore<ParseUser> store = (ParseObjectStore<ParseUser>) mock(ParseObjectStore.class); when(store.getAsync()).thenReturn(Task.forResult(ParseObject.<ParseUser>from(state))); CachedCurrentUserController controller = new CachedCurrentUserController(store); ParseUser user = ParseTaskUtils.wait(controller.getAsync(false)); assertTrue(user.isLazy()); }
@Test public void testGetAsyncWithCurrentUserReadFromDiskFailureAndLazyLogin() throws Exception { ParseObjectStore<ParseUser> store = (ParseObjectStore<ParseUser>) mock(ParseObjectStore.class); when(store.getAsync()).thenReturn(Task.<ParseUser>forError(new RuntimeException("failure"))); CachedCurrentUserController controller = new CachedCurrentUserController(store); ParseUser currentUser = ParseTaskUtils.wait(controller.getAsync(true)); // We need to make sure the user is created by lazy login assertTrue(currentUser.isLazy()); assertTrue(currentUser.isCurrentUser()); assertSame(controller.currentUser, currentUser); assertFalse(controller.currentUserMatchesDisk); // We do not test the lazy login auth data here, it is covered in lazyLogin() unit test }
@Test public void testLazyLogin() { CachedCurrentUserController controller = new CachedCurrentUserController(null); String authType = ParseAnonymousUtils.AUTH_TYPE; Map<String, String> authData = new HashMap<>(); authData.put("sessionToken", "testSessionToken"); ParseUser user = controller.lazyLogIn(authType, authData); // Make sure use is generated through lazyLogin assertTrue(user.isLazy()); assertTrue(user.isCurrentUser()); Map<String, Map<String, String>> authPair = user.getMap(KEY_AUTH_DATA); assertEquals(1, authPair.size()); Map<String, String> authDataAgain = authPair.get(authType); assertEquals(1, authDataAgain.size()); assertEquals("testSessionToken", authDataAgain.get("sessionToken")); // Make sure controller state is correct assertSame(user, controller.currentUser); assertFalse(controller.currentUserMatchesDisk); }
@Test public void testGetAsyncAnonymousUser() throws Exception { ParseUser.State state = new ParseUser.State.Builder() .objectId("fake") .putAuthData(ParseAnonymousUtils.AUTH_TYPE, new HashMap<String, String>()) .build(); ParseObjectStore<ParseUser> store = (ParseObjectStore<ParseUser>) mock(ParseObjectStore.class); when(store.getAsync()).thenReturn(Task.forResult(ParseObject.<ParseUser>from(state))); CachedCurrentUserController controller = new CachedCurrentUserController(store); ParseUser user = ParseTaskUtils.wait(controller.getAsync(false)); assertFalse(user.isLazy()); }
@Test public void testCopy() { ParseACL acl = new ParseACL(); final ParseUser unresolvedUser = mock(ParseUser.class); when(unresolvedUser.isLazy()).thenReturn(true); // This will set unresolvedUser and permissionsById acl.setReadAccess(unresolvedUser, true); acl.setWriteAccess(unresolvedUser, true); // We need to reset unresolvedUser since registerSaveListener will be triggered once in // setReadAccess() reset(unresolvedUser); ParseACL copiedACL = new ParseACL(acl); assertEquals(1, copiedACL.getPermissionsById().size()); assertTrue(copiedACL.getPermissionsById().containsKey(UNRESOLVED_KEY)); assertTrue(copiedACL.getReadAccess(unresolvedUser)); assertTrue(copiedACL.getWriteAccess(unresolvedUser)); assertFalse(copiedACL.isShared()); assertSame(unresolvedUser, copiedACL.getUnresolvedUser()); verify(unresolvedUser, times(1)).registerSaveListener(any(GetCallback.class)); }
assertFalse(user.isLazy());
assertEquals("newValue", user.get("newKey")); assertFalse(user.isLazy());
@Test public void testGetAsyncWithNoInMemoryCurrentUserAndLazyLogin() throws Exception { ParseObjectStore<ParseUser> store = (ParseObjectStore<ParseUser>) mock(ParseObjectStore.class); when(store.getAsync()).thenReturn(Task.<ParseUser>forResult(null)); CachedCurrentUserController controller = new CachedCurrentUserController(store); ParseCorePlugins.getInstance().registerCurrentUserController(controller); // CurrentUser is null but currentUserMatchesDisk is true happens when a user logout controller.currentUserMatchesDisk = true; ParseUser currentUser = ParseTaskUtils.wait(controller.getAsync(true)); // We need to make sure the user is created by lazy login assertTrue(currentUser.isLazy()); assertTrue(currentUser.isCurrentUser()); assertSame(controller.currentUser, currentUser); assertFalse(controller.currentUserMatchesDisk); // We do not test the lazy login auth data here, it is covered in lazyLogin() unit test }