ImportKeys: Add ability to "Show key" instead of "Import" for already imported keys

This commit is contained in:
Andrea Torlaschi
2016-08-24 11:42:06 +02:00
parent 48266fd8e0
commit 702888bbe4
6 changed files with 71 additions and 16 deletions

View File

@@ -29,6 +29,7 @@ import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import java.io.IOException; import java.io.IOException;
import java.io.Serializable; import java.io.Serializable;
import java.math.BigInteger;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
@@ -48,18 +49,23 @@ public class ImportKeysListEntry implements Serializable, Parcelable {
private ArrayList<Map.Entry<String, HashSet<String>>> mSortedUserIds; private ArrayList<Map.Entry<String, HashSet<String>>> mSortedUserIds;
private String mKeyIdHex; private String mKeyIdHex;
private boolean mSecretKey;
private boolean mRevoked; private boolean mRevoked;
private boolean mExpired; private boolean mExpired;
private Date mDate; // TODO: not displayed private boolean mUpdated;
private Date mDate;
private String mFingerprintHex; private String mFingerprintHex;
private Integer mBitStrength; private Integer mBitStrength;
private String mCurveOid; private String mCurveOid;
private String mAlgorithm; private String mAlgorithm;
private boolean mSecretKey;
private UserId mPrimaryUserId; private UserId mPrimaryUserId;
private String mKeyserver; private String mKeyserver;
private String mKeybaseName; private String mKeybaseName;
private String mFbUsername; private String mFbUsername;
private String mQuery; private String mQuery;
private Integer mHashCode = null; private Integer mHashCode = null;
@@ -82,6 +88,10 @@ public class ImportKeysListEntry implements Serializable, Parcelable {
return mKeyIdHex; return mKeyIdHex;
} }
public long getKeyId() {
return new BigInteger(mKeyIdHex.substring(2), 16).longValue();
}
public void setKeyIdHex(String keyIdHex) { public void setKeyIdHex(String keyIdHex) {
mKeyIdHex = keyIdHex; mKeyIdHex = keyIdHex;
} }
@@ -114,6 +124,14 @@ public class ImportKeysListEntry implements Serializable, Parcelable {
return mDate; return mDate;
} }
public boolean isUpdated() {
return mUpdated;
}
public void setUpdated(boolean updated) {
mUpdated = updated;
}
public void setDate(Date date) { public void setDate(Date date) {
mDate = date; mDate = date;
} }
@@ -343,6 +361,7 @@ public class ImportKeysListEntry implements Serializable, Parcelable {
dest.writeSerializable(mMergedUserIds); dest.writeSerializable(mMergedUserIds);
dest.writeByte((byte) (mRevoked ? 1 : 0)); dest.writeByte((byte) (mRevoked ? 1 : 0));
dest.writeByte((byte) (mExpired ? 1 : 0)); dest.writeByte((byte) (mExpired ? 1 : 0));
dest.writeByte((byte) (mUpdated ? 1 : 0));
dest.writeInt(mDate == null ? 0 : 1); dest.writeInt(mDate == null ? 0 : 1);
if (mDate != null) { if (mDate != null) {
dest.writeLong(mDate.getTime()); dest.writeLong(mDate.getTime());
@@ -370,6 +389,7 @@ public class ImportKeysListEntry implements Serializable, Parcelable {
vr.mMergedUserIds = (HashMap<String, HashSet<String>>) source.readSerializable(); vr.mMergedUserIds = (HashMap<String, HashSet<String>>) source.readSerializable();
vr.mRevoked = source.readByte() == 1; vr.mRevoked = source.readByte() == 1;
vr.mExpired = source.readByte() == 1; vr.mExpired = source.readByte() == 1;
vr.mUpdated = source.readByte() == 1;
vr.mDate = source.readInt() != 0 ? new Date(source.readLong()) : null; vr.mDate = source.readInt() != 0 ? new Date(source.readLong()) : null;
vr.mFingerprintHex = source.readString(); vr.mFingerprintHex = source.readString();
vr.mKeyIdHex = source.readString(); vr.mKeyIdHex = source.readString();

View File

@@ -926,10 +926,12 @@ public class ProviderHelper {
} }
CanonicalizedPublicKeyRing canPublicRing; CanonicalizedPublicKeyRing canPublicRing;
boolean alreadyExists = false;
// If there is an old keyring, merge it // If there is an old keyring, merge it
try { try {
UncachedKeyRing oldPublicRing = getCanonicalizedPublicKeyRing(masterKeyId).getUncachedKeyRing(); UncachedKeyRing oldPublicRing = getCanonicalizedPublicKeyRing(masterKeyId).getUncachedKeyRing();
alreadyExists = true;
// Merge data from new public ring into the old one // Merge data from new public ring into the old one
log(LogType.MSG_IP_MERGE_PUBLIC); log(LogType.MSG_IP_MERGE_PUBLIC);
@@ -998,18 +1000,23 @@ public class ProviderHelper {
} }
} }
int result = SaveKeyringResult.SAVED_PUBLIC; int result;
if (!skipSave) { if (!skipSave) {
result = saveCanonicalizedPublicKeyRing(canPublicRing, progress, canSecretRing != null); result = saveCanonicalizedPublicKeyRing(canPublicRing, progress, canSecretRing != null);
} else {
result = SaveKeyringResult.SAVED_PUBLIC
| (alreadyExists ? SaveKeyringResult.UPDATED : 0);
} }
// Save the saved keyring (if any) // Save the saved keyring (if any)
if (canSecretRing != null) { if (canSecretRing != null) {
progress.setProgress(LogType.MSG_IP_REINSERT_SECRET.getMsgId(), 90, 100); progress.setProgress(LogType.MSG_IP_REINSERT_SECRET.getMsgId(), 90, 100);
int secretResult = SaveKeyringResult.SAVED_SECRET; int secretResult;
if (!skipSave) { if (!skipSave) {
saveCanonicalizedSecretKeyRing(canSecretRing); secretResult = saveCanonicalizedSecretKeyRing(canSecretRing);
} else {
secretResult = SaveKeyringResult.SAVED_SECRET;
} }
if ((secretResult & SaveKeyringResult.RESULT_ERROR) != SaveKeyringResult.RESULT_ERROR) { if ((secretResult & SaveKeyringResult.RESULT_ERROR) != SaveKeyringResult.RESULT_ERROR) {
@@ -1018,7 +1025,6 @@ public class ProviderHelper {
} }
return new SaveKeyringResult(result, mLog, canSecretRing); return new SaveKeyringResult(result, mLog, canSecretRing);
} catch (IOException e) { } catch (IOException e) {
log(LogType.MSG_IP_ERROR_IO_EXC); log(LogType.MSG_IP_ERROR_IO_EXC);
return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog, null); return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog, null);
@@ -1051,10 +1057,12 @@ public class ProviderHelper {
} }
CanonicalizedSecretKeyRing canSecretRing; CanonicalizedSecretKeyRing canSecretRing;
boolean alreadyExists = false;
// If there is an old secret key, merge it. // If there is an old secret key, merge it.
try { try {
UncachedKeyRing oldSecretRing = getCanonicalizedSecretKeyRing(masterKeyId).getUncachedKeyRing(); UncachedKeyRing oldSecretRing = getCanonicalizedSecretKeyRing(masterKeyId).getUncachedKeyRing();
alreadyExists = true;
// Merge data from new secret ring into old one // Merge data from new secret ring into old one
log(LogType.MSG_IS_MERGE_SECRET); log(LogType.MSG_IS_MERGE_SECRET);
@@ -1129,9 +1137,11 @@ public class ProviderHelper {
return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog, null); return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog, null);
} }
int publicResult = SaveKeyringResult.SAVED_PUBLIC; int publicResult;
if (!skipSave) { if (!skipSave) {
publicResult = saveCanonicalizedPublicKeyRing(canPublicRing, progress, true); publicResult = saveCanonicalizedPublicKeyRing(canPublicRing, progress, true);
} else {
publicResult = SaveKeyringResult.SAVED_PUBLIC;
} }
if ((publicResult & SaveKeyringResult.RESULT_ERROR) == SaveKeyringResult.RESULT_ERROR) { if ((publicResult & SaveKeyringResult.RESULT_ERROR) == SaveKeyringResult.RESULT_ERROR) {
@@ -1140,13 +1150,15 @@ public class ProviderHelper {
progress.setProgress(LogType.MSG_IP_REINSERT_SECRET.getMsgId(), 90, 100); progress.setProgress(LogType.MSG_IP_REINSERT_SECRET.getMsgId(), 90, 100);
int result = SaveKeyringResult.SAVED_SECRET; int result;
if (!skipSave) { if (!skipSave) {
result = saveCanonicalizedSecretKeyRing(canSecretRing); result = saveCanonicalizedSecretKeyRing(canSecretRing);
} else {
result = SaveKeyringResult.SAVED_SECRET
| (alreadyExists ? SaveKeyringResult.UPDATED : 0);
} }
return new SaveKeyringResult(result, mLog, canSecretRing); return new SaveKeyringResult(result, mLog, canSecretRing);
} catch (IOException e) { } catch (IOException e) {
log(LogType.MSG_IS_ERROR_IO_EXC); log(LogType.MSG_IS_ERROR_IO_EXC);
return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog, null); return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog, null);

View File

@@ -17,11 +17,13 @@
package org.sufficientlysecure.keychain.ui.adapter; package org.sufficientlysecure.keychain.ui.adapter;
import android.content.Intent;
import android.databinding.DataBindingUtil; import android.databinding.DataBindingUtil;
import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentActivity;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup; import android.view.ViewGroup;
import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Constants;
@@ -35,7 +37,9 @@ import org.sufficientlysecure.keychain.keyimport.processing.ImportKeysResultList
import org.sufficientlysecure.keychain.operations.ImportOperation; import org.sufficientlysecure.keychain.operations.ImportOperation;
import org.sufficientlysecure.keychain.operations.results.ImportKeyResult; import org.sufficientlysecure.keychain.operations.results.ImportKeyResult;
import org.sufficientlysecure.keychain.pgp.CanonicalizedKeyRing; import org.sufficientlysecure.keychain.pgp.CanonicalizedKeyRing;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
import org.sufficientlysecure.keychain.service.ImportKeyringParcel; import org.sufficientlysecure.keychain.service.ImportKeyringParcel;
import org.sufficientlysecure.keychain.ui.ViewKeyActivity;
import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper; import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper;
import org.sufficientlysecure.keychain.ui.util.Notify; import org.sufficientlysecure.keychain.ui.util.Notify;
import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Log;
@@ -131,7 +135,7 @@ public class ImportKeysAdapter extends RecyclerView.Adapter<ImportKeysAdapter.Vi
final boolean downloaded = keyState.mDownloaded; final boolean downloaded = keyState.mDownloaded;
final boolean showed = keyState.mShowed; final boolean showed = keyState.mShowed;
b.card.setOnClickListener(new View.OnClickListener() { b.card.setOnClickListener(new OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
mCurrent = position; mCurrent = position;
@@ -143,13 +147,22 @@ public class ImportKeysAdapter extends RecyclerView.Adapter<ImportKeysAdapter.Vi
} }
}); });
b.extra.importKey.setOnClickListener(new View.OnClickListener() { b.extra.importKey.setOnClickListener(new OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
getKey(entry, false); getKey(entry, false);
} }
}); });
b.extra.showKey.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(mActivity, ViewKeyActivity.class);
intent.setData(KeyRings.buildGenericKeyRingUri(entry.getKeyId()));
mActivity.startActivity(intent);
}
});
b.extraContainer.setVisibility(showed ? View.VISIBLE : View.GONE); b.extraContainer.setVisibility(showed ? View.VISIBLE : View.GONE);
} }
@@ -210,6 +223,7 @@ public class ImportKeysAdapter extends RecyclerView.Adapter<ImportKeysAdapter.Vi
entry.setRevoked(keyRing.isRevoked()); entry.setRevoked(keyRing.isRevoked());
entry.setExpired(keyRing.isExpired()); entry.setExpired(keyRing.isExpired());
entry.setUpdated(result.isOkUpdated());
entry.setDate(keyRing.getCreationDate()); entry.setDate(keyRing.getCreationDate());
entry.setKeyId(keyRing.getMasterKeyId()); entry.setKeyId(keyRing.getMasterKeyId());

