Skip to content

Commit 9fc43a1

Browse files
Merge pull request #304 from wttech/feature/user-keystore-add-key
Add user private keys management commands: add, delete
2 parents e15d85e + 9ad92cf commit 9fc43a1

File tree

11 files changed

+341
-90
lines changed

11 files changed

+341
-90
lines changed

.github/workflows/release-perform.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ jobs:
3131

3232
- uses: actions/setup-go@v3
3333
with:
34-
go-version: '1.20'
34+
go-version: '1.24'
3535
cache: true
3636

3737
- uses: goreleaser/goreleaser-action@v2

.github/workflows/test.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919

2020
steps:
2121
- name: Cache Go modules
22-
uses: actions/cache@v2
22+
uses: actions/cache@v4
2323
with:
2424
path: |
2525
~/.cache/go-build
@@ -29,13 +29,13 @@ jobs:
2929
${{ runner.os }}-go-
3030
3131
- name: Set up Go
32-
uses: actions/setup-go@v2
32+
uses: actions/setup-go@v5
3333
with:
34-
go-version: '1.20'
34+
go-version: '1.24'
3535
id: go
3636

3737
- name: Checkout source code
38-
uses: actions/checkout@v3
38+
uses: actions/checkout@v4
3939

4040
- name: Run build
4141
run: make

