From 848342856624c4ede848ac64e1ef6883b611e19a Mon Sep 17 00:00:00 2001 From: Stephen Brown Date: Thu, 26 Sep 2024 18:39:00 +0100 Subject: [PATCH 1/3] Check user --- backends/jwt_files.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/backends/jwt_files.go b/backends/jwt_files.go index 42fc49fd..a6bc9552 100644 --- a/backends/jwt_files.go +++ b/backends/jwt_files.go @@ -17,7 +17,7 @@ func NewFilesJWTChecker(authOpts map[string]string, logLevel log.Level, hasher h /* We could ask for a file listing available users with no password, but that gives very little value versus just assuming users in the ACL file are valid ones, while general rules apply to any user. - Thus, padswords file makes no sense for JWT, we only need to check ACLs. + Thus, passwords file makes no sense for JWT, we only need to check ACLs. */ aclPath, ok := authOpts["jwt_acl_path"] if !ok || aclPath == "" { @@ -36,7 +36,8 @@ func NewFilesJWTChecker(authOpts map[string]string, logLevel log.Level, hasher h } func (o *filesJWTChecker) GetUser(token string) (bool, error) { - return false, nil + _, err := getUsernameForToken(o.options, token, o.options.skipUserExpiration) + return err == nil, nil } func (o *filesJWTChecker) GetSuperuser(token string) (bool, error) { From e751f71706fe00fddb60f9d3fb4809069bf54d47 Mon Sep 17 00:00:00 2001 From: Stephen Brown Date: Mon, 30 Sep 2024 12:23:50 +0100 Subject: [PATCH 2/3] tests for jwt files mode user auth --- backends/jwt_test.go | 53 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/backends/jwt_test.go b/backends/jwt_test.go index 795e0414..4ff0decf 100644 --- a/backends/jwt_test.go +++ b/backends/jwt_test.go @@ -218,6 +218,59 @@ func TestFilesJWTChecker(t *testing.T) { token, err := notPresentJwtToken.SignedString([]byte(jwtSecret)) So(err, ShouldBeNil) + invalidToken, err := notPresentJwtToken.SignedString([]byte("badsecret")) + So(err, ShouldBeNil) + + expiredToken, err := expiredToken.SignedString([]byte(jwtSecret)) + So(err, ShouldBeNil) + + Convey("Given a valid token, it should correctly authenticate it", func() { + authenticated, err := filesChecker.GetUser(token) + + So(err, ShouldBeNil) + So(authenticated, ShouldBeTrue) + }) + + Convey("Given an invalid token, it should not authenticate it", func() { + authenticated, err := filesChecker.GetUser(invalidToken) + + So(err, ShouldBeNil) + So(authenticated, ShouldBeFalse) + }) + + Convey("Given an expired token, it should not authenticate it", func() { + authenticated, err := filesChecker.GetUser(expiredToken) + + So(err, ShouldBeNil) + So(authenticated, ShouldBeFalse) + }) + + Convey("Given an expired token with skip user expiration, it should anyway authenticate it", func() { + skipExpirationOptions := tkOptions + skipExpirationOptions.skipUserExpiration = true + filesChecker, err := NewFilesJWTChecker(authOpts, logLevel, hasher, skipExpirationOptions) + So(err, ShouldBeNil) + + authenticated, err := filesChecker.GetUser(expiredToken) + + So(err, ShouldBeNil) + So(authenticated, ShouldBeTrue) + }) + + Convey("Given a plain non-token format valid username, it should not authenticate it", func() { + authenticated, err := filesChecker.GetUser(username) + + So(err, ShouldBeNil) + So(authenticated, ShouldBeFalse) + }) + + Convey("Given a plain non-token format random username, it should not authenticate it", func() { + authenticated, err := filesChecker.GetUser("somerandomuser") + + So(err, ShouldBeNil) + So(authenticated, ShouldBeFalse) + }) + Convey("Access should be granted for ACL mentioned users", func() { tt, err := filesChecker.CheckAcl(token, "test/not_present", "id", 1) From 43c8202b9097681a2367fb1940f97595d859a362 Mon Sep 17 00:00:00 2001 From: Stephen Brown Date: Wed, 18 Dec 2024 17:11:21 +0000 Subject: [PATCH 3/3] mosquitto breaks without this --- backends/jwt_files.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backends/jwt_files.go b/backends/jwt_files.go index a6bc9552..f5990d53 100644 --- a/backends/jwt_files.go +++ b/backends/jwt_files.go @@ -49,7 +49,7 @@ func (o *filesJWTChecker) CheckAcl(token, topic, clientid string, acc int32) (bo if err != nil { log.Printf("jwt get user error: %s", err) - return false, err + return false, nil } return o.checker.CheckAcl(username, topic, clientid, acc)