Merge "Add encryption to SecurityPolicy" into honeycomb

This commit is contained in:
Andy Stadler 2011-01-13 13:26:13 -08:00 committed by Android (Google) Code Review
commit 4f721a1625
5 changed files with 215 additions and 67 deletions

View File

@ -22,5 +22,6 @@
<force-lock /> <force-lock />
<wipe-data /> <wipe-data />
<expire-password /> <expire-password />
<encrypted-storage />
</uses-policies> </uses-policies>
</device-admin> </device-admin>

View File

@ -48,7 +48,7 @@ public class SecurityPolicy {
private PolicySet mAggregatePolicy; private PolicySet mAggregatePolicy;
/* package */ static final PolicySet NO_POLICY_SET = /* package */ static final PolicySet NO_POLICY_SET =
new PolicySet(0, PolicySet.PASSWORD_MODE_NONE, 0, 0, false, 0, 0, 0); new PolicySet(0, PolicySet.PASSWORD_MODE_NONE, 0, 0, false, 0, 0, 0, false);
/** /**
* This projection on Account is for scanning/reading * This projection on Account is for scanning/reading
@ -104,6 +104,7 @@ public class SecurityPolicy {
* password history take the max (strongest mode) * password history take the max (strongest mode)
* password expiration take the min (strongest mode) * password expiration take the min (strongest mode)
* password complex chars take the max (strongest mode) * password complex chars take the max (strongest mode)
* encryption take the max (logical or)
* *
* @return a policy representing the strongest aggregate. If no policy sets are defined, * @return a policy representing the strongest aggregate. If no policy sets are defined,
* a lightweight "nothing required" policy will be returned. Never null. * a lightweight "nothing required" policy will be returned. Never null.
@ -119,6 +120,7 @@ public class SecurityPolicy {
int passwordHistory = Integer.MIN_VALUE; int passwordHistory = Integer.MIN_VALUE;
int passwordExpirationDays = Integer.MAX_VALUE; int passwordExpirationDays = Integer.MAX_VALUE;
int passwordComplexChars = Integer.MIN_VALUE; int passwordComplexChars = Integer.MIN_VALUE;
boolean requireEncryption = false;
Cursor c = mContext.getContentResolver().query(Account.CONTENT_URI, Cursor c = mContext.getContentResolver().query(Account.CONTENT_URI,
ACCOUNT_SECURITY_PROJECTION, Account.SECURITY_NONZERO_SELECTION, null, null); ACCOUNT_SECURITY_PROJECTION, Account.SECURITY_NONZERO_SELECTION, null, null);
@ -147,6 +149,7 @@ public class SecurityPolicy {
passwordComplexChars); passwordComplexChars);
} }
requireRemoteWipe |= p.mRequireRemoteWipe; requireRemoteWipe |= p.mRequireRemoteWipe;
requireEncryption |= p.mRequireEncryption;
policiesFound = true; policiesFound = true;
} }
} }
@ -165,7 +168,7 @@ public class SecurityPolicy {
return new PolicySet(minPasswordLength, passwordMode, maxPasswordFails, return new PolicySet(minPasswordLength, passwordMode, maxPasswordFails,
maxScreenLockTime, requireRemoteWipe, passwordExpirationDays, passwordHistory, maxScreenLockTime, requireRemoteWipe, passwordExpirationDays, passwordHistory,
passwordComplexChars); passwordComplexChars, requireEncryption);
} else { } else {
return NO_POLICY_SET; return NO_POLICY_SET;
} }
@ -210,6 +213,57 @@ public class SecurityPolicy {
setActivePolicies(); setActivePolicies();
} }
/**
* API: Query if the proposed set of policies are supported on the device.
*
* @param policies requested
* @return boolean if supported
*/
public boolean isSupported(PolicySet policies) {
// IMPLEMENTATION: At this time, the only policy which might not be supported is
// encryption (which requires low-level systems support). Other policies are fully
// supported by the framework and do not need to be checked.
if (policies.mRequireEncryption) {
int encryptionStatus = getDPM().getStorageEncryption(null);
if (encryptionStatus == DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED) {
return false;
}
}
return true;
}
/**
* API: Query used to determine if a given policy is "active" (the device is operating at
* the required security level).
*
* @param policies the policies requested, or null to check aggregate stored policies
* @return true if the requested policies are active, false if not.
*/
public boolean isActive(PolicySet policies) {
int reasons = getInactiveReasons(policies);
return reasons == 0;
}
/**
* Return bits from isActive: Device Policy Manager has not been activated
*/
public final static int INACTIVE_NEED_ACTIVATION = 1;
/**
* Return bits from isActive: Some required configuration is not correct (no user action).
*/
public final static int INACTIVE_NEED_CONFIGURATION = 2;
/**
* Return bits from isActive: Password needs to be set or updated
*/
public final static int INACTIVE_NEED_PASSWORD = 4;
/**
* Return bits from isActive: Encryption has not be enabled
*/
public final static int INACTIVE_NEED_ENCRYPTION = 8;
/** /**
* API: Query used to determine if a given policy is "active" (the device is operating at * API: Query used to determine if a given policy is "active" (the device is operating at
* the required security level). * the required security level).
@ -227,37 +281,39 @@ public class SecurityPolicy {
* based on the requirements of the account with the shortest interval. * based on the requirements of the account with the shortest interval.
* *
* @param policies the policies requested, or null to check aggregate stored policies * @param policies the policies requested, or null to check aggregate stored policies
* @return true if the policies are active, false if not active * @return zero if the requested policies are active, non-zero bits indicates that more work
* is needed (typically, by the user) before the required security polices are fully active.
*/ */
public boolean isActive(PolicySet policies) { public int getInactiveReasons(PolicySet policies) {
// select aggregate set if needed // select aggregate set if needed
if (policies == null) { if (policies == null) {
policies = getAggregatePolicy(); policies = getAggregatePolicy();
} }
// quick check for the "empty set" of no policies // quick check for the "empty set" of no policies
if (policies == NO_POLICY_SET) { if (policies == NO_POLICY_SET) {
return true; return 0;
} }
int reasons = 0;
DevicePolicyManager dpm = getDPM(); DevicePolicyManager dpm = getDPM();
if (isActiveAdmin()) { if (isActiveAdmin()) {
// check each policy explicitly // check each policy explicitly
if (policies.mMinPasswordLength > 0) { if (policies.mMinPasswordLength > 0) {
if (dpm.getPasswordMinimumLength(mAdminName) < policies.mMinPasswordLength) { if (dpm.getPasswordMinimumLength(mAdminName) < policies.mMinPasswordLength) {
return false; reasons |= INACTIVE_NEED_PASSWORD;
} }
} }
if (policies.mPasswordMode > 0) { if (policies.mPasswordMode > 0) {
if (dpm.getPasswordQuality(mAdminName) < policies.getDPManagerPasswordQuality()) { if (dpm.getPasswordQuality(mAdminName) < policies.getDPManagerPasswordQuality()) {
return false; reasons |= INACTIVE_NEED_PASSWORD;
} }
if (!dpm.isActivePasswordSufficient()) { if (!dpm.isActivePasswordSufficient()) {
return false; reasons |= INACTIVE_NEED_PASSWORD;
} }
} }
if (policies.mMaxScreenLockTime > 0) { if (policies.mMaxScreenLockTime > 0) {
// Note, we use seconds, dpm uses milliseconds // Note, we use seconds, dpm uses milliseconds
if (dpm.getMaximumTimeToLock(mAdminName) > policies.mMaxScreenLockTime * 1000) { if (dpm.getMaximumTimeToLock(mAdminName) > policies.mMaxScreenLockTime * 1000) {
return false; reasons |= INACTIVE_NEED_CONFIGURATION;
} }
} }
if (policies.mPasswordExpirationDays > 0) { if (policies.mPasswordExpirationDays > 0) {
@ -265,34 +321,40 @@ public class SecurityPolicy {
long currentTimeout = dpm.getPasswordExpirationTimeout(mAdminName); long currentTimeout = dpm.getPasswordExpirationTimeout(mAdminName);
if (currentTimeout == 0 if (currentTimeout == 0
|| currentTimeout > policies.getDPManagerPasswordExpirationTimeout()) { || currentTimeout > policies.getDPManagerPasswordExpirationTimeout()) {
return false; reasons |= INACTIVE_NEED_PASSWORD;
} }
// confirm that the current password hasn't expired // confirm that the current password hasn't expired
long expirationDate = dpm.getPasswordExpiration(mAdminName); long expirationDate = dpm.getPasswordExpiration(mAdminName);
long timeUntilExpiration = expirationDate - System.currentTimeMillis(); long timeUntilExpiration = expirationDate - System.currentTimeMillis();
boolean expired = timeUntilExpiration < 0; boolean expired = timeUntilExpiration < 0;
if (expired) { if (expired) {
return false; reasons |= INACTIVE_NEED_PASSWORD;
} }
} }
if (policies.mPasswordHistory > 0) { if (policies.mPasswordHistory > 0) {
if (dpm.getPasswordHistoryLength(mAdminName) < policies.mPasswordHistory) { if (dpm.getPasswordHistoryLength(mAdminName) < policies.mPasswordHistory) {
return false; reasons |= INACTIVE_NEED_PASSWORD;
} }
} }
if (policies.mPasswordComplexChars > 0) { if (policies.mPasswordComplexChars > 0) {
if (dpm.getPasswordMinimumNonLetter(mAdminName) < policies.mPasswordComplexChars) { if (dpm.getPasswordMinimumNonLetter(mAdminName) < policies.mPasswordComplexChars) {
return false; reasons |= INACTIVE_NEED_PASSWORD;
}
}
if (policies.mRequireEncryption) {
int encryptionStatus = getDPM().getStorageEncryption(null);
if (encryptionStatus != DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE) {
reasons |= INACTIVE_NEED_ENCRYPTION;
} }
} }
// password failures are counted locally - no test required here // password failures are counted locally - no test required here
// no check required for remote wipe (it's supported, if we're the admin) // no check required for remote wipe (it's supported, if we're the admin)
// making it this far means we passed! // If we made it all the way, reasons == 0 here. Otherwise it's a list of grievances.
return true; return reasons;
} }
// return false, not active // return false, not active
return false; return INACTIVE_NEED_ACTIVATION;
} }
/** /**
@ -323,6 +385,8 @@ public class SecurityPolicy {
dpm.setPasswordHistoryLength(mAdminName, policies.mPasswordHistory); dpm.setPasswordHistoryLength(mAdminName, policies.mPasswordHistory);
// password minimum complex characters // password minimum complex characters
dpm.setPasswordMinimumNonLetter(mAdminName, policies.mPasswordComplexChars); dpm.setPasswordMinimumNonLetter(mAdminName, policies.mPasswordComplexChars);
// encryption required
dpm.setStorageEncryption(mAdminName, policies.mRequireEncryption);
} }
} }
@ -422,14 +486,16 @@ public class SecurityPolicy {
private static final int PASSWORD_EXPIRATION_SHIFT = 26; private static final int PASSWORD_EXPIRATION_SHIFT = 26;
private static final long PASSWORD_EXPIRATION_MASK = 1023L << PASSWORD_EXPIRATION_SHIFT; private static final long PASSWORD_EXPIRATION_MASK = 1023L << PASSWORD_EXPIRATION_SHIFT;
public static final int PASSWORD_EXPIRATION_MAX = 1023; public static final int PASSWORD_EXPIRATION_MAX = 1023;
// bit 35..42: password history (length; 0=not required) // bit 36..43: password history (length; 0=not required)
private static final int PASSWORD_HISTORY_SHIFT = 36; private static final int PASSWORD_HISTORY_SHIFT = 36;
private static final long PASSWORD_HISTORY_MASK = 255L << PASSWORD_HISTORY_SHIFT; private static final long PASSWORD_HISTORY_MASK = 255L << PASSWORD_HISTORY_SHIFT;
public static final int PASSWORD_HISTORY_MAX = 255; public static final int PASSWORD_HISTORY_MAX = 255;
// bit 42..46: min complex characters (0=not required) // bit 44..48: min complex characters (0=not required)
private static final int PASSWORD_COMPLEX_CHARS_SHIFT = 44; private static final int PASSWORD_COMPLEX_CHARS_SHIFT = 44;
private static final long PASSWORD_COMPLEX_CHARS_MASK = 31L << PASSWORD_COMPLEX_CHARS_SHIFT; private static final long PASSWORD_COMPLEX_CHARS_MASK = 31L << PASSWORD_COMPLEX_CHARS_SHIFT;
public static final int PASSWORD_COMPLEX_CHARS_MAX = 31; public static final int PASSWORD_COMPLEX_CHARS_MAX = 31;
// bit 49: requires device encryption
private static final long REQUIRE_ENCRYPTION = 1L << 49;
/* Convert days to mSec (used for password expiration) */ /* Convert days to mSec (used for password expiration) */
private static final long DAYS_TO_MSEC = 24 * 60 * 60 * 1000; private static final long DAYS_TO_MSEC = 24 * 60 * 60 * 1000;
@ -444,6 +510,7 @@ public class SecurityPolicy {
/*package*/ final int mPasswordExpirationDays; /*package*/ final int mPasswordExpirationDays;
/*package*/ final int mPasswordHistory; /*package*/ final int mPasswordHistory;
/*package*/ final int mPasswordComplexChars; /*package*/ final int mPasswordComplexChars;
/*package*/ final boolean mRequireEncryption;
public int getMinPasswordLengthForTest() { public int getMinPasswordLengthForTest() {
return mMinPasswordLength; return mMinPasswordLength;
@ -465,6 +532,10 @@ public class SecurityPolicy {
return mRequireRemoteWipe; return mRequireRemoteWipe;
} }
public boolean isRequireEncryptionForTest() {
return mRequireEncryption;
}
/** /**
* Create from raw values. * Create from raw values.
* @param minPasswordLength (0=not enforced) * @param minPasswordLength (0=not enforced)
@ -479,7 +550,8 @@ public class SecurityPolicy {
*/ */
public PolicySet(int minPasswordLength, int passwordMode, int maxPasswordFails, public PolicySet(int minPasswordLength, int passwordMode, int maxPasswordFails,
int maxScreenLockTime, boolean requireRemoteWipe, int passwordExpirationDays, int maxScreenLockTime, boolean requireRemoteWipe, int passwordExpirationDays,
int passwordHistory, int passwordComplexChars) throws IllegalArgumentException { int passwordHistory, int passwordComplexChars, boolean requireEncryption)
throws IllegalArgumentException {
// If we're not enforcing passwords, make sure we clean up related values, since EAS // If we're not enforcing passwords, make sure we clean up related values, since EAS
// can send non-zero values for any or all of these // can send non-zero values for any or all of these
if (passwordMode == PASSWORD_MODE_NONE) { if (passwordMode == PASSWORD_MODE_NONE) {
@ -529,6 +601,7 @@ public class SecurityPolicy {
mPasswordExpirationDays = passwordExpirationDays; mPasswordExpirationDays = passwordExpirationDays;
mPasswordHistory = passwordHistory; mPasswordHistory = passwordHistory;
mPasswordComplexChars = passwordComplexChars; mPasswordComplexChars = passwordComplexChars;
mRequireEncryption = requireEncryption;
} }
/** /**
@ -558,6 +631,7 @@ public class SecurityPolicy {
(int) ((flags & PASSWORD_HISTORY_MASK) >> PASSWORD_HISTORY_SHIFT); (int) ((flags & PASSWORD_HISTORY_MASK) >> PASSWORD_HISTORY_SHIFT);
mPasswordComplexChars = mPasswordComplexChars =
(int) ((flags & PASSWORD_COMPLEX_CHARS_MASK) >> PASSWORD_COMPLEX_CHARS_SHIFT); (int) ((flags & PASSWORD_COMPLEX_CHARS_MASK) >> PASSWORD_COMPLEX_CHARS_SHIFT);
mRequireEncryption = 0 != (flags & REQUIRE_ENCRYPTION);
} }
/** /**
@ -661,6 +735,7 @@ public class SecurityPolicy {
dest.writeInt(mPasswordExpirationDays); dest.writeInt(mPasswordExpirationDays);
dest.writeInt(mPasswordHistory); dest.writeInt(mPasswordHistory);
dest.writeInt(mPasswordComplexChars); dest.writeInt(mPasswordComplexChars);
dest.writeInt(mRequireEncryption ? 1 : 0);
} }
/** /**
@ -675,6 +750,7 @@ public class SecurityPolicy {
mPasswordExpirationDays = in.readInt(); mPasswordExpirationDays = in.readInt();
mPasswordHistory = in.readInt(); mPasswordHistory = in.readInt();
mPasswordComplexChars = in.readInt(); mPasswordComplexChars = in.readInt();
mRequireEncryption = in.readInt() == 1;
} }
@Override @Override
@ -689,12 +765,11 @@ public class SecurityPolicy {
flags |= mPasswordMode; flags |= mPasswordMode;
flags |= (long)mMaxPasswordFails << PASSWORD_MAX_FAILS_SHIFT; flags |= (long)mMaxPasswordFails << PASSWORD_MAX_FAILS_SHIFT;
flags |= (long)mMaxScreenLockTime << SCREEN_LOCK_TIME_SHIFT; flags |= (long)mMaxScreenLockTime << SCREEN_LOCK_TIME_SHIFT;
if (mRequireRemoteWipe) { if (mRequireRemoteWipe) flags |= REQUIRE_REMOTE_WIPE;
flags |= REQUIRE_REMOTE_WIPE;
}
flags |= (long)mPasswordHistory << PASSWORD_HISTORY_SHIFT; flags |= (long)mPasswordHistory << PASSWORD_HISTORY_SHIFT;
flags |= (long)mPasswordExpirationDays << PASSWORD_EXPIRATION_SHIFT; flags |= (long)mPasswordExpirationDays << PASSWORD_EXPIRATION_SHIFT;
flags |= (long)mPasswordComplexChars << PASSWORD_COMPLEX_CHARS_SHIFT; flags |= (long)mPasswordComplexChars << PASSWORD_COMPLEX_CHARS_SHIFT;
if (mRequireEncryption) flags |= REQUIRE_ENCRYPTION;
return flags; return flags;
} }
@ -705,7 +780,8 @@ public class SecurityPolicy {
+ mMaxScreenLockTime + " remote-wipe-req=" + mRequireRemoteWipe + mMaxScreenLockTime + " remote-wipe-req=" + mRequireRemoteWipe
+ " pw-expiration=" + mPasswordExpirationDays + " pw-expiration=" + mPasswordExpirationDays
+ " pw-history=" + mPasswordHistory + " pw-history=" + mPasswordHistory
+ " pw-complex-chars=" + mPasswordComplexChars + "}"; + " pw-complex-chars=" + mPasswordComplexChars
+ " require-encryption=" + mRequireEncryption + "}";
} }
} }

View File

@ -37,12 +37,15 @@ import android.os.Bundle;
* 3. When we are actively administrating, check current policies and see if they're sufficient * 3. When we are actively administrating, check current policies and see if they're sufficient
* 4. If not, set policies * 4. If not, set policies
* 5. If necessary, request for user to update device password * 5. If necessary, request for user to update device password
* 6. If necessary, request for user to activate device encryption
*/ */
public class AccountSecurity extends Activity { public class AccountSecurity extends Activity {
private static final String EXTRA_ACCOUNT_ID = "com.android.email.activity.setup.ACCOUNT_ID"; private static final String EXTRA_ACCOUNT_ID = "com.android.email.activity.setup.ACCOUNT_ID";
private static final int REQUEST_ENABLE = 1; private static final int REQUEST_ENABLE = 1;
private static final int REQUEST_PASSWORD = 2;
private static final int REQUEST_ENCRYPTION = 3;
/** /**
* Used for generating intent for this activity (which is intended to be launched * Used for generating intent for this activity (which is intended to be launched
@ -91,7 +94,11 @@ public class AccountSecurity extends Activity {
} }
} else { } else {
// already active - try to set actual policies, finish, and return // already active - try to set actual policies, finish, and return
setActivePolicies(); boolean startedActivity = setActivePolicies();
if (startedActivity) {
// keep this activity on stack to process result
return;
}
} }
} }
} }
@ -104,11 +111,17 @@ public class AccountSecurity extends Activity {
*/ */
@Override @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) { protected void onActivityResult(int requestCode, int resultCode, Intent data) {
boolean startedActivity = false;
switch (requestCode) { switch (requestCode) {
case REQUEST_PASSWORD:
case REQUEST_ENCRYPTION:
// Force the result code and just check the DPM to check for actual success
resultCode = Activity.RESULT_OK;
//$FALL-THROUGH$
case REQUEST_ENABLE: case REQUEST_ENABLE:
if (resultCode == Activity.RESULT_OK) { if (resultCode == Activity.RESULT_OK) {
// now active - try to set actual policies // now active - try to set actual policies
setActivePolicies(); startedActivity = setActivePolicies();
} else { } else {
// failed - repost notification, and exit // failed - repost notification, and exit
final long accountId = getIntent().getLongExtra(EXTRA_ACCOUNT_ID, -1); final long accountId = getIntent().getLongExtra(EXTRA_ACCOUNT_ID, -1);
@ -123,30 +136,45 @@ public class AccountSecurity extends Activity {
} }
} }
} }
finish(); if (!startedActivity) {
finish();
}
super.onActivityResult(requestCode, resultCode, data); super.onActivityResult(requestCode, resultCode, data);
} }
/** /**
* Now that we are connected as an active device admin, try to set the device to the * Now that we are connected as an active device admin, try to set the device to the
* correct security level, and ask for a password if necessary. * correct security level, and ask for a password if necessary.
* @return true if we started another activity (and should not finish(), as we're waiting for
* their result.)
*/ */
private void setActivePolicies() { private boolean setActivePolicies() {
SecurityPolicy sp = SecurityPolicy.getInstance(this); SecurityPolicy sp = SecurityPolicy.getInstance(this);
// check current security level - if sufficient, we're done! // check current security level - if sufficient, we're done!
if (sp.isActive(null)) { if (sp.isActive(null)) {
Account.clearSecurityHoldOnAllAccounts(this); Account.clearSecurityHoldOnAllAccounts(this);
return; return false;
} }
// set current security level // set current security level
sp.setActivePolicies(); sp.setActivePolicies();
// check current security level - if sufficient, we're done! // check current security level - if sufficient, we're done!
if (sp.isActive(null)) { int inactiveReasons = sp.getInactiveReasons(null);
if (inactiveReasons == 0) {
Account.clearSecurityHoldOnAllAccounts(this); Account.clearSecurityHoldOnAllAccounts(this);
return; return false;
} }
// if not sufficient, launch the activity to have the user set a new password. // If password or encryption required, launch relevant intent
Intent intent = new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD); if ((inactiveReasons & SecurityPolicy.INACTIVE_NEED_PASSWORD) != 0) {
startActivity(intent); // launch the activity to have the user set a new password.
Intent intent = new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD);
startActivityForResult(intent, REQUEST_PASSWORD);
return true;
} else if ((inactiveReasons & SecurityPolicy.INACTIVE_NEED_ENCRYPTION) != 0) {
// launch the activity to start up encryption.
Intent intent = new Intent(DevicePolicyManager.ACTION_START_ENCRYPTION);
startActivityForResult(intent, REQUEST_ENCRYPTION);
return true;
}
return false;
} }
} }

View File

@ -196,7 +196,7 @@ public class ProvisionParser extends Parser {
mPolicySet = new SecurityPolicy.PolicySet(minPasswordLength, passwordMode, mPolicySet = new SecurityPolicy.PolicySet(minPasswordLength, passwordMode,
maxPasswordFails, maxScreenLockTime, true, passwordExpirationDays, passwordHistory, maxPasswordFails, maxScreenLockTime, true, passwordExpirationDays, passwordHistory,
passwordComplexChars); passwordComplexChars, false);
} }
/** /**
@ -253,7 +253,7 @@ public class ProvisionParser extends Parser {
mPolicySet = new PolicySet(sps.mMinPasswordLength, sps.mPasswordMode, sps.mMaxPasswordFails, mPolicySet = new PolicySet(sps.mMinPasswordLength, sps.mPasswordMode, sps.mMaxPasswordFails,
sps.mMaxScreenLockTime, true, sps.mPasswordExpiration, sps.mPasswordHistory, sps.mMaxScreenLockTime, true, sps.mPasswordExpiration, sps.mPasswordHistory,
sps.mPasswordComplexChars); sps.mPasswordComplexChars, false);
} }
/** /**

View File

@ -48,7 +48,7 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
private Context mMockContext; private Context mMockContext;
private static final PolicySet EMPTY_POLICY_SET = private static final PolicySet EMPTY_POLICY_SET =
new PolicySet(0, PolicySet.PASSWORD_MODE_NONE, 0, 0, false, 0, 0, 0); new PolicySet(0, PolicySet.PASSWORD_MODE_NONE, 0, 0, false, 0, 0, 0, false);
public SecurityPolicyTests() { public SecurityPolicyTests() {
super(EmailProvider.class, EmailProvider.EMAIL_AUTHORITY); super(EmailProvider.class, EmailProvider.EMAIL_AUTHORITY);
@ -108,28 +108,28 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
// We know that EMPTY_POLICY_SET doesn't generate an Exception or we wouldn't be here // We know that EMPTY_POLICY_SET doesn't generate an Exception or we wouldn't be here
// Try some illegal parameters // Try some illegal parameters
try { try {
new PolicySet(100, PolicySet.PASSWORD_MODE_SIMPLE, 0, 0, false, 0, 0, 0); new PolicySet(100, PolicySet.PASSWORD_MODE_SIMPLE, 0, 0, false, 0, 0, 0, false);
fail("Too-long password allowed"); fail("Too-long password allowed");
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
} }
try { try {
new PolicySet(0, PolicySet.PASSWORD_MODE_STRONG + 1, 0, 0, false, 0, 0, 0); new PolicySet(0, PolicySet.PASSWORD_MODE_STRONG + 1, 0, 0, false, 0, 0, 0, false);
fail("Illegal password mode allowed"); fail("Illegal password mode allowed");
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
} }
PolicySet ps = new PolicySet(0, PolicySet.PASSWORD_MODE_SIMPLE, 0, PolicySet ps = new PolicySet(0, PolicySet.PASSWORD_MODE_SIMPLE, 0,
PolicySet.SCREEN_LOCK_TIME_MAX + 1, false, 0, 0, 0); PolicySet.SCREEN_LOCK_TIME_MAX + 1, false, 0, 0, 0, false);
assertEquals(PolicySet.SCREEN_LOCK_TIME_MAX, ps.getMaxScreenLockTimeForTest()); assertEquals(PolicySet.SCREEN_LOCK_TIME_MAX, ps.getMaxScreenLockTimeForTest());
ps = new PolicySet(0, PolicySet.PASSWORD_MODE_SIMPLE, ps = new PolicySet(0, PolicySet.PASSWORD_MODE_SIMPLE,
PolicySet.PASSWORD_MAX_FAILS_MAX + 1, 0, false, 0, 0, 0); PolicySet.PASSWORD_MAX_FAILS_MAX + 1, 0, false, 0, 0, 0, false);
assertEquals(PolicySet.PASSWORD_MAX_FAILS_MAX, ps.getMaxPasswordFailsForTest()); assertEquals(PolicySet.PASSWORD_MAX_FAILS_MAX, ps.getMaxPasswordFailsForTest());
// All password related fields should be zero when password mode is NONE // All password related fields should be zero when password mode is NONE
// Illegal values for these fields should be ignored // Illegal values for these fields should be ignored
ps = new PolicySet(999/*length*/, PolicySet.PASSWORD_MODE_NONE, ps = new PolicySet(999/*length*/, PolicySet.PASSWORD_MODE_NONE,
999/*fails*/, 9999/*screenlock*/, false, 999/*expir*/, 999/*history*/, 999/*fails*/, 9999/*screenlock*/, false, 999/*expir*/, 999/*history*/,
999/*complex*/); 999/*complex*/, false);
assertEquals(0, ps.mMinPasswordLength); assertEquals(0, ps.mMinPasswordLength);
assertEquals(0, ps.mMaxScreenLockTime); assertEquals(0, ps.mMaxScreenLockTime);
assertEquals(0, ps.mMaxPasswordFails); assertEquals(0, ps.mMaxPasswordFails);
@ -139,7 +139,7 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
// With a simple password, we should set complex chars to zero // With a simple password, we should set complex chars to zero
ps = new PolicySet(4/*length*/, PolicySet.PASSWORD_MODE_SIMPLE, ps = new PolicySet(4/*length*/, PolicySet.PASSWORD_MODE_SIMPLE,
0, 0, false, 0, 0, 3/*complex*/); 0, 0, false, 0, 0, 3/*complex*/, false);
assertEquals(4, ps.mMinPasswordLength); assertEquals(4, ps.mMinPasswordLength);
assertEquals(0, ps.mPasswordComplexChars); assertEquals(0, ps.mPasswordComplexChars);
} }
@ -165,14 +165,16 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
// with a single account in security mode, should return same security as in account // with a single account in security mode, should return same security as in account
// first test with partially-populated policies // first test with partially-populated policies
Account a3 = ProviderTestUtils.setupAccount("sec-3", false, mMockContext); Account a3 = ProviderTestUtils.setupAccount("sec-3", false, mMockContext);
PolicySet p3ain = new PolicySet(10, PolicySet.PASSWORD_MODE_SIMPLE, 0, 0, false, 0, 0, 0); PolicySet p3ain = new PolicySet(10, PolicySet.PASSWORD_MODE_SIMPLE, 0, 0, false, 0, 0, 0,
false);
p3ain.writeAccount(a3, null, true, mMockContext); p3ain.writeAccount(a3, null, true, mMockContext);
PolicySet p3aout = sp.computeAggregatePolicy(); PolicySet p3aout = sp.computeAggregatePolicy();
assertNotNull(p3aout); assertNotNull(p3aout);
assertEquals(p3ain, p3aout); assertEquals(p3ain, p3aout);
// Repeat that test with fully-populated policies // Repeat that test with fully-populated policies
PolicySet p3bin = new PolicySet(10, PolicySet.PASSWORD_MODE_SIMPLE, 15, 16, false, 6, 2, 3); PolicySet p3bin = new PolicySet(10, PolicySet.PASSWORD_MODE_SIMPLE, 15, 16, false, 6, 2, 3,
false);
p3bin.writeAccount(a3, null, true, mMockContext); p3bin.writeAccount(a3, null, true, mMockContext);
PolicySet p3bout = sp.computeAggregatePolicy(); PolicySet p3bout = sp.computeAggregatePolicy();
assertNotNull(p3bout); assertNotNull(p3bout);
@ -184,7 +186,9 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
// wipe required - OR logic - will *not* change here because false // wipe required - OR logic - will *not* change here because false
// expiration - will not change because 0 (unspecified) // expiration - will not change because 0 (unspecified)
// max complex chars - max logic - will change // max complex chars - max logic - will change
PolicySet p4in = new PolicySet(20, PolicySet.PASSWORD_MODE_STRONG, 25, 26, false, 0, 5, 7); // encryption required - OR logic - will *not* change here because false
PolicySet p4in = new PolicySet(20, PolicySet.PASSWORD_MODE_STRONG, 25, 26, false, 0, 5, 7,
false);
Account a4 = ProviderTestUtils.setupAccount("sec-4", false, mMockContext); Account a4 = ProviderTestUtils.setupAccount("sec-4", false, mMockContext);
p4in.writeAccount(a4, null, true, mMockContext); p4in.writeAccount(a4, null, true, mMockContext);
PolicySet p4out = sp.computeAggregatePolicy(); PolicySet p4out = sp.computeAggregatePolicy();
@ -197,6 +201,7 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
assertEquals(5, p4out.mPasswordHistory); assertEquals(5, p4out.mPasswordHistory);
assertEquals(7, p4out.mPasswordComplexChars); assertEquals(7, p4out.mPasswordComplexChars);
assertFalse(p4out.mRequireRemoteWipe); assertFalse(p4out.mRequireRemoteWipe);
assertFalse(p4out.mRequireEncryption);
// add another account which mixes it up (the remaining fields will change) // add another account which mixes it up (the remaining fields will change)
// pw length and pw mode - max logic - will *not* change because smaller #s here // pw length and pw mode - max logic - will *not* change because smaller #s here
@ -204,7 +209,9 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
// wipe required - OR logic - will change here because true // wipe required - OR logic - will change here because true
// expiration time - min logic - will change because lower here // expiration time - min logic - will change because lower here
// history & complex chars - will not change because 0 (unspecified) // history & complex chars - will not change because 0 (unspecified)
PolicySet p5in = new PolicySet(4, PolicySet.PASSWORD_MODE_SIMPLE, 5, 6, true, 1, 0, 0); // encryption required - OR logic - will change here because true
PolicySet p5in = new PolicySet(4, PolicySet.PASSWORD_MODE_SIMPLE, 5, 6, true, 1, 0, 0,
true);
Account a5 = ProviderTestUtils.setupAccount("sec-5", false, mMockContext); Account a5 = ProviderTestUtils.setupAccount("sec-5", false, mMockContext);
p5in.writeAccount(a5, null, true, mMockContext); p5in.writeAccount(a5, null, true, mMockContext);
PolicySet p5out = sp.computeAggregatePolicy(); PolicySet p5out = sp.computeAggregatePolicy();
@ -214,9 +221,10 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
assertEquals(5, p5out.mMaxPasswordFails); assertEquals(5, p5out.mMaxPasswordFails);
assertEquals(6, p5out.mMaxScreenLockTime); assertEquals(6, p5out.mMaxScreenLockTime);
assertEquals(1, p5out.mPasswordExpirationDays); assertEquals(1, p5out.mPasswordExpirationDays);
assertEquals(5, p4out.mPasswordHistory); assertEquals(5, p5out.mPasswordHistory);
assertEquals(7, p4out.mPasswordComplexChars); assertEquals(7, p5out.mPasswordComplexChars);
assertTrue(p5out.mRequireRemoteWipe); assertTrue(p5out.mRequireRemoteWipe);
assertTrue(p5out.mRequireEncryption);
} }
/** /**
@ -244,8 +252,9 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
*/ */
@SmallTest @SmallTest
public void testFieldIsolation() { public void testFieldIsolation() {
// Check PASSWORD_LENGTH
PolicySet p = new PolicySet(PolicySet.PASSWORD_LENGTH_MAX, PolicySet.PASSWORD_MODE_SIMPLE, PolicySet p = new PolicySet(PolicySet.PASSWORD_LENGTH_MAX, PolicySet.PASSWORD_MODE_SIMPLE,
0, 0, false, 0, 0 ,0); 0, 0, false, 0, 0 ,0, false);
assertEquals(PolicySet.PASSWORD_MODE_SIMPLE, p.mPasswordMode); assertEquals(PolicySet.PASSWORD_MODE_SIMPLE, p.mPasswordMode);
assertEquals(PolicySet.PASSWORD_LENGTH_MAX, p.mMinPasswordLength); assertEquals(PolicySet.PASSWORD_LENGTH_MAX, p.mMinPasswordLength);
assertEquals(0, p.mMaxPasswordFails); assertEquals(0, p.mMaxPasswordFails);
@ -254,8 +263,10 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
assertEquals(0, p.mPasswordHistory); assertEquals(0, p.mPasswordHistory);
assertEquals(0, p.mPasswordComplexChars); assertEquals(0, p.mPasswordComplexChars);
assertFalse(p.mRequireRemoteWipe); assertFalse(p.mRequireRemoteWipe);
assertFalse(p.mRequireEncryption);
p = new PolicySet(0, PolicySet.PASSWORD_MODE_STRONG, 0, 0, false, 0, 0, 0); // Check PASSWORD_MODE
p = new PolicySet(0, PolicySet.PASSWORD_MODE_STRONG, 0, 0, false, 0, 0, 0, false);
assertEquals(PolicySet.PASSWORD_MODE_STRONG, p.mPasswordMode); assertEquals(PolicySet.PASSWORD_MODE_STRONG, p.mPasswordMode);
assertEquals(0, p.mMinPasswordLength); assertEquals(0, p.mMinPasswordLength);
assertEquals(0, p.mMaxPasswordFails); assertEquals(0, p.mMaxPasswordFails);
@ -264,9 +275,11 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
assertEquals(0, p.mPasswordHistory); assertEquals(0, p.mPasswordHistory);
assertEquals(0, p.mPasswordComplexChars); assertEquals(0, p.mPasswordComplexChars);
assertFalse(p.mRequireRemoteWipe); assertFalse(p.mRequireRemoteWipe);
assertFalse(p.mRequireEncryption);
// Check PASSWORD_FAILS (note, mode must be set for this to be non-zero)
p = new PolicySet(0, PolicySet.PASSWORD_MODE_SIMPLE, PolicySet.PASSWORD_MAX_FAILS_MAX, 0, p = new PolicySet(0, PolicySet.PASSWORD_MODE_SIMPLE, PolicySet.PASSWORD_MAX_FAILS_MAX, 0,
false, 0, 0, 0); false, 0, 0, 0, false);
assertEquals(PolicySet.PASSWORD_MODE_SIMPLE, p.mPasswordMode); assertEquals(PolicySet.PASSWORD_MODE_SIMPLE, p.mPasswordMode);
assertEquals(0, p.mMinPasswordLength); assertEquals(0, p.mMinPasswordLength);
assertEquals(PolicySet.PASSWORD_MAX_FAILS_MAX, p.mMaxPasswordFails); assertEquals(PolicySet.PASSWORD_MAX_FAILS_MAX, p.mMaxPasswordFails);
@ -275,9 +288,11 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
assertEquals(0, p.mPasswordHistory); assertEquals(0, p.mPasswordHistory);
assertEquals(0, p.mPasswordComplexChars); assertEquals(0, p.mPasswordComplexChars);
assertFalse(p.mRequireRemoteWipe); assertFalse(p.mRequireRemoteWipe);
assertFalse(p.mRequireEncryption);
// Check SCREEN_LOCK_TIME (note, mode must be set for this to be non-zero)
p = new PolicySet(0, PolicySet.PASSWORD_MODE_SIMPLE, 0, PolicySet.SCREEN_LOCK_TIME_MAX, p = new PolicySet(0, PolicySet.PASSWORD_MODE_SIMPLE, 0, PolicySet.SCREEN_LOCK_TIME_MAX,
false, 0, 0, 0); false, 0, 0, 0, false);
assertEquals(PolicySet.PASSWORD_MODE_SIMPLE, p.mPasswordMode); assertEquals(PolicySet.PASSWORD_MODE_SIMPLE, p.mPasswordMode);
assertEquals(0, p.mMinPasswordLength); assertEquals(0, p.mMinPasswordLength);
assertEquals(0, p.mMaxPasswordFails); assertEquals(0, p.mMaxPasswordFails);
@ -286,8 +301,10 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
assertEquals(0, p.mPasswordHistory); assertEquals(0, p.mPasswordHistory);
assertEquals(0, p.mPasswordComplexChars); assertEquals(0, p.mPasswordComplexChars);
assertFalse(p.mRequireRemoteWipe); assertFalse(p.mRequireRemoteWipe);
assertFalse(p.mRequireEncryption);
p = new PolicySet(0, PolicySet.PASSWORD_MODE_NONE, 0, 0, true, 0, 0, 0); // Check REQUIRE_REMOTE_WIPE
p = new PolicySet(0, PolicySet.PASSWORD_MODE_NONE, 0, 0, true, 0, 0, 0, false);
assertEquals(PolicySet.PASSWORD_MODE_NONE, p.mPasswordMode); assertEquals(PolicySet.PASSWORD_MODE_NONE, p.mPasswordMode);
assertEquals(0, p.mMinPasswordLength); assertEquals(0, p.mMinPasswordLength);
assertEquals(0, p.mMaxPasswordFails); assertEquals(0, p.mMaxPasswordFails);
@ -296,9 +313,11 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
assertEquals(0, p.mPasswordHistory); assertEquals(0, p.mPasswordHistory);
assertEquals(0, p.mPasswordComplexChars); assertEquals(0, p.mPasswordComplexChars);
assertTrue(p.mRequireRemoteWipe); assertTrue(p.mRequireRemoteWipe);
assertFalse(p.mRequireEncryption);
// Check PASSWORD_EXPIRATION (note, mode must be set for this to be non-zero)
p = new PolicySet(0, PolicySet.PASSWORD_MODE_SIMPLE, 0, 0, false, p = new PolicySet(0, PolicySet.PASSWORD_MODE_SIMPLE, 0, 0, false,
PolicySet.PASSWORD_EXPIRATION_MAX, 0, 0); PolicySet.PASSWORD_EXPIRATION_MAX, 0, 0, false);
assertEquals(PolicySet.PASSWORD_MODE_SIMPLE, p.mPasswordMode); assertEquals(PolicySet.PASSWORD_MODE_SIMPLE, p.mPasswordMode);
assertEquals(0, p.mMinPasswordLength); assertEquals(0, p.mMinPasswordLength);
assertEquals(0, p.mMaxPasswordFails); assertEquals(0, p.mMaxPasswordFails);
@ -307,9 +326,11 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
assertEquals(0, p.mPasswordHistory); assertEquals(0, p.mPasswordHistory);
assertEquals(0, p.mPasswordComplexChars); assertEquals(0, p.mPasswordComplexChars);
assertFalse(p.mRequireRemoteWipe); assertFalse(p.mRequireRemoteWipe);
assertFalse(p.mRequireEncryption);
// Check PASSWORD_HISTORY (note, mode must be set for this to be non-zero)
p = new PolicySet(0, PolicySet.PASSWORD_MODE_SIMPLE, 0, 0, false, 0, p = new PolicySet(0, PolicySet.PASSWORD_MODE_SIMPLE, 0, 0, false, 0,
PolicySet.PASSWORD_HISTORY_MAX, 0); PolicySet.PASSWORD_HISTORY_MAX, 0, false);
assertEquals(PolicySet.PASSWORD_MODE_SIMPLE, p.mPasswordMode); assertEquals(PolicySet.PASSWORD_MODE_SIMPLE, p.mPasswordMode);
assertEquals(0, p.mMinPasswordLength); assertEquals(0, p.mMinPasswordLength);
assertEquals(0, p.mMaxPasswordFails); assertEquals(0, p.mMaxPasswordFails);
@ -318,9 +339,11 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
assertEquals(PolicySet.PASSWORD_HISTORY_MAX, p.mPasswordHistory); assertEquals(PolicySet.PASSWORD_HISTORY_MAX, p.mPasswordHistory);
assertEquals(0, p.mPasswordComplexChars); assertEquals(0, p.mPasswordComplexChars);
assertFalse(p.mRequireRemoteWipe); assertFalse(p.mRequireRemoteWipe);
assertFalse(p.mRequireEncryption);
// Check PASSWORD_COMPLEX_CHARS (note, mode must be set for this to be non-zero)
p = new PolicySet(0, PolicySet.PASSWORD_MODE_STRONG, 0, 0, false, 0, 0, p = new PolicySet(0, PolicySet.PASSWORD_MODE_STRONG, 0, 0, false, 0, 0,
PolicySet.PASSWORD_COMPLEX_CHARS_MAX); PolicySet.PASSWORD_COMPLEX_CHARS_MAX, false);
assertEquals(PolicySet.PASSWORD_MODE_STRONG, p.mPasswordMode); assertEquals(PolicySet.PASSWORD_MODE_STRONG, p.mPasswordMode);
assertEquals(0, p.mMinPasswordLength); assertEquals(0, p.mMinPasswordLength);
assertEquals(0, p.mMaxPasswordFails); assertEquals(0, p.mMaxPasswordFails);
@ -329,6 +352,19 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
assertEquals(0, p.mPasswordHistory); assertEquals(0, p.mPasswordHistory);
assertEquals(PolicySet.PASSWORD_COMPLEX_CHARS_MAX, p.mPasswordComplexChars); assertEquals(PolicySet.PASSWORD_COMPLEX_CHARS_MAX, p.mPasswordComplexChars);
assertFalse(p.mRequireRemoteWipe); assertFalse(p.mRequireRemoteWipe);
assertFalse(p.mRequireEncryption);
// Check REQUIRE_ENCRYPTION
p = new PolicySet(0, PolicySet.PASSWORD_MODE_NONE, 0, 0, false, 0, 0, 0, true);
assertEquals(PolicySet.PASSWORD_MODE_NONE, p.mPasswordMode);
assertEquals(0, p.mMinPasswordLength);
assertEquals(0, p.mMaxPasswordFails);
assertEquals(0, p.mMaxScreenLockTime);
assertEquals(0, p.mPasswordExpirationDays);
assertEquals(0, p.mPasswordHistory);
assertEquals(0, p.mPasswordComplexChars);
assertFalse(p.mRequireRemoteWipe);
assertTrue(p.mRequireEncryption);
} }
/** /**
@ -336,7 +372,7 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
*/ */
@SmallTest @SmallTest
public void testAccountEncoding() { public void testAccountEncoding() {
PolicySet p1 = new PolicySet(1, PolicySet.PASSWORD_MODE_STRONG, 3, 4, true, 7, 8, 9); PolicySet p1 = new PolicySet(1, PolicySet.PASSWORD_MODE_STRONG, 3, 4, true, 7, 8, 9, false);
Account a = new Account(); Account a = new Account();
final String SYNC_KEY = "test_sync_key"; final String SYNC_KEY = "test_sync_key";
p1.writeAccount(a, SYNC_KEY, false, null); p1.writeAccount(a, SYNC_KEY, false, null);
@ -350,9 +386,9 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
*/ */
@SmallTest @SmallTest
public void testEquals() { public void testEquals() {
PolicySet p1 = new PolicySet(1, PolicySet.PASSWORD_MODE_STRONG, 3, 4, true, 7, 8, 9); PolicySet p1 = new PolicySet(1, PolicySet.PASSWORD_MODE_STRONG, 3, 4, true, 7, 8, 9, false);
PolicySet p2 = new PolicySet(1, PolicySet.PASSWORD_MODE_STRONG, 3, 4, true, 7, 8, 9); PolicySet p2 = new PolicySet(1, PolicySet.PASSWORD_MODE_STRONG, 3, 4, true, 7, 8, 9, false);
PolicySet p3 = new PolicySet(2, PolicySet.PASSWORD_MODE_SIMPLE, 5, 6, true, 7, 8, 9); PolicySet p3 = new PolicySet(2, PolicySet.PASSWORD_MODE_SIMPLE, 5, 6, true, 7, 8, 9, false);
assertTrue(p1.equals(p2)); assertTrue(p1.equals(p2));
assertFalse(p2.equals(p3)); assertFalse(p2.equals(p3));
} }
@ -401,11 +437,13 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
*/ */
public void testDisableAdmin() { public void testDisableAdmin() {
Account a1 = ProviderTestUtils.setupAccount("disable-1", false, mMockContext); Account a1 = ProviderTestUtils.setupAccount("disable-1", false, mMockContext);
PolicySet p1 = new PolicySet(10, PolicySet.PASSWORD_MODE_SIMPLE, 0, 0, false, 0, 0, 0); PolicySet p1 = new PolicySet(10, PolicySet.PASSWORD_MODE_SIMPLE, 0, 0, false, 0, 0, 0,
false);
p1.writeAccount(a1, "sync-key-1", true, mMockContext); p1.writeAccount(a1, "sync-key-1", true, mMockContext);
Account a2 = ProviderTestUtils.setupAccount("disable-2", false, mMockContext); Account a2 = ProviderTestUtils.setupAccount("disable-2", false, mMockContext);
PolicySet p2 = new PolicySet(20, PolicySet.PASSWORD_MODE_STRONG, 25, 26, false, 0, 0, 0); PolicySet p2 = new PolicySet(20, PolicySet.PASSWORD_MODE_STRONG, 25, 26, false, 0, 0, 0,
false);
p2.writeAccount(a2, "sync-key-2", true, mMockContext); p2.writeAccount(a2, "sync-key-2", true, mMockContext);
Account a3 = ProviderTestUtils.setupAccount("disable-3", false, mMockContext); Account a3 = ProviderTestUtils.setupAccount("disable-3", false, mMockContext);
@ -460,7 +498,8 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
// Add a single expiring account // Add a single expiring account
Account a2 = ProviderTestUtils.setupAccount("expiring-2", false, mMockContext); Account a2 = ProviderTestUtils.setupAccount("expiring-2", false, mMockContext);
PolicySet p2 = new PolicySet(20, PolicySet.PASSWORD_MODE_STRONG, 25, 26, false, 30, 0, 0); PolicySet p2 = new PolicySet(20, PolicySet.PASSWORD_MODE_STRONG, 25, 26, false, 30, 0, 0,
false);
p2.writeAccount(a2, "sync-key-2", true, mMockContext); p2.writeAccount(a2, "sync-key-2", true, mMockContext);
// The expiring account should be returned // The expiring account should be returned
@ -469,7 +508,8 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
// Add an account with a longer expiration // Add an account with a longer expiration
Account a3 = ProviderTestUtils.setupAccount("expiring-3", false, mMockContext); Account a3 = ProviderTestUtils.setupAccount("expiring-3", false, mMockContext);
PolicySet p3 = new PolicySet(20, PolicySet.PASSWORD_MODE_STRONG, 25, 26, false, 60, 0, 0); PolicySet p3 = new PolicySet(20, PolicySet.PASSWORD_MODE_STRONG, 25, 26, false, 60, 0, 0,
false);
p3.writeAccount(a3, "sync-key-3", true, mMockContext); p3.writeAccount(a3, "sync-key-3", true, mMockContext);
// The original expiring account (a2) should be returned // The original expiring account (a2) should be returned
@ -478,7 +518,8 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
// Add an account with a shorter expiration // Add an account with a shorter expiration
Account a4 = ProviderTestUtils.setupAccount("expiring-4", false, mMockContext); Account a4 = ProviderTestUtils.setupAccount("expiring-4", false, mMockContext);
PolicySet p4 = new PolicySet(20, PolicySet.PASSWORD_MODE_STRONG, 25, 26, false, 15, 0, 0); PolicySet p4 = new PolicySet(20, PolicySet.PASSWORD_MODE_STRONG, 25, 26, false, 15, 0, 0,
false);
p4.writeAccount(a4, "sync-key-4", true, mMockContext); p4.writeAccount(a4, "sync-key-4", true, mMockContext);
// The new expiring account (a4) should be returned // The new expiring account (a4) should be returned
@ -507,7 +548,8 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
// Two accounts - a1 is normal, a2 has security (but no expiration) // Two accounts - a1 is normal, a2 has security (but no expiration)
Account a1 = ProviderTestUtils.setupAccount("expired-1", true, mMockContext); Account a1 = ProviderTestUtils.setupAccount("expired-1", true, mMockContext);
Account a2 = ProviderTestUtils.setupAccount("expired-2", false, mMockContext); Account a2 = ProviderTestUtils.setupAccount("expired-2", false, mMockContext);
PolicySet p2 = new PolicySet(20, PolicySet.PASSWORD_MODE_STRONG, 25, 26, false, 0, 0, 0); PolicySet p2 = new PolicySet(20, PolicySet.PASSWORD_MODE_STRONG, 25, 26, false, 0, 0, 0,
false);
p2.writeAccount(a2, "sync-key-2", true, mMockContext); p2.writeAccount(a2, "sync-key-2", true, mMockContext);
// Add a mailbox & messages to each account // Add a mailbox & messages to each account
@ -532,7 +574,8 @@ public class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
// Add 3rd account that really expires // Add 3rd account that really expires
Account a3 = ProviderTestUtils.setupAccount("expired-3", false, mMockContext); Account a3 = ProviderTestUtils.setupAccount("expired-3", false, mMockContext);
PolicySet p3 = new PolicySet(20, PolicySet.PASSWORD_MODE_STRONG, 25, 26, false, 30, 0, 0); PolicySet p3 = new PolicySet(20, PolicySet.PASSWORD_MODE_STRONG, 25, 26, false, 30, 0, 0,
false);
p3.writeAccount(a3, "sync-key-3", true, mMockContext); p3.writeAccount(a3, "sync-key-3", true, mMockContext);
// Add mailbox & messages to 3rd account // Add mailbox & messages to 3rd account