cmd/aem/cli.go

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,14 @@ import (
55
"bytes"
66
"encoding/json"
77
"fmt"
8+
"io"
9+
"os"
10+
"path"
11+
"reflect"
12+
"sort"
13+
"strings"
14+
"time"
15+
816
"github.com/fatih/color"
917
"github.com/iancoleman/strcase"
1018
"github.com/jmespath-community/go-jmespath"
@@ -18,13 +26,6 @@ import (
1826
"github.com/wttech/aemc/pkg/common/fmtx"
1927
"github.com/wttech/aemc/pkg/common/pathx"
2028
"github.com/wttech/aemc/pkg/common/stringsx"
21-
"io"
22-
"os"
23-
"path"
24-
"reflect"
25-
"sort"
26-
"strings"
27-
"time"
2829
)
2930

3031
const (
@@ -206,7 +207,7 @@ func (c *CLI) openOutputLogFile() *os.File {
206207
}
207208
file, err := os.OpenFile(c.outputLogFile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
208209
if err != nil {
209-
log.Fatalf(fmt.Sprintf("cannot open/create CLI output file '%s': %s", c.outputLogFile, err))
210+
log.Fatalf("cannot open/create CLI output file '%s': %s", c.outputLogFile, err)
210211
}
211212
return file
212213
}
@@ -231,13 +232,13 @@ func (c *CLI) printCommandResult() {
231232
if c.outputNoColor {
232233
entry := log.WithField("changed", r.Changed).WithField("elapsed", r.Elapsed)
233234
if r.Failed {
234-
entry.Errorf(msg)
235+
entry.Error(msg)
235236
} else {
236-
entry.Infof(msg)
237+
entry.Info(msg)
237238
}
238239
} else {
239240
if r.Failed {
240-
log.Errorf(color.RedString(msg))
241+
log.Error(color.RedString(msg))
241242
} else {
242243
if r.Changed {
243244
log.Info(color.YellowString(msg))

cmd/aem/user.go

Lines changed: 107 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ func (c *CLI) userCmd() *cobra.Command {
1313
Aliases: []string{"usr"},
1414
}
1515
cmd.AddCommand(c.userKeyStore())
16+
cmd.AddCommand(c.userKey())
1617
cmd.AddCommand(c.userPassword())
1718
return cmd
1819
}
@@ -29,10 +30,21 @@ func (c *CLI) userKeyStore() *cobra.Command {
2930
return cmd
3031
}
3132

33+
func (c *CLI) userKey() *cobra.Command {
34+
cmd := &cobra.Command{
35+
Use: "key",
36+
Short: "Private keys management",
37+
Aliases: []string{"keys"},
38+
}
39+
cmd.AddCommand(c.userKeyAdd())
40+
cmd.AddCommand(c.userKeyDelete())
41+
return cmd
42+
}
43+
3244
func (c *CLI) userPassword() *cobra.Command {
3345
cmd := &cobra.Command{
3446
Use: "password",
35-
Short: "User password management",
47+
Short: "Password management",
3648
Aliases: []string{"pwd"},
3749
}
3850
cmd.AddCommand(c.UserPasswordSet())
@@ -42,7 +54,7 @@ func (c *CLI) userPassword() *cobra.Command {
4254
func (c *CLI) KeystoreStatus() *cobra.Command {
4355
cmd := &cobra.Command{
4456
Use: "status",
45-
Short: "Get status of keystore",
57+
Short: "Get status of a user keystore",
4658
Aliases: []string{"show", "get", "read", "describe", "ls"},
4759
Run: func(cmd *cobra.Command, args []string) {
4860
instance, err := c.aem.InstanceManager().One()
@@ -54,7 +66,7 @@ func (c *CLI) KeystoreStatus() *cobra.Command {
5466
id, _ := cmd.Flags().GetString("id")
5567
scope, _ := cmd.Flags().GetString("scope")
5668

57-
result, err := instance.Auth().UserManager().KeystoreStatus(scope, id)
69+
result, err := instance.Auth().UserManager().Keystore().Status(scope, id)
5870

5971
if err != nil {
6072
c.Error(err)
@@ -68,14 +80,13 @@ func (c *CLI) KeystoreStatus() *cobra.Command {
6880
cmd.Flags().String("id", "", "user id")
6981
_ = cmd.MarkFlagRequired("id")
7082
cmd.Flags().String("scope", "", "user scope")
71-
_ = cmd.MarkFlagRequired("scope")
7283
return cmd
7384
}
7485

7586
func (c *CLI) KeystoreCreate() *cobra.Command {
7687
cmd := &cobra.Command{
7788
Use: "create",
78-
Short: "Create user Keystore",
89+
Short: "Create user keystore",
7990
Aliases: []string{"make", "new"},
8091
Run: func(cmd *cobra.Command, args []string) {
8192
instance, err := c.aem.InstanceManager().One()
@@ -87,17 +98,17 @@ func (c *CLI) KeystoreCreate() *cobra.Command {
8798
id, _ := cmd.Flags().GetString("id")
8899
scope, _ := cmd.Flags().GetString("scope")
89100
password, _ := cmd.Flags().GetString("keystore-password")
90-
changed, err := instance.Auth().UserManager().KeystoreCreate(scope, id, password)
101+
changed, err := instance.Auth().UserManager().Keystore().Create(scope, id, password)
91102

92103
if err != nil {
93104
c.Error(err)
94105
return
95106
}
96107

97108
if changed {
98-
c.Changed("User Keystore created")
109+
c.Changed("User keystore created")
99110
} else {
100-
c.Ok("User Keystore already exists")
111+
c.Ok("User keystore already exists")
101112
}
102113
},
103114
}
@@ -110,6 +121,94 @@ func (c *CLI) KeystoreCreate() *cobra.Command {
110121
return cmd
111122
}
112123

124+
func (c *CLI) userKeyAdd() *cobra.Command {
125+
cmd := &cobra.Command{
126+
Use: "add",
127+
Short: "Add user private key to the keystore",
128+
Aliases: []string{"create", "new"},
129+
Run: func(cmd *cobra.Command, args []string) {
130+
instance, err := c.aem.InstanceManager().One()
131+
if err != nil {
132+
c.Error(err)
133+
return
134+
}
135+
136+
changed, err := instance.Auth().UserManager().Keystore().AddKey(
137+
cmd.Flag("scope").Value.String(),
138+
cmd.Flag("id").Value.String(),
139+
cmd.Flag("keystore-file").Value.String(),
140+
cmd.Flag("keystore-password").Value.String(),
141+
cmd.Flag("key-alias").Value.String(),
142+
cmd.Flag("key-password").Value.String(),
143+
cmd.Flag("new-alias").Value.String(),
144+
)
145+
146+
if err != nil {
147+
c.Error(err)
148+
return
149+
}
150+
if changed {
151+
c.Changed("User key added")
152+
} else {
153+
c.Ok("User key already exists")
154+
}
155+
},
156+
}
157+
158+
cmd.Flags().String("id", "", "user id")
159+
_ = cmd.MarkFlagRequired("id")
160+
cmd.Flags().String("scope", "", "user scope")
161+
cmd.Flags().String("keystore-file", "", "path to keystore file")
162+
_ = cmd.MarkFlagRequired("keystore-file")
163+
cmd.Flags().String("keystore-password", "", "keystore password")
164+
_ = cmd.MarkFlagRequired("keystore-password")
165+
cmd.Flags().String("key-alias", "", "key alias")
166+
_ = cmd.MarkFlagRequired("key-alias")
167+
cmd.Flags().String("key-password", "", "key password")
168+
cmd.Flags().String("new-alias", "", "new key alias (optional)")
169+
170+
return cmd
171+
}
172+
173+
func (c *CLI) userKeyDelete() *cobra.Command {
174+
cmd := &cobra.Command{
175+
Use: "delete",
176+
Short: "Delete user private key from the keystore",
177+
Aliases: []string{"remove", "rm"},
178+
Run: func(cmd *cobra.Command, args []string) {
179+
instance, err := c.aem.InstanceManager().One()
180+
if err != nil {
181+
c.Error(err)
182+
return
183+
}
184+
185+
changed, err := instance.Auth().UserManager().Keystore().DeleteKey(
186+
cmd.Flag("scope").Value.String(),
187+
cmd.Flag("id").Value.String(),
188+
cmd.Flag("key-alias").Value.String(),
189+
)
190+
191+
if err != nil {
192+
c.Error(err)
193+
return
194+
}
195+
if changed {
196+
c.Changed("User key deleted")
197+
} else {
198+
c.Ok("User key does not exist")
199+
}
200+
},
201+
}
202+
203+
cmd.Flags().String("id", "", "user id")
204+
_ = cmd.MarkFlagRequired("id")
205+
cmd.Flags().String("scope", "", "user scope")
206+
cmd.Flags().String("key-alias", "", "key alias")
207+
_ = cmd.MarkFlagRequired("key-alias")
208+
209+
return cmd
210+
}
211+
113212
func (c *CLI) UserPasswordSet() *cobra.Command {
114213
cmd := &cobra.Command{
115214
Use: "set",

go.mod

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module github.com/wttech/aemc
22

3-
go 1.20
3+
go 1.24
44

55
require (
66
github.com/Masterminds/goutils v1.1.1
@@ -23,6 +23,7 @@ require (
2323
github.com/mholt/archiver/v3 v3.5.1
2424
github.com/olekukonko/tablewriter v0.0.5
2525
github.com/otiai10/copy v1.14.0
26+
github.com/pavlo-v-chernykh/keystore-go/v4 v4.5.0
2627
github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06
2728
github.com/samber/lo v1.39.0
2829
github.com/segmentio/textio v1.2.0

go.sum

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,13 @@ github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdf
3333
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
3434
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
3535
github.com/essentialkaos/check v1.2.1 h1:avvyFy/1acUNwfxwuOLsHeCjfXtMygtbu0lVDr3nxFs=
36+
github.com/essentialkaos/check v1.2.1/go.mod h1:PhxzfJWlf5L/skuyhzBLIvjMB5Xu9TIyDIsqpY5MvB8=
3637
github.com/essentialkaos/go-jar v1.0.6 h1:BAzvYTsXurNd/FcL4nYSH2pWV9DfavVAzlyYqULxcPE=
3738
github.com/essentialkaos/go-jar v1.0.6/go.mod h1:HZPc/zrzjoE2FjCRmIXZj7zQ6RN33/qjtf6ZxaEy7Hw=
3839
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
3940
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
4041
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
42+
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
4143
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
4244
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
4345
github.com/go-resty/resty/v2 v2.11.0 h1:i7jMfNOJYMp69lq7qozJP+bjgzfAzeOhuGlyDrqxT/8=
@@ -79,7 +81,9 @@ github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQ
7981
github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU=
8082
github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
8183
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
84+
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
8285
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
86+
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
8387
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
8488
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
8589
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
@@ -95,6 +99,7 @@ github.com/mholt/archiver/v3 v3.5.1/go.mod h1:e3dqJ7H78uzsRSEACH1joayhuSyhnonssn
9599
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
96100
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
97101
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
102+
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
98103
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
99104
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
100105
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
@@ -107,6 +112,9 @@ github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6
107112
github.com/otiai10/copy v1.14.0 h1:dCI/t1iTdYGtkvCuBG2BgR6KZa83PTclw4U5n2wAllU=
108113
github.com/otiai10/copy v1.14.0/go.mod h1:ECfuL02W+/FkTWZWgQqXPWZgW9oeKCSQ5qVfSc4qc4w=
109114
github.com/otiai10/mint v1.5.1 h1:XaPLeE+9vGbuyEHem1JNk3bYc7KKqyI/na0/mLd/Kks=
115+
github.com/otiai10/mint v1.5.1/go.mod h1:MJm72SBthJjz8qhefc4z1PYEieWmy8Bku7CjcAqyUSM=
116+
github.com/pavlo-v-chernykh/keystore-go/v4 v4.5.0 h1:2nosf3P75OZv2/ZO/9Px5ZgZ5gbKrzA3joN1QMfOGMQ=
117+
github.com/pavlo-v-chernykh/keystore-go/v4 v4.5.0/go.mod h1:lAVhWwbNaveeJmxrxuSTxMgKpF6DjnuVpn6T8WiBwYQ=
110118
github.com/pelletier/go-toml/v2 v2.1.1 h1:LWAJwfNvjQZCFIDKWYQaM62NcYeYViCmWIwmOStowAI=
111119
github.com/pelletier/go-toml/v2 v2.1.1/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
112120
github.com/pierrec/lz4/v4 v4.1.2/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
@@ -119,6 +127,7 @@ github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJ
119127
github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
120128
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
121129
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
130+
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
122131
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
123132
github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06 h1:OkMGxebDjyw0ULyrTYWeN0UNCCkmCWfjPnIA2W6oviI=
124133
github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06/go.mod h1:+ePHsJ1keEjQtpvf9HHw0f4ZeJ0TLRsxhunSI2hYJSs=
@@ -218,6 +227,7 @@ golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
218227
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
219228
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
220229
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
230+
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
221231
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
222232
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
223233
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
@@ -226,6 +236,7 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
226236
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
227237
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
228238
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
239+
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
229240
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
230241
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
231242
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
File renamed without changes.

pkg/keystore/keystore_status.go renamed to pkg/keystore/status.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ package keystore
22

33
import (
44
"bytes"
5+
"io"
6+
57
"github.com/samber/lo"
68
"github.com/wttech/aemc/pkg/common/fmtx"
7-
"io"
89
)
910

1011
type Status struct {
@@ -34,3 +35,9 @@ func (s *Status) MarshalText() string {
3435
})))
3536
return bs.String()
3637
}
38+
39+
func (s *Status) HasAlias(privateKeyAlias string) bool {
40+
return lo.ContainsBy(s.PrivateKeys, func(c PrivateKey) bool {
41+
return c.Alias == privateKeyAlias
42+
})
43+
}

0 commit comments

Comments
 (0)