-
Notifications
You must be signed in to change notification settings - Fork 9
Add user private keys management commands: add, delete #304
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 5 commits
546a23e
89283a7
2384789
3afa3a8
7ede2e4
4dabdca
7f18fed
0389721
967dd39
edfd649
9ad92cf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -13,6 +13,7 @@ func (c *CLI) userCmd() *cobra.Command { | |
| Aliases: []string{"usr"}, | ||
| } | ||
| cmd.AddCommand(c.userKeyStore()) | ||
| cmd.AddCommand(c.userKey()) | ||
| cmd.AddCommand(c.userPassword()) | ||
| return cmd | ||
| } | ||
|
|
@@ -29,10 +30,21 @@ func (c *CLI) userKeyStore() *cobra.Command { | |
| return cmd | ||
| } | ||
|
|
||
| func (c *CLI) userKey() *cobra.Command { | ||
| cmd := &cobra.Command{ | ||
| Use: "key", | ||
| Short: "Private keys management", | ||
| Aliases: []string{"keys"}, | ||
| } | ||
| cmd.AddCommand(c.userKeyAdd()) | ||
| cmd.AddCommand(c.userKeyDelete()) | ||
| return cmd | ||
| } | ||
|
|
||
| func (c *CLI) userPassword() *cobra.Command { | ||
| cmd := &cobra.Command{ | ||
| Use: "password", | ||
| Short: "User password management", | ||
| Short: "Password management", | ||
| Aliases: []string{"pwd"}, | ||
| } | ||
| cmd.AddCommand(c.UserPasswordSet()) | ||
|
|
@@ -42,7 +54,7 @@ func (c *CLI) userPassword() *cobra.Command { | |
| func (c *CLI) KeystoreStatus() *cobra.Command { | ||
| cmd := &cobra.Command{ | ||
| Use: "status", | ||
| Short: "Get status of keystore", | ||
| Short: "Get status of a user's keystore", | ||
| Aliases: []string{"show", "get", "read", "describe", "ls"}, | ||
| Run: func(cmd *cobra.Command, args []string) { | ||
| instance, err := c.aem.InstanceManager().One() | ||
|
|
@@ -54,7 +66,7 @@ func (c *CLI) KeystoreStatus() *cobra.Command { | |
| id, _ := cmd.Flags().GetString("id") | ||
| scope, _ := cmd.Flags().GetString("scope") | ||
|
|
||
| result, err := instance.Auth().UserManager().KeystoreStatus(scope, id) | ||
| result, err := instance.Auth().UserManager().Keystore().Status(scope, id) | ||
|
|
||
| if err != nil { | ||
| c.Error(err) | ||
|
|
@@ -68,14 +80,13 @@ func (c *CLI) KeystoreStatus() *cobra.Command { | |
| cmd.Flags().String("id", "", "user id") | ||
| _ = cmd.MarkFlagRequired("id") | ||
| cmd.Flags().String("scope", "", "user scope") | ||
| _ = cmd.MarkFlagRequired("scope") | ||
| return cmd | ||
| } | ||
|
|
||
| func (c *CLI) KeystoreCreate() *cobra.Command { | ||
| cmd := &cobra.Command{ | ||
| Use: "create", | ||
| Short: "Create user Keystore", | ||
| Short: "Create user's keystore", | ||
| Aliases: []string{"make", "new"}, | ||
| Run: func(cmd *cobra.Command, args []string) { | ||
| instance, err := c.aem.InstanceManager().One() | ||
|
|
@@ -87,17 +98,17 @@ func (c *CLI) KeystoreCreate() *cobra.Command { | |
| id, _ := cmd.Flags().GetString("id") | ||
| scope, _ := cmd.Flags().GetString("scope") | ||
| password, _ := cmd.Flags().GetString("keystore-password") | ||
| changed, err := instance.Auth().UserManager().KeystoreCreate(scope, id, password) | ||
| changed, err := instance.Auth().UserManager().Keystore().Create(scope, id, password) | ||
|
|
||
| if err != nil { | ||
| c.Error(err) | ||
| return | ||
| } | ||
|
|
||
| if changed { | ||
| c.Changed("User Keystore created") | ||
| c.Changed("User keystore created") | ||
| } else { | ||
| c.Ok("User Keystore already exists") | ||
| c.Ok("User keystore already exists") | ||
| } | ||
| }, | ||
| } | ||
|
|
@@ -110,6 +121,94 @@ func (c *CLI) KeystoreCreate() *cobra.Command { | |
| return cmd | ||
| } | ||
|
|
||
| func (c *CLI) userKeyAdd() *cobra.Command { | ||
| cmd := &cobra.Command{ | ||
| Use: "add", | ||
| Short: "Add user's private key to their keystore", | ||
|
||
| Aliases: []string{"create", "new"}, | ||
| Run: func(cmd *cobra.Command, args []string) { | ||
| instance, err := c.aem.InstanceManager().One() | ||
| if err != nil { | ||
| c.Error(err) | ||
| return | ||
| } | ||
|
|
||
| changed, err := instance.Auth().UserManager().Keystore().AddKey( | ||
| cmd.Flag("scope").Value.String(), | ||
| cmd.Flag("id").Value.String(), | ||
| cmd.Flag("keystore-file").Value.String(), | ||
| cmd.Flag("keystore-password").Value.String(), | ||
| cmd.Flag("key-alias").Value.String(), | ||
| cmd.Flag("key-password").Value.String(), | ||
| cmd.Flag("new-alias").Value.String(), | ||
| ) | ||
|
|
||
| if err != nil { | ||
| c.Error(err) | ||
| return | ||
| } | ||
| if changed { | ||
| c.Changed("User key added") | ||
| } else { | ||
| c.Ok("User key already exists") | ||
| } | ||
| }, | ||
| } | ||
|
|
||
| cmd.Flags().String("id", "", "user id") | ||
| _ = cmd.MarkFlagRequired("id") | ||
| cmd.Flags().String("scope", "", "user scope") | ||
| cmd.Flags().String("keystore-file", "", "path to keystore file") | ||
| _ = cmd.MarkFlagRequired("keystore-file") | ||
| cmd.Flags().String("keystore-password", "", "keystore password") | ||
| _ = cmd.MarkFlagRequired("keystore-password") | ||
| cmd.Flags().String("key-alias", "", "key alias") | ||
| _ = cmd.MarkFlagRequired("key-alias") | ||
| cmd.Flags().String("key-password", "", "key password") | ||
| cmd.Flags().String("new-alias", "", "new key alias (optional)") | ||
|
|
||
| return cmd | ||
| } | ||
|
|
||
| func (c *CLI) userKeyDelete() *cobra.Command { | ||
| cmd := &cobra.Command{ | ||
| Use: "delete", | ||
| Short: "Delete user's private key from their keystore", | ||
| Aliases: []string{"remove", "rm"}, | ||
| Run: func(cmd *cobra.Command, args []string) { | ||
| instance, err := c.aem.InstanceManager().One() | ||
| if err != nil { | ||
| c.Error(err) | ||
| return | ||
| } | ||
|
|
||
| changed, err := instance.Auth().UserManager().Keystore().DeleteKey( | ||
| cmd.Flag("scope").Value.String(), | ||
| cmd.Flag("id").Value.String(), | ||
| cmd.Flag("key-alias").Value.String(), | ||
| ) | ||
|
|
||
| if err != nil { | ||
| c.Error(err) | ||
| return | ||
| } | ||
| if changed { | ||
| c.Changed("User key deleted") | ||
| } else { | ||
| c.Ok("User key does not exist") | ||
| } | ||
| }, | ||
| } | ||
|
|
||
| cmd.Flags().String("id", "", "user id") | ||
| _ = cmd.MarkFlagRequired("id") | ||
| cmd.Flags().String("scope", "", "user scope") | ||
| cmd.Flags().String("key-alias", "", "key alias") | ||
| _ = cmd.MarkFlagRequired("key-alias") | ||
|
|
||
| return cmd | ||
| } | ||
|
|
||
| func (c *CLI) UserPasswordSet() *cobra.Command { | ||
| cmd := &cobra.Command{ | ||
| Use: "set", | ||
|
|
||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. keystore/{keystore_status => status}.go |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,159 @@ | ||
| package pkg | ||
|
|
||
| import ( | ||
| "fmt" | ||
| "slices" | ||
|
|
||
| "github.com/wttech/aemc/pkg/common/pathx" | ||
| "github.com/wttech/aemc/pkg/keystore" | ||
| ) | ||
|
|
||
| type KeystoreManager struct { | ||
| instance *Instance | ||
| } | ||
|
|
||
| func (km *KeystoreManager) Status(scope, id string) (*keystore.Status, error) { | ||
| userKeystorePath := composeUserPath(scope, id) + ".ks.json" | ||
|
||
|
|
||
| response, err := km.instance.http.Request().Get(userKeystorePath) | ||
|
|
||
| if err != nil { | ||
| return nil, fmt.Errorf("%s > cannot read user keystore: %w", km.instance.IDColor(), err) | ||
| } | ||
|
|
||
| if response.IsError() { | ||
| return nil, fmt.Errorf("%s > cannot read user keystore: %s", km.instance.IDColor(), response.Status()) | ||
| } | ||
|
|
||
| result, err := keystore.UnmarshalStatus(response.RawBody()) | ||
| if err != nil { | ||
| return nil, fmt.Errorf("%s > cannot parse user keystore status response: %w", km.instance.IDColor(), err) | ||
| } | ||
|
|
||
| return result, nil | ||
| } | ||
|
|
||
| func (km *KeystoreManager) Create(scope, id, keystorePassword string) (bool, error) { | ||
| statusResponse, statusError := km.Status(scope, id) | ||
| if statusError != nil { | ||
| return false, statusError | ||
| } | ||
|
|
||
| if statusResponse.Created { | ||
| return false, nil | ||
| } | ||
|
|
||
| pathParams := map[string]string{ | ||
| "newPassword": keystorePassword, | ||
| "rePassword": keystorePassword, | ||
| ":operation": "createStore", | ||
| } | ||
|
|
||
| userKeystoreCreatePath := composeUserPath(scope, id) + ".ks.html" | ||
| postResponse, postError := km.instance.http.Request().SetQueryParams(pathParams).Post(userKeystoreCreatePath) | ||
|
|
||
| if postError != nil { | ||
| return false, fmt.Errorf("%s > cannot create user keystore: %w", km.instance.IDColor(), postError) | ||
| } | ||
|
|
||
| if postResponse.IsError() { | ||
| return false, fmt.Errorf("%s > cannot create user keystore: %s", km.instance.IDColor(), postResponse.Status()) | ||
| } | ||
|
|
||
| return true, nil | ||
| } | ||
|
|
||
| func (km *KeystoreManager) AddKey(scope, id, keystoreFilePath, keystoreFilePassword, privateKeyAlias, privateKeyPassword, privateKeyNewAlias string) (bool, error) { | ||
| if !pathx.Exists(keystoreFilePath) { | ||
| return false, fmt.Errorf("%s > keystore file does not exist: %s", km.instance.IDColor(), keystoreFilePath) | ||
| } | ||
| if privateKeyNewAlias == "" { | ||
| privateKeyNewAlias = privateKeyAlias | ||
| } | ||
| if privateKeyPassword == "" { | ||
| privateKeyPassword = keystoreFilePassword | ||
| } | ||
|
|
||
| readKeystore, err := readKeyStore(keystoreFilePath, []byte(keystoreFilePassword)) | ||
| if err != nil { | ||
| return false, fmt.Errorf("%s > cannot read keystore file %s: %w", km.instance.IDColor(), keystoreFilePath, err) | ||
| } | ||
|
|
||
| aliases := readKeystore.Aliases() | ||
| if aliases == nil { | ||
| return false, fmt.Errorf("%s > keystore file does not contain any aliases", km.instance.IDColor()) | ||
| } | ||
| if !slices.Contains(aliases, privateKeyAlias) { | ||
| return false, fmt.Errorf("%s > keystore file does not contain alias: %s", km.instance.IDColor(), privateKeyAlias) | ||
| } | ||
|
|
||
| status, err := km.Status(scope, id) | ||
| if err != nil { | ||
| return false, err | ||
| } | ||
|
|
||
| if status == nil || !status.Created { | ||
| return false, fmt.Errorf("%s > cannot add key as keystore does not exist", km.instance.IDColor()) | ||
| } | ||
| if status.HasAlias(privateKeyAlias) { | ||
| return false, nil | ||
| } | ||
|
|
||
| requestFiles := map[string]string{ | ||
| "keyStore": keystoreFilePath, | ||
| } | ||
|
|
||
| keystorePath := composeUserPath(scope, id) + ".ks.html" | ||
| formData := map[string]string{ | ||
| "keyStorePass": keystoreFilePassword, | ||
| "alias": privateKeyAlias, | ||
| "keyPassword": privateKeyPassword, | ||
| "newAlias": privateKeyNewAlias, | ||
| "keyStoreType": "jks", | ||
| } | ||
|
|
||
| response, err := km.instance.http.Request(). | ||
| SetFiles(requestFiles). | ||
| SetFormData(formData). | ||
| Post(keystorePath) | ||
|
|
||
| if err != nil { | ||
| return false, fmt.Errorf("%s > cannot add key: %w", km.instance.IDColor(), err) | ||
| } | ||
| if response.IsError() { | ||
| return false, fmt.Errorf("%s > cannot add key: %s", km.instance.IDColor(), response.Status()) | ||
| } | ||
| return true, nil | ||
| } | ||
|
|
||
| func (km *KeystoreManager) DeleteKey(scope, id, privateKeyAlias string) (bool, error) { | ||
| status, err := km.Status(scope, id) | ||
| if err != nil { | ||
| return false, err | ||
| } | ||
|
|
||
| if status == nil || !status.Created { | ||
| return false, fmt.Errorf("%s > cannot delete key: keystore does not exist", km.instance.IDColor()) | ||
| } | ||
| if !status.HasAlias(privateKeyAlias) { | ||
| return false, nil | ||
| } | ||
|
|
||
| formData := map[string]string{ | ||
| "removeAlias": privateKeyAlias, | ||
| } | ||
|
|
||
| userKeystorePath := composeUserPath(scope, id) + ".ks.html" | ||
| response, err := km.instance.http.Request(). | ||
| SetFormData(formData). | ||
| Post(userKeystorePath) | ||
|
|
||
| if err != nil { | ||
| return false, fmt.Errorf("%s > cannot delete key: %w", km.instance.IDColor(), err) | ||
| } | ||
| if response.IsError() { | ||
| return false, fmt.Errorf("%s > cannot delete key: %s", km.instance.IDColor(), response.Status()) | ||
| } | ||
|
|
||
| return true, nil | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just
user keystore? :)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok