From 9170ca6f3da245d5c42b4474d4d61c88497f3ac8 Mon Sep 17 00:00:00 2001 From: prongbang Date: Wed, 12 Jan 2022 17:00:19 +0700 Subject: [PATCH] Handle Token is expired and change module jwt-go to golang-jwt --- .travis.yml | 2 +- README.md | 4 +- adapter.go | 18 +----- common.go | 14 ++--- common_test.go | 5 +- go.mod | 24 +++++--- go.sum | 74 +++++++++---------------- middleware.go | 26 +++++---- middleware_test.go | 24 +++++++- role_adapter.go | 17 ++++++ adapter_test.go => role_adapter_test.go | 2 +- 11 files changed, 109 insertions(+), 101 deletions(-) create mode 100644 role_adapter.go rename adapter_test.go => role_adapter_test.go (92%) diff --git a/.travis.yml b/.travis.yml index 545b7fd..d4cbf8e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: go go: - - 1.14.x + - 1.15.x - tip env: - GO111MODULE=on diff --git a/README.md b/README.md index 2127e8e..b6f60a3 100644 --- a/README.md +++ b/README.md @@ -112,7 +112,7 @@ func NewRedisAdapter() fibercasbinrest.Adapter { const mockAdminToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c" -func (r *redisAdapter) GetRoleByToken(reqToken string) []string { +func (r *redisAdapter) GetRoleByToken(reqToken string) ([]string, error) { // Validate example not use on production role := "anonymous" if reqToken == mockAdminToken { @@ -120,7 +120,7 @@ func (r *redisAdapter) GetRoleByToken(reqToken string) []string { } else if reqToken == "TOKEN_DBA" { role = "dba" } - return []string{role} + return []string{role}, nil } func main() { diff --git a/adapter.go b/adapter.go index 1134dc9..948bfa5 100644 --- a/adapter.go +++ b/adapter.go @@ -9,21 +9,5 @@ const ( // Adapter interface for implements GetRoleByToken type Adapter interface { - GetRoleByToken(reqToken string) []string -} - -type roleAdapter struct { - Secret []byte -} - -func (r *roleAdapter) GetRoleByToken(reqToken string) []string { - t := GetValue(reqToken, RoleKey, r.Secret) - return ParseRoles(t) -} - -// NewRoleAdapter create adapter -func NewRoleAdapter(secret string) Adapter { - return &roleAdapter{ - Secret: []byte(secret), - } + GetRoleByToken(reqToken string) ([]string, error) } diff --git a/common.go b/common.go index f662445..4f2c6bd 100644 --- a/common.go +++ b/common.go @@ -3,9 +3,7 @@ package fibercasbinrest import ( "encoding/json" "fmt" - "log" - - "github.com/dgrijalva/jwt-go" + "github.com/golang-jwt/jwt" ) // Verify JWT @@ -27,18 +25,16 @@ func ParseToken(token string, secret []byte) (*jwt.Token, error) { } // GetValue for get payload from JWT -func GetValue(reqToken string, key string, secretKey []byte) interface{} { +func GetValue(reqToken string, key string, secretKey []byte) (interface{}, error) { token, err := ParseToken(reqToken, secretKey) if err != nil { - log.Println(err) - return "" + return "", err } claims, ok := token.Claims.(jwt.MapClaims) if ok && token.Valid { - return claims[key] + return claims[key], nil } - log.Println(claims.Valid().Error()) - return "" + return "", claims.Valid() } // ParseRoles interface to string array diff --git a/common_test.go b/common_test.go index 0daad3c..81090e3 100644 --- a/common_test.go +++ b/common_test.go @@ -26,7 +26,7 @@ func TestGetValueSuccess(t *testing.T) { secret := []byte("test") // When - actual := fibercasbinrest.GetValue(token, key, secret) + actual, _ := fibercasbinrest.GetValue(token, key, secret) // Then assert.Equal(t, actual, expect) @@ -40,7 +40,7 @@ func TestGetValueError(t *testing.T) { secret := []byte("invalid-secret") // When - actual := fibercasbinrest.GetValue(token, key, secret) + actual, _ := fibercasbinrest.GetValue(token, key, secret) // Then assert.Equal(t, actual, expect) @@ -69,4 +69,3 @@ func TestVerifyFalse(t *testing.T) { // Then assert.Equal(t, actual, false) } - diff --git a/go.mod b/go.mod index d59662d..759b17b 100644 --- a/go.mod +++ b/go.mod @@ -1,13 +1,23 @@ module github.com/prongbang/fiber-casbinrest -go 1.15 +go 1.17 require ( - github.com/casbin/casbin/v2 v2.23.0 - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/dgrijalva/jwt-go v3.2.0+incompatible - github.com/gofiber/fiber/v2 v2.5.0 - github.com/kr/pretty v0.2.1 // indirect + github.com/casbin/casbin/v2 v2.40.6 + github.com/gofiber/fiber/v2 v2.24.0 + github.com/golang-jwt/jwt v3.2.2+incompatible github.com/stretchr/testify v1.7.0 - gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect +) + +require ( + github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible // indirect + github.com/andybalholm/brotli v1.0.2 // indirect + github.com/davecgh/go-spew v1.1.0 // indirect + github.com/klauspost/compress v1.13.4 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/valyala/bytebufferpool v1.0.0 // indirect + github.com/valyala/fasthttp v1.31.0 // indirect + github.com/valyala/tcplisten v1.0.0 // indirect + golang.org/x/sys v0.0.0-20210514084401-e8d321eab015 // indirect + gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect ) diff --git a/go.sum b/go.sum index 39419b8..b7502cd 100644 --- a/go.sum +++ b/go.sum @@ -1,69 +1,49 @@ github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible h1:1G1pk05UrOh0NlF1oeaaix1x8XzrfjIDK47TY0Zehcw= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= -github.com/andybalholm/brotli v1.0.0 h1:7UCwP93aiSfvWpapti8g88vVVGp2qqtGyePsSuDafo4= -github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= -github.com/casbin/casbin/v2 v2.13.1 h1:K2ChfTOlEgCd9H6J3efOCatqLPyBj2ZCKwyhVRq4XSg= -github.com/casbin/casbin/v2 v2.13.1/go.mod h1:XXtYGrs/0zlOsJMeRteEdVi/FsB0ph7KgNfjoCoJUD8= -github.com/casbin/casbin/v2 v2.23.0 h1:V6TSSwplERP/KP6aEXm6C1Sg29bofM1aH1y01Hm+y0I= -github.com/casbin/casbin/v2 v2.23.0/go.mod h1:wUgota0cQbTXE6Vd+KWpg41726jFRi7upxio0sR+Xd0= +github.com/andybalholm/brotli v1.0.2 h1:JKnhI/XQ75uFBTiuzXpzFrUriDPiZjlOSzh6wXogP0E= +github.com/andybalholm/brotli v1.0.2/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= +github.com/casbin/casbin/v2 v2.40.6 h1:Fy8UmYaLst1zjyQ7Uw/Kq9Vxgyk91EtZO/cUUSm3kpQ= +github.com/casbin/casbin/v2 v2.40.6/go.mod h1:sEL80qBYTbd+BPeL4iyvwYzFT3qwLaESq5aFKVLbLfA= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= -github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/gofiber/fiber v1.14.6 h1:QRUPvPmr8ijQuGo1MgupHBn8E+wW0IKqiOvIZPtV70o= -github.com/gofiber/fiber/v2 v2.0.6 h1:eq1LGUM8arRCWxjQPvQzJJIRKDsc7Up/kxaSCUP6PIo= -github.com/gofiber/fiber/v2 v2.0.6/go.mod h1:VyfrlfcUCW0TcO5uaLHVlxZ8N25BgwnP6YjkzJmJP24= -github.com/gofiber/fiber/v2 v2.5.0 h1:yml405Um7b98EeMjx63OjSFTATLmX985HPWFfNUPV0w= -github.com/gofiber/fiber/v2 v2.5.0/go.mod h1:f8BRRIMjMdRyt2qmJ/0Sea3j3rwwfufPrh9WNBRiVZ0= +github.com/gofiber/fiber/v2 v2.24.0 h1:18rpLoQMJBVlLtX/PwgHj3hIxPSeWfN1YeDJ2lEnzjU= +github.com/gofiber/fiber/v2 v2.24.0/go.mod h1:MR1usVH3JHYRyQwMe2eZXRSZHRX38fkV+A7CPB+DlDQ= +github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= +github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= +github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/klauspost/compress v1.10.7 h1:7rix8v8GpI3ZBb0nSozFRgbtXKv+hOe+qfEpZqybrAg= -github.com/klauspost/compress v1.10.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/klauspost/compress v1.13.4 h1:0zhec2I8zGnjWcKyLl6i3gPqKANCCn5e9xmviEEeX6s= +github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasthttp v1.16.0 h1:9zAqOYLl8Tuy3E5R6ckzGDJ1g8+pw15oQp2iL9Jl6gQ= -github.com/valyala/fasthttp v1.16.0/go.mod h1:YOKImeEosDdBPnxc0gy7INqi3m1zK6A+xl6TwOBhHCA= -github.com/valyala/fasthttp v1.18.0 h1:IV0DdMlatq9QO1Cr6wGJPVW1sV1Q8HvZXAIcjorylyM= -github.com/valyala/fasthttp v1.18.0/go.mod h1:jjraHZVbKOXftJfsOYoAjaeygpj5hr8ermTRJNroD7A= -github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a h1:0R4NLDRDZX6JcmhJgXi5E4b8Wg84ihbmUKp/GvSPEzc= -github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= +github.com/valyala/fasthttp v1.31.0 h1:lrauRLII19afgCs2fnWRJ4M5IkV0lo2FqA61uGkNBfE= +github.com/valyala/fasthttp v1.31.0/go.mod h1:2rsYD01CKFrjjsvFxx75KlEUNpWNBY9JWD3K/7o2Cus= +github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8= +github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20201016165138-7b1cca2348c0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200929083018-4d22bbb62b3c h1:/h0vtH0PyU0xAoZJVcRw1k0Ng+U0JAy3QDiFmppIlIE= -golang.org/x/sys v0.0.0-20200929083018-4d22bbb62b3c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201210223839-7e3030f88018 h1:XKi8B/gRBuTZN1vU9gFsLMm6zVz5FSCDzm8JYACnjy8= -golang.org/x/sys v0.0.0-20201210223839-7e3030f88018/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210514084401-e8d321eab015 h1:hZR0X1kPW+nwyJ9xRxqZk1vx5RUObAPBdKVvXPDUH/E= +golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/middleware.go b/middleware.go index 41ac1c0..e10aea6 100644 --- a/middleware.go +++ b/middleware.go @@ -1,7 +1,6 @@ package fibercasbinrest import ( - "log" "net/http" "strings" @@ -53,35 +52,38 @@ func middlewareWithConfig(config Config) fiber.Handler { config.Skipper = DefaultConfig.Skipper } return func(c *fiber.Ctx) error { - if config.Skipper(c) || config.CheckPermissions(c) { + pass, err := config.CheckPermissions(c) + if config.Skipper(c) || (pass && err == nil) { return c.Next() } + if err != nil && strings.ToLower(err.Error()) == "token is expired" { + return c.Status(http.StatusUnauthorized). + JSON(fiber.Map{"message": err.Error()}) + } return c.Status(http.StatusForbidden). - JSON(fiber.Map{"message": "Forbidden"}) + JSON(fiber.Map{"message": http.StatusText(http.StatusForbidden)}) } } // GetRole gets the roles name from the request. -func (a *Config) GetRole(c *fiber.Ctx) []string { +func (a *Config) GetRole(c *fiber.Ctx) ([]string, error) { token := c.Get(fiber.HeaderAuthorization) authorization := strings.Split(token, "Bearer") if len(authorization) == 2 { return a.Adapter.GetRoleByToken(strings.TrimSpace(authorization[1])) } - return []string{RoleAnonymous} + return []string{RoleAnonymous}, nil } // CheckPermissions checks the role/path/method combination from the request. -func (a *Config) CheckPermissions(c *fiber.Ctx) bool { - roles := a.GetRole(c) +func (a *Config) CheckPermissions(c *fiber.Ctx) (bool, error) { + roles, err := a.GetRole(c) allowed := false for _, role := range roles { - result, err := a.Enforcer.Enforce(strings.ToLower(role), c.Path(), c.Method()) - if result && err == nil { + result, e := a.Enforcer.Enforce(strings.ToLower(role), c.Path(), c.Method()) + if result && e == nil { allowed = true - } else { - log.Println(err) } } - return allowed + return allowed, err } diff --git a/middleware_test.go b/middleware_test.go index 76b68c3..e7bd70b 100644 --- a/middleware_test.go +++ b/middleware_test.go @@ -20,14 +20,14 @@ func NewRedisAdapter() fibercasbinrest.Adapter { const mockAdminToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c" -func (r *redisAdapter) GetRoleByToken(reqToken string) []string { +func (r *redisAdapter) GetRoleByToken(reqToken string) ([]string, error) { role := "anonymous" if reqToken == mockAdminToken { role = "admin" } else if reqToken == "TOKEN_DBA" { role = "dba" } - return []string{role} + return []string{role}, nil } var adapter fibercasbinrest.Adapter @@ -144,3 +144,23 @@ func TestRoleAdminByJWTStatusOK(t *testing.T) { // Then assert.Equal(t, http.StatusOK, res.StatusCode) } + +func TestRoleAdminByJWTTokenExpired(t *testing.T) { + // Given + secret := "secret" + token := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2NDEsInJvbGVzIjpbIkFETUlOIiwiVVNFUiJdfQ.P7B4nnVuw6FUscVtKLUn011Q0iZssO7LEr_o7d8nprE" + ce, _ := casbin.NewEnforcer("example/auth_model.conf", "example/policy.csv") + e := fiber.New() + e.Use(fibercasbinrest.NewDefault(ce, secret)) + e.Get("/", func(c *fiber.Ctx) error { + return c.Status(http.StatusOK).JSON("OK") + }) + req := httptest.NewRequest(http.MethodGet, "/", nil) + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token)) + + // When + res, _ := e.Test(req, 10000) + + // Then + assert.Equal(t, http.StatusUnauthorized, res.StatusCode) +} diff --git a/role_adapter.go b/role_adapter.go new file mode 100644 index 0000000..32036f7 --- /dev/null +++ b/role_adapter.go @@ -0,0 +1,17 @@ +package fibercasbinrest + +type roleAdapter struct { + Secret []byte +} + +func (r *roleAdapter) GetRoleByToken(reqToken string) ([]string, error) { + t, err := GetValue(reqToken, RoleKey, r.Secret) + return ParseRoles(t), err +} + +// NewRoleAdapter create adapter +func NewRoleAdapter(secret string) Adapter { + return &roleAdapter{ + Secret: []byte(secret), + } +} diff --git a/adapter_test.go b/role_adapter_test.go similarity index 92% rename from adapter_test.go rename to role_adapter_test.go index 6afe28e..3514bf2 100644 --- a/adapter_test.go +++ b/role_adapter_test.go @@ -14,7 +14,7 @@ func TestGetRoleByTokenSuccess(t *testing.T) { adpt := fibercasbinrest.NewRoleAdapter(secret) // When - actual := adpt.GetRoleByToken(token) + actual, _ := adpt.GetRoleByToken(token) // Then assert.Equal(t, actual, expect)