server: pass IQBC to authorizer (#4838)

Before, the option InterQueryCache(...) passed to the authorizer's config
had set it to `nil` -- it wasn't set up yet.

Now, the ordering allows for caching in the system authz policies.

Fixes #4829.

Signed-off-by: Stephan Renatus <stephan.renatus@gmail.com>
This commit is contained in:
Stephan Renatus
2022-07-04 14:06:26 +02:00
committed by GitHub
parent a52e31748a
commit 7305b1663b
2 changed files with 74 additions and 4 deletions
+4 -2
View File
@@ -158,8 +158,6 @@ func New() *Server {
// from s.Listeners().
func (s *Server) Init(ctx context.Context) (*Server, error) {
s.initRouters()
s.Handler = s.initHandlerAuth(s.Handler)
s.DiagnosticHandler = s.initHandlerAuth(s.DiagnosticHandler)
txn, err := s.store.NewTransaction(ctx, storage.WriteParams)
if err != nil {
@@ -182,6 +180,10 @@ func (s *Server) Init(ctx context.Context) (*Server, error) {
s.interQueryBuiltinCache = iCache.NewInterQueryCache(s.manager.InterQueryBuiltinCacheConfig())
s.manager.RegisterCacheTrigger(s.updateCacheConfig)
// authorizer, if configured, needs the iCache to be set up already
s.Handler = s.initHandlerAuth(s.Handler)
s.DiagnosticHandler = s.initHandlerAuth(s.DiagnosticHandler)
return s, s.store.Commit(ctx, txn)
}
+70 -2
View File
@@ -16,6 +16,7 @@ import (
"reflect"
"sort"
"strings"
"sync/atomic"
"testing"
"time"
@@ -3545,6 +3546,73 @@ func TestAuthorization(t *testing.T) {
}
}
func TestAuthorizationUsesInterQueryCache(t *testing.T) {
ctx := context.Background()
store := inmem.New()
m, err := plugins.New([]byte{}, "test", store)
if err != nil {
panic(err)
}
if err := m.Start(ctx); err != nil {
panic(err)
}
txn := storage.NewTransactionOrDie(ctx, store, storage.WriteParams)
var c uint64
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
atomic.AddUint64(&c, 1)
fmt.Fprintf(w, `{"count": %d}`, c)
}))
authzPolicy := fmt.Sprintf(`package system.authz
default allow := false
allow {
resp := http.send({
"method": "GET", "url": "%[1]s/foo",
"force_cache": true,
"force_json_decode": true,
"force_cache_duration_seconds": 60,
})
resp.body.count == 1
}
`, ts.URL)
t.Log(authzPolicy)
if err := store.UpsertPolicy(ctx, txn, "test", []byte(authzPolicy)); err != nil {
t.Fatal(err)
}
if err := store.Commit(ctx, txn); err != nil {
t.Fatal(err)
}
server, err := New().
WithAddresses([]string{":8182"}).
WithStore(store).
WithManager(m).
WithAuthorization(AuthorizationBasic).
Init(ctx)
if err != nil {
t.Fatal(err)
}
for i := 0; i < 5; i++ {
req1, err := http.NewRequest(http.MethodGet, "http://localhost:8182/health", nil)
if err != nil {
t.Fatal(err)
}
validateAuthorizedRequest(t, server, req1, http.StatusOK)
}
}
func validateAuthorizedRequest(t *testing.T, s *Server, req *http.Request, exp int) {
t.Helper()
@@ -3553,7 +3621,7 @@ func validateAuthorizedRequest(t *testing.T, s *Server, req *http.Request, exp i
// First check the main router
s.Handler.ServeHTTP(r, req)
if r.Code != exp {
t.Fatalf("(Default Handler) Expected %v but got: %v", exp, r)
t.Errorf("(Default Handler) Expected %v but got: %v", exp, r)
}
r = httptest.NewRecorder()
@@ -3561,7 +3629,7 @@ func validateAuthorizedRequest(t *testing.T, s *Server, req *http.Request, exp i
// Ensure that auth happens for the diagnostic handler as well
s.DiagnosticHandler.ServeHTTP(r, req)
if r.Code != exp {
t.Fatalf("(Diagnostic Handler) Expected %v but got: %v", exp, r)
t.Errorf("(Diagnostic Handler) Expected %v but got: %v", exp, r)
}
}