Make keybase an experimental feature

This commit is contained in:
Dominik Schürmann
2015-08-28 15:18:11 +02:00
parent 905148f586
commit 765ec094c9
12 changed files with 216 additions and 216 deletions

View File

@@ -111,6 +111,7 @@ public final class Constants {
// other settings
public static final String EXPERIMENTAL_ENABLE_WORD_CONFIRM = "experimentalEnableWordConfirm";
public static final String EXPERIMENTAL_ENABLE_LINKED_IDENTITIES = "experimentalEnableLinkedIdentities";
public static final String EXPERIMENTAL_ENABLE_KEYBASE = "experimentalEnableKeybase";
public static final class Theme {
public static final String LIGHT = "light";

View File

@@ -570,7 +570,11 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
initializeExperimentalEnableLinkedIdentities(
(SwitchPreference) findPreference(Constants.Pref.EXPERIMENTAL_ENABLE_LINKED_IDENTITIES));
initializeExperimentalEnableKeybase(
(SwitchPreference) findPreference(Constants.Pref.EXPERIMENTAL_ENABLE_KEYBASE));
initializeTheme((ListPreference) findPreference(Constants.Pref.THEME));
}
}
@@ -702,4 +706,15 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
}
});
}
private static void initializeExperimentalEnableKeybase(final SwitchPreference mExperimentalKeybase) {
mExperimentalKeybase.setChecked(sPreferences.getExperimentalEnableKeybase());
mExperimentalKeybase.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
public boolean onPreferenceChange(Preference preference, Object newValue) {
mExperimentalKeybase.setChecked((Boolean) newValue);
sPreferences.setExperimentalEnableKeybase((Boolean) newValue);
return false;
}
});
}
}

View File

@@ -300,6 +300,13 @@ public class ViewKeyActivity extends BaseNfcActivity implements
.replace(R.id.view_key_fragment, frag)
.commit();
if (Preferences.getPreferences(this).getExperimentalEnableKeybase()) {
final ViewKeyKeybaseFragment keybaseFrag = ViewKeyKeybaseFragment.newInstance(mDataUri);
manager.beginTransaction()
.replace(R.id.view_key_keybase_fragment, keybaseFrag)
.commit();
}
// need to postpone loading of the yubikey fragment until after mMasterKeyId
// is available, but we mark here that this should be done
mShowYubikeyAfterCreation = true;

View File

@@ -57,7 +57,6 @@ public class ViewKeyAdvActivity extends BaseActivity implements
public static final int TAB_IDENTITIES = 1;
public static final int TAB_SUBKEYS = 2;
public static final int TAB_CERTS = 3;
public static final int TAB_KEYBASE = 4;
// view
private ViewPager mViewPager;
@@ -140,11 +139,6 @@ public class ViewKeyAdvActivity extends BaseActivity implements
adapter.addTab(ViewKeyAdvCertsFragment.class,
certsBundle, getString(R.string.key_view_tab_certs));
Bundle trustBundle = new Bundle();
trustBundle.putParcelable(ViewKeyTrustFragment.ARG_DATA_URI, dataUri);
adapter.addTab(ViewKeyTrustFragment.class,
trustBundle, getString(R.string.key_view_tab_keybase));
// update layout after operations
mSlidingTabLayout.setViewPager(mViewPager);
}

View File

