package user import ( "context" "time" "forge.cadoles.com/Cadoles/emissary/internal/datastore" "forge.cadoles.com/Cadoles/emissary/internal/jwk" "github.com/lestrrat-go/jwx/v2/jwa" "github.com/lestrrat-go/jwx/v2/jws" "github.com/lestrrat-go/jwx/v2/jwt" "github.com/pkg/errors" ) func parseToken(ctx context.Context, keys jwk.Set, rawToken string, acceptableSkew time.Duration) (jwt.Token, error) { token, err := jwt.Parse( []byte(rawToken), jwt.WithKeySet(keys, jws.WithRequireKid(false)), jwt.WithValidate(true), jwt.WithAcceptableSkew(acceptableSkew), jwt.WithContext(ctx), ) if err != nil { return nil, errors.WithStack(err) } return token, nil } const ( DefaultRoleKey string = "role" DefaultTenantKey string = "tenant" ) func GenerateToken(ctx context.Context, key jwk.Key, tenant datastore.TenantID, subject string, role Role) (string, error) { token := jwt.New() if err := token.Set(jwt.SubjectKey, subject); err != nil { return "", errors.WithStack(err) } if err := token.Set(DefaultRoleKey, role); err != nil { return "", errors.WithStack(err) } if err := token.Set(DefaultTenantKey, tenant); err != nil { return "", errors.WithStack(err) } now := time.Now().UTC() if err := token.Set(jwt.NotBeforeKey, now); err != nil { return "", errors.WithStack(err) } if err := token.Set(jwt.IssuedAtKey, now); err != nil { return "", errors.WithStack(err) } rawToken, err := jwt.Sign(token, jwt.WithKey(jwa.RS256, key)) if err != nil { return "", errors.WithStack(err) } return string(rawToken), nil }