support github resource (pa)
This commit is contained in:
@@ -777,6 +777,7 @@ public abstract class OperationResult implements Parcelable {
|
||||
MSG_LV_FETCH_ERROR (LogLevel.ERROR, R.string.msg_lv_fetch_error),
|
||||
MSG_LV_FETCH_ERROR_URL (LogLevel.ERROR, R.string.msg_lv_fetch_error_url),
|
||||
MSG_LV_FETCH_ERROR_IO (LogLevel.ERROR, R.string.msg_lv_fetch_error_io),
|
||||
MSG_LV_FETCH_ERROR_FORMAT(LogLevel.ERROR, R.string.msg_lv_fetch_error_format),
|
||||
|
||||
//export log
|
||||
MSG_EXPORT_LOG(LogLevel.START,R.string.msg_export_log_start),
|
||||
|
||||
@@ -2,6 +2,12 @@ package org.sufficientlysecure.keychain.pgp.linked;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.apache.http.client.methods.HttpRequestBase;
|
||||
import org.apache.http.impl.client.DefaultHttpClient;
|
||||
import org.apache.http.params.BasicHttpParams;
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.operations.results.LinkedVerifyResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
|
||||
@@ -9,6 +15,10 @@ import org.sufficientlysecure.keychain.operations.results.OperationResult.Operat
|
||||
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
|
||||
import org.sufficientlysecure.keychain.util.Log;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URI;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map.Entry;
|
||||
@@ -117,4 +127,49 @@ public abstract class LinkedCookieResource extends LinkedResource {
|
||||
|
||||
}
|
||||
|
||||
public static String getResponseBody(HttpRequestBase request) throws IOException, HttpStatusException {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
DefaultHttpClient httpClient = new DefaultHttpClient(new BasicHttpParams());
|
||||
HttpResponse response = httpClient.execute(request);
|
||||
int statusCode = response.getStatusLine().getStatusCode();
|
||||
String reason = response.getStatusLine().getReasonPhrase();
|
||||
|
||||
if (statusCode != 200) {
|
||||
throw new HttpStatusException(statusCode, reason);
|
||||
}
|
||||
|
||||
HttpEntity entity = response.getEntity();
|
||||
InputStream inputStream = entity.getContent();
|
||||
|
||||
BufferedReader bReader = new BufferedReader(
|
||||
new InputStreamReader(inputStream, "UTF-8"), 8);
|
||||
String line;
|
||||
while ((line = bReader.readLine()) != null) {
|
||||
sb.append(line);
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static class HttpStatusException extends Throwable {
|
||||
|
||||
private final int mStatusCode;
|
||||
private final String mReason;
|
||||
|
||||
HttpStatusException(int statusCode, String reason) {
|
||||
mStatusCode = statusCode;
|
||||
mReason = reason;
|
||||
}
|
||||
|
||||
public int getStatus() {
|
||||
return mStatusCode;
|
||||
}
|
||||
|
||||
public String getReason() {
|
||||
return mReason;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
package org.sufficientlysecure.keychain.pgp.linked.resources;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.DrawableRes;
|
||||
import android.support.annotation.StringRes;
|
||||
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.R;
|
||||
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
|
||||
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
|
||||
import org.sufficientlysecure.keychain.pgp.linked.LinkedCookieResource;
|
||||
import org.sufficientlysecure.keychain.util.Log;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
||||
public class GithubResource extends LinkedCookieResource {
|
||||
|
||||
final String mHandle;
|
||||
final String mGistId;
|
||||
|
||||
GithubResource(Set<String> flags, HashMap<String,String> params, URI uri,
|
||||
String handle, String gistId) {
|
||||
super(flags, params, uri);
|
||||
|
||||
mHandle = handle;
|
||||
mGistId = gistId;
|
||||
}
|
||||
|
||||
public static String generateText (Context context, byte[] fingerprint) {
|
||||
String cookie = LinkedCookieResource.generate(context, fingerprint);
|
||||
|
||||
return String.format(context.getResources().getString(R.string.linked_id_github_text), cookie);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String fetchResource (OperationLog log, int indent) {
|
||||
|
||||
log.add(LogType.MSG_LV_FETCH, indent, mSubUri.toString());
|
||||
indent += 1;
|
||||
|
||||
try {
|
||||
|
||||
HttpGet httpGet = new HttpGet("https://api.github.com/gists/" + mGistId);
|
||||
|
||||
String response = getResponseBody(httpGet);
|
||||
|
||||
JSONObject obj = new JSONObject(response);
|
||||
|
||||
JSONObject owner = obj.getJSONObject("owner");
|
||||
if (!mHandle.equals(owner.getString("login"))) {
|
||||
log.add(LogType.MSG_LV_FETCH_ERROR_FORMAT, indent);
|
||||
return null;
|
||||
}
|
||||
|
||||
JSONObject files = obj.getJSONObject("files");
|
||||
Iterator<String> it = files.keys();
|
||||
if (it.hasNext()) {
|
||||
// TODO can there be multiple candidates?
|
||||
JSONObject file = files.getJSONObject(it.next());
|
||||
return file.getString("content");
|
||||
}
|
||||
|
||||
} catch (HttpStatusException e) {
|
||||
// log verbose output to logcat
|
||||
Log.e(Constants.TAG, "http error (" + e.getStatus() + "): " + e.getReason());
|
||||
log.add(LogType.MSG_LV_FETCH_ERROR, indent, Integer.toString(e.getStatus()));
|
||||
} catch (MalformedURLException e) {
|
||||
log.add(LogType.MSG_LV_FETCH_ERROR_URL, indent);
|
||||
} catch (IOException e) {
|
||||
Log.e(Constants.TAG, "io error", e);
|
||||
log.add(LogType.MSG_LV_FETCH_ERROR_IO, indent);
|
||||
} catch (JSONException e) {
|
||||
Log.e(Constants.TAG, "json error", e);
|
||||
log.add(LogType.MSG_LV_FETCH_ERROR_FORMAT, indent);
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
public static GithubResource create(Set<String> flags, HashMap<String,String> params, URI uri) {
|
||||
|
||||
// no params or flags
|
||||
if (!flags.isEmpty() || !params.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Pattern p = Pattern.compile("https://gist\\.github\\.com/([a-zA-Z0-9_]+)/([0-9a-f]+)");
|
||||
Matcher match = p.matcher(uri.toString());
|
||||
if (!match.matches()) {
|
||||
return null;
|
||||
}
|
||||
String handle = match.group(1);
|
||||
String gistId = match.group(2);
|
||||
|
||||
return new GithubResource(flags, params, uri, handle, gistId);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @DrawableRes
|
||||
int getDisplayIcon() {
|
||||
return R.drawable.github;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @StringRes
|
||||
int getVerifiedText() {
|
||||
return R.string.linked_verified_github;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisplayTitle(Context context) {
|
||||
return "Github";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisplayComment(Context context) {
|
||||
return mHandle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isViewable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Intent getViewIntent() {
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
intent.setData(Uri.parse(mSubUri.toString()));
|
||||
return intent;
|
||||
}
|
||||
}
|
||||
@@ -9,27 +9,19 @@ import android.util.Log;
|
||||
|
||||
import com.textuality.keybase.lib.JWalk;
|
||||
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.client.methods.HttpRequestBase;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.apache.http.impl.client.DefaultHttpClient;
|
||||
import org.apache.http.params.BasicHttpParams;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.R;
|
||||
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
|
||||
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
|
||||
import org.sufficientlysecure.keychain.pgp.linked.LinkedCookieResource;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URI;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
@@ -61,7 +53,7 @@ public class TwitterResource extends LinkedCookieResource {
|
||||
return null;
|
||||
}
|
||||
|
||||
Pattern p = Pattern.compile("https://twitter.com/([a-zA-Z0-9_]+)/status/([0-9]+)");
|
||||
Pattern p = Pattern.compile("https://twitter\\.com/([a-zA-Z0-9_]+)/status/([0-9]+)");
|
||||
Matcher match = p.matcher(uri.toString());
|
||||
if (!match.matches()) {
|
||||
return null;
|
||||
@@ -102,16 +94,25 @@ public class TwitterResource extends LinkedCookieResource {
|
||||
|
||||
JSONObject user = obj.getJSONObject("user");
|
||||
if (!mHandle.equalsIgnoreCase(user.getString("screen_name"))) {
|
||||
log.add(LogType.MSG_LV_FETCH_ERROR_FORMAT, indent);
|
||||
return null;
|
||||
}
|
||||
|
||||
// update the results with the body of the response
|
||||
return obj.getString("text");
|
||||
} catch (HttpStatusException e) {
|
||||
// log verbose output to logcat
|
||||
Log.e(Constants.TAG, "http error (" + e.getStatus() + "): " + e.getReason());
|
||||
log.add(LogType.MSG_LV_FETCH_ERROR, indent, Integer.toString(e.getStatus()));
|
||||
} catch (IOException e) {
|
||||
Log.e(Constants.TAG, "io error", e);
|
||||
log.add(LogType.MSG_LV_FETCH_ERROR_IO, indent);
|
||||
} catch (JSONException e) {
|
||||
Log.e(Constants.TAG, "json error parsing stream", e);
|
||||
return null;
|
||||
Log.e(Constants.TAG, "json error", e);
|
||||
log.add(LogType.MSG_LV_FETCH_ERROR_FORMAT, indent);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -184,10 +185,11 @@ public class TwitterResource extends LinkedCookieResource {
|
||||
|
||||
// update the results with the body of the response
|
||||
return null;
|
||||
} catch (JSONException e) {
|
||||
Log.e(Constants.TAG, "json error parsing stream", e);
|
||||
return null;
|
||||
} catch (JSONException | HttpStatusException | IOException e) {
|
||||
Log.e(Constants.TAG, "exception parsing stream", e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String authToken;
|
||||
@@ -217,42 +219,13 @@ public class TwitterResource extends LinkedCookieResource {
|
||||
authToken = JWalk.getString(rawAuthorization, "access_token");
|
||||
return authToken;
|
||||
|
||||
} catch (UnsupportedEncodingException | JSONException | IllegalStateException ex) {
|
||||
Log.e(Constants.TAG, "auth token fetching error", ex);
|
||||
} catch (JSONException | IllegalStateException | HttpStatusException | IOException ex) {
|
||||
Log.e(Constants.TAG, "exception fetching auth token", ex);
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static String getResponseBody(HttpRequestBase request) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
try {
|
||||
|
||||
DefaultHttpClient httpClient = new DefaultHttpClient(new BasicHttpParams());
|
||||
HttpResponse response = httpClient.execute(request);
|
||||
int statusCode = response.getStatusLine().getStatusCode();
|
||||
String reason = response.getStatusLine().getReasonPhrase();
|
||||
|
||||
if (statusCode == 200) {
|
||||
|
||||
HttpEntity entity = response.getEntity();
|
||||
InputStream inputStream = entity.getContent();
|
||||
|
||||
BufferedReader bReader = new BufferedReader(
|
||||
new InputStreamReader(inputStream, "UTF-8"), 8);
|
||||
String line;
|
||||
while ((line = bReader.readLine()) != null) {
|
||||
sb.append(line);
|
||||
}
|
||||
} else {
|
||||
sb.append(reason);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Log.e(Constants.TAG, "http request error", e);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static String rot13(String input) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < input.length(); i++) {
|
||||
|
||||
BIN
OpenKeychain/src/main/res/drawable/github.png
Normal file
BIN
OpenKeychain/src/main/res/drawable/github.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.7 KiB |
@@ -1178,6 +1178,7 @@
|
||||
<string name="msg_lv_fetch_error">"Server error (HTTP %s)"</string>
|
||||
<string name="msg_lv_fetch_error_url">"URL is malformed!"</string>
|
||||
<string name="msg_lv_fetch_error_io">"IO Error!"</string>
|
||||
<string name="msg_lv_fetch_error_format">"Format error!"</string>
|
||||
|
||||
<string name="msg_acc_saved">"Account saved"</string>
|
||||
|
||||
@@ -1307,6 +1308,7 @@
|
||||
<string name="linked_create_verify">"Verify"</string>
|
||||
<string name="linked_text_clipboard">Text has been copied to clipboard</string>
|
||||
<string name="linked_verified_https">"The Website has been fetched and verified."</string>
|
||||
<string name="linked_verified_github">"The Gist has been fetched and verified."</string>
|
||||
<string name="linked_verified_dns">"The DNS record has been fetched and verified."</string>
|
||||
<string name="linked_verified_twitter">"The Tweet has been fetched and verified."</string>
|
||||
<plurals name="linked_id_expand">
|
||||
@@ -1317,6 +1319,7 @@
|
||||
<string name="linked_select_1">"A \'linked identity\' connects your pgp key to a resource on the web."</string>
|
||||
<string name="linked_select_2">"Please select a type:"</string>
|
||||
<string name="linked_id_generic_text">"This file claims ownership of the OpenPGP key with long id %2$s.\n\nCookie for proof:\n%1$s"</string>
|
||||
<string name="linked_id_github_text">"This Gist confirms the Linked Identity in my OpenPGP key, and links it to this Github account.\n\nCookie for proof:\n%1$s"</string>
|
||||
<string name="linked_verifying">"Verifying…"</string>
|
||||
<string name="linked_verify_success">"Verified!"</string>
|
||||
<string name="linked_verify_error">"Verification error!"</string>
|
||||
|
||||
Reference in New Issue
Block a user