Allow updating OAuth accounts

This commit is contained in:
M66B 2020-11-25 19:05:32 +01:00
parent 687795e3d4
commit ad439fd392
6 changed files with 146 additions and 172 deletions

View File

@ -92,6 +92,11 @@ public interface DaoAccount {
@Query("SELECT * FROM account WHERE name = :name")
EntityAccount getAccount(String name);
@Query("SELECT * FROM account" +
" WHERE user = :user" +
" AND auth_type = :auth_type")
EntityAccount getAccount(String user, int auth_type);
@Query("SELECT * FROM account WHERE `primary`")
EntityAccount getPrimaryAccount();

View File

@ -104,6 +104,12 @@ public interface DaoIdentity {
" AND host LIKE :domain")
int setIdentityPassword(long account, String user, String password, String domain);
@Query("UPDATE identity SET password = :password" +
" WHERE account = :account" +
" AND user = :user" +
" AND auth_type = :auth_type")
int setIdentityPassword(long account, String user, String password, int auth_type);
@Query("UPDATE identity SET last_connected = :last_connected WHERE id = :id")
int setIdentityConnected(long id, long last_connected);

View File

@ -19,7 +19,6 @@ package eu.faircode.email;
Copyright 2018-2020 by Marcel Bokhorst (M66B)
*/
import android.accounts.Account;
import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent;
@ -27,7 +26,6 @@ import android.graphics.Color;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
@ -45,7 +43,6 @@ import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.RadioGroup;
import android.widget.ScrollView;
import android.widget.Spinner;
@ -64,7 +61,6 @@ import com.sun.mail.imap.protocol.IMAPProtocol;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;
@ -72,12 +68,9 @@ import java.util.Objects;
import javax.mail.Folder;
import static android.accounts.AccountManager.newChooseAccountIntent;
import static android.app.Activity.RESULT_OK;
import static com.google.android.material.textfield.TextInputLayout.END_ICON_NONE;
import static com.google.android.material.textfield.TextInputLayout.END_ICON_PASSWORD_TOGGLE;
import static eu.faircode.email.GmailState.TYPE_GOOGLE;
import static eu.faircode.email.ServiceAuthenticator.AUTH_TYPE_GMAIL;
import static eu.faircode.email.ServiceAuthenticator.AUTH_TYPE_OAUTH;
import static eu.faircode.email.ServiceAuthenticator.AUTH_TYPE_PASSWORD;
@ -96,7 +89,6 @@ public class FragmentAccount extends FragmentBase {
private RadioGroup rgEncryption;
private CheckBox cbInsecure;
private EditText etPort;
private ImageButton ibAccount;
private EditText etUser;
private TextInputLayout tilPassword;
private TextView tvCharacters;
@ -166,8 +158,7 @@ public class FragmentAccount extends FragmentBase {
private static final int REQUEST_COLOR = 1;
private static final int REQUEST_SAVE = 2;
private static final int REQUEST_ACCOUNT = 3;
private static final int REQUEST_DELETE = 4;
private static final int REQUEST_DELETE = 3;
@Override
public void onCreate(Bundle savedInstanceState) {
@ -202,7 +193,6 @@ public class FragmentAccount extends FragmentBase {
etPort = view.findViewById(R.id.etPort);
rgEncryption = view.findViewById(R.id.rgEncryption);
cbInsecure = view.findViewById(R.id.cbInsecure);
ibAccount = view.findViewById(R.id.ibAccount);
etUser = view.findViewById(R.id.etUser);
tilPassword = view.findViewById(R.id.tilPassword);
tvCharacters = view.findViewById(R.id.tvCharacters);
@ -326,24 +316,6 @@ public class FragmentAccount extends FragmentBase {
}
});
ibAccount.setEnabled(id >= 0 && auth == AUTH_TYPE_GMAIL);
ibAccount.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Account account = new Account(etUser.getText().toString(), TYPE_GOOGLE);
Intent intent = newChooseAccountIntent(
account,
new ArrayList(Arrays.asList(account)),
new String[]{TYPE_GOOGLE},
false,
null,
null,
null,
null);
startActivityForResult(intent, REQUEST_ACCOUNT);
}
});
tilPassword.getEditText().addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
@ -1523,7 +1495,6 @@ public class FragmentAccount extends FragmentBase {
tilPassword.setEnabled(false);
btnCertificate.setEnabled(false);
}
ibAccount.setEnabled(auth == AUTH_TYPE_GMAIL);
cbOnDemand.setEnabled(cbSynchronize.isChecked());
cbPrimary.setEnabled(cbSynchronize.isChecked());
@ -1640,10 +1611,6 @@ public class FragmentAccount extends FragmentBase {
} else if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED))
getParentFragmentManager().popBackStack();
break;
case REQUEST_ACCOUNT:
if (resultCode == RESULT_OK)
onAccount();
break;
case REQUEST_DELETE:
if (resultCode == RESULT_OK)
onDelete();
@ -1654,13 +1621,6 @@ public class FragmentAccount extends FragmentBase {
}
}
private void onAccount() {
Intent sync = new Intent(Settings.ACTION_SYNC_SETTINGS)
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (sync.resolveActivity(getContext().getPackageManager()) != null)
startActivity(sync);
}
private void onDelete() {
Bundle args = new Bundle();
args.putLong("id", id);

View File

@ -396,73 +396,81 @@ public class FragmentGmail extends FragmentBase {
try {
db.beginTransaction();
EntityAccount primary = db.account().getPrimaryAccount();
EntityAccount update = db.account().getAccount(user, AUTH_TYPE_GMAIL);
if (update == null) {
EntityAccount primary = db.account().getPrimaryAccount();
// Create account
EntityAccount account = new EntityAccount();
// Create account
EntityAccount account = new EntityAccount();
account.host = provider.imap.host;
account.encryption = aencryption;
account.port = provider.imap.port;
account.auth_type = AUTH_TYPE_GMAIL;
account.user = user;
account.password = password;
account.host = provider.imap.host;
account.encryption = aencryption;
account.port = provider.imap.port;
account.auth_type = AUTH_TYPE_GMAIL;
account.user = user;
account.password = password;
account.name = provider.name + "/" + username;
account.name = provider.name + "/" + username;
account.synchronize = true;
account.primary = (primary == null);
account.synchronize = true;
account.primary = (primary == null);
account.created = new Date().getTime();
account.last_connected = account.created;
account.created = new Date().getTime();
account.last_connected = account.created;
account.id = db.account().insertAccount(account);
args.putLong("account", account.id);
EntityLog.log(context, "Gmail account=" + account.name);
account.id = db.account().insertAccount(account);
args.putLong("account", account.id);
EntityLog.log(context, "Gmail account=" + account.name);
// Create folders
for (EntityFolder folder : folders) {
EntityFolder existing = db.folder().getFolderByName(account.id, folder.name);
if (existing == null) {
folder.account = account.id;
folder.id = db.folder().insertFolder(folder);
EntityLog.log(context, "Gmail folder=" + folder.name + " type=" + folder.type);
if (folder.synchronize)
EntityOperation.sync(context, folder.id, false);
// Create folders
for (EntityFolder folder : folders) {
EntityFolder existing = db.folder().getFolderByName(account.id, folder.name);
if (existing == null) {
folder.account = account.id;
folder.id = db.folder().insertFolder(folder);
EntityLog.log(context, "Gmail folder=" + folder.name + " type=" + folder.type);
if (folder.synchronize)
EntityOperation.sync(context, folder.id, false);
}
}
// Set swipe left/right folder
for (EntityFolder folder : folders)
if (EntityFolder.TRASH.equals(folder.type))
account.swipe_left = folder.id;
else if (EntityFolder.ARCHIVE.equals(folder.type))
account.swipe_right = folder.id;
db.account().updateAccount(account);
if (TextUtils.isEmpty(name))
name = user.split("@")[0];
// Create identity
EntityIdentity identity = new EntityIdentity();
identity.name = name;
identity.email = user;
identity.account = account.id;
identity.host = provider.smtp.host;
identity.encryption = iencryption;
identity.port = provider.smtp.port;
identity.auth_type = AUTH_TYPE_GMAIL;
identity.user = user;
identity.password = password;
identity.synchronize = true;
identity.primary = true;
identity.max_size = max_size;
identity.id = db.identity().insertIdentity(identity);
EntityLog.log(context, "Gmail identity=" + identity.name + " email=" + identity.email);
} else {
args.putLong("account", update.id);
EntityLog.log(context, "Gmail update account=" + update.name);
db.account().setAccountPassword(update.id, password);
db.identity().setIdentityPassword(update.id, update.user, password, update.auth_type);
}
// Set swipe left/right folder
for (EntityFolder folder : folders)
if (EntityFolder.TRASH.equals(folder.type))
account.swipe_left = folder.id;
else if (EntityFolder.ARCHIVE.equals(folder.type))
account.swipe_right = folder.id;
db.account().updateAccount(account);
if (TextUtils.isEmpty(name))
name = user.split("@")[0];
// Create identity
EntityIdentity identity = new EntityIdentity();
identity.name = name;
identity.email = user;
identity.account = account.id;
identity.host = provider.smtp.host;
identity.encryption = iencryption;
identity.port = provider.smtp.port;
identity.auth_type = AUTH_TYPE_GMAIL;
identity.user = user;
identity.password = password;
identity.synchronize = true;
identity.primary = true;
identity.max_size = max_size;
identity.id = db.identity().insertIdentity(identity);
EntityLog.log(context, "Gmail identity=" + identity.name + " email=" + identity.email);
db.setTransactionSuccessful();
} finally {
db.endTransaction();

View File

@ -511,80 +511,88 @@ public class FragmentOAuth extends FragmentBase {
try {
db.beginTransaction();
EntityAccount primary = db.account().getPrimaryAccount();
EntityAccount update = db.account().getAccount(username, AUTH_TYPE_OAUTH);
if (update == null) {
EntityAccount primary = db.account().getPrimaryAccount();
// Create account
EntityAccount account = new EntityAccount();
// Create account
EntityAccount account = new EntityAccount();
account.host = provider.imap.host;
account.encryption = aencryption;
account.port = provider.imap.port;
account.auth_type = AUTH_TYPE_OAUTH;
account.provider = provider.id;
account.user = username;
account.password = state;
account.host = provider.imap.host;
account.encryption = aencryption;
account.port = provider.imap.port;
account.auth_type = AUTH_TYPE_OAUTH;
account.provider = provider.id;
account.user = username;
account.password = state;
int at = address.indexOf('@');
String user = address.substring(0, at);
int at = address.indexOf('@');
String user = address.substring(0, at);
account.name = provider.name + "/" + user;
account.name = provider.name + "/" + user;
account.synchronize = true;
account.primary = (primary == null);
account.synchronize = true;
account.primary = (primary == null);
if (provider.keepalive > 0)
account.poll_interval = provider.keepalive;
if (provider.keepalive > 0)
account.poll_interval = provider.keepalive;
account.partial_fetch = provider.partial;
account.partial_fetch = provider.partial;
account.created = new Date().getTime();
account.last_connected = account.created;
account.created = new Date().getTime();
account.last_connected = account.created;
account.id = db.account().insertAccount(account);
args.putLong("account", account.id);
EntityLog.log(context, "OAuth account=" + account.name);
account.id = db.account().insertAccount(account);
args.putLong("account", account.id);
EntityLog.log(context, "OAuth account=" + account.name);
// Create folders
for (EntityFolder folder : folders) {
EntityFolder existing = db.folder().getFolderByName(account.id, folder.name);
if (existing == null) {
folder.account = account.id;
folder.id = db.folder().insertFolder(folder);
EntityLog.log(context, "OAuth folder=" + folder.name + " type=" + folder.type);
if (folder.synchronize)
EntityOperation.sync(context, folder.id, false);
// Create folders
for (EntityFolder folder : folders) {
EntityFolder existing = db.folder().getFolderByName(account.id, folder.name);
if (existing == null) {
folder.account = account.id;
folder.id = db.folder().insertFolder(folder);
EntityLog.log(context, "OAuth folder=" + folder.name + " type=" + folder.type);
if (folder.synchronize)
EntityOperation.sync(context, folder.id, false);
}
}
}
// Set swipe left/right folder
for (EntityFolder folder : folders)
if (EntityFolder.TRASH.equals(folder.type))
account.swipe_left = folder.id;
else if (EntityFolder.ARCHIVE.equals(folder.type))
account.swipe_right = folder.id;
// Set swipe left/right folder
for (EntityFolder folder : folders)
if (EntityFolder.TRASH.equals(folder.type))
account.swipe_left = folder.id;
else if (EntityFolder.ARCHIVE.equals(folder.type))
account.swipe_right = folder.id;
db.account().updateAccount(account);
db.account().updateAccount(account);
// Create identities
for (Pair<String, String> identity : identities) {
EntityIdentity ident = new EntityIdentity();
ident.name = identity.second;
ident.email = identity.first;
ident.account = account.id;
// Create identities
for (Pair<String, String> identity : identities) {
EntityIdentity ident = new EntityIdentity();
ident.name = identity.second;
ident.email = identity.first;
ident.account = account.id;
ident.host = provider.smtp.host;
ident.encryption = iencryption;
ident.port = provider.smtp.port;
ident.auth_type = AUTH_TYPE_OAUTH;
ident.provider = provider.id;
ident.user = username;
ident.password = state;
ident.synchronize = true;
ident.primary = ident.user.equals(ident.email);
ident.max_size = max_size;
ident.host = provider.smtp.host;
ident.encryption = iencryption;
ident.port = provider.smtp.port;
ident.auth_type = AUTH_TYPE_OAUTH;
ident.provider = provider.id;
ident.user = username;
ident.password = state;
ident.synchronize = true;
ident.primary = ident.user.equals(ident.email);
ident.max_size = max_size;
ident.id = db.identity().insertIdentity(ident);
EntityLog.log(context, "OAuth identity=" + ident.name + " email=" + ident.email);
ident.id = db.identity().insertIdentity(ident);
EntityLog.log(context, "OAuth identity=" + ident.name + " email=" + ident.email);
}
} else {
args.putLong("account", update.id);
EntityLog.log(context, "OAuth update account=" + update.name);
db.account().setAccountPassword(update.id, state);
db.identity().setIdentityPassword(update.id, update.user, state, update.auth_type);
}
db.setTransactionSuccessful();

View File

@ -230,21 +230,8 @@
android:labelFor="@+id/etUser"
android:text="@string/title_user"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
app:layout_constraintBottom_toBottomOf="@id/ibAccount"
app:layout_constraintEnd_toStartOf="@+id/ibAccount"
app:layout_constraintStart_toStartOf="parent" />
<ImageButton
android:id="@+id/ibAccount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:paddingEnd="12dp"
android:tag="ignore"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/etPort"
app:srcCompat="@drawable/twotone_settings_24" />
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/etPort" />
<eu.faircode.email.EditTextPlain
android:id="@+id/etUser"
@ -254,7 +241,7 @@
android:inputType="text"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/ibAccount" />
app:layout_constraintTop_toBottomOf="@id/tvUser" />
<!-- password -->