diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java index 60bcf187d..6a9656b28 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java @@ -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"; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SettingsActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SettingsActivity.java index 43edc8220..4077f1c84 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SettingsActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SettingsActivity.java @@ -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; + } + }); + } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java index 4ae568d28..06126ebc4 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java @@ -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; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvActivity.java index 673092e61..edd9feec9 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvActivity.java @@ -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); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyTrustFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyKeybaseFragment.java similarity index 78% rename from OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyTrustFragment.java rename to OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyKeybaseFragment.java index 150acdc90..266633061 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyTrustFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyKeybaseFragment.java @@ -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, CryptoOperationHelper.Callback { 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 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, don’t 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, don’t 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; } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Preferences.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Preferences.java index 3225c3765..4ef215036 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Preferences.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Preferences.java @@ -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) { diff --git a/OpenKeychain/src/main/res/layout/view_key_activity.xml b/OpenKeychain/src/main/res/layout/view_key_activity.xml index 1c29ad759..3913122bc 100644 --- a/OpenKeychain/src/main/res/layout/view_key_activity.xml +++ b/OpenKeychain/src/main/res/layout/view_key_activity.xml @@ -182,18 +182,32 @@ android:layout_gravity="fill_vertical" app:layout_behavior="@string/appbar_scrolling_view_behavior"> - + android:layout_height="match_parent" + android:orientation="vertical"> + + + + + - + diff --git a/OpenKeychain/src/main/res/layout/view_key_adv_keybase_fragment.xml b/OpenKeychain/src/main/res/layout/view_key_adv_keybase_fragment.xml index eecb19000..75d56e092 100644 --- a/OpenKeychain/src/main/res/layout/view_key_adv_keybase_fragment.xml +++ b/OpenKeychain/src/main/res/layout/view_key_adv_keybase_fragment.xml @@ -1,126 +1,95 @@ + android:layout_height="wrap_content" + android:orientation="vertical" + android:paddingBottom="16dp" + android:paddingLeft="16dp" + android:paddingRight="16dp" + android:paddingTop="16dp"> - + android:layout_gravity="center" + card_view:cardBackgroundColor="?attr/colorCardViewBackground" + card_view:cardCornerRadius="4dp" + card_view:cardElevation="2dp" + card_view:cardUseCompatPadding="true"> - - - - - - + android:orientation="vertical"> + android:layout_height="wrap_content" + android:text="@string/section_keybase_proofs" /> + 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" /> - + + android:layout_height="wrap_content" + android:orientation="vertical" + android:paddingBottom="16dp" + android:paddingLeft="16dp" + android:paddingRight="16dp" + android:paddingTop="16dp"> + 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" /> - + + + android:layout_height="0dp" + android:layout_marginTop="16dp" + android:layout_weight="1" + android:text="@string/section_proof_details" /> + + - - - - - - - - - - - + + + \ No newline at end of file diff --git a/OpenKeychain/src/main/res/layout/view_key_adv_keybase_proof.xml b/OpenKeychain/src/main/res/layout/view_key_adv_keybase_proof.xml index 0ffd151c1..033282305 100644 --- a/OpenKeychain/src/main/res/layout/view_key_adv_keybase_proof.xml +++ b/OpenKeychain/src/main/res/layout/view_key_adv_keybase_proof.xml @@ -7,7 +7,7 @@ android:layout_height="wrap_content" android:paddingLeft="6dip" android:text="1." - style="?android:attr/textAppearanceMedium" /> + style="?android:attr/textAppearanceSmall" /> + style="?android:attr/textAppearanceSmall" /> diff --git a/OpenKeychain/src/main/res/layout/view_key_fragment.xml b/OpenKeychain/src/main/res/layout/view_key_fragment.xml index 42c8f617b..0d15ba7dc 100644 --- a/OpenKeychain/src/main/res/layout/view_key_fragment.xml +++ b/OpenKeychain/src/main/res/layout/view_key_fragment.xml @@ -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"> - "Identities" "YubiKey" "Linked System Contact" + "Keybase.io Proofs" "Should you trust this key?" Proof verification - "Proofs from the Internet" "Subkeys" "Key Search" "Keyserver, keybase.io" @@ -197,6 +197,8 @@ "Allows to compare fingerprints with words instead of hexadecimal representation." "Linked Identities" "Linked Identities" + "Keybase.io Proofs" + "Every time a key is displayed, this will contact keybase.io for key proofs" "Enable Tor" @@ -674,12 +676,6 @@ "Something is wrong with this identity!" - "You have already confirmed this key!" - "This is one of your keys!" - "This key is neither revoked nor expired.\nYou haven’t confirmed it, but you may choose to trust it." - "This key has been revoked by its owner. You should not trust it." - "This key has expired. You should not trust it." - "It may be OK to use this to decrypt an old message dating from the time when this key was valid." "No proof from the Internet on this key’s trustworthiness." "Start search" "Keybase.io offers “proofs” which assert that the owner of this key: " diff --git a/OpenKeychain/src/main/res/xml/experimental_preferences.xml b/OpenKeychain/src/main/res/xml/experimental_preferences.xml index eb88e3ed9..33ab92697 100644 --- a/OpenKeychain/src/main/res/xml/experimental_preferences.xml +++ b/OpenKeychain/src/main/res/xml/experimental_preferences.xml @@ -18,6 +18,13 @@ android:summary="@string/label_experimental_settings_linked_identities_summary" android:title="@string/label_experimental_settings_linked_identities_title" /> + +