From b2a909598ba78783b05c58508310f864c56c897b Mon Sep 17 00:00:00 2001 From: Marc Blank Date: Wed, 11 May 2011 10:52:48 -0700 Subject: [PATCH] Create/test method to set "not downloadable" flag based on policy Change-Id: I08bec46d0c961bdc9530768f5198346338b3e2f3 --- .../android/emailcommon/provider/Policy.java | 49 +++++++++++ .../android/email/provider/PolicyTests.java | 81 +++++++++++++++++++ 2 files changed, 130 insertions(+) diff --git a/emailcommon/src/com/android/emailcommon/provider/Policy.java b/emailcommon/src/com/android/emailcommon/provider/Policy.java index 6afc7b23c..6a8de571a 100644 --- a/emailcommon/src/com/android/emailcommon/provider/Policy.java +++ b/emailcommon/src/com/android/emailcommon/provider/Policy.java @@ -19,6 +19,7 @@ import com.android.emailcommon.utility.Utility; import android.app.admin.DevicePolicyManager; import android.content.ContentProviderOperation; +import android.content.ContentResolver; import android.content.ContentUris; import android.content.ContentValues; import android.content.Context; @@ -113,6 +114,12 @@ public final class Policy extends EmailContent implements EmailContent.PolicyCol public static final Policy NO_POLICY = new Policy(); + private static final String[] ATTACHMENT_RESET_PROJECTION = + new String[] {EmailContent.RECORD_ID, AttachmentColumns.SIZE, AttachmentColumns.FLAGS}; + private static final int ATTACHMENT_RESET_PROJECTION_ID = 0; + private static final int ATTACHMENT_RESET_PROJECTION_SIZE = 1; + private static final int ATTACHMENT_RESET_PROJECTION_FLAGS = 2; + public Policy() { mBaseUri = CONTENT_URI; // By default, the password mode is "none" @@ -208,6 +215,48 @@ public final class Policy extends EmailContent implements EmailContent.PolicyCol } } + + /** + * Review all attachment records for this account, and reset the "don't allow download" flag + * as required by the account's new security policies + * @param context the caller's context + * @param account the account whose attachments need to be reviewed + * @param policy the new policy for this account + */ + public static void setAttachmentFlagsForNewPolicy(Context context, Account account, + Policy policy) { + // A nasty bit of work; start with all attachments for a given account + ContentResolver resolver = context.getContentResolver(); + Cursor c = resolver.query(Attachment.CONTENT_URI, ATTACHMENT_RESET_PROJECTION, + AttachmentColumns.ACCOUNT_KEY + "=?", new String[] {Long.toString(account.mId)}, + null); + ContentValues cv = new ContentValues(); + try { + // Get maximum allowed size (0 if we don't allow attachments at all) + int policyMax = policy.mDontAllowAttachments ? 0 : (policy.mMaxAttachmentSize > 0) ? + policy.mMaxAttachmentSize : Integer.MAX_VALUE; + while (c.moveToNext()) { + int flags = c.getInt(ATTACHMENT_RESET_PROJECTION_FLAGS); + int size = c.getInt(ATTACHMENT_RESET_PROJECTION_SIZE); + boolean wasRestricted = (flags & Attachment.FLAG_POLICY_DISALLOWS_DOWNLOAD) != 0; + boolean isRestricted = size > policyMax; + if (isRestricted != wasRestricted) { + if (isRestricted) { + flags |= Attachment.FLAG_POLICY_DISALLOWS_DOWNLOAD; + } else { + flags &= ~Attachment.FLAG_POLICY_DISALLOWS_DOWNLOAD; + } + long id = c.getLong(ATTACHMENT_RESET_PROJECTION_ID); + cv.put(AttachmentColumns.FLAGS, flags); + resolver.update(ContentUris.withAppendedId(Attachment.CONTENT_URI, id), + cv, null, null); + } + } + } finally { + c.close(); + } + } + /** * Normalize the Policy. If the password mode is "none", zero out all password-related fields; * zero out complex characters for simple passwords. diff --git a/tests/src/com/android/email/provider/PolicyTests.java b/tests/src/com/android/email/provider/PolicyTests.java index 487ade4da..9fd0fab0d 100644 --- a/tests/src/com/android/email/provider/PolicyTests.java +++ b/tests/src/com/android/email/provider/PolicyTests.java @@ -18,6 +18,10 @@ package com.android.email.provider; import com.android.emailcommon.provider.EmailContent; import com.android.emailcommon.provider.EmailContent.Account; +import com.android.emailcommon.provider.EmailContent.Attachment; +import com.android.emailcommon.provider.EmailContent.AttachmentColumns; +import com.android.emailcommon.provider.EmailContent.Mailbox; +import com.android.emailcommon.provider.EmailContent.Message; import com.android.emailcommon.provider.Policy; import android.content.Context; @@ -25,6 +29,8 @@ import android.os.Parcel; import android.test.ProviderTestCase2; import android.test.suitebuilder.annotation.MediumTest; +import java.util.ArrayList; + /** * This is a series of unit tests for the Policy class * @@ -35,6 +41,9 @@ import android.test.suitebuilder.annotation.MediumTest; @MediumTest public class PolicyTests extends ProviderTestCase2 { + private static final String CANT_DOWNLOAD_SELECTION = "(" + AttachmentColumns.FLAGS + "&" + + Attachment.FLAG_POLICY_DISALLOWS_DOWNLOAD + ")!=0"; + private Context mMockContext; public PolicyTests() { @@ -104,6 +113,78 @@ public class PolicyTests extends ProviderTestCase2 { assertNull(account.mSecuritySyncKey); } + private Attachment setupSimpleAttachment(String name, long size, Account acct) { + Attachment att = ProviderTestUtils.setupAttachment(-1, name, size, false, mMockContext); + att.mAccountKey = acct.mId; + return att; + } + public void testSetAttachmentFlagsForNewPolicy() { + Account acct = ProviderTestUtils.setupAccount("acct1", true, mMockContext); + Policy policy1 = new Policy(); + policy1.mDontAllowAttachments = true; + policy1.setAccountPolicy(mMockContext, acct, "0"); + Mailbox box = ProviderTestUtils.setupMailbox("box1", acct.mId, true, mMockContext); + Message msg1 = ProviderTestUtils.setupMessage("message1", acct.mId, box.mId, false, false, + mMockContext); + ArrayList atts = new ArrayList(); + Attachment att1 = setupSimpleAttachment("fileName1", 10001L, acct); + atts.add(att1); + Attachment att2 = setupSimpleAttachment("fileName2", 20001L, acct); + atts.add(att2); + msg1.mAttachments = atts; + msg1.save(mMockContext); + Message msg2 = ProviderTestUtils.setupMessage("message2", acct.mId, box.mId, false, false, + mMockContext); + atts.clear(); + Attachment att3 = setupSimpleAttachment("fileName3", 70001L, acct); + atts.add(att3); + Attachment att4 = setupSimpleAttachment("fileName4", 5001L, acct); + atts.add(att4); + msg2.mAttachments = atts; + msg2.save(mMockContext); + // Make sure we've got our 4 attachments + assertEquals(4, EmailContent.count(mMockContext, Attachment.CONTENT_URI)); + // All should be downloadable + assertEquals(0, EmailContent.count(mMockContext, Attachment.CONTENT_URI, + CANT_DOWNLOAD_SELECTION, null)); + // Enforce our no-attachments policy + Policy.setAttachmentFlagsForNewPolicy(mMockContext, acct, policy1); + // None should be downloadable + assertEquals(4, EmailContent.count(mMockContext, Attachment.CONTENT_URI, + CANT_DOWNLOAD_SELECTION, null)); + + Policy policy2 = new Policy(); + policy2.mMaxAttachmentSize = 20000; + // Switch to new policy that sets a limit, but otherwise allows attachments + Policy.setAttachmentFlagsForNewPolicy(mMockContext, acct, policy2); + // Two shouldn't be downloadable + assertEquals(2, EmailContent.count(mMockContext, Attachment.CONTENT_URI, + CANT_DOWNLOAD_SELECTION, null)); + // Make sure they're the right ones (att2 and att3) + att2 = Attachment.restoreAttachmentWithId(mMockContext, att2.mId); + assertTrue((att2.mFlags & Attachment.FLAG_POLICY_DISALLOWS_DOWNLOAD) != 0); + att3 = Attachment.restoreAttachmentWithId(mMockContext, att3.mId); + assertTrue((att3.mFlags & Attachment.FLAG_POLICY_DISALLOWS_DOWNLOAD) != 0); + + Policy policy3 = new Policy(); + policy3.mMaxAttachmentSize = 5001; + // Switch to new policy that sets a lower limit + Policy.setAttachmentFlagsForNewPolicy(mMockContext, acct, policy3); + // Three shouldn't be downloadable + assertEquals(3, EmailContent.count(mMockContext, Attachment.CONTENT_URI, + CANT_DOWNLOAD_SELECTION, null)); + // Make sure the right one is downloadable + att4 = Attachment.restoreAttachmentWithId(mMockContext, att4.mId); + assertTrue((att4.mFlags & Attachment.FLAG_POLICY_DISALLOWS_DOWNLOAD) == 0); + + Policy policy4 = new Policy(); + // Switch to new policy that is without restrictions + Policy.setAttachmentFlagsForNewPolicy(mMockContext, acct, policy4); + // Nothing should be blocked now + assertEquals(0, EmailContent.count(mMockContext, Attachment.CONTENT_URI, + CANT_DOWNLOAD_SELECTION, null)); + } + public void testParcel() { Policy policy = new Policy(); policy.mPasswordMode = Policy.PASSWORD_MODE_STRONG;