@@ -5,6 +5,7 @@ package middleware
55
66import (
77 "encoding/base64"
8+ "errors"
89 "net/http"
910 "net/http/httptest"
1011 "strings"
@@ -16,78 +17,110 @@ import (
1617
1718func TestBasicAuth (t * testing.T ) {
1819 e := echo .New ()
19- req := httptest .NewRequest (http .MethodGet , "/" , nil )
20- res := httptest .NewRecorder ()
21- c := e .NewContext (req , res )
22- f := func (u , p string , c echo.Context ) (bool , error ) {
20+
21+ mockValidator := func (u , p string , c echo.Context ) (bool , error ) {
2322 if u == "joe" && p == "secret" {
2423 return true , nil
2524 }
2625 return false , nil
2726 }
28- h := BasicAuth (f )(func (c echo.Context ) error {
29- return c .String (http .StatusOK , "test" )
30- })
31-
32- // Valid credentials
33- auth := basic + " " + base64 .StdEncoding .EncodeToString ([]byte ("joe:secret" ))
34- req .Header .Set (echo .HeaderAuthorization , auth )
35- assert .NoError (t , h (c ))
36-
37- h = BasicAuthWithConfig (BasicAuthConfig {
38- Validator : f ,
39- Realm : "someRealm" ,
40- })(func (c echo.Context ) error {
41- return c .String (http .StatusOK , "test" )
42- })
43-
44- // Valid credentials
45- auth = basic + " " + base64 .StdEncoding .EncodeToString ([]byte ("joe:secret" ))
46- req .Header .Set (echo .HeaderAuthorization , auth )
47- assert .NoError (t , h (c ))
4827
49- // Case-insensitive header scheme
50- auth = strings .ToUpper (basic ) + " " + base64 .StdEncoding .EncodeToString ([]byte ("joe:secret" ))
51- req .Header .Set (echo .HeaderAuthorization , auth )
52- assert .NoError (t , h (c ))
53-
54- // Invalid credentials
55- auth = basic + " " + base64 .StdEncoding .EncodeToString ([]byte ("joe:invalid-password" ))
56- req .Header .Set (echo .HeaderAuthorization , auth )
57- he := h (c ).(* echo.HTTPError )
58- assert .Equal (t , http .StatusUnauthorized , he .Code )
59- assert .Equal (t , basic + ` realm="someRealm"` , res .Header ().Get (echo .HeaderWWWAuthenticate ))
28+ // Define the test cases
29+ tests := []struct {
30+ name string
31+ authHeader string
32+ expectedCode int
33+ expectedAuth string
34+ skipperResult bool
35+ expectedErr bool
36+ expectedErrMsg string
37+ }{
38+ {
39+ name : "Valid credentials" ,
40+ authHeader : basic + " " + base64 .StdEncoding .EncodeToString ([]byte ("joe:secret" )),
41+ expectedCode : http .StatusOK ,
42+ skipperResult : false ,
43+ },
44+ {
45+ name : "Case-insensitive header scheme" ,
46+ authHeader : strings .ToUpper (basic ) + " " + base64 .StdEncoding .EncodeToString ([]byte ("joe:secret" )),
47+ expectedCode : http .StatusOK ,
48+ skipperResult : false ,
49+ },
50+ {
51+ name : "Invalid credentials" ,
52+ authHeader : basic + " " + base64 .StdEncoding .EncodeToString ([]byte ("joe:invalid-password" )),
53+ expectedCode : http .StatusUnauthorized ,
54+ expectedAuth : basic + ` realm="someRealm"` ,
55+ skipperResult : false ,
56+ expectedErr : true ,
57+ expectedErrMsg : "Unauthorized" ,
58+ },
59+ {
60+ name : "Invalid base64 string" ,
61+ authHeader : basic + " invalidString" ,
62+ expectedCode : http .StatusBadRequest ,
63+ skipperResult : false ,
64+ expectedErr : true ,
65+ expectedErrMsg : "Bad Request" ,
66+ },
67+ {
68+ name : "Missing Authorization header" ,
69+ expectedCode : http .StatusUnauthorized ,
70+ skipperResult : false ,
71+ expectedErr : true ,
72+ expectedErrMsg : "Unauthorized" ,
73+ },
74+ {
75+ name : "Invalid Authorization header" ,
76+ authHeader : base64 .StdEncoding .EncodeToString ([]byte ("invalid" )),
77+ expectedCode : http .StatusUnauthorized ,
78+ skipperResult : false ,
79+ expectedErr : true ,
80+ expectedErrMsg : "Unauthorized" ,
81+ },
82+ {
83+ name : "Skipped Request" ,
84+ authHeader : basic + " " + base64 .StdEncoding .EncodeToString ([]byte ("joe:skip" )),
85+ expectedCode : http .StatusOK ,
86+ skipperResult : true ,
87+ },
88+ }
6089
61- // Invalid base64 string
62- auth = basic + " invalidString"
63- req .Header .Set (echo .HeaderAuthorization , auth )
64- he = h (c ).(* echo.HTTPError )
65- assert .Equal (t , http .StatusBadRequest , he .Code )
90+ for _ , tt := range tests {
91+ t .Run (tt .name , func (t * testing.T ) {
6692
67- // Missing Authorization header
68- req .Header .Del (echo .HeaderAuthorization )
69- he = h (c ).(* echo.HTTPError )
70- assert .Equal (t , http .StatusUnauthorized , he .Code )
93+ req := httptest .NewRequest (http .MethodGet , "/" , nil )
94+ res := httptest .NewRecorder ()
95+ c := e .NewContext (req , res )
7196
72- // Invalid Authorization header
73- auth = base64 .StdEncoding .EncodeToString ([]byte ("invalid" ))
74- req .Header .Set (echo .HeaderAuthorization , auth )
75- he = h (c ).(* echo.HTTPError )
76- assert .Equal (t , http .StatusUnauthorized , he .Code )
97+ if tt .authHeader != "" {
98+ req .Header .Set (echo .HeaderAuthorization , tt .authHeader )
99+ }
77100
78- h = BasicAuthWithConfig (BasicAuthConfig {
79- Validator : f ,
80- Realm : "someRealm" ,
81- Skipper : func (c echo.Context ) bool {
82- return true
83- },
84- })(func (c echo.Context ) error {
85- return c .String (http .StatusOK , "test" )
86- })
101+ h : = BasicAuthWithConfig (BasicAuthConfig {
102+ Validator : mockValidator ,
103+ Realm : "someRealm" ,
104+ Skipper : func (c echo.Context ) bool {
105+ return tt . skipperResult
106+ },
107+ })(func (c echo.Context ) error {
108+ return c .String (http .StatusOK , "test" )
109+ })
87110
88- // Skipped Request
89- auth = basic + " " + base64 .StdEncoding .EncodeToString ([]byte ("joe:skip" ))
90- req .Header .Set (echo .HeaderAuthorization , auth )
91- assert .NoError (t , h (c ))
111+ err := h (c )
92112
113+ if tt .expectedErr {
114+ var he * echo.HTTPError
115+ errors .As (err , & he )
116+ assert .Equal (t , tt .expectedCode , he .Code )
117+ if tt .expectedAuth != "" {
118+ assert .Equal (t , tt .expectedAuth , res .Header ().Get (echo .HeaderWWWAuthenticate ))
119+ }
120+ } else {
121+ assert .NoError (t , err )
122+ assert .Equal (t , tt .expectedCode , res .Code )
123+ }
124+ })
125+ }
93126}
0 commit comments