traefik-forward-auth/main_test.go

211 lines
5.1 KiB
Go
Raw Normal View History

2018-07-19 08:50:12 +01:00
package main
import (
2019-01-22 10:50:55 +00:00
"fmt"
"time"
// "reflect"
"io/ioutil"
"net/http"
"net/http/httptest"
"net/url"
"strings"
"testing"
2018-07-19 08:50:12 +01:00
)
/**
* Utilities
*/
2018-07-19 08:50:12 +01:00
2019-01-22 10:50:55 +00:00
type TokenServerHandler struct{}
2018-07-19 08:50:12 +01:00
func (t *TokenServerHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
2019-01-22 10:50:55 +00:00
fmt.Fprint(w, `{"access_token":"123456789"}`)
2018-07-19 08:50:12 +01:00
}
2019-01-22 10:50:55 +00:00
type UserServerHandler struct{}
2018-07-19 08:50:12 +01:00
func (t *UserServerHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
2019-01-22 10:50:55 +00:00
fmt.Fprint(w, `{
2018-07-19 08:50:12 +01:00
"id":"1",
"email":"example@example.com",
"verified_email":true,
"hd":"example.com"
}`)
}
func init() {
2019-01-22 14:19:17 +00:00
log = CreateLogger("panic", "")
2018-07-19 08:50:12 +01:00
}
func httpRequest(r *http.Request, c *http.Cookie) (*http.Response, string) {
2019-01-22 10:50:55 +00:00
w := httptest.NewRecorder()
2018-07-19 08:50:12 +01:00
2019-01-22 10:50:55 +00:00
// Set cookies on recorder
if c != nil {
http.SetCookie(w, c)
}
2018-07-19 08:50:12 +01:00
2019-01-22 10:50:55 +00:00
// Copy into request
for _, c := range w.HeaderMap["Set-Cookie"] {
r.Header.Add("Cookie", c)
}
2018-07-19 08:50:12 +01:00
2019-01-22 10:50:55 +00:00
handler(w, r)
2018-07-19 08:50:12 +01:00
2019-01-22 10:50:55 +00:00
res := w.Result()
body, _ := ioutil.ReadAll(res.Body)
2018-07-19 08:50:12 +01:00
2019-01-22 10:50:55 +00:00
return res, string(body)
2018-07-19 08:50:12 +01:00
}
func newHttpRequest(uri string) *http.Request {
2019-01-22 10:50:55 +00:00
r := httptest.NewRequest("", "http://example.com", nil)
r.Header.Add("X-Forwarded-Uri", uri)
return r
2018-07-19 08:50:12 +01:00
}
func qsDiff(one, two url.Values) {
2019-01-22 10:51:41 +00:00
for k := range one {
2019-01-22 10:50:55 +00:00
if two.Get(k) == "" {
fmt.Printf("Key missing: %s\n", k)
}
if one.Get(k) != two.Get(k) {
fmt.Printf("Value different for %s: expected: '%s' got: '%s'\n", k, one.Get(k), two.Get(k))
}
}
2019-01-22 10:51:41 +00:00
for k := range two {
2019-01-22 10:50:55 +00:00
if one.Get(k) == "" {
fmt.Printf("Extra key: %s\n", k)
}
}
}
/**
* Tests
*/
2018-07-19 08:50:12 +01:00
func TestHandler(t *testing.T) {
2019-01-22 10:50:55 +00:00
fw = &ForwardAuth{
Path: "_oauth",
ClientId: "idtest",
ClientSecret: "sectest",
Scope: "scopetest",
LoginURL: &url.URL{
Scheme: "http",
Host: "test.com",
Path: "/auth",
},
CookieName: "cookie_test",
Lifetime: time.Second * time.Duration(10),
}
// Should redirect vanilla request to login url
req := newHttpRequest("foo")
res, _ := httpRequest(req, nil)
if res.StatusCode != 307 {
t.Error("Vanilla request should be redirected with 307, got:", res.StatusCode)
}
fwd, _ := res.Location()
if fwd.Scheme != "http" || fwd.Host != "test.com" || fwd.Path != "/auth" {
t.Error("Vanilla request should be redirected to login url, got:", fwd)
}
// Should catch invalid cookie
req = newHttpRequest("foo")
c := fw.MakeCookie(req, "test@example.com")
parts := strings.Split(c.Value, "|")
c.Value = fmt.Sprintf("bad|%s|%s", parts[1], parts[2])
res, _ = httpRequest(req, c)
if res.StatusCode != 401 {
t.Error("Request with invalid cookie shound't be authorised", res.StatusCode)
}
// Should validate email
req = newHttpRequest("foo")
c = fw.MakeCookie(req, "test@example.com")
fw.Domain = []string{"test.com"}
res, _ = httpRequest(req, c)
if res.StatusCode != 401 {
t.Error("Request with invalid cookie shound't be authorised", res.StatusCode)
}
// Should allow valid request email
req = newHttpRequest("foo")
c = fw.MakeCookie(req, "test@example.com")
fw.Domain = []string{}
res, _ = httpRequest(req, c)
if res.StatusCode != 200 {
t.Error("Valid request should be allowed, got:", res.StatusCode)
}
// Should pass through user
users := res.Header["X-Forwarded-User"]
if len(users) != 1 {
t.Error("Valid request missing X-Forwarded-User header")
} else if users[0] != "test@example.com" {
t.Error("X-Forwarded-User should match user, got: ", users)
}
2018-07-19 08:50:12 +01:00
}
func TestCallback(t *testing.T) {
2019-01-22 10:50:55 +00:00
fw = &ForwardAuth{
Path: "_oauth",
ClientId: "idtest",
ClientSecret: "sectest",
Scope: "scopetest",
LoginURL: &url.URL{
Scheme: "http",
Host: "test.com",
Path: "/auth",
},
CSRFCookieName: "csrf_test",
}
// Setup token server
tokenServerHandler := &TokenServerHandler{}
tokenServer := httptest.NewServer(tokenServerHandler)
defer tokenServer.Close()
tokenUrl, _ := url.Parse(tokenServer.URL)
fw.TokenURL = tokenUrl
// Setup user server
userServerHandler := &UserServerHandler{}
userServer := httptest.NewServer(userServerHandler)
defer userServer.Close()
userUrl, _ := url.Parse(userServer.URL)
fw.UserURL = userUrl
// Should pass auth response request to callback
req := newHttpRequest("_oauth")
res, _ := httpRequest(req, nil)
if res.StatusCode != 401 {
t.Error("Auth callback without cookie shound't be authorised, got:", res.StatusCode)
}
// Should catch invalid csrf cookie
req = newHttpRequest("_oauth?state=12345678901234567890123456789012:http://redirect")
c := fw.MakeCSRFCookie(req, "nononononononononononononononono")
res, _ = httpRequest(req, c)
if res.StatusCode != 401 {
t.Error("Auth callback with invalid cookie shound't be authorised, got:", res.StatusCode)
}
// Should redirect valid request
req = newHttpRequest("_oauth?state=12345678901234567890123456789012:http://redirect")
c = fw.MakeCSRFCookie(req, "12345678901234567890123456789012")
res, _ = httpRequest(req, c)
if res.StatusCode != 307 {
t.Error("Valid callback should be allowed, got:", res.StatusCode)
}
fwd, _ := res.Location()
if fwd.Scheme != "http" || fwd.Host != "redirect" || fwd.Path != "" {
t.Error("Valid request should be redirected to return url, got:", fwd)
}
}