Skip to content

Commit e1fe38d

Browse files
committed
delete: add new -i switch
Similar to `update -i`.
1 parent f334e0b commit e1fe38d

File tree

5 files changed

+94
-29
lines changed

5 files changed

+94
-29
lines changed

commands/delete.go

Lines changed: 50 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -14,47 +14,67 @@ func newDeleteCommand(ctx *Context) *cobra.Command {
1414
var user string
1515
var passwordType PasswordType = "plain"
1616
var dryRun bool
17+
var id string
1718
var cmd = &cobra.Command{
1819
Use: "delete",
1920
Short: "deletes an existing password",
2021
RunE: func(cmd *cobra.Command, args []string) error {
21-
reader := bufio.NewReader(cmd.InOrStdin())
22-
if len(machine) == 0 {
23-
fmt.Fprintf(cmd.OutOrStdout(), "Machine: ")
24-
line, err := reader.ReadString('\n')
25-
if err != nil {
26-
return fmt.Errorf("ReadString() failed: %s", err)
27-
}
28-
machine = strings.TrimSuffix(line, "\n")
29-
}
30-
if len(user) == 0 {
31-
fmt.Fprintf(cmd.OutOrStdout(), "User: ")
32-
line, err := reader.ReadString('\n')
33-
if err != nil {
34-
return fmt.Errorf("ReadString() failed: %s", err)
35-
}
36-
user = strings.TrimSuffix(line, "\n")
37-
}
38-
3922
transaction, err := ctx.Database.Begin()
4023
if err != nil {
4124
return fmt.Errorf("db.Begin() failed: %s", err)
4225
}
4326

4427
defer transaction.Rollback()
45-
query, err := transaction.Prepare("delete from passwords where machine=? and service=? and user=? and type=?")
46-
if err != nil {
47-
return fmt.Errorf("db.Prepare() failed: %s", err)
48-
}
4928

50-
result, err := query.Exec(machine, service, user, passwordType)
51-
if err != nil {
52-
return fmt.Errorf("db.Exec() failed: %s", err)
53-
}
29+
var affected int64
30+
if len(id) > 0 {
31+
query, err := transaction.Prepare("delete from passwords where id=?")
32+
if err != nil {
33+
return fmt.Errorf("db.Prepare() failed: %s", err)
34+
}
5435

55-
affected, err := result.RowsAffected()
56-
if err != nil {
57-
return fmt.Errorf("result.RowsAffected() failed: %s", err)
36+
result, err := query.Exec(id)
37+
if err != nil {
38+
return fmt.Errorf("db.Exec() failed: %s", err)
39+
}
40+
41+
affected, err = result.RowsAffected()
42+
if err != nil {
43+
return fmt.Errorf("result.RowsAffected() failed: %s", err)
44+
}
45+
} else {
46+
reader := bufio.NewReader(cmd.InOrStdin())
47+
if len(machine) == 0 {
48+
fmt.Fprintf(cmd.OutOrStdout(), "Machine: ")
49+
line, err := reader.ReadString('\n')
50+
if err != nil {
51+
return fmt.Errorf("ReadString() failed: %s", err)
52+
}
53+
machine = strings.TrimSuffix(line, "\n")
54+
}
55+
if len(user) == 0 {
56+
fmt.Fprintf(cmd.OutOrStdout(), "User: ")
57+
line, err := reader.ReadString('\n')
58+
if err != nil {
59+
return fmt.Errorf("ReadString() failed: %s", err)
60+
}
61+
user = strings.TrimSuffix(line, "\n")
62+
}
63+
64+
query, err := transaction.Prepare("delete from passwords where machine=? and service=? and user=? and type=?")
65+
if err != nil {
66+
return fmt.Errorf("db.Prepare() failed: %s", err)
67+
}
68+
69+
result, err := query.Exec(machine, service, user, passwordType)
70+
if err != nil {
71+
return fmt.Errorf("db.Exec() failed: %s", err)
72+
}
73+
74+
affected, err = result.RowsAffected()
75+
if err != nil {
76+
return fmt.Errorf("result.RowsAffected() failed: %s", err)
77+
}
5878
}
5979
if dryRun {
6080
fmt.Fprintf(cmd.OutOrStdout(), "Would delete %v password\n", affected)
@@ -72,6 +92,7 @@ func newDeleteCommand(ctx *Context) *cobra.Command {
7292
cmd.Flags().StringVarP(&user, "user", "u", "", "user (default: ask)")
7393
cmd.Flags().VarP(&passwordType, "type", "t", `password type ("plain" or "totp")`)
7494
cmd.Flags().BoolVarP(&dryRun, "dry-run", "n", false, `do everything except actually perform the database action (default: false)`)
95+
cmd.Flags().StringVarP(&id, "id", "i", "", `unique identifier (default: '')`)
7596

7697
return cmd
7798
}

commands/delete_test.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,38 @@ func TestDelete(t *testing.T) {
3838
}
3939
}
4040

41+
func TestDeleteById(t *testing.T) {
42+
ctx := CreateContextForTesting(t)
43+
expectedMachine := "mymachine"
44+
expectedService := "myservice"
45+
expectedUser := "myuser"
46+
expectedPassword := "mypassword"
47+
var expectedType PasswordType = "plain"
48+
_, err := createPassword(&ctx, expectedMachine, expectedService, expectedUser, expectedPassword, expectedType)
49+
if err != nil {
50+
t.Fatalf("createPassword() = %q, want nil", err)
51+
}
52+
os.Args = []string{"", "delete", "--id", "1"}
53+
inBuf := new(bytes.Buffer)
54+
outBuf := new(bytes.Buffer)
55+
56+
actualRet := Main(inBuf, outBuf)
57+
58+
expectedRet := 0
59+
if actualRet != expectedRet {
60+
t.Fatalf("Main() = %q, want %q", actualRet, expectedRet)
61+
}
62+
results, err := readPasswords(ctx.Database, searchOptions{})
63+
if err != nil {
64+
t.Fatalf("readPasswords() err = %q, want nil", err)
65+
}
66+
actualLength := len(results)
67+
expectedLength := 0
68+
if actualLength != expectedLength {
69+
t.Fatalf("actualLength = %q, want %q", actualLength, expectedLength)
70+
}
71+
}
72+
4173
func TestInteractiveDelete(t *testing.T) {
4274
ctx := CreateContextForTesting(t)
4375
expectedMachine := "mymachine"

guide/src/news.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
- update: new `-i` switch to edit the `machine`, `service` or `user` of a password without changing
66
the password itself
77
- `sync` is renamed to `pull`, since it's a remote -> local copy only
8+
- delete: new `-i` switch to delete a password based on the search result
89

910
## 7.4
1011

guide/src/usage.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,3 +166,10 @@ In which case the command is not interactive:
166166
```console
167167
Deleted 1 password
168168
```
169+
170+
An alternative approach is to use `cpm search` to find the password ID, then you can delete based on
171+
that ID:
172+
173+
```
174+
cpm delete -i <id>
175+
```

man/cpm-delete.1

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ deletes an existing password
2525
\fB-h\fP, \fB--help\fP[=false]
2626
help for delete
2727

28+
.PP
29+
\fB-i\fP, \fB--id\fP=""
30+
unique identifier (default: '')
31+
2832
.PP
2933
\fB-m\fP, \fB--machine\fP=""
3034
machine (default: ask)

0 commit comments

Comments
 (0)