diff --git a/app/boot_levels.go b/app/boot_levels.go index ba5c48cf7..78c8c8905 100644 --- a/app/boot_levels.go +++ b/app/boot_levels.go @@ -123,7 +123,9 @@ func (app *CortezaApp) Setup() (err error) { // set base path for links&routes in auth server authHandlers.BasePath = app.Opt.HTTPServer.BaseUrl - auth.SetupDefault(app.Opt.Auth.Secret, app.Opt.Auth.Expiry) + if err = auth.SetupDefault(app.Opt.Auth.Secret, app.Opt.Auth.Expiry); err != nil { + return + } http.SetupDefaults( app.Opt.HTTPClient.HttpClientTimeout, diff --git a/auth/auth.go b/auth/auth.go index 09681297a..84a9f7283 100644 --- a/auth/auth.go +++ b/auth/auth.go @@ -135,10 +135,8 @@ func New(ctx context.Context, log *zap.Logger, s store.Storer, opt options.AuthO } // ensure all requested scopes are allowed on a client - for _, scope := range strings.Split(tgr.Scope, " ") { - if !auth.CheckScope(client.Scope, scope) { - return false, fmt.Errorf("client does not allow use of '%s' scope", scope) - } + if !auth.CheckScope(client.Scope, strings.Split(tgr.Scope, " ")...) { + return false, fmt.Errorf("client does not allow use of '%s' scope", client.Scope) } return true, nil diff --git a/auth/handlers/handle_oauth2.go b/auth/handlers/handle_oauth2.go index f796ce233..d47b8f191 100644 --- a/auth/handlers/handle_oauth2.go +++ b/auth/handlers/handle_oauth2.go @@ -6,13 +6,14 @@ import ( "crypto/rsa" "encoding/json" "fmt" - "github.com/lestrrat-go/jwx/jwk" "net/http" "net/url" "strconv" "strings" "time" + "github.com/lestrrat-go/jwx/jwk" + "github.com/cortezaproject/corteza-server/auth/oauth2" "github.com/cortezaproject/corteza-server/auth/request" "github.com/cortezaproject/corteza-server/pkg/auth" diff --git a/auth/oauth2/oauth2.go b/auth/oauth2/oauth2.go index 2ecb26d45..ed499f1db 100644 --- a/auth/oauth2/oauth2.go +++ b/auth/oauth2/oauth2.go @@ -97,8 +97,7 @@ func NewServer(manager *manage.Manager) *server.Server { msg = re.Error.Error() } - logger.Default(). - Warn(msg) + logger.Default().Warn(msg) }) return srv diff --git a/automation/automation/jwt_handler.go b/automation/automation/jwt_handler.go index ee9887d8e..532d0047d 100644 --- a/automation/automation/jwt_handler.go +++ b/automation/automation/jwt_handler.go @@ -2,12 +2,14 @@ package automation import ( "context" + "crypto/x509" "encoding/json" + "encoding/pem" "fmt" "strings" "github.com/lestrrat-go/jwx/jwa" - "github.com/lestrrat-go/jwx/jwk" + "github.com/lestrrat-go/jwx/jws" "github.com/lestrrat-go/jwx/jwt" ) @@ -68,38 +70,36 @@ func (h jwtHandler) generate(ctx context.Context, args *jwtGenerateArgs) (res *j }) var ( + key interface{} + tkn = jwt.New() - keySet jwk.Set tokenBytes []byte + headers = jws.NewHeaders() ) + for k, v := range auxh { + _ = headers.Set(k, v) + } + for k, v := range auxp { if err = tkn.Set(k, v); err != nil { return } } - //< HEAD - // // check if we use cert - // { - // pemBlock, _ := pem.Decode([]byte(args.secretString)) - // - // if pemBlock != nil { - // if secret, err = x509.ParsePKCS8PrivateKey(pemBlock.Bytes); err != nil { - // return - // } - // } else { - // secret = []byte(args.secretString) - // } - //= - // @todo check if jwk.Parse provides the same logic as before with pem.Decode and x59.ParsePkC8PrivateKey - if keySet, err = jwk.Parse([]byte(args.secretString)); err != nil { - return - //> e3a304d5... Replacing dgrijalva/jwt-go with lestrrat-go/jwx + if decodedKey, _ := pem.Decode([]byte(args.secretString)); decodedKey != nil { + if key, err = x509.ParsePKCS8PrivateKey(decodedKey.Bytes); err != nil { + return nil, err + } + + tokenBytes, err = jwt.Sign(tkn, jwa.RS256, key, jwt.WithHeaders(headers)) + } else { + key = []byte(args.secretString) + tokenBytes, err = jwt.Sign(tkn, jwa.HS256, key, jwt.WithHeaders(headers)) } - if tokenBytes, err = jwt.Sign(tkn, jwa.HS512, keySet); err != nil { - return + if err != nil { + return nil, fmt.Errorf("could not sign token: %w", err) } return &jwtGenerateResults{Token: string(tokenBytes)}, nil diff --git a/automation/automation/jwt_handler_test.go b/automation/automation/jwt_handler_test.go index 9e4943708..3958439a5 100644 --- a/automation/automation/jwt_handler_test.go +++ b/automation/automation/jwt_handler_test.go @@ -9,75 +9,6 @@ import ( "github.com/stretchr/testify/require" ) -func TestJwtHandler(t *testing.T) { - type ( - tf struct { - name string - exp string - err error - params *jwtGenerateArgs - } - ) - - var ( - handler = &jwtHandler{} - tcc = []tf{ - { - name: "proxy processer with auth headers", - exp: "eyJhbGciOiJSUzI1NiIsImtleSI6InZhbHVlIiwidHlwIjoiSldUIn0.eyJrZXkiOiJ2YWx1ZSIsInNjb3BlIjpbInNjb3BlIiwic2NvcGUyIl19.OnnLBsJdrZwAPeMjYIJPlZPW7bZdp-JbgNKFrRPnPXcuQVAUxK-R69-kDZbdsRZFOaU-AC52Tz4Ft3-SzADgFroSpoNjpEdJwbaKANlG_pm2b8-1pXSc0YzhY7DqBs4iae2pI0FGpeT_dza6kp9TL3NQfgqjx05Q3Gz5-3Kk32MD3zIvpUXgwkPbb4XLJxiY2Ra1dRWVI5Guk4GyLA19b7Z-DrHg1GE9mDy_NwZZD994Iri9e5zmcAikRtfHO7guPtBKVwhvt3u37wXtRgEYMyFQAn2ZSZaTytK8161Y-TOcdLVlqy4OfasaVt1pP0aNI9GGz5R-OVCOghW7TqZ6YQ", - err: nil, - params: &jwtGenerateArgs{ - Scope: `scope scope2`, - headerVars: must(expr.CastToVars(map[string]interface{}{"key": "value"})), - payloadVars: must(expr.CastToVars(map[string]interface{}{"key": "value"})), - secretString: prKey, - hasHeader: true, - hasPayload: true, - hasSecret: true}, - }, - { - name: "proxy processer with auth headers", - exp: "", - err: errors.New("could not generate JWT, payload missing"), - params: &jwtGenerateArgs{ - hasHeader: true, - hasPayload: false, - hasSecret: true}, - }, - { - name: "proxy processer with auth headers", - exp: "", - err: errors.New("could not generate JWT, secret or cert missing"), - params: &jwtGenerateArgs{ - hasHeader: true, - hasPayload: true, - hasSecret: false}, - }, - } - ) - - for _, tc := range tcc { - t.Run(tc.name, func(t *testing.T) { - var ( - req = require.New(t) - ctx = context.Background() - ) - - res, err := handler.generate(ctx, tc.params) - - if tc.err == nil { - req.NoError(err) - } else { - req.EqualError(err, tc.err.Error()) - } - - if res != nil { - req.Equal(tc.exp, res.Token) - } - }) - } -} - const prKey string = `-----BEGIN PRIVATE KEY----- MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCn2MSVSyMzdZ5Q cD0KMZAuhAmWE06qS/agpkG9OmvxsBAXjS8/2oaLCtmpF7Sx7XEJOaVUz8caty0L @@ -107,6 +38,90 @@ DPEHFHeWn8T4obfuUjTw1mwj7Xjzr40HDitjIQa0bvBVwdYyEgiEw1CaeaUpq9Z8 ElGWoRHT87pfoZjbdPz7a4Y= -----END PRIVATE KEY-----` +func TestJwtHandler(t *testing.T) { + type ( + tf struct { + name string + exp string + err error + params *jwtGenerateArgs + } + ) + + var ( + handler = &jwtHandler{} + tcc = []tf{ + { + name: "proxy processer with auth headers", + exp: "eyJhbGciOiJSUzI1NiIsImtleSI6InZhbHVlIiwidHlwIjoiSldUIn0.eyJrZXkiOiJ2YWx1ZSIsInNjb3BlIjpbInNjb3BlIiwic2NvcGUyIl19.OnnLBsJdrZwAPeMjYIJPlZPW7bZdp-JbgNKFrRPnPXcuQVAUxK-R69-kDZbdsRZFOaU-AC52Tz4Ft3-SzADgFroSpoNjpEdJwbaKANlG_pm2b8-1pXSc0YzhY7DqBs4iae2pI0FGpeT_dza6kp9TL3NQfgqjx05Q3Gz5-3Kk32MD3zIvpUXgwkPbb4XLJxiY2Ra1dRWVI5Guk4GyLA19b7Z-DrHg1GE9mDy_NwZZD994Iri9e5zmcAikRtfHO7guPtBKVwhvt3u37wXtRgEYMyFQAn2ZSZaTytK8161Y-TOcdLVlqy4OfasaVt1pP0aNI9GGz5R-OVCOghW7TqZ6YQ", + err: nil, + params: &jwtGenerateArgs{ + Scope: `scope scope2`, + headerVars: must(expr.CastToVars(map[string]interface{}{"key": "value"})), + payloadVars: must(expr.CastToVars(map[string]interface{}{"key": "value"})), + secretString: prKey, + hasHeader: true, + hasPayload: true, + hasSecret: true, + }, + }, + { + name: "sign with secret", + exp: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJ2YWx1ZSIsInNjb3BlIjpbInNjb3BlIiwic2NvcGUyIl19.hvdRtewS0d8wPHF-oNHj0BaeOhgmmJkmerzg_qUI1Uo", + params: &jwtGenerateArgs{ + Scope: `scope scope2`, + hasHeader: true, + payloadVars: must(expr.CastToVars(map[string]interface{}{"key": "value"})), + hasPayload: true, + hasSecret: true, + secretString: "*silly-secret*", + }, + }, + { + name: "proxy processer with auth headers", + exp: "", + err: errors.New("could not generate JWT, payload missing"), + params: &jwtGenerateArgs{ + hasHeader: true, + hasPayload: false, + hasSecret: true, + }, + }, + { + name: "proxy processer with auth headers", + exp: "", + err: errors.New("could not generate JWT, secret or cert missing"), + params: &jwtGenerateArgs{ + hasHeader: true, + hasPayload: true, + hasSecret: false, + }, + }, + } + ) + + for _, tc := range tcc { + t.Run(tc.name, func(t *testing.T) { + var ( + req = require.New(t) + ctx = context.Background() + ) + + res, err := handler.generate(ctx, tc.params) + + if tc.err == nil { + req.NoError(err) + } else { + req.EqualError(err, tc.err.Error()) + } + + if res != nil { + req.Equal(tc.exp, res.Token) + } + }) + } +} + func must(v map[string]expr.TypedValue, err error) map[string]expr.TypedValue { if err != nil { panic(err) diff --git a/pkg/api/server/server.go b/pkg/api/server/server.go index 61b4c4350..29c323f3e 100644 --- a/pkg/api/server/server.go +++ b/pkg/api/server/server.go @@ -85,6 +85,8 @@ func (s server) Serve(ctx context.Context) { r.Use(LogResponse) } + println("using up DefaultJwtHandler", auth.DefaultJwtHandler != nil) + r.Use( auth.DefaultJwtHandler.HttpVerifier(), auth.DefaultJwtHandler.HttpAuthenticator(), diff --git a/pkg/auth/jwt.go b/pkg/auth/jwt.go index bb0bfd40b..bd804ff82 100644 --- a/pkg/auth/jwt.go +++ b/pkg/auth/jwt.go @@ -4,12 +4,15 @@ import ( "context" "encoding/json" "fmt" + "net/http" "strings" "time" + "github.com/cortezaproject/corteza-server/pkg/api" "github.com/cortezaproject/corteza-server/pkg/id" "github.com/cortezaproject/corteza-server/pkg/payload" "github.com/cortezaproject/corteza-server/system/types" + "github.com/go-chi/jwtauth" "github.com/lestrrat-go/jwx/jwa" "github.com/lestrrat-go/jwx/jwk" "github.com/lestrrat-go/jwx/jwt" @@ -22,7 +25,7 @@ type ( expiry time.Duration signAlgo jwa.SignatureAlgorithm - signKey jwk.Set + signKey jwk.Key } tokenStore interface { @@ -47,33 +50,30 @@ var ( DefaultJwtStore tokenStore ) -func SetupDefault(secret string, expiry time.Duration) { +func SetupDefault(secret string, expiry time.Duration) (err error) { // Use JWT secret for hmac signer for now DefaultSigner = HmacSigner(secret) - DefaultJwtHandler, _ = TokenManager(secret, expiry) + DefaultJwtHandler, err = TokenManager(secret, expiry) + return } -func TokenManager(secret string, expiry time.Duration) (*tokenManager, error) { - var ( - err error - set jwk.Set - ) - - if len(secret) == 0 { - return nil, fmt.Errorf("JWT secret missing") - } - - // @todo jwk.Parse can accept other input types beside byte-slice - // we could use it to strength Corteza's security - if set, err = jwk.Parse([]byte(secret)); err != nil { - return nil, err - } - - return &tokenManager{ +// TokenManager returns token management facility +// @todo should be extended to accept different kinds of algorythms, private-keys etc. +func TokenManager(secret string, expiry time.Duration) (tm *tokenManager, err error) { + tm = &tokenManager{ expiry: expiry, signAlgo: jwa.HS512, - signKey: set, - }, nil + } + + if len(secret) == 0 { + return nil, fmt.Errorf("JWK missing") + } + + if tm.signKey, err = jwk.New([]byte(secret)); err != nil { + return nil, fmt.Errorf("could not parse JWK: %w", err) + } + + return // //var ( @@ -103,9 +103,9 @@ func SetJWTStore(store tokenStore) { DefaultJwtStore = store } -// Authenticate the tokej from the given string and return parsed token or error +// Authenticate the token from the given string and return parsed token or error func (tm *tokenManager) Authenticate(token string) (pToken jwt.Token, err error) { - if pToken, err = jwt.Parse([]byte(token), jwt.WithKeySet(tm.signKey)); err != nil { + if pToken, err = jwt.Parse([]byte(token), jwt.WithVerify(tm.signAlgo, tm.signKey)); err != nil { return } @@ -154,7 +154,7 @@ func (tm *tokenManager) Encode(identity Identifiable, clientID uint64, scope ... // previous implementation had special a "salt" claim that ensured JWT uniquness // we're using more standard approach with JWT ID now. - if err = token.Set(jwt.JwtIDKey, id.Next()); err != nil { + if err = token.Set(jwt.JwtIDKey, fmt.Sprintf("%d", id.Next())); err != nil { return } @@ -194,49 +194,47 @@ func (tm *tokenManager) Encode(identity Identifiable, clientID uint64, scope ... //return access } -//// HttpVerifier returns a HTTP handler that verifies JWT and stores it into context -//func (t *tokenManager) HttpVerifier() func(http.Handler) http.Handler { -// //jwt.WithHTTPClient() -// return func(next http.Handler) http.Handler { -// return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { -// token, err := jwt.ParseRequest(req) -// if err != nil { -// -// } -// -// next.ServeHTTP(w, req) -// }) -// } -// -// return jwtauth.Verifier(t.tokenAuth) -//} +// HttpVerifier returns a HTTP handler that verifies JWT and stores it into context +func (tm *tokenManager) HttpVerifier() func(http.Handler) http.Handler { + ////jwt.WithHTTPClient() + //return func(next http.Handler) http.Handler { + // return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { + // token, err := jwt.ParseRequest(req) + // if err != nil { + // + // } + // + // next.ServeHTTP(w, req) + // }) + //} -//// HttpAuthenticator converts JWT claims into identity and stores it into context -//func (tm *tokenManager) HttpAuthenticator() func(http.Handler) http.Handler { -// return func(next http.Handler) http.Handler { -// return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { -// ctx := r.Context() -// -// tkn, claims, err := jwtauth.FromContext(ctx) -// -// // When token is present, expect no errors and valid claims! -// if tkn != nil { -// if err != nil { -// // But if token is present, the shouldn't be an error -// api.Send(w, r, err) -// return -// } -// -// ctx = SetIdentityToContext(ctx, ClaimsToIdentity(claims)) -// ctx = context.WithValue(ctx, scopeCtxKey{}, claims["scope"]) -// -// r = r.WithContext(ctx) -// } -// -// next.ServeHTTP(w, r) -// }) -// } -//} + return jwtauth.Verifier(jwtauth.New(tm.signAlgo.String(), tm.signKey, nil)) +} + +// HttpAuthenticator converts JWT claims into identity and stores it into context +func (tm *tokenManager) HttpAuthenticator() func(http.Handler) http.Handler { + return func(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + + tkn, _, err := jwtauth.FromContext(ctx) + + // When token is present, expect no errors and valid claims! + if tkn != nil { + if err != nil { + // But if token is present, there shouldn't be an error + api.Send(w, r, err) + return + } + + ctx = SetIdentityToContext(ctx, IdentityFromToken(tkn)) + r = r.WithContext(ctx) + } + + next.ServeHTTP(w, r) + }) + } +} // Generates JWT and stores alongside with client-confirmation entry, func (tm *tokenManager) Generate(ctx context.Context, i Identifiable, clientID uint64, scope ...string) (token []byte, err error) { diff --git a/pkg/auth/middleware.go b/pkg/auth/middleware.go index cfdb49217..441508656 100644 --- a/pkg/auth/middleware.go +++ b/pkg/auth/middleware.go @@ -4,6 +4,7 @@ import ( "net/http" "github.com/cortezaproject/corteza-server/pkg/errors" + "github.com/davecgh/go-spew/spew" "github.com/go-chi/jwtauth" ) @@ -16,30 +17,36 @@ func AccessTokenCheck(scope ...string) func(http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { var ctx = r.Context() - jwtauth.Authenticator() + token, _, err := jwtauth.FromContext(ctx) + spew.Dump(token, err) - // retrieve token and claims from context - tkn, _, err := jwtauth.FromContext(ctx) - if err != nil || !tkn.Valid { - errors.ProperlyServeHTTP(w, r, ErrUnauthorized(), false) - return - } - - // check valid scope - for _, s := range scope { - if !CheckScope(ctx.Value(scopeCtxKey{}), s) { - errors.ProperlyServeHTTP(w, r, ErrUnauthorizedScope(), false) - return - } - } - - // verify JWT from store - _, err = DefaultJwtStore.LookupAuthOa2tokenByAccess(ctx, tkn.Raw) if err != nil { errors.ProperlyServeHTTP(w, r, ErrUnauthorized(), false) return } + if !CheckJwtScope(token, scope...) { + errors.ProperlyServeHTTP(w, r, ErrUnauthorizedScope(), false) + } + + // @todo we need to check if token is in store!! + // @todo we need to check if token is in store!! + // @todo we need to check if token is in store!! + // @todo we need to check if token is in store!! + // @todo we need to check if token is in store!! + // @todo we need to check if token is in store!! + // @todo we need to check if token is in store!! + // @todo we need to check if token is in store!! + // @todo we need to check if token is in store!! + // @todo we need to check if token is in store!! + // + //// verify JWT from store + //_, err = DefaultJwtStore.LookupAuthOa2tokenByAccess(ctx, tkn.Raw) + //if err != nil { + // errors.ProperlyServeHTTP(w, r, ErrUnauthorized(), false) + // return + //} + next.ServeHTTP(w, r) }) } diff --git a/pkg/auth/scope.go b/pkg/auth/scope.go index af7db7834..7d0e5e1b0 100644 --- a/pkg/auth/scope.go +++ b/pkg/auth/scope.go @@ -2,27 +2,40 @@ package auth import ( "strings" -) -type ( - scopeCtxKey struct{} + "github.com/lestrrat-go/jwx/jwt" ) const ( scopeDelimiter = " " ) -// Checks if required scope is in claim +// CheckJwtScope verifies if required scope is in claim // We're using interface{} and casting it if needed to simplify usage of the fn by directly // using it with map[string]interface{} claims type -func CheckScope(claim interface{}, req string) bool { - claimStr, ok := claim.(string) +func CheckJwtScope(token jwt.Token, required ...string) bool { + scopeClaimRaw, has := token.Get("scope") + if !has { + return false + } + + scopeClaim, ok := scopeClaimRaw.(string) if !ok { return false } - return strings.Contains( - scopeDelimiter+claimStr+scopeDelimiter, - scopeDelimiter+strings.TrimSpace(req)+scopeDelimiter, - ) + return CheckScope(scopeClaim, required...) +} + +func CheckScope(scope string, required ...string) bool { + scope = scopeDelimiter + strings.TrimSpace(scope) + scopeDelimiter + + for _, req := range required { + req = scopeDelimiter + strings.TrimSpace(req) + scopeDelimiter + if strings.Contains(scope, req) { + return true + } + } + + return false } diff --git a/pkg/websocket/session.go b/pkg/websocket/session.go index 7463cdaed..ed073b080 100644 --- a/pkg/websocket/session.go +++ b/pkg/websocket/session.go @@ -296,7 +296,7 @@ func (s *session) authenticate(p *payloadAuth) error { return err } - if scope, has := token.Get("scope"); !has || !auth.CheckScope(scope, "api") { + if !auth.CheckJwtScope(token, "api") { return fmt.Errorf("client does not allow use of websockets (missing 'api' scope)") } diff --git a/pkg/websocket/session_test.go b/pkg/websocket/session_test.go index 188bd68da..9c9cca3ad 100644 --- a/pkg/websocket/session_test.go +++ b/pkg/websocket/session_test.go @@ -15,9 +15,17 @@ func TestSession_procRawMessage(t *testing.T) { var ( req = require.New(t) s = session{server: Server(nil, options.WebsocketOpt{})} - jwtHandler, err = auth.JWT("secret", time.Minute) + jwtHandler, err = auth.TokenManager("secret", time.Minute) userID uint64 = 123 + token []byte + + mockResponse = func(token []byte) (out []byte) { + out = []byte(`{"@type": "credentials", "@value": {"accessToken": "`) + out = append(out, token...) + out = append(out, []byte(`"}}`)...) + return + } ) if testing.Verbose() { @@ -27,17 +35,17 @@ func TestSession_procRawMessage(t *testing.T) { } req.NoError(err) - s.server.accessToken = jwtHandler - jwt := jwtHandler.Encode(auth.Authenticated(userID, 456, 789)) + token, err = jwtHandler.Encode(auth.Authenticated(userID, 456, 789), 0, "api") + req.NoError(err) req.EqualError(s.procRawMessage([]byte("{}")), "unauthenticated session") req.Nil(s.identity) - req.EqualError(s.procRawMessage([]byte(`{"@type": "credentials", "@value": {"accessToken": ""}}`)), "unauthorized: token contains an invalid number of segments") + req.EqualError(s.procRawMessage(mockResponse(nil)), "unauthorized: failed to parse token: EOF") req.Nil(s.identity) - req.NoError(s.procRawMessage([]byte(`{"@type": "credentials", "@value": {"accessToken": "` + jwt + `"}}`))) + req.NoError(s.procRawMessage(mockResponse(token))) req.NotNil(s.identity) req.Equal(userID, s.identity.Identity()) @@ -45,15 +53,17 @@ func TestSession_procRawMessage(t *testing.T) { req.Equal(userID, s.identity.Identity()) // Repeat with the same user - jwt = jwtHandler.Encode(auth.Authenticated(userID, 456, 789)) + token, err = jwtHandler.Encode(auth.Authenticated(userID, 456, 789), 0, "api") + req.NoError(err) - req.NoError(s.procRawMessage([]byte(`{"@type": "credentials", "@value": {"accessToken": "` + jwt + `"}}`))) + req.NoError(s.procRawMessage(mockResponse(token))) req.NotNil(s.identity) req.Equal(userID, s.identity.Identity()) // Try to authenticate on an existing authenticated session as a different user - jwt = jwtHandler.Encode(auth.Authenticated(userID+1, 456, 789)) + token, err = jwtHandler.Encode(auth.Authenticated(userID+1, 456, 789), 0, "api") + req.NoError(err) - req.EqualError(s.procRawMessage([]byte(`{"@type": "credentials", "@value": {"accessToken": "`+jwt+`"}}`)), "unauthorized: identity does not match") + req.EqualError(s.procRawMessage(mockResponse(token)), "unauthorized: identity does not match") } diff --git a/tests/compose/main_test.go b/tests/compose/main_test.go index 3d563d517..c801f7126 100644 --- a/tests/compose/main_test.go +++ b/tests/compose/main_test.go @@ -44,7 +44,7 @@ type ( cUser *sysTypes.User roleID uint64 - token string + token []byte } ) @@ -124,7 +124,7 @@ func newHelper(t *testing.T) helper { func (h *helper) identityToHelper(u *sysTypes.User) { var err error h.cUser = u - h.token, err = auth.DefaultJwtHandler.Generate(context.Background(), u) + h.token, err = auth.DefaultJwtHandler.Generate(context.Background(), u, 0) if err != nil { panic(err) } diff --git a/tests/federation/main_test.go b/tests/federation/main_test.go index 0e25bd0b7..5101915b3 100644 --- a/tests/federation/main_test.go +++ b/tests/federation/main_test.go @@ -30,7 +30,7 @@ type ( cUser *sysTypes.User roleID uint64 - token string + token []byte } ) diff --git a/tests/reporter/main_test.go b/tests/reporter/main_test.go index e18119353..66e70cb07 100644 --- a/tests/reporter/main_test.go +++ b/tests/reporter/main_test.go @@ -47,7 +47,7 @@ type ( cUser *sysTypes.User roleID uint64 - token string + token []byte } auxReport struct { diff --git a/tests/system/main_test.go b/tests/system/main_test.go index d9e51438e..52ebe9399 100644 --- a/tests/system/main_test.go +++ b/tests/system/main_test.go @@ -49,7 +49,7 @@ type ( cUser *types.User roleID uint64 - token string + token []byte data embed.FS } )