fix: restore request denied on invalid auth after contextual middlwares
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/pr Build is passing Details

This commit is contained in:
Adrien Marquès 2021-06-20 10:24:12 +02:00
parent 97941da901
commit fd1ced5a8b
Signed by: xdrm-brackets
GPG Key ID: D75243CA236D825E
2 changed files with 104 additions and 0 deletions

View File

@ -63,6 +63,18 @@ func (s Handler) resolve(w http.ResponseWriter, r *http.Request) {
// create http handler // create http handler
var h http.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { var h http.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
auth := api.GetAuth(r.Context())
if auth == nil {
handleError(api.ErrPermission, w, r)
return
}
// reject non granted requests
if !auth.Granted() {
handleError(api.ErrPermission, w, r)
return
}
// use context defined in the request // use context defined in the request
s.handle(r.Context(), input, handler, service, w, r) s.handle(r.Context(), input, handler, service, w, r)
}) })

View File

@ -3,6 +3,7 @@ package aicra_test
import ( import (
"bytes" "bytes"
"context" "context"
"encoding/json"
"fmt" "fmt"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
@ -275,6 +276,97 @@ func TestWithAuth(t *testing.T) {
} }
func TestPermissionError(t *testing.T) {
tt := []struct {
name string
manifest string
permissions []string
granted bool
}{
{
name: "permission fulfilled",
manifest: `[ { "method": "GET", "path": "/path", "scope": [["A"]], "info": "info", "in": {}, "out": {} } ]`,
permissions: []string{"A"},
granted: true,
},
{
name: "missing permission",
manifest: `[ { "method": "GET", "path": "/path", "scope": [["A"]], "info": "info", "in": {}, "out": {} } ]`,
permissions: []string{},
granted: false,
},
}
for _, tc := range tt {
t.Run(tc.name, func(t *testing.T) {
builder := &aicra.Builder{}
if err := addBuiltinTypes(builder); err != nil {
t.Fatalf("unexpected error <%v>", err)
}
// add active permissions
builder.WithContext(func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
a := api.GetAuth(r.Context())
if a == nil {
t.Fatalf("cannot access api.Auth form request context")
}
a.Active = tc.permissions
next.ServeHTTP(w, r)
})
})
err := builder.Setup(strings.NewReader(tc.manifest))
if err != nil {
t.Fatalf("setup: unexpected error <%v>", err)
}
pathHandler := func(ctx context.Context) (*struct{}, api.Err) {
return nil, api.ErrNotImplemented
}
if err := builder.Bind(http.MethodGet, "/path", pathHandler); err != nil {
t.Fatalf("bind: unexpected error <%v>", err)
}
handler, err := builder.Build()
if err != nil {
t.Fatalf("build: unexpected error <%v>", err)
}
response := httptest.NewRecorder()
request := httptest.NewRequest(http.MethodGet, "/path", &bytes.Buffer{})
// test request
handler.ServeHTTP(response, request)
if response.Body == nil {
t.Fatalf("response has no body")
}
type jsonResponse struct {
Err api.Err `json:"error"`
}
var res jsonResponse
err = json.Unmarshal(response.Body.Bytes(), &res)
if err != nil {
t.Fatalf("cannot unmarshal response: %s", err)
}
expectedError := api.ErrNotImplemented
if !tc.granted {
expectedError = api.ErrPermission
}
if res.Err.Code != expectedError.Code {
t.Fatalf("expected error code %d got %d", expectedError.Code, res.Err.Code)
}
})
}
}
func TestDynamicScope(t *testing.T) { func TestDynamicScope(t *testing.T) {
tt := []struct { tt := []struct {
name string name string