From e0b5d9735615a426c65891e516f31a61a1b7a9cd Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Mon, 11 Sep 2017 01:42:04 +0200 Subject: [PATCH] token-import: add entrypoint for blank token setup flow --- .../securitytoken/SecurityTokenInfo.java | 11 +-- .../keychain/ui/CreateKeyActivity.java | 32 +++---- .../ui/CreateSecurityTokenBlankFragment.java | 86 ------------------- .../ui/token/ManageSecurityTokenContract.java | 4 + .../ui/token/ManageSecurityTokenFragment.java | 17 ++++ .../token/ManageSecurityTokenPresenter.java | 30 +++++-- .../create_security_token_import_fragment.xml | 56 +++++++++--- .../layout/create_yubi_key_blank_fragment.xml | 76 ---------------- OpenKeychain/src/main/res/values/strings.xml | 18 ++-- 9 files changed, 116 insertions(+), 214 deletions(-) delete mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateSecurityTokenBlankFragment.java delete mode 100644 OpenKeychain/src/main/res/layout/create_yubi_key_blank_fragment.xml diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/SecurityTokenInfo.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/SecurityTokenInfo.java index 2f5af414d..5eacd5256 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/SecurityTokenInfo.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/SecurityTokenInfo.java @@ -1,6 +1,8 @@ package org.sufficientlysecure.keychain.securitytoken; +import java.util.Arrays; + import android.os.Parcelable; import android.support.annotation.Nullable; @@ -12,6 +14,8 @@ import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; @AutoValue public abstract class SecurityTokenInfo implements Parcelable { + private static final byte[] EMPTY_ARRAY = new byte[20]; + @Nullable public abstract byte[] getFingerprintSign(); @Nullable @@ -36,7 +40,8 @@ public abstract class SecurityTokenInfo implements Parcelable { } public boolean isEmpty() { - return getFingerprintSign() == null && getFingerprintDecrypt() == null && getFingerprintAuth() == null; + return Arrays.equals(EMPTY_ARRAY, getFingerprintSign()) && Arrays.equals(EMPTY_ARRAY, getFingerprintDecrypt()) && + Arrays.equals(EMPTY_ARRAY, getFingerprintAuth()); } public static SecurityTokenInfo create(byte[] fpSign, byte[] fpDecrypt, byte[] fpAuth, @@ -45,10 +50,6 @@ public abstract class SecurityTokenInfo implements Parcelable { userId, url, verifyRetries, verifyAdminRetries); } - public static SecurityTokenInfo createBlank(byte[] aid) { - return new AutoValue_SecurityTokenInfo(null, null, null, aid, null, null, 0, 0); - } - public static SecurityTokenInfo newInstanceDebugKeyserver() { if (!BuildConfig.DEBUG) { throw new UnsupportedOperationException("This operation is only available in debug builds!"); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java index 503de40d6..35b5816b0 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java @@ -110,16 +110,9 @@ public class CreateKeyActivity extends BaseSecurityTokenActivity { if (intent.hasExtra(EXTRA_SECURITY_TOKEN_INFO)) { SecurityTokenInfo tokenInfo = intent.getParcelableExtra(EXTRA_SECURITY_TOKEN_INFO); - if (!tokenInfo.isEmpty()) { - Fragment frag = ManageSecurityTokenFragment.newInstance(tokenInfo); - loadFragment(frag, FragAction.START); - - setTitle(R.string.title_import_keys); - } else { - Fragment frag = CreateSecurityTokenBlankFragment.newInstance(); - loadFragment(frag, FragAction.START); - setTitle(R.string.title_manage_my_keys); - } + Fragment frag = ManageSecurityTokenFragment.newInstance(tokenInfo); + loadFragment(frag, FragAction.START); + setTitle(R.string.title_manage_my_keys); // done return; @@ -164,15 +157,10 @@ public class CreateKeyActivity extends BaseSecurityTokenActivity { CreateSecurityTokenWaitFragment.sDisableFragmentAnimations = false; } - if (!tokenInfo.isEmpty()) { - Fragment frag = ManageSecurityTokenFragment.newInstance(tokenInfo); - if (mCurrentFragment instanceof ManageSecurityTokenFragment) { - loadFragment(frag, FragAction.REPLACE); - } else { - loadFragment(frag, FragAction.TO_RIGHT); - } + Fragment frag = ManageSecurityTokenFragment.newInstance(tokenInfo); + if (mCurrentFragment instanceof ManageSecurityTokenFragment) { + loadFragment(frag, FragAction.REPLACE); } else { - Fragment frag = CreateSecurityTokenBlankFragment.newInstance(); loadFragment(frag, FragAction.TO_RIGHT); } } @@ -196,6 +184,14 @@ public class CreateKeyActivity extends BaseSecurityTokenActivity { setContentView(R.layout.create_key_activity); } + public void startCreateKeyForSecurityToken(SecurityTokenInfo tokenInfo) { + mCreateSecurityToken = true; + this.tokenInfo = tokenInfo; + + CreateKeyNameFragment frag = CreateKeyNameFragment.newInstance(); + loadFragment(frag, FragAction.TO_RIGHT); + } + public enum FragAction { START, TO_RIGHT, diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateSecurityTokenBlankFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateSecurityTokenBlankFragment.java deleted file mode 100644 index 3100ccddb..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateSecurityTokenBlankFragment.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (C) 2014 Dominik Schürmann - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.sufficientlysecure.keychain.ui; - - -import android.app.Activity; -import android.content.Context; -import android.os.Bundle; -import android.support.v4.app.Fragment; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.ui.CreateKeyActivity.FragAction; - -public class CreateSecurityTokenBlankFragment extends Fragment { - - CreateKeyActivity mCreateKeyActivity; - View mBackButton; - View mNextButton; - - /** - * Creates new instance of this fragment - */ - public static CreateSecurityTokenBlankFragment newInstance() { - return new CreateSecurityTokenBlankFragment(); - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View view = inflater.inflate(R.layout.create_yubi_key_blank_fragment, container, false); - - mBackButton = view.findViewById(R.id.create_key_back_button); - mNextButton = view.findViewById(R.id.create_key_next_button); - - mBackButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (getFragmentManager().getBackStackEntryCount() == 0) { - getActivity().setResult(Activity.RESULT_CANCELED); - getActivity().finish(); - } else { - mCreateKeyActivity.loadFragment(null, FragAction.TO_LEFT); - } - } - }); - mNextButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - nextClicked(); - } - }); - - return view; - } - - @Override - public void onAttach(Context context) { - super.onAttach(context); - mCreateKeyActivity = (CreateKeyActivity) getActivity(); - } - - private void nextClicked() { - mCreateKeyActivity.mCreateSecurityToken = true; - - CreateKeyNameFragment frag = CreateKeyNameFragment.newInstance(); - mCreateKeyActivity.loadFragment(frag, FragAction.TO_RIGHT); - } - -} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/token/ManageSecurityTokenContract.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/token/ManageSecurityTokenContract.java index 67084c493..a3c52f3f6 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/token/ManageSecurityTokenContract.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/token/ManageSecurityTokenContract.java @@ -56,6 +56,8 @@ class ManageSecurityTokenContract { void onSecurityTokenResetSuccess(SecurityTokenInfo tokenInfo); void onSecurityTokenResetCanceled(SecurityTokenInfo tokenInfo); + void onClickSetupToken(); + void onClickUnlockToken(); void onMenuClickChangePin(); void onInputAdminPin(String adminPin, String newPin); @@ -73,6 +75,7 @@ class ManageSecurityTokenContract { void showActionViewKey(); void showActionRetryOrFromFile(); void showActionLocked(int unlockAttempts); + void showActionEmptyToken(); void hideAction(); void operationImportKey(byte[] importKeyData); @@ -85,6 +88,7 @@ class ManageSecurityTokenContract { void showFileSelectDialog(); void showConfirmResetDialog(); void showAdminPinDialog(); + void startCreateKeyForToken(SecurityTokenInfo tokenInfo); void showDisplayLogActivity(OperationResult result); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/token/ManageSecurityTokenFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/token/ManageSecurityTokenFragment.java index 28d8d34de..9a9fbd62d 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/token/ManageSecurityTokenFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/token/ManageSecurityTokenFragment.java @@ -130,6 +130,7 @@ public class ManageSecurityTokenFragment extends Fragment implements ManageSecur view.findViewById(R.id.button_unlock).setOnClickListener(this); view.findViewById(R.id.button_unlock_impossible).setOnClickListener(this); view.findViewById(R.id.button_load_file).setOnClickListener(this); + view.findViewById(R.id.button_setup).setOnClickListener(this); setHasOptionsMenu(true); @@ -253,6 +254,11 @@ public class ManageSecurityTokenFragment extends Fragment implements ManageSecur } } + @Override + public void showActionEmptyToken() { + actionAnimator.setDisplayedChildId(R.id.token_layout_empty); + } + @Override public void hideAction() { actionAnimator.setDisplayedChild(0); @@ -325,6 +331,12 @@ public class ManageSecurityTokenFragment extends Fragment implements ManageSecur adminPinDialog.show(); } + @Override + public void startCreateKeyForToken(SecurityTokenInfo tokenInfo) { + CreateKeyActivity activity = (CreateKeyActivity) getActivity(); + activity.startCreateKeyForSecurityToken(tokenInfo); + } + @Override public void showErrorCannotUnlock() { Notify.create(getActivity(), R.string.token_error_locked_indefinitely, Style.ERROR).show(); @@ -430,6 +442,11 @@ public class ManageSecurityTokenFragment extends Fragment implements ManageSecur presenter.onClickUnlockTokenImpossible(); break; } + + case R.id.button_setup: { + presenter.onClickSetupToken(); + break; + } } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/token/ManageSecurityTokenPresenter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/token/ManageSecurityTokenPresenter.java index 1af2405fd..2a31a3516 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/token/ManageSecurityTokenPresenter.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/token/ManageSecurityTokenPresenter.java @@ -107,7 +107,8 @@ class ManageSecurityTokenPresenter implements ManageSecurityTokenMvpPresenter { private void continueSearch() { if (!checkedKeyStatus) { boolean keyIsLocked = tokenInfo.getVerifyRetries() == 0; - if (keyIsLocked) { + boolean keyIsEmpty = tokenInfo.isEmpty(); + if (keyIsLocked || keyIsEmpty) { // the "checking key status" is fake: we only do it if we already know the key is locked view.statusLineAdd(StatusLine.CHECK_KEY); delayPerformKeyCheck(); @@ -148,19 +149,27 @@ class ManageSecurityTokenPresenter implements ManageSecurityTokenMvpPresenter { } private void performKeyCheck() { - boolean isLocked = tokenInfo.getVerifyRetries() == 0; - if (!isLocked) { + boolean keyIsEmpty = tokenInfo.isEmpty(); + if (keyIsEmpty) { view.statusLineOk(); - checkedKeyStatus = true; - continueSearch(); + view.showActionEmptyToken(); return; } - view.statusLineError(); + boolean keyIsLocked = tokenInfo.getVerifyRetries() == 0; + if (keyIsLocked) { + view.statusLineError(); - int unlockAttemptsLeft = tokenInfo.getVerifyAdminRetries(); - view.showActionLocked(unlockAttemptsLeft); + int unlockAttemptsLeft = tokenInfo.getVerifyAdminRetries(); + view.showActionLocked(unlockAttemptsLeft); + return; + } + + view.statusLineOk(); + + checkedKeyStatus = true; + continueSearch(); } @Override @@ -346,6 +355,11 @@ class ManageSecurityTokenPresenter implements ManageSecurityTokenMvpPresenter { } } + @Override + public void onClickSetupToken() { + view.startCreateKeyForToken(tokenInfo); + } + @Override public void onSecurityTokenChangePinSuccess(SecurityTokenInfo tokenInfo) { this.tokenInfo = tokenInfo; diff --git a/OpenKeychain/src/main/res/layout/create_security_token_import_fragment.xml b/OpenKeychain/src/main/res/layout/create_security_token_import_fragment.xml index 6554b8e89..9a35ad763 100644 --- a/OpenKeychain/src/main/res/layout/create_security_token_import_fragment.xml +++ b/OpenKeychain/src/main/res/layout/create_security_token_import_fragment.xml @@ -50,7 +50,7 @@ android:inAnimation="@anim/fade_in_delayed" android:outAnimation="@anim/fade_out" android:clipChildren="false" - custom:initialView="05"> + custom:initialView="06"> @@ -79,7 +79,7 @@ android:drawableStart="@drawable/ic_repeat_grey_24dp" android:drawablePadding="12dp" android:textColor="@color/card_view_button" - android:text="@string/token_status_retry" + android:text="@string/token_action_retry" style="?borderlessButtonStyle" /> @@ -91,7 +91,7 @@ android:drawableStart="@drawable/ic_folder_grey_24dp" android:drawablePadding="12dp" android:textColor="@color/card_view_button" - android:text="@string/token_status_load_from_file" + android:text="@string/token_action_load_from_file" style="?borderlessButtonStyle" /> @@ -103,7 +103,7 @@ android:drawableStart="@drawable/ic_bomb_24dp" android:drawablePadding="12dp" android:textColor="@color/android_red_dark" - android:text="@string/token_status_reset" + android:text="@string/token_action_reset" style="?borderlessButtonStyle" /> @@ -120,7 +120,7 @@ android:layout_height="wrap_content" android:minHeight="?listPreferredItemHeight" android:gravity="center_vertical" - android:text="@string/token_status_key_found" + android:text="@string/token_result_key_found" style="?android:textAppearanceLarge" /> @@ -132,7 +132,7 @@ android:drawableStart="@drawable/ic_key_plus_grey600_24dp" android:drawablePadding="12dp" android:textColor="@color/card_view_button" - android:text="@string/token_status_import" + android:text="@string/token_action_import" style="?borderlessButtonStyle" /> @@ -144,7 +144,7 @@ android:drawableStart="@drawable/ic_bomb_24dp" android:drawablePadding="12dp" android:textColor="@color/android_red_dark" - android:text="@string/token_status_reset" + android:text="@string/token_action_reset" style="?borderlessButtonStyle" /> @@ -161,7 +161,7 @@ android:layout_height="wrap_content" android:minHeight="?listPreferredItemHeight" android:gravity="center_vertical" - android:text="@string/token_status_token_ok" + android:text="@string/token_result_token_ok" style="?android:textAppearanceLarge" /> @@ -173,7 +173,7 @@ android:drawableStart="@drawable/ic_vpn_key_grey_24dp" android:drawablePadding="12dp" android:textColor="@color/card_view_button" - android:text="@string/token_status_view_key" + android:text="@string/token_action_view_key" style="?borderlessButtonStyle" /> @@ -185,7 +185,7 @@ android:drawableStart="@drawable/ic_bomb_24dp" android:drawablePadding="12dp" android:textColor="@color/android_red_dark" - android:text="@string/token_status_reset" + android:text="@string/token_action_reset" style="?borderlessButtonStyle" /> @@ -259,7 +259,7 @@ android:drawableStart="@drawable/ic_bomb_24dp" android:drawablePadding="12dp" android:textColor="@color/android_red_dark" - android:text="@string/token_status_reset" + android:text="@string/token_action_reset" style="?borderlessButtonStyle" /> @@ -334,7 +334,37 @@ android:drawableStart="@drawable/ic_bomb_24dp" android:drawablePadding="12dp" android:textColor="@color/android_red_dark" - android:text="@string/token_status_reset" + android:text="@string/token_action_reset" + style="?borderlessButtonStyle" + /> + + + + + + + + +