Android Open Source - google-authenticator-android Importer






From Project

Back to project page google-authenticator-android.

License

The source code is released under:

Apache License

If you think the Android project google-authenticator-android listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 * Copyright 2011 Google Inc. All Rights Reserved.
 */* w ww. j  ava 2  s  . co m*/
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.android.apps.authenticator.dataimport;

import com.google.android.apps.authenticator.AccountDb;

import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Log;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * Imports the contents of {@link AccountDb} and the key material and settings from a
 * {@link Bundle}.
 *
 * @author klyubin@google.com (Alex Klyubin)
 */
public class Importer {

  private static final String LOG_TAG = Importer.class.getSimpleName();

  // @VisibleForTesting
  static final String KEY_ACCOUNTS = "accountDb";

  // @VisibleForTesting
  static final String KEY_PREFERENCES = "preferences";

  // @VisibleForTesting
  static final String KEY_NAME = "name";

  // @VisibleForTesting
  static final String KEY_ENCODED_SECRET = "encodedSecret";

  // @VisibleForTesting
  static final String KEY_TYPE = "type";

  // @VisibleForTesting
  static final String KEY_COUNTER = "counter";

  /**
   * Imports the contents of the provided {@link Bundle} into the provided {@link AccountDb} and
   * {@link SharedPreferences}. Does not overwrite existing records in the database.
   *
   * @param bundle source bundle.
   * @param accountDb destination {@link AccountDb}.
   * @param preferences destination preferences or {@code null} for none.
   */
  public void importFromBundle(Bundle bundle, AccountDb accountDb, SharedPreferences preferences) {
    Bundle accountDbBundle = bundle.getBundle(KEY_ACCOUNTS);
    if (accountDbBundle != null) {
      importAccountDbFromBundle(accountDbBundle, accountDb);
    }

    if (preferences != null) {
      Bundle preferencesBundle = bundle.getBundle(KEY_PREFERENCES);
      if (preferencesBundle != null) {
        importPreferencesFromBundle(preferencesBundle, preferences);
      }
    }
  }

  private void importAccountDbFromBundle(Bundle bundle, AccountDb accountDb) {
    // Each account is stored in a Bundle whose key is a string representing the ordinal (integer)
    // position of the account in the database.
    List<String> sortedAccountBundleKeys = new ArrayList<String>(bundle.keySet());
    Collections.sort(sortedAccountBundleKeys, new IntegerStringComparator());
    int importedAccountCount = 0;
    for (String accountBundleKey : sortedAccountBundleKeys) {
      Bundle accountBundle = bundle.getBundle(accountBundleKey);
      String name = accountBundle.getString(KEY_NAME);
      if (name == null) {
        Log.w(LOG_TAG, "Skipping account #" + accountBundleKey + ": name missing");
        continue;
      }
      if (accountDb.nameExists(name)) {
        // Don't log account name here and below because it's considered PII
        Log.w(LOG_TAG, "Skipping account #" + accountBundleKey + ": already configured");
        continue;
      }
      String encodedSecret = accountBundle.getString(KEY_ENCODED_SECRET);
      if (encodedSecret == null) {
        Log.w(LOG_TAG, "Skipping account #" + accountBundleKey + ": secret missing");
        continue;
      }
      String typeString = accountBundle.getString(KEY_TYPE);
      AccountDb.OtpType type;
      if ("totp".equals(typeString)) {
        type = AccountDb.OtpType.TOTP;
      } else if ("hotp".equals(typeString)) {
        type = AccountDb.OtpType.HOTP;
      } else {
        Log.w(LOG_TAG, "Skipping account #" + accountBundleKey
            + ": unsupported type: \"" + typeString + "\"");
        continue;
      }

      Integer counter =
          accountBundle.containsKey(KEY_COUNTER) ? accountBundle.getInt(KEY_COUNTER) : null;
      if (counter == null) {
        if (type == AccountDb.OtpType.HOTP) {
          Log.w(LOG_TAG, "Skipping account #" + accountBundleKey + ": counter missing");
          continue;
        } else {
          // TOTP
          counter = AccountDb.DEFAULT_HOTP_COUNTER;
        }
      }

      accountDb.update(name, encodedSecret, name, type, counter);
      importedAccountCount++;
    }

    Log.i(LOG_TAG, "Imported " + importedAccountCount + " accounts");
  }

