private CacheEntry getEntry(Context context, Account account) {
   CacheEntry entry;
   if (account.isSaved() && !account.isTemporary()) {
     entry = mCache.get(account.mId);
     if (entry == null) {
       LogUtils.d(Logging.LOG_TAG, "initializing entry from database");
       final HostAuth hostAuth = account.getOrCreateHostAuthRecv(context);
       final Credential credential = hostAuth.getOrCreateCredential(context);
       entry =
           new CacheEntry(
               account.mId,
               credential.mProviderId,
               credential.mAccessToken,
               credential.mRefreshToken,
               credential.mExpiration);
       mCache.put(account.mId, entry);
     }
   } else {
     // This account is temporary, just create a temporary entry. Don't store
     // it in the cache, it won't be findable because we don't yet have an account Id.
     final HostAuth hostAuth = account.getOrCreateHostAuthRecv(context);
     final Credential credential = hostAuth.getCredential(context);
     entry =
         new CacheEntry(
             account.mId,
             credential.mProviderId,
             credential.mAccessToken,
             credential.mRefreshToken,
             credential.mExpiration);
   }
   return entry;
 }
 @Override
 public Bundle autoDiscover(String userName, String password) throws RemoteException {
   HostAuth hostAuth = new HostAuth();
   hostAuth.mLogin = userName;
   hostAuth.mPassword = password;
   hostAuth.mFlags = HostAuth.FLAG_AUTHENTICATE | HostAuth.FLAG_SSL;
   hostAuth.mPort = 443;
   return new EasSyncService().tryAutodiscover(ExchangeService.this, hostAuth);
 }
  private void saveEntry(Context context, CacheEntry entry) {
    LogUtils.d(Logging.LOG_TAG, "saveEntry");

    final Account account = Account.restoreAccountWithId(context, entry.mAccountId);
    final HostAuth hostAuth = account.getOrCreateHostAuthRecv(context);
    final Credential cred = hostAuth.getOrCreateCredential(context);
    cred.mProviderId = entry.mProviderId;
    cred.mAccessToken = entry.mAccessToken;
    cred.mRefreshToken = entry.mRefreshToken;
    cred.mExpiration = entry.mExpirationTime;
    cred.update(context, cred.toContentValues());
  }
Ejemplo n.º 4
0
  /**
   * Legacy URI parser. Used in parsing template from provider.xml Example string:
   * "eas+ssl+trustallcerts://user:password@server/domain:123"
   *
   * <p>Note that the use of client certificate is specified in the URI, a secure connection type
   * must be used.
   */
  public static void setHostAuthFromString(HostAuth auth, String uriString)
      throws URISyntaxException {
    URI uri = new URI(uriString);
    String path = uri.getPath();
    String domain = null;
    if (!TextUtils.isEmpty(path)) {
      // Strip off the leading slash that begins the path.
      domain = path.substring(1);
    }
    auth.mDomain = domain;
    auth.setLogin(uri.getUserInfo());

    String scheme = uri.getScheme();
    auth.setConnection(scheme, uri.getHost(), uri.getPort());
  }
 /**
  * Return a list of all Accounts in EmailProvider. Because the result of this call may be used in
  * account reconciliation, an exception is thrown if the result cannot be guaranteed accurate
  *
  * @param context the caller's context
  * @param accounts a list that Accounts will be added into
  * @return the list of Accounts
  * @throws ProviderUnavailableException if the list of Accounts cannot be guaranteed valid
  */
 @Override
 public AccountList collectAccounts(Context context, AccountList accounts) {
   ContentResolver resolver = context.getContentResolver();
   Cursor c = resolver.query(Account.CONTENT_URI, Account.CONTENT_PROJECTION, null, null, null);
   // We must throw here; callers might use the information we provide for reconciliation, etc.
   if (c == null) throw new ProviderUnavailableException();
   try {
     ContentValues cv = new ContentValues();
     while (c.moveToNext()) {
       long hostAuthId = c.getLong(Account.CONTENT_HOST_AUTH_KEY_RECV_COLUMN);
       if (hostAuthId > 0) {
         HostAuth ha = HostAuth.restoreHostAuthWithId(context, hostAuthId);
         if (ha != null && ha.mProtocol.equals(Eas.PROTOCOL)) {
           Account account = new Account();
           account.restore(c);
           // Cache the HostAuth
           account.mHostAuthRecv = ha;
           accounts.add(account);
           // Fixup flags for inbox (should accept moved mail)
           Mailbox inbox = Mailbox.restoreMailboxOfType(context, account.mId, Mailbox.TYPE_INBOX);
           if (inbox != null && ((inbox.mFlags & Mailbox.FLAG_ACCEPTS_MOVED_MAIL) == 0)) {
             cv.put(MailboxColumns.FLAGS, inbox.mFlags | Mailbox.FLAG_ACCEPTS_MOVED_MAIL);
             resolver.update(
                 ContentUris.withAppendedId(Mailbox.CONTENT_URI, inbox.mId), cv, null, null);
           }
         }
       }
     }
   } finally {
     c.close();
   }
   return accounts;
 }
