-
-
Notifications
You must be signed in to change notification settings - Fork 84
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
check if user's provider is in the list of current providers
- Loading branch information
Showing
2 changed files
with
117 additions
and
55 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,18 +16,21 @@ import ( | |
"github.com/stretchr/testify/require" | ||
|
||
"github.com/go-pkgz/auth/logger" | ||
"github.com/go-pkgz/auth/provider" | ||
"github.com/go-pkgz/auth/token" | ||
) | ||
|
||
var testJwtValid = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJ0ZXN0X3N5cyIsImV4cCI6Mjc4OTE5MTgyMiwianRpIjoicmFuZG9tIGlkIiwiaXNzIjoicmVtYXJrNDIiLCJuYmYiOjE1MjY4ODQyMjIsInVzZXIiOnsibmFtZSI6Im5hbWUxIiwiaWQiOiJpZDEiLCJwaWN0dXJlIjoiaHR0cDovL2V4YW1wbGUuY29tL3BpYy5wbmciLCJpcCI6IjEyNy4wLjAuMSIsImVtYWlsIjoibWVAZXhhbXBsZS5jb20iLCJhdHRycyI6eyJib29sYSI6dHJ1ZSwic3RyYSI6InN0cmEtdmFsIn19fQ.OWPdibrSSSHuOV3DzzLH5soO6kUcERELL7_GLf7Ja_E" | ||
var testJwtValid = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJ0ZXN0X3N5cyIsImV4cCI6Mjc4OTE5MTgyMiwianRpIjoicmFuZG9tIGlkIiwiaXNzIjoicmVtYXJrNDIiLCJuYmYiOjE1MjY4ODQyMjIsInVzZXIiOnsibmFtZSI6Im5hbWUxIiwiaWQiOiJwcm92aWRlcjFfaWQxIiwicGljdHVyZSI6Imh0dHA6Ly9leGFtcGxlLmNvbS9waWMucG5nIiwiaXAiOiIxMjcuMC4wLjEiLCJlbWFpbCI6Im1lQGV4YW1wbGUuY29tIiwiYXR0cnMiOnsiYm9vbGEiOnRydWUsInN0cmEiOiJzdHJhLXZhbCJ9fX0.orBYt_pVA4uvCCw0JMQLla3DA0mpjRTl_U9vT_wtI30" | ||
|
||
var testJwtExpired = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJ0ZXN0X3N5cyIsImV4cCI6MTE4OTE5MTgyMiwianRpIjoicmFuZG9tIGlkIiwiaXNzIjoicmVtYXJrNDIiLCJuYmYiOjE1MjY4ODQyMjIsInVzZXIiOnsibmFtZSI6Im5hbWUxIiwiaWQiOiJpZDEiLCJwaWN0dXJlIjoiaHR0cDovL2V4YW1wbGUuY29tL3BpYy5wbmciLCJpcCI6IjEyNy4wLjAuMSIsImVtYWlsIjoibWVAZXhhbXBsZS5jb20iLCJhdHRycyI6eyJib29sYSI6dHJ1ZSwic3RyYSI6InN0cmEtdmFsIn19fQ.lJNUjG_9rpAghqy5GwIOrgfQnGDnF3PW5sGzKdijmmg" | ||
var testJwtValidWrongProvider = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJ0ZXN0X3N5cyIsImV4cCI6Mjc4OTE5MTgyMiwianRpIjoicmFuZG9tIGlkIiwiaXNzIjoicmVtYXJrNDIiLCJuYmYiOjE1MjY4ODQyMjIsInVzZXIiOnsibmFtZSI6Im5hbWUxIiwiaWQiOiJwcm92aWRlcjNfaWQxIiwicGljdHVyZSI6Imh0dHA6Ly9leGFtcGxlLmNvbS9waWMucG5nIiwiaXAiOiIxMjcuMC4wLjEiLCJlbWFpbCI6Im1lQGV4YW1wbGUuY29tIiwiYXR0cnMiOnsiYm9vbGEiOnRydWUsInN0cmEiOiJzdHJhLXZhbCJ9fX0.p0w7GmXKwujm0ROn0RIACnBwN4KmPcqXDMS9YoFq4jQ" | ||
|
||
var testJwtExpired = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJ0ZXN0X3N5cyIsImV4cCI6MTE4OTE5MTgyMiwianRpIjoicmFuZG9tIGlkIiwiaXNzIjoicmVtYXJrNDIiLCJuYmYiOjE1MjY4ODQyMjIsInVzZXIiOnsibmFtZSI6Im5hbWUxIiwiaWQiOiJwcm92aWRlcjFfaWQxIiwicGljdHVyZSI6Imh0dHA6Ly9leGFtcGxlLmNvbS9waWMucG5nIiwiaXAiOiIxMjcuMC4wLjEiLCJlbWFpbCI6Im1lQGV4YW1wbGUuY29tIiwiYXR0cnMiOnsiYm9vbGEiOnRydWUsInN0cmEiOiJzdHJhLXZhbCJ9fX0.PlRRc5YA6pvoVOT4NLLOoTwU2Kn3GaTfbjr6j-P6RhA" | ||
|
||
var testJwtWithHandshake = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJ0ZXN0X3N5cyIsImV4cCI6Mjc4OTE5MTgyMiwianRpIjoicmFuZG9tIGlkIiwiaXNzIjoicmVtYXJrNDIiLCJuYmYiOjE1MjY4ODQyMjIsInVzZXIiOnsibmFtZSI6Im5hbWUxIiwiaWQiOiJpZDEiLCJwaWN0dXJlIjoiaHR0cDovL2V4YW1wbGUuY29tL3BpYy5wbmciLCJpcCI6IjEyNy4wLjAuMSIsImVtYWlsIjoibWVAZXhhbXBsZS5jb20iLCJhdHRycyI6eyJib29sYSI6dHJ1ZSwic3RyYSI6InN0cmEtdmFsIn19LCJoYW5kc2hha2UiOnsic3RhdGUiOiIxMjM0NTYiLCJmcm9tIjoiZnJvbSIsImlkIjoibXlpZC0xMjM0NTYifX0._2X1cAEoxjLA7XuN8xW8V9r7rYfP_m9lSRz_9_UFzac" | ||
|
||
var testJwtNoUser = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjI3ODkxOTE4MjIsImp0aSI6InJhbmRvbSBpZCIsImlzcyI6InJlbWFyazQyIiwibmJmIjoxNTI2ODg0MjIyfQ.sBpblkbBRzZsBSPPNrTWqA5h7h54solrw5L4IypJT_o" | ||
|
||
var testJwtWithRole = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJ0ZXN0X3N5cyIsImV4cCI6Mjc4OTE5MTgyMiwianRpIjoicmFuZG9tIGlkIiwiaXNzIjoicmVtYXJrNDIiLCJuYmYiOjE1MjY4ODQyMjIsInVzZXIiOnsibmFtZSI6Im5hbWUxIiwiaWQiOiJpZDEiLCJwaWN0dXJlIjoiaHR0cDovL2V4YW1wbGUuY29tL3BpYy5wbmciLCJpcCI6IjEyNy4wLjAuMSIsImVtYWlsIjoibWVAZXhhbXBsZS5jb20iLCJhdHRycyI6eyJib29sYSI6dHJ1ZSwic3RyYSI6InN0cmEtdmFsIn0sInJvbGUiOiJlbXBsb3llZSJ9fQ.VLW4_LUDZq_eFc9F1Zx1lbv2Whic2VHy6C0dJ5azL8A" | ||
var testJwtWithRole = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJ0ZXN0X3N5cyIsImV4cCI6Mjc4OTE5MTgyMiwianRpIjoicmFuZG9tIGlkIiwiaXNzIjoicmVtYXJrNDIiLCJuYmYiOjE1MjY4ODQyMjIsInVzZXIiOnsibmFtZSI6Im5hbWUxIiwiaWQiOiJwcm92aWRlcjFfaWQxIiwicGljdHVyZSI6Imh0dHA6Ly9leGFtcGxlLmNvbS9waWMucG5nIiwiaXAiOiIxMjcuMC4wLjEiLCJlbWFpbCI6Im1lQGV4YW1wbGUuY29tIiwiYXR0cnMiOnsiYm9vbGEiOnRydWUsInN0cmEiOiJzdHJhLXZhbCJ9LCJyb2xlIjoiZW1wbG95ZWUifX0.o95raB0aNl2TWUs43Tu6xyX5Y3Fa5wv6_6RFJuN-d6g" | ||
|
||
func TestAuthJWTCookie(t *testing.T) { | ||
a := makeTestAuth(t) | ||
|
@@ -36,7 +39,7 @@ func TestAuthJWTCookie(t *testing.T) { | |
handler := func(w http.ResponseWriter, r *http.Request) { | ||
u, err := token.GetUserInfo(r) | ||
assert.NoError(t, err) | ||
assert.Equal(t, token.User{Name: "name1", ID: "id1", Picture: "http://example.com/pic.png", | ||
assert.Equal(t, token.User{Name: "name1", ID: "provider1_id1", Picture: "http://example.com/pic.png", | ||
IP: "127.0.0.1", Email: "[email protected]", Audience: "test_sys", | ||
Attributes: map[string]interface{}{"boola": true, "stra": "stra-val"}}, u) | ||
w.WriteHeader(201) | ||
|
@@ -45,40 +48,61 @@ func TestAuthJWTCookie(t *testing.T) { | |
server := httptest.NewServer(mux) | ||
defer server.Close() | ||
|
||
expiration := int(365 * 24 * time.Hour.Seconds()) //nolint | ||
req, err := http.NewRequest("GET", server.URL+"/auth", http.NoBody) | ||
require.Nil(t, err) | ||
req.AddCookie(&http.Cookie{Name: "JWT", Value: testJwtValid, HttpOnly: true, Path: "/", MaxAge: expiration, Secure: false}) | ||
req.Header.Add("X-XSRF-TOKEN", "random id") | ||
|
||
client := &http.Client{Timeout: 5 * time.Second} | ||
resp, err := client.Do(req) | ||
require.NoError(t, err) | ||
assert.Equal(t, 201, resp.StatusCode, "valid token user") | ||
expiration := int(365 * 24 * time.Hour.Seconds()) // nolint | ||
|
||
req, err = http.NewRequest("GET", server.URL+"/auth", http.NoBody) | ||
require.Nil(t, err) | ||
req.AddCookie(&http.Cookie{Name: "JWT", Value: testJwtValid, HttpOnly: true, Path: "/", MaxAge: expiration, Secure: false}) | ||
req.Header.Add("X-XSRF-TOKEN", "wrong id") | ||
resp, err = client.Do(req) | ||
require.NoError(t, err) | ||
assert.Equal(t, 401, resp.StatusCode, "xsrf mismatch") | ||
t.Run("valid token", func(t *testing.T) { | ||
req, err := http.NewRequest("GET", server.URL+"/auth", http.NoBody) | ||
require.Nil(t, err) | ||
req.AddCookie(&http.Cookie{Name: "JWT", Value: testJwtValid, HttpOnly: true, Path: "/", MaxAge: expiration, Secure: false}) | ||
req.Header.Add("X-XSRF-TOKEN", "random id") | ||
|
||
req, err = http.NewRequest("GET", server.URL+"/auth", http.NoBody) | ||
require.Nil(t, err) | ||
req.AddCookie(&http.Cookie{Name: "JWT", Value: testJwtExpired, HttpOnly: true, Path: "/", MaxAge: expiration, Secure: false}) | ||
req.Header.Add("X-XSRF-TOKEN", "random id") | ||
resp, err = client.Do(req) | ||
require.NoError(t, err) | ||
assert.Equal(t, 201, resp.StatusCode, "token expired and refreshed") | ||
resp, err := client.Do(req) | ||
require.NoError(t, err) | ||
assert.Equal(t, 201, resp.StatusCode, "valid token user") | ||
}) | ||
|
||
req, err = http.NewRequest("GET", server.URL+"/auth", http.NoBody) | ||
require.Nil(t, err) | ||
req.AddCookie(&http.Cookie{Name: "JWT", Value: testJwtNoUser, HttpOnly: true, Path: "/", MaxAge: expiration, Secure: false}) | ||
req.Header.Add("X-XSRF-TOKEN", "random id") | ||
resp, err = client.Do(req) | ||
require.NoError(t, err) | ||
assert.Equal(t, 401, resp.StatusCode, "no user info in the token") | ||
t.Run("valid token, wrong provider", func(t *testing.T) { | ||
req, err := http.NewRequest("GET", server.URL+"/auth", http.NoBody) | ||
require.Nil(t, err) | ||
req.AddCookie(&http.Cookie{Name: "JWT", Value: testJwtValidWrongProvider, HttpOnly: true, Path: "/", | ||
MaxAge: expiration, Secure: false}) | ||
req.Header.Add("X-XSRF-TOKEN", "random id") | ||
|
||
resp, err := client.Do(req) | ||
require.NoError(t, err) | ||
assert.Equal(t, 401, resp.StatusCode, "user name1/provider3_id1 provider is not allowed") | ||
}) | ||
|
||
t.Run("xsrf mismatch", func(t *testing.T) { | ||
req, err := http.NewRequest("GET", server.URL+"/auth", http.NoBody) | ||
require.Nil(t, err) | ||
req.AddCookie(&http.Cookie{Name: "JWT", Value: testJwtValid, HttpOnly: true, Path: "/", MaxAge: expiration, Secure: false}) | ||
req.Header.Add("X-XSRF-TOKEN", "wrong id") | ||
resp, err := client.Do(req) | ||
require.NoError(t, err) | ||
assert.Equal(t, 401, resp.StatusCode, "xsrf mismatch") | ||
}) | ||
|
||
t.Run("token expired and refreshed", func(t *testing.T) { | ||
req, err := http.NewRequest("GET", server.URL+"/auth", http.NoBody) | ||
require.Nil(t, err) | ||
req.AddCookie(&http.Cookie{Name: "JWT", Value: testJwtExpired, HttpOnly: true, Path: "/", MaxAge: expiration, Secure: false}) | ||
req.Header.Add("X-XSRF-TOKEN", "random id") | ||
resp, err := client.Do(req) | ||
require.NoError(t, err) | ||
assert.Equal(t, 201, resp.StatusCode, "token expired and refreshed") | ||
}) | ||
|
||
t.Run("no user info in the token", func(t *testing.T) { | ||
req, err := http.NewRequest("GET", server.URL+"/auth", http.NoBody) | ||
require.Nil(t, err) | ||
req.AddCookie(&http.Cookie{Name: "JWT", Value: testJwtNoUser, HttpOnly: true, Path: "/", MaxAge: expiration, Secure: false}) | ||
req.Header.Add("X-XSRF-TOKEN", "random id") | ||
resp, err := client.Do(req) | ||
require.NoError(t, err) | ||
assert.Equal(t, 401, resp.StatusCode, "no user info in the token") | ||
}) | ||
} | ||
|
||
func TestAuthJWTHeader(t *testing.T) { | ||
|
@@ -87,19 +111,32 @@ func TestAuthJWTHeader(t *testing.T) { | |
defer server.Close() | ||
|
||
client := &http.Client{Timeout: 5 * time.Second} | ||
req, err := http.NewRequest("GET", server.URL+"/auth", http.NoBody) | ||
require.Nil(t, err) | ||
req.Header.Add("X-JWT", testJwtValid) | ||
resp, err := client.Do(req) | ||
require.NoError(t, err) | ||
assert.Equal(t, 201, resp.StatusCode, "valid token user") | ||
t.Run("valid token", func(t *testing.T) { | ||
req, err := http.NewRequest("GET", server.URL+"/auth", http.NoBody) | ||
require.Nil(t, err) | ||
req.Header.Add("X-JWT", testJwtValid) | ||
resp, err := client.Do(req) | ||
require.NoError(t, err) | ||
assert.Equal(t, 201, resp.StatusCode, "valid token user") | ||
}) | ||
|
||
req, err = http.NewRequest("GET", server.URL+"/auth", http.NoBody) | ||
require.Nil(t, err) | ||
req.Header.Add("X-JWT", testJwtExpired) | ||
resp, err = client.Do(req) | ||
require.NoError(t, err) | ||
assert.Equal(t, 401, resp.StatusCode, "token expired") | ||
t.Run("valid token, wrong provider", func(t *testing.T) { | ||
req, err := http.NewRequest("GET", server.URL+"/auth", http.NoBody) | ||
require.Nil(t, err) | ||
req.Header.Add("X-JWT", testJwtValidWrongProvider) | ||
resp, err := client.Do(req) | ||
require.NoError(t, err) | ||
assert.Equal(t, 401, resp.StatusCode, "wrong provider") | ||
}) | ||
|
||
t.Run("token expired", func(t *testing.T) { | ||
req, err := http.NewRequest("GET", server.URL+"/auth", http.NoBody) | ||
require.Nil(t, err) | ||
req.Header.Add("X-JWT", testJwtExpired) | ||
resp, err := client.Do(req) | ||
require.NoError(t, err) | ||
assert.Equal(t, 401, resp.StatusCode, "token expired") | ||
}) | ||
} | ||
|
||
func TestAuthJWTRefresh(t *testing.T) { | ||
|
@@ -113,7 +150,7 @@ func TestAuthJWTRefresh(t *testing.T) { | |
req, err := http.NewRequest("GET", server.URL+"/auth", http.NoBody) | ||
require.NoError(t, err) | ||
|
||
expiration := int(365 * 24 * time.Hour.Seconds()) //nolint | ||
expiration := int(365 * 24 * time.Hour.Seconds()) // nolint | ||
req.AddCookie(&http.Cookie{Name: "JWT", Value: testJwtExpired, HttpOnly: true, Path: "/", MaxAge: expiration, Secure: false}) | ||
req.Header.Add("X-XSRF-TOKEN", "random id") | ||
|
||
|
@@ -154,7 +191,7 @@ func TestAuthJWTRefreshConcurrentWithCache(t *testing.T) { | |
req, err := http.NewRequest("GET", server.URL+"/auth", http.NoBody) | ||
require.NoError(t, err) | ||
|
||
expiration := int(365 * 24 * time.Hour.Seconds()) //nolint | ||
expiration := int(365 * 24 * time.Hour.Seconds()) // nolint | ||
req.AddCookie(&http.Cookie{Name: "JWT", Value: testJwtExpired, HttpOnly: true, Path: "/", | ||
MaxAge: expiration, Secure: false}) | ||
req.Header.Add("X-XSRF-TOKEN", "random id") | ||
|
@@ -177,7 +214,7 @@ func TestAuthJWTRefreshConcurrentWithCache(t *testing.T) { | |
// make another expired token | ||
c, err := a.JWTService.Parse(testJwtExpired) | ||
require.NoError(t, err) | ||
c.User.ID = "other ID" | ||
c.User.ID = "provider1_other ID" | ||
tkSvc := a.JWTService.(*token.Service) | ||
tkn, err := tkSvc.Token(c) | ||
require.NoError(t, err) | ||
|
@@ -187,7 +224,7 @@ func TestAuthJWTRefreshConcurrentWithCache(t *testing.T) { | |
client := &http.Client{Jar: jar, Timeout: 5 * time.Second} | ||
req, err := http.NewRequest("GET", server.URL+"/auth", http.NoBody) | ||
require.NoError(t, err) | ||
expiration := int(365 * 24 * time.Hour.Seconds()) //nolint | ||
expiration := int(365 * 24 * time.Hour.Seconds()) // nolint | ||
req.AddCookie(&http.Cookie{Name: "JWT", Value: tkn, HttpOnly: true, Path: "/", MaxAge: expiration, Secure: false}) | ||
req.Header.Add("X-XSRF-TOKEN", "random id") | ||
resp, err := client.Do(req) | ||
|
@@ -223,7 +260,7 @@ func TestAuthJWTRefreshFailed(t *testing.T) { | |
req, err := http.NewRequest("GET", server.URL+"/auth", http.NoBody) | ||
require.NoError(t, err) | ||
|
||
expiration := int(365 * 24 * time.Hour.Seconds()) //nolint | ||
expiration := int(365 * 24 * time.Hour.Seconds()) // nolint | ||
req.AddCookie(&http.Cookie{Name: "JWT", Value: testJwtExpired, HttpOnly: true, Path: "/", | ||
MaxAge: expiration, Secure: false}) | ||
req.Header.Add("X-XSRF-TOKEN", "random id") | ||
|
@@ -413,7 +450,7 @@ func TestRBAC(t *testing.T) { | |
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||
u, err := token.GetUserInfo(r) | ||
assert.NoError(t, err) | ||
assert.Equal(t, token.User{Name: "name1", ID: "id1", Picture: "http://example.com/pic.png", | ||
assert.Equal(t, token.User{Name: "name1", ID: "provider1_id1", Picture: "http://example.com/pic.png", | ||
IP: "127.0.0.1", Email: "[email protected]", Audience: "test_sys", | ||
Attributes: map[string]interface{}{"boola": true, "stra": "stra-val"}, | ||
Role: "employee"}, u) | ||
|
@@ -426,7 +463,7 @@ func TestRBAC(t *testing.T) { | |
defer server.Close() | ||
|
||
// employee route only, token with employee role | ||
expiration := int(365 * 24 * time.Hour.Seconds()) //nolint | ||
expiration := int(365 * 24 * time.Hour.Seconds()) // nolint | ||
req, err := http.NewRequest("GET", server.URL+"/authForEmployees", http.NoBody) | ||
require.Nil(t, err) | ||
req.AddCookie(&http.Cookie{Name: "JWT", Value: testJwtWithRole, HttpOnly: true, Path: "/", | ||
|
@@ -439,7 +476,7 @@ func TestRBAC(t *testing.T) { | |
assert.Equal(t, 201, resp.StatusCode, "valid token user") | ||
|
||
// employee route only, token without employee role | ||
expiration = int(365 * 24 * time.Hour.Seconds()) //nolint | ||
expiration = int(365 * 24 * time.Hour.Seconds()) // nolint | ||
req, err = http.NewRequest("GET", server.URL+"/authForEmployees", http.NoBody) | ||
require.Nil(t, err) | ||
req.AddCookie(&http.Cookie{Name: "JWT", Value: testJwtValid, HttpOnly: true, Path: "/", | ||
|
@@ -480,6 +517,7 @@ func makeTestMux(_ *testing.T, a *Authenticator, required bool) http.Handler { | |
} | ||
|
||
func makeTestAuth(_ *testing.T) Authenticator { | ||
|
||
j := token.NewService(token.Opts{ | ||
SecretReader: token.SecretFunc(func(string) (string, error) { return "xyz 12345", nil }), | ||
SecureCookies: false, | ||
|
@@ -497,6 +535,10 @@ func makeTestAuth(_ *testing.T) Authenticator { | |
JWTService: j, | ||
Validator: token.ValidatorFunc(func(token string, claims token.Claims) bool { return true }), | ||
L: logger.Std, | ||
Providers: []provider.Service{ | ||
{Provider: provider.DirectHandler{ProviderName: "provider1"}}, | ||
{Provider: provider.DirectHandler{ProviderName: "provider2"}}, | ||
}, | ||
} | ||
} | ||
|
||
|