1
0
mirror of https://github.com/etesync/android synced 2024-12-23 23:18:46 +00:00

Add a fragment to setup user info.

This is used to create a keypair and put it on the server if one doesn't
exist, and fetch it and save it locally if one does.

It's currently called from the account activity.
This commit is contained in:
Tom Hacohen 2017-04-13 16:26:12 +01:00
parent beccb33904
commit a57936982d
3 changed files with 151 additions and 0 deletions

View File

@ -57,6 +57,7 @@ import com.etesync.syncadapter.model.CollectionInfo;
import com.etesync.syncadapter.model.JournalEntity; import com.etesync.syncadapter.model.JournalEntity;
import com.etesync.syncadapter.model.ServiceEntity; import com.etesync.syncadapter.model.ServiceEntity;
import com.etesync.syncadapter.resource.LocalCalendar; import com.etesync.syncadapter.resource.LocalCalendar;
import com.etesync.syncadapter.ui.setup.SetupUserInfoFragment;
import com.etesync.syncadapter.utils.HintManager; import com.etesync.syncadapter.utils.HintManager;
import com.etesync.syncadapter.utils.ShowcaseBuilder; import com.etesync.syncadapter.utils.ShowcaseBuilder;
@ -113,6 +114,10 @@ public class AccountActivity extends AppCompatActivity implements Toolbar.OnMenu
.playOn(tbCardDAV); .playOn(tbCardDAV);
HintManager.setHintSeen(this, HINT_VIEW_COLLECTION, true); HintManager.setHintSeen(this, HINT_VIEW_COLLECTION, true);
} }
if (!SetupUserInfoFragment.hasUserInfo(this, account)) {
SetupUserInfoFragment.newInstance(account).show(getSupportFragmentManager(), null);
}
} }
@Override @Override

View File

@ -0,0 +1,142 @@
package com.etesync.syncadapter.ui.setup;
import android.accounts.Account;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
import android.support.v7.app.AlertDialog;
import android.widget.TextView;
import com.etesync.syncadapter.AccountSettings;
import com.etesync.syncadapter.App;
import com.etesync.syncadapter.HttpClient;
import com.etesync.syncadapter.InvalidAccountException;
import com.etesync.syncadapter.R;
import com.etesync.syncadapter.journalmanager.Crypto;
import com.etesync.syncadapter.journalmanager.UserInfoManager;
import lombok.RequiredArgsConstructor;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import static com.etesync.syncadapter.Constants.KEY_ACCOUNT;
public class SetupUserInfoFragment extends DialogFragment {
private Account account;
private AccountSettings settings;
public static SetupUserInfoFragment newInstance(Account account) {
SetupUserInfoFragment frag = new SetupUserInfoFragment();
Bundle args = new Bundle(1);
args.putParcelable(KEY_ACCOUNT, account);
frag.setArguments(args);
return frag;
}
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
ProgressDialog progress = new ProgressDialog(getActivity());
progress.setTitle(R.string.login_encryption_setup_title);
progress.setMessage(getString(R.string.login_encryption_setup));
progress.setIndeterminate(true);
progress.setCanceledOnTouchOutside(false);
setCancelable(false);
return progress;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
account = getArguments().getParcelable(KEY_ACCOUNT);
try {
settings = new AccountSettings(getContext(), account);
} catch (Exception e) {
e.printStackTrace();
}
new SetupUserInfo().execute(account);
}
public static boolean hasUserInfo(Context context, Account account) {
AccountSettings settings;
try {
settings = new AccountSettings(context, account);
} catch (InvalidAccountException e) {
e.printStackTrace();
return false;
}
return settings.getKeyPair() != null;
}
protected class SetupUserInfo extends AsyncTask<Account, Integer, SetupUserInfo.SetupUserInfoResult> {
ProgressDialog progressDialog;
@Override
protected void onPreExecute() {
progressDialog = (ProgressDialog) getDialog();
}
@Override
protected SetupUserInfo.SetupUserInfoResult doInBackground(Account... accounts) {
try {
OkHttpClient httpClient = HttpClient.create(getContext(), account);
Crypto.CryptoManager cryptoManager = new Crypto.CryptoManager(com.etesync.syncadapter.journalmanager.Constants.CURRENT_VERSION, settings.password(), "userInfo");
UserInfoManager userInfoManager = new UserInfoManager(httpClient, HttpUrl.get(settings.getUri()));
UserInfoManager.UserInfo userInfo = userInfoManager.get(cryptoManager, account.name);
if (userInfo == null) {
App.log.info("Creating userInfo for " + account.name);
userInfo = UserInfoManager.UserInfo.generate(cryptoManager, account.name);
userInfoManager.create(userInfo);
} else {
App.log.info("Fetched userInfo for " + account.name);
}
Crypto.AsymmetricKeyPair keyPair = new Crypto.AsymmetricKeyPair(userInfo.getContent(cryptoManager), userInfo.getPubkey());
return new SetupUserInfoResult(keyPair, null);
} catch (Exception e) {
e.printStackTrace();
return new SetupUserInfoResult(null, e);
}
}
@Override
protected void onPostExecute(SetupUserInfoResult result) {
if (result.exception == null) {
settings.setKeyPair(result.keyPair);
} else {
Dialog dialog = new AlertDialog.Builder(getActivity())
.setTitle(R.string.login_encryption_error_title)
.setIcon(R.drawable.ic_error_dark)
.setMessage(result.exception.getLocalizedMessage())
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// dismiss
}
})
.create();
dialog.show();
}
dismissAllowingStateLoss();
}
@RequiredArgsConstructor
class SetupUserInfoResult {
final Crypto.AsymmetricKeyPair keyPair;
final Exception exception;
}
}
}

View File

@ -140,6 +140,10 @@
<string name="login_encryption_setup_title">Setting up encryption</string> <string name="login_encryption_setup_title">Setting up encryption</string>
<string name="login_encryption_setup">Please wait, setting up encryption…</string> <string name="login_encryption_setup">Please wait, setting up encryption…</string>
<!-- SetupUserInfoFragment -->
<string name="login_encryption_error_title">Encryption Error</string>
<!-- ImportFragment --> <!-- ImportFragment -->
<string name="import_dialog_title">Import</string> <string name="import_dialog_title">Import</string>
<string name="import_dialog_failed_title">Import Failed</string> <string name="import_dialog_failed_title">Import Failed</string>