From fcd27d2600711ccd32c000c6d58da19cb816a9bf Mon Sep 17 00:00:00 2001 From: Adithya Abraham Philip Date: Thu, 9 Jul 2015 22:51:20 +0530 Subject: implemented revocation on deletion --- .../keychain/operations/DeleteOperation.java | 18 ++- .../keychain/operations/EditKeyOperation.java | 33 +++++- .../keychain/operations/ExportOperation.java | 27 ++++- .../keychain/operations/RevokeOperation.java | 124 +++++++++++++++++++++ .../keychain/operations/results/DeleteResult.java | 16 ++- .../keychain/operations/results/EditKeyResult.java | 2 +- .../operations/results/InputPendingResult.java | 10 +- .../operations/results/OperationResult.java | 7 ++ .../keychain/operations/results/RevokeResult.java | 100 +++++++++++++++++ 9 files changed, 326 insertions(+), 11 deletions(-) create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/RevokeOperation.java create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/RevokeResult.java (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/DeleteOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/DeleteOperation.java index ac4a0da11..63c613aa6 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/DeleteOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/DeleteOperation.java @@ -18,19 +18,29 @@ package org.sufficientlysecure.keychain.operations; import android.content.Context; +import android.net.Uri; import android.support.annotation.NonNull; +import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.operations.results.ConsolidateResult; import org.sufficientlysecure.keychain.operations.results.DeleteResult; +import org.sufficientlysecure.keychain.operations.results.InputPendingResult; +import org.sufficientlysecure.keychain.operations.results.OperationResult; import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType; import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; import org.sufficientlysecure.keychain.pgp.Progressable; +import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException; +import org.sufficientlysecure.keychain.provider.CachedPublicKeyRing; +import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingData; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.service.ContactSyncAdapterService; import org.sufficientlysecure.keychain.service.DeleteKeyringParcel; +import org.sufficientlysecure.keychain.service.SaveKeyringParcel; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; +import org.sufficientlysecure.keychain.service.input.RequiredInputParcel; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; +import org.sufficientlysecure.keychain.util.Log; /** An operation which implements a high level keyring delete operation. * @@ -48,12 +58,17 @@ public class DeleteOperation extends BaseOperation { @NonNull @Override - public DeleteResult execute(DeleteKeyringParcel deleteKeyringParcel, + public OperationResult execute(DeleteKeyringParcel deleteKeyringParcel, CryptoInputParcel cryptoInputParcel) { long[] masterKeyIds = deleteKeyringParcel.mMasterKeyIds; boolean isSecret = deleteKeyringParcel.mIsSecret; + return onlyDeleteKey(masterKeyIds, isSecret); + } + + private DeleteResult onlyDeleteKey(long[] masterKeyIds, boolean isSecret) { + OperationLog log = new OperationLog(); if (masterKeyIds.length == 0) { @@ -113,7 +128,6 @@ public class DeleteOperation extends BaseOperation { } return new DeleteResult(result, log, success, fail); - } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/EditKeyOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/EditKeyOperation.java index eafbff4bc..f8f7e79a3 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/EditKeyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/EditKeyOperation.java @@ -21,7 +21,10 @@ import android.content.Context; import android.support.annotation.NonNull; import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.keyimport.HkpKeyserver; import org.sufficientlysecure.keychain.operations.results.EditKeyResult; +import org.sufficientlysecure.keychain.operations.results.ExportResult; +import org.sufficientlysecure.keychain.operations.results.InputPendingResult; import org.sufficientlysecure.keychain.operations.results.OperationResult; import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType; import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; @@ -34,6 +37,7 @@ import org.sufficientlysecure.keychain.pgp.UncachedKeyRing; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.provider.ProviderHelper.NotFoundException; import org.sufficientlysecure.keychain.service.ContactSyncAdapterService; +import org.sufficientlysecure.keychain.service.ExportKeyringParcel; import org.sufficientlysecure.keychain.service.PassphraseCacheService; import org.sufficientlysecure.keychain.service.SaveKeyringParcel; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; @@ -58,8 +62,16 @@ public class EditKeyOperation extends BaseOperation { super(context, providerHelper, progressable, cancelled); } + /** + * Saves an edited key, and uploads it to a server atomically or otherwise as + * specified in saveParcel + * + * @param saveParcel primary input to the operation + * @param cryptoInput input that changes if user interaction is required + * @return the result of the operation + */ @NonNull - public OperationResult execute(SaveKeyringParcel saveParcel, CryptoInputParcel cryptoInput) { + public InputPendingResult execute(SaveKeyringParcel saveParcel, CryptoInputParcel cryptoInput) { OperationLog log = new OperationLog(); log.add(LogType.MSG_ED, 0); @@ -120,6 +132,24 @@ public class EditKeyOperation extends BaseOperation { // It's a success, so this must be non-null now UncachedKeyRing ring = modifyResult.getRing(); + if (saveParcel.isUpload()) { + ExportKeyringParcel exportKeyringParcel = + new ExportKeyringParcel(saveParcel.getUploadKeyserver(), ring); + ExportResult uploadResult = + new ExportOperation(mContext, mProviderHelper, mProgressable) + .execute(exportKeyringParcel, cryptoInput); + if (uploadResult.isPending()) { + return uploadResult; + } else if (!uploadResult.success() && saveParcel.isUploadAtomic()) { + // if atomic, update fail implies edit operation should also fail and not save + log.add(uploadResult, 2); + return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, saveParcel.mMasterKeyId); + } else { + // upload succeeded or not atomic so we continue + log.add(uploadResult, 2); + } + } + // Save the new keyring. SaveKeyringResult saveResult = mProviderHelper .saveSecretKeyRing(ring, new ProgressScaler(mProgressable, 60, 95, 100)); @@ -160,5 +190,4 @@ public class EditKeyOperation extends BaseOperation { return new EditKeyResult(EditKeyResult.RESULT_OK, log, ring.getMasterKeyId()); } - } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ExportOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ExportOperation.java index 56ed4ef58..0dec35949 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ExportOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ExportOperation.java @@ -34,6 +34,7 @@ import android.content.Context; import android.database.Cursor; import android.net.Uri; import android.support.annotation.NonNull; +import android.support.annotation.Nullable; import android.text.TextUtils; import org.spongycastle.bcpg.ArmoredOutputStream; @@ -42,6 +43,7 @@ import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.keyimport.HkpKeyserver; import org.sufficientlysecure.keychain.keyimport.Keyserver.AddKeyException; import org.sufficientlysecure.keychain.operations.results.ExportResult; +import org.sufficientlysecure.keychain.operations.results.InputPendingResult; import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType; import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; import org.sufficientlysecure.keychain.pgp.CanonicalizedKeyRing; @@ -128,6 +130,18 @@ public class ExportOperation extends BaseOperation { } } + /** + * returns null if no user input required for upload, an InputPendingResult otherwise + */ + @Nullable + public InputPendingResult getUploadPendingInput() { + if (!OrbotHelper.isOrbotInRequiredState(mContext)) { + return new ExportResult(null, + RequiredInputParcel.createOrbotRequiredOperation()); + } + return null; + } + public ExportResult exportToFile(long[] masterKeyIds, boolean exportSecret, String outputFile) { OperationLog log = new OperationLog(); @@ -351,10 +365,15 @@ public class ExportOperation extends BaseOperation { HkpKeyserver hkpKeyserver = new HkpKeyserver(exportInput.mKeyserver); try { - CanonicalizedPublicKeyRing keyring - = mProviderHelper.getCanonicalizedPublicKeyRing( - exportInput.mCanonicalizedPublicKeyringUri); - return uploadKeyRingToServer(hkpKeyserver, keyring, proxy); + if (exportInput.mCanonicalizedPublicKeyringUri != null) { + CanonicalizedPublicKeyRing keyring + = mProviderHelper.getCanonicalizedPublicKeyRing( + exportInput.mCanonicalizedPublicKeyringUri); + return uploadKeyRingToServer(hkpKeyserver, keyring, proxy); + } else { + return uploadKeyRingToServer(hkpKeyserver, exportInput.mUncachedKeyRing, + proxy); + } } catch (ProviderHelper.NotFoundException e) { Log.e(Constants.TAG, "error uploading key", e); return new ExportResult(ExportResult.RESULT_ERROR, new OperationLog()); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/RevokeOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/RevokeOperation.java new file mode 100644 index 000000000..157e36e04 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/RevokeOperation.java @@ -0,0 +1,124 @@ +package org.sufficientlysecure.keychain.operations; + +import android.content.Context; +import android.database.Cursor; +import android.net.Uri; +import android.support.annotation.NonNull; + +import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.operations.results.DeleteResult; +import org.sufficientlysecure.keychain.operations.results.InputPendingResult; +import org.sufficientlysecure.keychain.operations.results.OperationResult; +import org.sufficientlysecure.keychain.operations.results.RevokeResult; +import org.sufficientlysecure.keychain.pgp.Progressable; +import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException; +import org.sufficientlysecure.keychain.provider.CachedPublicKeyRing; +import org.sufficientlysecure.keychain.provider.KeychainContract; +import org.sufficientlysecure.keychain.provider.ProviderHelper; +import org.sufficientlysecure.keychain.service.RevokeKeyringParcel; +import org.sufficientlysecure.keychain.service.SaveKeyringParcel; +import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; +import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; +import org.sufficientlysecure.keychain.util.Log; + +public class RevokeOperation extends BaseOperation { + + public RevokeOperation(Context context, ProviderHelper providerHelper, Progressable progressable) { + super(context, providerHelper, progressable); + } + + @NonNull + @Override + public OperationResult execute(RevokeKeyringParcel revokeKeyringParcel, + CryptoInputParcel cryptoInputParcel) { + + long masterKeyId = revokeKeyringParcel.mMasterKeyId; + + OperationResult.OperationLog log = new OperationResult.OperationLog(); + log.add(OperationResult.LogType.MSG_REVOKE, 0, + KeyFormattingUtils.beautifyKeyId(masterKeyId)); + + try { + + Uri secretUri = KeychainContract.KeyRings.buildUnifiedKeyRingUri(masterKeyId); + CachedPublicKeyRing keyRing = mProviderHelper.getCachedPublicKeyRing(secretUri); + + // check if this is a master secret key we can work with + switch (keyRing.getSecretKeyType(masterKeyId)) { + case GNU_DUMMY: + log.add(OperationResult.LogType.MSG_EK_ERROR_DUMMY, 1); + return new RevokeResult(RevokeResult.RESULT_ERROR, log, masterKeyId); + } + + SaveKeyringParcel saveKeyringParcel = getRevokedSaveKeyringParcel(masterKeyId, + keyRing.getFingerprint()); + + // all revoke operations are made atomic as of now + saveKeyringParcel.setUpdateOptions(revokeKeyringParcel.mUpload, true, + revokeKeyringParcel.mKeyserver); + + InputPendingResult revokeAndUploadResult = new EditKeyOperation(mContext, + mProviderHelper, mProgressable, mCancelled) + .execute(saveKeyringParcel, cryptoInputParcel); + + if (revokeAndUploadResult.isPending()) { + return revokeAndUploadResult; + } + + log.add(revokeAndUploadResult, 1); + + if (revokeAndUploadResult.success()) { + log.add(OperationResult.LogType.MSG_REVOKE_OK, 1); + return new RevokeResult(RevokeResult.RESULT_OK, log, masterKeyId); + } else { + log.add(OperationResult.LogType.MSG_REVOKE_KEY_FAIL, 1); + return new RevokeResult(RevokeResult.RESULT_ERROR, log, masterKeyId); + } + + } catch (PgpKeyNotFoundException | ProviderHelper.NotFoundException e) { + Log.e(Constants.TAG, "could not find key to revoke", e); + log.add(OperationResult.LogType.MSG_REVOKE_KEY_FAIL, 1); + return new RevokeResult(RevokeResult.RESULT_ERROR, log, masterKeyId); + } + } + + private SaveKeyringParcel getRevokedSaveKeyringParcel(long masterKeyId, byte[] fingerprint) { + final String[] SUBKEYS_PROJECTION = new String[]{ + KeychainContract.Keys.KEY_ID + }; + final int INDEX_KEY_ID = 0; + + Uri keysUri = KeychainContract.Keys.buildKeysUri(masterKeyId); + Cursor subKeyCursor = + mContext.getContentResolver().query(keysUri, SUBKEYS_PROJECTION, null, null, null); + + SaveKeyringParcel saveKeyringParcel = + new SaveKeyringParcel(masterKeyId, fingerprint); + + // add all subkeys, for revocation + while (subKeyCursor != null && subKeyCursor.moveToNext()) { + saveKeyringParcel.mRevokeSubKeys.add(subKeyCursor.getLong(INDEX_KEY_ID)); + } + if (subKeyCursor != null) { + subKeyCursor.close(); + } + + final String[] USER_IDS_PROJECTION = new String[]{ + KeychainContract.UserPackets.USER_ID + }; + final int INDEX_USER_ID = 0; + + Uri userIdsUri = KeychainContract.UserPackets.buildUserIdsUri(masterKeyId); + Cursor userIdCursor = mContext.getContentResolver().query( + userIdsUri, USER_IDS_PROJECTION, null, null, null); + + while (userIdCursor != null && userIdCursor.moveToNext()) { + saveKeyringParcel.mRevokeUserIds.add(userIdCursor.getString(INDEX_USER_ID)); + } + if (userIdCursor != null) { + userIdCursor.close(); + } + + return saveKeyringParcel; + } +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/DeleteResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/DeleteResult.java index 52ff8bf44..52c6e1491 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/DeleteResult.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/DeleteResult.java @@ -21,8 +21,10 @@ package org.sufficientlysecure.keychain.operations.results; import android.app.Activity; import android.content.Intent; import android.os.Parcel; +import android.support.annotation.Nullable; import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.service.input.RequiredInputParcel; import org.sufficientlysecure.keychain.ui.LogDisplayActivity; import org.sufficientlysecure.keychain.ui.LogDisplayFragment; import org.sufficientlysecure.keychain.ui.util.Notify; @@ -30,7 +32,7 @@ import org.sufficientlysecure.keychain.ui.util.Notify.ActionListener; import org.sufficientlysecure.keychain.ui.util.Notify.Showable; import org.sufficientlysecure.keychain.ui.util.Notify.Style; -public class DeleteResult extends OperationResult { +public class DeleteResult extends InputPendingResult { final public int mOk, mFail; @@ -40,6 +42,18 @@ public class DeleteResult extends OperationResult { mFail = fail; } + /** + * used when more input is required + * @param log operation log upto point of required input, if any + * @param requiredInput represents input required + */ + public DeleteResult(@Nullable OperationLog log, RequiredInputParcel requiredInput) { + super(log, requiredInput); + // values are not to be used + mOk = -1; + mFail = -1; + } + /** Construct from a parcel - trivial because we have no extra data. */ public DeleteResult(Parcel source) { super(source); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/EditKeyResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/EditKeyResult.java index 842b75c3b..b9407a864 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/EditKeyResult.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/EditKeyResult.java @@ -20,7 +20,7 @@ package org.sufficientlysecure.keychain.operations.results; import android.os.Parcel; -public class EditKeyResult extends OperationResult { +public class EditKeyResult extends InputPendingResult { public final Long mMasterKeyId; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/InputPendingResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/InputPendingResult.java index 0b7aa6d03..5b982ca61 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/InputPendingResult.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/InputPendingResult.java @@ -22,6 +22,7 @@ import java.util.ArrayList; import android.os.Parcel; +import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; import org.sufficientlysecure.keychain.service.input.RequiredInputParcel; public class InputPendingResult extends OperationResult { @@ -30,26 +31,33 @@ public class InputPendingResult extends OperationResult { public static final int RESULT_PENDING = RESULT_ERROR + 8; final RequiredInputParcel mRequiredInput; + // in case operation needs to add to/changes the cryptoInputParcel sent to it + final CryptoInputParcel mCryptoInputParcel; public InputPendingResult(int result, OperationLog log) { super(result, log); mRequiredInput = null; + mCryptoInputParcel = null; } - public InputPendingResult(OperationLog log, RequiredInputParcel requiredInput) { + public InputPendingResult(OperationLog log, RequiredInputParcel requiredInput, + CryptoInputParcel cryptoInputParcel) { super(RESULT_PENDING, log); mRequiredInput = requiredInput; + mCryptoInputParcel = cryptoInputParcel; } public InputPendingResult(Parcel source) { super(source); mRequiredInput = source.readParcelable(getClass().getClassLoader()); + mCryptoInputParcel = source.readParcelable(getClass().getClassLoader()); } @Override public void writeToParcel(Parcel dest, int flags) { super.writeToParcel(dest, flags); dest.writeParcelable(mRequiredInput, 0); + dest.writeParcelable(mCryptoInputParcel, 0); } public boolean isPending() { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java index 88d04350c..5105b7fdc 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java @@ -760,6 +760,13 @@ public abstract class OperationResult implements Parcelable { MSG_DEL_OK (LogLevel.OK, R.plurals.msg_del_ok), MSG_DEL_FAIL (LogLevel.WARN, R.plurals.msg_del_fail), + MSG_REVOKE_ERROR_EMPTY (LogLevel.ERROR, R.string.msg_revoke_error_empty), + MSG_REVOKE_ERROR_MULTI_SECRET (LogLevel.DEBUG, R.string.msg_revoke_error_multi_secret), + MSG_REVOKE_ERROR_NOT_FOUND (LogLevel.DEBUG, R.string.msg_revoke_error_multi_secret), + MSG_REVOKE (LogLevel.DEBUG, R.string.msg_revoke_key), + MSG_REVOKE_KEY_FAIL (LogLevel.WARN, R.string.msg_revoke_key_fail), + MSG_REVOKE_OK (LogLevel.OK, R.string.msg_revoke_ok), + // keybase verification MSG_KEYBASE_VERIFICATION(LogLevel.START, R.string.msg_keybase_verification), diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/RevokeResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/RevokeResult.java new file mode 100644 index 000000000..4b4892b05 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/RevokeResult.java @@ -0,0 +1,100 @@ +package org.sufficientlysecure.keychain.operations.results; + +import android.app.Activity; +import android.content.Intent; +import android.os.Parcel; +import android.os.Parcelable; +import android.support.annotation.Nullable; + +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.service.input.RequiredInputParcel; +import org.sufficientlysecure.keychain.ui.LogDisplayActivity; +import org.sufficientlysecure.keychain.ui.LogDisplayFragment; +import org.sufficientlysecure.keychain.ui.util.Notify; + +public class RevokeResult extends InputPendingResult { + + public final long mMasterKeyId; + + public RevokeResult(int result, OperationLog log, long masterKeyId) { + super(result, log); + mMasterKeyId = masterKeyId; + } + + /** + * used when more input is required + * @param log operation log upto point of required input, if any + * @param requiredInput represents input required + */ + public RevokeResult(@Nullable OperationLog log, RequiredInputParcel requiredInput) { + super(log, requiredInput); + // we won't use these values + mMasterKeyId = -1; + } + + /** Construct from a parcel - trivial because we have no extra data. */ + public RevokeResult(Parcel source) { + super(source); + mMasterKeyId = source.readLong(); + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + super.writeToParcel(dest, flags); + dest.writeLong(mMasterKeyId); + } + + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + @Override + public RevokeResult createFromParcel(Parcel in) { + return new RevokeResult(in); + } + + @Override + public RevokeResult[] newArray(int size) { + return new RevokeResult[size]; + } + }; + + @Override + public Notify.Showable createNotify(final Activity activity) { + + int resultType = getResult(); + + String str; + int duration; + Notify.Style style; + + // Not an overall failure + if ((resultType & OperationResult.RESULT_ERROR) == 0) { + + duration = Notify.LENGTH_LONG; + + // New and updated keys + if (resultType == OperationResult.RESULT_OK) { + style = Notify.Style.OK; + str = activity.getString(R.string.revoke_ok); + } else { + duration = 0; + style = Notify.Style.ERROR; + str = "internal error"; + } + + } else { + duration = 0; + style = Notify.Style.ERROR; + str = activity.getString(R.string.revoke_fail); + } + + return Notify.create(activity, str, duration, style, new Notify.ActionListener() { + @Override + public void onAction() { + Intent intent = new Intent( + activity, LogDisplayActivity.class); + intent.putExtra(LogDisplayFragment.EXTRA_RESULT, RevokeResult.this); + activity.startActivity(intent); + } + }, R.string.snackbar_details); + + } +} -- cgit v1.2.3