xref: /aosp_15_r20/cts/tests/devicepolicy/src/android/devicepolicy/cts/AccountMigrationTest.kt (revision b7c941bb3fa97aba169d73cee0bed2de8ac964bf)
1 /*
2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.devicepolicy.cts
18 
19 import android.accounts.Account
20 import android.accounts.AccountManager
21 import android.accounts.RemoteAccountManager
22 import android.app.admin.flags.Flags.FLAG_SPLIT_CREATE_MANAGED_PROFILE_ENABLED
23 import android.os.UserHandle
24 import com.android.bedstead.accounts.accounts
25 import com.android.bedstead.accounts.annotations.EnsureHasAccountAuthenticator
26 import com.android.bedstead.enterprise.annotations.EnsureHasDevicePolicyManagerRoleHolder
27 import com.android.bedstead.enterprise.dpmRoleHolder
28 import com.android.bedstead.flags.annotations.RequireFlagsEnabled
29 import com.android.bedstead.harrier.BedsteadJUnit4
30 import com.android.bedstead.harrier.DeviceState
31 import com.android.bedstead.harrier.UserType
32 import com.android.bedstead.harrier.annotations.Postsubmit
33 import com.android.bedstead.multiuser.annotations.EnsureHasSecondaryUser
34 import com.android.bedstead.multiuser.secondaryUser
35 import com.android.bedstead.nene.TestApis
36 import com.android.bedstead.permissions.CommonPermissions.COPY_ACCOUNTS
37 import com.android.bedstead.permissions.annotations.EnsureDoesNotHavePermission
38 import com.android.bedstead.remoteaccountauthenticator.RemoteAccountAuthenticator
39 import com.android.compatibility.common.util.ApiTest
40 import com.google.common.truth.Truth.assertThat
41 import org.junit.Assert.assertThrows
42 import org.junit.ClassRule
43 import org.junit.Rule
44 import org.junit.Test
45 import org.junit.runner.RunWith
46 
47 @RunWith(BedsteadJUnit4::class)
48 @RequireFlagsEnabled(FLAG_SPLIT_CREATE_MANAGED_PROFILE_ENABLED)
49 @EnsureHasAccountAuthenticator
50 class AccountMigrationTest {
51 
52     @Test
53     @EnsureHasDevicePolicyManagerRoleHolder
54     @Postsubmit(reason = "new test")
55     @ApiTest(apis = ["android.accounts.AccountManager#removeAccount"])
removeAccount_hasRemoveAccountsPermission_removesAccountnull56     fun removeAccount_hasRemoveAccountsPermission_removesAccount() {
57         val previousNumberOfAccounts = sDeviceState.accounts().allAccounts().size
58         val account = addAccount()
59 
60         val result = sDeviceState.dpmRoleHolder().accountManager().removeAccount(
61                 account,
62             null,
63             null,
64             null
65         ).result
66 
67         assertThat(result).isNotNull()
68         assertThat(result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT)).isTrue()
69         assertThat(sDeviceState.accounts().allAccounts().size).isEqualTo(previousNumberOfAccounts)
70     }
71 
72     @Test
73     @EnsureHasDevicePolicyManagerRoleHolder
74     @EnsureHasSecondaryUser
75     @EnsureHasAccountAuthenticator(onUser = UserType.SECONDARY_USER)
76     @ApiTest(apis = ["android.accounts.AccountManager#copyAccountToUser"])
copyAccountToUser_hasCopyAccountsPermission_copiesAccountToOtherUsernull77     fun copyAccountToUser_hasCopyAccountsPermission_copiesAccountToOtherUser() {
78         val account = addAccount()
79 
80         val result = sDeviceState.dpmRoleHolder().accountManager().copyAccountToUser(
81                 account,
82             sDeviceState.initialUser().userHandle(),
83                 sDeviceState.secondaryUser().userHandle(),
84             null,
85             null
86         ).result
87 
88         assertThat(result).isTrue()
89         assertThat(
90             sDeviceState.accounts(sDeviceState.secondaryUser())
91                 .containsAccount(account)
92         ).isTrue()
93     }
94 
95     @Test
96     @EnsureDoesNotHavePermission(COPY_ACCOUNTS)
97     @EnsureHasSecondaryUser
98     @EnsureHasAccountAuthenticator(onUser = UserType.SECONDARY_USER)
99     @Postsubmit(reason = "new test")
100     @ApiTest(apis = ["android.accounts.AccountManager#copyAccountToUser"])
copyAccountToUser_noPermission_throwsSecurityExceptionnull101     fun copyAccountToUser_noPermission_throwsSecurityException() {
102         val account = addAccount()
103 
104         assertThrows(SecurityException::class.java) {
105             sLocalAccountManager.copyAccountToUser(
106                     account,
107                 sDeviceState.initialUser().userHandle(),
108                     sDeviceState.secondaryUser().userHandle(),
109                 null,
110                 null
111             ).result
112         }
113     }
114 
115     @Test
116     @EnsureHasDevicePolicyManagerRoleHolder
117     @EnsureHasSecondaryUser
118     @EnsureHasAccountAuthenticator(onUser = UserType.SECONDARY_USER)
migrateAccount_hasCopyAccountsAndRemoveAccountsPermission_migratesAccountToOtherUsernull119     fun migrateAccount_hasCopyAccountsAndRemoveAccountsPermission_migratesAccountToOtherUser() {
120         val previousNumberOfAccounts = sDeviceState.accounts().allAccounts().size
121         val account = addAccount()
122 
123         sDeviceState.dpmRoleHolder().accountManager().migrateAccount(
124                 account,
125             sDeviceState.secondaryUser().userHandle()
126         )
127 
128         assertThat(sDeviceState.accounts().allAccounts().size).isEqualTo(previousNumberOfAccounts)
129         assertThat(
130             sDeviceState.accounts(sDeviceState.secondaryUser())
131                 .containsAccount(account)
132         ).isTrue()
133     }
134 
RemoteAccountManagernull135     private fun RemoteAccountManager.migrateAccount(account: Account, userHandle: UserHandle) {
136         copyAccountToUser(
137                 account,
138             sDeviceState.initialUser().userHandle(),
139                 userHandle,
140             null,
141             null
142         ).result
143         removeAccount(account, null, null, null).result
144     }
145 
containsAccountnull146     private fun RemoteAccountAuthenticator.containsAccount(account: Account): Boolean {
147         for (accountReference in allAccounts()) {
148             if (accountReference.account() == account) {
149                 return true
150             }
151         }
152         return false
153     }
154 
addAccountnull155     private fun addAccount() = sDeviceState.accounts().addAccount().add().account()
156 
157     companion object {
158         @ClassRule
159         @Rule
160         @JvmField
161         val sDeviceState = DeviceState()
162         private val sLocalAccountManager = TestApis
163                 .context().instrumentedContext()
164                 .getSystemService(AccountManager::class.java)!!
165     }
166 }
167