193 lines
4.4 KiB
Go
193 lines
4.4 KiB
Go
package server_test
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/influxdata/chronograf"
|
|
clog "github.com/influxdata/chronograf/log"
|
|
"github.com/influxdata/chronograf/server"
|
|
)
|
|
|
|
func TestCookieExtractor(t *testing.T) {
|
|
var test = []struct {
|
|
Desc string
|
|
Name string
|
|
Value string
|
|
Lookup string
|
|
Expected string
|
|
Err error
|
|
}{
|
|
{
|
|
Desc: "No cookie of this name",
|
|
Name: "Auth",
|
|
Value: "reallyimportant",
|
|
Lookup: "Doesntexist",
|
|
Expected: "",
|
|
Err: chronograf.ErrAuthentication,
|
|
},
|
|
{
|
|
Desc: "Cookie token extracted",
|
|
Name: "Auth",
|
|
Value: "reallyimportant",
|
|
Lookup: "Auth",
|
|
Expected: "reallyimportant",
|
|
Err: nil,
|
|
},
|
|
}
|
|
for _, test := range test {
|
|
req, _ := http.NewRequest("", "http://howdy.com", nil)
|
|
req.AddCookie(&http.Cookie{
|
|
Name: test.Name,
|
|
Value: test.Value,
|
|
})
|
|
|
|
var e chronograf.TokenExtractor = &server.CookieExtractor{
|
|
Name: test.Lookup,
|
|
}
|
|
actual, err := e.Extract(req)
|
|
if err != test.Err {
|
|
t.Errorf("Cookie extract error; expected %v actual %v", test.Err, err)
|
|
}
|
|
|
|
if actual != test.Expected {
|
|
t.Errorf("Token extract error; expected %v actual %v", test.Expected, actual)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestBearerExtractor(t *testing.T) {
|
|
var test = []struct {
|
|
Desc string
|
|
Header string
|
|
Value string
|
|
Lookup string
|
|
Expected string
|
|
Err error
|
|
}{
|
|
{
|
|
Desc: "No header of this name",
|
|
Header: "Doesntexist",
|
|
Value: "reallyimportant",
|
|
Expected: "",
|
|
Err: chronograf.ErrAuthentication,
|
|
},
|
|
{
|
|
Desc: "Auth header doesn't have Bearer",
|
|
Header: "Authorization",
|
|
Value: "Bad Value",
|
|
Expected: "",
|
|
Err: chronograf.ErrAuthentication,
|
|
},
|
|
{
|
|
Desc: "Auth header doesn't have Bearer token",
|
|
Header: "Authorization",
|
|
Value: "Bearer",
|
|
Expected: "",
|
|
Err: chronograf.ErrAuthentication,
|
|
},
|
|
{
|
|
Desc: "Authorization Bearer token success",
|
|
Header: "Authorization",
|
|
Value: "Bearer howdy",
|
|
Expected: "howdy",
|
|
Err: nil,
|
|
},
|
|
}
|
|
for _, test := range test {
|
|
req, _ := http.NewRequest("", "http://howdy.com", nil)
|
|
req.Header.Add(test.Header, test.Value)
|
|
|
|
var e chronograf.TokenExtractor = &server.BearerExtractor{}
|
|
actual, err := e.Extract(req)
|
|
if err != test.Err {
|
|
t.Errorf("Bearer extract error; expected %v actual %v", test.Err, err)
|
|
}
|
|
|
|
if actual != test.Expected {
|
|
t.Errorf("Token extract error; expected %v actual %v", test.Expected, actual)
|
|
}
|
|
}
|
|
}
|
|
|
|
type MockExtractor struct {
|
|
Err error
|
|
}
|
|
|
|
func (m *MockExtractor) Extract(*http.Request) (string, error) {
|
|
return "", m.Err
|
|
}
|
|
|
|
type MockAuthenticator struct {
|
|
Principal chronograf.Principal
|
|
Err error
|
|
}
|
|
|
|
func (m *MockAuthenticator) Authenticate(context.Context, string) (chronograf.Principal, error) {
|
|
return m.Principal, m.Err
|
|
}
|
|
|
|
func (m *MockAuthenticator) Token(context.Context, chronograf.Principal, time.Duration) (string, error) {
|
|
return "", m.Err
|
|
}
|
|
|
|
func TestAuthorizedToken(t *testing.T) {
|
|
var tests = []struct {
|
|
Desc string
|
|
Code int
|
|
Principal chronograf.Principal
|
|
ExtractorErr error
|
|
AuthErr error
|
|
Expected string
|
|
}{
|
|
{
|
|
Desc: "Error in extractor",
|
|
Code: http.StatusUnauthorized,
|
|
ExtractorErr: errors.New("error"),
|
|
},
|
|
{
|
|
Desc: "Error in extractor",
|
|
Code: http.StatusUnauthorized,
|
|
AuthErr: errors.New("error"),
|
|
},
|
|
{
|
|
Desc: "Authorized ok",
|
|
Code: http.StatusOK,
|
|
Principal: "Principal Strickland",
|
|
Expected: "Principal Strickland",
|
|
},
|
|
}
|
|
for _, test := range tests {
|
|
// next is a sentinel StatusOK and
|
|
// principal recorder.
|
|
var principal chronograf.Principal
|
|
next := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
w.WriteHeader(http.StatusOK)
|
|
principal = r.Context().Value(chronograf.PrincipalKey).(chronograf.Principal)
|
|
})
|
|
req, _ := http.NewRequest("GET", "", nil)
|
|
w := httptest.NewRecorder()
|
|
|
|
e := &MockExtractor{
|
|
Err: test.ExtractorErr,
|
|
}
|
|
a := &MockAuthenticator{
|
|
Err: test.AuthErr,
|
|
Principal: test.Principal,
|
|
}
|
|
|
|
logger := clog.New(clog.DebugLevel)
|
|
handler := server.AuthorizedToken(a, e, logger, next)
|
|
handler.ServeHTTP(w, req)
|
|
if w.Code != test.Code {
|
|
t.Errorf("Status code expected: %d actual %d", test.Code, w.Code)
|
|
} else if principal != test.Principal {
|
|
t.Errorf("Principal mismatch expected: %s actual %s", test.Principal, principal)
|
|
}
|
|
}
|
|
}
|