refactor/idiomatic-handlers-middlewares #25

Merged
xdrm-brackets merged 7 commits from refactor/idiomatic-handlers-middlewares into 0.4.0 2021-06-20 08:26:28 +00:00
2 changed files with 104 additions and 0 deletions
Showing only changes of commit fd1ced5a8b - Show all commits

View File

@ -63,6 +63,18 @@ func (s Handler) resolve(w http.ResponseWriter, r *http.Request) {
// create http handler
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
s.handle(r.Context(), input, handler, service, w, r)
})

View File

@ -3,6 +3,7 @@ package aicra_test
import (
"bytes"
"context"
"encoding/json"
"fmt"
"net/http"
"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) {
tt := []struct {
name string