Adjusting restrictions applied to non-admins.
1. Do not apply DISALLOW_REMOVE_USERS restriction. Enforce this in removeUser method to allow users to remove themselves.
2. Remove DISALLOW_SMS and DISALLOW_OUTGOING_CALLS restrictions that are applied by the framework.
Fixes: 110232368
Bug: 109697822
Test: atest CarUserManagerHelperTest; verified restrictions on mojave.
Change-Id: I036e30088ec9febdab87c19006f32772f2a3b1fc
diff --git a/car-lib/src/android/car/user/CarUserManagerHelper.java b/car-lib/src/android/car/user/CarUserManagerHelper.java
index 7fd7fd2..0ebf0f3 100644
--- a/car-lib/src/android/car/user/CarUserManagerHelper.java
+++ b/car-lib/src/android/car/user/CarUserManagerHelper.java
@@ -59,7 +59,6 @@
* Default set of restrictions for Non-Admin users.
*/
private static final Set<String> DEFAULT_NON_ADMIN_RESTRICTIONS = Sets.newArraySet(
- UserManager.DISALLOW_REMOVE_USER,
UserManager.DISALLOW_FACTORY_RESET
);
@@ -491,6 +490,12 @@
return null;
}
setDefaultNonAdminRestrictions(user, /* enable= */ true);
+
+ // Each non-admin has sms and outgoing call restrictions applied by the UserManager on
+ // creation. We want to enable these permissions by default in the car.
+ setUserRestriction(user, UserManager.DISALLOW_SMS, /* enable= */ false);
+ setUserRestriction(user, UserManager.DISALLOW_OUTGOING_CALLS, /* enable= */ false);
+
assignDefaultIcon(user);
return user;
}
@@ -541,6 +546,12 @@
return false;
}
+ if (!isCurrentProcessAdminUser() && !isCurrentProcessUser(userInfo)) {
+ // If the caller is non-admin, they can only delete themselves.
+ Log.e(TAG, "Non-admins cannot remove other users.");
+ return false;
+ }
+
if (userInfo.id == getCurrentForegroundUserId()) {
startNewGuestSession(guestUserName);
}
diff --git a/tests/carservice_unit_test/src/com/android/car/CarUserManagerHelperTest.java b/tests/carservice_unit_test/src/com/android/car/CarUserManagerHelperTest.java
index d91846a..5c90c97 100644
--- a/tests/carservice_unit_test/src/com/android/car/CarUserManagerHelperTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/CarUserManagerHelperTest.java
@@ -18,6 +18,7 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -272,15 +273,39 @@
}
@Test
- public void testRemoveUser() {
- // Cannot remove system user.
+ public void testCannotRemoveSystemUser() {
assertThat(mHelper.removeUser(mSystemUser, mGuestUserName)).isFalse();
+ }
- // Removing non-current, non-system user, simply calls removeUser.
- UserInfo userToRemove = createUserInfoForId(mCurrentProcessUser.id + 2);
+ @Test
+ public void testAdminsCanRemoveOtherUsers() {
+ int idToRemove = mCurrentProcessUser.id + 2;
+ UserInfo userToRemove = createUserInfoForId(idToRemove);
+ when(mUserManager.removeUser(idToRemove)).thenReturn(true);
- mHelper.removeUser(userToRemove, mGuestUserName);
- verify(mUserManager).removeUser(mCurrentProcessUser.id + 2);
+ // If Admin is removing non-current, non-system user, simply calls removeUser.
+ when(mUserManager.isAdminUser()).thenReturn(true);
+ assertThat(mHelper.removeUser(userToRemove, mGuestUserName)).isTrue();
+ verify(mUserManager).removeUser(idToRemove);
+ }
+
+ @Test
+ public void testNonAdminsCanOnlyRemoveThemselves() {
+ UserInfo otherUser = createUserInfoForId(mCurrentProcessUser.id + 2);
+
+ // Make current user non-admin.
+ when(mUserManager.isAdminUser()).thenReturn(false);
+
+ // Mock so that removeUser always pretends it's successful.
+ when(mUserManager.removeUser(anyInt())).thenReturn(true);
+
+ // If Non-Admin is trying to remove someone other than themselves, they should fail.
+ assertThat(mHelper.removeUser(otherUser, mGuestUserName)).isFalse();
+ verify(mUserManager, never()).removeUser(otherUser.id);
+
+ // If Non-Admin is trying to remove themselves, that's ok.
+ assertThat(mHelper.removeUser(mCurrentProcessUser, mGuestUserName)).isTrue();
+ verify(mUserManager).removeUser(mCurrentProcessUser.id);
}
@Test
@@ -358,17 +383,18 @@
@Test
public void testDefaultNonAdminRestrictions() {
String testUserName = "Test User";
- int testUserId = 20;
- boolean restrictionEnabled = true;
- UserInfo newNonAdmin = createUserInfoForId(testUserId);
+ int userId = 20;
+ UserInfo newNonAdmin = createUserInfoForId(userId);
when(mUserManager.createUser(testUserName, /* flags= */ 0)).thenReturn(newNonAdmin);
mHelper.createNewNonAdminUser(testUserName);
verify(mUserManager).setUserRestriction(
- UserManager.DISALLOW_REMOVE_USER, restrictionEnabled, UserHandle.of(testUserId));
+ UserManager.DISALLOW_FACTORY_RESET, /* enable= */ true, UserHandle.of(userId));
verify(mUserManager).setUserRestriction(
- UserManager.DISALLOW_FACTORY_RESET, restrictionEnabled, UserHandle.of(testUserId));
+ UserManager.DISALLOW_SMS, /* enable= */ false, UserHandle.of(userId));
+ verify(mUserManager).setUserRestriction(
+ UserManager.DISALLOW_OUTGOING_CALLS, /* enable= */ false, UserHandle.of(userId));
}
@Test
@@ -381,8 +407,6 @@
mHelper.assignAdminPrivileges(testInfo);
verify(mUserManager).setUserRestriction(
- UserManager.DISALLOW_REMOVE_USER, restrictionEnabled, UserHandle.of(testUserId));
- verify(mUserManager).setUserRestriction(
UserManager.DISALLOW_FACTORY_RESET, restrictionEnabled, UserHandle.of(testUserId));
}