View File

@@ -7,7 +7,6 @@
<variable name="nonInteractive" type="boolean" /> <variable name="nonInteractive" type="boolean" />
<variable name="entry" type="ImportKeysListEntry" /> <variable name="entry" type="ImportKeysListEntry" />
<variable name="expanded" type="boolean" />
</data> </data>
<android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto" <android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto"

View File

@@ -2,6 +2,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto"> xmlns:app="http://schemas.android.com/apk/res-auto">
<data> <data>
<import type="android.view.View" alias="V" />
<import type="org.sufficientlysecure.keychain.keyimport.ImportKeysListEntry" /> <import type="org.sufficientlysecure.keychain.keyimport.ImportKeysListEntry" />
<variable name="entry" type="ImportKeysListEntry" /> <variable name="entry" type="ImportKeysListEntry" />
@@ -98,7 +99,14 @@
<Button <Button
android:id="@+id/import_key" android:id="@+id/import_key"
style="@style/CardViewActionButton" style="@style/CardViewActionButton"
android:text="@string/btn_import" /> android:text="@string/btn_import"
android:visibility="@{entry.updated ? V.GONE : V.VISIBLE}" />
<Button
android:id="@+id/show_key"
style="@style/CardViewActionButton"
android:text="@string/btn_show_key"
android:visibility="@{entry.updated ? V.VISIBLE : V.GONE}" />
</LinearLayout> </LinearLayout>

