Skip to content

feat(cli): get, edit and delete commands - #33

Open
ericliswan wants to merge 5 commits into
mainfrom
feat/cli-get-edit-delete
Open

ericliswan wants to merge 5 commits into
mainfrom
feat/cli-get-edit-delete

Conversation

@ericliswan

Copy link
Copy Markdown
Owner

Summary

Adds pwv get, pwv edit and pwv delete. They share a chooser: one matching entry is used directly; when several match (case-insensitive), they are listed by number with site and username only, and the user picks one. get --show prints the password and refuses a non-terminal stdout unless --force. Without --show, get explains that clipboard copy arrives in plan PR #18. edit changes exactly one field per run. delete asks before removing, and --yes skips the question.

Closes #32

Type of change

  • feat - [ ] fix - [ ] docs - [x] test - [ ] refactor - [ ] ci/chore - [ ] security

How was this tested?

  • cargo fmt --all --check; cargo clippy --workspace --all-targets [--all-features] -- -D warnings; cargo test -p pwv-cli [--all-features]; cargo deny check.
  • Unit tests for the chooser: a single match needs no answer, numbered choice, out-of-range or non-numeric answers, missing site.
  • Integration test (under insecure-test-kdf) with two entries for one site:
    • The non-terminal refusal happens before the master password is read; --force overrides it.
    • Every edit field, with updated_at bumped and no new secret on stderr.
    • An empty new password is rejected.
    • A declined delete keeps the entry; y/YES deletes it; --yes deletes it without asking.
  • Usage errors (exit 2): edit with zero or two field flags, and get --force without --show.

Security checklist

  • No secret in args, env vars, logs, Debug output, errors or panics. A bad choice answer is not echoed, because a misaligned --password-stdin line could be a secret.
  • Crypto is called only from pwv-core::kdf / pwv-core::crypto (no crypto in this PR)
  • Any new header/file-format field is inside the AAD and validated on load (no format change)
  • Failure paths have tests (non-TTY refusal, missing entry, bad choice, empty password, declined delete)
  • Docs (README / DESIGN / THREAT_MODEL) updated if behaviour changed. The README command table is written in plan PR perf(kdf): benchmark and calibrate default parameters #23.

Notes for the reviewer

  • A declined delete exits 0 with "Nothing deleted" on stderr. It is the user's choice, not an error.
  • Matching entries are listed in vault (insertion) order, not sorted, so the numbers stay stable across runs for the same vault.
  • Two entries with the same site and username look identical in the chooser. Showing more detail would mean deciding which metadata to print; left as is for now.

Adds the shared chooser used by get, edit and delete: one match is
taken as is, several are listed by number (site and username only) and
the user picks one. A bad answer is not echoed back in the error, since
a misaligned --password-stdin line could be a secret.

Without --show, get explains that clipboard copy is not there yet.

Refs #32
get --show into a pipe or file can leave the password in a log or file
the user did not mean to write. --force (only valid with --show) is for
when that is the point. The check runs before unlocking so a refused
run does not pay for the KDF.

Refs #32
--username, --password and --notes form a required clap group that
allows only one, so a run always prompts for exactly one new value.
The secret fields use hidden prompts, an empty password is rejected as
in add, and Vault::update bumps updated_at.

The non-empty password check moves to a helper shared with add.

Refs #32
Shows the chosen entry's site and username and deletes only on y or
yes; anything else keeps it and exits 0. --yes skips the question for
scripts. The previous file stays as <vault>.bak, as on every save.

Refs #32
Two entries share a site in different case. The test covers the
numbered choice, the non-terminal refusal and its --force override,
every edit field (secrets never echoed on stderr, updated_at bumped),
a declined delete, --yes, and clap rejecting zero or two edit fields.

Refs #32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(cli): get, edit and delete commands

1 participant