Make export work with rowIds instead of MasterKeyIds

This commit is contained in:
uberspot 2014-03-11 03:22:05 +02:00
parent d937317012
commit 361c45a481
6 changed files with 91 additions and 52 deletions

View File

@ -63,7 +63,7 @@ public class ExportHelper {
/** /**
* Show dialog where to export keys * Show dialog where to export keys
*/ */
public void showExportKeysDialog(final Uri dataUri, final int keyType, public void showExportKeysDialog(final long[] rowIds, final int keyType,
final String exportFilename) { final String exportFilename) {
mExportFilename = exportFilename; mExportFilename = exportFilename;
@ -75,7 +75,7 @@ public class ExportHelper {
Bundle data = message.getData(); Bundle data = message.getData();
mExportFilename = data.getString(FileDialogFragment.MESSAGE_DATA_FILENAME); mExportFilename = data.getString(FileDialogFragment.MESSAGE_DATA_FILENAME);
exportKeys(dataUri, keyType); exportKeys(rowIds, keyType);
} }
} }
}; };
@ -86,7 +86,7 @@ public class ExportHelper {
DialogFragmentWorkaround.INTERFACE.runnableRunDelayed(new Runnable() { DialogFragmentWorkaround.INTERFACE.runnableRunDelayed(new Runnable() {
public void run() { public void run() {
String title = null; String title = null;
if (dataUri == null) { if (rowIds == null) {
// export all keys // export all keys
title = activity.getString(R.string.title_export_keys); title = activity.getString(R.string.title_export_keys);
} else { } else {
@ -112,7 +112,7 @@ public class ExportHelper {
/** /**
* Export keys * Export keys
*/ */
public void exportKeys(Uri dataUri, int keyType) { public void exportKeys(long[] rowIds, int keyType) {
Log.d(Constants.TAG, "exportKeys started"); Log.d(Constants.TAG, "exportKeys started");
// Send all information needed to service to export key in other thread // Send all information needed to service to export key in other thread
@ -126,13 +126,10 @@ public class ExportHelper {
data.putString(KeychainIntentService.EXPORT_FILENAME, mExportFilename); data.putString(KeychainIntentService.EXPORT_FILENAME, mExportFilename);
data.putInt(KeychainIntentService.EXPORT_KEY_TYPE, keyType); data.putInt(KeychainIntentService.EXPORT_KEY_TYPE, keyType);
if (dataUri == null) { if (rowIds == null) {
data.putBoolean(KeychainIntentService.EXPORT_ALL, true); data.putBoolean(KeychainIntentService.EXPORT_ALL, true);
} else { } else {
// TODO: put data uri into service??? data.putLongArray(KeychainIntentService.EXPORT_KEY_RING_ROW_ID, rowIds);
long keyRingMasterKeyId = ProviderHelper.getMasterKeyId(activity, dataUri);
data.putLong(KeychainIntentService.EXPORT_KEY_RING_MASTER_KEY_ID, keyRingMasterKeyId);
} }
intent.putExtra(KeychainIntentService.EXTRA_DATA, data); intent.putExtra(KeychainIntentService.EXTRA_DATA, data);

View File

@ -155,59 +155,53 @@ public class PgpImportExport {
return returnData; return returnData;
} }
public Bundle exportKeyRings(ArrayList<Long> keyRingMasterKeyIds, int keyType, public Bundle exportKeyRings(ArrayList<Long> keyRingRowIds, int keyType,
OutputStream outStream) throws PgpGeneralException, FileNotFoundException, OutputStream outStream) throws PgpGeneralException, FileNotFoundException,
PGPException, IOException { PGPException, IOException {
Bundle returnData = new Bundle(); Bundle returnData = new Bundle();
int rowIdsSize = keyRingRowIds.size();
updateProgress( updateProgress(
mContext.getResources().getQuantityString(R.plurals.progress_exporting_key, mContext.getResources().getQuantityString(R.plurals.progress_exporting_key,
keyRingMasterKeyIds.size()), 0, 100); rowIdsSize), 0, 100);
if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
throw new PgpGeneralException( throw new PgpGeneralException(
mContext.getString(R.string.error_external_storage_not_ready)); mContext.getString(R.string.error_external_storage_not_ready));
} }
// For each row id
for (int i = 0; i < rowIdsSize; ++i) {
// Create an output stream
ArmoredOutputStream arOutStream = new ArmoredOutputStream(outStream);
arOutStream.setHeader("Version", PgpHelper.getFullVersion(mContext));
if (keyType == Id.type.secret_key) { // If the keyType is secret get the PGPSecretKeyRing
ArmoredOutputStream outSec = new ArmoredOutputStream(outStream); // based on the row id and encode it to the output
outSec.setHeader("Version", PgpHelper.getFullVersion(mContext)); if (keyType == Id.type.secret_key) {
updateProgress(i * 100 / rowIdsSize / 2, 100);
for (int i = 0; i < keyRingMasterKeyIds.size(); ++i) { PGPSecretKeyRing secretKeyRing =
updateProgress(i * 100 / keyRingMasterKeyIds.size() / 2, 100); ProviderHelper.getPGPSecretKeyRingByRowId(mContext, keyRingRowIds.get(i));
PGPSecretKeyRing secretKeyRing = ProviderHelper.getPGPSecretKeyRingByMasterKeyId(
mContext, keyRingMasterKeyIds.get(i));
if (secretKeyRing != null) { if (secretKeyRing != null) {
secretKeyRing.encode(outSec); secretKeyRing.encode(arOutStream);
} }
} // Else if it's a public key get the PGPPublicKeyRing
outSec.close(); // and encode that to the output
} else { } else {
// export public keyrings... updateProgress(i * 100 / rowIdsSize, 100);
ArmoredOutputStream outPub = new ArmoredOutputStream(outStream); PGPPublicKeyRing publicKeyRing =
outPub.setHeader("Version", PgpHelper.getFullVersion(mContext)); ProviderHelper.getPGPPublicKeyRingByRowId(mContext, keyRingRowIds.get(i));
for (int i = 0; i < keyRingMasterKeyIds.size(); ++i) {
// double the needed time if exporting both public and secret parts
if (keyType == Id.type.secret_key) {
updateProgress(i * 100 / keyRingMasterKeyIds.size() / 2, 100);
} else {
updateProgress(i * 100 / keyRingMasterKeyIds.size(), 100);
}
PGPPublicKeyRing publicKeyRing = ProviderHelper.getPGPPublicKeyRingByMasterKeyId(
mContext, keyRingMasterKeyIds.get(i));
if (publicKeyRing != null) { if (publicKeyRing != null) {
publicKeyRing.encode(outPub); publicKeyRing.encode(arOutStream);
} }
} }
outPub.close();
arOutStream.close();
} }
returnData.putInt(KeychainIntentService.RESULT_EXPORT, keyRingMasterKeyIds.size()); returnData.putInt(KeychainIntentService.RESULT_EXPORT, rowIdsSize);
updateProgress(R.string.progress_done, 100, 100); updateProgress(R.string.progress_done, 100, 100);

View File

@ -404,6 +404,30 @@ public class ProviderHelper {
return masterKeyIds; return masterKeyIds;
} }
/**
* Private helper method
*/
private static ArrayList<Long> getKeyRingsRowIds(Context context, Uri queryUri) {
Cursor cursor = context.getContentResolver().query(queryUri,
new String[]{KeyRings._ID}, null, null, null);
ArrayList<Long> rowIds = new ArrayList<Long>();
if (cursor != null) {
int IdCol = cursor.getColumnIndex(KeyRings._ID);
if (cursor.moveToFirst()) {
do {
rowIds.add(cursor.getLong(IdCol));
} while (cursor.moveToNext());
}
}
if (cursor != null) {
cursor.close();
}
return rowIds;
}
/** /**
* Retrieves ids of all SecretKeyRings * Retrieves ids of all SecretKeyRings
*/ */
@ -420,6 +444,22 @@ public class ProviderHelper {
return getKeyRingsMasterKeyIds(context, queryUri); return getKeyRingsMasterKeyIds(context, queryUri);
} }
/**
* Retrieves ids of all SecretKeyRings
*/
public static ArrayList<Long> getSecretKeyRingsRowIds(Context context) {
Uri queryUri = KeyRings.buildSecretKeyRingsUri();
return getKeyRingsRowIds(context, queryUri);
}
/**
* Retrieves ids of all PublicKeyRings
*/
public static ArrayList<Long> getPublicKeyRingsRowIds(Context context) {
Uri queryUri = KeyRings.buildPublicKeyRingsUri();
return getKeyRingsRowIds(context, queryUri);
}
public static void deletePublicKeyRing(Context context, long rowId) { public static void deletePublicKeyRing(Context context, long rowId) {
ContentResolver cr = context.getContentResolver(); ContentResolver cr = context.getContentResolver();
cr.delete(KeyRings.buildPublicKeyRingsUri(Long.toString(rowId)), null, null); cr.delete(KeyRings.buildPublicKeyRingsUri(Long.toString(rowId)), null, null);

View File

@ -50,6 +50,7 @@ import org.sufficientlysecure.keychain.pgp.PgpImportExport;
import org.sufficientlysecure.keychain.pgp.PgpKeyOperation; import org.sufficientlysecure.keychain.pgp.PgpKeyOperation;
import org.sufficientlysecure.keychain.pgp.PgpSignEncrypt; import org.sufficientlysecure.keychain.pgp.PgpSignEncrypt;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.provider.KeychainContract;
import org.sufficientlysecure.keychain.provider.KeychainContract.DataStream; import org.sufficientlysecure.keychain.provider.KeychainContract.DataStream;
import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListEntry; import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListEntry;
@ -153,6 +154,7 @@ public class KeychainIntentService extends IntentService implements ProgressDial
public static final String EXPORT_KEY_TYPE = "export_key_type"; public static final String EXPORT_KEY_TYPE = "export_key_type";
public static final String EXPORT_ALL = "export_all"; public static final String EXPORT_ALL = "export_all";
public static final String EXPORT_KEY_RING_MASTER_KEY_ID = "export_key_ring_id"; public static final String EXPORT_KEY_RING_MASTER_KEY_ID = "export_key_ring_id";
public static final String EXPORT_KEY_RING_ROW_ID = "export_key_rind_row_id";
// upload key // upload key
public static final String UPLOAD_KEY_SERVER = "upload_key_server"; public static final String UPLOAD_KEY_SERVER = "upload_key_server";
@ -675,10 +677,12 @@ public class KeychainIntentService extends IntentService implements ProgressDial
String outputFile = data.getString(EXPORT_FILENAME); String outputFile = data.getString(EXPORT_FILENAME);
long[] rowIds = new long[0];
// If not exporting all keys get the rowIds of the keys to export from the intent
boolean exportAll = data.getBoolean(EXPORT_ALL); boolean exportAll = data.getBoolean(EXPORT_ALL);
long keyRingMasterKeyId = -1;
if (!exportAll) { if (!exportAll) {
keyRingMasterKeyId = data.getLong(EXPORT_KEY_RING_MASTER_KEY_ID); rowIds = data.getLongArray(EXPORT_KEY_RING_ROW_ID);
} }
/* Operation */ /* Operation */
@ -691,24 +695,26 @@ public class KeychainIntentService extends IntentService implements ProgressDial
// OutputStream // OutputStream
FileOutputStream outStream = new FileOutputStream(outputFile); FileOutputStream outStream = new FileOutputStream(outputFile);
ArrayList<Long> keyRingMasterKeyIds = new ArrayList<Long>(); ArrayList<Long> keyRingRowIds = new ArrayList<Long>();
if (exportAll) { if (exportAll) {
// get all key ring row ids based on export type
// get all key ring row ids based on export type
if (keyType == Id.type.public_key) { if (keyType == Id.type.public_key) {
keyRingMasterKeyIds = ProviderHelper.getPublicKeyRingsMasterKeyIds(this); keyRingRowIds = ProviderHelper.getPublicKeyRingsRowIds(this);
} else { } else {
keyRingMasterKeyIds = ProviderHelper.getSecretKeyRingsMasterKeyIds(this); keyRingRowIds = ProviderHelper.getSecretKeyRingsRowIds(this);
} }
} else { } else {
keyRingMasterKeyIds.add(keyRingMasterKeyId); for(long rowId : rowIds) {
keyRingRowIds.add(rowId);
}
} }
Bundle resultData = new Bundle(); Bundle resultData;
PgpImportExport pgpImportExport = new PgpImportExport(this, this); PgpImportExport pgpImportExport = new PgpImportExport(this, this);
resultData = pgpImportExport resultData = pgpImportExport
.exportKeyRings(keyRingMasterKeyIds, keyType, outStream); .exportKeyRings(keyRingRowIds, keyType, outStream);
sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, resultData); sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, resultData);
} catch (Exception e) { } catch (Exception e) {

View File

@ -329,7 +329,8 @@ public class EditKeyActivity extends ActionBarActivity {
cancelClicked(); cancelClicked();
return true; return true;
case R.id.menu_key_edit_export_file: case R.id.menu_key_edit_export_file:
mExportHelper.showExportKeysDialog(mDataUri, Id.type.secret_key, Constants.path.APP_DIR long[] ids = new long[]{Long.valueOf(mDataUri.getLastPathSegment())};
mExportHelper.showExportKeysDialog(ids, Id.type.secret_key, Constants.path.APP_DIR
+ "/secexport.asc"); + "/secexport.asc");
return true; return true;
case R.id.menu_key_edit_delete: { case R.id.menu_key_edit_delete: {

View File

@ -118,7 +118,8 @@ public class ViewKeyActivity extends ActionBarActivity {
uploadToKeyserver(mDataUri); uploadToKeyserver(mDataUri);
return true; return true;
case R.id.menu_key_view_export_file: case R.id.menu_key_view_export_file:
mExportHelper.showExportKeysDialog(mDataUri, Id.type.public_key, Constants.path.APP_DIR long[] ids = new long[]{Long.valueOf(mDataUri.getLastPathSegment())};
mExportHelper.showExportKeysDialog(ids, Id.type.public_key, Constants.path.APP_DIR
+ "/pubexport.asc"); + "/pubexport.asc");
return true; return true;
case R.id.menu_key_view_share_default_fingerprint: case R.id.menu_key_view_share_default_fingerprint: