only display custodian help recover explainer screen if you are a custodian

This commit is contained in:
ameba23
2021-03-22 17:03:22 +01:00
parent 365fa58928
commit 2486a60fea
2 changed files with 165 additions and 127 deletions

View File

@@ -1,11 +1,22 @@
package org.briarproject.briar.android.socialbackup; package org.briarproject.briar.android.socialbackup;
import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.widget.Toast;
import org.briarproject.bramble.api.contact.ContactId;
import org.briarproject.bramble.api.db.DatabaseComponent;
import org.briarproject.bramble.api.db.DbException;
import org.briarproject.briar.R; import org.briarproject.briar.R;
import org.briarproject.briar.android.activity.ActivityComponent; import org.briarproject.briar.android.activity.ActivityComponent;
import org.briarproject.briar.android.activity.BriarActivity; import org.briarproject.briar.android.activity.BriarActivity;
import org.briarproject.briar.android.fragment.BaseFragment; import org.briarproject.briar.android.fragment.BaseFragment;
import org.briarproject.briar.api.socialbackup.BackupMetadata;
import org.briarproject.briar.api.socialbackup.SocialBackupManager;
import javax.inject.Inject;
import static org.briarproject.briar.android.conversation.ConversationActivity.CONTACT_ID;
public class CustodianHelpRecoverActivity extends BriarActivity implements public class CustodianHelpRecoverActivity extends BriarActivity implements
BaseFragment.BaseFragmentListener, CustodianScanQrButtonListener { BaseFragment.BaseFragmentListener, CustodianScanQrButtonListener {
@@ -14,15 +25,39 @@ public class CustodianHelpRecoverActivity extends BriarActivity implements
component.inject(this); component.inject(this);
} }
@Inject
public SocialBackupManager socialBackupManager;
@Inject
public DatabaseComponent db;
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recover); // TODO change this setContentView(R.layout.activity_recover); // TODO change this
// TODO check if we have a shard for this secret owner
// if not we should not even display the menu item Intent intent = getIntent();
CustodianRecoveryModeExplainerFragment fragment = int id = intent.getIntExtra(CONTACT_ID, -1);
new CustodianRecoveryModeExplainerFragment(); if (id == -1) throw new IllegalStateException("No ContactId");
showInitialFragment(fragment); ContactId contactId = new ContactId(id);
// check if we have a shard for this secret owner
try {
db.transaction(false, txn -> {
if (!socialBackupManager.amCustodian(txn, contactId)) {
throw new DbException();
}
CustodianRecoveryModeExplainerFragment fragment =
new CustodianRecoveryModeExplainerFragment();
showInitialFragment(fragment);
});
} catch (DbException e) {
// TODO improve this
Toast.makeText(this,
"You do not hold a backup shard from this contact",
Toast.LENGTH_SHORT).show();
finish();
}
} }
@Override @Override

View File