  private static class IntegerStringComparator implements Comparator<String> {
    @Override
    public int compare(String lhs, String rhs) {
      int lhsValue = Integer.parseInt(lhs);
      int rhsValue = Integer.parseInt(rhs);
      return lhsValue - rhsValue;
    }
  }

  private boolean tryImportPreferencesFromBundle(Bundle bundle, SharedPreferences preferences) {
    SharedPreferences.Editor preferencesEditor = preferences.edit();
    for (String key : bundle.keySet()) {
      Object value = bundle.get(key);
      if (value instanceof Boolean) {
        preferencesEditor.putBoolean(key, (Boolean) value);
      } else if (value instanceof Float) {
        preferencesEditor.putFloat(key, (Float) value);
      } else if (value instanceof Integer) {
        preferencesEditor.putInt(key, (Integer) value);
      } else if (value instanceof Long) {
        preferencesEditor.putLong(key, (Long) value);
      } else if (value instanceof String) {
        preferencesEditor.putString(key, (String) value);
      } else {
        // Ignore: can only be Set<String> at the moment (API Level 11+), which we don't use anyway.
      }
    }
    return preferencesEditor.commit();
  }

  private void importPreferencesFromBundle(Bundle bundle, SharedPreferences preferences) {
    // Retry until the operation succeeds
    while (!tryImportPreferencesFromBundle(bundle, preferences)) {}
  }
}




Java Source Code List

com.google.android.apps.authenticator.AccountDb.java
com.google.android.apps.authenticator.AddOtherAccountActivity.java
com.google.android.apps.authenticator.AuthenticatorActivity.java
com.google.android.apps.authenticator.AuthenticatorApplication.java
com.google.android.apps.authenticator.Base32String.java
com.google.android.apps.authenticator.CheckCodeActivity.java
com.google.android.apps.authenticator.CountdownIndicator.java
com.google.android.apps.authenticator.EnterKeyActivity.java
com.google.android.apps.authenticator.FileUtilities.java
com.google.android.apps.authenticator.HexEncoding.java
com.google.android.apps.authenticator.MarketBuildOptionalFeatures.java
com.google.android.apps.authenticator.OptionalFeatures.java
com.google.android.apps.authenticator.OtpGenerationNotPermittedException.java
com.google.android.apps.authenticator.OtpProvider.java
com.google.android.apps.authenticator.OtpSourceException.java
com.google.android.apps.authenticator.OtpSource.java
com.google.android.apps.authenticator.PasscodeGenerator.java
com.google.android.apps.authenticator.Preconditions.java
com.google.android.apps.authenticator.RunOnThisLooperThreadExecutor.java
com.google.android.apps.authenticator.SettingsAboutActivity.java
com.google.android.apps.authenticator.SettingsActivity.java
com.google.android.apps.authenticator.TotpClock.java
com.google.android.apps.authenticator.TotpCountdownTask.java
com.google.android.apps.authenticator.TotpCounter.java
com.google.android.apps.authenticator.UserRowView.java
com.google.android.apps.authenticator.Utilities.java
com.google.android.apps.authenticator.dataimport.ExportServiceBasedImportController.java
com.google.android.apps.authenticator.dataimport.ImportController.java
com.google.android.apps.authenticator.dataimport.Importer.java
com.google.android.apps.authenticator.howitworks.IntroEnterCodeActivity.java
com.google.android.apps.authenticator.howitworks.IntroEnterPasswordActivity.java
com.google.android.apps.authenticator.howitworks.IntroVerifyDeviceActivity.java
com.google.android.apps.authenticator.testability.DependencyInjector.java
com.google.android.apps.authenticator.testability.HttpClientFactory.java
com.google.android.apps.authenticator.testability.SharedPreferencesRenamingDelegatingContext.java
com.google.android.apps.authenticator.testability.StartActivityListener.java
com.google.android.apps.authenticator.testability.TestableActivity.java
com.google.android.apps.authenticator.testability.TestablePreferenceActivity.java
com.google.android.apps.authenticator.timesync.AboutActivity.java
com.google.android.apps.authenticator.timesync.NetworkTimeProvider.java
com.google.android.apps.authenticator.timesync.SettingsTimeCorrectionActivity.java
com.google.android.apps.authenticator.timesync.SyncNowActivity.java
com.google.android.apps.authenticator.timesync.SyncNowController.java
com.google.android.apps.authenticator.wizard.WizardPageActivity.java