Ejemplo n.º 6
0
 public void testValidateAccount() throws Exception {
   setupAccountMailboxAndMessages(0);
   HostAuth auth = new HostAuth();
   auth.mAddress = mAccount.mEmailAddress;
   auth.mProtocol = "eas";
   auth.mLogin = mAccount.mDisplayName;
   auth.mPassword = "******";
   auth.mPort = 80;
   EasSyncService eas = getTestService(mAccount, mMailbox);
   Bundle bundle = eas.validateAccount(auth, mProviderContext);
   assertEquals("14.1", bundle.get(EmailServiceProxy.VALIDATE_BUNDLE_PROTOCOL_VERSION));
   assertEquals(
       MessagingException.NO_ERROR, bundle.get(EmailServiceProxy.VALIDATE_BUNDLE_RESULT_CODE));
 }
Ejemplo n.º 7
0
  public void testTryAutodiscover() throws RemoteException, IOException {
    String userName = "******";
    String password = "******";

    EasSyncService service = new EasSyncService();
    Bundle bundle1 = service.tryAutodiscover(userName, password);
    Bundle bundle2 = new Bundle();
    bundle2.putInt(EmailServiceProxy.AUTO_DISCOVER_BUNDLE_ERROR_CODE, MessagingException.NO_ERROR);
    HostAuth hostAuth = new HostAuth();
    hostAuth.mAddress = "google.com";
    hostAuth.mLogin = userName;
    hostAuth.mPassword = password;
    hostAuth.mPort = 443;
    hostAuth.mProtocol = "eas";
    hostAuth.mFlags = HostAuth.FLAG_SSL | HostAuth.FLAG_AUTHENTICATE;
    bundle2.putParcelable(EmailServiceProxy.AUTO_DISCOVER_BUNDLE_HOST_AUTH, hostAuth);
    assertEquals(bundle2.toString(), bundle1.toString());
  }
 /**
  * Add an account to the AccountManager.
  *
  * @param context Our {@link Context}.
  * @param account The {@link Account} we're adding.
  * @param email Whether the user wants to sync email on this account.
  * @param calendar Whether the user wants to sync calendar on this account.
  * @param contacts Whether the user wants to sync contacts on this account.
  * @param callback A callback for when the AccountManager is done.
  * @return The result of {@link AccountManager#addAccount}.
  */
 public static AccountManagerFuture<Bundle> setupAccountManagerAccount(
     final Context context,
     final Account account,
     final boolean email,
     final boolean calendar,
     final boolean contacts,
     final AccountManagerCallback<Bundle> callback) {
   final Bundle options = new Bundle(5);
   final HostAuth hostAuthRecv = HostAuth.restoreHostAuthWithId(context, account.mHostAuthKeyRecv);
   if (hostAuthRecv == null) {
     return null;
   }
   // Set up username/password
   options.putString(EasAuthenticatorService.OPTIONS_USERNAME, account.mEmailAddress);
   options.putString(EasAuthenticatorService.OPTIONS_PASSWORD, hostAuthRecv.mPassword);
   options.putBoolean(EasAuthenticatorService.OPTIONS_CONTACTS_SYNC_ENABLED, contacts);
   options.putBoolean(EasAuthenticatorService.OPTIONS_CALENDAR_SYNC_ENABLED, calendar);
   options.putBoolean(EasAuthenticatorService.OPTIONS_EMAIL_SYNC_ENABLED, email);
   final EmailServiceInfo info = getServiceInfo(context, hostAuthRecv.mProtocol);
   return AccountManager.get(context)
       .addAccount(info.accountType, null, null, options, null, callback, null);
 }
  public static void updateAccountManagerType(
      Context context, android.accounts.Account amAccount, final Map<String, String> protocolMap) {
    final ContentResolver resolver = context.getContentResolver();
    final Cursor c =
        resolver.query(
            Account.CONTENT_URI,
            Account.CONTENT_PROJECTION,
            AccountColumns.EMAIL_ADDRESS + "=?",
            new String[] {amAccount.name},
            null);
    // That's odd, isn't it?
    if (c == null) return;
    try {
      if (c.moveToNext()) {
        // Get the EmailProvider Account/HostAuth
        final Account account = new Account();
        account.restore(c);
        final HostAuth hostAuth = HostAuth.restoreHostAuthWithId(context, account.mHostAuthKeyRecv);
        if (hostAuth == null) {
          return;
        }

        final String newProtocol = protocolMap.get(hostAuth.mProtocol);
        if (newProtocol == null) {
          // This account doesn't need updating.
          return;
        }

        LogUtils.w(Logging.LOG_TAG, "Converting " + amAccount.name + " to " + newProtocol);

        final ContentValues accountValues = new ContentValues();
        int oldFlags = account.mFlags;

        // Mark the provider account incomplete so it can't get reconciled away
        account.mFlags |= Account.FLAGS_INCOMPLETE;
        accountValues.put(AccountColumns.FLAGS, account.mFlags);
        final Uri accountUri = ContentUris.withAppendedId(Account.CONTENT_URI, account.mId);
        resolver.update(accountUri, accountValues, null, null);

        // Change the HostAuth to reference the new protocol; this has to be done before
        // trying to create the AccountManager account (below)
        final ContentValues hostValues = new ContentValues();
        hostValues.put(HostAuth.PROTOCOL, newProtocol);
        resolver.update(
            ContentUris.withAppendedId(HostAuth.CONTENT_URI, hostAuth.mId), hostValues, null, null);
        LogUtils.w(Logging.LOG_TAG, "Updated HostAuths");

        try {
          // Get current settings for the existing AccountManager account
          boolean email = ContentResolver.getSyncAutomatically(amAccount, EmailContent.AUTHORITY);
          if (!email) {
            // Try our old provider name
            email = ContentResolver.getSyncAutomatically(amAccount, "com.android.email.provider");
          }
          final boolean contacts =
              ContentResolver.getSyncAutomatically(amAccount, ContactsContract.AUTHORITY);
          final boolean calendar =
              ContentResolver.getSyncAutomatically(amAccount, CalendarContract.AUTHORITY);
          LogUtils.w(
              Logging.LOG_TAG,
              "Email: " + email + ", Contacts: " + contacts + "," + " Calendar: " + calendar);

          // Get sync keys for calendar/contacts
          final String amName = amAccount.name;
          final String oldType = amAccount.type;
          ContentProviderClient client =
              context
                  .getContentResolver()
                  .acquireContentProviderClient(CalendarContract.CONTENT_URI);
          byte[] calendarSyncKey = null;
          try {
            calendarSyncKey =
                SyncStateContract.Helpers.get(
                    client,
                    asCalendarSyncAdapter(SyncState.CONTENT_URI, amName, oldType),
                    new android.accounts.Account(amName, oldType));
          } catch (RemoteException e) {
            LogUtils.w(Logging.LOG_TAG, "Get calendar key FAILED");
          } finally {
            client.release();
          }
          client =
              context
                  .getContentResolver()
                  .acquireContentProviderClient(ContactsContract.AUTHORITY_URI);
          byte[] contactsSyncKey = null;
          try {
            contactsSyncKey =
                SyncStateContract.Helpers.get(
                    client,
                    ContactsContract.SyncState.CONTENT_URI,
                    new android.accounts.Account(amName, oldType));
          } catch (RemoteException e) {
            LogUtils.w(Logging.LOG_TAG, "Get contacts key FAILED");
          } finally {
            client.release();
          }
          if (calendarSyncKey != null) {
            LogUtils.w(Logging.LOG_TAG, "Got calendar key: " + new String(calendarSyncKey));
          }
          if (contactsSyncKey != null) {
            LogUtils.w(Logging.LOG_TAG, "Got contacts key: " + new String(contactsSyncKey));
          }

          // Set up a new AccountManager account with new type and old settings
          AccountManagerFuture<?> amFuture =
              setupAccountManagerAccount(context, account, email, calendar, contacts, null);
          finishAccountManagerBlocker(amFuture);
          LogUtils.w(Logging.LOG_TAG, "Created new AccountManager account");

          // TODO: Clean up how we determine the type.
          final String accountType = protocolMap.get(hostAuth.mProtocol + "_type");
          // Move calendar and contacts data from the old account to the new one.
          // We must do this before deleting the old account or the data is lost.
          moveCalendarData(context.getContentResolver(), amName, oldType, accountType);
          moveContactsData(context.getContentResolver(), amName, oldType, accountType);

          // Delete the AccountManager account
          amFuture = AccountManager.get(context).removeAccount(amAccount, null, null);
          finishAccountManagerBlocker(amFuture);
          LogUtils.w(Logging.LOG_TAG, "Deleted old AccountManager account");

          // Restore sync keys for contacts/calendar

          if (accountType != null && calendarSyncKey != null && calendarSyncKey.length != 0) {
            client =
                context
                    .getContentResolver()
                    .acquireContentProviderClient(CalendarContract.CONTENT_URI);
            try {
              SyncStateContract.Helpers.set(
                  client,
                  asCalendarSyncAdapter(SyncState.CONTENT_URI, amName, accountType),
                  new android.accounts.Account(amName, accountType),
                  calendarSyncKey);
              LogUtils.w(Logging.LOG_TAG, "Set calendar key...");
            } catch (RemoteException e) {
              LogUtils.w(Logging.LOG_TAG, "Set calendar key FAILED");
            } finally {
              client.release();
            }
          }
          if (accountType != null && contactsSyncKey != null && contactsSyncKey.length != 0) {
            client =
                context
                    .getContentResolver()
                    .acquireContentProviderClient(ContactsContract.AUTHORITY_URI);
            try {
              SyncStateContract.Helpers.set(
                  client,
                  ContactsContract.SyncState.CONTENT_URI,
                  new android.accounts.Account(amName, accountType),
                  contactsSyncKey);
              LogUtils.w(Logging.LOG_TAG, "Set contacts key...");
            } catch (RemoteException e) {
              LogUtils.w(Logging.LOG_TAG, "Set contacts key FAILED");
            }
          }

          // That's all folks!
          LogUtils.w(Logging.LOG_TAG, "Account update completed.");
        } finally {
          // Clear the incomplete flag on the provider account
          accountValues.put(AccountColumns.FLAGS, oldFlags);
          resolver.update(accountUri, accountValues, null, null);
          LogUtils.w(Logging.LOG_TAG, "[Incomplete flag cleared]");
        }
      }
    } finally {
      c.close();
    }
  }