diff --git a/tests/accounts_test.go b/tests/accounts_test.go index 952258a..4a2061d 100644 --- a/tests/accounts_test.go +++ b/tests/accounts_test.go @@ -2,9 +2,10 @@ package tests import ( "fmt" - "github.com/nats-io/nkeys" "time" + "github.com/nats-io/nkeys" + "github.com/nats-io/jwt/v2" authb "github.com/synadia-io/jwt-auth-builder.go" ) diff --git a/tests/external_test.go b/tests/external_test.go index c8f7f2d..2ab0742 100644 --- a/tests/external_test.go +++ b/tests/external_test.go @@ -2,11 +2,12 @@ package tests import ( "fmt" + "testing" + "github.com/nats-io/nkeys" "github.com/stretchr/testify/assert" authb "github.com/synadia-io/jwt-auth-builder.go" nsc "github.com/synadia-io/jwt-auth-builder.go/providers/nsc" - "testing" ) func TestExternal(v *testing.T) { diff --git a/tests/users_test.go b/tests/users_test.go index f6829ab..1812114 100644 --- a/tests/users_test.go +++ b/tests/users_test.go @@ -1,9 +1,10 @@ package tests import ( - "github.com/nats-io/nkeys" "time" + "github.com/nats-io/nkeys" + "github.com/nats-io/jwt/v2" authb "github.com/synadia-io/jwt-auth-builder.go" ) diff --git a/types.go b/types.go index e8ad8b2..cee09b9 100644 --- a/types.go +++ b/types.go @@ -348,6 +348,8 @@ type Users interface { // If the provided ID is only a public key the user will be ephemeral and will not stored, // other operations, as cred generation will fail AddWithIdentity(name string, signer string, id string) (User, error) + // ImportEphemeral imports an ephemeral user from a claim + ImportEphemeral(c *jwt.UserClaims, key string) (User, error) // Delete the user by matching its name or subject Delete(name string) error // Get returns the user by matching its name or subject diff --git a/users.go b/users.go index e5733b2..2165bbe 100644 --- a/users.go +++ b/users.go @@ -17,6 +17,43 @@ func (a *UsersImpl) Add(name string, key string) (User, error) { return a.add(name, key, uk) } +func (a *UsersImpl) ImportEphemeral(c *jwt.UserClaims, key string) (User, error) { + if key == "" { + key = a.accountData.Key.Public + } + k, signingKey, err := a.accountData.getKey(key) + if err != nil { + return nil, err + } + + id, err := KeyFrom(c.Subject, nkeys.PrefixByteUser) + if err != nil { + return nil, err + } + ok, scoped := a.accountData.ScopedSigningKeys().Contains(key) + + d := &UserData{ + BaseData: BaseData{EntityName: c.Name, Key: id, Modified: true}, + AccountData: a.accountData, + Claim: c, + RejectEdits: ok && scoped, + Ephemeral: true, + } + d.Claim.Name = c.Name + if signingKey { + d.Claim.IssuerAccount = a.accountData.Key.Public + } + if scoped { + d.Claim.UserPermissionLimits = jwt.UserPermissionLimits{} + } + d.Token, err = a.accountData.Operator.SigningService.Sign(d.Claim, k) + if err != nil { + return nil, err + } + a.accountData.UserDatas = append(a.accountData.UserDatas, d) + return d, nil +} + func (a *UsersImpl) add(name string, key string, uk *Key) (User, error) { if key == "" { key = a.accountData.Key.Public