Respond to loss of device admin status

If the user revokes device admin status, reset our internal state and
the state of any accounts that might have been depending on it.  This
halts syncing immediately and rewinds the security/provisioning state
of any such accounts to a known state (as if the account had just been
created.)

Bug: 2387961
This commit is contained in:
Andrew Stadler 2010-02-16 14:33:08 -08:00
parent 105c1786f7
commit af55e3e436
2 changed files with 53 additions and 4 deletions

View File

@ -51,7 +51,7 @@ public class SecurityPolicy {
private boolean mNotificationActive;
private boolean mAdminEnabled;
private static final PolicySet NO_POLICY_SET =
/* package */ static final PolicySet NO_POLICY_SET =
new PolicySet(0, PolicySet.PASSWORD_MODE_NONE, 0, 0, false);
/**
@ -626,11 +626,18 @@ public class SecurityPolicy {
* Internal handler for enabled/disabled transitions. Handles DeviceAdmin.onEnabled and
* and DeviceAdmin.onDisabled.
*/
private void onAdminEnabled(boolean isEnabled) {
/* package */ void onAdminEnabled(boolean isEnabled) {
if (isEnabled && !mAdminEnabled) {
// TODO: transition to enabled state
} else if (!isEnabled && mAdminEnabled) {
// TODO: transition to disabled state
// transition to disabled state
// Response: clear *all* security state information from the accounts, forcing
// them back to the initial configurations requiring policy administration
ContentValues cv = new ContentValues();
cv.put(AccountColumns.SECURITY_FLAGS, 0);
cv.putNull(AccountColumns.SECURITY_SYNC_KEY);
mContext.getContentResolver().update(Account.CONTENT_URI, cv, null, null);
updatePolicies(-1);
}
mAdminEnabled = isEnabled;
}

View File

@ -294,5 +294,47 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
Account a2a = Account.restoreAccountWithId(mMockContext, a2.mId);
assertEquals(Account.FLAGS_VIBRATE, a2a.mFlags);
}
/**
* Test the response to disabling DeviceAdmin status
*/
public void testDisableAdmin() {
Account a1 = ProviderTestUtils.setupAccount("disable-1", false, mMockContext);
PolicySet p1 = new PolicySet(10, PolicySet.PASSWORD_MODE_SIMPLE, 0, 0, false);
p1.writeAccount(a1, "sync-key-1", true, mMockContext);
Account a2 = ProviderTestUtils.setupAccount("disable-2", false, mMockContext);
PolicySet p2 = new PolicySet(20, PolicySet.PASSWORD_MODE_STRONG, 25, 26, false);
p2.writeAccount(a2, "sync-key-2", true, mMockContext);
Account a3 = ProviderTestUtils.setupAccount("disable-3", false, mMockContext);
a3.mSecurityFlags = 0;
a3.mSecuritySyncKey = null;
a3.save(mMockContext);
SecurityPolicy sp = getSecurityPolicy();
// Confirm that "enabling" device admin does not change security status (flags & sync key)
PolicySet before = sp.getAggregatePolicy();
sp.onAdminEnabled(true); // "enabled" should not change anything
PolicySet after1 = sp.getAggregatePolicy();
assertEquals(before, after1);
Account a1a = Account.restoreAccountWithId(mMockContext, a1.mId);
assertNotNull(a1a.mSecuritySyncKey);
Account a2a = Account.restoreAccountWithId(mMockContext, a2.mId);
assertNotNull(a2a.mSecuritySyncKey);
Account a3a = Account.restoreAccountWithId(mMockContext, a3.mId);
assertNull(a3a.mSecuritySyncKey);
// Revoke device admin status. In the accounts we set up, security values should be reset
sp.onAdminEnabled(false); // "disabled" should clear policies
PolicySet after2 = sp.getAggregatePolicy();
assertEquals(SecurityPolicy.NO_POLICY_SET, after2);
Account a1b = Account.restoreAccountWithId(mMockContext, a1.mId);
assertNull(a1b.mSecuritySyncKey);
Account a2b = Account.restoreAccountWithId(mMockContext, a2.mId);
assertNull(a2b.mSecuritySyncKey);
Account a3b = Account.restoreAccountWithId(mMockContext, a3.mId);
assertNull(a3b.mSecuritySyncKey);
}
}