From 94d667f96808e6dc47d29b7e1849adb3b9d2692b Mon Sep 17 00:00:00 2001 From: fum1h1to <75571344+fum1h1to@users.noreply.github.com> Date: Wed, 30 Oct 2024 14:54:28 +0900 Subject: [PATCH] Fix memory increase (#18) * fix Signed-off-by: fum1h1to <75571344+fum1h1to@users.noreply.github.com> * fix: gache updating Signed-off-by: fum1h1to <75571344+fum1h1to@users.noreply.github.com> * fix: comment Signed-off-by: fum1h1to <75571344+fum1h1to@users.noreply.github.com> --------- Signed-off-by: fum1h1to <75571344+fum1h1to@users.noreply.github.com> --- authorizerd.go | 31 ++-- authorizerd_test.go | 436 +++++++++++++++++++------------------------- go.mod | 2 +- go.sum | 4 +- policy/daemon.go | 2 +- 5 files changed, 203 insertions(+), 272 deletions(-) diff --git a/authorizerd.go b/authorizerd.go index 7a97ea6..3819594 100644 --- a/authorizerd.go +++ b/authorizerd.go @@ -73,10 +73,9 @@ type authority struct { client *http.Client // successful result cache - cache gache.Gache[Principal] - cacheExp time.Duration - cacheMemoryUsage *atomic.Int64 - cacheMemoryUsageMap gache.Gache[int64] + cache gache.Gache[Principal] + cacheExp time.Duration + cacheMemoryUsage *atomic.Int64 // roleCertURIPrefix roleCertURIPrefix string @@ -132,9 +131,8 @@ const ( func New(opts ...Option) (Authorizerd, error) { var ( prov = &authority{ - cache: gache.New[Principal](), - cacheMemoryUsage: &atomic.Int64{}, - cacheMemoryUsageMap: gache.New[int64](), + cache: gache.New[Principal](), + cacheMemoryUsage: &atomic.Int64{}, } err error pkPro pubkey.Provider @@ -331,7 +329,6 @@ func (a *authority) Start(ctx context.Context) <-chan error { case <-ctx.Done(): g.Stop() g.Clear() - a.cacheMemoryUsageMap.Clear() ech <- ctx.Err() return case err := <-cech: @@ -481,19 +478,16 @@ func (a *authority) authorize(ctx context.Context, m mode, tok, act, res, query }) a.cache.SetWithExpire(key.String(), p, a.cacheExp) - // Memory usage that cannot be calculated with gache.Size(). - // The memory usage of the principal cache entity and - // the memory usage of the key (cacheMemoryUsage + cacheMemoryUsageMap). - principalCacheSize := principalCacheMemoryUsage(p) + (int64(len(key.String())) * 2) + // Calculate memory usage of key and principal that cannot be calculated with gache.Size() + principalCacheSize := principalCacheMemoryUsage(key.String(), p) - a.cacheMemoryUsageMap.SetWithExpire(key.String(), principalCacheSize, 0) a.cacheMemoryUsage.Add(principalCacheSize) return p, nil } // principalCacheMemoryUsage returns memory usage of principal -func principalCacheMemoryUsage(p Principal) int64 { +func principalCacheMemoryUsage(key string, p Principal) int64 { structSize := int64(unsafe.Sizeof(p)) name := p.Name() domain := p.Domain() @@ -515,7 +509,7 @@ func principalCacheMemoryUsage(p Principal) int64 { const int64Size = 8 timesSize := int64Size * 2 - return structSize + nameSize + domainSize + rolesSize + authorizedRolesSize + int64(timesSize) + return structSize + nameSize + domainSize + rolesSize + authorizedRolesSize + int64(timesSize) + int64(len(key)) } // GetPrincipalCacheLen returns entries number of cached principals @@ -525,14 +519,13 @@ func (a *authority) GetPrincipalCacheLen() int { // GetPrincipalCacheSize returns memory usage of cached principals func (a *authority) GetPrincipalCacheSize() int64 { - return int64(a.cache.Size()) + a.cacheMemoryUsage.Load() + int64(a.cacheMemoryUsageMap.Size()) + return int64(a.cache.Size()) + a.cacheMemoryUsage.Load() } // cacheExpiredHook refreshes the value of cacheMemoryUsage when the cache expires. -func (prov *authority) cacheExpiredHook(ctx context.Context, key string) { - cacheUsage, _ := prov.cacheMemoryUsageMap.Get(key) +func (prov *authority) cacheExpiredHook(ctx context.Context, key string, value Principal) { + cacheUsage := principalCacheMemoryUsage(key, value) prov.cacheMemoryUsage.Add(-cacheUsage) - prov.cacheMemoryUsageMap.Delete(key) } // Verify returns error of verification. Returns nil if ANY authorizer succeeds (OR logic). diff --git a/authorizerd_test.go b/authorizerd_test.go index 3688113..ae51892 100644 --- a/authorizerd_test.go +++ b/authorizerd_test.go @@ -479,12 +479,11 @@ func Test_authorizer_Init(t *testing.T) { func Test_authorizer_Start(t *testing.T) { type fields struct { - pubkeyd pubkey.Daemon - policyd policy.Daemon - jwkd jwk.Daemon - cache gache.Gache[Principal] - cacheExp time.Duration - cacheMemoryUsageMap gache.Gache[int64] + pubkeyd pubkey.Daemon + policyd policy.Daemon + jwkd jwk.Daemon + cache gache.Gache[Principal] + cacheExp time.Duration } type args struct { ctx context.Context @@ -509,12 +508,11 @@ func Test_authorizer_Start(t *testing.T) { return test{ name: "test context done", fields: fields{ - pubkeyd: pdm, - policyd: pm, - jwkd: jd, - cache: gache.New[Principal](), - cacheExp: time.Minute, - cacheMemoryUsageMap: gache.New[int64](), + pubkeyd: pdm, + policyd: pm, + jwkd: jd, + cache: gache.New[Principal](), + cacheExp: time.Minute, }, args: args{ ctx: ctx, @@ -542,12 +540,11 @@ func Test_authorizer_Start(t *testing.T) { return test{ name: "test context pubkey updater returns error", fields: fields{ - pubkeyd: pdm, - policyd: pm, - jwkd: jd, - cache: gache.New[Principal](), - cacheExp: time.Minute, - cacheMemoryUsageMap: gache.New[int64](), + pubkeyd: pdm, + policyd: pm, + jwkd: jd, + cache: gache.New[Principal](), + cacheExp: time.Minute, }, args: args{ ctx: ctx, @@ -575,12 +572,11 @@ func Test_authorizer_Start(t *testing.T) { return test{ name: "test policyd returns error", fields: fields{ - pubkeyd: pdm, - policyd: pm, - jwkd: jd, - cache: gache.New[Principal](), - cacheExp: time.Minute, - cacheMemoryUsageMap: gache.New[int64](), + pubkeyd: pdm, + policyd: pm, + jwkd: jd, + cache: gache.New[Principal](), + cacheExp: time.Minute, }, args: args{ ctx: ctx, @@ -617,12 +613,11 @@ func Test_authorizer_Start(t *testing.T) { return test{ name: "test jwkd returns error", fields: fields{ - pubkeyd: pdm, - policyd: pm, - jwkd: jd, - cache: gache.New[Principal](), - cacheExp: time.Minute, - cacheMemoryUsageMap: gache.New[int64](), + pubkeyd: pdm, + policyd: pm, + jwkd: jd, + cache: gache.New[Principal](), + cacheExp: time.Minute, }, args: args{ ctx: ctx, @@ -642,12 +637,11 @@ func Test_authorizer_Start(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { prov := &authority{ - pubkeyd: tt.fields.pubkeyd, - policyd: tt.fields.policyd, - jwkd: tt.fields.jwkd, - cache: tt.fields.cache, - cacheExp: tt.fields.cacheExp, - cacheMemoryUsageMap: tt.fields.cacheMemoryUsageMap, + pubkeyd: tt.fields.pubkeyd, + policyd: tt.fields.policyd, + jwkd: tt.fields.jwkd, + cache: tt.fields.cache, + cacheExp: tt.fields.cacheExp, } ch := prov.Start(tt.args.ctx) gotErr := <-ch @@ -667,12 +661,11 @@ func Test_authorizer_AuthorizeRoleToken(t *testing.T) { res string } type fields struct { - policyd policy.Daemon - cache gache.Gache[Principal] - cacheExp time.Duration - cacheMemoryUsageMap gache.Gache[int64] - roleTokenProcessor role.Processor - cacheMemoryUsage *atomic.Int64 + policyd policy.Daemon + cache gache.Gache[Principal] + cacheExp time.Duration + roleTokenProcessor role.Processor + cacheMemoryUsage *atomic.Int64 } type test struct { name string @@ -685,7 +678,6 @@ func Test_authorizer_AuthorizeRoleToken(t *testing.T) { tests := []test{ func() test { c := gache.New[Principal]() - c2 := gache.New[int64]() rt := &role.Token{} p := &principal{ name: rt.Principal, @@ -708,12 +700,11 @@ func Test_authorizer_AuthorizeRoleToken(t *testing.T) { res: "dummyRes", }, fields: fields{ - policyd: pdm, - roleTokenProcessor: rpm, - cache: c, - cacheExp: time.Minute, - cacheMemoryUsageMap: c2, - cacheMemoryUsage: &atomic.Int64{}, + policyd: pdm, + roleTokenProcessor: rpm, + cache: c, + cacheExp: time.Minute, + cacheMemoryUsage: &atomic.Int64{}, }, wantErr: "", wantResult: p, @@ -728,7 +719,6 @@ func Test_authorizer_AuthorizeRoleToken(t *testing.T) { }(), func() test { c := gache.New[Principal]() - c2 := gache.New[int64]() rt := &role.Token{} p := &principal{ name: rt.Principal, @@ -752,11 +742,10 @@ func Test_authorizer_AuthorizeRoleToken(t *testing.T) { res: "dummyRes", }, fields: fields{ - policyd: pdm, - roleTokenProcessor: rpm, - cache: c, - cacheMemoryUsageMap: c2, - cacheExp: time.Minute, + policyd: pdm, + roleTokenProcessor: rpm, + cache: c, + cacheExp: time.Minute, }, wantErr: "", wantResult: p, @@ -764,7 +753,6 @@ func Test_authorizer_AuthorizeRoleToken(t *testing.T) { }(), func() test { c := gache.New[Principal]() - c2 := gache.New[int64]() c.Set("dummyTok:dummyAct:dummyRes", &principal{}) rpm := &RoleProcessorMock{ rt: &role.Token{}, @@ -780,18 +768,16 @@ func Test_authorizer_AuthorizeRoleToken(t *testing.T) { res: "dummyRes", }, fields: fields{ - policyd: pdm, - roleTokenProcessor: rpm, - cache: c, - cacheMemoryUsageMap: c2, - cacheExp: time.Minute, + policyd: pdm, + roleTokenProcessor: rpm, + cache: c, + cacheExp: time.Minute, }, wantErr: "empty action / resource: Access denied due to invalid/empty action/resource values", } }(), func() test { c := gache.New[Principal]() - c2 := gache.New[int64]() c.Set("dummyTok:dummyAct:dummyRes", &principal{}) rpm := &RoleProcessorMock{ rt: &role.Token{}, @@ -807,18 +793,16 @@ func Test_authorizer_AuthorizeRoleToken(t *testing.T) { res: "", }, fields: fields{ - policyd: pdm, - roleTokenProcessor: rpm, - cache: c, - cacheMemoryUsageMap: c2, - cacheExp: time.Minute, + policyd: pdm, + roleTokenProcessor: rpm, + cache: c, + cacheExp: time.Minute, }, wantErr: "empty action / resource: Access denied due to invalid/empty action/resource values", } }(), func() test { c := gache.New[Principal]() - c2 := gache.New[int64]() rpm := &RoleProcessorMock{ wantErr: errors.New("cannot parse roletoken"), } @@ -832,18 +816,16 @@ func Test_authorizer_AuthorizeRoleToken(t *testing.T) { res: "dummyRes", }, fields: fields{ - policyd: pdm, - roleTokenProcessor: rpm, - cache: c, - cacheMemoryUsageMap: c2, - cacheExp: time.Minute, + policyd: pdm, + roleTokenProcessor: rpm, + cache: c, + cacheExp: time.Minute, }, wantErr: "error authorize role token: cannot parse roletoken", } }(), func() test { c := gache.New[Principal]() - c2 := gache.New[int64]() rpm := &RoleProcessorMock{ rt: &role.Token{}, } @@ -861,11 +843,10 @@ func Test_authorizer_AuthorizeRoleToken(t *testing.T) { res: "dummyRes", }, fields: fields{ - policyd: pdm, - roleTokenProcessor: rpm, - cache: c, - cacheMemoryUsageMap: c2, - cacheExp: time.Minute, + policyd: pdm, + roleTokenProcessor: rpm, + cache: c, + cacheExp: time.Minute, }, wantErr: "token unauthorized: deny", } @@ -874,12 +855,11 @@ func Test_authorizer_AuthorizeRoleToken(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { prov := &authority{ - policyd: tt.fields.policyd, - roleProcessor: tt.fields.roleTokenProcessor, - cache: tt.fields.cache, - cacheExp: tt.fields.cacheExp, - cacheMemoryUsageMap: tt.fields.cacheMemoryUsageMap, - cacheMemoryUsage: tt.fields.cacheMemoryUsage, + policyd: tt.fields.policyd, + roleProcessor: tt.fields.roleTokenProcessor, + cache: tt.fields.cache, + cacheExp: tt.fields.cacheExp, + cacheMemoryUsage: tt.fields.cacheMemoryUsage, } err := prov.VerifyRoleToken(tt.args.ctx, tt.args.tok, tt.args.act, tt.args.res) if err != nil { @@ -934,7 +914,6 @@ func Test_authorizer_authorize(t *testing.T) { client *http.Client cache gache.Gache[Principal] cacheExp time.Duration - cacheMemoryUsageMap gache.Gache[int64] roleCertURIPrefix string pubkeyRefreshPeriod string pubkeySysAuthDomain string @@ -968,7 +947,6 @@ func Test_authorizer_authorize(t *testing.T) { tests := []test{ func() test { c := gache.New[Principal]() - c2 := gache.New[int64]() var count int pdm := &PolicydMock{ CheckPolicyRoleFunc: func(ctx context.Context, domain string, roles []string, action, resource string) ([]string, error) { @@ -991,12 +969,11 @@ func Test_authorizer_authorize(t *testing.T) { return test{ name: "test disablePolicyd true", fields: fields{ - cache: c, - cacheMemoryUsageMap: c2, - policyd: pdm, - disablePolicyd: true, - roleProcessor: rpm, - cacheMemoryUsage: &atomic.Int64{}, + cache: c, + policyd: pdm, + disablePolicyd: true, + roleProcessor: rpm, + cacheMemoryUsage: &atomic.Int64{}, }, args: args{ m: roleToken, @@ -1017,7 +994,6 @@ func Test_authorizer_authorize(t *testing.T) { }(), func() test { c := gache.New[Principal]() - c2 := gache.New[int64]() pdm := &PolicydMock{} rt := &role.Token{} p := &principal{ @@ -1034,12 +1010,11 @@ func Test_authorizer_authorize(t *testing.T) { return test{ name: "test cache key when disablePolicyd is true", fields: fields{ - cache: c, - cacheMemoryUsageMap: c2, - policyd: pdm, - disablePolicyd: true, - roleProcessor: rpm, - cacheMemoryUsage: &atomic.Int64{}, + cache: c, + policyd: pdm, + disablePolicyd: true, + roleProcessor: rpm, + cacheMemoryUsage: &atomic.Int64{}, }, args: args{ m: roleToken, @@ -1061,7 +1036,6 @@ func Test_authorizer_authorize(t *testing.T) { }(), func() test { c := gache.New[Principal]() - c2 := gache.New[int64]() pdm := &PolicydMock{} rt := &role.Token{} p := &principal{ @@ -1078,12 +1052,11 @@ func Test_authorizer_authorize(t *testing.T) { return test{ name: "test cache key when disablePolicyd is false", fields: fields{ - cache: c, - cacheMemoryUsageMap: c2, - policyd: pdm, - disablePolicyd: false, - roleProcessor: rpm, - cacheMemoryUsage: &atomic.Int64{}, + cache: c, + policyd: pdm, + disablePolicyd: false, + roleProcessor: rpm, + cacheMemoryUsage: &atomic.Int64{}, }, args: args{ m: roleToken, @@ -1105,7 +1078,6 @@ func Test_authorizer_authorize(t *testing.T) { }(), func() test { c := gache.New[Principal]() - c2 := gache.New[int64]() pdm := &PolicydMock{} rt := &role.Token{ Domain: "domain", @@ -1132,13 +1104,12 @@ func Test_authorizer_authorize(t *testing.T) { return test{ name: "test cache key when disablePolicyd is false and translator is not nil", fields: fields{ - cache: c, - cacheMemoryUsageMap: c2, - policyd: pdm, - disablePolicyd: false, - roleProcessor: rpm, - translator: mr, - cacheMemoryUsage: &atomic.Int64{}, + cache: c, + policyd: pdm, + disablePolicyd: false, + roleProcessor: rpm, + translator: mr, + cacheMemoryUsage: &atomic.Int64{}, }, args: args{ m: roleToken, @@ -1161,7 +1132,6 @@ func Test_authorizer_authorize(t *testing.T) { }(), func() test { c := gache.New[Principal]() - c2 := gache.New[int64]() pdm := &PolicydMock{} rt := &role.Token{ Domain: "domain", @@ -1188,13 +1158,12 @@ func Test_authorizer_authorize(t *testing.T) { return test{ name: "test cache key when disablePolicyd is false and translator is not nil, but didn't match", fields: fields{ - cache: c, - cacheMemoryUsageMap: c2, - policyd: pdm, - disablePolicyd: false, - roleProcessor: rpm, - translator: mr, - cacheMemoryUsage: &atomic.Int64{}, + cache: c, + policyd: pdm, + disablePolicyd: false, + roleProcessor: rpm, + translator: mr, + cacheMemoryUsage: &atomic.Int64{}, }, args: args{ m: roleToken, @@ -1217,7 +1186,6 @@ func Test_authorizer_authorize(t *testing.T) { }(), func() test { c := gache.New[Principal]() - c2 := gache.New[int64]() pdm := &PolicydMock{} rt := &role.Token{ Domain: "domain", @@ -1236,12 +1204,11 @@ func Test_authorizer_authorize(t *testing.T) { return test{ name: "test cache key when disablePolicyd is false and translator is nil", fields: fields{ - cache: c, - cacheMemoryUsageMap: c2, - policyd: pdm, - disablePolicyd: false, - roleProcessor: rpm, - cacheMemoryUsage: &atomic.Int64{}, + cache: c, + policyd: pdm, + disablePolicyd: false, + roleProcessor: rpm, + cacheMemoryUsage: &atomic.Int64{}, }, args: args{ m: roleToken, @@ -1264,7 +1231,6 @@ func Test_authorizer_authorize(t *testing.T) { }(), func() test { c := gache.New[Principal]() - c2 := gache.New[int64]() pdm := &PolicydMock{ CheckPolicyRoleFunc: func(ctx context.Context, domain string, roles []string, action, resource string) ([]string, error) { if resource != "/public/path" { @@ -1290,13 +1256,12 @@ func Test_authorizer_authorize(t *testing.T) { return test{ name: "test resourcePrefix", fields: fields{ - cache: c, - cacheMemoryUsageMap: c2, - policyd: pdm, - disablePolicyd: false, - roleProcessor: rpm, - resourcePrefix: "/public", - cacheMemoryUsage: &atomic.Int64{}, + cache: c, + policyd: pdm, + disablePolicyd: false, + roleProcessor: rpm, + resourcePrefix: "/public", + cacheMemoryUsage: &atomic.Int64{}, }, args: args{ m: roleToken, @@ -1325,7 +1290,6 @@ func Test_authorizer_authorize(t *testing.T) { client: tt.fields.client, cache: tt.fields.cache, cacheExp: tt.fields.cacheExp, - cacheMemoryUsageMap: tt.fields.cacheMemoryUsageMap, roleCertURIPrefix: tt.fields.roleCertURIPrefix, pubkeyRefreshPeriod: tt.fields.pubkeyRefreshPeriod, pubkeySysAuthDomain: tt.fields.pubkeySysAuthDomain, @@ -1362,7 +1326,8 @@ func Test_authorizer_authorize(t *testing.T) { func Test_authorizer_principalCacheMemoryUsage(t *testing.T) { type args struct { - p Principal + key string + p Principal } type test struct { name string @@ -1388,9 +1353,10 @@ func Test_authorizer_principalCacheMemoryUsage(t *testing.T) { return test{ name: "principalCacheMemoryUsage return correct principal memory usage for role token", args: args{ - p: pc, + key: "dummyKey", + p: pc, }, - want: 162, + want: 170, } }(), func() test { @@ -1416,15 +1382,16 @@ func Test_authorizer_principalCacheMemoryUsage(t *testing.T) { return test{ name: "principalCacheMemoryUsage return correct principal memory usage for access token", args: args{ - p: pc, + key: "dummyKey", + p: pc, }, - want: 158, + want: 166, } }(), } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got := principalCacheMemoryUsage(tt.args.p) + got := principalCacheMemoryUsage(tt.args.key, tt.args.p) if !reflect.DeepEqual(got, tt.want) { t.Errorf("authorizerd.principalCacheMemoryUsage() = %v, want %v", got, tt.want) } @@ -1828,9 +1795,8 @@ func Test_authorizer_GetPrincipalCacheLen(t *testing.T) { func Test_authorizer_GetPrincipalCacheSize(t *testing.T) { type fields struct { - cache gache.Gache[Principal] - cacheMemoryUsageMap gache.Gache[int64] - cacheMemoryUsage *atomic.Int64 + cache gache.Gache[Principal] + cacheMemoryUsage *atomic.Int64 } type test struct { name string @@ -1840,15 +1806,13 @@ func Test_authorizer_GetPrincipalCacheSize(t *testing.T) { tests := []test{ func() test { c := gache.New[Principal]() - c2 := gache.New[int64]() return test{ name: "GetPrincipalCacheSize return memoryUsage field", fields: fields{ - cache: c, - cacheMemoryUsageMap: c2, - cacheMemoryUsage: &atomic.Int64{}, + cache: c, + cacheMemoryUsage: &atomic.Int64{}, }, - want: int64(c.Size()) + 100 + int64(c2.Size()), + want: int64(c.Size()) + 100, } }(), } @@ -1856,9 +1820,8 @@ func Test_authorizer_GetPrincipalCacheSize(t *testing.T) { t.Run(tt.name, func(t *testing.T) { a := &authority{ - cache: tt.fields.cache, - cacheMemoryUsageMap: tt.fields.cacheMemoryUsageMap, - cacheMemoryUsage: tt.fields.cacheMemoryUsage, + cache: tt.fields.cache, + cacheMemoryUsage: tt.fields.cacheMemoryUsage, } a.cacheMemoryUsage.Store(100) if got := a.GetPrincipalCacheSize(); got != tt.want { @@ -1870,11 +1833,11 @@ func Test_authorizer_GetPrincipalCacheSize(t *testing.T) { func Test_authorizer_cacheExpiredHook(t *testing.T) { type fields struct { - ctx context.Context - key string - cache gache.Gache[Principal] - cacheMemoryUsageMap gache.Gache[int64] - cacheMemoryUsage *atomic.Int64 + ctx context.Context + key string + pc *principal + cache gache.Gache[Principal] + cacheMemoryUsage *atomic.Int64 } type test struct { name string @@ -1884,7 +1847,6 @@ func Test_authorizer_cacheExpiredHook(t *testing.T) { tests := []test{ func() test { c := gache.New[Principal]() - c2 := gache.New[int64]() rt := &role.Token{ Principal: "dummyPrincipal", @@ -1902,18 +1864,17 @@ func Test_authorizer_cacheExpiredHook(t *testing.T) { } key := "key" c.Set(key, pc) - cacheUsage := principalCacheMemoryUsage(pc) + cacheUsage := principalCacheMemoryUsage(key, pc) cacheMemoryUsage := &atomic.Int64{} cacheMemoryUsage.Add(cacheUsage) - c2.Set(key, cacheUsage) return test{ - name: "cacheExpiredHook updating cacheMemoryUsage and removing cacheMemoryUsageMap", + name: "cacheExpiredHook updating cacheMemoryUsage", fields: fields{ - ctx: context.Background(), - key: key, - cache: c, - cacheMemoryUsageMap: c2, - cacheMemoryUsage: cacheMemoryUsage, + ctx: context.Background(), + key: key, + pc: pc, + cache: c, + cacheMemoryUsage: cacheMemoryUsage, }, want: 0, } @@ -1923,11 +1884,10 @@ func Test_authorizer_cacheExpiredHook(t *testing.T) { t.Run(tt.name, func(t *testing.T) { a := &authority{ - cache: tt.fields.cache, - cacheMemoryUsageMap: tt.fields.cacheMemoryUsageMap, - cacheMemoryUsage: tt.fields.cacheMemoryUsage, + cache: tt.fields.cache, + cacheMemoryUsage: tt.fields.cacheMemoryUsage, } - a.cacheExpiredHook(tt.fields.ctx, tt.fields.key) + a.cacheExpiredHook(tt.fields.ctx, tt.fields.key, tt.fields.pc) got := a.cacheMemoryUsage.Load() if got != tt.want { t.Errorf("authority.cacheExpiredHook() = %v, want %v", got, tt.want) @@ -2026,12 +1986,11 @@ func Test_authorizer_Authorize(t *testing.T) { func Test_authorizer_AuthorizeAccessToken(t *testing.T) { type fields struct { - policyd policy.Daemon - accessProcessor access.Processor - cache gache.Gache[Principal] - cacheMemoryUsageMap gache.Gache[int64] - cacheExp time.Duration - cacheMemoryUsage *atomic.Int64 + policyd policy.Daemon + accessProcessor access.Processor + cache gache.Gache[Principal] + cacheExp time.Duration + cacheMemoryUsage *atomic.Int64 } type args struct { ctx context.Context @@ -2052,7 +2011,6 @@ func Test_authorizer_AuthorizeAccessToken(t *testing.T) { func() test { now := fastime.Now() c := gache.New[Principal]() - c2 := gache.New[int64]() at := &access.OAuth2AccessTokenClaim{ Scope: []string{"role"}, BaseClaim: access.BaseClaim{ @@ -2093,12 +2051,11 @@ func Test_authorizer_AuthorizeAccessToken(t *testing.T) { res: "dummyRes", }, fields: fields{ - policyd: pdm, - accessProcessor: apm, - cache: c, - cacheExp: time.Minute, - cacheMemoryUsageMap: c2, - cacheMemoryUsage: &atomic.Int64{}, + policyd: pdm, + accessProcessor: apm, + cache: c, + cacheExp: time.Minute, + cacheMemoryUsage: &atomic.Int64{}, }, wantErr: "", wantResult: p, @@ -2118,7 +2075,6 @@ func Test_authorizer_AuthorizeAccessToken(t *testing.T) { func() test { now := fastime.Now() c := gache.New[Principal]() - c2 := gache.New[int64]() at := &access.OAuth2AccessTokenClaim{ Scope: []string{"role"}, BaseClaim: access.BaseClaim{ @@ -2168,12 +2124,11 @@ func Test_authorizer_AuthorizeAccessToken(t *testing.T) { cert: cert, }, fields: fields{ - policyd: pdm, - accessProcessor: apm, - cache: c, - cacheMemoryUsageMap: c2, - cacheExp: time.Minute, - cacheMemoryUsage: &atomic.Int64{}, + policyd: pdm, + accessProcessor: apm, + cache: c, + cacheExp: time.Minute, + cacheMemoryUsage: &atomic.Int64{}, }, wantErr: "", wantResult: p, @@ -2193,7 +2148,6 @@ func Test_authorizer_AuthorizeAccessToken(t *testing.T) { func() test { now := fastime.Now() c := gache.New[Principal]() - c2 := gache.New[int64]() at := &access.OAuth2AccessTokenClaim{} p := &oAuthAccessToken{ principal: principal{ @@ -2227,11 +2181,10 @@ func Test_authorizer_AuthorizeAccessToken(t *testing.T) { res: "dummyRes", }, fields: fields{ - policyd: pdm, - accessProcessor: apm, - cache: c, - cacheExp: time.Minute, - cacheMemoryUsageMap: c2, + policyd: pdm, + accessProcessor: apm, + cache: c, + cacheExp: time.Minute, }, wantErr: "", wantResult: p, @@ -2259,7 +2212,6 @@ func Test_authorizer_AuthorizeAccessToken(t *testing.T) { }, } c := gache.New[Principal]() - c2 := gache.New[int64]() at := &access.OAuth2AccessTokenClaim{} p := &oAuthAccessToken{ principal: principal{ @@ -2294,11 +2246,10 @@ func Test_authorizer_AuthorizeAccessToken(t *testing.T) { cert: cert, }, fields: fields{ - policyd: pdm, - accessProcessor: apm, - cache: c, - cacheExp: time.Minute, - cacheMemoryUsageMap: c2, + policyd: pdm, + accessProcessor: apm, + cache: c, + cacheExp: time.Minute, }, wantErr: "", wantResult: p, @@ -2317,7 +2268,6 @@ func Test_authorizer_AuthorizeAccessToken(t *testing.T) { }(), func() test { c := gache.New[Principal]() - c2 := gache.New[int64]() c.Set("dummyTok:dummyAct:dummyRes", &principal{}) apm := &AccessProcessorMock{ atc: &access.OAuth2AccessTokenClaim{}, @@ -2333,18 +2283,16 @@ func Test_authorizer_AuthorizeAccessToken(t *testing.T) { res: "dummyRes", }, fields: fields{ - policyd: pdm, - accessProcessor: apm, - cache: c, - cacheExp: time.Minute, - cacheMemoryUsageMap: c2, + policyd: pdm, + accessProcessor: apm, + cache: c, + cacheExp: time.Minute, }, wantErr: "empty action / resource: Access denied due to invalid/empty action/resource values", } }(), func() test { c := gache.New[Principal]() - c2 := gache.New[int64]() c.Set("dummyTok:dummyAct:dummyRes", &principal{}) apm := &AccessProcessorMock{ atc: &access.OAuth2AccessTokenClaim{}, @@ -2360,18 +2308,16 @@ func Test_authorizer_AuthorizeAccessToken(t *testing.T) { res: "", }, fields: fields{ - policyd: pdm, - accessProcessor: apm, - cache: c, - cacheExp: time.Minute, - cacheMemoryUsageMap: c2, + policyd: pdm, + accessProcessor: apm, + cache: c, + cacheExp: time.Minute, }, wantErr: "empty action / resource: Access denied due to invalid/empty action/resource values", } }(), func() test { c := gache.New[Principal]() - c2 := gache.New[int64]() apm := &AccessProcessorMock{ wantErr: errors.New("cannot parse access token"), } @@ -2385,18 +2331,16 @@ func Test_authorizer_AuthorizeAccessToken(t *testing.T) { res: "dummyRes", }, fields: fields{ - policyd: pdm, - accessProcessor: apm, - cache: c, - cacheExp: time.Minute, - cacheMemoryUsageMap: c2, + policyd: pdm, + accessProcessor: apm, + cache: c, + cacheExp: time.Minute, }, wantErr: "error authorize access token: cannot parse access token", } }(), func() test { c := gache.New[Principal]() - c2 := gache.New[int64]() apm := &AccessProcessorMock{ atc: &access.OAuth2AccessTokenClaim{}, } @@ -2414,11 +2358,10 @@ func Test_authorizer_AuthorizeAccessToken(t *testing.T) { res: "dummyRes", }, fields: fields{ - policyd: pdm, - accessProcessor: apm, - cache: c, - cacheExp: time.Minute, - cacheMemoryUsageMap: c2, + policyd: pdm, + accessProcessor: apm, + cache: c, + cacheExp: time.Minute, }, wantErr: "token unauthorized: deny", } @@ -2434,7 +2377,6 @@ func Test_authorizer_AuthorizeAccessToken(t *testing.T) { }, } c := gache.New[Principal]() - c2 := gache.New[int64]() at := &access.OAuth2AccessTokenClaim{ Scope: []string{"role"}, BaseClaim: access.BaseClaim{ @@ -2477,12 +2419,11 @@ func Test_authorizer_AuthorizeAccessToken(t *testing.T) { // no cert }, fields: fields{ - policyd: pdm, - accessProcessor: apm, - cache: c, - cacheExp: time.Minute, - cacheMemoryUsageMap: c2, - cacheMemoryUsage: &atomic.Int64{}, + policyd: pdm, + accessProcessor: apm, + cache: c, + cacheExp: time.Minute, + cacheMemoryUsage: &atomic.Int64{}, }, wantErr: "", wantResult: p, @@ -2509,7 +2450,6 @@ func Test_authorizer_AuthorizeAccessToken(t *testing.T) { }, } c := gache.New[Principal]() - c2 := gache.New[int64]() at := &access.OAuth2AccessTokenClaim{} p := &oAuthAccessToken{ principal: principal{ @@ -2537,11 +2477,10 @@ func Test_authorizer_AuthorizeAccessToken(t *testing.T) { // no cert }, fields: fields{ - policyd: pdm, - accessProcessor: apm, - cache: c, - cacheExp: time.Minute, - cacheMemoryUsageMap: c2, + policyd: pdm, + accessProcessor: apm, + cache: c, + cacheExp: time.Minute, }, wantErr: "error authorize access token: error mTLS client certificate is nil", } @@ -2550,12 +2489,11 @@ func Test_authorizer_AuthorizeAccessToken(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { a := &authority{ - policyd: tt.fields.policyd, - accessProcessor: tt.fields.accessProcessor, - cache: tt.fields.cache, - cacheExp: tt.fields.cacheExp, - cacheMemoryUsageMap: tt.fields.cacheMemoryUsageMap, - cacheMemoryUsage: tt.fields.cacheMemoryUsage, + policyd: tt.fields.policyd, + accessProcessor: tt.fields.accessProcessor, + cache: tt.fields.cache, + cacheExp: tt.fields.cacheExp, + cacheMemoryUsage: tt.fields.cacheMemoryUsage, } err := a.VerifyAccessToken(tt.args.ctx, tt.args.tok, tt.args.act, tt.args.res, tt.args.cert) if err != nil { diff --git a/go.mod b/go.mod index 9298137..eec54c8 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/golang-jwt/jwt/v4 v4.5.0 github.com/google/go-cmp v0.6.0 github.com/kpango/fastime v1.1.9 - github.com/kpango/gache/v2 v2.0.11 + github.com/kpango/gache/v2 v2.1.0 github.com/kpango/glg v1.6.15 github.com/lestrrat-go/jwx v1.2.26 github.com/pkg/errors v0.9.1 diff --git a/go.sum b/go.sum index 5a0e7b6..56d9881 100644 --- a/go.sum +++ b/go.sum @@ -20,8 +20,8 @@ github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/q github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/kpango/fastime v1.1.9 h1:xVQHcqyPt5M69DyFH7g1EPRns1YQNap9d5eLhl/Jy84= github.com/kpango/fastime v1.1.9/go.mod h1:vyD7FnUn08zxY4b/QFBZVG+9EWMYsNl+QF0uE46urD4= -github.com/kpango/gache/v2 v2.0.11 h1:uyIXOyx47YhE/0cvP2vf/T+ZCauUD8kSKcsl0IhsAjk= -github.com/kpango/gache/v2 v2.0.11/go.mod h1:0YTbg//JH4Zylm/8LNHRaSbiXphcFStdVhiftgVpPds= +github.com/kpango/gache/v2 v2.1.0 h1:QghBsCQFFSGc3cLuD1rpHRy73Pd095hhv3eyxjf7+40= +github.com/kpango/gache/v2 v2.1.0/go.mod h1:0YTbg//JH4Zylm/8LNHRaSbiXphcFStdVhiftgVpPds= github.com/kpango/glg v1.6.15 h1:nw0xSxpSyrDIWHeb3dvnE08PW+SCbK+aYFETT75IeLA= github.com/kpango/glg v1.6.15/go.mod h1:cmsc7Yeu8AS3wHLmN7bhwENXOpxfq+QoqxCIk2FneRk= github.com/lestrrat-go/backoff/v2 v2.0.8 h1:oNb5E5isby2kiro9AgdHLv5N5tint1AnDVVf2E2un5A= diff --git a/policy/daemon.go b/policy/daemon.go index 4bbe917..ab931e5 100644 --- a/policy/daemon.go +++ b/policy/daemon.go @@ -184,7 +184,7 @@ func (p *policyd) Update(ctx context.Context) error { rp.StartExpired(ctx, p.purgePeriod). EnableExpiredHook(). - SetExpiredHook(func(ctx context.Context, key string) { + SetExpiredHook(func(ctx context.Context, key string, v []*Assertion) { // key = :role. fetchAndCachePolicy(ctx, *(p.rolePolicies), p.fetchers[strings.Split(key, ":role.")[0]]) })