Skip to content
This repository was archived by the owner on Jun 5, 2022. It is now read-only.

Commit 3fea9a5

Browse files
committed
Require authentication before changing password or deleting account
- Require user to authenticate again using device credentials before performing the 'dangerous' account actions (change password, delete account) to slightly increase security. Server-side verification not feasible without password reset option, which would make an email address required.
1 parent d05f761 commit 3fea9a5

File tree

2 files changed

+61
-2
lines changed

2 files changed

+61
-2
lines changed

app/src/main/java/nl/jpelgrm/movienotifier/ui/settings/SettingsAccountOverviewFragment.java

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
package nl.jpelgrm.movienotifier.ui.settings;
22

3+
import android.app.KeyguardManager;
34
import android.content.Context;
45
import android.content.Intent;
56
import android.content.SharedPreferences;
67
import android.os.AsyncTask;
78
import android.os.Build;
89
import android.os.Bundle;
910
import android.provider.Settings;
10-
import android.util.Log;
1111
import android.view.LayoutInflater;
1212
import android.view.View;
1313
import android.view.ViewGroup;
@@ -47,7 +47,12 @@
4747
import retrofit2.Callback;
4848
import retrofit2.Response;
4949

50+
import static android.app.Activity.RESULT_OK;
51+
5052
public class SettingsAccountOverviewFragment extends Fragment {
53+
public static final int INTENT_AUTHENTICATE_PASSWORD = 160;
54+
public static final int INTENT_AUTHENTICATE_DELETE = 161;
55+
5156
@BindView(R.id.accountCoordinator) CoordinatorLayout coordinator;
5257

5358
@BindView(R.id.progress) ProgressBar progress;
@@ -120,7 +125,7 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat
120125

121126
accountSwitch.setOnClickListener(v -> switchToThis());
122127
accountName.setOnClickListener(v -> editDetail(SettingsAccountUpdateFragment.UpdateMode.NAME));
123-
accountPassword.setOnClickListener(v -> editDetail(SettingsAccountUpdateFragment.UpdateMode.PASSWORD));
128+
accountPassword.setOnClickListener(v -> editPassword());
124129
accountLogout.setOnClickListener(v -> logout());
125130
accountDelete.setOnClickListener(v -> delete());
126131
accountSwitch.setVisibility(isCurrentUser ? View.GONE : View.VISIBLE);
@@ -179,6 +184,22 @@ private void editDetail(SettingsAccountUpdateFragment.UpdateMode mode) {
179184
((SettingsActivity) getActivity()).editUserDetail(user.getId(), mode);
180185
}
181186

187+
private void editPassword() {
188+
if(getContext() != null) {
189+
KeyguardManager keyguardManager = (KeyguardManager) getContext().getSystemService(Context.KEYGUARD_SERVICE);
190+
if(keyguardManager != null) {
191+
Intent authenticationIntent = keyguardManager.createConfirmDeviceCredentialIntent(null, null);
192+
if(authenticationIntent != null) {
193+
startActivityForResult(authenticationIntent, INTENT_AUTHENTICATE_PASSWORD);
194+
} else {
195+
editDetail(SettingsAccountUpdateFragment.UpdateMode.PASSWORD);
196+
}
197+
} else {
198+
editDetail(SettingsAccountUpdateFragment.UpdateMode.PASSWORD);
199+
}
200+
}
201+
}
202+
182203
private void togglePushNotifications() {
183204
String token = notificationSettings.getString("token", "");
184205
User toUpdate = new User();
@@ -400,6 +421,22 @@ private void logoutLocal() {
400421
}
401422

402423
private void delete() {
424+
if(getContext() != null) {
425+
KeyguardManager keyguardManager = (KeyguardManager) getContext().getSystemService(Context.KEYGUARD_SERVICE);
426+
if(keyguardManager != null) {
427+
Intent authenticationIntent = keyguardManager.createConfirmDeviceCredentialIntent(null, null);
428+
if(authenticationIntent != null) {
429+
startActivityForResult(authenticationIntent, INTENT_AUTHENTICATE_DELETE);
430+
} else {
431+
doDelete();
432+
}
433+
} else {
434+
doDelete();
435+
}
436+
}
437+
}
438+
439+
private void doDelete() {
403440
error.setVisibility(View.GONE);
404441

405442
new AlertDialog.Builder(getContext()).setMessage(R.string.user_settings_security_delete_confirm).setPositiveButton(R.string.yes, (dialogInterface, i) -> {
@@ -487,6 +524,27 @@ private void setFieldsEnabled(boolean enabled) {
487524
notificationsEmailAddress.setClickable(enabled);
488525
}
489526

527+
@Override
528+
public void onActivityResult(int requestCode, int resultCode, Intent data) {
529+
switch(requestCode) {
530+
case INTENT_AUTHENTICATE_PASSWORD:
531+
case INTENT_AUTHENTICATE_DELETE:
532+
if(resultCode == RESULT_OK) {
533+
if(requestCode == INTENT_AUTHENTICATE_PASSWORD) {
534+
editDetail(SettingsAccountUpdateFragment.UpdateMode.PASSWORD);
535+
} else {
536+
doDelete();
537+
}
538+
} else {
539+
Snackbar.make(coordinator, R.string.user_settings_security_authenticate, Snackbar.LENGTH_LONG).show();
540+
}
541+
break;
542+
default:
543+
super.onActivityResult(requestCode, resultCode, data);
544+
break;
545+
}
546+
}
547+
490548
private interface OnUpdatedListener {
491549
void onResult(boolean success);
492550
}

app/src/main/res/values/strings.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@
155155
<string name="user_settings_security_delete_success">Deleted account</string>
156156
<string name="user_settings_security_logout">Log out from app</string>
157157
<string name="user_settings_security_logout_success">Logged out of account</string>
158+
<string name="user_settings_security_authenticate">We couldn\'t authenticate you, please try again</string>
158159
<string name="user_settings_notifications_title">Notifications</string>
159160
<string name="user_settings_notifications_push">Push notifications on this device</string>
160161
<string name="user_settings_notifications_push_debug">Turn push notifications off everywhere</string>

0 commit comments

Comments
 (0)