introduce EditKeyResult with transient UncachedKeyRing (half-baked!)

This commit is contained in:
Vincent Breitmoser 2014-07-27 01:22:10 +02:00
parent a8782272b3
commit f4ee71e3ef
14 changed files with 99 additions and 51 deletions

View File

@ -47,9 +47,11 @@ import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyEncryptorBuilder;
import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralMsgIdException; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralMsgIdException;
import org.sufficientlysecure.keychain.service.OperationResultParcel;
import org.sufficientlysecure.keychain.service.OperationResultParcel.LogLevel; import org.sufficientlysecure.keychain.service.OperationResultParcel.LogLevel;
import org.sufficientlysecure.keychain.service.OperationResultParcel.LogType; import org.sufficientlysecure.keychain.service.OperationResultParcel.LogType;
import org.sufficientlysecure.keychain.service.OperationResultParcel.OperationLog; import org.sufficientlysecure.keychain.service.OperationResultParcel.OperationLog;
import org.sufficientlysecure.keychain.service.OperationResults.EditKeyResult;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel; import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.SubkeyAdd; import org.sufficientlysecure.keychain.service.SaveKeyringParcel.SubkeyAdd;
import org.sufficientlysecure.keychain.util.IterableIterator; import org.sufficientlysecure.keychain.util.IterableIterator;
@ -163,8 +165,10 @@ public class PgpKeyOperation {
} }
} }
public UncachedKeyRing createSecretKeyRing(SaveKeyringParcel saveParcel, OperationLog log, public EditKeyResult createSecretKeyRing(SaveKeyringParcel saveParcel) {
int indent) {
OperationLog log = new OperationLog();
int indent = 0;
try { try {
@ -213,7 +217,7 @@ public class PgpKeyOperation {
PGPSecretKeyRing sKR = new PGPSecretKeyRing( PGPSecretKeyRing sKR = new PGPSecretKeyRing(
masterSecretKey.getEncoded(), new JcaKeyFingerprintCalculator()); masterSecretKey.getEncoded(), new JcaKeyFingerprintCalculator());
return internal(sKR, masterSecretKey, add.mFlags, saveParcel, "", log, indent); return internal(sKR, masterSecretKey, add.mFlags, saveParcel, "", log);
} catch (PGPException e) { } catch (PGPException e) {
log.add(LogLevel.ERROR, LogType.MSG_CR_ERROR_INTERNAL_PGP, indent); log.add(LogLevel.ERROR, LogType.MSG_CR_ERROR_INTERNAL_PGP, indent);
@ -237,8 +241,11 @@ public class PgpKeyOperation {
* are changed by adding new certificates, which implicitly override older certificates. * are changed by adding new certificates, which implicitly override older certificates.
* *
*/ */
public UncachedKeyRing modifySecretKeyRing(WrappedSecretKeyRing wsKR, SaveKeyringParcel saveParcel, public EditKeyResult modifySecretKeyRing(WrappedSecretKeyRing wsKR, SaveKeyringParcel saveParcel,
String passphrase, OperationLog log, int indent) { String passphrase) {
OperationLog log = new OperationLog();
int indent = 0;
/* /*
* 1. Unlock private key * 1. Unlock private key
@ -277,14 +284,16 @@ public class PgpKeyOperation {
// since this is the master key, this contains at least CERTIFY_OTHER // since this is the master key, this contains at least CERTIFY_OTHER
int masterKeyFlags = readKeyFlags(masterSecretKey.getPublicKey()) | KeyFlags.CERTIFY_OTHER; int masterKeyFlags = readKeyFlags(masterSecretKey.getPublicKey()) | KeyFlags.CERTIFY_OTHER;
return internal(sKR, masterSecretKey, masterKeyFlags, saveParcel, passphrase, log, indent); return internal(sKR, masterSecretKey, masterKeyFlags, saveParcel, passphrase, log);
} }
private UncachedKeyRing internal(PGPSecretKeyRing sKR, PGPSecretKey masterSecretKey, private EditKeyResult internal(PGPSecretKeyRing sKR, PGPSecretKey masterSecretKey,
int masterKeyFlags, int masterKeyFlags,
SaveKeyringParcel saveParcel, String passphrase, SaveKeyringParcel saveParcel, String passphrase,
OperationLog log, int indent) { OperationLog log) {
int indent = 1;
updateProgress(R.string.progress_certifying_master_key, 20, 100); updateProgress(R.string.progress_certifying_master_key, 20, 100);
@ -613,7 +622,7 @@ public class PgpKeyOperation {
} }
log.add(LogLevel.OK, LogType.MSG_MF_SUCCESS, indent); log.add(LogLevel.OK, LogType.MSG_MF_SUCCESS, indent);
return new UncachedKeyRing(sKR); return new EditKeyResult(OperationResultParcel.RESULT_OK, log, new UncachedKeyRing(sKR));
} }

View File

@ -24,6 +24,7 @@ import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.os.Message; import android.os.Message;
import android.os.Messenger; import android.os.Messenger;
import android.os.Parcelable;
import android.os.RemoteException; import android.os.RemoteException;
import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Constants;
@ -53,6 +54,7 @@ import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
import org.sufficientlysecure.keychain.provider.KeychainDatabase; import org.sufficientlysecure.keychain.provider.KeychainDatabase;
import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.service.OperationResultParcel.OperationLog; import org.sufficientlysecure.keychain.service.OperationResultParcel.OperationLog;
import org.sufficientlysecure.keychain.service.OperationResults.EditKeyResult;
import org.sufficientlysecure.keychain.service.OperationResults.ImportKeyResult; import org.sufficientlysecure.keychain.service.OperationResults.ImportKeyResult;
import org.sufficientlysecure.keychain.util.InputData; import org.sufficientlysecure.keychain.util.InputData;
import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Log;
@ -333,38 +335,36 @@ public class KeychainIntentService extends IntentService
/* Operation */ /* Operation */
ProviderHelper providerHelper = new ProviderHelper(this); ProviderHelper providerHelper = new ProviderHelper(this);
PgpKeyOperation keyOperations = new PgpKeyOperation(new ProgressScaler(this, 10, 50, 100)); PgpKeyOperation keyOperations = new PgpKeyOperation(new ProgressScaler(this, 10, 50, 100));
try { EditKeyResult result;
OperationLog log = new OperationLog();
UncachedKeyRing ring;
if (saveParcel.mMasterKeyId != null) {
String passphrase = data.getString(SAVE_KEYRING_PASSPHRASE);
WrappedSecretKeyRing secRing =
providerHelper.getWrappedSecretKeyRing(saveParcel.mMasterKeyId);
ring = keyOperations.modifySecretKeyRing(secRing, saveParcel, if (saveParcel.mMasterKeyId != null) {
passphrase, log, 0); String passphrase = data.getString(SAVE_KEYRING_PASSPHRASE);
} else { WrappedSecretKeyRing secRing =
ring = keyOperations.createSecretKeyRing(saveParcel, log, 0); providerHelper.getWrappedSecretKeyRing(saveParcel.mMasterKeyId);
}
providerHelper.saveSecretKeyRing(ring, new ProgressScaler(this, 10, 95, 100)); result = keyOperations.modifySecretKeyRing(secRing, saveParcel, passphrase);
} else {
result = keyOperations.createSecretKeyRing(saveParcel);
}
// cache new passphrase UncachedKeyRing ring = result.getRing();
if (saveParcel.mNewPassphrase != null) {
PassphraseCacheService.addCachedPassphrase(this, ring.getMasterKeyId(), providerHelper.saveSecretKeyRing(ring, new ProgressScaler(this, 10, 95, 100));
saveParcel.mNewPassphrase, ring.getPublicKey().getPrimaryUserIdWithFallback());
} // cache new passphrase
} catch (ProviderHelper.NotFoundException e) { if (saveParcel.mNewPassphrase != null) {
sendErrorToHandler(e); PassphraseCacheService.addCachedPassphrase(this, ring.getMasterKeyId(),
saveParcel.mNewPassphrase, ring.getPublicKey().getPrimaryUserIdWithFallback());
} }
setProgress(R.string.progress_done, 100, 100); setProgress(R.string.progress_done, 100, 100);
/* Output */ /* Output */
sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY); sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, result);
} catch (Exception e) { } catch (Exception e) {
sendErrorToHandler(e); sendErrorToHandler(e);
} }
} else if (ACTION_DELETE_FILE_SECURELY.equals(action)) { } else if (ACTION_DELETE_FILE_SECURELY.equals(action)) {
try { try {
/* Input */ /* Input */
@ -624,6 +624,12 @@ public class KeychainIntentService extends IntentService
} }
} }
private void sendMessageToHandler(Integer arg1, OperationResultParcel data) {
Bundle bundle = new Bundle();
bundle.putParcelable(OperationResultParcel.EXTRA_RESULT, data);
sendMessageToHandler(arg1, null, bundle);
}
private void sendMessageToHandler(Integer arg1, Bundle data) { private void sendMessageToHandler(Integer arg1, Bundle data) {
sendMessageToHandler(arg1, null, data); sendMessageToHandler(arg1, null, data);
} }

View File

@ -144,20 +144,45 @@ public class OperationResultParcel implements Parcelable {
color = Style.GREEN; color = Style.GREEN;
} }
str = activity.getString(R.string.import_error); str = "operation succeeded!";
// str = activity.getString(R.string.import_error);
} else { } else {
duration = 0; duration = 0;
color = Style.RED; color = Style.RED;
str = activity.getString(R.string.import_error);
str = "operation failed";
// str = activity.getString(R.string.import_error);
} }
boolean button = getLog() != null && !getLog().isEmpty();
SuperCardToast toast = new SuperCardToast(activity, SuperCardToast toast = new SuperCardToast(activity,
SuperToast.Type.STANDARD, Style.getStyle(color, SuperToast.Animations.POPUP)); button ? SuperToast.Type.BUTTON : SuperToast.Type.STANDARD,
Style.getStyle(color, SuperToast.Animations.POPUP));
toast.setText(str); toast.setText(str);
toast.setDuration(duration); toast.setDuration(duration);
toast.setIndeterminate(duration == 0); toast.setIndeterminate(duration == 0);
toast.setSwipeToDismiss(true); toast.setSwipeToDismiss(true);
// If we have a log and it's non-empty, show a View Log button
if (button) {
toast.setButtonIcon(R.drawable.ic_action_view_as_list,
activity.getResources().getString(R.string.view_log));
toast.setButtonTextColor(activity.getResources().getColor(R.color.black));
toast.setTextColor(activity.getResources().getColor(R.color.black));
toast.setOnClickWrapper(new OnClickWrapper("supercardtoast",
new SuperToast.OnClickListener() {
@Override
public void onClick(View view, Parcelable token) {
Intent intent = new Intent(
activity, LogDisplayActivity.class);
intent.putExtra(LogDisplayFragment.EXTRA_RESULT, OperationResultParcel.this);
activity.startActivity(intent);
}
}
));
}
return toast; return toast;

