Skip to content

Commit

Permalink
Test for OAuth2 access control
Browse files Browse the repository at this point in the history
  • Loading branch information
Johannes Koch committed May 28, 2021
1 parent 22268cd commit 5a3c2b4
Show file tree
Hide file tree
Showing 3 changed files with 150 additions and 0 deletions.
105 changes: 105 additions & 0 deletions server/http_oauth2_test.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package server_test

import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"net/http/httptest"
"strings"
"testing"
"time"

Expand Down Expand Up @@ -197,3 +199,106 @@ func TestEndpoints_OAuth2_Options(t *testing.T) {
shutdown()
}
}

func TestOAuth2AccessControl(t *testing.T) {
client := newClient()
helper := test.New(t)

oauthOrigin := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
if req.URL.Path == "/token" {
_ = req.ParseForm()
rw.Header().Set("Content-Type", "application/json")
rw.WriteHeader(http.StatusOK)

body := []byte(`{
"access_token": "abcdef0123456789",
"token_type": "bearer",
"expires_in": 100,
"form_params": "` + req.PostForm.Encode() + `",
"authorization": "` + req.Header.Get("Authorization") + `"
}`)
_, werr := rw.Write(body)
helper.Must(werr)

return
}
rw.WriteHeader(http.StatusBadRequest)
}))
defer oauthOrigin.Close()

type testCase struct {
name string
filename string
path string
header http.Header
status int
params string
authorization string
wantErrLog string
}

for _, tc := range []testCase{
{"no code, but error", "04_couper.hcl", "/cb?error=qeuboub", http.Header{}, http.StatusForbidden, "", "", "access control error: ac: missing code query parameter; query='error=qeuboub"},
{"no code; error handler", "05_couper.hcl", "/cb?error=qeuboub", http.Header{}, http.StatusBadRequest, "", "", "access control error: ac: missing code query parameter; query='error=qeuboub"},
{"code; client_secret_basic", "04_couper.hcl", "/cb?code=qeuboub", http.Header{"Cookie": []string{"pkcecv=qerbnr"}}, http.StatusOK, "code=qeuboub&code_verifier=qerbnr&grant_type=authorization_code&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Fcb", "Basic Zm9vOmV0YmluYnA0aW4=", ""},
{"code; client_secret_post", "05_couper.hcl", "/cb?code=qeuboub", http.Header{}, http.StatusOK, "client_id=foo&client_secret=etbinbp4in&code=qeuboub&grant_type=authorization_code&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Fcb", "", ""},
} {
t.Run(tc.path[1:], func(subT *testing.T) {
shutdown, hook := newCouper("testdata/oauth2/"+tc.filename, test.New(t))
defer shutdown()

req, err := http.NewRequest(http.MethodGet, "http://back.end:8080"+tc.path, nil)
helper.Must(err)

for k, v := range tc.header {
req.Header.Set(k, v[0])
}
req.Header.Set("X-Token-URL", oauthOrigin.URL)

res, err := client.Do(req)
helper.Must(err)

if res.StatusCode != tc.status {
t.Errorf("%q: expected Status %d, got: %d", tc.name, tc.status, res.StatusCode)
return
}

tokenResBytes, err := ioutil.ReadAll(res.Body)
var jData map[string]interface{}
json.Unmarshal(tokenResBytes, &jData)
if params, ok := jData["form_params"]; ok {
if params != tc.params {
t.Errorf("%q: expected params %s, got: %s", tc.name, tc.params, params)
return
}
} else {
if "" != tc.params {
t.Errorf("%q: expected params %s, got no", tc.name, tc.params)
return
}
}
if authorization, ok := jData["authorization"]; ok {
if authorization != tc.authorization {
t.Errorf("%q: expected authorization %s, got: %s", tc.name, tc.authorization, authorization)
return
}
} else {
if "" != tc.authorization {
t.Errorf("%q: expected authorization %s, got no", tc.name, tc.authorization)
return
}
}

message := getAccessControlMessages(hook)
if tc.wantErrLog == "" {
if message != "" {
t.Errorf("%q: Expected error log: %q, actual: %#v", tc.name, tc.wantErrLog, message)
}
} else {
if !strings.HasPrefix(message, tc.wantErrLog) {
t.Errorf("%q: Expected error log message: %q, actual: %#v", tc.name, tc.wantErrLog, message)
}
}
})
}
}
20 changes: 20 additions & 0 deletions server/testdata/oauth2/04_couper.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
server "client" {
api {
endpoint "/cb" {
access_control = ["ac"]
response {
json_body = request.context.ac
}
}
}
}
definitions {
oauth2 "ac" {
grant_type = "authorization_code"
redirect_uri = "http://localhost:8080/cb" # value is not checked
token_endpoint = "${request.headers.x-token-url}/token"
client_id = "foo"
client_secret = "etbinbp4in"
code_verifier_value = request.cookies.pkcecv
}
}
25 changes: 25 additions & 0 deletions server/testdata/oauth2/05_couper.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
server "client" {
api {
endpoint "/cb" {
access_control = ["ac"]
response {
json_body = request.context.ac
}
}
}
}
definitions {
oauth2 "ac" {
grant_type = "authorization_code"
redirect_uri = "http://localhost:8080/cb" # value is not checked
token_endpoint = "${request.headers.x-token-url}/token"
token_endpoint_auth_method = "client_secret_post"
client_id = "foo"
client_secret = "etbinbp4in"
error_handler {
response {
status = 400
}
}
}
}

0 comments on commit 5a3c2b4

Please sign in to comment.