48 lines
1.5 KiB
Go
48 lines
1.5 KiB
Go
package middleware
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
|
|
"github.com/prabhupadasays/spsays-bff/internal/rbac"
|
|
)
|
|
|
|
func withStaff(perms ...string) context.Context {
|
|
return context.WithValue(context.Background(), staffCtxKey{}, &StaffContext{
|
|
RoleKey: "x", Perms: rbac.NewSet(perms),
|
|
})
|
|
}
|
|
|
|
func TestRequirePermission(t *testing.T) {
|
|
ok := http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusNoContent) })
|
|
gate := RequirePermission("users:ban")(ok)
|
|
|
|
cases := []struct {
|
|
name string
|
|
ctx context.Context
|
|
want int
|
|
}{
|
|
{"moderator without the permission", withStaff("reports:read", "users:read"), http.StatusForbidden},
|
|
{"admin with it", withStaff("users:ban"), http.StatusNoContent},
|
|
{"superadmin wildcard", withStaff(rbac.Wildcard), http.StatusNoContent},
|
|
// Outside RequireStaff there's no staff context at all: refuse.
|
|
{"no staff context", context.Background(), http.StatusForbidden},
|
|
}
|
|
for _, c := range cases {
|
|
rec := httptest.NewRecorder()
|
|
gate.ServeHTTP(rec, httptest.NewRequest(http.MethodPost, "/", nil).WithContext(c.ctx))
|
|
if rec.Code != c.want {
|
|
t.Errorf("%s: status %d, want %d", c.name, rec.Code, c.want)
|
|
}
|
|
}
|
|
|
|
// Staff management is never reachable through a catalog permission.
|
|
if withStaffSet("users:ban", "quizzes:write").Has(rbac.ManageStaff) {
|
|
t.Error("a non-wildcard set holds admins:manage")
|
|
}
|
|
}
|
|
|
|
func withStaffSet(perms ...string) rbac.Set { return rbac.NewSet(perms) }
|