View File

@@ -532,6 +532,11 @@
<string name="import_qr_code_too_short_fingerprint">"Fingerprint is too short!"</string> <string name="import_qr_code_too_short_fingerprint">"Fingerprint is too short!"</string>
<string name="import_qr_code_button">"Scan QR Code"</string> <string name="import_qr_code_button">"Scan QR Code"</string>
<string name="import_qr_code_text">"Place your camera over the QR Code!"</string> <string name="import_qr_code_text">"Place your camera over the QR Code!"</string>
<string name="btn_import">"Import"</string>
<string name="btn_import_keys">"Import all keys"</string>
<string name="btn_view_list">"View list"</string>
<string name="btn_refresh">"Refresh"</string>
<string name="btn_show_key">"Show key"</string>
<!-- Import from URL --> <!-- Import from URL -->
<string name="import_url_warn_no_search_parameter">"No search query defined. You can still manually search on this keyserver."</string> <string name="import_url_warn_no_search_parameter">"No search query defined. You can still manually search on this keyserver."</string>
@@ -1573,9 +1578,6 @@
<string name="security_token_status_partly">"Security Token matches, partly bound to key"</string> <string name="security_token_status_partly">"Security Token matches, partly bound to key"</string>
<string name="security_token_create">"Hold Security Token against the back of your device."</string> <string name="security_token_create">"Hold Security Token against the back of your device."</string>
<string name="security_token_reset_or_import">"This Security Token already contains a key. You can import the key using the cloud or reset the Security Token."</string> <string name="security_token_reset_or_import">"This Security Token already contains a key. You can import the key using the cloud or reset the Security Token."</string>
<string name="btn_import">"Import"</string>
<string name="btn_import_keys">"Import all keys"</string>
<string name="btn_view_list">"View list"</string>
<string name="btn_reset">"Reset"</string> <string name="btn_reset">"Reset"</string>
<string name="security_token_import_radio">"Import key"</string> <string name="security_token_import_radio">"Import key"</string>
<string name="security_token_reset_radio">"Reset Security Token"</string> <string name="security_token_reset_radio">"Reset Security Token"</string>