@@ -16,18 +16,21 @@ import (
1616 "github.com/stretchr/testify/require"
1717
1818 "github.com/go-pkgz/auth/logger"
19+ "github.com/go-pkgz/auth/provider"
1920 "github.com/go-pkgz/auth/token"
2021)
2122
22- var testJwtValid = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJ0ZXN0X3N5cyIsImV4cCI6Mjc4OTE5MTgyMiwianRpIjoicmFuZG9tIGlkIiwiaXNzIjoicmVtYXJrNDIiLCJuYmYiOjE1MjY4ODQyMjIsInVzZXIiOnsibmFtZSI6Im5hbWUxIiwiaWQiOiJpZDEiLCJwaWN0dXJlIjoiaHR0cDovL2V4YW1wbGUuY29tL3BpYy5wbmciLCJpcCI6IjEyNy4wLjAuMSIsImVtYWlsIjoibWVAZXhhbXBsZS5jb20iLCJhdHRycyI6eyJib29sYSI6dHJ1ZSwic3RyYSI6InN0cmEtdmFsIn19fQ.OWPdibrSSSHuOV3DzzLH5soO6kUcERELL7_GLf7Ja_E "
23+ var testJwtValid = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJ0ZXN0X3N5cyIsImV4cCI6Mjc4OTE5MTgyMiwianRpIjoicmFuZG9tIGlkIiwiaXNzIjoicmVtYXJrNDIiLCJuYmYiOjE1MjY4ODQyMjIsInVzZXIiOnsibmFtZSI6Im5hbWUxIiwiaWQiOiJwcm92aWRlcjFfaWQxIiwicGljdHVyZSI6Imh0dHA6Ly9leGFtcGxlLmNvbS9waWMucG5nIiwiaXAiOiIxMjcuMC4wLjEiLCJlbWFpbCI6Im1lQGV4YW1wbGUuY29tIiwiYXR0cnMiOnsiYm9vbGEiOnRydWUsInN0cmEiOiJzdHJhLXZhbCJ9fX0.orBYt_pVA4uvCCw0JMQLla3DA0mpjRTl_U9vT_wtI30 "
2324
24- var testJwtExpired = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJ0ZXN0X3N5cyIsImV4cCI6MTE4OTE5MTgyMiwianRpIjoicmFuZG9tIGlkIiwiaXNzIjoicmVtYXJrNDIiLCJuYmYiOjE1MjY4ODQyMjIsInVzZXIiOnsibmFtZSI6Im5hbWUxIiwiaWQiOiJpZDEiLCJwaWN0dXJlIjoiaHR0cDovL2V4YW1wbGUuY29tL3BpYy5wbmciLCJpcCI6IjEyNy4wLjAuMSIsImVtYWlsIjoibWVAZXhhbXBsZS5jb20iLCJhdHRycyI6eyJib29sYSI6dHJ1ZSwic3RyYSI6InN0cmEtdmFsIn19fQ.lJNUjG_9rpAghqy5GwIOrgfQnGDnF3PW5sGzKdijmmg"
25+ var testJwtValidWrongProvider = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJ0ZXN0X3N5cyIsImV4cCI6Mjc4OTE5MTgyMiwianRpIjoicmFuZG9tIGlkIiwiaXNzIjoicmVtYXJrNDIiLCJuYmYiOjE1MjY4ODQyMjIsInVzZXIiOnsibmFtZSI6Im5hbWUxIiwiaWQiOiJwcm92aWRlcjNfaWQxIiwicGljdHVyZSI6Imh0dHA6Ly9leGFtcGxlLmNvbS9waWMucG5nIiwiaXAiOiIxMjcuMC4wLjEiLCJlbWFpbCI6Im1lQGV4YW1wbGUuY29tIiwiYXR0cnMiOnsiYm9vbGEiOnRydWUsInN0cmEiOiJzdHJhLXZhbCJ9fX0.p0w7GmXKwujm0ROn0RIACnBwN4KmPcqXDMS9YoFq4jQ"
26+
27+ var testJwtExpired = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJ0ZXN0X3N5cyIsImV4cCI6MTE4OTE5MTgyMiwianRpIjoicmFuZG9tIGlkIiwiaXNzIjoicmVtYXJrNDIiLCJuYmYiOjE1MjY4ODQyMjIsInVzZXIiOnsibmFtZSI6Im5hbWUxIiwiaWQiOiJwcm92aWRlcjFfaWQxIiwicGljdHVyZSI6Imh0dHA6Ly9leGFtcGxlLmNvbS9waWMucG5nIiwiaXAiOiIxMjcuMC4wLjEiLCJlbWFpbCI6Im1lQGV4YW1wbGUuY29tIiwiYXR0cnMiOnsiYm9vbGEiOnRydWUsInN0cmEiOiJzdHJhLXZhbCJ9fX0.PlRRc5YA6pvoVOT4NLLOoTwU2Kn3GaTfbjr6j-P6RhA"
2528
2629var testJwtWithHandshake = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJ0ZXN0X3N5cyIsImV4cCI6Mjc4OTE5MTgyMiwianRpIjoicmFuZG9tIGlkIiwiaXNzIjoicmVtYXJrNDIiLCJuYmYiOjE1MjY4ODQyMjIsInVzZXIiOnsibmFtZSI6Im5hbWUxIiwiaWQiOiJpZDEiLCJwaWN0dXJlIjoiaHR0cDovL2V4YW1wbGUuY29tL3BpYy5wbmciLCJpcCI6IjEyNy4wLjAuMSIsImVtYWlsIjoibWVAZXhhbXBsZS5jb20iLCJhdHRycyI6eyJib29sYSI6dHJ1ZSwic3RyYSI6InN0cmEtdmFsIn19LCJoYW5kc2hha2UiOnsic3RhdGUiOiIxMjM0NTYiLCJmcm9tIjoiZnJvbSIsImlkIjoibXlpZC0xMjM0NTYifX0._2X1cAEoxjLA7XuN8xW8V9r7rYfP_m9lSRz_9_UFzac"
2730
2831var testJwtNoUser = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjI3ODkxOTE4MjIsImp0aSI6InJhbmRvbSBpZCIsImlzcyI6InJlbWFyazQyIiwibmJmIjoxNTI2ODg0MjIyfQ.sBpblkbBRzZsBSPPNrTWqA5h7h54solrw5L4IypJT_o"
2932
30- var testJwtWithRole = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJ0ZXN0X3N5cyIsImV4cCI6Mjc4OTE5MTgyMiwianRpIjoicmFuZG9tIGlkIiwiaXNzIjoicmVtYXJrNDIiLCJuYmYiOjE1MjY4ODQyMjIsInVzZXIiOnsibmFtZSI6Im5hbWUxIiwiaWQiOiJpZDEiLCJwaWN0dXJlIjoiaHR0cDovL2V4YW1wbGUuY29tL3BpYy5wbmciLCJpcCI6IjEyNy4wLjAuMSIsImVtYWlsIjoibWVAZXhhbXBsZS5jb20iLCJhdHRycyI6eyJib29sYSI6dHJ1ZSwic3RyYSI6InN0cmEtdmFsIn0sInJvbGUiOiJlbXBsb3llZSJ9fQ.VLW4_LUDZq_eFc9F1Zx1lbv2Whic2VHy6C0dJ5azL8A "
33+ var testJwtWithRole = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJ0ZXN0X3N5cyIsImV4cCI6Mjc4OTE5MTgyMiwianRpIjoicmFuZG9tIGlkIiwiaXNzIjoicmVtYXJrNDIiLCJuYmYiOjE1MjY4ODQyMjIsInVzZXIiOnsibmFtZSI6Im5hbWUxIiwiaWQiOiJwcm92aWRlcjFfaWQxIiwicGljdHVyZSI6Imh0dHA6Ly9leGFtcGxlLmNvbS9waWMucG5nIiwiaXAiOiIxMjcuMC4wLjEiLCJlbWFpbCI6Im1lQGV4YW1wbGUuY29tIiwiYXR0cnMiOnsiYm9vbGEiOnRydWUsInN0cmEiOiJzdHJhLXZhbCJ9LCJyb2xlIjoiZW1wbG95ZWUifX0.o95raB0aNl2TWUs43Tu6xyX5Y3Fa5wv6_6RFJuN-d6g "
3134
3235func TestAuthJWTCookie (t * testing.T ) {
3336 a := makeTestAuth (t )
@@ -36,7 +39,7 @@ func TestAuthJWTCookie(t *testing.T) {
3639 handler := func (w http.ResponseWriter , r * http.Request ) {
3740 u , err := token .GetUserInfo (r )
3841 assert .NoError (t , err )
39- assert .Equal (t , token.User {Name : "name1" , ID : "id1 " , Picture : "http://example.com/pic.png" ,
42+ assert .Equal (t , token.User {Name : "name1" , ID : "provider1_id1 " , Picture : "http://example.com/pic.png" ,
4043 IP : "127.0.0.1" , Email : "me@example.com" , Audience : "test_sys" ,
4144 Attributes : map [string ]interface {}{"boola" : true , "stra" : "stra-val" }}, u )
4245 w .WriteHeader (201 )
@@ -45,40 +48,61 @@ func TestAuthJWTCookie(t *testing.T) {
4548 server := httptest .NewServer (mux )
4649 defer server .Close ()
4750
51+ client := & http.Client {Timeout : 5 * time .Second }
4852 expiration := int (365 * 24 * time .Hour .Seconds ()) //nolint
49- req , err := http .NewRequest ("GET" , server .URL + "/auth" , http .NoBody )
50- require .Nil (t , err )
51- req .AddCookie (& http.Cookie {Name : "JWT" , Value : testJwtValid , HttpOnly : true , Path : "/" , MaxAge : expiration , Secure : false })
52- req .Header .Add ("X-XSRF-TOKEN" , "random id" )
5353
54- client := & http.Client {Timeout : 5 * time .Second }
55- resp , err := client .Do (req )
56- require .NoError (t , err )
57- assert .Equal (t , 201 , resp .StatusCode , "valid token user" )
54+ t .Run ("valid token" , func (t * testing.T ) {
55+ req , err := http .NewRequest ("GET" , server .URL + "/auth" , http .NoBody )
56+ require .Nil (t , err )
57+ req .AddCookie (& http.Cookie {Name : "JWT" , Value : testJwtValid , HttpOnly : true , Path : "/" , MaxAge : expiration , Secure : false })
58+ req .Header .Add ("X-XSRF-TOKEN" , "random id" )
5859
59- req , err = http .NewRequest ("GET" , server .URL + "/auth" , http .NoBody )
60- require .Nil (t , err )
61- req .AddCookie (& http.Cookie {Name : "JWT" , Value : testJwtValid , HttpOnly : true , Path : "/" , MaxAge : expiration , Secure : false })
62- req .Header .Add ("X-XSRF-TOKEN" , "wrong id" )
63- resp , err = client .Do (req )
64- require .NoError (t , err )
65- assert .Equal (t , 401 , resp .StatusCode , "xsrf mismatch" )
60+ resp , err := client .Do (req )
61+ require .NoError (t , err )
62+ assert .Equal (t , 201 , resp .StatusCode , "valid token user" )
63+ })
6664
67- req , err = http .NewRequest ("GET" , server .URL + "/auth" , http .NoBody )
68- require .Nil (t , err )
69- req .AddCookie (& http.Cookie {Name : "JWT" , Value : testJwtExpired , HttpOnly : true , Path : "/" , MaxAge : expiration , Secure : false })
70- req .Header .Add ("X-XSRF-TOKEN" , "random id" )
71- resp , err = client .Do (req )
72- require .NoError (t , err )
73- assert .Equal (t , 201 , resp .StatusCode , "token expired and refreshed" )
65+ t .Run ("valid token, wrong provider" , func (t * testing.T ) {
66+ req , err := http .NewRequest ("GET" , server .URL + "/auth" , http .NoBody )
67+ require .Nil (t , err )
68+ req .AddCookie (& http.Cookie {Name : "JWT" , Value : testJwtValidWrongProvider , HttpOnly : true , Path : "/" ,
69+ MaxAge : expiration , Secure : false })
70+ req .Header .Add ("X-XSRF-TOKEN" , "random id" )
7471
75- req , err = http .NewRequest ("GET" , server .URL + "/auth" , http .NoBody )
76- require .Nil (t , err )
77- req .AddCookie (& http.Cookie {Name : "JWT" , Value : testJwtNoUser , HttpOnly : true , Path : "/" , MaxAge : expiration , Secure : false })
78- req .Header .Add ("X-XSRF-TOKEN" , "random id" )
79- resp , err = client .Do (req )
80- require .NoError (t , err )
81- assert .Equal (t , 401 , resp .StatusCode , "no user info in the token" )
72+ resp , err := client .Do (req )
73+ require .NoError (t , err )
74+ assert .Equal (t , 401 , resp .StatusCode , "user name1/provider3_id1 provider is not allowed" )
75+ })
76+
77+ t .Run ("xsrf mismatch" , func (t * testing.T ) {
78+ req , err := http .NewRequest ("GET" , server .URL + "/auth" , http .NoBody )
79+ require .Nil (t , err )
80+ req .AddCookie (& http.Cookie {Name : "JWT" , Value : testJwtValid , HttpOnly : true , Path : "/" , MaxAge : expiration , Secure : false })
81+ req .Header .Add ("X-XSRF-TOKEN" , "wrong id" )
82+ resp , err := client .Do (req )
83+ require .NoError (t , err )
84+ assert .Equal (t , 401 , resp .StatusCode , "xsrf mismatch" )
85+ })
86+
87+ t .Run ("token expired and refreshed" , func (t * testing.T ) {
88+ req , err := http .NewRequest ("GET" , server .URL + "/auth" , http .NoBody )
89+ require .Nil (t , err )
90+ req .AddCookie (& http.Cookie {Name : "JWT" , Value : testJwtExpired , HttpOnly : true , Path : "/" , MaxAge : expiration , Secure : false })
91+ req .Header .Add ("X-XSRF-TOKEN" , "random id" )
92+ resp , err := client .Do (req )
93+ require .NoError (t , err )
94+ assert .Equal (t , 201 , resp .StatusCode , "token expired and refreshed" )
95+ })
96+
97+ t .Run ("no user info in the token" , func (t * testing.T ) {
98+ req , err := http .NewRequest ("GET" , server .URL + "/auth" , http .NoBody )
99+ require .Nil (t , err )
100+ req .AddCookie (& http.Cookie {Name : "JWT" , Value : testJwtNoUser , HttpOnly : true , Path : "/" , MaxAge : expiration , Secure : false })
101+ req .Header .Add ("X-XSRF-TOKEN" , "random id" )
102+ resp , err := client .Do (req )
103+ require .NoError (t , err )
104+ assert .Equal (t , 401 , resp .StatusCode , "no user info in the token" )
105+ })
82106}
83107
84108func TestAuthJWTHeader (t * testing.T ) {
@@ -87,19 +111,32 @@ func TestAuthJWTHeader(t *testing.T) {
87111 defer server .Close ()
88112
89113 client := & http.Client {Timeout : 5 * time .Second }
90- req , err := http .NewRequest ("GET" , server .URL + "/auth" , http .NoBody )
91- require .Nil (t , err )
92- req .Header .Add ("X-JWT" , testJwtValid )
93- resp , err := client .Do (req )
94- require .NoError (t , err )
95- assert .Equal (t , 201 , resp .StatusCode , "valid token user" )
114+ t .Run ("valid token" , func (t * testing.T ) {
115+ req , err := http .NewRequest ("GET" , server .URL + "/auth" , http .NoBody )
116+ require .Nil (t , err )
117+ req .Header .Add ("X-JWT" , testJwtValid )
118+ resp , err := client .Do (req )
119+ require .NoError (t , err )
120+ assert .Equal (t , 201 , resp .StatusCode , "valid token user" )
121+ })
96122
97- req , err = http .NewRequest ("GET" , server .URL + "/auth" , http .NoBody )
98- require .Nil (t , err )
99- req .Header .Add ("X-JWT" , testJwtExpired )
100- resp , err = client .Do (req )
101- require .NoError (t , err )
102- assert .Equal (t , 401 , resp .StatusCode , "token expired" )
123+ t .Run ("valid token, wrong provider" , func (t * testing.T ) {
124+ req , err := http .NewRequest ("GET" , server .URL + "/auth" , http .NoBody )
125+ require .Nil (t , err )
126+ req .Header .Add ("X-JWT" , testJwtValidWrongProvider )
127+ resp , err := client .Do (req )
128+ require .NoError (t , err )
129+ assert .Equal (t , 401 , resp .StatusCode , "wrong provider" )
130+ })
131+
132+ t .Run ("token expired" , func (t * testing.T ) {
133+ req , err := http .NewRequest ("GET" , server .URL + "/auth" , http .NoBody )
134+ require .Nil (t , err )
135+ req .Header .Add ("X-JWT" , testJwtExpired )
136+ resp , err := client .Do (req )
137+ require .NoError (t , err )
138+ assert .Equal (t , 401 , resp .StatusCode , "token expired" )
139+ })
103140}
104141
105142func TestAuthJWTRefresh (t * testing.T ) {
@@ -177,7 +214,7 @@ func TestAuthJWTRefreshConcurrentWithCache(t *testing.T) {
177214 // make another expired token
178215 c , err := a .JWTService .Parse (testJwtExpired )
179216 require .NoError (t , err )
180- c .User .ID = "other ID"
217+ c .User .ID = "provider1_other ID"
181218 tkSvc := a .JWTService .(* token.Service )
182219 tkn , err := tkSvc .Token (c )
183220 require .NoError (t , err )
@@ -413,7 +450,7 @@ func TestRBAC(t *testing.T) {
413450 handler := http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
414451 u , err := token .GetUserInfo (r )
415452 assert .NoError (t , err )
416- assert .Equal (t , token.User {Name : "name1" , ID : "id1 " , Picture : "http://example.com/pic.png" ,
453+ assert .Equal (t , token.User {Name : "name1" , ID : "provider1_id1 " , Picture : "http://example.com/pic.png" ,
417454 IP : "127.0.0.1" , Email : "me@example.com" , Audience : "test_sys" ,
418455 Attributes : map [string ]interface {}{"boola" : true , "stra" : "stra-val" },
419456 Role : "employee" }, u )
@@ -438,7 +475,7 @@ func TestRBAC(t *testing.T) {
438475 require .NoError (t , err )
439476 assert .Equal (t , 201 , resp .StatusCode , "valid token user" )
440477
441- // employee route only, token without employee role
478+ // employee route only, token without an employee role
442479 expiration = int (365 * 24 * time .Hour .Seconds ()) //nolint
443480 req , err = http .NewRequest ("GET" , server .URL + "/authForEmployees" , http .NoBody )
444481 require .Nil (t , err )
@@ -480,6 +517,7 @@ func makeTestMux(_ *testing.T, a *Authenticator, required bool) http.Handler {
480517}
481518
482519func makeTestAuth (_ * testing.T ) Authenticator {
520+
483521 j := token .NewService (token.Opts {
484522 SecretReader : token .SecretFunc (func (string ) (string , error ) { return "xyz 12345" , nil }),
485523 SecureCookies : false ,
@@ -497,6 +535,10 @@ func makeTestAuth(_ *testing.T) Authenticator {
497535 JWTService : j ,
498536 Validator : token .ValidatorFunc (func (token string , claims token.Claims ) bool { return true }),
499537 L : logger .Std ,
538+ Providers : []provider.Service {
539+ {Provider : provider.DirectHandler {ProviderName : "provider1" }},
540+ {Provider : provider.DirectHandler {ProviderName : "provider2" }},
541+ },
500542 }
501543}
502544
0 commit comments