Skip to content

Commit

Permalink
[FEAT] changed edit signing-key to allow --sk generate, or infer …
Browse files Browse the repository at this point in the history
…the sk if the value for the role is given or just the role is given

FIX #633
  • Loading branch information
aricart committed Feb 1, 2024
1 parent 3f89317 commit 3ea62a0
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 6 deletions.
49 changes: 43 additions & 6 deletions cmd/editscopedsk.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ nsc edit signing-key --account <n> --sk <sk> --allow-sub <subject>,...
return RunAction(cmd, args, &params)
},
}
cmd.Flags().StringVarP(&params.skName, "sk", "", "", "signing key to set scope for or role name for already existing scoped signing key")
cmd.Flags().StringVarP(&params.role, "role", "", "", "role associated with the signing key scope")
params.sk.BindFlagsForOne("sk", "", nkeys.PrefixByteAccount, cmd)
params.AccountContextParams.BindFlags(cmd)
params.UserPermissionLimits.BindFlags(cmd)
return cmd
Expand All @@ -52,6 +52,7 @@ func init() {
}

type EditScopedSkParams struct {
sk SigningKeysParams
skName string
role string
claim *jwt.AccountClaims
Expand All @@ -66,6 +67,7 @@ func (p *EditScopedSkParams) SetDefaults(ctx ActionCtx) error {
return err
}
p.SignerParams.SetDefaults(nkeys.PrefixByteOperator, true, ctx)

return nil
}

Expand All @@ -80,16 +82,51 @@ func (p *EditScopedSkParams) Load(ctx ActionCtx) error {
return err
}

if p.skName == "" {
ctx.CurrentCmd().SilenceUsage = false
return fmt.Errorf("signing key is required")
}

p.claim, err = ctx.StoreCtx().Store.ReadAccountClaim(p.AccountContextParams.Name)
if err != nil {
return err
}

if p.sk.Empty() && p.role != "" {
kp := keyByRoleName(ctx.StoreCtx().KeyStore, p.claim, p.role)
if kp != nil {
s, err := kp.PublicKey()
if err != nil {
return err
}
p.sk.paths = append(p.sk.paths, s)
}
}

// try to normalize the values
if err := p.sk.Valid(); err != nil {
// if we are not valid, that means we didn't get a sk or "generate"
if len(p.sk.paths) > 0 {
// try that as a scope role
kp := keyByRoleName(ctx.StoreCtx().KeyStore, p.claim, p.sk.paths[0])
if kp != nil {
s, err := kp.PublicKey()
if err != nil {
return err
}
p.skName = s
}
}
}

if p.skName == "" {
pks, err := p.sk.PublicKeys()
if err != nil {
return err
}
if len(pks) > 0 {
p.skName = pks[0]
} else {
ctx.CurrentCmd().SilenceUsage = false
return fmt.Errorf("signing key is required")
}
}

s, found := p.claim.SigningKeys.GetScope(p.skName)
if !found {
kp := keyByRoleName(ctx.StoreCtx().KeyStore, p.claim, p.skName)
Expand Down
82 changes: 82 additions & 0 deletions cmd/editscopedsk_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,3 +138,85 @@ func Test_EditScopedSk_ResolveAny(t *testing.T) {
"--sk", "foo", "--subs", "10")
require.Error(t, err)
}

