From 6b000d75ee54fc16d32f5f97c1d7049496cb4446 Mon Sep 17 00:00:00 2001 From: M66B Date: Fri, 24 Dec 2021 08:37:33 +0100 Subject: [PATCH] Allow switching to password auth --- .../java/eu/faircode/email/DaoIdentity.java | 7 +- .../eu/faircode/email/FragmentAccount.java | 118 ++++++++++++------ .../eu/faircode/email/FragmentIdentity.java | 2 +- .../java/eu/faircode/email/FragmentPop.java | 2 +- app/src/main/res/values/strings.xml | 2 + 5 files changed, 88 insertions(+), 43 deletions(-) diff --git a/app/src/main/java/eu/faircode/email/DaoIdentity.java b/app/src/main/java/eu/faircode/email/DaoIdentity.java index bc3a962cd0..e77e1dc387 100644 --- a/app/src/main/java/eu/faircode/email/DaoIdentity.java +++ b/app/src/main/java/eu/faircode/email/DaoIdentity.java @@ -104,12 +104,13 @@ public interface DaoIdentity { @Query("UPDATE identity SET password = :password WHERE id = :id AND NOT (password IS :password)") int setIdentityPassword(long id, String password); - @Query("UPDATE identity SET password = :password" + + @Query("UPDATE identity" + + " SET password = :password, auth_type = :auth_type" + " WHERE account = :account" + " AND user = :user" + - " AND NOT (password IS :password)" + + " AND NOT (password IS :password AND auth_type = :auth_type)" + " AND host LIKE :domain") - int setIdentityPassword(long account, String user, String password, String domain); + int setIdentityPassword(long account, String user, String password, int auth_type, String domain); @Query("UPDATE identity" + " SET password = :password, auth_type = :new_auth_type" + diff --git a/app/src/main/java/eu/faircode/email/FragmentAccount.java b/app/src/main/java/eu/faircode/email/FragmentAccount.java index c18fbece1d..4f1a76889b 100644 --- a/app/src/main/java/eu/faircode/email/FragmentAccount.java +++ b/app/src/main/java/eu/faircode/email/FragmentAccount.java @@ -29,6 +29,7 @@ import static eu.faircode.email.ServiceAuthenticator.AUTH_TYPE_PASSWORD; import android.app.NotificationManager; import android.content.Context; import android.content.Intent; +import android.content.SharedPreferences; import android.graphics.Color; import android.graphics.Paint; import android.net.Uri; @@ -58,10 +59,12 @@ import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.appcompat.widget.PopupMenu; import androidx.constraintlayout.widget.Group; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentTransaction; import androidx.lifecycle.Lifecycle; +import androidx.preference.PreferenceManager; import com.google.android.material.snackbar.Snackbar; import com.google.android.material.textfield.TextInputLayout; @@ -719,6 +722,10 @@ public class FragmentAccount extends FragmentBase { result.account = db.account().getAccount(id); result.folders = new ArrayList<>(); + if (result.account.auth_type != AUTH_TYPE_PASSWORD && + !Objects.equals(result.account.password, password)) + auth = AUTH_TYPE_PASSWORD; + // Check IMAP server / get folders String protocol = "imap" + (encryption == EmailService.ENCRYPTION_SSL ? "s" : ""); try (EmailService iservice = new EmailService( @@ -983,6 +990,10 @@ public class FragmentAccount extends FragmentBase { DB db = DB.getInstance(context); EntityAccount account = db.account().getAccount(id); + if (account.auth_type != AUTH_TYPE_PASSWORD && + !Objects.equals(account.password, password)) + auth = AUTH_TYPE_PASSWORD; + if (should) { if (account == null) return !TextUtils.isEmpty(host) && !TextUtils.isEmpty(user); @@ -1130,7 +1141,7 @@ public class FragmentAccount extends FragmentBase { if (account != null && !account.password.equals(password)) { String domain = UriHelper.getParentDomain(context, account.host); String match = (Objects.equals(account.host, domain) ? account.host : "%." + domain); - int count = db.identity().setIdentityPassword(account.id, account.user, password, match); + int count = db.identity().setIdentityPassword(account.id, account.user, password, auth, match); Log.i("Updated passwords=" + count + " match=" + match); } @@ -1442,12 +1453,13 @@ public class FragmentAccount extends FragmentBase { @Override protected void onExecuted(Bundle args, final EntityAccount account) { // Get providers - List providers = EmailProvider.loadProfiles(getContext()); + final Context context = getContext(); + List providers = EmailProvider.loadProfiles(context); providers.add(0, new EmailProvider(getString(R.string.title_select))); providers.add(1, new EmailProvider(getString(R.string.title_custom))); ArrayAdapter aaProvider = - new ArrayAdapter<>(getContext(), R.layout.spinner_item1, android.R.id.text1, providers); + new ArrayAdapter<>(context, R.layout.spinner_item1, android.R.id.text1, providers); aaProvider.setDropDownViewResource(R.layout.spinner_item1_dropdown); spProvider.setAdapter(aaProvider); @@ -1505,7 +1517,7 @@ public class FragmentAccount extends FragmentBase { etCategory.setText(account == null ? null : account.category); btnColor.setColor(account == null ? null : account.color); - boolean pro = ActivityBilling.isPro(getContext()); + boolean pro = ActivityBilling.isPro(context); cbNotify.setChecked(account != null && account.notify && pro); cbNotify.setEnabled(pro); @@ -1570,42 +1582,72 @@ public class FragmentAccount extends FragmentBase { tilPassword.setEndIconOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - Fragment fragment; - if (auth == AUTH_TYPE_GMAIL) - fragment = new FragmentGmail(); - else if (auth == AUTH_TYPE_OAUTH) - fragment = new FragmentOAuth(); - else { - Log.e("Unknown auth=" + auth); - return; - } + PopupMenuLifecycle popupMenu = new PopupMenuLifecycle(context, FragmentAccount.this, view); + + popupMenu.getMenu().add(Menu.NONE, R.string.title_account_auth_update, 1, R.string.title_account_auth_update); + popupMenu.getMenu().add(Menu.NONE, R.string.title_account_auth_password, 2, R.string.title_account_auth_password); + + popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem item) { + int id = item.getItemId(); + if (id == R.string.title_account_auth_update) { + onUpdate(); + return true; + } else if (id == R.string.title_account_auth_password) { + onPassword(); + return true; + } else + return false; + } - try { - Bundle aargs = new Bundle(); - if (auth == AUTH_TYPE_OAUTH) { - if (account == null) - throw new IllegalArgumentException("Account missing"); - - EmailProvider provider = - EmailProvider.getProvider(view.getContext(), account.provider); - aargs.putString("id", provider.id); - aargs.putString("name", provider.description); - aargs.putString("privacy", provider.oauth.privacy); - aargs.putBoolean("askAccount", provider.oauth.askAccount); + private void onUpdate() { + Fragment fragment; + if (auth == AUTH_TYPE_GMAIL) + fragment = new FragmentGmail(); + else if (auth == AUTH_TYPE_OAUTH) + fragment = new FragmentOAuth(); + else { + Log.e("Unknown auth=" + auth); + return; + } + + try { + Bundle aargs = new Bundle(); + if (auth == AUTH_TYPE_OAUTH) { + if (account == null) + throw new IllegalArgumentException("Account missing"); + + EmailProvider provider = + EmailProvider.getProvider(view.getContext(), account.provider); + aargs.putString("id", provider.id); + aargs.putString("name", provider.description); + aargs.putString("privacy", provider.oauth.privacy); + aargs.putBoolean("askAccount", provider.oauth.askAccount); + } + aargs.putString("personal", args.getString("personal")); + aargs.putString("address", etUser.getText().toString()); + aargs.putBoolean("update", true); + + fragment.setArguments(aargs); + + getParentFragmentManager().popBackStack(); + FragmentTransaction fragmentTransaction = getParentFragmentManager().beginTransaction(); + fragmentTransaction.replace(R.id.content_frame, fragment).addToBackStack("quick"); + fragmentTransaction.commit(); + } catch (Throwable ex) { + Log.e(ex); + } } - aargs.putString("personal", args.getString("personal")); - aargs.putString("address", etUser.getText().toString()); - aargs.putBoolean("update", true); - - fragment.setArguments(aargs); - - getParentFragmentManager().popBackStack(); - FragmentTransaction fragmentTransaction = getParentFragmentManager().beginTransaction(); - fragmentTransaction.replace(R.id.content_frame, fragment).addToBackStack("quick"); - fragmentTransaction.commit(); - } catch (Throwable ex) { - Log.e(ex); - } + + private void onPassword() { + tilPassword.getEditText().setText(null); + tilPassword.getEditText().setEnabled(true); + tilPassword.requestFocus(); + } + }); + + popupMenu.show(); } }); } diff --git a/app/src/main/java/eu/faircode/email/FragmentIdentity.java b/app/src/main/java/eu/faircode/email/FragmentIdentity.java index 7f5a289ae3..f8a26b7c69 100644 --- a/app/src/main/java/eu/faircode/email/FragmentIdentity.java +++ b/app/src/main/java/eu/faircode/email/FragmentIdentity.java @@ -955,7 +955,7 @@ public class FragmentIdentity extends FragmentBase { if (identity != null && !identity.password.equals(password)) { int count = db.identity().setIdentityPassword( identity.account, - identity.user, password, + identity.user, password, identity.auth_type, identity.host); Log.i("Updated passwords=" + count); } diff --git a/app/src/main/java/eu/faircode/email/FragmentPop.java b/app/src/main/java/eu/faircode/email/FragmentPop.java index 365c88438f..7d5b9cbcea 100644 --- a/app/src/main/java/eu/faircode/email/FragmentPop.java +++ b/app/src/main/java/eu/faircode/email/FragmentPop.java @@ -495,7 +495,7 @@ public class FragmentPop extends FragmentBase { if (account != null && !account.password.equals(password)) { String domain = UriHelper.getParentDomain(context, account.host); String match = (Objects.equals(account.host, domain) ? account.host : "%." + domain); - int count = db.identity().setIdentityPassword(account.id, account.user, password, match); + int count = db.identity().setIdentityPassword(account.id, account.user, password, AUTH_TYPE_PASSWORD, match); Log.i("Updated passwords=" + count + " match=" + match); } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6abd18d7ee..d50384b4ac 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -909,6 +909,8 @@ An identity is required to send emails A drafts folder is required to send emails Sending emails requires a drafts folder to be selected in the account settings + Update authorization + Switch to password authentication Delete this account permanently? Delete this identity permanently? Edit as HTML