From f1b499f101a3abd0fc5e6652acd097f0735320e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Sch=C3=A4ttgen?= Date: Sat, 5 Aug 2017 15:15:31 +0200 Subject: [PATCH] Started working on authentication methods --- app/build.gradle | 1 + app/src/main/AndroidManifest.xml | 8 +- .../impy/aegis/CustomAuthenticatedSlide.java | 55 ++++++ .../impy/aegis/CustomAuthenticationSlide.java | 89 +++++++++ .../java/me/impy/aegis/IntroActivity.java | 3 + .../me/impy/aegis/SetPasswordActivity.java | 13 ++ .../SetFingerprintAuthenticationDialog.java | 172 ++++++++++++++++++ .../main/res/layout/activity_set_password.xml | 61 +++++++ .../layout/fragment_authenticated_slide.xml | 75 ++++++++ .../layout/fragment_authentication_slide.xml | 99 ++++++++++ app/src/main/res/values/strings.xml | 18 +- app/src/main/res/values/styles.xml | 5 +- 12 files changed, 593 insertions(+), 6 deletions(-) create mode 100644 app/src/main/java/me/impy/aegis/CustomAuthenticatedSlide.java create mode 100644 app/src/main/java/me/impy/aegis/CustomAuthenticationSlide.java create mode 100644 app/src/main/java/me/impy/aegis/SetPasswordActivity.java create mode 100644 app/src/main/java/me/impy/aegis/finger/SetFingerprintAuthenticationDialog.java create mode 100644 app/src/main/res/layout/activity_set_password.xml create mode 100644 app/src/main/res/layout/fragment_authenticated_slide.xml create mode 100644 app/src/main/res/layout/fragment_authentication_slide.xml diff --git a/app/build.gradle b/app/build.gradle index 69275baa..1288d2b5 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -39,5 +39,6 @@ dependencies { compile 'com.android.support:support-v4:25.0.0' compile 'com.android.support:recyclerview-v7:25.0.0' compile 'com.yarolegovich:lovely-dialog:1.0.4' + compile 'com.mattprecious.swirl:swirl:1.0.0' testCompile 'junit:junit:4.12' } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a104e2c8..bca640b5 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -33,9 +33,9 @@ android:label="@string/title_activity_intro" android:theme="@style/Theme.Intro"> - + + + - - \ No newline at end of file + diff --git a/app/src/main/java/me/impy/aegis/CustomAuthenticatedSlide.java b/app/src/main/java/me/impy/aegis/CustomAuthenticatedSlide.java new file mode 100644 index 00000000..dce7f57d --- /dev/null +++ b/app/src/main/java/me/impy/aegis/CustomAuthenticatedSlide.java @@ -0,0 +1,55 @@ +package me.impy.aegis; + +import android.hardware.fingerprint.FingerprintManager; +import android.os.Build; +import android.support.annotation.RequiresApi; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.CheckBox; +import android.widget.RadioButton; + +import com.mattprecious.swirl.SwirlView; + +import javax.crypto.Cipher; + +import agency.tango.materialintroscreen.SlideFragment; +import me.impy.aegis.finger.FingerprintAuthenticationDialogFragment; + +public class CustomAuthenticatedSlide extends SlideFragment { + private CheckBox checkBox; + private RadioButton passwordRadioButton; + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + final View view = inflater.inflate(R.layout.fragment_authenticated_slide, container, false); + return view; + } + + @Override + public int backgroundColor() { + return R.color.colorHeaderSuccess; + } + + @Override + public int buttonsColor() { + return R.color.colorAccent; + } + + @Override + public boolean canMoveFurther() { + return true; //checkBox.isChecked(); + } + + public void onAuthenticated(FingerprintAuthenticationDialogFragment.Action action, FingerprintManager.CryptoObject obj) { + + } + + @Override + public String cantMoveFurtherErrorMessage() { + return "Ja bijna vriend"; + //return getString(R.string.error_message); + } +} diff --git a/app/src/main/java/me/impy/aegis/CustomAuthenticationSlide.java b/app/src/main/java/me/impy/aegis/CustomAuthenticationSlide.java new file mode 100644 index 00000000..c3f1d3b8 --- /dev/null +++ b/app/src/main/java/me/impy/aegis/CustomAuthenticationSlide.java @@ -0,0 +1,89 @@ +package me.impy.aegis; + +import android.app.Activity; +import android.content.Intent; +import android.hardware.fingerprint.FingerprintManager; +import android.os.Build; +import android.os.Bundle; +import android.support.annotation.RequiresApi; +import android.app.DialogFragment; +import android.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.CheckBox; +import android.widget.RadioButton; +import android.widget.RadioGroup; + +import com.mattprecious.swirl.SwirlView; + +import agency.tango.materialintroscreen.SlideFragment; +import me.impy.aegis.finger.FingerprintAuthenticationDialogFragment; +import me.impy.aegis.finger.SetFingerprintAuthenticationDialog; + +public class CustomAuthenticationSlide extends SlideFragment implements SetFingerprintAuthenticationDialog.InterfaceCommunicator{ + private CheckBox checkBox; + private RadioButton fingerprintRadioButton; + private RadioGroup authenticationMethodRadioGroup; + + public static final int DIALOG_FRAGMENT = 1; + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + final View view = inflater.inflate(R.layout.fragment_authentication_slide, container, false); + final CustomAuthenticationSlide caller = this; + + fingerprintRadioButton = (RadioButton) view.findViewById(R.id.rb_fingerprint); + fingerprintRadioButton.setOnClickListener(new View.OnClickListener() { + @RequiresApi(api = Build.VERSION_CODES.M) + @Override + public void onClick(View view) { + SetFingerprintAuthenticationDialog fragment = new SetFingerprintAuthenticationDialog(); + //fragment.setCryptoObject(new FingerprintManager.CryptoObject(cipher)); + fragment.setStage(SetFingerprintAuthenticationDialog.Stage.FINGERPRINT); + fragment.setCaller(caller); + //fragment.setAction(action); + fragment.show(getActivity().getFragmentManager(), "dialog"); + } + }); + + authenticationMethodRadioGroup = (RadioGroup) view.findViewById(R.id.rg_authenticationMethod); + return view; + } + + @Override + public int backgroundColor() { + return R.color.colorHeaderSuccess; + } + + @Override + public int buttonsColor() { + return R.color.colorAccent; + } + + @Override + public boolean canMoveFurther() { + return authenticationMethodRadioGroup.getCheckedRadioButtonId() != -1; + } + + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + + } + + + @Override + public String cantMoveFurtherErrorMessage() { + return "Please select an authentication method"; + //return getString(R.string.error_message); + } + + @Override + public void sendRequestCode(int code) { + if (code == 1) { + + } else if (code == 0){ + authenticationMethodRadioGroup.clearCheck(); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/me/impy/aegis/IntroActivity.java b/app/src/main/java/me/impy/aegis/IntroActivity.java index 075a0d40..a0d3e6be 100644 --- a/app/src/main/java/me/impy/aegis/IntroActivity.java +++ b/app/src/main/java/me/impy/aegis/IntroActivity.java @@ -39,6 +39,9 @@ public class IntroActivity extends MaterialIntroActivity { } }, "Permission granted")); + + addSlide(new CustomAuthenticationSlide()); + addSlide(new CustomAuthenticatedSlide()); } @Override diff --git a/app/src/main/java/me/impy/aegis/SetPasswordActivity.java b/app/src/main/java/me/impy/aegis/SetPasswordActivity.java new file mode 100644 index 00000000..879a2dea --- /dev/null +++ b/app/src/main/java/me/impy/aegis/SetPasswordActivity.java @@ -0,0 +1,13 @@ +package me.impy.aegis; + +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; + +public class SetPasswordActivity extends AppCompatActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_set_password); + } +} diff --git a/app/src/main/java/me/impy/aegis/finger/SetFingerprintAuthenticationDialog.java b/app/src/main/java/me/impy/aegis/finger/SetFingerprintAuthenticationDialog.java new file mode 100644 index 00000000..9e44900e --- /dev/null +++ b/app/src/main/java/me/impy/aegis/finger/SetFingerprintAuthenticationDialog.java @@ -0,0 +1,172 @@ +package me.impy.aegis.finger; + +/* + * Copyright (C) 2015 The Android Open Source Project + * + * 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 + */ + +import android.app.Activity; +import android.app.DialogFragment; +import android.content.Context; +import android.content.DialogInterface; +import android.content.SharedPreferences; +import android.hardware.fingerprint.FingerprintManager; +import android.os.Build; +import android.os.Bundle; +import android.preference.PreferenceManager; +import android.support.annotation.RequiresApi; +import android.view.KeyEvent; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputMethodManager; +import android.widget.Button; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.TextView; + +import me.impy.aegis.CustomAuthenticationSlide; +import me.impy.aegis.IntroActivity; +import me.impy.aegis.MainActivity; +import me.impy.aegis.R; + +/** + * A dialog which uses fingerprint APIs to authenticate the user, and falls back to password + * authentication if fingerprint is not available. + */ +@RequiresApi(api = Build.VERSION_CODES.M) +public class SetFingerprintAuthenticationDialog extends DialogFragment implements FingerprintUiHelper.Callback { + + private Button mCancelButton; + private Button mSecondDialogButton; + private View mFingerprintContent; + private View mBackupContent; + private EditText mPassword; + private CheckBox mUseFingerprintFutureCheckBox; + private TextView mPasswordDescriptionTextView; + private TextView mNewFingerprintEnrolledTextView; + + private Stage mStage = Stage.FINGERPRINT; + private Action mAction; + + private FingerprintManager.CryptoObject mCryptoObject; + private FingerprintUiHelper mFingerprintUiHelper; + private IntroActivity mIntroActivity; + public InterfaceCommunicator interfaceCommunicator; + + private InputMethodManager mInputMethodManager; + private SharedPreferences mSharedPreferences; + private CustomAuthenticationSlide customAuthenticationSlide; + + public void setCaller(CustomAuthenticationSlide customAuthenticationSlide) + { + this.customAuthenticationSlide = customAuthenticationSlide; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setRetainInstance(true); + setStyle(DialogFragment.STYLE_NORMAL, android.R.style.Theme_Material_Light_Dialog); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + getDialog().setTitle(getString(R.string.sign_in)); + View v = inflater.inflate(R.layout.fingerprint_dialog_container, container, false); + mCancelButton = (Button) v.findViewById(R.id.cancel_button); + mCancelButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + customAuthenticationSlide.sendRequestCode(0); + dismiss(); + } + }); + + mFingerprintContent = v.findViewById(R.id.fingerprint_container); + mFingerprintUiHelper = new FingerprintUiHelper( + mIntroActivity.getSystemService(FingerprintManager.class), + (ImageView) v.findViewById(R.id.fingerprint_icon), + (TextView) v.findViewById(R.id.fingerprint_status), this); + + return v; + } + + @Override + public void onResume() { + super.onResume(); + if (mStage == Stage.FINGERPRINT) { + mFingerprintUiHelper.startListening(mCryptoObject); + } + } + + public void setStage(Stage stage) { + mStage = stage; + } + + public void setAction(Action action) { mAction = action; } + + @Override + public void onPause() { + super.onPause(); + mFingerprintUiHelper.stopListening(); + } + + @Override + public void onDismiss(DialogInterface dialog) { + super.onDismiss(dialog); + customAuthenticationSlide.sendRequestCode(0); + } + + @Override + public void onAttach(Activity activity) { + super.onAttach(activity); + mIntroActivity = (IntroActivity) activity; + + } + + @Override + public void onAuthenticated() { + // Callback from FingerprintUiHelper. Let the activity know that authentication was + // successful. + customAuthenticationSlide.sendRequestCode(1); + dismiss(); + } + + @Override + public void onError() { + customAuthenticationSlide.sendRequestCode(0); + } + + public interface InterfaceCommunicator { + void sendRequestCode(int code); + } + + /** + * Enumeration to indicate which authentication method the user is trying to authenticate with. + */ + public enum Stage { + FINGERPRINT, + NEW_FINGERPRINT_ENROLLED, + PASSWORD + } + + public enum Action { + LOAD, + SAVE + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/activity_set_password.xml b/app/src/main/res/layout/activity_set_password.xml new file mode 100644 index 00000000..11394179 --- /dev/null +++ b/app/src/main/res/layout/activity_set_password.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + +