diff options
Diffstat (limited to 'app/src/main/java/com')
3 files changed, 95 insertions, 2 deletions
diff --git a/app/src/main/java/com/zeapo/pwdstore/PasswordStore.java b/app/src/main/java/com/zeapo/pwdstore/PasswordStore.java index 96e58d89..adfd62ff 100644 --- a/app/src/main/java/com/zeapo/pwdstore/PasswordStore.java +++ b/app/src/main/java/com/zeapo/pwdstore/PasswordStore.java @@ -405,6 +405,14 @@ public class PasswordStore extends AppCompatActivity { startActivityForResult(intent, PgpHandler.REQUEST_CODE_DECRYPT_AND_VERIFY); } + public void editPassword(PasswordItem item) { + Intent intent = new Intent(this, PgpHandler.class); + intent.putExtra("NAME", item.toString()); + intent.putExtra("FILE_PATH", item.getFile().getAbsolutePath()); + intent.putExtra("Operation", "EDIT"); + startActivityForResult(intent, PgpHandler.REQUEST_CODE_EDIT); + } + public void createPassword() { if (!PasswordRepository.isInitialized()) { new AlertDialog.Builder(this) diff --git a/app/src/main/java/com/zeapo/pwdstore/crypto/PgpHandler.java b/app/src/main/java/com/zeapo/pwdstore/crypto/PgpHandler.java index fd92a1f7..a80e4800 100644 --- a/app/src/main/java/com/zeapo/pwdstore/crypto/PgpHandler.java +++ b/app/src/main/java/com/zeapo/pwdstore/crypto/PgpHandler.java @@ -65,6 +65,7 @@ public class PgpHandler extends AppCompatActivity implements OpenPgpServiceConne public static final int REQUEST_CODE_DECRYPT_AND_VERIFY = 9913; public static final int REQUEST_CODE_GET_KEY = 9914; public static final int REQUEST_CODE_GET_KEY_IDS = 9915; + public static final int REQUEST_CODE_EDIT = 9916; public final class Constants { public static final String TAG = "Keychain"; @@ -146,7 +147,8 @@ public class PgpHandler extends AppCompatActivity implements OpenPgpServiceConne public void editPassword() { - // if in encrypt or (in decrypt and password is invisible), do nothing + // if in encrypt or in decrypt and password is invisible + // (because !showPassword, so this will instantly close), do nothing if (findViewById(R.id.crypto_password_show) == null || findViewById(R.id.crypto_container).getVisibility() != View.VISIBLE) return; @@ -353,6 +355,10 @@ public class PgpHandler extends AppCompatActivity implements OpenPgpServiceConne case REQUEST_CODE_GET_KEY_IDS: getKeyIds(data); break; + case REQUEST_CODE_EDIT: { + edit(data); + break; + } } } else if (resultCode == RESULT_CANCELED) { setResult(RESULT_CANCELED, data); @@ -456,6 +462,39 @@ public class PgpHandler extends AppCompatActivity implements OpenPgpServiceConne setResult(RESULT_OK); finish(); } + + // edit + if (requestCode == REQUEST_CODE_EDIT && os != null) { + try { + if (returnToCiphertextField) { + findViewById(R.id.progress_bar).setVisibility(View.GONE); + findViewById(R.id.progress_bar_label).setVisibility(View.GONE); + + findViewById(R.id.crypto_container).setVisibility(View.VISIBLE); + + Typeface monoTypeface = Typeface.createFromAsset(getAssets(), "fonts/sourcecodepro.ttf"); + String[] passContent = os.toString("UTF-8").split("\n"); + ((TextView) findViewById(R.id.crypto_password_show)) + .setTypeface(monoTypeface); + ((TextView) findViewById(R.id.crypto_password_show)) + .setText(passContent[0]); + + String extraContent = os.toString("UTF-8").replaceFirst(".*\n", ""); + if (extraContent.length() != 0) { + ((TextView) findViewById(R.id.crypto_extra_show)) + .setTypeface(monoTypeface); + ((TextView) findViewById(R.id.crypto_extra_show)) + .setText(extraContent); + } + + editPassword(); + } else { + Log.d("PGPHANDLER", "Error message after decrypt : " + os.toString()); + } + } catch (UnsupportedEncodingException e) { + Log.e(Constants.TAG, "UnsupportedEncodingException", e); + } + } break; } case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED: { @@ -560,6 +599,24 @@ public class PgpHandler extends AppCompatActivity implements OpenPgpServiceConne } + public void edit(Intent data) { + // exactly same as decrypt, only we want a different callback + data.setAction(OpenPgpApi.ACTION_DECRYPT_VERIFY); + + findViewById(R.id.progress_bar).setVisibility(View.VISIBLE); + + try { + InputStream is = FileUtils.openInputStream(new File(getIntent().getExtras().getString("FILE_PATH"))); + + ByteArrayOutputStream os = new ByteArrayOutputStream(); + + OpenPgpApi api = new OpenPgpApi(this, mServiceConnection.getService()); + api.executeApiAsync(data, is, os, new PgpCallback(true, os, REQUEST_CODE_EDIT)); + } catch (Exception e) { + e.printStackTrace(); + } + } + // TODO (low priority but still...) android M potential permissions crashes @Override public void onBound(IOpenPgpService2 service) { @@ -591,6 +648,14 @@ public class PgpHandler extends AppCompatActivity implements OpenPgpServiceConne // String keys = keyIDs.split(",").length > 1 ? keyIDs : keyIDs.split(",")[0]; // ((TextView) findViewById(R.id.crypto_key_ids)).setText(keys); // } + } else if (extra.getString("Operation").equals("EDIT")) { + setContentView(R.layout.decrypt_layout); + ((TextView) findViewById(R.id.crypto_password_file)).setText(extra.getString("NAME")); + String cat = new File(extra.getString("FILE_PATH").replace(PasswordRepository.getWorkTree().getAbsolutePath(), "")) + .getParentFile().getName(); + + ((TextView) findViewById(R.id.crypto_password_category)).setText(cat + "/"); + edit(new Intent()); } } diff --git a/app/src/main/java/com/zeapo/pwdstore/utils/PasswordRecyclerAdapter.java b/app/src/main/java/com/zeapo/pwdstore/utils/PasswordRecyclerAdapter.java index c9158b30..45dd0d0b 100644 --- a/app/src/main/java/com/zeapo/pwdstore/utils/PasswordRecyclerAdapter.java +++ b/app/src/main/java/com/zeapo/pwdstore/utils/PasswordRecyclerAdapter.java @@ -25,6 +25,7 @@ public class PasswordRecyclerAdapter extends RecyclerView.Adapter<PasswordRecycl private final PasswordFragment.OnFragmentInteractionListener listener; private final Set<Integer> selectedItems; private ActionMode mActionMode; + private Boolean canEdit; // Provide a reference to the views for each data item // Complex data items may need more than one view per item, and @@ -85,6 +86,14 @@ public class PasswordRecyclerAdapter extends RecyclerView.Adapter<PasswordRecycl toggleSelection(holder.getAdapterPosition(), holder.card, pass.getType()); if (selectedItems.isEmpty()) { mActionMode.finish(); + } else if (selectedItems.size() == 1 && !canEdit) { + if (values.get(selectedItems.iterator().next()).getType() == PasswordItem.TYPE_PASSWORD) { + canEdit = true; + mActionMode.invalidate(); + } + } else if (selectedItems.size() >= 1 && canEdit) { + canEdit = false; + mActionMode.invalidate(); } } else { listener.onFragmentInteraction(pass); @@ -99,8 +108,10 @@ public class PasswordRecyclerAdapter extends RecyclerView.Adapter<PasswordRecycl return false; } toggleSelection(holder.getAdapterPosition(), holder.card, pass.getType()); + canEdit = pass.getType() == PasswordItem.TYPE_PASSWORD; // Start the CAB using the ActionMode.Callback mActionMode = activity.startSupportActionMode(mActionModeCallback); + mActionMode.invalidate(); return true; } }); @@ -123,7 +134,12 @@ public class PasswordRecyclerAdapter extends RecyclerView.Adapter<PasswordRecycl // may be called multiple times if the mode is invalidated. @Override public boolean onPrepareActionMode(ActionMode mode, Menu menu) { - return false; // Return false if nothing is done + if (canEdit) { + menu.findItem(R.id.menu_edit_password).setVisible(true); + } else { + menu.findItem(R.id.menu_edit_password).setVisible(false); + } + return true; // Return false if nothing is done } // Called when the user selects a contextual menu item @@ -134,6 +150,10 @@ public class PasswordRecyclerAdapter extends RecyclerView.Adapter<PasswordRecycl activity.deletePasswords(PasswordRecyclerAdapter.this, new TreeSet<>(selectedItems)); mode.finish(); // Action picked, so close the CAB return true; + case R.id.menu_edit_password: + activity.editPassword(values.get(selectedItems.iterator().next())); + mode.finish(); + return true; default: return false; } |