@@ -8,162 +8,165 @@ import android.view.MenuInflater;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.SeekBar; import android.widget.SeekBar;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.DbException;
import org.briarproject.briar.R; import org.briarproject.briar.R;
import org.briarproject.briar.android.activity.ActivityComponent; import org.briarproject.briar.android.activity.ActivityComponent;
import org.briarproject.briar.android.contactselection.ContactSelectorListener;
import org.briarproject.briar.android.fragment.BaseFragment; import org.briarproject.briar.android.fragment.BaseFragment;
import org.magmacollective.darkcrystal.secretsharingwrapper.SecretSharingWrapper; import org.magmacollective.darkcrystal.secretsharingwrapper.SecretSharingWrapper;
import static java.util.Objects.requireNonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
public class ThresholdSelectorFragment extends BaseFragment { public class ThresholdSelectorFragment extends BaseFragment {
public static final String TAG = ThresholdSelectorFragment.class.getName(); public static final String TAG = ThresholdSelectorFragment.class.getName();
private static final String NUMBER_CUSTODIANS = "numberCustodians"; private static final String NUMBER_CUSTODIANS = "numberCustodians";
protected ThresholdDefinedListener listener; protected ThresholdDefinedListener listener;
// TODO this should be the actual number of custodians // TODO this should be the actual number of custodians
private int numberOfCustodians; private int numberOfCustodians;
private int threshold; private int threshold;
private int recommendedThreshold; private int recommendedThreshold;
private SeekBar seekBar; private SeekBar seekBar;
private TextView thresholdRepresentation; private TextView thresholdRepresentation;
private TextView message; private TextView message;
private TextView mOfn; private TextView mOfn;
public static ThresholdSelectorFragment newInstance(int numberCustodians) { public static ThresholdSelectorFragment newInstance(int numberCustodians) {
Bundle bundle = new Bundle(); Bundle bundle = new Bundle();
bundle.putInt(NUMBER_CUSTODIANS, numberCustodians); bundle.putInt(NUMBER_CUSTODIANS, numberCustodians);
ThresholdSelectorFragment fragment = new ThresholdSelectorFragment(); ThresholdSelectorFragment fragment = new ThresholdSelectorFragment();
fragment.setArguments(bundle); fragment.setArguments(bundle);
return fragment; return fragment;
} }
@Override @Override
public void onCreate(@Nullable Bundle savedInstanceState) { public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
requireActivity().setTitle(R.string.title_define_threshold); requireActivity().setTitle(R.string.title_define_threshold);
} }
@Nullable @Nullable
@Override @Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { public View onCreateView(@NonNull LayoutInflater inflater,
View view = inflater.inflate(R.layout.fragment_select_threshold, @Nullable ViewGroup container,
container, false); @Nullable Bundle savedInstanceState) {
Bundle args = requireArguments(); View view = inflater.inflate(R.layout.fragment_select_threshold,
numberOfCustodians = args.getInt(NUMBER_CUSTODIANS); container, false);
Bundle args = requireArguments();
numberOfCustodians = args.getInt(NUMBER_CUSTODIANS);
seekBar = view.findViewById(R.id.seekBar); seekBar = view.findViewById(R.id.seekBar);
thresholdRepresentation = view.findViewById(R.id.textViewThresholdRepresentation); thresholdRepresentation =
message = view.findViewById(R.id.textViewMessage); view.findViewById(R.id.textViewThresholdRepresentation);
mOfn = view.findViewById(R.id.textViewmOfn); message = view.findViewById(R.id.textViewMessage);
int max = numberOfCustodians - 3; mOfn = view.findViewById(R.id.textViewmOfn);
seekBar.setMax(max); int max = numberOfCustodians - 3;
seekBar.setOnSeekBarChangeListener(new SeekBarListener()); seekBar.setMax(max);
recommendedThreshold = SecretSharingWrapper.defaultThreshold(numberOfCustodians); seekBar.setOnSeekBarChangeListener(new SeekBarListener());
threshold = recommendedThreshold; recommendedThreshold =
seekBar.setProgress(threshold - 2); SecretSharingWrapper.defaultThreshold(numberOfCustodians);
threshold = recommendedThreshold;
seekBar.setProgress(threshold - 2);
thresholdRepresentation.setText(buildThresholdRepresentationString()); thresholdRepresentation.setText(buildThresholdRepresentationString());
setmOfnText(); setmOfnText();
return view; return view;
// return super.onCreateView(inflater, container, savedInstanceState); // return super.onCreateView(inflater, container, savedInstanceState);
} }
private void setmOfnText() { private void setmOfnText() {
mOfn.setText(String.format("%d of %d contacts needed to recover your account", threshold, numberOfCustodians)); mOfn.setText(String.format(
} "%d of %d contacts needed to recover your account", threshold,
numberOfCustodians));
}
@Override @Override
public void onAttach(Context context) { public void onAttach(Context context) {
super.onAttach(context); super.onAttach(context);
listener = (ThresholdDefinedListener) context; listener = (ThresholdDefinedListener) context;
} }
@Override @Override
public String getUniqueTag() { public String getUniqueTag() {
return TAG; return TAG;
} }
@Override @Override
public void injectFragment(ActivityComponent component) { public void injectFragment(ActivityComponent component) {
component.inject(this); component.inject(this);
} }
@Override @Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.define_threshold_actions, menu); inflater.inflate(R.menu.define_threshold_actions, menu);
super.onCreateOptionsMenu(menu, inflater); super.onCreateOptionsMenu(menu, inflater);
} }
@Override @Override
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) { switch (item.getItemId()) {
case R.id.action_threshold_defined: case R.id.action_threshold_defined:
try { try {
listener.thresholdDefined(threshold); listener.thresholdDefined(threshold);
} catch (DbException e) { } catch (DbException e) {
e.printStackTrace(); e.printStackTrace();
} }
return true; return true;
default: default:
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);
} }
} }
private String buildThresholdRepresentationString () { private String buildThresholdRepresentationString() {
String thresholdRepresentationText = ""; String thresholdRepresentationText = "";
for (int i = 0; i < threshold; i++) { for (int i = 0; i < threshold; i++) {
thresholdRepresentationText += getString(R.string.filled_bullet); thresholdRepresentationText += getString(R.string.filled_bullet);
} }
for (int i = 0; i < (numberOfCustodians - threshold); i++) { for (int i = 0; i < (numberOfCustodians - threshold); i++) {
thresholdRepresentationText += getString(R.string.linear_bullet); thresholdRepresentationText += getString(R.string.linear_bullet);
} }
return thresholdRepresentationText; return thresholdRepresentationText;
} }
private class SeekBarListener implements SeekBar.OnSeekBarChangeListener { private class SeekBarListener implements SeekBar.OnSeekBarChangeListener {
@Override @Override
public void onProgressChanged(SeekBar seekBar, int progress, public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) { boolean fromUser) {
threshold = progress + 2; threshold = progress + 2;
thresholdRepresentation.setText( thresholdRepresentation.setText(
buildThresholdRepresentationString() buildThresholdRepresentationString()
); );
setmOfnText(); setmOfnText();
int sanityLevel = SecretSharingWrapper.thresholdSanity(threshold, numberOfCustodians); int sanityLevel = SecretSharingWrapper
int text = R.string.threshold_secure; .thresholdSanity(threshold, numberOfCustodians);
if (threshold == recommendedThreshold) text = R.string.threshold_recommended; int text = R.string.threshold_secure;
if (sanityLevel < -1) text = R.string.threshold_low_insecure; if (threshold == recommendedThreshold)
if (sanityLevel > 0) text = R.string.threshold_high_insecure; text = R.string.threshold_recommended;
message.setText(text); if (sanityLevel < -1) text = R.string.threshold_low_insecure;
// TODO change colour of thresholdRepresentation to green/red based on sanityLevel if (sanityLevel > 0) text = R.string.threshold_high_insecure;
} message.setText(text);
// TODO change colour of thresholdRepresentation to green/red based on sanityLevel
}
@Override @Override
public void onStartTrackingTouch(SeekBar seekBar) { public void onStartTrackingTouch(SeekBar seekBar) {
// do nothing // do nothing
} }
@Override @Override
public void onStopTrackingTouch(SeekBar seekBar) { public void onStopTrackingTouch(SeekBar seekBar) {
// do nothing // do nothing
} }
} }
} }