@@ -59,14 +59,12 @@ import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
public class ViewKeyTrustFragment extends LoaderFragment implements
public class ViewKeyKeybaseFragment extends LoaderFragment implements
LoaderManager.LoaderCallbacks<Cursor>,
CryptoOperationHelper.Callback<KeybaseVerificationParcel, KeybaseVerificationResult> {
public static final String ARG_DATA_URI = "uri";
private View mStartSearch;
private TextView mTrustReadout;
private TextView mReportHeader;
private TableLayout mProofListing;
private LayoutInflater mInflater;
@@ -86,15 +84,25 @@ public class ViewKeyTrustFragment extends LoaderFragment implements
private CryptoOperationHelper<KeybaseVerificationParcel, KeybaseVerificationResult>
mKeybaseOpHelper;
/**
* Creates new instance of this fragment
*/
public static ViewKeyKeybaseFragment newInstance(Uri dataUri) {
ViewKeyKeybaseFragment frag = new ViewKeyKeybaseFragment();
Bundle args = new Bundle();
args.putParcelable(ARG_DATA_URI, dataUri);
frag.setArguments(args);
return frag;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup superContainer, Bundle savedInstanceState) {
View root = super.onCreateView(inflater, superContainer, savedInstanceState);
View view = inflater.inflate(R.layout.view_key_adv_keybase_fragment, getContainer());
mInflater = inflater;
mTrustReadout = (TextView) view.findViewById(R.id.view_key_trust_readout);
mStartSearch = view.findViewById(R.id.view_key_trust_search_cloud);
mStartSearch.setEnabled(false);
mReportHeader = (TextView) view.findViewById(R.id.view_key_trust_cloud_narrative);
mProofListing = (TableLayout) view.findViewById(R.id.view_key_proof_list);
mProofVerifyHeader = view.findViewById(R.id.view_key_proof_verify_header);
@@ -157,85 +165,47 @@ public class ViewKeyTrustFragment extends LoaderFragment implements
}
boolean nothingSpecial = true;
StringBuilder message = new StringBuilder();
// Swap the new cursor in. (The framework will take care of closing the
// old cursor once we return.)
if (data.moveToFirst()) {
if (data.getInt(INDEX_UNIFIED_HAS_ANY_SECRET) != 0) {
message.append(getString(R.string.key_trust_it_is_yours)).append("\n");
nothingSpecial = false;
} else if (data.getInt(INDEX_VERIFIED) != 0) {
message.append(getString(R.string.key_trust_already_verified)).append("\n");
nothingSpecial = false;
}
// If this key is revoked, dont trust it!
if (data.getInt(INDEX_TRUST_IS_REVOKED) != 0) {
message.append(getString(R.string.key_trust_revoked)).
append(getString(R.string.key_trust_old_keys));
nothingSpecial = false;
} else {
if (data.getInt(INDEX_TRUST_IS_EXPIRED) != 0) {
// if expired, dont trust it!
message.append(getString(R.string.key_trust_expired)).
append(getString(R.string.key_trust_old_keys));
nothingSpecial = false;
}
}
if (nothingSpecial) {
message.append(getString(R.string.key_trust_maybe));
}
final byte[] fp = data.getBlob(INDEX_TRUST_FINGERPRINT);
final String fingerprint = KeyFormattingUtils.convertFingerprintToHex(fp);
if (fingerprint != null) {
mStartSearch.setEnabled(true);
mStartSearch.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
final Preferences.ProxyPrefs proxyPrefs =
Preferences.getPreferences(getActivity()).getProxyPrefs();
OrbotHelper.DialogActions dialogActions = new OrbotHelper.DialogActions() {
@Override
public void onOrbotStarted() {
mStartSearch.setEnabled(false);
new DescribeKey(proxyPrefs.parcelableProxy).execute(fingerprint);
}
@Override
public void onNeutralButton() {
mStartSearch.setEnabled(false);
new DescribeKey(ParcelableProxy.getForNoProxy())
.execute(fingerprint);
}
@Override
public void onCancel() {
}
};
if (OrbotHelper.putOrbotInRequiredState(dialogActions, getActivity())) {
mStartSearch.setEnabled(false);
new DescribeKey(proxyPrefs.parcelableProxy).execute(fingerprint);
}
}
});
}
startSearch(fingerprint);
}
mTrustReadout.setText(message);
setContentShown(true);
}
private void startSearch(final String fingerprint) {
final Preferences.ProxyPrefs proxyPrefs =
Preferences.getPreferences(getActivity()).getProxyPrefs();
OrbotHelper.DialogActions dialogActions = new OrbotHelper.DialogActions() {
@Override
public void onOrbotStarted() {
new DescribeKey(proxyPrefs.parcelableProxy).execute(fingerprint);
}
@Override
public void onNeutralButton() {
new DescribeKey(ParcelableProxy.getForNoProxy())
.execute(fingerprint);
}
@Override
public void onCancel() {
}
};
if (OrbotHelper.putOrbotInRequiredState(dialogActions, getActivity())) {
new DescribeKey(proxyPrefs.parcelableProxy).execute(fingerprint);
}
}
/**
* This is called when the last Cursor provided to onLoadFinished() above is about to be closed.
* We need to make sure we are no longer using it.
@@ -299,17 +269,16 @@ public class ViewKeyTrustFragment extends LoaderFragment implements
return new ResultPage(getString(R.string.key_trust_results_prefix), proofList);
}
private SpannableStringBuilder formatSpannableString(SpannableStringBuilder proofLinks,String proofType){
private SpannableStringBuilder formatSpannableString(SpannableStringBuilder proofLinks, String proofType) {
//Formatting SpannableStringBuilder with String.format() causes the links to stop working.
//This method is to insert the links while reserving the links
SpannableStringBuilder ssb = new SpannableStringBuilder();
ssb.append(proofType);
if(proofType.contains("%s")){
if (proofType.contains("%s")) {
int i = proofType.indexOf("%s");
ssb.replace(i,i+2,proofLinks);
}
else ssb.append(proofLinks);
ssb.replace(i, i + 2, proofLinks);
} else ssb.append(proofLinks);
return ssb;
}
@@ -343,7 +312,6 @@ public class ViewKeyTrustFragment extends LoaderFragment implements
result.mHeader = getActivity().getString(R.string.key_trust_no_cloud_evidence);
}
mStartSearch.setVisibility(View.GONE);
mReportHeader.setVisibility(View.VISIBLE);
mProofListing.setVisibility(View.VISIBLE);
mReportHeader.setText(result.mHeader);
@@ -358,22 +326,35 @@ public class ViewKeyTrustFragment extends LoaderFragment implements
text.setMovementMethod(LinkMovementMethod.getInstance());
mProofListing.addView(row);
}
// mSearchReport.loadDataWithBaseURL("file:///android_res/drawable/", s, "text/html", "UTF-8", null);
}
}
private String getProofNarrative(int proofType) {
int stringIndex;
switch (proofType) {
case Proof.PROOF_TYPE_TWITTER: stringIndex = R.string.keybase_narrative_twitter; break;
case Proof.PROOF_TYPE_GITHUB: stringIndex = R.string.keybase_narrative_github; break;
case Proof.PROOF_TYPE_DNS: stringIndex = R.string.keybase_narrative_dns; break;
case Proof.PROOF_TYPE_WEB_SITE: stringIndex = R.string.keybase_narrative_web_site; break;
case Proof.PROOF_TYPE_HACKERNEWS: stringIndex = R.string.keybase_narrative_hackernews; break;
case Proof.PROOF_TYPE_COINBASE: stringIndex = R.string.keybase_narrative_coinbase; break;
case Proof.PROOF_TYPE_REDDIT: stringIndex = R.string.keybase_narrative_reddit; break;
default: stringIndex = R.string.keybase_narrative_unknown;
case Proof.PROOF_TYPE_TWITTER:
stringIndex = R.string.keybase_narrative_twitter;
break;
case Proof.PROOF_TYPE_GITHUB:
stringIndex = R.string.keybase_narrative_github;
break;
case Proof.PROOF_TYPE_DNS:
stringIndex = R.string.keybase_narrative_dns;
break;
case Proof.PROOF_TYPE_WEB_SITE:
stringIndex = R.string.keybase_narrative_web_site;
break;
case Proof.PROOF_TYPE_HACKERNEWS:
stringIndex = R.string.keybase_narrative_hackernews;
break;
case Proof.PROOF_TYPE_COINBASE:
stringIndex = R.string.keybase_narrative_coinbase;
break;
case Proof.PROOF_TYPE_REDDIT:
stringIndex = R.string.keybase_narrative_reddit;
break;
default:
stringIndex = R.string.keybase_narrative_unknown;
}
return getActivity().getString(stringIndex);
}
@@ -390,14 +371,22 @@ public class ViewKeyTrustFragment extends LoaderFragment implements
// which proofs do we have working verifiers for?
private boolean haveProofFor(int proofType) {
switch (proofType) {
case Proof.PROOF_TYPE_TWITTER: return true;
case Proof.PROOF_TYPE_GITHUB: return true;
case Proof.PROOF_TYPE_DNS: return true;
case Proof.PROOF_TYPE_WEB_SITE: return true;
case Proof.PROOF_TYPE_HACKERNEWS: return true;
case Proof.PROOF_TYPE_COINBASE: return true;
case Proof.PROOF_TYPE_REDDIT: return true;
default: return false;
case Proof.PROOF_TYPE_TWITTER:
return true;
case Proof.PROOF_TYPE_GITHUB:
return true;
case Proof.PROOF_TYPE_DNS:
return true;
case Proof.PROOF_TYPE_WEB_SITE:
return true;
case Proof.PROOF_TYPE_HACKERNEWS:
return true;
case Proof.PROOF_TYPE_COINBASE:
return true;
case Proof.PROOF_TYPE_REDDIT:
return true;
default:
return false;
}
}

View File

@@ -381,6 +381,16 @@ public class Preferences {
return mSharedPreferences.getBoolean(Pref.EXPERIMENTAL_ENABLE_LINKED_IDENTITIES, false);
}
public void setExperimentalEnableKeybase(boolean enableKeybase) {
SharedPreferences.Editor editor = mSharedPreferences.edit();
editor.putBoolean(Pref.EXPERIMENTAL_ENABLE_KEYBASE, enableKeybase);
editor.commit();
}
public boolean getExperimentalEnableKeybase() {
return mSharedPreferences.getBoolean(Pref.EXPERIMENTAL_ENABLE_KEYBASE, false);
}
public void upgradePreferences(Context context) {
if (mSharedPreferences.getInt(Constants.Pref.PREF_DEFAULT_VERSION, 0) !=
Constants.Defaults.PREF_VERSION) {

View File

@@ -182,18 +182,32 @@
android:layout_gravity="fill_vertical"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<FrameLayout
<LinearLayout
android:id="@+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:orientation="vertical">
<FrameLayout
android:id="@+id/view_key_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_height="wrap_content" />
<FrameLayout
android:id="@+id/view_key_keybase_fragment"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<!--
placeholder to improve the scrolling.
Somehow the content must be large enough to enable scrolling on NestedScrollView
-->
<View
android:layout_width="match_parent"
android:layout_height="230dp"
android:orientation="vertical" />
</FrameLayout>
</LinearLayout>
</android.support.v4.widget.FlingNestedScrollView>

View File

@@ -1,126 +1,95 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="16dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="16dp">
<TextView
android:layout_width="wrap_content"
<android.support.v7.widget.CardView
android:id="@+id/card_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorButtonRow"
android:padding="8dp"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="@string/key_trust_header_text"
android:gravity="center_horizontal" />
android:layout_gravity="center"
card_view:cardBackgroundColor="?attr/colorCardViewBackground"
card_view:cardCornerRadius="4dp"
card_view:cardElevation="2dp"
card_view:cardUseCompatPadding="true">
<View
android:layout_width="match_parent"
android:layout_height="1dip"
android:background="?android:attr/listDivider" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- focusable and related properties to workaround http://stackoverflow.com/q/16182331-->
<LinearLayout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="true"
android:focusableInTouchMode="true"
android:descendantFocusability="beforeDescendants"
android:orientation="vertical"
android:paddingLeft="16dp"
android:paddingRight="16dp">
android:orientation="vertical">
<TextView
style="@style/SectionHeader"
style="@style/CardViewHeader"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_marginTop="8dp"
android:text="@string/section_should_you_trust"
android:layout_weight="1" />
android:layout_height="wrap_content"
android:text="@string/section_keybase_proofs" />
<TextView
android:id="@+id/view_key_trust_readout"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_marginTop="14dp"
android:layout_marginLeft="8dp"
android:layout_weight="1"
style="?android:attr/textAppearanceMedium" />
android:layout_height="wrap_content"
android:background="?attr/colorButtonRow"
android:gravity="center_horizontal"
android:padding="8dp"
android:text="@string/key_trust_header_text"
android:textAppearance="?android:attr/textAppearanceSmall" />
<TextView
style="@style/SectionHeader"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_marginTop="14dp"
android:text="@string/section_cloud_evidence"
android:layout_weight="1" />
<View
android:layout_width="match_parent"
android:layout_height="1dip"
android:background="?android:attr/listDivider" />
<LinearLayout
android:id="@+id/view_key_trust_search_cloud"
android:layout_width="match_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
android:clickable="true"
android:paddingRight="4dp"
style="?android:attr/borderlessButtonStyle"
android:orientation="horizontal">
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="16dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="16dp">
<TextView
android:paddingLeft="8dp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_width="0dip"
android:layout_height="match_parent"
android:text="@string/key_trust_start_cloud_search"
android:layout_weight="1"
android:gravity="center_vertical" />
android:id="@+id/view_key_trust_cloud_narrative"
style="?android:attr/textAppearanceMedium"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginBottom="14dp"
android:layout_marginLeft="8dp"
android:layout_weight="1" />
<ImageView
<TableLayout
android:id="@+id/view_key_proof_list"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/view_key_proof_verify_header"
style="@style/SectionHeader"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:padding="8dp"
android:src="@drawable/ic_action_search_cloud"
android:layout_gravity="center_vertical" />
android:layout_height="0dp"
android:layout_marginTop="16dp"
android:layout_weight="1"
android:text="@string/section_proof_details" />
<TextView
android:id="@+id/view_key_proof_verify_detail"
style="?android:attr/textAppearanceMedium"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginLeft="8dp"
android:layout_marginTop="14dp"
android:layout_weight="1" />
</LinearLayout>
<TextView
android:id="@+id/view_key_trust_cloud_narrative"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_marginTop="14dp"
android:layout_marginBottom="14dp"
android:layout_marginLeft="8dp"
android:layout_weight="1"
style="?android:attr/textAppearanceMedium" />
<TableLayout
android:id="@+id/view_key_proof_list"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/view_key_proof_verify_header"
style="@style/SectionHeader"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_marginTop="16dp"
android:text="@string/section_proof_details"
android:layout_weight="1" />
<TextView
android:id="@+id/view_key_proof_verify_detail"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_marginTop="14dp"
android:layout_marginLeft="8dp"
android:layout_weight="1"
style="?android:attr/textAppearanceMedium" />
</LinearLayout>
</ScrollView>
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>

View File

@@ -7,7 +7,7 @@
android:layout_height="wrap_content"
android:paddingLeft="6dip"
android:text="1."
style="?android:attr/textAppearanceMedium" />
style="?android:attr/textAppearanceSmall" />
<TextView
android:id="@+id/proof_text"
@@ -15,5 +15,5 @@
android:layout_height="wrap_content"
android:paddingLeft="6dip"
android:text="Posts to twitter as Timbray"
style="?android:attr/textAppearanceMedium" />
style="?android:attr/textAppearanceSmall" />
</TableRow>

View File

@@ -3,12 +3,10 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="230dp"
android:paddingBottom="16dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="16dp">
<!-- paddingBottom is this large to improve the scrolling.
Somehow the content must be large enough to enable scrolling on NestedScrollView -->
<android.support.v7.widget.CardView
android:id="@+id/card_view"

View File

@@ -43,9 +43,9 @@
<string name="section_user_ids">"Identities"</string>
<string name="section_yubikey">"YubiKey"</string>
<string name="section_linked_system_contact">"Linked System Contact"</string>
<string name="section_keybase_proofs">"Keybase.io Proofs"</string>
<string name="section_should_you_trust">"Should you trust this key?"</string>
<string name="section_proof_details">Proof verification</string>
<string name="section_cloud_evidence">"Proofs from the Internet"</string>
<string name="section_keys">"Subkeys"</string>
<string name="section_cloud_search">"Key Search"</string>
<string name="section_cloud_search_summary">"Keyserver, keybase.io"</string>
@@ -197,6 +197,8 @@
<string name="label_experimental_settings_word_confirm_summary">"Allows to compare fingerprints with words instead of hexadecimal representation."</string>
<string name="label_experimental_settings_linked_identities_title">"Linked Identities"</string>
<string name="label_experimental_settings_linked_identities_summary">"Linked Identities"</string>
<string name="label_experimental_settings_keybase_title">"Keybase.io Proofs"</string>
<string name="label_experimental_settings_keybase_summary">"Every time a key is displayed, this will contact keybase.io for key proofs"</string>
<!-- Proxy Preferences -->
<string name="pref_proxy_tor_title">"Enable Tor"</string>
@@ -674,12 +676,6 @@
<string name="user_id_info_invalid_text">"Something is wrong with this identity!"</string>
<!-- Key trust -->
<string name="key_trust_already_verified">"You have already confirmed this key!"</string>
<string name="key_trust_it_is_yours">"This is one of your keys!"</string>
<string name="key_trust_maybe">"This key is neither revoked nor expired.\nYou havent confirmed it, but you may choose to trust it."</string>
<string name="key_trust_revoked">"This key has been revoked by its owner. You should not trust it."</string>
<string name="key_trust_expired">"This key has expired. You should not trust it."</string>
<string name="key_trust_old_keys">"It may be OK to use this to decrypt an old message dating from the time when this key was valid."</string>
<string name="key_trust_no_cloud_evidence">"No proof from the Internet on this keys trustworthiness."</string>
<string name="key_trust_start_cloud_search">"Start search"</string>
<string name="key_trust_results_prefix">"Keybase.io offers “proofs” which assert that the owner of this key: "</string>

View File

@@ -18,6 +18,13 @@
android:summary="@string/label_experimental_settings_linked_identities_summary"
android:title="@string/label_experimental_settings_linked_identities_title" />
<SwitchPreference
android:defaultValue="false"
android:key="experimentalEnableKeybase"
android:persistent="false"
android:summary="@string/label_experimental_settings_keybase_summary"
android:title="@string/label_experimental_settings_keybase_title" />
<ListPreference
android:dialogTitle="@string/label_theme"
android:entries="@array/theme_entries"