diff --git a/headers.go b/headers.go new file mode 100644 index 0000000..b40ae69 --- /dev/null +++ b/headers.go @@ -0,0 +1,31 @@ +package rest + +import ( + "fmt" + "net/http" +) + +// IsAuthenticated returns true if the bearer token in a request's authorization is equal to a user-defined token. +// This function always returns true if the user-defined token is empty i.e. no authentication required. +func IsAuthenticated(req *http.Request, token string) bool { + if token == "" { + return true + } + + read := ReadBearerToken(req) + return read == token +} + +// ReadBearerToken reads the token portion of a bearer token in a request's authorization header. +// This function returns an empty string if the header is not provided or is not a bearer token. +func ReadBearerToken(req *http.Request) string { + header := req.Header.Get("authorization") + if len(header) > 8 { + bearer := header[0:7] + fmt.Println(bearer) + if bearer == "bearer " || bearer == "Bearer " { + return header[7:] + } + } + return "" +} diff --git a/headers_test.go b/headers_test.go new file mode 100644 index 0000000..60c7126 --- /dev/null +++ b/headers_test.go @@ -0,0 +1,73 @@ +package rest + +import ( + "net/http" + "net/http/httptest" + "testing" +) + +func TestIsAuthenticated(t *testing.T) { + type TestCase struct { + Req *http.Request + Token string + Expected bool + } + + testCases := []TestCase{} + + req := httptest.NewRequest("GET", "/", nil) + req.Header.Add("authorization", "bearer abcd") + testCases = append(testCases, TestCase{Req: req, Token: "abcd", Expected: true}) + + req = httptest.NewRequest("POST", "/", nil) + req.Header.Add("authorization", "Bearer defg hijk") + testCases = append(testCases, TestCase{Req: req, Token: "defg hijk", Expected: true}) + + req = httptest.NewRequest("DELETE", "/", nil) + testCases = append(testCases, TestCase{Req: req, Token: "", Expected: true}) + + req = httptest.NewRequest("GET", "/", nil) + testCases = append(testCases, TestCase{Req: req, Token: "lmno"}) + + req = httptest.NewRequest("GET", "/", nil) + req.Header.Add("authorization", "Bearer pqrs") + testCases = append(testCases, TestCase{Req: req, Expected: true}) + + for i, tc := range testCases { + t.Logf("(%d) Testing request authorization header against %q", i, tc.Token) + + actual := IsAuthenticated(tc.Req, tc.Token) + if actual != tc.Expected { + t.Errorf("Expected %v, got %v", tc.Expected, actual) + } + } +} + +func TestReadBearerToken(t *testing.T) { + type TestCase struct { + Req *http.Request + Expected string + } + + testCases := []TestCase{} + + req := httptest.NewRequest("GET", "/", nil) + req.Header.Add("authorization", "bearer abcd") + testCases = append(testCases, TestCase{Req: req, Expected: "abcd"}) + + req = httptest.NewRequest("POST", "/", nil) + req.Header.Add("authorization", "Bearer defg hijk") + testCases = append(testCases, TestCase{Req: req, Expected: "defg hijk"}) + + req = httptest.NewRequest("DELETE", "/", nil) + testCases = append(testCases, TestCase{Req: req, Expected: ""}) + + for i, tc := range testCases { + t.Logf("(%d) Testing request authorization header against %q", i, tc.Expected) + + actual := ReadBearerToken(tc.Req) + if actual != tc.Expected { + t.Errorf("Expected %q, got %q", tc.Expected, actual) + } + } +}