func Test_EditScopedSkAddGenerates(t *testing.T) {
ts := NewTestStore(t, "edit scope")
defer ts.Done(t)

_, err := ts.Store.ReadOperatorClaim()
require.NoError(t, err)

ts.AddAccount(t, "A")

// add the scope with a generate
_, _, err = ExecuteCmd(createEditSkopedSkCmd(), "--sk", "generate")
require.NoError(t, err)

ac, err := ts.Store.ReadAccountClaim("A")
require.NoError(t, err)
require.Len(t, ac.SigningKeys.Keys(), 1)
pk := ac.SigningKeys.Keys()[0]
scope, ok := ac.SigningKeys.GetScope(pk)
require.True(t, ok)
us, ok := scope.(*jwt.UserScope)
require.True(t, ok)
require.NotNil(t, us)

// get the scope with the key
_, _, err = ExecuteCmd(createEditSkopedSkCmd(), "--sk", pk, "--role", "foo")
require.NoError(t, err)

ac, err = ts.Store.ReadAccountClaim("A")
require.NoError(t, err)
require.Len(t, ac.SigningKeys.Keys(), 1)
scope, ok = ac.SigningKeys.GetScope(pk)
require.True(t, ok)
us, ok = scope.(*jwt.UserScope)
require.True(t, ok)
require.NotNil(t, us)
require.Equal(t, us.Role, "foo")
}

func Test_EditScopedSkByRole(t *testing.T) {
ts := NewTestStore(t, "edit scope")
defer ts.Done(t)

_, err := ts.Store.ReadOperatorClaim()
require.NoError(t, err)

ts.AddAccount(t, "A")

// add the scope with a generate
_, _, err = ExecuteCmd(createEditSkopedSkCmd(), "--sk", "generate", "--role", "foo")
require.NoError(t, err)

// get the scope by saying that the key is the role
_, _, err = ExecuteCmd(createEditSkopedSkCmd(), "--sk", "foo", "--allow-pub", ">")
require.NoError(t, err)

ac, err := ts.Store.ReadAccountClaim("A")
require.NoError(t, err)
require.Len(t, ac.SigningKeys.Keys(), 1)
scope, ok := ac.SigningKeys.GetScope(ac.SigningKeys.Keys()[0])
require.True(t, ok)
us, ok := scope.(*jwt.UserScope)
require.True(t, ok)
require.NotNil(t, us)
require.Equal(t, us.Role, "foo")
require.Len(t, us.Template.Pub.Allow, 1)

// get the scope by just specifying the role
_, _, err = ExecuteCmd(createEditSkopedSkCmd(), "--role", "foo", "--allow-sub", ">")
require.NoError(t, err)

ac, err = ts.Store.ReadAccountClaim("A")
require.NoError(t, err)
require.Len(t, ac.SigningKeys.Keys(), 1)
scope, ok = ac.SigningKeys.GetScope(ac.SigningKeys.Keys()[0])
require.True(t, ok)
us, ok = scope.(*jwt.UserScope)
require.True(t, ok)
require.NotNil(t, us)
require.Equal(t, us.Role, "foo")
require.Len(t, us.Template.Sub.Allow, 1)
}
15 changes: 15 additions & 0 deletions cmd/signingkeyseditor.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,17 @@ func (e *SigningKeysParams) BindFlags(flagName string, shorthand string, kind nk
}
}

func (e *SigningKeysParams) BindFlagsForOne(flagName string, shorthand string, kind nkeys.PrefixByte, cmd *cobra.Command) {
e.flagName = flagName
e.kind = kind
if kind == nkeys.PrefixByteCurve {
e.paths = make([]string, 1)
cmd.Flags().StringVarP(&e.paths[0], flagName, shorthand, "", `curve key or keypath or the value "generate" to generate a curve encryption target key on the fly`)
} else {
cmd.Flags().StringSliceVarP(&e.paths, flagName, shorthand, nil, `signing key or keypath or the value "generate" to generate a key pair on the fly`)
}
}

func (e *SigningKeysParams) valid(s string) error {
if s == "generate" {
return nil
Expand Down Expand Up @@ -96,6 +107,10 @@ func (e *SigningKeysParams) Valid() error {
return nil
}

func (e *SigningKeysParams) Empty() bool {
return len(e.paths) == 0
}

func (e *SigningKeysParams) PublicKeys() ([]string, error) {
var keys []string
for _, v := range e.paths {
Expand Down

0 comments on commit 3ea62a0

Please sign in to comment.