diff options
author | Vincent Breitmoser <valodim@mugenguild.com> | 2015-09-02 04:13:32 +0200 |
---|---|---|
committer | Vincent Breitmoser <valodim@mugenguild.com> | 2015-09-02 04:14:45 +0200 |
commit | 2cda48642722069c7e26d0a25d196e8a41128290 (patch) | |
tree | 29bf478f9bf25bb2a7c2026ec2a3b8c8d0acfe79 /OpenKeychain/src | |
parent | 87f7fe65a8ddf9f9f2f9881c0f2ef8f5d0e8c9f1 (diff) | |
download | open-keychain-2cda48642722069c7e26d0a25d196e8a41128290.tar.gz open-keychain-2cda48642722069c7e26d0a25d196e8a41128290.tar.bz2 open-keychain-2cda48642722069c7e26d0a25d196e8a41128290.zip |
linked: use webview instead of app, and some minor layoutings
Diffstat (limited to 'OpenKeychain/src')
7 files changed, 197 insertions, 126 deletions
diff --git a/OpenKeychain/src/main/AndroidManifest.xml b/OpenKeychain/src/main/AndroidManifest.xml index cb886ed50..d2e953f8a 100644 --- a/OpenKeychain/src/main/AndroidManifest.xml +++ b/OpenKeychain/src/main/AndroidManifest.xml @@ -113,16 +113,7 @@ <activity android:name=".ui.linked.LinkedIdWizard" android:configChanges="orientation|screenSize|keyboardHidden|keyboard" - android:launchMode="singleInstance" android:label="@string/title_linked_create"> - <intent-filter> - <action android:name="android.intent.action.VIEW" /> - <category android:name="android.intent.category.DEFAULT" /> - <category android:name="android.intent.category.BROWSABLE" /> - <data - android:host="linked" - android:scheme="oauth-openkeychain" /> - </intent-filter> </activity> <activity android:name=".ui.QrCodeViewActivity" diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateGithubFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateGithubFragment.java index b59166721..f04e10529 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateGithubFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateGithubFragment.java @@ -28,8 +28,18 @@ import java.io.OutputStream; import java.io.OutputStreamWriter; import java.net.URI; import java.net.URL; - +import java.util.Random; + +import android.annotation.SuppressLint; +import android.app.Activity; +import android.app.Dialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.DialogInterface.OnDismissListener; +import android.content.Intent; +import android.net.Uri; import android.os.AsyncTask; +import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.support.annotation.NonNull; @@ -38,11 +48,16 @@ import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; +import android.webkit.WebView; +import android.webkit.WebViewClient; +import android.widget.ImageView; +import android.widget.TextView; import android.widget.ViewAnimator; import javax.net.ssl.HttpsURLConnection; import org.json.JSONException; import org.json.JSONObject; +import org.spongycastle.util.encoders.Hex; import org.sufficientlysecure.keychain.BuildConfig; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; @@ -50,7 +65,9 @@ import org.sufficientlysecure.keychain.linked.LinkedAttribute; import org.sufficientlysecure.keychain.linked.resources.GithubResource; import org.sufficientlysecure.keychain.operations.results.EditKeyResult; import org.sufficientlysecure.keychain.pgp.WrappedUserAttribute; +import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.service.SaveKeyringParcel; +import org.sufficientlysecure.keychain.ui.ViewKeyActivity; import org.sufficientlysecure.keychain.ui.base.CryptoOperationFragment; import org.sufficientlysecure.keychain.ui.widget.StatusIndicator; import org.sufficientlysecure.keychain.util.Log; @@ -65,6 +82,7 @@ public class LinkedIdCreateGithubFragment extends CryptoOperationFragment<SaveKe byte[] mFingerprint; long mMasterKeyId; private SaveKeyringParcel mSaveKeyringParcel; + private TextView mLinkedIdTitle, mLinkedIdComment; public static LinkedIdCreateGithubFragment newInstance() { return new LinkedIdCreateGithubFragment(); @@ -84,10 +102,15 @@ public class LinkedIdCreateGithubFragment extends CryptoOperationFragment<SaveKe mStatus2 = (StatusIndicator) view.findViewById(R.id.linked_status_step2); mStatus3 = (StatusIndicator) view.findViewById(R.id.linked_status_step3); + ((ImageView) view.findViewById(R.id.linked_id_type_icon)).setImageResource(R.drawable.linked_github); + ((ImageView) view.findViewById(R.id.linked_id_certified_icon)).setImageResource(R.drawable.octo_link_24dp); + mLinkedIdTitle = (TextView) view.findViewById(R.id.linked_id_title); + mLinkedIdComment = (TextView) view.findViewById(R.id.linked_id_comment); + view.findViewById(R.id.button_send).setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { - step1GetOAuthToken(); + step1GetOAuthCode(); } }); @@ -95,48 +118,62 @@ public class LinkedIdCreateGithubFragment extends CryptoOperationFragment<SaveKe } @Override - public void onResume() { - super.onResume(); + public void onActivityCreated(@Nullable Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); LinkedIdWizard wizard = (LinkedIdWizard) getActivity(); mFingerprint = wizard.mFingerprint; mMasterKeyId = wizard.mMasterKeyId; + } + + private void step1GetOAuthCode() { + + mStatus1.setDisplayedChild(1); + mStatus2.setDisplayedChild(0); + mStatus3.setDisplayedChild(0); + + mButtonContainer.setDisplayedChild(1); + + new Handler().postDelayed(new Runnable() { + @Override + public void run() { + oAuthRequest("github.com/login/oauth/authorize", "7a011b66275f244d3f21", "gist"); + } + }, 300); + + } + + private void step1GetOAuthToken() { - final String oAuthCode = wizard.oAuthGetCode(); - final String oAuthState = wizard.oAuthGetState(); - if (oAuthCode == null) { + if (mOAuthCode == null) { Log.d(Constants.TAG, "no code"); return; } - final String gistText = GithubResource.generate(wizard, mFingerprint); + Activity activity = getActivity(); + if (activity == null) { + return; + } + + // this is only good once! + final String oAuthCode = mOAuthCode, oAuthState = mOAuthState; + mOAuthCode = null; + mOAuthState = null; - Log.d(Constants.TAG, "got code: " + oAuthCode); + final String gistText = GithubResource.generate(activity, mFingerprint); new AsyncTask<Void,Void,JSONObject>() { @Override protected JSONObject doInBackground(Void... dummy) { try { - long timer = System.currentTimeMillis(); - JSONObject params = new JSONObject(); params.put("client_id", "7a011b66275f244d3f21"); params.put("client_secret", "eaced8a6655719d8c6848396de97b3f5d7a89fec"); params.put("code", oAuthCode); params.put("state", oAuthState); - JSONObject result = jsonHttpRequest("https://github.com/login/oauth/access_token", params, null); - - // ux flow: this operation should take at last a second - timer = System.currentTimeMillis() -timer; - if (timer < 1000) try { - Thread.sleep(1000 -timer); - } catch (InterruptedException e) { - // never mind - } - - return result; + return jsonHttpRequest("https://github.com/login/oauth/access_token", params, null); } catch (IOException e) { Log.e(Constants.TAG, "error in request", e); @@ -165,29 +202,6 @@ public class LinkedIdCreateGithubFragment extends CryptoOperationFragment<SaveKe } - private void step1GetOAuthToken() { - - mStatus1.setDisplayedChild(1); - mStatus2.setDisplayedChild(0); - mStatus3.setDisplayedChild(0); - - mButtonContainer.setDisplayedChild(1); - - new Handler().postDelayed(new Runnable() { - @Override - public void run() { - - LinkedIdWizard wizard = (LinkedIdWizard) getActivity(); - if (wizard == null) { - return; - } - wizard.oAuthRequest("github.com/login/oauth/authorize", "7a011b66275f244d3f21", "gist"); - - } - }, 250); - - } - private void step2PostGist(final String accessToken, final String gistText) { mStatus2.setDisplayedChild(1); @@ -249,6 +263,8 @@ public class LinkedIdCreateGithubFragment extends CryptoOperationFragment<SaveKe URI uri = URI.create("https://gist.github.com/" + gistLogin + "/" + gistId); GithubResource resource = GithubResource.create(uri); + revokeToken(accessToken); + mStatus2.setDisplayedChild(2); step3EditKey(resource); @@ -262,8 +278,35 @@ public class LinkedIdCreateGithubFragment extends CryptoOperationFragment<SaveKe } + private void revokeToken(final String token) { + + new AsyncTask<Void,Void,Void>() { + @Override + protected Void doInBackground(Void... dummy) { + try { + HttpsURLConnection nection = (HttpsURLConnection) new URL( + "https://api.github.com/applications/7a011b66275f244d3f21/tokens/" + token) + .openConnection(); + nection.setRequestMethod("DELETE"); + nection.connect(); + } catch (IOException e) { + // nvm + } + return null; + } + }.execute(); + + } + private void step3EditKey(final GithubResource resource) { + // set item data while we're there + { + Context context = getActivity(); + mLinkedIdTitle.setText(resource.getDisplayTitle(context)); + mLinkedIdComment.setText(resource.getDisplayComment(context)); + } + mStatus3.setDisplayedChild(1); new Handler().postDelayed(new Runnable() { @@ -291,6 +334,23 @@ public class LinkedIdCreateGithubFragment extends CryptoOperationFragment<SaveKe @Override public void onCryptoOperationSuccess(EditKeyResult result) { mStatus3.setDisplayedChild(2); + mButtonContainer.setDisplayedChild(2); + + new Handler().postDelayed(new Runnable() { + @Override + public void run() { + Activity activity = getActivity(); + Intent intent = new Intent(activity, ViewKeyActivity.class); + intent.setData(KeyRings.buildGenericKeyRingUri(mMasterKeyId)); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + mButtonContainer.getCurrentView().setTransitionName("linked_item"); + activity.finishAfterTransition(); + } else { + activity.finish(); + } + } + }, 1000); } @Override @@ -305,6 +365,72 @@ public class LinkedIdCreateGithubFragment extends CryptoOperationFragment<SaveKe mStatus3.setDisplayedChild(3); } + + private String mOAuthCode, mOAuthState; + + @SuppressLint("SetJavaScriptEnabled") // trusted https website, it's ok + public void oAuthRequest(String hostAndPath, String clientId, String scope) { + + Activity activity = getActivity(); + if (activity == null) { + return; + } + + byte[] buf = new byte[16]; + new Random().nextBytes(buf); + mOAuthState = new String(Hex.encode(buf)); + + final Dialog auth_dialog = new Dialog(activity); + auth_dialog.setContentView(R.layout.oauth_webview); + WebView web = (WebView) auth_dialog.findViewById(R.id.web_view); + web.getSettings().setJavaScriptEnabled(true); + web.setWebViewClient(new WebViewClient() { + + boolean authComplete = false; + + @Override + public boolean shouldOverrideUrlLoading(WebView view, String url) { + Uri uri = Uri.parse(url); + if ("oauth-openkeychain".equals(uri.getScheme()) && !authComplete) { + authComplete = true; + + if (uri.getQueryParameter("error") != null) { + Log.i(Constants.TAG, "ACCESS_DENIED_HERE"); + auth_dialog.dismiss(); + return true; + } + + // check if mOAuthState == queryParam[state] + mOAuthCode = uri.getQueryParameter("code"); + + Log.d(Constants.TAG, "got ok response, code is " + mOAuthCode); + + auth_dialog.dismiss(); + return true; + } + return false; + } + + }); + + auth_dialog.setTitle("GitHub Authorization"); + auth_dialog.setCancelable(true); + auth_dialog.setOnDismissListener(new OnDismissListener() { + @Override + public void onDismiss(DialogInterface dialog) { + step1GetOAuthToken(); + } + }); + auth_dialog.show(); + + web.loadUrl("https://" + hostAndPath + + "?client_id=" + clientId + + "&scope=" + scope + + "&redirect_uri=oauth-openkeychain://linked/" + + "&state=" + mOAuthState); + + } + private static JSONObject jsonHttpRequest(String url, JSONObject params, String accessToken) throws IOException { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdWizard.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdWizard.java index 3441bb399..2c29d1d77 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdWizard.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdWizard.java @@ -17,10 +17,8 @@ package org.sufficientlysecure.keychain.ui.linked; -import java.util.Random; import android.content.Context; -import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.support.v4.app.Fragment; @@ -28,7 +26,6 @@ import android.support.v4.app.FragmentTransaction; import android.view.View; import android.view.inputmethod.InputMethodManager; -import org.spongycastle.util.encoders.Hex; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException; @@ -36,8 +33,6 @@ import org.sufficientlysecure.keychain.provider.CachedPublicKeyRing; import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.ui.base.BaseActivity; -import org.sufficientlysecure.keychain.ui.util.Notify; -import org.sufficientlysecure.keychain.ui.util.Notify.Style; import org.sufficientlysecure.keychain.util.Log; public class LinkedIdWizard extends BaseActivity { @@ -131,53 +126,4 @@ public class LinkedIdWizard extends BaseActivity { inputManager.hideSoftInputFromWindow(v.getWindowToken(), 0); } - private String mOAuthCode, mOAuthState; - - @Override - protected void onNewIntent(Intent intent) { - super.onNewIntent(intent); - - Uri uri = intent.getData(); - Log.d(Constants.TAG, "received oauth uri: " + uri); - if (mOAuthState != null && uri != null) { - String state = uri.getQueryParameter("state"); - if (!mOAuthState.equalsIgnoreCase(state)) { - Notify.create(this, "OAuth State Error!", Style.ERROR).show(); - return; - } - mOAuthCode = uri.getQueryParameter("code"); - } - - } - - public String oAuthGetCode() { - try { - return mOAuthCode; - } finally { - mOAuthCode = null; - } - } - - public String oAuthGetState() { - return mOAuthState; - } - - public void oAuthRequest(String hostAndPath, String clientId, String scope) { - - byte[] buf = new byte[16]; - new Random().nextBytes(buf); - mOAuthState = new String(Hex.encode(buf)); - - Intent intent = new Intent( - Intent.ACTION_VIEW, - Uri.parse("https://" + hostAndPath + - "?client_id=" + clientId + - "&scope=" + scope + - "&redirect_uri=oauth-openkeychain://linked/" + - "&state=" + mOAuthState)); - - startActivity(intent); - - } - } diff --git a/OpenKeychain/src/main/res/layout/linked_create_github_fragment.xml b/OpenKeychain/src/main/res/layout/linked_create_github_fragment.xml index 276aaff54..e15f29eb8 100644 --- a/OpenKeychain/src/main/res/layout/linked_create_github_fragment.xml +++ b/OpenKeychain/src/main/res/layout/linked_create_github_fragment.xml @@ -1,7 +1,8 @@ <?xml version="1.0" encoding="UTF-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" - android:layout_height="match_parent"> + android:layout_height="match_parent" + xmlns:custom="http://schemas.android.com/apk/res-auto"> <ScrollView android:layout_width="match_parent" @@ -122,14 +123,16 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/button_container" - android:outAnimation="@anim/fade_out"> + android:layout_marginTop="16dp" + android:layout_marginBottom="16dp" + android:inAnimation="@anim/fade_in" + android:outAnimation="@anim/fade_out" + custom:initialView="2"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" - android:layout_marginTop="16dp" - android:layout_marginBottom="16dp" style="?android:buttonBarButtonStyle" android:drawableLeft="@drawable/link_24dp" android:drawableStart="@drawable/link_24dp" @@ -142,6 +145,8 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" /> + <include layout="@layout/linked_id_item" /> + </org.sufficientlysecure.keychain.ui.widget.ToolableViewAnimator> </LinearLayout> diff --git a/OpenKeychain/src/main/res/layout/loader_layout.xml b/OpenKeychain/src/main/res/layout/loader_layout.xml index 61dd48635..6f94384dc 100644 --- a/OpenKeychain/src/main/res/layout/loader_layout.xml +++ b/OpenKeychain/src/main/res/layout/loader_layout.xml @@ -4,7 +4,6 @@ android:layout_height="match_parent" android:orientation="vertical"> - <!--rebuild functionality of ListFragment --> <LinearLayout android:id="@+id/loader_progress" android:orientation="vertical" @@ -15,15 +14,8 @@ <ProgressBar style="?android:attr/progressBarStyleLarge" android:layout_width="wrap_content" - android:layout_height="wrap_content" /> - - <TextView - android:layout_width="wrap_content" android:layout_height="wrap_content" - android:textAppearance="?android:attr/textAppearanceSmall" - android:text="" - android:paddingTop="4dip" - android:singleLine="true" /> + android:gravity="center" /> </LinearLayout> diff --git a/OpenKeychain/src/main/res/layout/oauth_webview.xml b/OpenKeychain/src/main/res/layout/oauth_webview.xml new file mode 100644 index 000000000..f00fdfd17 --- /dev/null +++ b/OpenKeychain/src/main/res/layout/oauth_webview.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <WebView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:id="@+id/web_view"/> + +</LinearLayout>
\ No newline at end of file diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index ff126a7a5..fcf84da53 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -82,7 +82,6 @@ <string name="btn_export_to_server">"Upload To Keyserver"</string> <string name="btn_next">"Next"</string> <string name="btn_back">"Back"</string> - <string name="btn_cancel">"Cancel"</string> <string name="btn_no">"No"</string> <string name="btn_match">"Fingerprints match"</string> <string name="btn_share_encrypted_signed">"Encrypt/sign and share text"</string> @@ -1591,10 +1590,10 @@ <string name="linked_verified_github">"The link between this GitHub account and key was securely verified. <b>If you believe the account is genuine</b>, confirm this verification with your key."</string> <string name="linked_verified_dns">"The link between this Domain Name and key was securely verified. <b>If you believe the Domain is genuine</b>, confirm this verification with your key."</string> <string name="linked_verified_twitter">"The link between this Twitter account and key was securely verified. <b>If you believe the account is genuine</b>, confirm this verification with your key."</string> - <string name="linked_verified_secret_https">"The link between your Website and key was securely verified. Everything looks in order."</string> - <string name="linked_verified_secret_github">"The link between your GitHub account and key was securely verified. Everything looks in order."</string> - <string name="linked_verified_secret_dns">"The link between your Domain Name and key was securely verified. Everything looks in order."</string> - <string name="linked_verified_secret_twitter">"The link between this Twitter account and key was securely verified. Everything looks in order."</string> + <string name="linked_verified_secret_https">"Everything looks in order."</string> + <string name="linked_verified_secret_github">"Everything looks in order."</string> + <string name="linked_verified_secret_dns">"Everything looks in order."</string> + <string name="linked_verified_secret_twitter">"Everything looks in order."</string> <plurals name="linked_id_expand"> <item quantity="one">"There is one more unknown identity type"</item> |