added Facebook links support, reworked Preferences
This commit is contained in:
parent
a0b46b0d3b
commit
f29280bbb2
|
@ -681,6 +681,22 @@
|
|||
<data android:pathPattern="/pks/lookup.*" />
|
||||
</intent-filter>
|
||||
|
||||
<!-- VIEW from facebook public key urls opened in a browser -->
|
||||
<intent-filter android:label="@string/intent_import_key">
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
|
||||
<data android:scheme="https" />
|
||||
<data android:scheme="http" />
|
||||
|
||||
<data android:host="www.facebook.com" />
|
||||
<data android:host="facebook.com" />
|
||||
|
||||
<data android:pathPattern="/..*/publickey/download" />
|
||||
</intent-filter>
|
||||
|
||||
<!-- IMPORT_KEY with files TODO: does this work? -->
|
||||
<intent-filter android:label="@string/intent_import_key">
|
||||
<action android:name="org.sufficientlysecure.keychain.action.IMPORT_KEY" />
|
||||
|
|
|
@ -48,6 +48,9 @@ public class CloudSearch {
|
|||
if (cloudPrefs.searchKeybase) {
|
||||
servers.add(new KeybaseKeyserver(proxy));
|
||||
}
|
||||
if (cloudPrefs.searchFacebook) {
|
||||
servers.add(new FacebookKeyserver(proxy));
|
||||
}
|
||||
final ImportKeysList results = new ImportKeysList(servers.size());
|
||||
|
||||
ArrayList<Thread> searchThreads = new ArrayList<>();
|
||||
|
|
|
@ -0,0 +1,197 @@
|
|||
/*
|
||||
* Copyright (C) 2015 Dominik Schürmann <dominik@dominikschuermann.de>
|
||||
* Copyright (C) 2015 Vincent Breitmoser <v.breitmoser@mugenguild.com>
|
||||
* Copyright (C) 2015 Adithya Abraham Philip <adithyaphilip@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.sufficientlysecure.keychain.keyimport;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import com.squareup.okhttp.OkHttpClient;
|
||||
import com.squareup.okhttp.Request;
|
||||
import com.squareup.okhttp.Response;
|
||||
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.pgp.PgpHelper;
|
||||
import org.sufficientlysecure.keychain.pgp.UncachedKeyRing;
|
||||
import org.sufficientlysecure.keychain.pgp.UncachedPublicKey;
|
||||
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
|
||||
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
|
||||
import org.sufficientlysecure.keychain.util.Log;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.Proxy;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
public class FacebookKeyserver extends Keyserver {
|
||||
|
||||
private static final String FB_KEY_URL_FORMAT
|
||||
= "https://www.facebook.com/%s/publickey/download";
|
||||
private static final String FB_HOST = "facebook.com";
|
||||
private static final String FB_HOST_WWW = "www." + FB_HOST;
|
||||
|
||||
public static final String FB_URL = "https://" + FB_HOST_WWW;
|
||||
|
||||
public static final String ORIGIN = FB_URL;
|
||||
|
||||
private final Proxy mProxy;
|
||||
|
||||
public FacebookKeyserver(Proxy proxy) {
|
||||
mProxy = proxy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ImportKeysListEntry> search(String fbUsername)
|
||||
throws QueryFailedException, QueryNeedsRepairException {
|
||||
List<ImportKeysListEntry> entry = new ArrayList<>(1);
|
||||
|
||||
String data = get(fbUsername);
|
||||
// if we're here that means key retrieval succeeded,
|
||||
// would have thrown an exception otherwise
|
||||
try {
|
||||
UncachedKeyRing keyRing = UncachedKeyRing.decodeFromData(data.getBytes());
|
||||
try {
|
||||
entry.add(getEntry(keyRing, fbUsername));
|
||||
} catch (UnsupportedOperationException e) {
|
||||
Log.e(Constants.TAG, "Parsing retrieved Facebook key failed!");
|
||||
}
|
||||
} catch (PgpGeneralException | IOException e) {
|
||||
Log.e(Constants.TAG, "Failed parsing key from Facebook during search", e);
|
||||
throw new QueryFailedException("No valid key found on Facebook");
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String get(String fbUsername) throws QueryFailedException {
|
||||
Log.d(Constants.TAG, "FacebookKeyserver get: " + fbUsername + " using Proxy: " + mProxy);
|
||||
|
||||
String data = query(fbUsername);
|
||||
|
||||
if (data == null) {
|
||||
throw new QueryFailedException("data is null");
|
||||
}
|
||||
|
||||
Matcher matcher = PgpHelper.PGP_PUBLIC_KEY.matcher(data);
|
||||
if (matcher.find()) {
|
||||
return matcher.group(1);
|
||||
}
|
||||
throw new QueryFailedException("data is null");
|
||||
}
|
||||
|
||||
private String query(String fbUsername) throws QueryFailedException {
|
||||
try {
|
||||
String request = String.format(FB_KEY_URL_FORMAT, fbUsername);
|
||||
Log.d(Constants.TAG, "fetching from Facebook with: " + request + " proxy: " + mProxy);
|
||||
|
||||
OkHttpClient client = new OkHttpClient();
|
||||
client.setProxy(mProxy);
|
||||
|
||||
URL url = new URL(request);
|
||||
|
||||
Response response = client.newCall(new Request.Builder().url(url).build()).execute();
|
||||
|
||||
// contains body both in case of success or failure
|
||||
String responseBody = response.body().string();
|
||||
|
||||
if (response.isSuccessful()) {
|
||||
return responseBody;
|
||||
} else {
|
||||
// probably a 404 indicating that the key does not exist
|
||||
throw new QueryFailedException("key for " + fbUsername + " not found on Facebook");
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
Log.e(Constants.TAG, "IOException at Facebook key download", e);
|
||||
throw new QueryFailedException("Cannot connect to Facebook. "
|
||||
+ "Check your Internet connection!"
|
||||
+ (mProxy == Proxy.NO_PROXY ? "" : " Using proxy " + mProxy));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(String armoredKey) throws AddKeyException {
|
||||
// Implementing will require usage of FB API
|
||||
throw new UnsupportedOperationException("Uploading keys not supported yet");
|
||||
}
|
||||
|
||||
/**
|
||||
* Facebook returns the entire key even during our searching phase.
|
||||
*
|
||||
* @throws UnsupportedOperationException if the key could not be parsed
|
||||
*/
|
||||
@NonNull
|
||||
public static ImportKeysListEntry getEntry(UncachedKeyRing ring, String fbUsername)
|
||||
throws UnsupportedOperationException {
|
||||
ImportKeysListEntry entry = new ImportKeysListEntry();
|
||||
entry.setSecretKey(false); // keys imported from Facebook must be public
|
||||
entry.addOrigin(ORIGIN);
|
||||
|
||||
// so we can query for the Facebook username directly, and to identify the source to
|
||||
// download the key from
|
||||
entry.setFbUsername(fbUsername);
|
||||
|
||||
UncachedPublicKey key = ring.getPublicKey();
|
||||
|
||||
entry.setPrimaryUserId(key.getPrimaryUserIdWithFallback());
|
||||
entry.setUserIds(key.getUnorderedUserIds());
|
||||
entry.updateMergedUserIds();
|
||||
|
||||
entry.setPrimaryUserId(key.getPrimaryUserIdWithFallback());
|
||||
|
||||
entry.setKeyId(key.getKeyId());
|
||||
entry.setKeyIdHex(KeyFormattingUtils.convertKeyIdToHex(key.getKeyId()));
|
||||
|
||||
entry.setFingerprintHex(KeyFormattingUtils.convertFingerprintToHex(key.getFingerprint()));
|
||||
|
||||
|
||||
try {
|
||||
if (key.isEC()) { // unsupported key format (ECDH or ECDSA)
|
||||
Log.e(Constants.TAG, "ECDH/ECDSA key - not supported.");
|
||||
throw new UnsupportedOperationException(
|
||||
"ECDH/ECDSA keys not supported yet");
|
||||
}
|
||||
entry.setBitStrength(key.getBitStrength());
|
||||
final int algorithm = key.getAlgorithm();
|
||||
entry.setAlgorithm(KeyFormattingUtils.getAlgorithmInfo(algorithm, key.getBitStrength(),
|
||||
key.getCurveOid()));
|
||||
} catch (NumberFormatException | NullPointerException e) {
|
||||
Log.e(Constants.TAG, "Conversion for bit size, algorithm, or creation date failed.", e);
|
||||
// can't use this key
|
||||
throw new UnsupportedOperationException(
|
||||
"Conversion for bit size, algorithm, or creation date failed.");
|
||||
}
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
public static String getUsernameFromUri(Uri uri) {
|
||||
// path pattern is /username/publickey/download
|
||||
return uri.getPathSegments().get(0);
|
||||
}
|
||||
|
||||
public static boolean isFacebookHost(Uri uri) {
|
||||
String host = uri.getHost();
|
||||
return host.equalsIgnoreCase(FB_HOST) || host.equalsIgnoreCase(FB_HOST_WWW);
|
||||
}
|
||||
}
|
|
@ -77,9 +77,15 @@ public class ImportKeysList extends ArrayList<ImportKeysListEntry> {
|
|||
for (String origin : incoming.getOrigins()) {
|
||||
existing.addOrigin(origin);
|
||||
|
||||
// to work properly, Keybase-sourced entries need to pass along the extra
|
||||
if (KeybaseKeyserver.ORIGIN.equals(origin)) {
|
||||
existing.setExtraData(incoming.getExtraData());
|
||||
// to work properly, Keybase-sourced/Facebook-sourced entries need to pass along the
|
||||
// identifying name/id
|
||||
if (incoming.getKeybaseName() != null) {
|
||||
existing.setKeybaseName(incoming.getKeybaseName());
|
||||
// one of the origins is not a HKP keyserver
|
||||
incomingFromHkpServer = false;
|
||||
}
|
||||
if (incoming.getFbUsername() != null) {
|
||||
existing.setFbUsername(incoming.getFbUsername());
|
||||
// one of the origins is not a HKP keyserver
|
||||
incomingFromHkpServer = false;
|
||||
}
|
||||
|
|
|
@ -49,7 +49,8 @@ public class ImportKeysListEntry implements Serializable, Parcelable {
|
|||
private String mAlgorithm;
|
||||
private boolean mSecretKey;
|
||||
private String mPrimaryUserId;
|
||||
private String mExtraData;
|
||||
private String mKeybaseName;
|
||||
private String mFbUsername;
|
||||
private String mQuery;
|
||||
private ArrayList<String> mOrigins;
|
||||
private Integer mHashCode = null;
|
||||
|
@ -81,7 +82,8 @@ public class ImportKeysListEntry implements Serializable, Parcelable {
|
|||
dest.writeString(mAlgorithm);
|
||||
dest.writeByte((byte) (mSecretKey ? 1 : 0));
|
||||
dest.writeByte((byte) (mSelected ? 1 : 0));
|
||||
dest.writeString(mExtraData);
|
||||
dest.writeString(mKeybaseName);
|
||||
dest.writeString(mFbUsername);
|
||||
dest.writeStringList(mOrigins);
|
||||
}
|
||||
|
||||
|
@ -102,7 +104,8 @@ public class ImportKeysListEntry implements Serializable, Parcelable {
|
|||
vr.mAlgorithm = source.readString();
|
||||
vr.mSecretKey = source.readByte() == 1;
|
||||
vr.mSelected = source.readByte() == 1;
|
||||
vr.mExtraData = source.readString();
|
||||
vr.mKeybaseName = source.readString();
|
||||
vr.mFbUsername = source.readString();
|
||||
vr.mOrigins = new ArrayList<>();
|
||||
source.readStringList(vr.mOrigins);
|
||||
|
||||
|
@ -229,12 +232,20 @@ public class ImportKeysListEntry implements Serializable, Parcelable {
|
|||
mPrimaryUserId = uid;
|
||||
}
|
||||
|
||||
public String getExtraData() {
|
||||
return mExtraData;
|
||||
public String getKeybaseName() {
|
||||
return mKeybaseName;
|
||||
}
|
||||
|
||||
public void setExtraData(String extraData) {
|
||||
mExtraData = extraData;
|
||||
public String getFbUsername() {
|
||||
return mFbUsername;
|
||||
}
|
||||
|
||||
public void setKeybaseName(String keybaseName) {
|
||||
mKeybaseName = keybaseName;
|
||||
}
|
||||
|
||||
public void setFbUsername(String fbUsername) {
|
||||
mFbUsername = fbUsername;
|
||||
}
|
||||
|
||||
public String getQuery() {
|
||||
|
|
|
@ -81,8 +81,9 @@ public class KeybaseKeyserver extends Keyserver {
|
|||
entry.setFingerprintHex(fingerprint);
|
||||
|
||||
entry.setKeyIdHex("0x" + match.getKeyID());
|
||||
// store extra info, so we can query for the keybase id directly
|
||||
entry.setExtraData(username);
|
||||
// so we can query for the keybase id directly, and to identify the location from which the
|
||||
// key is to be retrieved
|
||||
entry.setKeybaseName(username);
|
||||
|
||||
final int bitStrength = match.getBitStrength();
|
||||
entry.setBitStrength(bitStrength);
|
||||
|
|
|
@ -21,7 +21,6 @@ package org.sufficientlysecure.keychain.keyimport;
|
|||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.Proxy;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class Keyserver {
|
||||
|
|
|
@ -32,24 +32,39 @@ public class ParcelableKeyRing implements Parcelable {
|
|||
public final String mExpectedFingerprint;
|
||||
public final String mKeyIdHex;
|
||||
public final String mKeybaseName;
|
||||
public final String mFbUsername;
|
||||
|
||||
public ParcelableKeyRing(byte[] bytes) {
|
||||
mBytes = bytes;
|
||||
mExpectedFingerprint = null;
|
||||
mKeyIdHex = null;
|
||||
mKeybaseName = null;
|
||||
this(null, bytes, false);
|
||||
}
|
||||
public ParcelableKeyRing(String expectedFingerprint, byte[] bytes) {
|
||||
|
||||
/**
|
||||
* @param disAmbiguator useless parameter intended to distinguish this overloaded constructor
|
||||
* for when null is passed as first two arguments
|
||||
*/
|
||||
public ParcelableKeyRing(String expectedFingerprint, byte[] bytes, boolean disAmbiguator) {
|
||||
mBytes = bytes;
|
||||
mExpectedFingerprint = expectedFingerprint;
|
||||
mKeyIdHex = null;
|
||||
mKeybaseName = null;
|
||||
mFbUsername = null;
|
||||
}
|
||||
public ParcelableKeyRing(String expectedFingerprint, String keyIdHex, String keybaseName) {
|
||||
|
||||
public ParcelableKeyRing(String expectedFingerprint, String keyIdHex) {
|
||||
mBytes = null;
|
||||
mExpectedFingerprint = expectedFingerprint;
|
||||
mKeyIdHex = keyIdHex;
|
||||
mKeybaseName = null;
|
||||
mFbUsername = null;
|
||||
}
|
||||
|
||||
public ParcelableKeyRing(String expectedFingerprint, String keyIdHex, String keybaseName,
|
||||
String fbUsername) {
|
||||
mBytes = null;
|
||||
mExpectedFingerprint = expectedFingerprint;
|
||||
mKeyIdHex = keyIdHex;
|
||||
mKeybaseName = keybaseName;
|
||||
mFbUsername = fbUsername;
|
||||
}
|
||||
|
||||
private ParcelableKeyRing(Parcel source) {
|
||||
|
@ -58,6 +73,7 @@ public class ParcelableKeyRing implements Parcelable {
|
|||
mExpectedFingerprint = source.readString();
|
||||
mKeyIdHex = source.readString();
|
||||
mKeybaseName = source.readString();
|
||||
mFbUsername = source.readString();
|
||||
}
|
||||
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
|
@ -65,6 +81,7 @@ public class ParcelableKeyRing implements Parcelable {
|
|||
dest.writeString(mExpectedFingerprint);
|
||||
dest.writeString(mKeyIdHex);
|
||||
dest.writeString(mKeybaseName);
|
||||
dest.writeString(mFbUsername);
|
||||
}
|
||||
|
||||
public static final Creator<ParcelableKeyRing> CREATOR = new Creator<ParcelableKeyRing>() {
|
||||
|
|
|
@ -38,6 +38,7 @@ import android.support.annotation.NonNull;
|
|||
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.R;
|
||||
import org.sufficientlysecure.keychain.keyimport.FacebookKeyserver;
|
||||
import org.sufficientlysecure.keychain.keyimport.HkpKeyserver;
|
||||
import org.sufficientlysecure.keychain.keyimport.KeybaseKeyserver;
|
||||
import org.sufficientlysecure.keychain.keyimport.Keyserver;
|
||||
|
@ -156,6 +157,7 @@ public class ImportOperation extends BaseOperation<ImportKeyringParcel> {
|
|||
double progSteps = 100.0 / num;
|
||||
|
||||
KeybaseKeyserver keybaseServer = null;
|
||||
FacebookKeyserver facebookServer = null;
|
||||
HkpKeyserver keyServer = null;
|
||||
|
||||
// iterate over all entries
|
||||
|
@ -228,6 +230,12 @@ public class ImportOperation extends BaseOperation<ImportKeyringParcel> {
|
|||
byte[] data = keybaseServer.get(entry.mKeybaseName).getBytes();
|
||||
UncachedKeyRing keybaseKey = UncachedKeyRing.decodeFromData(data);
|
||||
|
||||
if (keybaseKey != null) {
|
||||
log.add(LogType.MSG_IMPORT_FETCH_KEYSERVER_OK, 3);
|
||||
} else {
|
||||
log.add(LogType.MSG_IMPORT_FETCH_ERROR_DECODE, 3);
|
||||
}
|
||||
|
||||
// If there already is a key, merge the two
|
||||
if (key != null && keybaseKey != null) {
|
||||
log.add(LogType.MSG_IMPORT_MERGE, 3);
|
||||
|
@ -247,6 +255,44 @@ public class ImportOperation extends BaseOperation<ImportKeyringParcel> {
|
|||
log.add(LogType.MSG_IMPORT_FETCH_ERROR_KEYSERVER, 3, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// if the key is from Facebook, fetch from there
|
||||
if (entry.mFbUsername != null) {
|
||||
// Make sure we have this cached
|
||||
if (facebookServer == null) {
|
||||
facebookServer = new FacebookKeyserver(proxy);
|
||||
}
|
||||
|
||||
try {
|
||||
log.add(LogType.MSG_IMPORT_FETCH_FACEBOOK, 2, entry.mFbUsername);
|
||||
byte[] data = facebookServer.get(entry.mFbUsername).getBytes();
|
||||
UncachedKeyRing facebookKey = UncachedKeyRing.decodeFromData(data);
|
||||
|
||||
if (facebookKey != null) {
|
||||
log.add(LogType.MSG_IMPORT_FETCH_KEYSERVER_OK, 3);
|
||||
} else {
|
||||
log.add(LogType.MSG_IMPORT_FETCH_ERROR_DECODE, 3);
|
||||
}
|
||||
|
||||
// If there already is a key, merge the two
|
||||
if (key != null && facebookKey != null) {
|
||||
log.add(LogType.MSG_IMPORT_MERGE, 3);
|
||||
facebookKey = key.merge(facebookKey, log, 4);
|
||||
// If the merge didn't fail, use the new merged key
|
||||
if (facebookKey != null) {
|
||||
key = facebookKey;
|
||||
} else {
|
||||
log.add(LogType.MSG_IMPORT_MERGE_ERROR, 4);
|
||||
}
|
||||
} else if (facebookKey != null) {
|
||||
key = facebookKey;
|
||||
}
|
||||
} catch (Keyserver.QueryFailedException e) {
|
||||
// download failed, too bad. just proceed
|
||||
Log.e(Constants.TAG, "query failed", e);
|
||||
log.add(LogType.MSG_IMPORT_FETCH_ERROR_KEYSERVER, 3, e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (key == null) {
|
||||
|
|
|
@ -233,6 +233,18 @@ public abstract class OperationResult implements Parcelable {
|
|||
dest.writeParcelable(mSubResult, 0);
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<SubLogEntryParcel> CREATOR = new Parcelable.Creator<SubLogEntryParcel>() {
|
||||
@Override
|
||||
public SubLogEntryParcel createFromParcel(Parcel in) {
|
||||
return new SubLogEntryParcel(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubLogEntryParcel[] newArray(int size) {
|
||||
return new SubLogEntryParcel[size];
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
StringBuilder getPrintableLogEntry(Resources resources, int indent) {
|
||||
|
||||
|
@ -757,6 +769,7 @@ public abstract class OperationResult implements Parcelable {
|
|||
MSG_IMPORT_FETCH_ERROR_KEYSERVER(LogLevel.ERROR, R.string.msg_import_fetch_error_keyserver),
|
||||
MSG_IMPORT_FETCH_ERROR_KEYSERVER_SECRET (LogLevel.ERROR, R.string.msg_import_fetch_error_keyserver_secret),
|
||||
MSG_IMPORT_FETCH_KEYBASE (LogLevel.INFO, R.string.msg_import_fetch_keybase),
|
||||
MSG_IMPORT_FETCH_FACEBOOK (LogLevel.INFO, R.string.msg_import_fetch_facebook),
|
||||
MSG_IMPORT_FETCH_KEYSERVER (LogLevel.INFO, R.string.msg_import_fetch_keyserver),
|
||||
MSG_IMPORT_FETCH_KEYSERVER_OK (LogLevel.DEBUG, R.string.msg_import_fetch_keyserver_ok),
|
||||
MSG_IMPORT_KEYSERVER (LogLevel.DEBUG, R.string.msg_import_keyserver),
|
||||
|
|
|
@ -440,7 +440,7 @@ public class KeyserverSyncAdapterService extends Service {
|
|||
String hexKeyId = KeyFormattingUtils
|
||||
.convertKeyIdToHex(keyId);
|
||||
// we aren't updating from keybase as of now
|
||||
keyList.add(new ParcelableKeyRing(fingerprint, hexKeyId, null));
|
||||
keyList.add(new ParcelableKeyRing(fingerprint, hexKeyId));
|
||||
}
|
||||
keyCursor.close();
|
||||
|
||||
|
|
|
@ -218,15 +218,10 @@ public class CreateYubiKeyImportResetFragment
|
|||
public void importKey() {
|
||||
|
||||
ArrayList<ParcelableKeyRing> keyList = new ArrayList<>();
|
||||
keyList.add(new ParcelableKeyRing(mNfcFingerprint, null, null));
|
||||
keyList.add(new ParcelableKeyRing(mNfcFingerprint, null));
|
||||
mKeyList = keyList;
|
||||
|
||||
{
|
||||
Preferences prefs = Preferences.getPreferences(getActivity());
|
||||
Preferences.CloudSearchPrefs cloudPrefs =
|
||||
new Preferences.CloudSearchPrefs(true, true, prefs.getPreferredKeyserver());
|
||||
mKeyserver = cloudPrefs.keyserver;
|
||||
}
|
||||
mKeyserver = Preferences.getPreferences(getActivity()).getPreferredKeyserver();
|
||||
|
||||
super.setProgressMessageResource(R.string.progress_importing);
|
||||
|
||||
|
|
|
@ -138,16 +138,11 @@ public abstract class DecryptFragment extends Fragment implements LoaderManager.
|
|||
final String keyserver;
|
||||
|
||||
// search config
|
||||
{
|
||||
Preferences prefs = Preferences.getPreferences(getActivity());
|
||||
Preferences.CloudSearchPrefs cloudPrefs =
|
||||
new Preferences.CloudSearchPrefs(true, true, prefs.getPreferredKeyserver());
|
||||
keyserver = cloudPrefs.keyserver;
|
||||
}
|
||||
keyserver = Preferences.getPreferences(getActivity()).getPreferredKeyserver();
|
||||
|
||||
{
|
||||
ParcelableKeyRing keyEntry = new ParcelableKeyRing(null,
|
||||
KeyFormattingUtils.convertKeyIdToHex(unknownKeyId), null);
|
||||
KeyFormattingUtils.convertKeyIdToHex(unknownKeyId));
|
||||
ArrayList<ParcelableKeyRing> selectedEntries = new ArrayList<>();
|
||||
selectedEntries.add(keyEntry);
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
package org.sufficientlysecure.keychain.ui;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
@ -746,16 +745,11 @@ public class DecryptListFragment
|
|||
final String keyserver;
|
||||
|
||||
// search config
|
||||
{
|
||||
Preferences prefs = Preferences.getPreferences(getActivity());
|
||||
Preferences.CloudSearchPrefs cloudPrefs =
|
||||
new Preferences.CloudSearchPrefs(true, true, prefs.getPreferredKeyserver());
|
||||
keyserver = cloudPrefs.keyserver;
|
||||
}
|
||||
keyserver = Preferences.getPreferences(getActivity()).getPreferredKeyserver();
|
||||
|
||||
{
|
||||
ParcelableKeyRing keyEntry = new ParcelableKeyRing(null,
|
||||
KeyFormattingUtils.convertKeyIdToHex(unknownKeyId), null);
|
||||
KeyFormattingUtils.convertKeyIdToHex(unknownKeyId));
|
||||
ArrayList<ParcelableKeyRing> selectedEntries = new ArrayList<>();
|
||||
selectedEntries.add(keyEntry);
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ import android.view.ViewGroup;
|
|||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.R;
|
||||
import org.sufficientlysecure.keychain.intents.OpenKeychainIntents;
|
||||
import org.sufficientlysecure.keychain.keyimport.FacebookKeyserver;
|
||||
import org.sufficientlysecure.keychain.keyimport.ImportKeysListEntry;
|
||||
import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing;
|
||||
import org.sufficientlysecure.keychain.operations.results.ImportKeyResult;
|
||||
|
@ -41,6 +42,7 @@ import org.sufficientlysecure.keychain.ui.util.Notify;
|
|||
import org.sufficientlysecure.keychain.util.Log;
|
||||
import org.sufficientlysecure.keychain.util.ParcelableFileCache;
|
||||
import org.sufficientlysecure.keychain.util.ParcelableFileCache.IteratorWithSize;
|
||||
import org.sufficientlysecure.keychain.util.Preferences;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
@ -50,6 +52,8 @@ public class ImportKeysActivity extends BaseNfcActivity
|
|||
|
||||
public static final String ACTION_IMPORT_KEY = OpenKeychainIntents.IMPORT_KEY;
|
||||
public static final String ACTION_IMPORT_KEY_FROM_KEYSERVER = OpenKeychainIntents.IMPORT_KEY_FROM_KEYSERVER;
|
||||
public static final String ACTION_IMPORT_KEY_FROM_FACEBOOK
|
||||
= Constants.INTENT_PREFIX + "IMPORT_KEY_FROM_FACEBOOK";
|
||||
public static final String ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN_RESULT =
|
||||
Constants.INTENT_PREFIX + "IMPORT_KEY_FROM_KEY_SERVER_AND_RETURN_RESULT";
|
||||
public static final String ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN_TO_SERVICE = Constants.INTENT_PREFIX
|
||||
|
@ -101,11 +105,6 @@ public class ImportKeysActivity extends BaseNfcActivity
|
|||
if (getIntent().hasExtra(EXTRA_PENDING_INTENT_DATA)) {
|
||||
mPendingIntentData = getIntent().getParcelableExtra(EXTRA_PENDING_INTENT_DATA);
|
||||
}
|
||||
|
||||
// if we aren't being restored, initialize fragments
|
||||
if (savedInstanceState == null) {
|
||||
handleActions(getIntent());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -113,6 +112,18 @@ public class ImportKeysActivity extends BaseNfcActivity
|
|||
setContentView(R.layout.import_keys_activity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNewIntent(Intent intent) {
|
||||
super.onNewIntent(intent);
|
||||
setIntent(intent);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResumeFragments() {
|
||||
super.onResumeFragments();
|
||||
handleActions(getIntent());
|
||||
}
|
||||
|
||||
protected void handleActions(Intent intent) {
|
||||
String action = intent.getAction();
|
||||
Bundle extras = intent.getExtras();
|
||||
|
@ -124,7 +135,9 @@ public class ImportKeysActivity extends BaseNfcActivity
|
|||
}
|
||||
|
||||
if (Intent.ACTION_VIEW.equals(action)) {
|
||||
if ("http".equals(scheme) || "https".equals(scheme)) {
|
||||
if (FacebookKeyserver.isFacebookHost(dataUri)) {
|
||||
action = ACTION_IMPORT_KEY_FROM_FACEBOOK;
|
||||
} else if ("http".equals(scheme) || "https".equals(scheme)) {
|
||||
action = ACTION_SEARCH_KEYSERVER_FROM_URL;
|
||||
} else {
|
||||
// Android's Action when opening file associated to Keychain (see AndroidManifest.xml)
|
||||
|
@ -205,26 +218,31 @@ public class ImportKeysActivity extends BaseNfcActivity
|
|||
}
|
||||
break;
|
||||
}
|
||||
case ACTION_IMPORT_KEY_FROM_FACEBOOK: {
|
||||
String fbUsername = FacebookKeyserver.getUsernameFromUri(dataUri);
|
||||
|
||||
Preferences.CloudSearchPrefs cloudSearchPrefs =
|
||||
new Preferences.CloudSearchPrefs(false, true, true, null);
|
||||
// we allow our users to edit the query if they wish
|
||||
startTopCloudFragment(fbUsername, false, cloudSearchPrefs);
|
||||
// search immediately
|
||||
startListFragment(null, null, fbUsername, cloudSearchPrefs);
|
||||
break;
|
||||
}
|
||||
case ACTION_SEARCH_KEYSERVER_FROM_URL: {
|
||||
// need to process URL to get search query and keyserver authority
|
||||
String query = dataUri.getQueryParameter("search");
|
||||
String keyserver = dataUri.getAuthority();
|
||||
// if query not specified, we still allow users to search the keyserver in the link
|
||||
if (query == null) {
|
||||
Notify.create(this, R.string.import_url_warn_no_search_parameter, Notify.LENGTH_INDEFINITE,
|
||||
Notify.Style.WARN).show();
|
||||
// we just set the keyserver
|
||||
startTopCloudFragment(null, false, keyserver);
|
||||
// we don't set the keyserver for ImportKeysListFragment since
|
||||
// it'll be set in the cloudSearchPrefs of ImportKeysCloudFragment
|
||||
// which is used when the user clicks on the search button
|
||||
startListFragment(null, null, null, null);
|
||||
} else {
|
||||
// we allow our users to edit the query if they wish
|
||||
startTopCloudFragment(query, false, keyserver);
|
||||
// search immediately
|
||||
startListFragment(null, null, query, keyserver);
|
||||
}
|
||||
Preferences.CloudSearchPrefs cloudSearchPrefs = new Preferences.CloudSearchPrefs(
|
||||
true, true, true, dataUri.getAuthority());
|
||||
// we allow our users to edit the query if they wish
|
||||
startTopCloudFragment(query, false, cloudSearchPrefs);
|
||||
// search immediately (if query is not null)
|
||||
startListFragment(null, null, query, cloudSearchPrefs);
|
||||
break;
|
||||
}
|
||||
case ACTION_IMPORT_KEY_FROM_FILE:
|
||||
|
@ -254,18 +272,21 @@ public class ImportKeysActivity extends BaseNfcActivity
|
|||
}
|
||||
|
||||
/**
|
||||
* if the fragment is started with non-null bytes/dataUri/serverQuery, it will immediately
|
||||
* load content
|
||||
* Shows the list of keys to be imported.
|
||||
* If the fragment is started with non-null bytes/dataUri/serverQuery, it will immediately
|
||||
* load content.
|
||||
*
|
||||
* @param bytes bytes containing list of keyrings to import
|
||||
* @param dataUri uri to file to import keyrings from
|
||||
* @param serverQuery query to search for on the keyserver
|
||||
* @param keyserver keyserver authority to search on. If null will use keyserver from
|
||||
* user preferences
|
||||
* @param bytes bytes containing list of keyrings to import
|
||||
* @param dataUri uri to file to import keyrings from
|
||||
* @param serverQuery query to search for on the keyserver
|
||||
* @param cloudSearchPrefs search specifications to use. If null will retrieve from user's
|
||||
* preferences.
|
||||
*/
|
||||
private void startListFragment(byte[] bytes, Uri dataUri, String serverQuery, String keyserver) {
|
||||
private void startListFragment(byte[] bytes, Uri dataUri, String serverQuery,
|
||||
Preferences.CloudSearchPrefs cloudSearchPrefs) {
|
||||
Fragment listFragment =
|
||||
ImportKeysListFragment.newInstance(bytes, dataUri, serverQuery, false, keyserver);
|
||||
ImportKeysListFragment.newInstance(bytes, dataUri, serverQuery, false,
|
||||
cloudSearchPrefs);
|
||||
getSupportFragmentManager().beginTransaction()
|
||||
.replace(R.id.import_keys_list_container, listFragment, TAG_FRAG_LIST)
|
||||
.commit();
|
||||
|
@ -283,14 +304,16 @@ public class ImportKeysActivity extends BaseNfcActivity
|
|||
* loads the CloudFragment, which consists of the search bar, search button and settings icon
|
||||
* visually.
|
||||
*
|
||||
* @param query search query
|
||||
* @param disableQueryEdit if true, user will not be able to edit the search query
|
||||
* @param keyserver keyserver authority to use for search, if null will use keyserver
|
||||
* specified in user preferences
|
||||
* @param query search query
|
||||
* @param disableQueryEdit if true, user will not be able to edit the search query
|
||||
* @param cloudSearchPrefs keyserver authority to use for search, if null will use keyserver
|
||||
* specified in user preferences
|
||||
*/
|
||||
private void startTopCloudFragment(String query, boolean disableQueryEdit, String keyserver) {
|
||||
private void startTopCloudFragment(String query, boolean disableQueryEdit,
|
||||
Preferences.CloudSearchPrefs cloudSearchPrefs) {
|
||||
findViewById(R.id.import_keys_top_layout).setVisibility(View.VISIBLE);
|
||||
Fragment importCloudFragment = ImportKeysCloudFragment.newInstance(query, disableQueryEdit, keyserver);
|
||||
Fragment importCloudFragment = ImportKeysCloudFragment.newInstance(query, disableQueryEdit,
|
||||
cloudSearchPrefs);
|
||||
getSupportFragmentManager().beginTransaction()
|
||||
.replace(R.id.import_keys_top_container, importCloudFragment, TAG_FRAG_TOP)
|
||||
.commit();
|
||||
|
@ -363,9 +386,8 @@ public class ImportKeysActivity extends BaseNfcActivity
|
|||
// change the format into ParcelableKeyRing
|
||||
ArrayList<ImportKeysListEntry> entries = keyListFragment.getSelectedEntries();
|
||||
for (ImportKeysListEntry entry : entries) {
|
||||
keys.add(new ParcelableKeyRing(
|
||||
entry.getFingerprintHex(), entry.getKeyIdHex(), entry.getExtraData())
|
||||
);
|
||||
keys.add(new ParcelableKeyRing(entry.getFingerprintHex(),
|
||||
entry.getKeyIdHex(), entry.getKeybaseName(), entry.getFbUsername()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -42,33 +42,35 @@ import org.sufficientlysecure.keychain.util.Preferences;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Consists of the search bar, search button, and search settings button
|
||||
*/
|
||||
public class ImportKeysCloudFragment extends Fragment {
|
||||
public static final String ARG_QUERY = "query";
|
||||
public static final String ARG_DISABLE_QUERY_EDIT = "disable_query_edit";
|
||||
public static final String ARG_KEYSERVER = "keyserver";
|
||||
public static final String ARG_CLOUD_SEARCH_PREFS = "cloud_search_prefs";
|
||||
|
||||
private ImportKeysActivity mImportActivity;
|
||||
|
||||
private View mSearchButton;
|
||||
private AutoCompleteTextView mQueryEditText;
|
||||
private View mConfigButton;
|
||||
|
||||
/**
|
||||
* Creates new instance of this fragment
|
||||
*
|
||||
* @param query query to search for
|
||||
* @param disableQueryEdit if true, user cannot edit query
|
||||
* @param keyserver specified keyserver authority to use. If null, will use keyserver
|
||||
* specified in user preferences
|
||||
* @param cloudSearchPrefs search parameters to use. If null will retrieve from user's
|
||||
* preferences.
|
||||
*/
|
||||
public static ImportKeysCloudFragment newInstance(String query, boolean disableQueryEdit,
|
||||
String keyserver) {
|
||||
Preferences.CloudSearchPrefs
|
||||
cloudSearchPrefs) {
|
||||
ImportKeysCloudFragment frag = new ImportKeysCloudFragment();
|
||||
|
||||
Bundle args = new Bundle();
|
||||
args.putString(ARG_QUERY, query);
|
||||
args.putBoolean(ARG_DISABLE_QUERY_EDIT, disableQueryEdit);
|
||||
args.putString(ARG_KEYSERVER, keyserver);
|
||||
args.putParcelable(ARG_CLOUD_SEARCH_PREFS, cloudSearchPrefs);
|
||||
|
||||
frag.setArguments(args);
|
||||
|
||||
|
@ -82,9 +84,7 @@ public class ImportKeysCloudFragment extends Fragment {
|
|||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.import_keys_cloud_fragment, container, false);
|
||||
|
||||
mSearchButton = view.findViewById(R.id.cloud_import_server_search);
|
||||
mQueryEditText = (AutoCompleteTextView) view.findViewById(R.id.cloud_import_server_query);
|
||||
mConfigButton = view.findViewById(R.id.cloud_import_server_config_button);
|
||||
|
||||
List<String> namesAndEmails = ContactHelper.getContactNames(getActivity());
|
||||
namesAndEmails.addAll(ContactHelper.getContactMails(getActivity()));
|
||||
|
@ -96,7 +96,8 @@ public class ImportKeysCloudFragment extends Fragment {
|
|||
)
|
||||
);
|
||||
|
||||
mSearchButton.setOnClickListener(new OnClickListener() {
|
||||
View searchButton = view.findViewById(R.id.cloud_import_server_search);
|
||||
searchButton.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
search(mQueryEditText.getText().toString());
|
||||
|
@ -116,7 +117,8 @@ public class ImportKeysCloudFragment extends Fragment {
|
|||
}
|
||||
});
|
||||
|
||||
mConfigButton.setOnClickListener(new OnClickListener() {
|
||||
View configButton = view.findViewById(R.id.cloud_import_server_config_button);
|
||||
configButton.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Intent intent = new Intent(mImportActivity, SettingsActivity.class);
|
||||
|
@ -159,15 +161,14 @@ public class ImportKeysCloudFragment extends Fragment {
|
|||
}
|
||||
|
||||
private void search(String query) {
|
||||
Preferences.CloudSearchPrefs cloudSearchPrefs;
|
||||
String explicitKeyserver = getArguments().getString(ARG_KEYSERVER);
|
||||
// no explicit keyserver passed
|
||||
if (explicitKeyserver == null) {
|
||||
Preferences.CloudSearchPrefs cloudSearchPrefs
|
||||
= getArguments().getParcelable(ARG_CLOUD_SEARCH_PREFS);
|
||||
|
||||
// no explicit search preferences passed
|
||||
if (cloudSearchPrefs == null) {
|
||||
cloudSearchPrefs = Preferences.getPreferences(getActivity()).getCloudSearchPrefs();
|
||||
} else {
|
||||
// assume we are also meant to search keybase.io
|
||||
cloudSearchPrefs = new Preferences.CloudSearchPrefs(true, true, explicitKeyserver);
|
||||
}
|
||||
|
||||
mImportActivity.loadCallback(
|
||||
new ImportKeysListFragment.CloudLoaderState(query, cloudSearchPrefs));
|
||||
toggleKeyboard(false);
|
||||
|
|
|
@ -65,7 +65,7 @@ public class ImportKeysListFragment extends ListFragment implements
|
|||
private static final String ARG_BYTES = "bytes";
|
||||
public static final String ARG_SERVER_QUERY = "query";
|
||||
public static final String ARG_NON_INTERACTIVE = "non_interactive";
|
||||
public static final String ARG_KEYSERVER_URL = "keyserver_url";
|
||||
public static final String ARG_CLOUD_SEARCH_PREFS = "cloud_search_prefs";
|
||||
|
||||
private static final int REQUEST_PERMISSION_READ_EXTERNAL_STORAGE = 12;
|
||||
|
||||
|
@ -140,32 +140,35 @@ public class ImportKeysListFragment extends ListFragment implements
|
|||
* by dataUri, or searches a keyserver for serverQuery, if parameter is not null, in that order
|
||||
* Will immediately load data if non-null bytes/dataUri/serverQuery
|
||||
*
|
||||
* @param bytes byte data containing list of keyrings to be imported
|
||||
* @param dataUri file from which keyrings are to be imported
|
||||
* @param serverQuery query to search for on keyserver
|
||||
* @param keyserver if not null, will perform search on specified keyserver. Else, uses
|
||||
* keyserver specified in user preferences
|
||||
* @param bytes byte data containing list of keyrings to be imported
|
||||
* @param dataUri file from which keyrings are to be imported
|
||||
* @param serverQuery query to search for on keyserver
|
||||
* @param cloudSearchPrefs search parameters to use. If null will retrieve from user's
|
||||
* preferences.
|
||||
* @return fragment with arguments set based on passed parameters
|
||||
*/
|
||||
public static ImportKeysListFragment newInstance(byte[] bytes, Uri dataUri, String serverQuery,
|
||||
String keyserver) {
|
||||
return newInstance(bytes, dataUri, serverQuery, false, keyserver);
|
||||
Preferences.CloudSearchPrefs cloudSearchPrefs) {
|
||||
return newInstance(bytes, dataUri, serverQuery, false, cloudSearchPrefs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Visually consists of a list of keyrings with checkboxes to specify which are to be imported
|
||||
* Will immediately load data if non-null bytes/dataUri/serverQuery is supplied
|
||||
*
|
||||
* @param bytes byte data containing list of keyrings to be imported
|
||||
* @param dataUri file from which keyrings are to be imported
|
||||
* @param serverQuery query to search for on keyserver
|
||||
* @param nonInteractive if true, users will not be able to check/uncheck items in the list
|
||||
* @param keyserver if set, will perform search on specified keyserver. If null, falls back
|
||||
* to keyserver specified in user preferences
|
||||
* @param bytes byte data containing list of keyrings to be imported
|
||||
* @param dataUri file from which keyrings are to be imported
|
||||
* @param serverQuery query to search for on keyserver
|
||||
* @param nonInteractive if true, users will not be able to check/uncheck items in the list
|
||||
* @param cloudSearchPrefs search parameters to use. If null will retrieve from user's
|
||||
* preferences.
|
||||
* @return fragment with arguments set based on passed parameters
|
||||
*/
|
||||
public static ImportKeysListFragment newInstance(byte[] bytes, Uri dataUri, String serverQuery,
|
||||
boolean nonInteractive, String keyserver) {
|
||||
public static ImportKeysListFragment newInstance(byte[] bytes,
|
||||
Uri dataUri,
|
||||
String serverQuery,
|
||||
boolean nonInteractive,
|
||||
Preferences.CloudSearchPrefs cloudSearchPrefs) {
|
||||
ImportKeysListFragment frag = new ImportKeysListFragment();
|
||||
|
||||
Bundle args = new Bundle();
|
||||
|
@ -173,7 +176,7 @@ public class ImportKeysListFragment extends ListFragment implements
|
|||
args.putParcelable(ARG_DATA_URI, dataUri);
|
||||
args.putString(ARG_SERVER_QUERY, serverQuery);
|
||||
args.putBoolean(ARG_NON_INTERACTIVE, nonInteractive);
|
||||
args.putString(ARG_KEYSERVER_URL, keyserver);
|
||||
args.putParcelable(ARG_CLOUD_SEARCH_PREFS, cloudSearchPrefs);
|
||||
|
||||
frag.setArguments(args);
|
||||
|
||||
|
@ -223,7 +226,6 @@ public class ImportKeysListFragment extends ListFragment implements
|
|||
Uri dataUri = args.getParcelable(ARG_DATA_URI);
|
||||
byte[] bytes = args.getByteArray(ARG_BYTES);
|
||||
String query = args.getString(ARG_SERVER_QUERY);
|
||||
String keyserver = args.getString(ARG_KEYSERVER_URL);
|
||||
mNonInteractive = args.getBoolean(ARG_NON_INTERACTIVE, false);
|
||||
|
||||
getListView().setOnTouchListener(new OnTouchListener() {
|
||||
|
@ -241,11 +243,10 @@ public class ImportKeysListFragment extends ListFragment implements
|
|||
if (dataUri != null || bytes != null) {
|
||||
mLoaderState = new BytesLoaderState(bytes, dataUri);
|
||||
} else if (query != null) {
|
||||
Preferences.CloudSearchPrefs cloudSearchPrefs;
|
||||
if (keyserver == null) {
|
||||
Preferences.CloudSearchPrefs cloudSearchPrefs
|
||||
= args.getParcelable(ARG_CLOUD_SEARCH_PREFS);
|
||||
if (cloudSearchPrefs == null) {
|
||||
cloudSearchPrefs = Preferences.getPreferences(getActivity()).getCloudSearchPrefs();
|
||||
} else {
|
||||
cloudSearchPrefs = new Preferences.CloudSearchPrefs(true, true, keyserver);
|
||||
}
|
||||
|
||||
mLoaderState = new CloudLoaderState(query, cloudSearchPrefs);
|
||||
|
|
|
@ -19,7 +19,6 @@ package org.sufficientlysecure.keychain.ui;
|
|||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.net.Uri;
|
||||
import android.nfc.NdefMessage;
|
||||
import android.nfc.NfcAdapter;
|
||||
|
@ -130,7 +129,6 @@ public class ImportKeysProxyActivity extends FragmentActivity
|
|||
String scannedContent = scanResult.getContents();
|
||||
processScannedContent(scannedContent);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -199,7 +197,7 @@ public class ImportKeysProxyActivity extends FragmentActivity
|
|||
}
|
||||
|
||||
public void importKeys(String fingerprint) {
|
||||
ParcelableKeyRing keyEntry = new ParcelableKeyRing(fingerprint, null, null);
|
||||
ParcelableKeyRing keyEntry = new ParcelableKeyRing(fingerprint, null);
|
||||
ArrayList<ParcelableKeyRing> selectedEntries = new ArrayList<>();
|
||||
selectedEntries.add(keyEntry);
|
||||
|
||||
|
@ -209,12 +207,7 @@ public class ImportKeysProxyActivity extends FragmentActivity
|
|||
private void startImportService(ArrayList<ParcelableKeyRing> keyRings) {
|
||||
|
||||
// search config
|
||||
{
|
||||
Preferences prefs = Preferences.getPreferences(this);
|
||||
Preferences.CloudSearchPrefs cloudPrefs =
|
||||
new Preferences.CloudSearchPrefs(true, true, prefs.getPreferredKeyserver());
|
||||
mKeyserver = cloudPrefs.keyserver;
|
||||
}
|
||||
mKeyserver = Preferences.getPreferences(this).getPreferredKeyserver();
|
||||
|
||||
mKeyList = keyRings;
|
||||
|
||||
|
|
|
@ -588,7 +588,7 @@ public class KeyListFragment extends LoaderFragment
|
|||
while (cursor.moveToNext()) {
|
||||
byte[] blob = cursor.getBlob(0);//fingerprint column is 0
|
||||
String fingerprint = KeyFormattingUtils.convertFingerprintToHex(blob);
|
||||
ParcelableKeyRing keyEntry = new ParcelableKeyRing(fingerprint, null, null);
|
||||
ParcelableKeyRing keyEntry = new ParcelableKeyRing(fingerprint, null);
|
||||
keyList.add(keyEntry);
|
||||
}
|
||||
mKeyList = keyList;
|
||||
|
@ -597,12 +597,7 @@ public class KeyListFragment extends LoaderFragment
|
|||
}
|
||||
|
||||
// search config
|
||||
{
|
||||
Preferences prefs = Preferences.getPreferences(getActivity());
|
||||
Preferences.CloudSearchPrefs cloudPrefs =
|
||||
new Preferences.CloudSearchPrefs(true, true, prefs.getPreferredKeyserver());
|
||||
mKeyserver = cloudPrefs.keyserver;
|
||||
}
|
||||
mKeyserver = Preferences.getPreferences(getActivity()).getPreferredKeyserver();
|
||||
|
||||
mImportOpHelper = new CryptoOperationHelper<>(1, this, this, R.string.progress_updating);
|
||||
mImportOpHelper.setProgressCancellable(true);
|
||||
|
|
|
@ -29,11 +29,9 @@ import android.content.Intent;
|
|||
import android.content.pm.PackageManager;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.preference.CheckBoxPreference;
|
||||
import android.preference.EditTextPreference;
|
||||
import android.preference.ListPreference;
|
||||
import android.preference.Preference;
|
||||
import android.preference.PreferenceActivity;
|
||||
import android.preference.PreferenceFragment;
|
||||
import android.preference.PreferenceScreen;
|
||||
import android.preference.SwitchPreference;
|
||||
|
@ -115,6 +113,15 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
|
|||
});
|
||||
}
|
||||
|
||||
public static abstract class PresetPreferenceFragment extends PreferenceFragment {
|
||||
@Override
|
||||
public void addPreferencesFromResource(int preferencesResId) {
|
||||
// so that preferences are written to our preference file, not the default
|
||||
Preferences.setPreferenceManagerFileAndMode(this.getPreferenceManager());
|
||||
super.addPreferencesFromResource(preferencesResId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBuildHeaders(List<Header> target) {
|
||||
super.onBuildHeaders(target);
|
||||
|
@ -124,7 +131,7 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
|
|||
/**
|
||||
* This fragment shows the Cloud Search preferences
|
||||
*/
|
||||
public static class CloudSearchPrefsFragment extends PreferenceFragment {
|
||||
public static class CloudSearchPrefsFragment extends PresetPreferenceFragment {
|
||||
|
||||
private PreferenceScreen mKeyServerPreference = null;
|
||||
|
||||
|
@ -149,12 +156,6 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
|
|||
return false;
|
||||
}
|
||||
});
|
||||
initializeSearchKeyserver(
|
||||
(SwitchPreference) findPreference(Constants.Pref.SEARCH_KEYSERVER)
|
||||
);
|
||||
initializeSearchKeybase(
|
||||
(SwitchPreference) findPreference(Constants.Pref.SEARCH_KEYBASE)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -172,12 +173,20 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static String keyserverSummary(Context context) {
|
||||
String[] servers = sPreferences.getKeyServers();
|
||||
String serverSummary = context.getResources().getQuantityString(
|
||||
R.plurals.n_keyservers, servers.length, servers.length);
|
||||
return serverSummary + "; " + context.getString(R.string.label_preferred) + ": " + sPreferences
|
||||
.getPreferredKeyserver();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This fragment shows the PIN/password preferences
|
||||
*/
|
||||
public static class PassphrasePrefsFragment extends PreferenceFragment {
|
||||
public static class PassphrasePrefsFragment extends PresetPreferenceFragment {
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
@ -186,18 +195,27 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
|
|||
// Load the preferences from an XML resource
|
||||
addPreferencesFromResource(R.xml.passphrase_preferences);
|
||||
|
||||
initializePassphraseCacheSubs(
|
||||
(CheckBoxPreference) findPreference(Constants.Pref.PASSPHRASE_CACHE_SUBS));
|
||||
|
||||
initializePassphraseCacheTtl(
|
||||
(IntegerListPreference) findPreference(Constants.Pref.PASSPHRASE_CACHE_TTL));
|
||||
}
|
||||
|
||||
initializeUseNumKeypadForYubiKeyPin(
|
||||
(CheckBoxPreference) findPreference(Constants.Pref.USE_NUMKEYPAD_FOR_YUBIKEY_PIN));
|
||||
private static void initializePassphraseCacheTtl(
|
||||
final IntegerListPreference passphraseCacheTtl) {
|
||||
passphraseCacheTtl.setValue("" + sPreferences.getPassphraseCacheTtl());
|
||||
passphraseCacheTtl.setSummary(passphraseCacheTtl.getEntry());
|
||||
passphraseCacheTtl
|
||||
.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
passphraseCacheTtl.setValue(newValue.toString());
|
||||
passphraseCacheTtl.setSummary(passphraseCacheTtl.getEntry());
|
||||
sPreferences.setPassphraseCacheTtl(Integer.parseInt(newValue.toString()));
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public static class ProxyPrefsFragment extends PreferenceFragment {
|
||||
public static class ProxyPrefsFragment extends PresetPreferenceFragment {
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
@ -213,37 +231,18 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
|
|||
private EditTextPreference mProxyHost;
|
||||
private EditTextPreference mProxyPort;
|
||||
private ListPreference mProxyType;
|
||||
private PreferenceActivity mActivity;
|
||||
private PreferenceFragment mFragment;
|
||||
private PresetPreferenceFragment mFragment;
|
||||
|
||||
public Initializer(PreferenceFragment fragment) {
|
||||
public Initializer(PresetPreferenceFragment fragment) {
|
||||
mFragment = fragment;
|
||||
}
|
||||
|
||||
public Initializer(PreferenceActivity activity) {
|
||||
mActivity = activity;
|
||||
}
|
||||
|
||||
public Preference automaticallyFindPreference(String key) {
|
||||
if (mFragment != null) {
|
||||
return mFragment.findPreference(key);
|
||||
} else {
|
||||
return mActivity.findPreference(key);
|
||||
}
|
||||
return mFragment.findPreference(key);
|
||||
}
|
||||
|
||||
public void initialize() {
|
||||
// makes android's preference framework write to our file instead of default
|
||||
// This allows us to use the "persistent" attribute to simplify code
|
||||
if (mFragment != null) {
|
||||
Preferences.setPreferenceManagerFileAndMode(mFragment.getPreferenceManager());
|
||||
// Load the preferences from an XML resource
|
||||
mFragment.addPreferencesFromResource(R.xml.proxy_preferences);
|
||||
} else {
|
||||
Preferences.setPreferenceManagerFileAndMode(mActivity.getPreferenceManager());
|
||||
// Load the preferences from an XML resource
|
||||
mActivity.addPreferencesFromResource(R.xml.proxy_preferences);
|
||||
}
|
||||
mFragment.addPreferencesFromResource(R.xml.proxy_preferences);
|
||||
|
||||
mUseTor = (SwitchPreference) automaticallyFindPreference(Constants.Pref.USE_TOR_PROXY);
|
||||
mUseNormalProxy = (SwitchPreference) automaticallyFindPreference(Constants.Pref.USE_NORMAL_PROXY);
|
||||
|
@ -268,7 +267,7 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
|
|||
mUseTor.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
Activity activity = mFragment != null ? mFragment.getActivity() : mActivity;
|
||||
Activity activity = mFragment.getActivity();
|
||||
if ((Boolean) newValue) {
|
||||
boolean installed = OrbotHelper.isOrbotInstalled(activity);
|
||||
if (!installed) {
|
||||
|
@ -314,7 +313,7 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
|
|||
mProxyHost.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
Activity activity = mFragment != null ? mFragment.getActivity() : mActivity;
|
||||
Activity activity = mFragment.getActivity();
|
||||
if (TextUtils.isEmpty((String) newValue)) {
|
||||
Notify.create(
|
||||
activity,
|
||||
|
@ -332,7 +331,7 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
|
|||
mProxyPort.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
Activity activity = mFragment != null ? mFragment.getActivity() : mActivity;
|
||||
Activity activity = mFragment.getActivity();
|
||||
try {
|
||||
int port = Integer.parseInt((String) newValue);
|
||||
if (port < 0 || port > 65535) {
|
||||
|
@ -407,7 +406,7 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
|
|||
/**
|
||||
* This fragment shows the keyserver/contacts sync preferences
|
||||
*/
|
||||
public static class SyncPrefsFragment extends PreferenceFragment {
|
||||
public static class SyncPrefsFragment extends PresetPreferenceFragment {
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
@ -542,7 +541,7 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
|
|||
/**
|
||||
* This fragment shows experimental features
|
||||
*/
|
||||
public static class ExperimentalPrefsFragment extends PreferenceFragment {
|
||||
public static class ExperimentalPrefsFragment extends PresetPreferenceFragment {
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
@ -551,18 +550,24 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
|
|||
// Load the preferences from an XML resource
|
||||
addPreferencesFromResource(R.xml.experimental_preferences);
|
||||
|
||||
initializeExperimentalEnableWordConfirm(
|
||||
(SwitchPreference) findPreference(Constants.Pref.EXPERIMENTAL_ENABLE_WORD_CONFIRM));
|
||||
|
||||
initializeExperimentalEnableLinkedIdentities(
|
||||
(SwitchPreference) findPreference(Constants.Pref.EXPERIMENTAL_ENABLE_LINKED_IDENTITIES));
|
||||
|
||||
initializeExperimentalEnableKeybase(
|
||||
(SwitchPreference) findPreference(Constants.Pref.EXPERIMENTAL_ENABLE_KEYBASE));
|
||||
|
||||
initializeTheme((ListPreference) findPreference(Constants.Pref.THEME));
|
||||
|
||||
}
|
||||
|
||||
private static void initializeTheme(final ListPreference themePref) {
|
||||
themePref.setSummary(themePref.getEntry() + "\n"
|
||||
+ themePref.getContext().getString(R.string.label_experimental_settings_theme_summary));
|
||||
themePref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
themePref.setSummary(newValue + "\n"
|
||||
+ themePref.getContext().getString(R.string.label_experimental_settings_theme_summary));
|
||||
|
||||
((SettingsActivity) themePref.getContext()).recreate();
|
||||
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean isValidFragment(String fragmentName) {
|
||||
|
@ -573,125 +578,4 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
|
|||
|| ExperimentalPrefsFragment.class.getName().equals(fragmentName)
|
||||
|| super.isValidFragment(fragmentName);
|
||||
}
|
||||
|
||||
private static void initializePassphraseCacheSubs(final CheckBoxPreference mPassphraseCacheSubs) {
|
||||
mPassphraseCacheSubs.setChecked(sPreferences.getPassphraseCacheSubs());
|
||||
mPassphraseCacheSubs.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
mPassphraseCacheSubs.setChecked((Boolean) newValue);
|
||||
sPreferences.setPassphraseCacheSubs((Boolean) newValue);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void initializePassphraseCacheTtl(final IntegerListPreference mPassphraseCacheTtl) {
|
||||
mPassphraseCacheTtl.setValue("" + sPreferences.getPassphraseCacheTtl());
|
||||
mPassphraseCacheTtl.setSummary(mPassphraseCacheTtl.getEntry());
|
||||
mPassphraseCacheTtl
|
||||
.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
mPassphraseCacheTtl.setValue(newValue.toString());
|
||||
mPassphraseCacheTtl.setSummary(mPassphraseCacheTtl.getEntry());
|
||||
sPreferences.setPassphraseCacheTtl(Integer.parseInt(newValue.toString()));
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void initializeTheme(final ListPreference mTheme) {
|
||||
mTheme.setValue(sPreferences.getTheme());
|
||||
mTheme.setSummary(mTheme.getEntry() + "\n"
|
||||
+ mTheme.getContext().getString(R.string.label_experimental_settings_theme_summary));
|
||||
mTheme.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
mTheme.setValue((String) newValue);
|
||||
mTheme.setSummary(mTheme.getEntry() + "\n"
|
||||
+ mTheme.getContext().getString(R.string.label_experimental_settings_theme_summary));
|
||||
sPreferences.setTheme((String) newValue);
|
||||
|
||||
((SettingsActivity) mTheme.getContext()).recreate();
|
||||
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void initializeSearchKeyserver(final SwitchPreference mSearchKeyserver) {
|
||||
Preferences.CloudSearchPrefs prefs = sPreferences.getCloudSearchPrefs();
|
||||
mSearchKeyserver.setChecked(prefs.searchKeyserver);
|
||||
mSearchKeyserver.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
mSearchKeyserver.setChecked((Boolean) newValue);
|
||||
sPreferences.setSearchKeyserver((Boolean) newValue);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void initializeSearchKeybase(final SwitchPreference mSearchKeybase) {
|
||||
Preferences.CloudSearchPrefs prefs = sPreferences.getCloudSearchPrefs();
|
||||
mSearchKeybase.setChecked(prefs.searchKeybase);
|
||||
mSearchKeybase.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
mSearchKeybase.setChecked((Boolean) newValue);
|
||||
sPreferences.setSearchKeybase((Boolean) newValue);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static String keyserverSummary(Context context) {
|
||||
String[] servers = sPreferences.getKeyServers();
|
||||
String serverSummary = context.getResources().getQuantityString(
|
||||
R.plurals.n_keyservers, servers.length, servers.length);
|
||||
return serverSummary + "; " + context.getString(R.string.label_preferred) + ": " + sPreferences
|
||||
.getPreferredKeyserver();
|
||||
}
|
||||
|
||||
private static void initializeUseNumKeypadForYubiKeyPin(final CheckBoxPreference mUseNumKeypadForYubiKeyPin) {
|
||||
mUseNumKeypadForYubiKeyPin.setChecked(sPreferences.useNumKeypadForYubiKeyPin());
|
||||
mUseNumKeypadForYubiKeyPin.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
mUseNumKeypadForYubiKeyPin.setChecked((Boolean) newValue);
|
||||
sPreferences.setUseNumKeypadForYubiKeyPin((Boolean) newValue);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void initializeExperimentalEnableWordConfirm(final SwitchPreference mExperimentalEnableWordConfirm) {
|
||||
mExperimentalEnableWordConfirm.setChecked(sPreferences.getExperimentalEnableWordConfirm());
|
||||
mExperimentalEnableWordConfirm.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
mExperimentalEnableWordConfirm.setChecked((Boolean) newValue);
|
||||
sPreferences.setExperimentalEnableWordConfirm((Boolean) newValue);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void initializeExperimentalEnableLinkedIdentities(final SwitchPreference mExperimentalEnableLinkedIdentities) {
|
||||
mExperimentalEnableLinkedIdentities.setChecked(sPreferences.getExperimentalEnableLinkedIdentities());
|
||||
mExperimentalEnableLinkedIdentities.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
mExperimentalEnableLinkedIdentities.setChecked((Boolean) newValue);
|
||||
sPreferences.setExperimentalEnableLinkedIdentities((Boolean) newValue);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1038,18 +1038,12 @@ public class ViewKeyActivity extends BaseNfcActivity implements
|
|||
KeychainContract.Keys.FINGERPRINT, ProviderHelper.FIELD_TYPE_BLOB);
|
||||
String fingerprint = KeyFormattingUtils.convertFingerprintToHex(blob);
|
||||
|
||||
ParcelableKeyRing keyEntry = new ParcelableKeyRing(fingerprint, null, null);
|
||||
ParcelableKeyRing keyEntry = new ParcelableKeyRing(fingerprint, null);
|
||||
ArrayList<ParcelableKeyRing> entries = new ArrayList<>();
|
||||
entries.add(keyEntry);
|
||||
mKeyList = entries;
|
||||
|
||||
// search config
|
||||
{
|
||||
Preferences prefs = Preferences.getPreferences(this);
|
||||
Preferences.CloudSearchPrefs cloudPrefs =
|
||||
new Preferences.CloudSearchPrefs(true, true, prefs.getPreferredKeyserver());
|
||||
mKeyserver = cloudPrefs.keyserver;
|
||||
}
|
||||
mKeyserver = Preferences.getPreferences(this).getPreferredKeyserver();
|
||||
|
||||
mOperationHelper.cryptoOperation();
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ public class EmailKeyHelper {
|
|||
// Put them in a list and import
|
||||
ArrayList<ParcelableKeyRing> keys = new ArrayList<>(entries.size());
|
||||
for (ImportKeysListEntry entry : entries) {
|
||||
keys.add(new ParcelableKeyRing(entry.getFingerprintHex(), entry.getKeyIdHex(), null));
|
||||
keys.add(new ParcelableKeyRing(entry.getFingerprintHex(), entry.getKeyIdHex()));
|
||||
}
|
||||
mKeyList = keys;
|
||||
mKeyserver = keyserver;
|
||||
|
|
|
@ -21,10 +21,10 @@ package org.sufficientlysecure.keychain.util;
|
|||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
|
||||
import android.content.res.Resources;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.Constants.Pref;
|
||||
|
@ -42,7 +42,6 @@ import java.util.Vector;
|
|||
public class Preferences {
|
||||
private static Preferences sPreferences;
|
||||
private SharedPreferences mSharedPreferences;
|
||||
private Resources mResources;
|
||||
|
||||
private static String PREF_FILE_NAME = "APG.main";
|
||||
private static int PREF_FILE_MODE = Context.MODE_MULTI_PROCESS;
|
||||
|
@ -62,10 +61,15 @@ public class Preferences {
|
|||
}
|
||||
|
||||
private Preferences(Context context) {
|
||||
mResources = context.getResources();
|
||||
updateSharedPreferences(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes android's preference framework write to our file instead of default.
|
||||
* This allows us to use the "persistent" attribute to simplify code, which automatically
|
||||
* writes and reads preference values.
|
||||
* @param manager
|
||||
*/
|
||||
public static void setPreferenceManagerFileAndMode(PreferenceManager manager) {
|
||||
manager.setSharedPreferencesName(PREF_FILE_NAME);
|
||||
manager.setSharedPreferencesMode(PREF_FILE_MODE);
|
||||
|
@ -130,12 +134,6 @@ public class Preferences {
|
|||
return mSharedPreferences.getBoolean(Pref.USE_NUMKEYPAD_FOR_YUBIKEY_PIN, true);
|
||||
}
|
||||
|
||||
public void setUseNumKeypadForYubiKeyPin(boolean useNumKeypadForYubikeyPin) {
|
||||
SharedPreferences.Editor editor = mSharedPreferences.edit();
|
||||
editor.putBoolean(Pref.USE_NUMKEYPAD_FOR_YUBIKEY_PIN, useNumKeypadForYubikeyPin);
|
||||
editor.commit();
|
||||
}
|
||||
|
||||
public void setFirstTime(boolean value) {
|
||||
SharedPreferences.Editor editor = mSharedPreferences.edit();
|
||||
editor.putBoolean(Constants.Pref.FIRST_TIME, value);
|
||||
|
@ -181,18 +179,6 @@ public class Preferences {
|
|||
editor.commit();
|
||||
}
|
||||
|
||||
public void setSearchKeyserver(boolean searchKeyserver) {
|
||||
SharedPreferences.Editor editor = mSharedPreferences.edit();
|
||||
editor.putBoolean(Pref.SEARCH_KEYSERVER, searchKeyserver);
|
||||
editor.commit();
|
||||
}
|
||||
|
||||
public void setSearchKeybase(boolean searchKeybase) {
|
||||
SharedPreferences.Editor editor = mSharedPreferences.edit();
|
||||
editor.putBoolean(Pref.SEARCH_KEYBASE, searchKeybase);
|
||||
editor.commit();
|
||||
}
|
||||
|
||||
public void setFilesUseCompression(boolean compress) {
|
||||
SharedPreferences.Editor editor = mSharedPreferences.edit();
|
||||
editor.putBoolean(Pref.FILE_USE_COMPRESSION, compress);
|
||||
|
@ -266,17 +252,6 @@ public class Preferences {
|
|||
return Integer.parseInt(mSharedPreferences.getString(Pref.PROXY_PORT, "-1"));
|
||||
}
|
||||
|
||||
/**
|
||||
* we store port as String for easy interfacing with EditTextPreference, but return it as an integer
|
||||
*
|
||||
* @param port proxy port
|
||||
*/
|
||||
public void setProxyPort(String port) {
|
||||
SharedPreferences.Editor editor = mSharedPreferences.edit();
|
||||
editor.putString(Pref.PROXY_PORT, port);
|
||||
editor.commit();
|
||||
}
|
||||
|
||||
public Proxy.Type getProxyType() {
|
||||
final String typeHttp = Pref.ProxyType.TYPE_HTTP;
|
||||
final String typeSocks = Pref.ProxyType.TYPE_SOCKS;
|
||||
|
@ -338,12 +313,14 @@ public class Preferences {
|
|||
public CloudSearchPrefs getCloudSearchPrefs() {
|
||||
return new CloudSearchPrefs(mSharedPreferences.getBoolean(Pref.SEARCH_KEYSERVER, true),
|
||||
mSharedPreferences.getBoolean(Pref.SEARCH_KEYBASE, true),
|
||||
false,
|
||||
getPreferredKeyserver());
|
||||
}
|
||||
|
||||
public static class CloudSearchPrefs {
|
||||
public static class CloudSearchPrefs implements Parcelable {
|
||||
public final boolean searchKeyserver;
|
||||
public final boolean searchKeybase;
|
||||
public final boolean searchFacebook;
|
||||
public final String keyserver;
|
||||
|
||||
/**
|
||||
|
@ -351,41 +328,58 @@ public class Preferences {
|
|||
* @param searchKeybase should keybase.io be searched
|
||||
* @param keyserver the keyserver url authority to search on
|
||||
*/
|
||||
public CloudSearchPrefs(boolean searchKeyserver, boolean searchKeybase, String keyserver) {
|
||||
public CloudSearchPrefs(boolean searchKeyserver, boolean searchKeybase,
|
||||
boolean searchFacebook, String keyserver) {
|
||||
this.searchKeyserver = searchKeyserver;
|
||||
this.searchKeybase = searchKeybase;
|
||||
this.searchFacebook = searchFacebook;
|
||||
this.keyserver = keyserver;
|
||||
}
|
||||
|
||||
protected CloudSearchPrefs(Parcel in) {
|
||||
searchKeyserver = in.readByte() != 0x00;
|
||||
searchKeybase = in.readByte() != 0x00;
|
||||
searchFacebook = in.readByte() != 0x00;
|
||||
keyserver = in.readString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeByte((byte) (searchKeyserver ? 0x01 : 0x00));
|
||||
dest.writeByte((byte) (searchKeybase ? 0x01 : 0x00));
|
||||
dest.writeByte((byte) (searchFacebook ? 0x01 : 0x00));
|
||||
dest.writeString(keyserver);
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<CloudSearchPrefs> CREATOR
|
||||
= new Parcelable.Creator<CloudSearchPrefs>() {
|
||||
@Override
|
||||
public CloudSearchPrefs createFromParcel(Parcel in) {
|
||||
return new CloudSearchPrefs(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CloudSearchPrefs[] newArray(int size) {
|
||||
return new CloudSearchPrefs[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// experimental prefs
|
||||
|
||||
public void setExperimentalEnableWordConfirm(boolean enableWordConfirm) {
|
||||
SharedPreferences.Editor editor = mSharedPreferences.edit();
|
||||
editor.putBoolean(Pref.EXPERIMENTAL_ENABLE_WORD_CONFIRM, enableWordConfirm);
|
||||
editor.commit();
|
||||
}
|
||||
|
||||
public boolean getExperimentalEnableWordConfirm() {
|
||||
return mSharedPreferences.getBoolean(Pref.EXPERIMENTAL_ENABLE_WORD_CONFIRM, false);
|
||||
}
|
||||
|
||||
public void setExperimentalEnableLinkedIdentities(boolean enableLinkedIdentities) {
|
||||
SharedPreferences.Editor editor = mSharedPreferences.edit();
|
||||
editor.putBoolean(Pref.EXPERIMENTAL_ENABLE_LINKED_IDENTITIES, enableLinkedIdentities);
|
||||
editor.commit();
|
||||
}
|
||||
|
||||
public boolean getExperimentalEnableLinkedIdentities() {
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -193,6 +193,8 @@
|
|||
<string name="pref_keyserver_summary">"Search keys on selected OpenPGP keyservers (HKP protocol)"</string>
|
||||
<string name="pref_keybase">"keybase.io"</string>
|
||||
<string name="pref_keybase_summary">"Search keys on keybase.io"</string>
|
||||
<string name="pref_facebook">"Facebook"</string>
|
||||
<string name="pref_facebook_summary">"Search keys on Facebook by username"</string>
|
||||
|
||||
<string name="label_sync_settings_keyserver_title">"Automatic key updates"</string>
|
||||
<string name="label_sync_settings_keyserver_summary_on">"Every three days, keys are updated from the preferred keyserver"</string>
|
||||
|
@ -1294,6 +1296,7 @@
|
|||
<string name="msg_import_fetch_error_keyserver">"Could not retrieve key from keyservers: %s"</string>
|
||||
<string name="msg_import_fetch_error_keyserver_secret">"Cannot import secret key from keyserver!"</string>
|
||||
<string name="msg_import_fetch_keybase">"Retrieving from keybase.io: %s"</string>
|
||||
<string name="msg_import_fetch_facebook">"Retrieving from Facebook: %s"</string>
|
||||
<string name="msg_import_fetch_keyserver">"Retrieving from keyserver: %s"</string>
|
||||
<string name="msg_import_fetch_keyserver_ok">"Key retrieval successful"</string>
|
||||
<string name="msg_import_keyserver">"Using keyserver %s"</string>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<Preference
|
||||
android:persistent="false"
|
||||
android:persistent="true"
|
||||
android:selectable="false"
|
||||
android:title="@string/label_experimental_settings_desc_title"
|
||||
android:summary="@string/label_experimental_settings_desc_summary" />
|
||||
|
@ -8,21 +8,21 @@
|
|||
<SwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:key="experimentalEnableWordConfirm"
|
||||
android:persistent="false"
|
||||
android:persistent="true"
|
||||
android:summary="@string/label_experimental_settings_word_confirm_summary"
|
||||
android:title="@string/label_experimental_settings_word_confirm_title" />
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:key="experimentalEnableLinkedIdentities"
|
||||
android:persistent="false"
|
||||
android:persistent="true"
|
||||
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:persistent="true"
|
||||
android:summary="@string/label_experimental_settings_keybase_summary"
|
||||
android:title="@string/label_experimental_settings_keybase_title" />
|
||||
|
||||
|
@ -31,7 +31,7 @@
|
|||
android:entries="@array/theme_entries"
|
||||
android:entryValues="@array/theme_values"
|
||||
android:key="theme"
|
||||
android:persistent="false"
|
||||
android:persistent="true"
|
||||
android:title="@string/label_theme" />
|
||||
|
||||
</PreferenceScreen>
|
||||
|
|
|
@ -7,11 +7,11 @@
|
|||
android:title="@string/label_passphrase_cache_ttl" />
|
||||
<CheckBoxPreference
|
||||
android:key="passphraseCacheSubs"
|
||||
android:persistent="false"
|
||||
android:persistent="true"
|
||||
android:title="@string/label_passphrase_cache_subs" />
|
||||
<CheckBoxPreference
|
||||
android:defaultValue="false"
|
||||
android:key="useNumKeypadForYubikeyPin"
|
||||
android:persistent="false"
|
||||
android:persistent="true"
|
||||
android:title="@string/label_use_num_keypad_for_yubikey_pin" />
|
||||
</PreferenceScreen>
|
||||
|
|
Loading…
Reference in a new issue