View File

@ -143,7 +143,7 @@ public abstract class OperationResults {
// If we have a log and it's non-empty, show a View Log button // If we have a log and it's non-empty, show a View Log button
if (button) { if (button) {
toast.setButtonIcon(R.drawable.ic_action_view_as_list, toast.setButtonIcon(R.drawable.ic_action_view_as_list,
activity.getResources().getString(R.string.import_view_log)); activity.getResources().getString(R.string.view_log));
toast.setButtonTextColor(activity.getResources().getColor(R.color.black)); toast.setButtonTextColor(activity.getResources().getColor(R.color.black));
toast.setTextColor(activity.getResources().getColor(R.color.black)); toast.setTextColor(activity.getResources().getColor(R.color.black));
toast.setOnClickWrapper(new OnClickWrapper("supercardtoast", toast.setOnClickWrapper(new OnClickWrapper("supercardtoast",
@ -167,6 +167,18 @@ public abstract class OperationResults {
public static class EditKeyResult extends OperationResultParcel { public static class EditKeyResult extends OperationResultParcel {
private transient UncachedKeyRing mRing;
public EditKeyResult(int result, OperationLog log,
UncachedKeyRing ring) {
super(result, log);
mRing = ring;
}
public UncachedKeyRing getRing() {
return mRing;
}
public EditKeyResult(Parcel source) { public EditKeyResult(Parcel source) {
super(source); super(source);
} }

View File

@ -48,6 +48,7 @@ import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.service.KeychainIntentService; import org.sufficientlysecure.keychain.service.KeychainIntentService;
import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
import org.sufficientlysecure.keychain.service.OperationResults; import org.sufficientlysecure.keychain.service.OperationResults;
import org.sufficientlysecure.keychain.service.OperationResults.EditKeyResult;
import org.sufficientlysecure.keychain.service.OperationResults.ImportKeyResult; import org.sufficientlysecure.keychain.service.OperationResults.ImportKeyResult;
import org.sufficientlysecure.keychain.service.PassphraseCacheService; import org.sufficientlysecure.keychain.service.PassphraseCacheService;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel; import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
@ -467,21 +468,18 @@ public class EditKeyFragment extends LoaderFragment implements
super.handleMessage(message); super.handleMessage(message);
if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
getActivity().finish();
// TODO below
// get returned data bundle // get returned data bundle
Bundle returnData = message.getData(); Bundle returnData = message.getData();
if (returnData == null) { if (returnData == null) {
return; return;
} }
final OperationResults.SaveKeyringResult result = final OperationResults.EditKeyResult result =
returnData.getParcelable(KeychainIntentService.RESULT); returnData.getParcelable(EditKeyResult.EXTRA_RESULT);
if (result == null) { if (result == null) {
return; return;
} }
// if bad -> display here! // if bad -> display here!
if (!result.success()) { if (!result.success()) {
result.createNotify(getActivity()).show(); result.createNotify(getActivity()).show();
@ -490,7 +488,7 @@ public class EditKeyFragment extends LoaderFragment implements
// if good -> finish, return result to showkey and display there! // if good -> finish, return result to showkey and display there!
Intent intent = new Intent(); Intent intent = new Intent();
intent.putExtra(ImportKeyResult.EXTRA_RESULT, result); intent.putExtra(EditKeyResult.EXTRA_RESULT, result);
getActivity().setResult(EditKeyActivity.RESULT_OK, intent); getActivity().setResult(EditKeyActivity.RESULT_OK, intent);
getActivity().finish(); getActivity().finish();

View File

@ -350,7 +350,7 @@ public class ViewKeyActivity extends ActionBarActivity implements
@Override @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) { protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (data.hasExtra(OperationResultParcel.EXTRA_RESULT)) { if (data != null && data.hasExtra(OperationResultParcel.EXTRA_RESULT)) {
OperationResultParcel result = data.getParcelableExtra(OperationResultParcel.EXTRA_RESULT); OperationResultParcel result = data.getParcelableExtra(OperationResultParcel.EXTRA_RESULT);
result.createNotify(this).show(); result.createNotify(this).show();
} else { } else {

View File

@ -251,9 +251,7 @@ public class ViewKeyMainFragment extends LoaderFragment implements
private void editKey(Uri dataUri) { private void editKey(Uri dataUri) {
Intent editIntent = new Intent(getActivity(), EditKeyActivity.class); Intent editIntent = new Intent(getActivity(), EditKeyActivity.class);
editIntent.setData(KeychainContract.KeyRingData.buildSecretKeyRingUri(dataUri)); editIntent.setData(KeychainContract.KeyRingData.buildSecretKeyRingUri(dataUri));
// editIntent.setAction(EditKeyActivity.ACTION_EDIT_KEY); startActivityForResult(editIntent, 0);
// startActivityForResult(editIntent, 0);
startActivity(editIntent);
} }
} }

View File

@ -370,7 +370,7 @@
<item quantity="one">Clave%2$s importada con éxito.</item> <item quantity="one">Clave%2$s importada con éxito.</item>
<item quantity="other">%1$d claves%2$s importadas con éxito.</item> <item quantity="other">%1$d claves%2$s importadas con éxito.</item>
</plurals> </plurals>
<string name="import_view_log">Ver registro (log)</string> <string name="view_log">Ver registro (log)</string>
<string name="import_error_nothing">No hay nada que importar.</string> <string name="import_error_nothing">No hay nada que importar.</string>
<string name="import_error">¡Error importando claves!</string> <string name="import_error">¡Error importando claves!</string>
<string name="import_with_warnings">, con advertencias</string> <string name="import_with_warnings">, con advertencias</string>

View File

@ -358,7 +358,7 @@
<item quantity="one">Clef importée avec succès</item> <item quantity="one">Clef importée avec succès</item>
<item quantity="other">%1$d clefs importées avec succès</item> <item quantity="other">%1$d clefs importées avec succès</item>
</plurals> </plurals>
<string name="import_view_log">Consulter le journal</string> <string name="view_log">Consulter le journal</string>
<string name="import_error_nothing">Rien à importer.</string> <string name="import_error_nothing">Rien à importer.</string>
<string name="import_error">Erreur lors de l\'importation des clefs !</string> <string name="import_error">Erreur lors de l\'importation des clefs !</string>
<string name="import_with_warnings">, avec des avertissements</string> <string name="import_with_warnings">, avec des avertissements</string>

View File

@ -354,7 +354,7 @@
<string name="import_clipboard_button">Ottieni chiave dagli appunti</string> <string name="import_clipboard_button">Ottieni chiave dagli appunti</string>
<string name="import_keybase_button">Ottieni chiave da Keybase.io</string> <string name="import_keybase_button">Ottieni chiave da Keybase.io</string>
<!--Import result toast--> <!--Import result toast-->
<string name="import_view_log">Mostra registro</string> <string name="view_log">Mostra registro</string>
<string name="import_error_nothing">Niente da importare</string> <string name="import_error_nothing">Niente da importare</string>
<string name="import_error">Errore di importazione chiavi!</string> <string name="import_error">Errore di importazione chiavi!</string>
<string name="import_with_warnings">, con avvisi</string> <string name="import_with_warnings">, con avvisi</string>

View File

@ -358,7 +358,7 @@
<plurals name="import_keys_updated"> <plurals name="import_keys_updated">
<item quantity="other">%1$d の鍵%2$sのアップデートに成功。</item> <item quantity="other">%1$d の鍵%2$sのアップデートに成功。</item>
</plurals> </plurals>
<string name="import_view_log">ログを見る</string> <string name="view_log">ログを見る</string>
<string name="import_error_nothing">インポートするものがありません。</string> <string name="import_error_nothing">インポートするものがありません。</string>
<string name="import_error">鍵のインポートのエラー!</string> <string name="import_error">鍵のインポートのエラー!</string>
<string name="import_with_warnings">、とワーニング</string> <string name="import_with_warnings">、とワーニング</string>

View File

@ -371,7 +371,7 @@
<item quantity="few">и обновлено %1$d ключей%2$s.</item> <item quantity="few">и обновлено %1$d ключей%2$s.</item>
<item quantity="other">и обновлено %1$d ключей%2$s.</item> <item quantity="other">и обновлено %1$d ключей%2$s.</item>
</plurals> </plurals>
<string name="import_view_log">Смотреть журнал</string> <string name="view_log">Смотреть журнал</string>
<string name="import_error_nothing">Нет данных для импорта.</string> <string name="import_error_nothing">Нет данных для импорта.</string>
<string name="import_error">Ошибка импорта ключей!</string> <string name="import_error">Ошибка импорта ключей!</string>
<string name="import_with_warnings">, с предупреждениями</string> <string name="import_with_warnings">, с предупреждениями</string>

View File

@ -352,7 +352,7 @@
<string name="import_clipboard_button">Отримати ключ з буфера обміну</string> <string name="import_clipboard_button">Отримати ключ з буфера обміну</string>
<string name="import_keybase_button">Отримати ключ із Keybase.io</string> <string name="import_keybase_button">Отримати ключ із Keybase.io</string>
<!--Import result toast--> <!--Import result toast-->
<string name="import_view_log">Переглянути журнал</string> <string name="view_log">Переглянути журнал</string>
<string name="import_error_nothing">Нема що імпортувати.</string> <string name="import_error_nothing">Нема що імпортувати.</string>
<string name="import_error">Помилка імпорту ключів!</string> <string name="import_error">Помилка імпорту ключів!</string>
<!--Intent labels--> <!--Intent labels-->

View File

@ -403,7 +403,7 @@
<item quantity="one">Successfully updated key%2$s.</item> <item quantity="one">Successfully updated key%2$s.</item>
<item quantity="other">Successfully updated %1$d keys%2$s.</item> <item quantity="other">Successfully updated %1$d keys%2$s.</item>
</plurals> </plurals>
<string name="import_view_log">View Log</string> <string name="view_log">View Log</string>
<string name="import_error_nothing">Nothing to import.</string> <string name="import_error_nothing">Nothing to import.</string>
<string name="import_error">Error importing keys!</string> <string name="import_error">Error importing keys!</string>
<string name="import_with_warnings">, with warnings</string> <string name="import_with_warnings">, with warnings</string>