From 844e5eb8fbe4ce6b70a69b51cb71135fa1f9ba38 Mon Sep 17 00:00:00 2001 From: Nick Alexander Date: Fri, 27 Mar 2015 11:24:04 -0700 Subject: [PATCH] Bug 1148029 - Disable Reading List sync when using custom endpoints. r=rnewman This tries to sync prod accounts against prod Reading List, stage accounts against stage Reading List, and reject all other account servers. Custom Sync (Token) servers (not prod, not stage) should cause us not to Sync Reading List, the intention being to avoid storing data with Mozilla if the user has expressed a desire not to. ======== https://github.com/mozilla-services/android-sync/commit/b69b0975059210cb2e4f72d5509dec9ce86d8b30 Author: Nick Alexander Bug 1148029 - Disable Reading List sync when using custom endpoints. Custom is interpreted to mean neither Mozilla production nor Mozilla stage. To ease the burden of testing stage, we sync the reading list against stage reading list storage when the account is authing against stage FxA. Messaging this in some way would be nice but will have to wait for follow-up. --- .../fxa/authenticator/AndroidFxAccount.java | 1 + .../authenticator/FxAccountAuthenticator.java | 10 ++++- .../base/reading/ReadingListSyncAdapter.java | 38 +++++++++++++++++-- 3 files changed, 44 insertions(+), 5 deletions(-) diff --git a/mobile/android/base/fxa/authenticator/AndroidFxAccount.java b/mobile/android/base/fxa/authenticator/AndroidFxAccount.java index ac63b551a9c7..f3866d75d6ad 100644 --- a/mobile/android/base/fxa/authenticator/AndroidFxAccount.java +++ b/mobile/android/base/fxa/authenticator/AndroidFxAccount.java @@ -652,6 +652,7 @@ public class AndroidFxAccount { setState(state.makeSeparatedState()); accountManager.setUserData(account, ACCOUNT_KEY_IDP_SERVER, authServerEndpoint); accountManager.setUserData(account, ACCOUNT_KEY_TOKEN_SERVER, tokenServerEndpoint); + ContentResolver.setIsSyncable(account, BrowserContract.READING_LIST_AUTHORITY, 1); } /** diff --git a/mobile/android/base/fxa/authenticator/FxAccountAuthenticator.java b/mobile/android/base/fxa/authenticator/FxAccountAuthenticator.java index 4433e7f307ef..c043ed102e55 100644 --- a/mobile/android/base/fxa/authenticator/FxAccountAuthenticator.java +++ b/mobile/android/base/fxa/authenticator/FxAccountAuthenticator.java @@ -183,7 +183,15 @@ public class FxAccountAuthenticator extends AbstractAccountAuthenticator { final Responder responder = new Responder(response, fxAccount); - final String oauthServerUri = FxAccountConstants.DEFAULT_OAUTH_SERVER_ENDPOINT; + // Allow testing against stage. + final boolean usingStageAuthServer = FxAccountConstants.STAGE_AUTH_SERVER_ENDPOINT.equals(fxAccount.getAccountServerURI()); + final String oauthServerUri; + if (usingStageAuthServer) { + oauthServerUri = FxAccountConstants.STAGE_OAUTH_SERVER_ENDPOINT; + } else { + oauthServerUri = FxAccountConstants.DEFAULT_OAUTH_SERVER_ENDPOINT; + } + final String audience; try { audience = FxAccountUtils.getAudienceForURL(oauthServerUri); // The assertion gets traded in for an oauth bearer token. diff --git a/mobile/android/base/reading/ReadingListSyncAdapter.java b/mobile/android/base/reading/ReadingListSyncAdapter.java index 7a8b7047e1cf..0a4544f6eb1b 100644 --- a/mobile/android/base/reading/ReadingListSyncAdapter.java +++ b/mobile/android/base/reading/ReadingListSyncAdapter.java @@ -16,7 +16,9 @@ import org.mozilla.gecko.background.ReadingListConstants; import org.mozilla.gecko.background.common.PrefsBranch; import org.mozilla.gecko.background.common.log.Logger; import org.mozilla.gecko.background.fxa.FxAccountUtils; +import org.mozilla.gecko.db.BrowserContract; import org.mozilla.gecko.db.BrowserContract.ReadingListItems; +import org.mozilla.gecko.fxa.FxAccountConstants; import org.mozilla.gecko.fxa.authenticator.AndroidFxAccount; import org.mozilla.gecko.fxa.sync.FxAccountSyncDelegate; import org.mozilla.gecko.sync.net.AuthHeaderProvider; @@ -110,7 +112,7 @@ public class ReadingListSyncAdapter extends AbstractThreadedSyncAdapter { } private void syncWithAuthorization(final Context context, - final Account account, + final String endpointString, final SyncResult syncResult, final FxAccountSyncDelegate syncDelegate, final String authToken, @@ -118,7 +120,6 @@ public class ReadingListSyncAdapter extends AbstractThreadedSyncAdapter { final Bundle extras) { final AuthHeaderProvider auth = new BearerAuthHeaderProvider(authToken); - final String endpointString = ReadingListConstants.DEFAULT_PROD_ENDPOINT; final URI endpoint; Logger.info(LOG_TAG, "Syncing reading list against " + endpointString); try { @@ -152,7 +153,7 @@ public class ReadingListSyncAdapter extends AbstractThreadedSyncAdapter { // time through, we'll request a new one, which will drive the login // state machine, produce a new assertion, and eventually a fresh token. Logger.info(LOG_TAG, "Invalidating oauth token after 401!"); - AccountManager.get(context).invalidateAuthToken(account.type, authToken); + AccountManager.get(context).invalidateAuthToken(FxAccountConstants.ACCOUNT_TYPE, authToken); } }); // TODO: backoffs, and everything else handled by a SessionCallback. @@ -166,6 +167,35 @@ public class ReadingListSyncAdapter extends AbstractThreadedSyncAdapter { final Context context = getContext(); final AndroidFxAccount fxAccount = new AndroidFxAccount(context, account); + // Don't sync Reading List if we're in a non-default configuration, but allow testing against stage. + final String accountServerURI = fxAccount.getAccountServerURI(); + final boolean usingDefaultAuthServer = FxAccountConstants.DEFAULT_AUTH_SERVER_ENDPOINT.equals(accountServerURI); + final boolean usingStageAuthServer = FxAccountConstants.STAGE_AUTH_SERVER_ENDPOINT.equals(accountServerURI); + if (!usingDefaultAuthServer && !usingStageAuthServer) { + Logger.error(LOG_TAG, "Skipping Reading List sync because Firefox Account is not using prod or stage auth server."); + // Stop syncing the Reading List entirely. + ContentResolver.setIsSyncable(account, BrowserContract.READING_LIST_AUTHORITY, 0); + return; + } + final String tokenServerURI = fxAccount.getTokenServerURI(); + final boolean usingDefaultSyncServer = FxAccountConstants.DEFAULT_TOKEN_SERVER_ENDPOINT.equals(tokenServerURI); + final boolean usingStageSyncServer = FxAccountConstants.STAGE_TOKEN_SERVER_ENDPOINT.equals(tokenServerURI); + if (!usingDefaultSyncServer && !usingStageSyncServer) { + Logger.error(LOG_TAG, "Skipping Reading List sync because Sync is not using the prod or stage Sync (token) server."); + Logger.debug(LOG_TAG, "If the user has chosen to not store Sync data with Mozilla, we shouldn't store Reading List data with Mozilla ."); + // Stop syncing the Reading List entirely. + ContentResolver.setIsSyncable(account, BrowserContract.READING_LIST_AUTHORITY, 0); + return; + } + + // Allow testing against stage. + final String endpointString; + if (usingStageAuthServer) { + endpointString = ReadingListConstants.DEFAULT_DEV_ENDPOINT; + } else { + endpointString = ReadingListConstants.DEFAULT_PROD_ENDPOINT; + } + final CountDownLatch latch = new CountDownLatch(1); final FxAccountSyncDelegate syncDelegate = new FxAccountSyncDelegate(latch, syncResult); @@ -181,7 +211,7 @@ public class ReadingListSyncAdapter extends AbstractThreadedSyncAdapter { throw new RuntimeException("Couldn't get oauth token! Aborting sync."); } final SharedPreferences sharedPrefs = fxAccount.getReadingListPrefs(); - syncWithAuthorization(context, account, syncResult, syncDelegate, authToken, sharedPrefs, extras); + syncWithAuthorization(context, endpointString, syncResult, syncDelegate, authToken, sharedPrefs, extras); latch.await(TIMEOUT_SECONDS, TimeUnit.SECONDS); Logger.info(LOG_TAG, "Reading list sync done.");