Key Access Gate positive cache by user and Required Groups set.
Avoids reusing an allow decision after the configured group list changes on a live gate. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -213,6 +213,35 @@ func TestAccessGateCachesPositiveMembership(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestAccessGateCacheKeyedByGroupSet(t *testing.T) {
|
||||
var calls atomic.Int32
|
||||
srv := groupsOCSServer(t, func(w http.ResponseWriter, r *http.Request) {
|
||||
calls.Add(1)
|
||||
_ = json.NewEncoder(w).Encode(map[string]any{
|
||||
"ocs": map[string]any{"data": map[string]any{"groups": []string{"dns-ops"}}},
|
||||
})
|
||||
})
|
||||
cred := gonexapp.Credentials{
|
||||
BaseURL: srv.URL, AppID: "app", AppVersion: "0.1.0", AAVersion: "1.0.0", AppSecret: "s",
|
||||
}
|
||||
gate := &gonexapp.AccessGate{
|
||||
Cred: cred, Groups: []string{"dns-ops"}, CacheTTL: time.Minute,
|
||||
Client: srv.Client(), OCS: gonexapp.OCSClient{Cred: cred, Client: srv.Client()},
|
||||
}
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/zones", nil)
|
||||
req.Header.Set("AUTHORIZATION-APP-API", authHeader("alice"))
|
||||
if gate.Check(req) != gonexapp.CheckAllowed {
|
||||
t.Fatal("first allow")
|
||||
}
|
||||
gate.Groups = []string{"other-group"}
|
||||
if gate.Check(req) != gonexapp.CheckDenied {
|
||||
t.Fatalf("after group-set change want denied, calls=%d", calls.Load())
|
||||
}
|
||||
if calls.Load() != 2 {
|
||||
t.Fatalf("ocs calls=%d want 2 (cache must not reuse prior group-set)", calls.Load())
|
||||
}
|
||||
}
|
||||
|
||||
func TestAccessGateDoesNotCacheDenial(t *testing.T) {
|
||||
var calls atomic.Int32
|
||||
srv := groupsOCSServer(t, func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
Reference in New Issue
Block a user