From 2864ed0c0e5c3db684697b449aaeec619f7034ff Mon Sep 17 00:00:00 2001 From: Miguel Martinez Date: Sat, 8 Nov 2025 01:07:51 +0100 Subject: [PATCH 1/8] clear goroutines Signed-off-by: Miguel Martinez --- app/controlplane/cmd/main.go | 8 - app/controlplane/cmd/wire.go | 2 +- app/controlplane/cmd/wire_gen.go | 2 +- .../usercontext/apitoken_middleware.go | 1 + .../usercontext/apitoken_middleware_test.go | 8 +- .../internal/usercontext/entities/apitoken.go | 3 + .../pkg/authz/authz_integration_test.go | 91 --- app/controlplane/pkg/authz/authz_test.go | 138 +--- app/controlplane/pkg/authz/enforcer.go | 92 +-- .../pkg/authz/middleware/middleware.go | 44 +- .../pkg/authz/middleware/middleware_test.go | 17 +- app/controlplane/pkg/biz/.mockery.yml | 11 +- app/controlplane/pkg/biz/apitoken.go | 40 +- .../pkg/biz/mocks/APITokenRepo.go | 561 ++++++++++--- .../pkg/biz/mocks/CASBackendRepo.go | 757 +++++++++++++++--- .../pkg/biz/mocks/OrganizationRepo.go | 343 ++++++-- app/controlplane/pkg/biz/mocks_test.go | 399 ++++++++- app/controlplane/pkg/biz/testhelpers/wire.go | 2 +- .../pkg/biz/testhelpers/wire_gen.go | 2 +- app/controlplane/pkg/data/apitoken.go | 5 +- app/controlplane/pkg/data/ent/apitoken.go | 17 + .../pkg/data/ent/apitoken/apitoken.go | 3 + .../pkg/data/ent/apitoken/where.go | 10 + .../pkg/data/ent/apitoken_create.go | 71 ++ .../pkg/data/ent/apitoken_update.go | 60 ++ .../pkg/data/ent/migrate/migrations/atlas.sum | 3 +- .../pkg/data/ent/migrate/schema.go | 9 +- app/controlplane/pkg/data/ent/mutation.go | 92 ++- .../pkg/data/ent/schema/apitoken.go | 4 + go.mod | 2 - go.sum | 4 - 31 files changed, 2122 insertions(+), 679 deletions(-) delete mode 100644 app/controlplane/pkg/authz/authz_integration_test.go diff --git a/app/controlplane/cmd/main.go b/app/controlplane/cmd/main.go index 4963feb7e..2e9595604 100644 --- a/app/controlplane/cmd/main.go +++ b/app/controlplane/cmd/main.go @@ -153,14 +153,6 @@ func main() { app.runsExpirer.Run(ctx, &biz.WorkflowRunExpirerOpts{CheckInterval: 1 * time.Minute, ExpirationWindow: 1 * time.Hour}) // Since policies management is not enabled yet but instead is based on a hardcoded list of permissions - // We'll perform a reconciliation of the policies with the tokens stored in the database on startup - // This will allow us to add more policies in the future and keep backwards compatibility with existing tokens - go func() { - if err := app.tokenAuthSyncer.SyncPolicies(); err != nil { - _ = logger.Log(log.LevelError, "msg", "syncing policies", "error", err) - } - }() - // Sync user access go func() { if err := app.userAccessSyncer.SyncUserAccess(ctx); err != nil { diff --git a/app/controlplane/cmd/wire.go b/app/controlplane/cmd/wire.go index b1730a4d0..eec255a29 100644 --- a/app/controlplane/cmd/wire.go +++ b/app/controlplane/cmd/wire.go @@ -53,7 +53,7 @@ func wireApp(*conf.Bootstrap, credentials.ReaderWriter, log.Logger, sdk.Availabl wire.FieldsOf(new(*conf.Bootstrap), "Server", "Auth", "Data", "CasServer", "ReferrerSharedIndex", "Onboarding", "PrometheusIntegration", "PolicyProviders", "NatsServer", "FederatedAuthentication"), wire.FieldsOf(new(*conf.Data), "Database"), dispatcher.New, - authz.NewDatabaseEnforcer, + authz.NewInMemoryEnforcer, policies.NewRegistry, newApp, newProtoValidator, diff --git a/app/controlplane/cmd/wire_gen.go b/app/controlplane/cmd/wire_gen.go index a18514605..6e745b5b4 100644 --- a/app/controlplane/cmd/wire_gen.go +++ b/app/controlplane/cmd/wire_gen.go @@ -113,7 +113,7 @@ func wireApp(bootstrap *conf.Bootstrap, readerWriter credentials.ReaderWriter, l apiTokenRepo := data.NewAPITokenRepo(dataData, logger) apiTokenJWTConfig := newJWTConfig(auth) config := authzConfig(bootstrap) - enforcer, err := authz.NewDatabaseEnforcer(databaseConfig, config) + enforcer, err := authz.NewInMemoryEnforcer(config) if err != nil { cleanup() return nil, nil, err diff --git a/app/controlplane/internal/usercontext/apitoken_middleware.go b/app/controlplane/internal/usercontext/apitoken_middleware.go index acd997f37..a26dea8e0 100644 --- a/app/controlplane/internal/usercontext/apitoken_middleware.go +++ b/app/controlplane/internal/usercontext/apitoken_middleware.go @@ -202,6 +202,7 @@ func setCurrentOrgAndAPIToken(ctx context.Context, apiTokenUC *biz.APITokenUseCa Token: token.JWT, ProjectID: token.ProjectID, ProjectName: token.ProjectName, + Policies: token.Policies, }) // Set the authorization subject that will be used to check the policies diff --git a/app/controlplane/internal/usercontext/apitoken_middleware_test.go b/app/controlplane/internal/usercontext/apitoken_middleware_test.go index 8e3914bd0..cae733ac2 100644 --- a/app/controlplane/internal/usercontext/apitoken_middleware_test.go +++ b/app/controlplane/internal/usercontext/apitoken_middleware_test.go @@ -1,5 +1,5 @@ // -// Copyright 2024 The Chainloop Authors. +// Copyright 2024-2025 The Chainloop Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -24,7 +24,7 @@ import ( "github.com/chainloop-dev/chainloop/app/controlplane/internal/usercontext/entities" "github.com/chainloop-dev/chainloop/app/controlplane/pkg/biz" - bizMocks "github.com/chainloop-dev/chainloop/app/controlplane/pkg/biz/mocks" + "github.com/chainloop-dev/chainloop/app/controlplane/pkg/biz/mocks" "github.com/chainloop-dev/chainloop/app/controlplane/pkg/jwt/apitoken" "github.com/go-kratos/kratos/v2/log" jwtmiddleware "github.com/go-kratos/kratos/v2/middleware/auth/jwt" @@ -97,8 +97,8 @@ func TestWithCurrentAPITokenAndOrgMiddleware(t *testing.T) { wantToken := &biz.APIToken{ID: uuid.New(), OrganizationID: wantOrgID} t.Run(tc.name, func(t *testing.T) { - apiTokenRepo := bizMocks.NewAPITokenRepo(t) - orgRepo := bizMocks.NewOrganizationRepo(t) + apiTokenRepo := mocks.NewAPITokenRepo(t) + orgRepo := mocks.NewOrganizationRepo(t) apiTokenUC, err := biz.NewAPITokenUseCase(apiTokenRepo, &biz.APITokenJWTConfig{SymmetricHmacKey: "test"}, nil, nil, nil, nil) require.NoError(t, err) orgUC := biz.NewOrganizationUseCase(orgRepo, nil, nil, nil, nil, nil, nil) diff --git a/app/controlplane/internal/usercontext/entities/apitoken.go b/app/controlplane/internal/usercontext/entities/apitoken.go index efdab169e..45638db5e 100644 --- a/app/controlplane/internal/usercontext/entities/apitoken.go +++ b/app/controlplane/internal/usercontext/entities/apitoken.go @@ -19,6 +19,7 @@ import ( "context" "time" + "github.com/chainloop-dev/chainloop/app/controlplane/pkg/authz" "github.com/google/uuid" ) @@ -30,6 +31,8 @@ type APIToken struct { Token string ProjectID *uuid.UUID ProjectName *string + // ACL policies for this token. Used for authorization checks. + Policies []*authz.Policy } func WithCurrentAPIToken(ctx context.Context, token *APIToken) context.Context { diff --git a/app/controlplane/pkg/authz/authz_integration_test.go b/app/controlplane/pkg/authz/authz_integration_test.go deleted file mode 100644 index b661c58b3..000000000 --- a/app/controlplane/pkg/authz/authz_integration_test.go +++ /dev/null @@ -1,91 +0,0 @@ -// -// Copyright 2024 The Chainloop Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package authz_test - -import ( - "fmt" - "testing" - "time" - - "github.com/cenkalti/backoff/v4" - "github.com/chainloop-dev/chainloop/app/controlplane/pkg/authz" - "github.com/chainloop-dev/chainloop/app/controlplane/pkg/biz/testhelpers" - "github.com/google/uuid" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestMultiReplicaPropagation(t *testing.T) { - // Create two enforcers that share the same database - db := testhelpers.NewTestDatabase(t) - defer db.Close(t) - - enforcerA, err := authz.NewDatabaseEnforcer(testhelpers.NewDataConfig(testhelpers.NewConfData(db, t)), &authz.Config{}) - require.NoError(t, err) - enforcerB, err := authz.NewDatabaseEnforcer(testhelpers.NewDataConfig(testhelpers.NewConfData(db, t)), &authz.Config{}) - require.NoError(t, err) - - // Subject and policies to add - sub := &authz.SubjectAPIToken{ID: uuid.NewString()} - want := []*authz.Policy{authz.PolicyWorkflowContractList, authz.PolicyWorkflowContractRead} - - // Create policies in one enforcer - err = enforcerA.AddPolicies(sub, want...) - require.NoError(t, err) - - // Make sure it propagates to the other one - got, err := enforcerA.GetFilteredPolicy(0, sub.String()) - require.NoError(t, err) - assert.Len(t, got, 2) - - // it might take a bit for the policies to propagate to the other enforcer - err = fnWithRetry(func() error { - got, err = enforcerB.GetFilteredPolicy(0, sub.String()) - require.NoError(t, err) - if len(got) == 2 { - return nil - } - return fmt.Errorf("policies not propagated yet") - }) - require.NoError(t, err) - assert.Len(t, got, 2) - - // Then delete them from the second one and check propagation again - require.NoError(t, enforcerB.ClearPolicies(sub)) - got, err = enforcerB.GetFilteredPolicy(0, sub.String()) - require.NoError(t, err) - assert.Len(t, got, 0) - - // Make sure it propagates to the other one - err = fnWithRetry(func() error { - got, err = enforcerA.GetFilteredPolicy(0, sub.String()) - require.NoError(t, err) - if len(got) == 0 { - return nil - } - - return fmt.Errorf("policies not propagated yet") - }) - require.NoError(t, err) - got, err = enforcerA.GetFilteredPolicy(0, sub.String()) - require.NoError(t, err) - assert.Len(t, got, 0) -} - -func fnWithRetry(f func() error) error { - // Max 1 seconds - return backoff.Retry(f, backoff.WithMaxRetries(backoff.NewConstantBackOff(100*time.Millisecond), 10)) -} diff --git a/app/controlplane/pkg/authz/authz_test.go b/app/controlplane/pkg/authz/authz_test.go index 1043fe31e..81bad1954 100644 --- a/app/controlplane/pkg/authz/authz_test.go +++ b/app/controlplane/pkg/authz/authz_test.go @@ -1,5 +1,5 @@ // -// Copyright 2024 The Chainloop Authors. +// Copyright 2024-2025 The Chainloop Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,92 +16,14 @@ package authz import ( - "fmt" "io" "os" "testing" - "github.com/google/uuid" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) -func TestAddPolicies(t *testing.T) { - testcases := []struct { - name string - subject *SubjectAPIToken - policies []*Policy - wantErr bool - wantNumberPolicies int - }{ - { - name: "empty policies and subject", - wantErr: true, - }, - { - name: "no subject", - policies: []*Policy{ - PolicyWorkflowContractList, - }, - wantErr: true, - }, - { - name: "no policies", - subject: &SubjectAPIToken{ID: uuid.NewString()}, - wantErr: true, - }, - { - name: "adds two policies", - subject: &SubjectAPIToken{ID: uuid.NewString()}, - policies: []*Policy{ - PolicyWorkflowContractList, - PolicyReferrerRead, - }, - wantNumberPolicies: 2, - }, - { - name: "handles duplicated policies", - subject: &SubjectAPIToken{ - ID: uuid.NewString(), - }, - policies: []*Policy{ - PolicyWorkflowContractList, - PolicyWorkflowContractRead, - PolicyWorkflowContractUpdate, - PolicyWorkflowContractList, - PolicyArtifactDownload, - PolicyWorkflowContractUpdate, - PolicyArtifactDownload, - }, - wantNumberPolicies: 4, - }, - } - - for _, tc := range testcases { - t.Run(tc.name, func(t *testing.T) { - enforcer, closer := testEnforcer(t) - closer.Close() - - err := enforcer.AddPolicies(tc.subject, tc.policies...) - if tc.wantErr { - assert.Error(t, err) - return - } - - require.NoError(t, err) - - for _, p := range tc.policies { - ok, err := enforcer.HasPolicy(tc.subject.String(), p.Resource, p.Action) - assert.NoError(t, err) - assert.True(t, ok, fmt.Sprintf("policy %s:%s not found", p.Resource, p.Action)) - } - - gotLength, err := enforcer.GetFilteredPolicy(0, tc.subject.String()) - assert.NoError(t, err) - assert.Len(t, gotLength, tc.wantNumberPolicies) - }) - } -} // simulate 2 enforcers on the same database (by acting on the same file enforcer) func TestSyncMultipleEnforcers(t *testing.T) { @@ -219,31 +141,6 @@ func TestSyncMultipleEnforcers(t *testing.T) { } } -func TestAddPoliciesDuplication(t *testing.T) { - want := []*Policy{ - PolicyWorkflowContractList, - PolicyWorkflowContractRead, - } - - enforcer, closer := testEnforcer(t) - defer closer.Close() - sub := &SubjectAPIToken{ID: uuid.NewString()} - - err := enforcer.AddPolicies(sub, want...) - require.NoError(t, err) - got, err := enforcer.GetFilteredPolicy(0, sub.String()) - require.NoError(t, err) - assert.Len(t, got, 2) - - // Update the list of policies we want to add by appending an extra one - want = append(want, PolicyWorkflowContractUpdate) - // AddPolicies only add the policies that are not already present preventing duplication - err = enforcer.AddPolicies(sub, want...) - assert.NoError(t, err) - got, err = enforcer.GetFilteredPolicy(0, sub.String()) - assert.NoError(t, err) - assert.Len(t, got, 3) -} func TestSyncRBACRoles(t *testing.T) { e, closer := testEnforcer(t) @@ -346,39 +243,6 @@ func TestDoSync(t *testing.T) { assert.Len(t, got, 2) } -func TestClearPolicies(t *testing.T) { - want := []*Policy{ - PolicyWorkflowContractList, - PolicyWorkflowContractRead, - } - - enforcer, closer := testEnforcer(t) - defer closer.Close() - sub := &SubjectAPIToken{ID: uuid.NewString()} - sub2 := &SubjectAPIToken{ID: uuid.NewString()} - - // Create policies for two different subjects - err := enforcer.AddPolicies(sub, want...) - require.NoError(t, err) - err = enforcer.AddPolicies(sub2, want...) - require.NoError(t, err) - // Each have 2 items - got, err := enforcer.GetFilteredPolicy(0, sub.String()) - require.NoError(t, err) - assert.Len(t, got, 2) - - // Clear all the policies for the subject - err = enforcer.ClearPolicies(sub) - assert.NoError(t, err) - // there should be no policies left for this user - got, err = enforcer.GetFilteredPolicy(0, sub.String()) - require.NoError(t, err) - assert.Len(t, got, 0) - // but the other user should still have 2 - got, err = enforcer.GetFilteredPolicy(0, sub2.String()) - require.NoError(t, err) - assert.Len(t, got, 2) -} func testEnforcer(t *testing.T) (*Enforcer, io.Closer) { f, err := os.CreateTemp(t.TempDir(), "policy*.csv") diff --git a/app/controlplane/pkg/authz/enforcer.go b/app/controlplane/pkg/authz/enforcer.go index 109cccdd6..369690db6 100644 --- a/app/controlplane/pkg/authz/enforcer.go +++ b/app/controlplane/pkg/authz/enforcer.go @@ -16,19 +16,14 @@ package authz import ( - "context" _ "embed" - "errors" "fmt" "slices" - psqlwatcher "github.com/IguteChung/casbin-psql-watcher" "github.com/casbin/casbin/v2" "github.com/casbin/casbin/v2/model" "github.com/casbin/casbin/v2/persist" fileadapter "github.com/casbin/casbin/v2/persist/file-adapter" - entadapter "github.com/casbin/ent-adapter" - config "github.com/chainloop-dev/chainloop/app/controlplane/pkg/conf/controlplane/config/v1" ) type SubjectAPIToken struct { @@ -55,81 +50,43 @@ type Enforcer struct { RestrictOrgCreation bool } -func (e *Enforcer) AddPolicies(sub *SubjectAPIToken, policies ...*Policy) error { - if len(policies) == 0 { - return errors.New("no policies to add") - } - - if sub == nil { - return errors.New("no subject provided") - } - - for _, p := range policies { - casbinPolicy := []string{sub.String(), p.Resource, p.Action} - // Add policies one by one to skip existing ones. - // This is because the bulk method AddPoliciesEx does not work well with the ent adapter - if _, err := e.AddPolicy(casbinPolicy); err != nil { - return fmt.Errorf("failed to add policy: %w", err) - } - } - - return nil -} - func (e *Enforcer) Enforce(sub string, p *Policy) (bool, error) { return e.Enforcer.Enforce(sub, p.Resource, p.Action) } -// Remove all the policies for the given subject -func (e *Enforcer) ClearPolicies(sub *SubjectAPIToken) error { - if sub == nil { - return errors.New("no subject provided") - } - - // Get all the policies for the subject - policies, err := e.GetFilteredPolicy(0, sub.String()) - if err != nil { - return fmt.Errorf("failed to get policies: %w", err) - } - - if _, err := e.RemovePolicies(policies); err != nil { - return fmt.Errorf("failed to remove policies: %w", err) +// EnforceWithPolicies checks if the required policy exists in the provided list of allowed policies. +// This is used for ACL-based authorization (e.g., API tokens) where policies are stored in the database +// rather than in Casbin. Returns true if the required policy is found in the allowed list. +func (e *Enforcer) EnforceWithPolicies(sub string, p *Policy, allowedPolicies []*Policy) (bool, error) { + for _, allowed := range allowedPolicies { + if allowed.Resource == p.Resource && allowed.Action == p.Action { + return true, nil + } } - - return nil + return false, nil } -// NewDatabaseEnforcer creates a new casbin authorization enforcer -// based on a database backend as policies storage backend -func NewDatabaseEnforcer(c *config.DatabaseConfig, config *Config) (*Enforcer, error) { - // policy storage in database - a, err := entadapter.NewAdapter(c.Driver, c.Source) +// NewInMemoryEnforcer creates a new casbin authorization enforcer with in-memory storage. +// Only static role policies from RolesMap are loaded. API token policies are checked separately +// using EnforceWithPolicies and are not stored in Casbin. +func NewInMemoryEnforcer(config *Config) (*Enforcer, error) { + // load model defined in model.conf + m, err := model.NewModelFromString(string(modelFile)) if err != nil { - return nil, fmt.Errorf("failed to create adapter: %w", err) + return nil, fmt.Errorf("failed to create model: %w", err) } - e, err := newEnforcer(a, config) + // Create enforcer without a persistent adapter - policies will be stored in memory only + enforcer, err := casbin.NewEnforcer(m) if err != nil { return nil, fmt.Errorf("failed to create enforcer: %w", err) } - // watch for policy changes in database and update enforcer - w, err := psqlwatcher.NewWatcherWithConnString(context.Background(), c.Source, psqlwatcher.Option{}) - if err != nil { - return nil, fmt.Errorf("failed to create watcher: %w", err) - } - - if err = e.SetWatcher(w); err != nil { - return nil, fmt.Errorf("failed to set watcher: %w", err) - } + e := &Enforcer{enforcer, config, config.RestrictOrgCreation} - if err = w.SetUpdateCallback(func(string) { - // When there is a change in the policy, we load the in-memory policy for the current enforcer - if err := e.LoadPolicy(); err != nil { - fmt.Printf("failed to load policy: %v", err) - } - }); err != nil { - return nil, fmt.Errorf("failed to set update callback: %w", err) + // Initialize the enforcer with the roles map + if err := syncRBACRoles(e, config); err != nil { + return nil, fmt.Errorf("failed to sync roles: %w", err) } return e, nil @@ -190,8 +147,7 @@ func doSync(e *Enforcer, c *Config) error { // Add all the defined policies if they don't exist for role, policies := range conf.RolesMap { for _, p := range policies { - // Add policies one by one to skip existing ones. - // This is because the bulk method AddPoliciesEx does not work well with the ent adapter + // Add policies one by one to skip existing ones casbinPolicy := []string{string(role), p.Resource, p.Action} _, err := e.AddPolicy(casbinPolicy) if err != nil { @@ -201,7 +157,7 @@ func doSync(e *Enforcer, c *Config) error { } // Delete all the policies that are not in the roles map - // 1 - load the policies from the enforcer DB + // 1 - load the policies from the enforcer policies, err := e.GetPolicy() if err != nil { return fmt.Errorf("failed to get policies: %w", err) diff --git a/app/controlplane/pkg/authz/middleware/middleware.go b/app/controlplane/pkg/authz/middleware/middleware.go index 10b17637b..b2d31c021 100644 --- a/app/controlplane/pkg/authz/middleware/middleware.go +++ b/app/controlplane/pkg/authz/middleware/middleware.go @@ -19,10 +19,12 @@ import ( "context" "errors" "regexp" + "strings" errorsAPI "github.com/go-kratos/kratos/v2/errors" "github.com/chainloop-dev/chainloop/app/controlplane/internal/usercontext" + "github.com/chainloop-dev/chainloop/app/controlplane/internal/usercontext/entities" "github.com/chainloop-dev/chainloop/app/controlplane/pkg/authz" "github.com/go-kratos/kratos/v2/log" "github.com/go-kratos/kratos/v2/middleware" @@ -31,6 +33,7 @@ import ( type Enforcer interface { Enforce(sub string, p *authz.Policy) (bool, error) + EnforceWithPolicies(sub string, p *authz.Policy, allowedPolicies []*authz.Policy) (bool, error) } // Check Authorization for the current API operation against the current user/token @@ -63,7 +66,7 @@ func WithAuthzMiddleware(enforcer Enforcer, logger *log.Helper) middleware.Middl } // Check the policies for the current API operation - if err := checkPolicies(subject, apiOperation, enforcer, logger); err != nil { + if err := checkPolicies(ctx, subject, apiOperation, enforcer, logger); err != nil { return nil, err } @@ -72,7 +75,7 @@ func WithAuthzMiddleware(enforcer Enforcer, logger *log.Helper) middleware.Middl } } -func checkPolicies(subject, apiOperation string, enforcer Enforcer, logger *log.Helper) error { +func checkPolicies(ctx context.Context, subject, apiOperation string, enforcer Enforcer, logger *log.Helper) error { logger.Infow("msg", "[authZ] checking authorization", "sub", subject, "operation", apiOperation) // If there is no entry in the map for this API operation, we deny access policies, err := policiesLookup(apiOperation) @@ -80,16 +83,37 @@ func checkPolicies(subject, apiOperation string, enforcer Enforcer, logger *log. return errorsAPI.Forbidden("forbidden", err.Error()) } - // Ask AuthZ enforcer if the token meets all the policies defined in the map - for _, p := range policies { - ok, err := enforcer.Enforce(subject, p) - if err != nil { - return errorsAPI.InternalServer("internal error", err.Error()) + // Check if this is an API token (subject starts with "api-token:") + if strings.HasPrefix(subject, "api-token:") { + // For API tokens, use ACL-based enforcement with token's policies + token := entities.CurrentAPIToken(ctx) + if token == nil { + return errorsAPI.InternalServer("internal error", "API token not found in context") } - if !ok { - logger.Infow("msg", "[authZ] policy not found", "sub", subject, "operation", apiOperation, "resource", p.Resource, "action", p.Action) - return errorsAPI.Forbidden("forbidden", "operation not allowed") + for _, p := range policies { + ok, err := enforcer.EnforceWithPolicies(subject, p, token.Policies) + if err != nil { + return errorsAPI.InternalServer("internal error", err.Error()) + } + + if !ok { + logger.Infow("msg", "[authZ] policy not found in token policies", "sub", subject, "operation", apiOperation, "resource", p.Resource, "action", p.Action) + return errorsAPI.Forbidden("forbidden", "operation not allowed") + } + } + } else { + // For users, use role-based enforcement via Casbin + for _, p := range policies { + ok, err := enforcer.Enforce(subject, p) + if err != nil { + return errorsAPI.InternalServer("internal error", err.Error()) + } + + if !ok { + logger.Infow("msg", "[authZ] policy not found", "sub", subject, "operation", apiOperation, "resource", p.Resource, "action", p.Action) + return errorsAPI.Forbidden("forbidden", "operation not allowed") + } } } diff --git a/app/controlplane/pkg/authz/middleware/middleware_test.go b/app/controlplane/pkg/authz/middleware/middleware_test.go index dc5887e0b..e4e7a90b7 100644 --- a/app/controlplane/pkg/authz/middleware/middleware_test.go +++ b/app/controlplane/pkg/authz/middleware/middleware_test.go @@ -1,5 +1,5 @@ // -// Copyright 2024 The Chainloop Authors. +// Copyright 2024-2025 The Chainloop Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -21,8 +21,8 @@ import ( "testing" "github.com/chainloop-dev/chainloop/app/controlplane/internal/usercontext" + "github.com/chainloop-dev/chainloop/app/controlplane/internal/usercontext/entities" "github.com/chainloop-dev/chainloop/app/controlplane/pkg/authz" - "github.com/chainloop-dev/chainloop/app/controlplane/pkg/authz/middleware/mocks" "github.com/go-kratos/kratos/v2/errors" "github.com/go-kratos/kratos/v2/log" "github.com/go-kratos/kratos/v2/transport" @@ -142,13 +142,24 @@ func TestWithAuthMiddleware(t *testing.T) { s := authz.SubjectAPIToken{ID: "deadbeef"} subject = s.String() ctx = usercontext.WithAuthzSubject(ctx, subject) + + // Add API token to context with policies + var policies []*authz.Policy + if tc.hasPermissions { + policies = []*authz.Policy{authz.PolicyWorkflowContractList} + } + ctx = entities.WithCurrentAPIToken(ctx, &entities.APIToken{ + ID: "deadbeef", + Policies: policies, + }) } // Request information ctx = transport.NewServerContext(ctx, &mockTransport{operation: tc.operationName}) - e := mocks.NewEnforcer(t) + e := NewMockEnforcer(t) e.On("Enforce", subject, mock.Anything).Maybe().Return(tc.hasPermissions, nil) + e.On("EnforceWithPolicies", subject, mock.Anything, mock.Anything).Maybe().Return(tc.hasPermissions, nil) m := WithAuthzMiddleware(e, logger) _, err := m(emptyHandler)(ctx, nil) diff --git a/app/controlplane/pkg/biz/.mockery.yml b/app/controlplane/pkg/biz/.mockery.yml index 103d2e709..cc03699e3 100644 --- a/app/controlplane/pkg/biz/.mockery.yml +++ b/app/controlplane/pkg/biz/.mockery.yml @@ -1,18 +1,19 @@ all: false -dir: '{{.InterfaceDir}}' -filename: mocks_test.go -force-file-write: true formatter: goimports include-auto-generated: false log-level: info -structname: '{{.Mock}}{{.InterfaceName}}' -pkgname: '{{.SrcPackageName}}' recursive: false require-template-schema-exists: true template: testify template-schema: '{{.Template}}.schema.json' packages: github.com/chainloop-dev/chainloop/app/controlplane/pkg/biz: + config: + dir: '{{.InterfaceDir}}/mocks' + filename: '{{.InterfaceName}}.go' + pkgname: mocks + structname: '{{.InterfaceName}}' interfaces: APITokenRepo: CASBackendRepo: + OrganizationRepo: diff --git a/app/controlplane/pkg/biz/apitoken.go b/app/controlplane/pkg/biz/apitoken.go index 5b00a1cd1..179e2e993 100644 --- a/app/controlplane/pkg/biz/apitoken.go +++ b/app/controlplane/pkg/biz/apitoken.go @@ -54,10 +54,12 @@ type APIToken struct { // If the token is scoped to a project ProjectID *uuid.UUID ProjectName *string + // ACL policies for this token + Policies []*authz.Policy } type APITokenRepo interface { - Create(ctx context.Context, name string, description *string, expiresAt *time.Time, organizationID uuid.UUID, projectID *uuid.UUID) (*APIToken, error) + Create(ctx context.Context, name string, description *string, expiresAt *time.Time, organizationID uuid.UUID, projectID *uuid.UUID, policies []*authz.Policy) (*APIToken, error) List(ctx context.Context, orgID *uuid.UUID, filters *APITokenListFilters) ([]*APIToken, error) Revoke(ctx context.Context, orgID, ID uuid.UUID) error UpdateExpiration(ctx context.Context, ID uuid.UUID, expiresAt time.Time) error @@ -186,7 +188,8 @@ func (uc *APITokenUseCase) Create(ctx context.Context, name string, description // NOTE: the expiration time is stored just for reference, it's also encoded in the JWT // We store it since Chainloop will not have access to the JWT to check the expiration once created - token, err := uc.apiTokenRepo.Create(ctx, name, description, expiresAt, orgUUID, projectID) + // Pass default policies to be stored with the token + token, err := uc.apiTokenRepo.Create(ctx, name, description, expiresAt, orgUUID, projectID, uc.DefaultAuthzPolicies) if err != nil { if IsErrAlreadyExists(err) { return nil, NewErrAlreadyExistsStr("name already taken") @@ -214,11 +217,6 @@ func (uc *APITokenUseCase) Create(ctx context.Context, name string, description return nil, fmt.Errorf("generating jwt: %w", err) } - // Add default policies to the enforcer - if err := uc.enforcer.AddPolicies(&authz.SubjectAPIToken{ID: token.ID.String()}, uc.DefaultAuthzPolicies...); err != nil { - return nil, fmt.Errorf("adding default policies: %w", err) - } - // Dispatch the event to the auditor to notify the creation of the token uc.auditorUC.Dispatch(ctx, &events.APITokenCreated{ APITokenBase: &events.APITokenBase{ @@ -343,11 +341,6 @@ func (uc *APITokenUseCase) Revoke(ctx context.Context, orgID, id string) error { return NewErrInvalidUUID(err) } - // clean policies - if err := uc.enforcer.ClearPolicies(&authz.SubjectAPIToken{ID: id}); err != nil { - return fmt.Errorf("removing policies: %w", err) - } - token, err := uc.apiTokenRepo.FindByID(ctx, tokenUUID) if err != nil { return fmt.Errorf("finding token: %w", err) @@ -418,29 +411,6 @@ func NewAPITokenSyncerUseCase(tokenUC *APITokenUseCase) *APITokenSyncerUseCase { } } -// Make sure all the API tokens contain the default policies -// NOTE: We'll remove this method once we have a proper policies management system where the user can add/remove policies -func (suc *APITokenSyncerUseCase) SyncPolicies() error { - suc.base.logger.Info("syncing policies for all the API tokens") - - // List all the non-revoked tokens from all the orgs - tokens, err := suc.base.apiTokenRepo.List(context.Background(), nil, nil) - if err != nil { - return fmt.Errorf("listing tokens: %w", err) - } - - for _, t := range tokens { - // Add default policies to the enforcer - if err := suc.base.enforcer.AddPolicies(&authz.SubjectAPIToken{ID: t.ID.String()}, suc.base.DefaultAuthzPolicies...); err != nil { - return fmt.Errorf("adding default policies: %w", err) - } - } - - suc.base.logger.Info("policies synced") - - return nil -} - func (uc *APITokenUseCase) UpdateLastUsedAt(ctx context.Context, tokenID string) error { id, err := uuid.Parse(tokenID) if err != nil { diff --git a/app/controlplane/pkg/biz/mocks/APITokenRepo.go b/app/controlplane/pkg/biz/mocks/APITokenRepo.go index 4d64bfa15..2778cee47 100644 --- a/app/controlplane/pkg/biz/mocks/APITokenRepo.go +++ b/app/controlplane/pkg/biz/mocks/APITokenRepo.go @@ -1,27 +1,49 @@ -// Code generated by mockery v2.53.4. DO NOT EDIT. +// Code generated by mockery; DO NOT EDIT. +// github.com/vektra/mockery +// template: testify package mocks import ( - context "context" - - biz "github.com/chainloop-dev/chainloop/app/controlplane/pkg/biz" + "context" + "time" + "github.com/chainloop-dev/chainloop/app/controlplane/pkg/authz" + "github.com/chainloop-dev/chainloop/app/controlplane/pkg/biz" + "github.com/google/uuid" mock "github.com/stretchr/testify/mock" +) - time "time" +// NewAPITokenRepo creates a new instance of APITokenRepo. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewAPITokenRepo(t interface { + mock.TestingT + Cleanup(func()) +}) *APITokenRepo { + mock := &APITokenRepo{} + mock.Mock.Test(t) - uuid "github.com/google/uuid" -) + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} // APITokenRepo is an autogenerated mock type for the APITokenRepo type type APITokenRepo struct { mock.Mock } -// Create provides a mock function with given fields: ctx, name, description, expiresAt, organizationID, projectID -func (_m *APITokenRepo) Create(ctx context.Context, name string, description *string, expiresAt *time.Time, organizationID uuid.UUID, projectID *uuid.UUID) (*biz.APIToken, error) { - ret := _m.Called(ctx, name, description, expiresAt, organizationID, projectID) +type APITokenRepo_Expecter struct { + mock *mock.Mock +} + +func (_m *APITokenRepo) EXPECT() *APITokenRepo_Expecter { + return &APITokenRepo_Expecter{mock: &_m.Mock} +} + +// Create provides a mock function for the type APITokenRepo +func (_mock *APITokenRepo) Create(ctx context.Context, name string, description *string, expiresAt *time.Time, organizationID uuid.UUID, projectID *uuid.UUID, policies []*authz.Policy) (*biz.APIToken, error) { + ret := _mock.Called(ctx, name, description, expiresAt, organizationID, projectID, policies) if len(ret) == 0 { panic("no return value specified for Create") @@ -29,29 +51,97 @@ func (_m *APITokenRepo) Create(ctx context.Context, name string, description *st var r0 *biz.APIToken var r1 error - if rf, ok := ret.Get(0).(func(context.Context, string, *string, *time.Time, uuid.UUID, *uuid.UUID) (*biz.APIToken, error)); ok { - return rf(ctx, name, description, expiresAt, organizationID, projectID) + if returnFunc, ok := ret.Get(0).(func(context.Context, string, *string, *time.Time, uuid.UUID, *uuid.UUID, []*authz.Policy) (*biz.APIToken, error)); ok { + return returnFunc(ctx, name, description, expiresAt, organizationID, projectID, policies) } - if rf, ok := ret.Get(0).(func(context.Context, string, *string, *time.Time, uuid.UUID, *uuid.UUID) *biz.APIToken); ok { - r0 = rf(ctx, name, description, expiresAt, organizationID, projectID) + if returnFunc, ok := ret.Get(0).(func(context.Context, string, *string, *time.Time, uuid.UUID, *uuid.UUID, []*authz.Policy) *biz.APIToken); ok { + r0 = returnFunc(ctx, name, description, expiresAt, organizationID, projectID, policies) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*biz.APIToken) } } - - if rf, ok := ret.Get(1).(func(context.Context, string, *string, *time.Time, uuid.UUID, *uuid.UUID) error); ok { - r1 = rf(ctx, name, description, expiresAt, organizationID, projectID) + if returnFunc, ok := ret.Get(1).(func(context.Context, string, *string, *time.Time, uuid.UUID, *uuid.UUID, []*authz.Policy) error); ok { + r1 = returnFunc(ctx, name, description, expiresAt, organizationID, projectID, policies) } else { r1 = ret.Error(1) } - return r0, r1 } -// FindByID provides a mock function with given fields: ctx, ID -func (_m *APITokenRepo) FindByID(ctx context.Context, ID uuid.UUID) (*biz.APIToken, error) { - ret := _m.Called(ctx, ID) +// APITokenRepo_Create_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Create' +type APITokenRepo_Create_Call struct { + *mock.Call +} + +// Create is a helper method to define mock.On call +// - ctx context.Context +// - name string +// - description *string +// - expiresAt *time.Time +// - organizationID uuid.UUID +// - projectID *uuid.UUID +// - policies []*authz.Policy +func (_e *APITokenRepo_Expecter) Create(ctx interface{}, name interface{}, description interface{}, expiresAt interface{}, organizationID interface{}, projectID interface{}, policies interface{}) *APITokenRepo_Create_Call { + return &APITokenRepo_Create_Call{Call: _e.mock.On("Create", ctx, name, description, expiresAt, organizationID, projectID, policies)} +} + +func (_c *APITokenRepo_Create_Call) Run(run func(ctx context.Context, name string, description *string, expiresAt *time.Time, organizationID uuid.UUID, projectID *uuid.UUID, policies []*authz.Policy)) *APITokenRepo_Create_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + var arg2 *string + if args[2] != nil { + arg2 = args[2].(*string) + } + var arg3 *time.Time + if args[3] != nil { + arg3 = args[3].(*time.Time) + } + var arg4 uuid.UUID + if args[4] != nil { + arg4 = args[4].(uuid.UUID) + } + var arg5 *uuid.UUID + if args[5] != nil { + arg5 = args[5].(*uuid.UUID) + } + var arg6 []*authz.Policy + if args[6] != nil { + arg6 = args[6].([]*authz.Policy) + } + run( + arg0, + arg1, + arg2, + arg3, + arg4, + arg5, + arg6, + ) + }) + return _c +} + +func (_c *APITokenRepo_Create_Call) Return(aPIToken *biz.APIToken, err error) *APITokenRepo_Create_Call { + _c.Call.Return(aPIToken, err) + return _c +} + +func (_c *APITokenRepo_Create_Call) RunAndReturn(run func(ctx context.Context, name string, description *string, expiresAt *time.Time, organizationID uuid.UUID, projectID *uuid.UUID, policies []*authz.Policy) (*biz.APIToken, error)) *APITokenRepo_Create_Call { + _c.Call.Return(run) + return _c +} + +// FindByID provides a mock function for the type APITokenRepo +func (_mock *APITokenRepo) FindByID(ctx context.Context, ID uuid.UUID) (*biz.APIToken, error) { + ret := _mock.Called(ctx, ID) if len(ret) == 0 { panic("no return value specified for FindByID") @@ -59,29 +149,67 @@ func (_m *APITokenRepo) FindByID(ctx context.Context, ID uuid.UUID) (*biz.APITok var r0 *biz.APIToken var r1 error - if rf, ok := ret.Get(0).(func(context.Context, uuid.UUID) (*biz.APIToken, error)); ok { - return rf(ctx, ID) + if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID) (*biz.APIToken, error)); ok { + return returnFunc(ctx, ID) } - if rf, ok := ret.Get(0).(func(context.Context, uuid.UUID) *biz.APIToken); ok { - r0 = rf(ctx, ID) + if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID) *biz.APIToken); ok { + r0 = returnFunc(ctx, ID) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*biz.APIToken) } } - - if rf, ok := ret.Get(1).(func(context.Context, uuid.UUID) error); ok { - r1 = rf(ctx, ID) + if returnFunc, ok := ret.Get(1).(func(context.Context, uuid.UUID) error); ok { + r1 = returnFunc(ctx, ID) } else { r1 = ret.Error(1) } - return r0, r1 } -// FindByIDInOrg provides a mock function with given fields: ctx, orgID, id -func (_m *APITokenRepo) FindByIDInOrg(ctx context.Context, orgID uuid.UUID, id uuid.UUID) (*biz.APIToken, error) { - ret := _m.Called(ctx, orgID, id) +// APITokenRepo_FindByID_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FindByID' +type APITokenRepo_FindByID_Call struct { + *mock.Call +} + +// FindByID is a helper method to define mock.On call +// - ctx context.Context +// - ID uuid.UUID +func (_e *APITokenRepo_Expecter) FindByID(ctx interface{}, ID interface{}) *APITokenRepo_FindByID_Call { + return &APITokenRepo_FindByID_Call{Call: _e.mock.On("FindByID", ctx, ID)} +} + +func (_c *APITokenRepo_FindByID_Call) Run(run func(ctx context.Context, ID uuid.UUID)) *APITokenRepo_FindByID_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 uuid.UUID + if args[1] != nil { + arg1 = args[1].(uuid.UUID) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *APITokenRepo_FindByID_Call) Return(aPIToken *biz.APIToken, err error) *APITokenRepo_FindByID_Call { + _c.Call.Return(aPIToken, err) + return _c +} + +func (_c *APITokenRepo_FindByID_Call) RunAndReturn(run func(ctx context.Context, ID uuid.UUID) (*biz.APIToken, error)) *APITokenRepo_FindByID_Call { + _c.Call.Return(run) + return _c +} + +// FindByIDInOrg provides a mock function for the type APITokenRepo +func (_mock *APITokenRepo) FindByIDInOrg(ctx context.Context, orgID uuid.UUID, id uuid.UUID) (*biz.APIToken, error) { + ret := _mock.Called(ctx, orgID, id) if len(ret) == 0 { panic("no return value specified for FindByIDInOrg") @@ -89,29 +217,73 @@ func (_m *APITokenRepo) FindByIDInOrg(ctx context.Context, orgID uuid.UUID, id u var r0 *biz.APIToken var r1 error - if rf, ok := ret.Get(0).(func(context.Context, uuid.UUID, uuid.UUID) (*biz.APIToken, error)); ok { - return rf(ctx, orgID, id) + if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID, uuid.UUID) (*biz.APIToken, error)); ok { + return returnFunc(ctx, orgID, id) } - if rf, ok := ret.Get(0).(func(context.Context, uuid.UUID, uuid.UUID) *biz.APIToken); ok { - r0 = rf(ctx, orgID, id) + if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID, uuid.UUID) *biz.APIToken); ok { + r0 = returnFunc(ctx, orgID, id) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*biz.APIToken) } } - - if rf, ok := ret.Get(1).(func(context.Context, uuid.UUID, uuid.UUID) error); ok { - r1 = rf(ctx, orgID, id) + if returnFunc, ok := ret.Get(1).(func(context.Context, uuid.UUID, uuid.UUID) error); ok { + r1 = returnFunc(ctx, orgID, id) } else { r1 = ret.Error(1) } - return r0, r1 } -// FindByNameInOrg provides a mock function with given fields: ctx, orgID, name -func (_m *APITokenRepo) FindByNameInOrg(ctx context.Context, orgID uuid.UUID, name string) (*biz.APIToken, error) { - ret := _m.Called(ctx, orgID, name) +// APITokenRepo_FindByIDInOrg_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FindByIDInOrg' +type APITokenRepo_FindByIDInOrg_Call struct { + *mock.Call +} + +// FindByIDInOrg is a helper method to define mock.On call +// - ctx context.Context +// - orgID uuid.UUID +// - id uuid.UUID +func (_e *APITokenRepo_Expecter) FindByIDInOrg(ctx interface{}, orgID interface{}, id interface{}) *APITokenRepo_FindByIDInOrg_Call { + return &APITokenRepo_FindByIDInOrg_Call{Call: _e.mock.On("FindByIDInOrg", ctx, orgID, id)} +} + +func (_c *APITokenRepo_FindByIDInOrg_Call) Run(run func(ctx context.Context, orgID uuid.UUID, id uuid.UUID)) *APITokenRepo_FindByIDInOrg_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 uuid.UUID + if args[1] != nil { + arg1 = args[1].(uuid.UUID) + } + var arg2 uuid.UUID + if args[2] != nil { + arg2 = args[2].(uuid.UUID) + } + run( + arg0, + arg1, + arg2, + ) + }) + return _c +} + +func (_c *APITokenRepo_FindByIDInOrg_Call) Return(aPIToken *biz.APIToken, err error) *APITokenRepo_FindByIDInOrg_Call { + _c.Call.Return(aPIToken, err) + return _c +} + +func (_c *APITokenRepo_FindByIDInOrg_Call) RunAndReturn(run func(ctx context.Context, orgID uuid.UUID, id uuid.UUID) (*biz.APIToken, error)) *APITokenRepo_FindByIDInOrg_Call { + _c.Call.Return(run) + return _c +} + +// FindByNameInOrg provides a mock function for the type APITokenRepo +func (_mock *APITokenRepo) FindByNameInOrg(ctx context.Context, orgID uuid.UUID, name string) (*biz.APIToken, error) { + ret := _mock.Called(ctx, orgID, name) if len(ret) == 0 { panic("no return value specified for FindByNameInOrg") @@ -119,29 +291,73 @@ func (_m *APITokenRepo) FindByNameInOrg(ctx context.Context, orgID uuid.UUID, na var r0 *biz.APIToken var r1 error - if rf, ok := ret.Get(0).(func(context.Context, uuid.UUID, string) (*biz.APIToken, error)); ok { - return rf(ctx, orgID, name) + if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID, string) (*biz.APIToken, error)); ok { + return returnFunc(ctx, orgID, name) } - if rf, ok := ret.Get(0).(func(context.Context, uuid.UUID, string) *biz.APIToken); ok { - r0 = rf(ctx, orgID, name) + if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID, string) *biz.APIToken); ok { + r0 = returnFunc(ctx, orgID, name) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*biz.APIToken) } } - - if rf, ok := ret.Get(1).(func(context.Context, uuid.UUID, string) error); ok { - r1 = rf(ctx, orgID, name) + if returnFunc, ok := ret.Get(1).(func(context.Context, uuid.UUID, string) error); ok { + r1 = returnFunc(ctx, orgID, name) } else { r1 = ret.Error(1) } - return r0, r1 } -// List provides a mock function with given fields: ctx, orgID, filters -func (_m *APITokenRepo) List(ctx context.Context, orgID *uuid.UUID, filters *biz.APITokenListFilters) ([]*biz.APIToken, error) { - ret := _m.Called(ctx, orgID, filters) +// APITokenRepo_FindByNameInOrg_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FindByNameInOrg' +type APITokenRepo_FindByNameInOrg_Call struct { + *mock.Call +} + +// FindByNameInOrg is a helper method to define mock.On call +// - ctx context.Context +// - orgID uuid.UUID +// - name string +func (_e *APITokenRepo_Expecter) FindByNameInOrg(ctx interface{}, orgID interface{}, name interface{}) *APITokenRepo_FindByNameInOrg_Call { + return &APITokenRepo_FindByNameInOrg_Call{Call: _e.mock.On("FindByNameInOrg", ctx, orgID, name)} +} + +func (_c *APITokenRepo_FindByNameInOrg_Call) Run(run func(ctx context.Context, orgID uuid.UUID, name string)) *APITokenRepo_FindByNameInOrg_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 uuid.UUID + if args[1] != nil { + arg1 = args[1].(uuid.UUID) + } + var arg2 string + if args[2] != nil { + arg2 = args[2].(string) + } + run( + arg0, + arg1, + arg2, + ) + }) + return _c +} + +func (_c *APITokenRepo_FindByNameInOrg_Call) Return(aPIToken *biz.APIToken, err error) *APITokenRepo_FindByNameInOrg_Call { + _c.Call.Return(aPIToken, err) + return _c +} + +func (_c *APITokenRepo_FindByNameInOrg_Call) RunAndReturn(run func(ctx context.Context, orgID uuid.UUID, name string) (*biz.APIToken, error)) *APITokenRepo_FindByNameInOrg_Call { + _c.Call.Return(run) + return _c +} + +// List provides a mock function for the type APITokenRepo +func (_mock *APITokenRepo) List(ctx context.Context, orgID *uuid.UUID, filters *biz.APITokenListFilters) ([]*biz.APIToken, error) { + ret := _mock.Called(ctx, orgID, filters) if len(ret) == 0 { panic("no return value specified for List") @@ -149,90 +365,255 @@ func (_m *APITokenRepo) List(ctx context.Context, orgID *uuid.UUID, filters *biz var r0 []*biz.APIToken var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *uuid.UUID, *biz.APITokenListFilters) ([]*biz.APIToken, error)); ok { - return rf(ctx, orgID, filters) + if returnFunc, ok := ret.Get(0).(func(context.Context, *uuid.UUID, *biz.APITokenListFilters) ([]*biz.APIToken, error)); ok { + return returnFunc(ctx, orgID, filters) } - if rf, ok := ret.Get(0).(func(context.Context, *uuid.UUID, *biz.APITokenListFilters) []*biz.APIToken); ok { - r0 = rf(ctx, orgID, filters) + if returnFunc, ok := ret.Get(0).(func(context.Context, *uuid.UUID, *biz.APITokenListFilters) []*biz.APIToken); ok { + r0 = returnFunc(ctx, orgID, filters) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]*biz.APIToken) } } - - if rf, ok := ret.Get(1).(func(context.Context, *uuid.UUID, *biz.APITokenListFilters) error); ok { - r1 = rf(ctx, orgID, filters) + if returnFunc, ok := ret.Get(1).(func(context.Context, *uuid.UUID, *biz.APITokenListFilters) error); ok { + r1 = returnFunc(ctx, orgID, filters) } else { r1 = ret.Error(1) } - return r0, r1 } -// Revoke provides a mock function with given fields: ctx, orgID, ID -func (_m *APITokenRepo) Revoke(ctx context.Context, orgID uuid.UUID, ID uuid.UUID) error { - ret := _m.Called(ctx, orgID, ID) +// APITokenRepo_List_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'List' +type APITokenRepo_List_Call struct { + *mock.Call +} + +// List is a helper method to define mock.On call +// - ctx context.Context +// - orgID *uuid.UUID +// - filters *biz.APITokenListFilters +func (_e *APITokenRepo_Expecter) List(ctx interface{}, orgID interface{}, filters interface{}) *APITokenRepo_List_Call { + return &APITokenRepo_List_Call{Call: _e.mock.On("List", ctx, orgID, filters)} +} + +func (_c *APITokenRepo_List_Call) Run(run func(ctx context.Context, orgID *uuid.UUID, filters *biz.APITokenListFilters)) *APITokenRepo_List_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 *uuid.UUID + if args[1] != nil { + arg1 = args[1].(*uuid.UUID) + } + var arg2 *biz.APITokenListFilters + if args[2] != nil { + arg2 = args[2].(*biz.APITokenListFilters) + } + run( + arg0, + arg1, + arg2, + ) + }) + return _c +} + +func (_c *APITokenRepo_List_Call) Return(aPITokens []*biz.APIToken, err error) *APITokenRepo_List_Call { + _c.Call.Return(aPITokens, err) + return _c +} + +func (_c *APITokenRepo_List_Call) RunAndReturn(run func(ctx context.Context, orgID *uuid.UUID, filters *biz.APITokenListFilters) ([]*biz.APIToken, error)) *APITokenRepo_List_Call { + _c.Call.Return(run) + return _c +} + +// Revoke provides a mock function for the type APITokenRepo +func (_mock *APITokenRepo) Revoke(ctx context.Context, orgID uuid.UUID, ID uuid.UUID) error { + ret := _mock.Called(ctx, orgID, ID) if len(ret) == 0 { panic("no return value specified for Revoke") } var r0 error - if rf, ok := ret.Get(0).(func(context.Context, uuid.UUID, uuid.UUID) error); ok { - r0 = rf(ctx, orgID, ID) + if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID, uuid.UUID) error); ok { + r0 = returnFunc(ctx, orgID, ID) } else { r0 = ret.Error(0) } - return r0 } -// UpdateExpiration provides a mock function with given fields: ctx, ID, expiresAt -func (_m *APITokenRepo) UpdateExpiration(ctx context.Context, ID uuid.UUID, expiresAt time.Time) error { - ret := _m.Called(ctx, ID, expiresAt) +// APITokenRepo_Revoke_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Revoke' +type APITokenRepo_Revoke_Call struct { + *mock.Call +} + +// Revoke is a helper method to define mock.On call +// - ctx context.Context +// - orgID uuid.UUID +// - ID uuid.UUID +func (_e *APITokenRepo_Expecter) Revoke(ctx interface{}, orgID interface{}, ID interface{}) *APITokenRepo_Revoke_Call { + return &APITokenRepo_Revoke_Call{Call: _e.mock.On("Revoke", ctx, orgID, ID)} +} + +func (_c *APITokenRepo_Revoke_Call) Run(run func(ctx context.Context, orgID uuid.UUID, ID uuid.UUID)) *APITokenRepo_Revoke_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 uuid.UUID + if args[1] != nil { + arg1 = args[1].(uuid.UUID) + } + var arg2 uuid.UUID + if args[2] != nil { + arg2 = args[2].(uuid.UUID) + } + run( + arg0, + arg1, + arg2, + ) + }) + return _c +} + +func (_c *APITokenRepo_Revoke_Call) Return(err error) *APITokenRepo_Revoke_Call { + _c.Call.Return(err) + return _c +} + +func (_c *APITokenRepo_Revoke_Call) RunAndReturn(run func(ctx context.Context, orgID uuid.UUID, ID uuid.UUID) error) *APITokenRepo_Revoke_Call { + _c.Call.Return(run) + return _c +} + +// UpdateExpiration provides a mock function for the type APITokenRepo +func (_mock *APITokenRepo) UpdateExpiration(ctx context.Context, ID uuid.UUID, expiresAt time.Time) error { + ret := _mock.Called(ctx, ID, expiresAt) if len(ret) == 0 { panic("no return value specified for UpdateExpiration") } var r0 error - if rf, ok := ret.Get(0).(func(context.Context, uuid.UUID, time.Time) error); ok { - r0 = rf(ctx, ID, expiresAt) + if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID, time.Time) error); ok { + r0 = returnFunc(ctx, ID, expiresAt) } else { r0 = ret.Error(0) } - return r0 } -// UpdateLastUsedAt provides a mock function with given fields: ctx, ID, lastUsedAt -func (_m *APITokenRepo) UpdateLastUsedAt(ctx context.Context, ID uuid.UUID, lastUsedAt time.Time) error { - ret := _m.Called(ctx, ID, lastUsedAt) +// APITokenRepo_UpdateExpiration_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpdateExpiration' +type APITokenRepo_UpdateExpiration_Call struct { + *mock.Call +} + +// UpdateExpiration is a helper method to define mock.On call +// - ctx context.Context +// - ID uuid.UUID +// - expiresAt time.Time +func (_e *APITokenRepo_Expecter) UpdateExpiration(ctx interface{}, ID interface{}, expiresAt interface{}) *APITokenRepo_UpdateExpiration_Call { + return &APITokenRepo_UpdateExpiration_Call{Call: _e.mock.On("UpdateExpiration", ctx, ID, expiresAt)} +} + +func (_c *APITokenRepo_UpdateExpiration_Call) Run(run func(ctx context.Context, ID uuid.UUID, expiresAt time.Time)) *APITokenRepo_UpdateExpiration_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 uuid.UUID + if args[1] != nil { + arg1 = args[1].(uuid.UUID) + } + var arg2 time.Time + if args[2] != nil { + arg2 = args[2].(time.Time) + } + run( + arg0, + arg1, + arg2, + ) + }) + return _c +} + +func (_c *APITokenRepo_UpdateExpiration_Call) Return(err error) *APITokenRepo_UpdateExpiration_Call { + _c.Call.Return(err) + return _c +} + +func (_c *APITokenRepo_UpdateExpiration_Call) RunAndReturn(run func(ctx context.Context, ID uuid.UUID, expiresAt time.Time) error) *APITokenRepo_UpdateExpiration_Call { + _c.Call.Return(run) + return _c +} + +// UpdateLastUsedAt provides a mock function for the type APITokenRepo +func (_mock *APITokenRepo) UpdateLastUsedAt(ctx context.Context, ID uuid.UUID, lastUsedAt time.Time) error { + ret := _mock.Called(ctx, ID, lastUsedAt) if len(ret) == 0 { panic("no return value specified for UpdateLastUsedAt") } var r0 error - if rf, ok := ret.Get(0).(func(context.Context, uuid.UUID, time.Time) error); ok { - r0 = rf(ctx, ID, lastUsedAt) + if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID, time.Time) error); ok { + r0 = returnFunc(ctx, ID, lastUsedAt) } else { r0 = ret.Error(0) } - return r0 } -// NewAPITokenRepo creates a new instance of APITokenRepo. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -// The first argument is typically a *testing.T value. -func NewAPITokenRepo(t interface { - mock.TestingT - Cleanup(func()) -}) *APITokenRepo { - mock := &APITokenRepo{} - mock.Mock.Test(t) +// APITokenRepo_UpdateLastUsedAt_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpdateLastUsedAt' +type APITokenRepo_UpdateLastUsedAt_Call struct { + *mock.Call +} - t.Cleanup(func() { mock.AssertExpectations(t) }) +// UpdateLastUsedAt is a helper method to define mock.On call +// - ctx context.Context +// - ID uuid.UUID +// - lastUsedAt time.Time +func (_e *APITokenRepo_Expecter) UpdateLastUsedAt(ctx interface{}, ID interface{}, lastUsedAt interface{}) *APITokenRepo_UpdateLastUsedAt_Call { + return &APITokenRepo_UpdateLastUsedAt_Call{Call: _e.mock.On("UpdateLastUsedAt", ctx, ID, lastUsedAt)} +} - return mock +func (_c *APITokenRepo_UpdateLastUsedAt_Call) Run(run func(ctx context.Context, ID uuid.UUID, lastUsedAt time.Time)) *APITokenRepo_UpdateLastUsedAt_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 uuid.UUID + if args[1] != nil { + arg1 = args[1].(uuid.UUID) + } + var arg2 time.Time + if args[2] != nil { + arg2 = args[2].(time.Time) + } + run( + arg0, + arg1, + arg2, + ) + }) + return _c +} + +func (_c *APITokenRepo_UpdateLastUsedAt_Call) Return(err error) *APITokenRepo_UpdateLastUsedAt_Call { + _c.Call.Return(err) + return _c +} + +func (_c *APITokenRepo_UpdateLastUsedAt_Call) RunAndReturn(run func(ctx context.Context, ID uuid.UUID, lastUsedAt time.Time) error) *APITokenRepo_UpdateLastUsedAt_Call { + _c.Call.Return(run) + return _c } diff --git a/app/controlplane/pkg/biz/mocks/CASBackendRepo.go b/app/controlplane/pkg/biz/mocks/CASBackendRepo.go index 5f6eaed9e..ad516cfb5 100644 --- a/app/controlplane/pkg/biz/mocks/CASBackendRepo.go +++ b/app/controlplane/pkg/biz/mocks/CASBackendRepo.go @@ -1,25 +1,47 @@ -// Code generated by mockery v2.53.5. DO NOT EDIT. +// Code generated by mockery; DO NOT EDIT. +// github.com/vektra/mockery +// template: testify package mocks import ( - context "context" - - biz "github.com/chainloop-dev/chainloop/app/controlplane/pkg/biz" + "context" + "github.com/chainloop-dev/chainloop/app/controlplane/pkg/biz" + "github.com/google/uuid" mock "github.com/stretchr/testify/mock" - - uuid "github.com/google/uuid" ) +// NewCASBackendRepo creates a new instance of CASBackendRepo. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewCASBackendRepo(t interface { + mock.TestingT + Cleanup(func()) +}) *CASBackendRepo { + mock := &CASBackendRepo{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} + // CASBackendRepo is an autogenerated mock type for the CASBackendRepo type type CASBackendRepo struct { mock.Mock } -// Create provides a mock function with given fields: _a0, _a1 -func (_m *CASBackendRepo) Create(_a0 context.Context, _a1 *biz.CASBackendCreateOpts) (*biz.CASBackend, error) { - ret := _m.Called(_a0, _a1) +type CASBackendRepo_Expecter struct { + mock *mock.Mock +} + +func (_m *CASBackendRepo) EXPECT() *CASBackendRepo_Expecter { + return &CASBackendRepo_Expecter{mock: &_m.Mock} +} + +// Create provides a mock function for the type CASBackendRepo +func (_mock *CASBackendRepo) Create(context1 context.Context, cASBackendCreateOpts *biz.CASBackendCreateOpts) (*biz.CASBackend, error) { + ret := _mock.Called(context1, cASBackendCreateOpts) if len(ret) == 0 { panic("no return value specified for Create") @@ -27,47 +49,124 @@ func (_m *CASBackendRepo) Create(_a0 context.Context, _a1 *biz.CASBackendCreateO var r0 *biz.CASBackend var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *biz.CASBackendCreateOpts) (*biz.CASBackend, error)); ok { - return rf(_a0, _a1) + if returnFunc, ok := ret.Get(0).(func(context.Context, *biz.CASBackendCreateOpts) (*biz.CASBackend, error)); ok { + return returnFunc(context1, cASBackendCreateOpts) } - if rf, ok := ret.Get(0).(func(context.Context, *biz.CASBackendCreateOpts) *biz.CASBackend); ok { - r0 = rf(_a0, _a1) + if returnFunc, ok := ret.Get(0).(func(context.Context, *biz.CASBackendCreateOpts) *biz.CASBackend); ok { + r0 = returnFunc(context1, cASBackendCreateOpts) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*biz.CASBackend) } } - - if rf, ok := ret.Get(1).(func(context.Context, *biz.CASBackendCreateOpts) error); ok { - r1 = rf(_a0, _a1) + if returnFunc, ok := ret.Get(1).(func(context.Context, *biz.CASBackendCreateOpts) error); ok { + r1 = returnFunc(context1, cASBackendCreateOpts) } else { r1 = ret.Error(1) } - return r0, r1 } -// Delete provides a mock function with given fields: ctx, ID -func (_m *CASBackendRepo) Delete(ctx context.Context, ID uuid.UUID) error { - ret := _m.Called(ctx, ID) +// CASBackendRepo_Create_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Create' +type CASBackendRepo_Create_Call struct { + *mock.Call +} + +// Create is a helper method to define mock.On call +// - context1 context.Context +// - cASBackendCreateOpts *biz.CASBackendCreateOpts +func (_e *CASBackendRepo_Expecter) Create(context1 interface{}, cASBackendCreateOpts interface{}) *CASBackendRepo_Create_Call { + return &CASBackendRepo_Create_Call{Call: _e.mock.On("Create", context1, cASBackendCreateOpts)} +} + +func (_c *CASBackendRepo_Create_Call) Run(run func(context1 context.Context, cASBackendCreateOpts *biz.CASBackendCreateOpts)) *CASBackendRepo_Create_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 *biz.CASBackendCreateOpts + if args[1] != nil { + arg1 = args[1].(*biz.CASBackendCreateOpts) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *CASBackendRepo_Create_Call) Return(cASBackend *biz.CASBackend, err error) *CASBackendRepo_Create_Call { + _c.Call.Return(cASBackend, err) + return _c +} + +func (_c *CASBackendRepo_Create_Call) RunAndReturn(run func(context1 context.Context, cASBackendCreateOpts *biz.CASBackendCreateOpts) (*biz.CASBackend, error)) *CASBackendRepo_Create_Call { + _c.Call.Return(run) + return _c +} + +// Delete provides a mock function for the type CASBackendRepo +func (_mock *CASBackendRepo) Delete(ctx context.Context, ID uuid.UUID) error { + ret := _mock.Called(ctx, ID) if len(ret) == 0 { panic("no return value specified for Delete") } var r0 error - if rf, ok := ret.Get(0).(func(context.Context, uuid.UUID) error); ok { - r0 = rf(ctx, ID) + if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID) error); ok { + r0 = returnFunc(ctx, ID) } else { r0 = ret.Error(0) } - return r0 } -// FindByID provides a mock function with given fields: ctx, ID -func (_m *CASBackendRepo) FindByID(ctx context.Context, ID uuid.UUID) (*biz.CASBackend, error) { - ret := _m.Called(ctx, ID) +// CASBackendRepo_Delete_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Delete' +type CASBackendRepo_Delete_Call struct { + *mock.Call +} + +// Delete is a helper method to define mock.On call +// - ctx context.Context +// - ID uuid.UUID +func (_e *CASBackendRepo_Expecter) Delete(ctx interface{}, ID interface{}) *CASBackendRepo_Delete_Call { + return &CASBackendRepo_Delete_Call{Call: _e.mock.On("Delete", ctx, ID)} +} + +func (_c *CASBackendRepo_Delete_Call) Run(run func(ctx context.Context, ID uuid.UUID)) *CASBackendRepo_Delete_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 uuid.UUID + if args[1] != nil { + arg1 = args[1].(uuid.UUID) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *CASBackendRepo_Delete_Call) Return(err error) *CASBackendRepo_Delete_Call { + _c.Call.Return(err) + return _c +} + +func (_c *CASBackendRepo_Delete_Call) RunAndReturn(run func(ctx context.Context, ID uuid.UUID) error) *CASBackendRepo_Delete_Call { + _c.Call.Return(run) + return _c +} + +// FindByID provides a mock function for the type CASBackendRepo +func (_mock *CASBackendRepo) FindByID(ctx context.Context, ID uuid.UUID) (*biz.CASBackend, error) { + ret := _mock.Called(ctx, ID) if len(ret) == 0 { panic("no return value specified for FindByID") @@ -75,29 +174,67 @@ func (_m *CASBackendRepo) FindByID(ctx context.Context, ID uuid.UUID) (*biz.CASB var r0 *biz.CASBackend var r1 error - if rf, ok := ret.Get(0).(func(context.Context, uuid.UUID) (*biz.CASBackend, error)); ok { - return rf(ctx, ID) + if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID) (*biz.CASBackend, error)); ok { + return returnFunc(ctx, ID) } - if rf, ok := ret.Get(0).(func(context.Context, uuid.UUID) *biz.CASBackend); ok { - r0 = rf(ctx, ID) + if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID) *biz.CASBackend); ok { + r0 = returnFunc(ctx, ID) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*biz.CASBackend) } } - - if rf, ok := ret.Get(1).(func(context.Context, uuid.UUID) error); ok { - r1 = rf(ctx, ID) + if returnFunc, ok := ret.Get(1).(func(context.Context, uuid.UUID) error); ok { + r1 = returnFunc(ctx, ID) } else { r1 = ret.Error(1) } - return r0, r1 } -// FindByIDInOrg provides a mock function with given fields: ctx, OrgID, ID -func (_m *CASBackendRepo) FindByIDInOrg(ctx context.Context, OrgID uuid.UUID, ID uuid.UUID) (*biz.CASBackend, error) { - ret := _m.Called(ctx, OrgID, ID) +// CASBackendRepo_FindByID_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FindByID' +type CASBackendRepo_FindByID_Call struct { + *mock.Call +} + +// FindByID is a helper method to define mock.On call +// - ctx context.Context +// - ID uuid.UUID +func (_e *CASBackendRepo_Expecter) FindByID(ctx interface{}, ID interface{}) *CASBackendRepo_FindByID_Call { + return &CASBackendRepo_FindByID_Call{Call: _e.mock.On("FindByID", ctx, ID)} +} + +func (_c *CASBackendRepo_FindByID_Call) Run(run func(ctx context.Context, ID uuid.UUID)) *CASBackendRepo_FindByID_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 uuid.UUID + if args[1] != nil { + arg1 = args[1].(uuid.UUID) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *CASBackendRepo_FindByID_Call) Return(cASBackend *biz.CASBackend, err error) *CASBackendRepo_FindByID_Call { + _c.Call.Return(cASBackend, err) + return _c +} + +func (_c *CASBackendRepo_FindByID_Call) RunAndReturn(run func(ctx context.Context, ID uuid.UUID) (*biz.CASBackend, error)) *CASBackendRepo_FindByID_Call { + _c.Call.Return(run) + return _c +} + +// FindByIDInOrg provides a mock function for the type CASBackendRepo +func (_mock *CASBackendRepo) FindByIDInOrg(ctx context.Context, OrgID uuid.UUID, ID uuid.UUID) (*biz.CASBackend, error) { + ret := _mock.Called(ctx, OrgID, ID) if len(ret) == 0 { panic("no return value specified for FindByIDInOrg") @@ -105,29 +242,73 @@ func (_m *CASBackendRepo) FindByIDInOrg(ctx context.Context, OrgID uuid.UUID, ID var r0 *biz.CASBackend var r1 error - if rf, ok := ret.Get(0).(func(context.Context, uuid.UUID, uuid.UUID) (*biz.CASBackend, error)); ok { - return rf(ctx, OrgID, ID) + if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID, uuid.UUID) (*biz.CASBackend, error)); ok { + return returnFunc(ctx, OrgID, ID) } - if rf, ok := ret.Get(0).(func(context.Context, uuid.UUID, uuid.UUID) *biz.CASBackend); ok { - r0 = rf(ctx, OrgID, ID) + if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID, uuid.UUID) *biz.CASBackend); ok { + r0 = returnFunc(ctx, OrgID, ID) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*biz.CASBackend) } } - - if rf, ok := ret.Get(1).(func(context.Context, uuid.UUID, uuid.UUID) error); ok { - r1 = rf(ctx, OrgID, ID) + if returnFunc, ok := ret.Get(1).(func(context.Context, uuid.UUID, uuid.UUID) error); ok { + r1 = returnFunc(ctx, OrgID, ID) } else { r1 = ret.Error(1) } - return r0, r1 } -// FindByNameInOrg provides a mock function with given fields: ctx, OrgID, name -func (_m *CASBackendRepo) FindByNameInOrg(ctx context.Context, OrgID uuid.UUID, name string) (*biz.CASBackend, error) { - ret := _m.Called(ctx, OrgID, name) +// CASBackendRepo_FindByIDInOrg_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FindByIDInOrg' +type CASBackendRepo_FindByIDInOrg_Call struct { + *mock.Call +} + +// FindByIDInOrg is a helper method to define mock.On call +// - ctx context.Context +// - OrgID uuid.UUID +// - ID uuid.UUID +func (_e *CASBackendRepo_Expecter) FindByIDInOrg(ctx interface{}, OrgID interface{}, ID interface{}) *CASBackendRepo_FindByIDInOrg_Call { + return &CASBackendRepo_FindByIDInOrg_Call{Call: _e.mock.On("FindByIDInOrg", ctx, OrgID, ID)} +} + +func (_c *CASBackendRepo_FindByIDInOrg_Call) Run(run func(ctx context.Context, OrgID uuid.UUID, ID uuid.UUID)) *CASBackendRepo_FindByIDInOrg_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 uuid.UUID + if args[1] != nil { + arg1 = args[1].(uuid.UUID) + } + var arg2 uuid.UUID + if args[2] != nil { + arg2 = args[2].(uuid.UUID) + } + run( + arg0, + arg1, + arg2, + ) + }) + return _c +} + +func (_c *CASBackendRepo_FindByIDInOrg_Call) Return(cASBackend *biz.CASBackend, err error) *CASBackendRepo_FindByIDInOrg_Call { + _c.Call.Return(cASBackend, err) + return _c +} + +func (_c *CASBackendRepo_FindByIDInOrg_Call) RunAndReturn(run func(ctx context.Context, OrgID uuid.UUID, ID uuid.UUID) (*biz.CASBackend, error)) *CASBackendRepo_FindByIDInOrg_Call { + _c.Call.Return(run) + return _c +} + +// FindByNameInOrg provides a mock function for the type CASBackendRepo +func (_mock *CASBackendRepo) FindByNameInOrg(ctx context.Context, OrgID uuid.UUID, name string) (*biz.CASBackend, error) { + ret := _mock.Called(ctx, OrgID, name) if len(ret) == 0 { panic("no return value specified for FindByNameInOrg") @@ -135,29 +316,73 @@ func (_m *CASBackendRepo) FindByNameInOrg(ctx context.Context, OrgID uuid.UUID, var r0 *biz.CASBackend var r1 error - if rf, ok := ret.Get(0).(func(context.Context, uuid.UUID, string) (*biz.CASBackend, error)); ok { - return rf(ctx, OrgID, name) + if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID, string) (*biz.CASBackend, error)); ok { + return returnFunc(ctx, OrgID, name) } - if rf, ok := ret.Get(0).(func(context.Context, uuid.UUID, string) *biz.CASBackend); ok { - r0 = rf(ctx, OrgID, name) + if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID, string) *biz.CASBackend); ok { + r0 = returnFunc(ctx, OrgID, name) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*biz.CASBackend) } } - - if rf, ok := ret.Get(1).(func(context.Context, uuid.UUID, string) error); ok { - r1 = rf(ctx, OrgID, name) + if returnFunc, ok := ret.Get(1).(func(context.Context, uuid.UUID, string) error); ok { + r1 = returnFunc(ctx, OrgID, name) } else { r1 = ret.Error(1) } - return r0, r1 } -// FindDefaultBackend provides a mock function with given fields: ctx, orgID -func (_m *CASBackendRepo) FindDefaultBackend(ctx context.Context, orgID uuid.UUID) (*biz.CASBackend, error) { - ret := _m.Called(ctx, orgID) +// CASBackendRepo_FindByNameInOrg_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FindByNameInOrg' +type CASBackendRepo_FindByNameInOrg_Call struct { + *mock.Call +} + +// FindByNameInOrg is a helper method to define mock.On call +// - ctx context.Context +// - OrgID uuid.UUID +// - name string +func (_e *CASBackendRepo_Expecter) FindByNameInOrg(ctx interface{}, OrgID interface{}, name interface{}) *CASBackendRepo_FindByNameInOrg_Call { + return &CASBackendRepo_FindByNameInOrg_Call{Call: _e.mock.On("FindByNameInOrg", ctx, OrgID, name)} +} + +func (_c *CASBackendRepo_FindByNameInOrg_Call) Run(run func(ctx context.Context, OrgID uuid.UUID, name string)) *CASBackendRepo_FindByNameInOrg_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 uuid.UUID + if args[1] != nil { + arg1 = args[1].(uuid.UUID) + } + var arg2 string + if args[2] != nil { + arg2 = args[2].(string) + } + run( + arg0, + arg1, + arg2, + ) + }) + return _c +} + +func (_c *CASBackendRepo_FindByNameInOrg_Call) Return(cASBackend *biz.CASBackend, err error) *CASBackendRepo_FindByNameInOrg_Call { + _c.Call.Return(cASBackend, err) + return _c +} + +func (_c *CASBackendRepo_FindByNameInOrg_Call) RunAndReturn(run func(ctx context.Context, OrgID uuid.UUID, name string) (*biz.CASBackend, error)) *CASBackendRepo_FindByNameInOrg_Call { + _c.Call.Return(run) + return _c +} + +// FindDefaultBackend provides a mock function for the type CASBackendRepo +func (_mock *CASBackendRepo) FindDefaultBackend(ctx context.Context, orgID uuid.UUID) (*biz.CASBackend, error) { + ret := _mock.Called(ctx, orgID) if len(ret) == 0 { panic("no return value specified for FindDefaultBackend") @@ -165,29 +390,67 @@ func (_m *CASBackendRepo) FindDefaultBackend(ctx context.Context, orgID uuid.UUI var r0 *biz.CASBackend var r1 error - if rf, ok := ret.Get(0).(func(context.Context, uuid.UUID) (*biz.CASBackend, error)); ok { - return rf(ctx, orgID) + if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID) (*biz.CASBackend, error)); ok { + return returnFunc(ctx, orgID) } - if rf, ok := ret.Get(0).(func(context.Context, uuid.UUID) *biz.CASBackend); ok { - r0 = rf(ctx, orgID) + if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID) *biz.CASBackend); ok { + r0 = returnFunc(ctx, orgID) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*biz.CASBackend) } } - - if rf, ok := ret.Get(1).(func(context.Context, uuid.UUID) error); ok { - r1 = rf(ctx, orgID) + if returnFunc, ok := ret.Get(1).(func(context.Context, uuid.UUID) error); ok { + r1 = returnFunc(ctx, orgID) } else { r1 = ret.Error(1) } - return r0, r1 } -// FindFallbackBackend provides a mock function with given fields: ctx, orgID -func (_m *CASBackendRepo) FindFallbackBackend(ctx context.Context, orgID uuid.UUID) (*biz.CASBackend, error) { - ret := _m.Called(ctx, orgID) +// CASBackendRepo_FindDefaultBackend_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FindDefaultBackend' +type CASBackendRepo_FindDefaultBackend_Call struct { + *mock.Call +} + +// FindDefaultBackend is a helper method to define mock.On call +// - ctx context.Context +// - orgID uuid.UUID +func (_e *CASBackendRepo_Expecter) FindDefaultBackend(ctx interface{}, orgID interface{}) *CASBackendRepo_FindDefaultBackend_Call { + return &CASBackendRepo_FindDefaultBackend_Call{Call: _e.mock.On("FindDefaultBackend", ctx, orgID)} +} + +func (_c *CASBackendRepo_FindDefaultBackend_Call) Run(run func(ctx context.Context, orgID uuid.UUID)) *CASBackendRepo_FindDefaultBackend_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 uuid.UUID + if args[1] != nil { + arg1 = args[1].(uuid.UUID) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *CASBackendRepo_FindDefaultBackend_Call) Return(cASBackend *biz.CASBackend, err error) *CASBackendRepo_FindDefaultBackend_Call { + _c.Call.Return(cASBackend, err) + return _c +} + +func (_c *CASBackendRepo_FindDefaultBackend_Call) RunAndReturn(run func(ctx context.Context, orgID uuid.UUID) (*biz.CASBackend, error)) *CASBackendRepo_FindDefaultBackend_Call { + _c.Call.Return(run) + return _c +} + +// FindFallbackBackend provides a mock function for the type CASBackendRepo +func (_mock *CASBackendRepo) FindFallbackBackend(ctx context.Context, orgID uuid.UUID) (*biz.CASBackend, error) { + ret := _mock.Called(ctx, orgID) if len(ret) == 0 { panic("no return value specified for FindFallbackBackend") @@ -195,29 +458,67 @@ func (_m *CASBackendRepo) FindFallbackBackend(ctx context.Context, orgID uuid.UU var r0 *biz.CASBackend var r1 error - if rf, ok := ret.Get(0).(func(context.Context, uuid.UUID) (*biz.CASBackend, error)); ok { - return rf(ctx, orgID) + if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID) (*biz.CASBackend, error)); ok { + return returnFunc(ctx, orgID) } - if rf, ok := ret.Get(0).(func(context.Context, uuid.UUID) *biz.CASBackend); ok { - r0 = rf(ctx, orgID) + if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID) *biz.CASBackend); ok { + r0 = returnFunc(ctx, orgID) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*biz.CASBackend) } } - - if rf, ok := ret.Get(1).(func(context.Context, uuid.UUID) error); ok { - r1 = rf(ctx, orgID) + if returnFunc, ok := ret.Get(1).(func(context.Context, uuid.UUID) error); ok { + r1 = returnFunc(ctx, orgID) } else { r1 = ret.Error(1) } - return r0, r1 } -// List provides a mock function with given fields: ctx, orgID -func (_m *CASBackendRepo) List(ctx context.Context, orgID uuid.UUID) ([]*biz.CASBackend, error) { - ret := _m.Called(ctx, orgID) +// CASBackendRepo_FindFallbackBackend_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FindFallbackBackend' +type CASBackendRepo_FindFallbackBackend_Call struct { + *mock.Call +} + +// FindFallbackBackend is a helper method to define mock.On call +// - ctx context.Context +// - orgID uuid.UUID +func (_e *CASBackendRepo_Expecter) FindFallbackBackend(ctx interface{}, orgID interface{}) *CASBackendRepo_FindFallbackBackend_Call { + return &CASBackendRepo_FindFallbackBackend_Call{Call: _e.mock.On("FindFallbackBackend", ctx, orgID)} +} + +func (_c *CASBackendRepo_FindFallbackBackend_Call) Run(run func(ctx context.Context, orgID uuid.UUID)) *CASBackendRepo_FindFallbackBackend_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 uuid.UUID + if args[1] != nil { + arg1 = args[1].(uuid.UUID) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *CASBackendRepo_FindFallbackBackend_Call) Return(cASBackend *biz.CASBackend, err error) *CASBackendRepo_FindFallbackBackend_Call { + _c.Call.Return(cASBackend, err) + return _c +} + +func (_c *CASBackendRepo_FindFallbackBackend_Call) RunAndReturn(run func(ctx context.Context, orgID uuid.UUID) (*biz.CASBackend, error)) *CASBackendRepo_FindFallbackBackend_Call { + _c.Call.Return(run) + return _c +} + +// List provides a mock function for the type CASBackendRepo +func (_mock *CASBackendRepo) List(ctx context.Context, orgID uuid.UUID) ([]*biz.CASBackend, error) { + ret := _mock.Called(ctx, orgID) if len(ret) == 0 { panic("no return value specified for List") @@ -225,29 +526,67 @@ func (_m *CASBackendRepo) List(ctx context.Context, orgID uuid.UUID) ([]*biz.CAS var r0 []*biz.CASBackend var r1 error - if rf, ok := ret.Get(0).(func(context.Context, uuid.UUID) ([]*biz.CASBackend, error)); ok { - return rf(ctx, orgID) + if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID) ([]*biz.CASBackend, error)); ok { + return returnFunc(ctx, orgID) } - if rf, ok := ret.Get(0).(func(context.Context, uuid.UUID) []*biz.CASBackend); ok { - r0 = rf(ctx, orgID) + if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID) []*biz.CASBackend); ok { + r0 = returnFunc(ctx, orgID) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]*biz.CASBackend) } } - - if rf, ok := ret.Get(1).(func(context.Context, uuid.UUID) error); ok { - r1 = rf(ctx, orgID) + if returnFunc, ok := ret.Get(1).(func(context.Context, uuid.UUID) error); ok { + r1 = returnFunc(ctx, orgID) } else { r1 = ret.Error(1) } - return r0, r1 } -// ListBackends provides a mock function with given fields: ctx, onlyDefaults -func (_m *CASBackendRepo) ListBackends(ctx context.Context, onlyDefaults bool) ([]*biz.CASBackend, error) { - ret := _m.Called(ctx, onlyDefaults) +// CASBackendRepo_List_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'List' +type CASBackendRepo_List_Call struct { + *mock.Call +} + +// List is a helper method to define mock.On call +// - ctx context.Context +// - orgID uuid.UUID +func (_e *CASBackendRepo_Expecter) List(ctx interface{}, orgID interface{}) *CASBackendRepo_List_Call { + return &CASBackendRepo_List_Call{Call: _e.mock.On("List", ctx, orgID)} +} + +func (_c *CASBackendRepo_List_Call) Run(run func(ctx context.Context, orgID uuid.UUID)) *CASBackendRepo_List_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 uuid.UUID + if args[1] != nil { + arg1 = args[1].(uuid.UUID) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *CASBackendRepo_List_Call) Return(cASBackends []*biz.CASBackend, err error) *CASBackendRepo_List_Call { + _c.Call.Return(cASBackends, err) + return _c +} + +func (_c *CASBackendRepo_List_Call) RunAndReturn(run func(ctx context.Context, orgID uuid.UUID) ([]*biz.CASBackend, error)) *CASBackendRepo_List_Call { + _c.Call.Return(run) + return _c +} + +// ListBackends provides a mock function for the type CASBackendRepo +func (_mock *CASBackendRepo) ListBackends(ctx context.Context, onlyDefaults bool) ([]*biz.CASBackend, error) { + ret := _mock.Called(ctx, onlyDefaults) if len(ret) == 0 { panic("no return value specified for ListBackends") @@ -255,47 +594,124 @@ func (_m *CASBackendRepo) ListBackends(ctx context.Context, onlyDefaults bool) ( var r0 []*biz.CASBackend var r1 error - if rf, ok := ret.Get(0).(func(context.Context, bool) ([]*biz.CASBackend, error)); ok { - return rf(ctx, onlyDefaults) + if returnFunc, ok := ret.Get(0).(func(context.Context, bool) ([]*biz.CASBackend, error)); ok { + return returnFunc(ctx, onlyDefaults) } - if rf, ok := ret.Get(0).(func(context.Context, bool) []*biz.CASBackend); ok { - r0 = rf(ctx, onlyDefaults) + if returnFunc, ok := ret.Get(0).(func(context.Context, bool) []*biz.CASBackend); ok { + r0 = returnFunc(ctx, onlyDefaults) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]*biz.CASBackend) } } - - if rf, ok := ret.Get(1).(func(context.Context, bool) error); ok { - r1 = rf(ctx, onlyDefaults) + if returnFunc, ok := ret.Get(1).(func(context.Context, bool) error); ok { + r1 = returnFunc(ctx, onlyDefaults) } else { r1 = ret.Error(1) } - return r0, r1 } -// SoftDelete provides a mock function with given fields: ctx, ID -func (_m *CASBackendRepo) SoftDelete(ctx context.Context, ID uuid.UUID) error { - ret := _m.Called(ctx, ID) +// CASBackendRepo_ListBackends_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ListBackends' +type CASBackendRepo_ListBackends_Call struct { + *mock.Call +} + +// ListBackends is a helper method to define mock.On call +// - ctx context.Context +// - onlyDefaults bool +func (_e *CASBackendRepo_Expecter) ListBackends(ctx interface{}, onlyDefaults interface{}) *CASBackendRepo_ListBackends_Call { + return &CASBackendRepo_ListBackends_Call{Call: _e.mock.On("ListBackends", ctx, onlyDefaults)} +} + +func (_c *CASBackendRepo_ListBackends_Call) Run(run func(ctx context.Context, onlyDefaults bool)) *CASBackendRepo_ListBackends_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 bool + if args[1] != nil { + arg1 = args[1].(bool) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *CASBackendRepo_ListBackends_Call) Return(cASBackends []*biz.CASBackend, err error) *CASBackendRepo_ListBackends_Call { + _c.Call.Return(cASBackends, err) + return _c +} + +func (_c *CASBackendRepo_ListBackends_Call) RunAndReturn(run func(ctx context.Context, onlyDefaults bool) ([]*biz.CASBackend, error)) *CASBackendRepo_ListBackends_Call { + _c.Call.Return(run) + return _c +} + +// SoftDelete provides a mock function for the type CASBackendRepo +func (_mock *CASBackendRepo) SoftDelete(ctx context.Context, ID uuid.UUID) error { + ret := _mock.Called(ctx, ID) if len(ret) == 0 { panic("no return value specified for SoftDelete") } var r0 error - if rf, ok := ret.Get(0).(func(context.Context, uuid.UUID) error); ok { - r0 = rf(ctx, ID) + if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID) error); ok { + r0 = returnFunc(ctx, ID) } else { r0 = ret.Error(0) } - return r0 } -// Update provides a mock function with given fields: _a0, _a1 -func (_m *CASBackendRepo) Update(_a0 context.Context, _a1 *biz.CASBackendUpdateOpts) (*biz.CASBackend, error) { - ret := _m.Called(_a0, _a1) +// CASBackendRepo_SoftDelete_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SoftDelete' +type CASBackendRepo_SoftDelete_Call struct { + *mock.Call +} + +// SoftDelete is a helper method to define mock.On call +// - ctx context.Context +// - ID uuid.UUID +func (_e *CASBackendRepo_Expecter) SoftDelete(ctx interface{}, ID interface{}) *CASBackendRepo_SoftDelete_Call { + return &CASBackendRepo_SoftDelete_Call{Call: _e.mock.On("SoftDelete", ctx, ID)} +} + +func (_c *CASBackendRepo_SoftDelete_Call) Run(run func(ctx context.Context, ID uuid.UUID)) *CASBackendRepo_SoftDelete_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 uuid.UUID + if args[1] != nil { + arg1 = args[1].(uuid.UUID) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *CASBackendRepo_SoftDelete_Call) Return(err error) *CASBackendRepo_SoftDelete_Call { + _c.Call.Return(err) + return _c +} + +func (_c *CASBackendRepo_SoftDelete_Call) RunAndReturn(run func(ctx context.Context, ID uuid.UUID) error) *CASBackendRepo_SoftDelete_Call { + _c.Call.Return(run) + return _c +} + +// Update provides a mock function for the type CASBackendRepo +func (_mock *CASBackendRepo) Update(context1 context.Context, cASBackendUpdateOpts *biz.CASBackendUpdateOpts) (*biz.CASBackend, error) { + ret := _mock.Called(context1, cASBackendUpdateOpts) if len(ret) == 0 { panic("no return value specified for Update") @@ -303,54 +719,129 @@ func (_m *CASBackendRepo) Update(_a0 context.Context, _a1 *biz.CASBackendUpdateO var r0 *biz.CASBackend var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *biz.CASBackendUpdateOpts) (*biz.CASBackend, error)); ok { - return rf(_a0, _a1) + if returnFunc, ok := ret.Get(0).(func(context.Context, *biz.CASBackendUpdateOpts) (*biz.CASBackend, error)); ok { + return returnFunc(context1, cASBackendUpdateOpts) } - if rf, ok := ret.Get(0).(func(context.Context, *biz.CASBackendUpdateOpts) *biz.CASBackend); ok { - r0 = rf(_a0, _a1) + if returnFunc, ok := ret.Get(0).(func(context.Context, *biz.CASBackendUpdateOpts) *biz.CASBackend); ok { + r0 = returnFunc(context1, cASBackendUpdateOpts) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*biz.CASBackend) } } - - if rf, ok := ret.Get(1).(func(context.Context, *biz.CASBackendUpdateOpts) error); ok { - r1 = rf(_a0, _a1) + if returnFunc, ok := ret.Get(1).(func(context.Context, *biz.CASBackendUpdateOpts) error); ok { + r1 = returnFunc(context1, cASBackendUpdateOpts) } else { r1 = ret.Error(1) } - return r0, r1 } -// UpdateValidationStatus provides a mock function with given fields: ctx, ID, status, validationError -func (_m *CASBackendRepo) UpdateValidationStatus(ctx context.Context, ID uuid.UUID, status biz.CASBackendValidationStatus, validationError *string) error { - ret := _m.Called(ctx, ID, status, validationError) +// CASBackendRepo_Update_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Update' +type CASBackendRepo_Update_Call struct { + *mock.Call +} + +// Update is a helper method to define mock.On call +// - context1 context.Context +// - cASBackendUpdateOpts *biz.CASBackendUpdateOpts +func (_e *CASBackendRepo_Expecter) Update(context1 interface{}, cASBackendUpdateOpts interface{}) *CASBackendRepo_Update_Call { + return &CASBackendRepo_Update_Call{Call: _e.mock.On("Update", context1, cASBackendUpdateOpts)} +} + +func (_c *CASBackendRepo_Update_Call) Run(run func(context1 context.Context, cASBackendUpdateOpts *biz.CASBackendUpdateOpts)) *CASBackendRepo_Update_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 *biz.CASBackendUpdateOpts + if args[1] != nil { + arg1 = args[1].(*biz.CASBackendUpdateOpts) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *CASBackendRepo_Update_Call) Return(cASBackend *biz.CASBackend, err error) *CASBackendRepo_Update_Call { + _c.Call.Return(cASBackend, err) + return _c +} + +func (_c *CASBackendRepo_Update_Call) RunAndReturn(run func(context1 context.Context, cASBackendUpdateOpts *biz.CASBackendUpdateOpts) (*biz.CASBackend, error)) *CASBackendRepo_Update_Call { + _c.Call.Return(run) + return _c +} + +// UpdateValidationStatus provides a mock function for the type CASBackendRepo +func (_mock *CASBackendRepo) UpdateValidationStatus(ctx context.Context, ID uuid.UUID, status biz.CASBackendValidationStatus, validationError *string) error { + ret := _mock.Called(ctx, ID, status, validationError) if len(ret) == 0 { panic("no return value specified for UpdateValidationStatus") } var r0 error - if rf, ok := ret.Get(0).(func(context.Context, uuid.UUID, biz.CASBackendValidationStatus, *string) error); ok { - r0 = rf(ctx, ID, status, validationError) + if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID, biz.CASBackendValidationStatus, *string) error); ok { + r0 = returnFunc(ctx, ID, status, validationError) } else { r0 = ret.Error(0) } - return r0 } -// NewCASBackendRepo creates a new instance of CASBackendRepo. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -// The first argument is typically a *testing.T value. -func NewCASBackendRepo(t interface { - mock.TestingT - Cleanup(func()) -}) *CASBackendRepo { - mock := &CASBackendRepo{} - mock.Mock.Test(t) +// CASBackendRepo_UpdateValidationStatus_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpdateValidationStatus' +type CASBackendRepo_UpdateValidationStatus_Call struct { + *mock.Call +} - t.Cleanup(func() { mock.AssertExpectations(t) }) +// UpdateValidationStatus is a helper method to define mock.On call +// - ctx context.Context +// - ID uuid.UUID +// - status biz.CASBackendValidationStatus +// - validationError *string +func (_e *CASBackendRepo_Expecter) UpdateValidationStatus(ctx interface{}, ID interface{}, status interface{}, validationError interface{}) *CASBackendRepo_UpdateValidationStatus_Call { + return &CASBackendRepo_UpdateValidationStatus_Call{Call: _e.mock.On("UpdateValidationStatus", ctx, ID, status, validationError)} +} - return mock +func (_c *CASBackendRepo_UpdateValidationStatus_Call) Run(run func(ctx context.Context, ID uuid.UUID, status biz.CASBackendValidationStatus, validationError *string)) *CASBackendRepo_UpdateValidationStatus_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 uuid.UUID + if args[1] != nil { + arg1 = args[1].(uuid.UUID) + } + var arg2 biz.CASBackendValidationStatus + if args[2] != nil { + arg2 = args[2].(biz.CASBackendValidationStatus) + } + var arg3 *string + if args[3] != nil { + arg3 = args[3].(*string) + } + run( + arg0, + arg1, + arg2, + arg3, + ) + }) + return _c +} + +func (_c *CASBackendRepo_UpdateValidationStatus_Call) Return(err error) *CASBackendRepo_UpdateValidationStatus_Call { + _c.Call.Return(err) + return _c +} + +func (_c *CASBackendRepo_UpdateValidationStatus_Call) RunAndReturn(run func(ctx context.Context, ID uuid.UUID, status biz.CASBackendValidationStatus, validationError *string) error) *CASBackendRepo_UpdateValidationStatus_Call { + _c.Call.Return(run) + return _c } diff --git a/app/controlplane/pkg/biz/mocks/OrganizationRepo.go b/app/controlplane/pkg/biz/mocks/OrganizationRepo.go index dad418d6b..7eb449ef9 100644 --- a/app/controlplane/pkg/biz/mocks/OrganizationRepo.go +++ b/app/controlplane/pkg/biz/mocks/OrganizationRepo.go @@ -1,25 +1,47 @@ -// Code generated by mockery v2.53.4. DO NOT EDIT. +// Code generated by mockery; DO NOT EDIT. +// github.com/vektra/mockery +// template: testify package mocks import ( - context "context" - - biz "github.com/chainloop-dev/chainloop/app/controlplane/pkg/biz" + "context" + "github.com/chainloop-dev/chainloop/app/controlplane/pkg/biz" + "github.com/google/uuid" mock "github.com/stretchr/testify/mock" - - uuid "github.com/google/uuid" ) +// NewOrganizationRepo creates a new instance of OrganizationRepo. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewOrganizationRepo(t interface { + mock.TestingT + Cleanup(func()) +}) *OrganizationRepo { + mock := &OrganizationRepo{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} + // OrganizationRepo is an autogenerated mock type for the OrganizationRepo type type OrganizationRepo struct { mock.Mock } -// Create provides a mock function with given fields: ctx, name -func (_m *OrganizationRepo) Create(ctx context.Context, name string) (*biz.Organization, error) { - ret := _m.Called(ctx, name) +type OrganizationRepo_Expecter struct { + mock *mock.Mock +} + +func (_m *OrganizationRepo) EXPECT() *OrganizationRepo_Expecter { + return &OrganizationRepo_Expecter{mock: &_m.Mock} +} + +// Create provides a mock function for the type OrganizationRepo +func (_mock *OrganizationRepo) Create(ctx context.Context, name string) (*biz.Organization, error) { + ret := _mock.Called(ctx, name) if len(ret) == 0 { panic("no return value specified for Create") @@ -27,47 +49,124 @@ func (_m *OrganizationRepo) Create(ctx context.Context, name string) (*biz.Organ var r0 *biz.Organization var r1 error - if rf, ok := ret.Get(0).(func(context.Context, string) (*biz.Organization, error)); ok { - return rf(ctx, name) + if returnFunc, ok := ret.Get(0).(func(context.Context, string) (*biz.Organization, error)); ok { + return returnFunc(ctx, name) } - if rf, ok := ret.Get(0).(func(context.Context, string) *biz.Organization); ok { - r0 = rf(ctx, name) + if returnFunc, ok := ret.Get(0).(func(context.Context, string) *biz.Organization); ok { + r0 = returnFunc(ctx, name) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*biz.Organization) } } - - if rf, ok := ret.Get(1).(func(context.Context, string) error); ok { - r1 = rf(ctx, name) + if returnFunc, ok := ret.Get(1).(func(context.Context, string) error); ok { + r1 = returnFunc(ctx, name) } else { r1 = ret.Error(1) } - return r0, r1 } -// Delete provides a mock function with given fields: ctx, ID -func (_m *OrganizationRepo) Delete(ctx context.Context, ID uuid.UUID) error { - ret := _m.Called(ctx, ID) +// OrganizationRepo_Create_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Create' +type OrganizationRepo_Create_Call struct { + *mock.Call +} + +// Create is a helper method to define mock.On call +// - ctx context.Context +// - name string +func (_e *OrganizationRepo_Expecter) Create(ctx interface{}, name interface{}) *OrganizationRepo_Create_Call { + return &OrganizationRepo_Create_Call{Call: _e.mock.On("Create", ctx, name)} +} + +func (_c *OrganizationRepo_Create_Call) Run(run func(ctx context.Context, name string)) *OrganizationRepo_Create_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *OrganizationRepo_Create_Call) Return(organization *biz.Organization, err error) *OrganizationRepo_Create_Call { + _c.Call.Return(organization, err) + return _c +} + +func (_c *OrganizationRepo_Create_Call) RunAndReturn(run func(ctx context.Context, name string) (*biz.Organization, error)) *OrganizationRepo_Create_Call { + _c.Call.Return(run) + return _c +} + +// Delete provides a mock function for the type OrganizationRepo +func (_mock *OrganizationRepo) Delete(ctx context.Context, ID uuid.UUID) error { + ret := _mock.Called(ctx, ID) if len(ret) == 0 { panic("no return value specified for Delete") } var r0 error - if rf, ok := ret.Get(0).(func(context.Context, uuid.UUID) error); ok { - r0 = rf(ctx, ID) + if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID) error); ok { + r0 = returnFunc(ctx, ID) } else { r0 = ret.Error(0) } - return r0 } -// FindByID provides a mock function with given fields: ctx, orgID -func (_m *OrganizationRepo) FindByID(ctx context.Context, orgID uuid.UUID) (*biz.Organization, error) { - ret := _m.Called(ctx, orgID) +// OrganizationRepo_Delete_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Delete' +type OrganizationRepo_Delete_Call struct { + *mock.Call +} + +// Delete is a helper method to define mock.On call +// - ctx context.Context +// - ID uuid.UUID +func (_e *OrganizationRepo_Expecter) Delete(ctx interface{}, ID interface{}) *OrganizationRepo_Delete_Call { + return &OrganizationRepo_Delete_Call{Call: _e.mock.On("Delete", ctx, ID)} +} + +func (_c *OrganizationRepo_Delete_Call) Run(run func(ctx context.Context, ID uuid.UUID)) *OrganizationRepo_Delete_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 uuid.UUID + if args[1] != nil { + arg1 = args[1].(uuid.UUID) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *OrganizationRepo_Delete_Call) Return(err error) *OrganizationRepo_Delete_Call { + _c.Call.Return(err) + return _c +} + +func (_c *OrganizationRepo_Delete_Call) RunAndReturn(run func(ctx context.Context, ID uuid.UUID) error) *OrganizationRepo_Delete_Call { + _c.Call.Return(run) + return _c +} + +// FindByID provides a mock function for the type OrganizationRepo +func (_mock *OrganizationRepo) FindByID(ctx context.Context, orgID uuid.UUID) (*biz.Organization, error) { + ret := _mock.Called(ctx, orgID) if len(ret) == 0 { panic("no return value specified for FindByID") @@ -75,29 +174,67 @@ func (_m *OrganizationRepo) FindByID(ctx context.Context, orgID uuid.UUID) (*biz var r0 *biz.Organization var r1 error - if rf, ok := ret.Get(0).(func(context.Context, uuid.UUID) (*biz.Organization, error)); ok { - return rf(ctx, orgID) + if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID) (*biz.Organization, error)); ok { + return returnFunc(ctx, orgID) } - if rf, ok := ret.Get(0).(func(context.Context, uuid.UUID) *biz.Organization); ok { - r0 = rf(ctx, orgID) + if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID) *biz.Organization); ok { + r0 = returnFunc(ctx, orgID) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*biz.Organization) } } - - if rf, ok := ret.Get(1).(func(context.Context, uuid.UUID) error); ok { - r1 = rf(ctx, orgID) + if returnFunc, ok := ret.Get(1).(func(context.Context, uuid.UUID) error); ok { + r1 = returnFunc(ctx, orgID) } else { r1 = ret.Error(1) } - return r0, r1 } -// FindByName provides a mock function with given fields: ctx, name -func (_m *OrganizationRepo) FindByName(ctx context.Context, name string) (*biz.Organization, error) { - ret := _m.Called(ctx, name) +// OrganizationRepo_FindByID_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FindByID' +type OrganizationRepo_FindByID_Call struct { + *mock.Call +} + +// FindByID is a helper method to define mock.On call +// - ctx context.Context +// - orgID uuid.UUID +func (_e *OrganizationRepo_Expecter) FindByID(ctx interface{}, orgID interface{}) *OrganizationRepo_FindByID_Call { + return &OrganizationRepo_FindByID_Call{Call: _e.mock.On("FindByID", ctx, orgID)} +} + +func (_c *OrganizationRepo_FindByID_Call) Run(run func(ctx context.Context, orgID uuid.UUID)) *OrganizationRepo_FindByID_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 uuid.UUID + if args[1] != nil { + arg1 = args[1].(uuid.UUID) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *OrganizationRepo_FindByID_Call) Return(organization *biz.Organization, err error) *OrganizationRepo_FindByID_Call { + _c.Call.Return(organization, err) + return _c +} + +func (_c *OrganizationRepo_FindByID_Call) RunAndReturn(run func(ctx context.Context, orgID uuid.UUID) (*biz.Organization, error)) *OrganizationRepo_FindByID_Call { + _c.Call.Return(run) + return _c +} + +// FindByName provides a mock function for the type OrganizationRepo +func (_mock *OrganizationRepo) FindByName(ctx context.Context, name string) (*biz.Organization, error) { + ret := _mock.Called(ctx, name) if len(ret) == 0 { panic("no return value specified for FindByName") @@ -105,29 +242,67 @@ func (_m *OrganizationRepo) FindByName(ctx context.Context, name string) (*biz.O var r0 *biz.Organization var r1 error - if rf, ok := ret.Get(0).(func(context.Context, string) (*biz.Organization, error)); ok { - return rf(ctx, name) + if returnFunc, ok := ret.Get(0).(func(context.Context, string) (*biz.Organization, error)); ok { + return returnFunc(ctx, name) } - if rf, ok := ret.Get(0).(func(context.Context, string) *biz.Organization); ok { - r0 = rf(ctx, name) + if returnFunc, ok := ret.Get(0).(func(context.Context, string) *biz.Organization); ok { + r0 = returnFunc(ctx, name) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*biz.Organization) } } - - if rf, ok := ret.Get(1).(func(context.Context, string) error); ok { - r1 = rf(ctx, name) + if returnFunc, ok := ret.Get(1).(func(context.Context, string) error); ok { + r1 = returnFunc(ctx, name) } else { r1 = ret.Error(1) } - return r0, r1 } -// Update provides a mock function with given fields: ctx, id, blockOnPolicyViolation, policiesAllowedHostnames -func (_m *OrganizationRepo) Update(ctx context.Context, id uuid.UUID, blockOnPolicyViolation *bool, policiesAllowedHostnames []string) (*biz.Organization, error) { - ret := _m.Called(ctx, id, blockOnPolicyViolation, policiesAllowedHostnames) +// OrganizationRepo_FindByName_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FindByName' +type OrganizationRepo_FindByName_Call struct { + *mock.Call +} + +// FindByName is a helper method to define mock.On call +// - ctx context.Context +// - name string +func (_e *OrganizationRepo_Expecter) FindByName(ctx interface{}, name interface{}) *OrganizationRepo_FindByName_Call { + return &OrganizationRepo_FindByName_Call{Call: _e.mock.On("FindByName", ctx, name)} +} + +func (_c *OrganizationRepo_FindByName_Call) Run(run func(ctx context.Context, name string)) *OrganizationRepo_FindByName_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *OrganizationRepo_FindByName_Call) Return(organization *biz.Organization, err error) *OrganizationRepo_FindByName_Call { + _c.Call.Return(organization, err) + return _c +} + +func (_c *OrganizationRepo_FindByName_Call) RunAndReturn(run func(ctx context.Context, name string) (*biz.Organization, error)) *OrganizationRepo_FindByName_Call { + _c.Call.Return(run) + return _c +} + +// Update provides a mock function for the type OrganizationRepo +func (_mock *OrganizationRepo) Update(ctx context.Context, id uuid.UUID, blockOnPolicyViolation *bool, policiesAllowedHostnames []string) (*biz.Organization, error) { + ret := _mock.Called(ctx, id, blockOnPolicyViolation, policiesAllowedHostnames) if len(ret) == 0 { panic("no return value specified for Update") @@ -135,36 +310,72 @@ func (_m *OrganizationRepo) Update(ctx context.Context, id uuid.UUID, blockOnPol var r0 *biz.Organization var r1 error - if rf, ok := ret.Get(0).(func(context.Context, uuid.UUID, *bool, []string) (*biz.Organization, error)); ok { - return rf(ctx, id, blockOnPolicyViolation, policiesAllowedHostnames) + if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID, *bool, []string) (*biz.Organization, error)); ok { + return returnFunc(ctx, id, blockOnPolicyViolation, policiesAllowedHostnames) } - if rf, ok := ret.Get(0).(func(context.Context, uuid.UUID, *bool, []string) *biz.Organization); ok { - r0 = rf(ctx, id, blockOnPolicyViolation, policiesAllowedHostnames) + if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID, *bool, []string) *biz.Organization); ok { + r0 = returnFunc(ctx, id, blockOnPolicyViolation, policiesAllowedHostnames) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*biz.Organization) } } - - if rf, ok := ret.Get(1).(func(context.Context, uuid.UUID, *bool, []string) error); ok { - r1 = rf(ctx, id, blockOnPolicyViolation, policiesAllowedHostnames) + if returnFunc, ok := ret.Get(1).(func(context.Context, uuid.UUID, *bool, []string) error); ok { + r1 = returnFunc(ctx, id, blockOnPolicyViolation, policiesAllowedHostnames) } else { r1 = ret.Error(1) } - return r0, r1 } -// NewOrganizationRepo creates a new instance of OrganizationRepo. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -// The first argument is typically a *testing.T value. -func NewOrganizationRepo(t interface { - mock.TestingT - Cleanup(func()) -}) *OrganizationRepo { - mock := &OrganizationRepo{} - mock.Mock.Test(t) +// OrganizationRepo_Update_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Update' +type OrganizationRepo_Update_Call struct { + *mock.Call +} - t.Cleanup(func() { mock.AssertExpectations(t) }) +// Update is a helper method to define mock.On call +// - ctx context.Context +// - id uuid.UUID +// - blockOnPolicyViolation *bool +// - policiesAllowedHostnames []string +func (_e *OrganizationRepo_Expecter) Update(ctx interface{}, id interface{}, blockOnPolicyViolation interface{}, policiesAllowedHostnames interface{}) *OrganizationRepo_Update_Call { + return &OrganizationRepo_Update_Call{Call: _e.mock.On("Update", ctx, id, blockOnPolicyViolation, policiesAllowedHostnames)} +} - return mock +func (_c *OrganizationRepo_Update_Call) Run(run func(ctx context.Context, id uuid.UUID, blockOnPolicyViolation *bool, policiesAllowedHostnames []string)) *OrganizationRepo_Update_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 uuid.UUID + if args[1] != nil { + arg1 = args[1].(uuid.UUID) + } + var arg2 *bool + if args[2] != nil { + arg2 = args[2].(*bool) + } + var arg3 []string + if args[3] != nil { + arg3 = args[3].([]string) + } + run( + arg0, + arg1, + arg2, + arg3, + ) + }) + return _c +} + +func (_c *OrganizationRepo_Update_Call) Return(organization *biz.Organization, err error) *OrganizationRepo_Update_Call { + _c.Call.Return(organization, err) + return _c +} + +func (_c *OrganizationRepo_Update_Call) RunAndReturn(run func(ctx context.Context, id uuid.UUID, blockOnPolicyViolation *bool, policiesAllowedHostnames []string) (*biz.Organization, error)) *OrganizationRepo_Update_Call { + _c.Call.Return(run) + return _c } diff --git a/app/controlplane/pkg/biz/mocks_test.go b/app/controlplane/pkg/biz/mocks_test.go index b93ff9392..4452ecb26 100644 --- a/app/controlplane/pkg/biz/mocks_test.go +++ b/app/controlplane/pkg/biz/mocks_test.go @@ -8,6 +8,7 @@ import ( "context" "time" + "github.com/chainloop-dev/chainloop/app/controlplane/pkg/authz" "github.com/google/uuid" mock "github.com/stretchr/testify/mock" ) @@ -40,8 +41,8 @@ func (_m *MockAPITokenRepo) EXPECT() *MockAPITokenRepo_Expecter { } // Create provides a mock function for the type MockAPITokenRepo -func (_mock *MockAPITokenRepo) Create(ctx context.Context, name string, description *string, expiresAt *time.Time, organizationID uuid.UUID, projectID *uuid.UUID) (*APIToken, error) { - ret := _mock.Called(ctx, name, description, expiresAt, organizationID, projectID) +func (_mock *MockAPITokenRepo) Create(ctx context.Context, name string, description *string, expiresAt *time.Time, organizationID uuid.UUID, projectID *uuid.UUID, policies []*authz.Policy) (*APIToken, error) { + ret := _mock.Called(ctx, name, description, expiresAt, organizationID, projectID, policies) if len(ret) == 0 { panic("no return value specified for Create") @@ -49,18 +50,18 @@ func (_mock *MockAPITokenRepo) Create(ctx context.Context, name string, descript var r0 *APIToken var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, string, *string, *time.Time, uuid.UUID, *uuid.UUID) (*APIToken, error)); ok { - return returnFunc(ctx, name, description, expiresAt, organizationID, projectID) + if returnFunc, ok := ret.Get(0).(func(context.Context, string, *string, *time.Time, uuid.UUID, *uuid.UUID, []*authz.Policy) (*APIToken, error)); ok { + return returnFunc(ctx, name, description, expiresAt, organizationID, projectID, policies) } - if returnFunc, ok := ret.Get(0).(func(context.Context, string, *string, *time.Time, uuid.UUID, *uuid.UUID) *APIToken); ok { - r0 = returnFunc(ctx, name, description, expiresAt, organizationID, projectID) + if returnFunc, ok := ret.Get(0).(func(context.Context, string, *string, *time.Time, uuid.UUID, *uuid.UUID, []*authz.Policy) *APIToken); ok { + r0 = returnFunc(ctx, name, description, expiresAt, organizationID, projectID, policies) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*APIToken) } } - if returnFunc, ok := ret.Get(1).(func(context.Context, string, *string, *time.Time, uuid.UUID, *uuid.UUID) error); ok { - r1 = returnFunc(ctx, name, description, expiresAt, organizationID, projectID) + if returnFunc, ok := ret.Get(1).(func(context.Context, string, *string, *time.Time, uuid.UUID, *uuid.UUID, []*authz.Policy) error); ok { + r1 = returnFunc(ctx, name, description, expiresAt, organizationID, projectID, policies) } else { r1 = ret.Error(1) } @@ -79,11 +80,12 @@ type MockAPITokenRepo_Create_Call struct { // - expiresAt *time.Time // - organizationID uuid.UUID // - projectID *uuid.UUID -func (_e *MockAPITokenRepo_Expecter) Create(ctx interface{}, name interface{}, description interface{}, expiresAt interface{}, organizationID interface{}, projectID interface{}) *MockAPITokenRepo_Create_Call { - return &MockAPITokenRepo_Create_Call{Call: _e.mock.On("Create", ctx, name, description, expiresAt, organizationID, projectID)} +// - policies []*authz.Policy +func (_e *MockAPITokenRepo_Expecter) Create(ctx interface{}, name interface{}, description interface{}, expiresAt interface{}, organizationID interface{}, projectID interface{}, policies interface{}) *MockAPITokenRepo_Create_Call { + return &MockAPITokenRepo_Create_Call{Call: _e.mock.On("Create", ctx, name, description, expiresAt, organizationID, projectID, policies)} } -func (_c *MockAPITokenRepo_Create_Call) Run(run func(ctx context.Context, name string, description *string, expiresAt *time.Time, organizationID uuid.UUID, projectID *uuid.UUID)) *MockAPITokenRepo_Create_Call { +func (_c *MockAPITokenRepo_Create_Call) Run(run func(ctx context.Context, name string, description *string, expiresAt *time.Time, organizationID uuid.UUID, projectID *uuid.UUID, policies []*authz.Policy)) *MockAPITokenRepo_Create_Call { _c.Call.Run(func(args mock.Arguments) { var arg0 context.Context if args[0] != nil { @@ -109,6 +111,10 @@ func (_c *MockAPITokenRepo_Create_Call) Run(run func(ctx context.Context, name s if args[5] != nil { arg5 = args[5].(*uuid.UUID) } + var arg6 []*authz.Policy + if args[6] != nil { + arg6 = args[6].([]*authz.Policy) + } run( arg0, arg1, @@ -116,6 +122,7 @@ func (_c *MockAPITokenRepo_Create_Call) Run(run func(ctx context.Context, name s arg3, arg4, arg5, + arg6, ) }) return _c @@ -126,7 +133,7 @@ func (_c *MockAPITokenRepo_Create_Call) Return(aPIToken *APIToken, err error) *M return _c } -func (_c *MockAPITokenRepo_Create_Call) RunAndReturn(run func(ctx context.Context, name string, description *string, expiresAt *time.Time, organizationID uuid.UUID, projectID *uuid.UUID) (*APIToken, error)) *MockAPITokenRepo_Create_Call { +func (_c *MockAPITokenRepo_Create_Call) RunAndReturn(run func(ctx context.Context, name string, description *string, expiresAt *time.Time, organizationID uuid.UUID, projectID *uuid.UUID, policies []*authz.Policy) (*APIToken, error)) *MockAPITokenRepo_Create_Call { _c.Call.Return(run) return _c } @@ -1443,3 +1450,371 @@ func (_c *MockCASBackendRepo_UpdateValidationStatus_Call) RunAndReturn(run func( _c.Call.Return(run) return _c } + +// NewMockOrganizationRepo creates a new instance of MockOrganizationRepo. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockOrganizationRepo(t interface { + mock.TestingT + Cleanup(func()) +}) *MockOrganizationRepo { + mock := &MockOrganizationRepo{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} + +// MockOrganizationRepo is an autogenerated mock type for the OrganizationRepo type +type MockOrganizationRepo struct { + mock.Mock +} + +type MockOrganizationRepo_Expecter struct { + mock *mock.Mock +} + +func (_m *MockOrganizationRepo) EXPECT() *MockOrganizationRepo_Expecter { + return &MockOrganizationRepo_Expecter{mock: &_m.Mock} +} + +// Create provides a mock function for the type MockOrganizationRepo +func (_mock *MockOrganizationRepo) Create(ctx context.Context, name string) (*Organization, error) { + ret := _mock.Called(ctx, name) + + if len(ret) == 0 { + panic("no return value specified for Create") + } + + var r0 *Organization + var r1 error + if returnFunc, ok := ret.Get(0).(func(context.Context, string) (*Organization, error)); ok { + return returnFunc(ctx, name) + } + if returnFunc, ok := ret.Get(0).(func(context.Context, string) *Organization); ok { + r0 = returnFunc(ctx, name) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*Organization) + } + } + if returnFunc, ok := ret.Get(1).(func(context.Context, string) error); ok { + r1 = returnFunc(ctx, name) + } else { + r1 = ret.Error(1) + } + return r0, r1 +} + +// MockOrganizationRepo_Create_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Create' +type MockOrganizationRepo_Create_Call struct { + *mock.Call +} + +// Create is a helper method to define mock.On call +// - ctx context.Context +// - name string +func (_e *MockOrganizationRepo_Expecter) Create(ctx interface{}, name interface{}) *MockOrganizationRepo_Create_Call { + return &MockOrganizationRepo_Create_Call{Call: _e.mock.On("Create", ctx, name)} +} + +func (_c *MockOrganizationRepo_Create_Call) Run(run func(ctx context.Context, name string)) *MockOrganizationRepo_Create_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *MockOrganizationRepo_Create_Call) Return(organization *Organization, err error) *MockOrganizationRepo_Create_Call { + _c.Call.Return(organization, err) + return _c +} + +func (_c *MockOrganizationRepo_Create_Call) RunAndReturn(run func(ctx context.Context, name string) (*Organization, error)) *MockOrganizationRepo_Create_Call { + _c.Call.Return(run) + return _c +} + +// Delete provides a mock function for the type MockOrganizationRepo +func (_mock *MockOrganizationRepo) Delete(ctx context.Context, ID uuid.UUID) error { + ret := _mock.Called(ctx, ID) + + if len(ret) == 0 { + panic("no return value specified for Delete") + } + + var r0 error + if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID) error); ok { + r0 = returnFunc(ctx, ID) + } else { + r0 = ret.Error(0) + } + return r0 +} + +// MockOrganizationRepo_Delete_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Delete' +type MockOrganizationRepo_Delete_Call struct { + *mock.Call +} + +// Delete is a helper method to define mock.On call +// - ctx context.Context +// - ID uuid.UUID +func (_e *MockOrganizationRepo_Expecter) Delete(ctx interface{}, ID interface{}) *MockOrganizationRepo_Delete_Call { + return &MockOrganizationRepo_Delete_Call{Call: _e.mock.On("Delete", ctx, ID)} +} + +func (_c *MockOrganizationRepo_Delete_Call) Run(run func(ctx context.Context, ID uuid.UUID)) *MockOrganizationRepo_Delete_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 uuid.UUID + if args[1] != nil { + arg1 = args[1].(uuid.UUID) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *MockOrganizationRepo_Delete_Call) Return(err error) *MockOrganizationRepo_Delete_Call { + _c.Call.Return(err) + return _c +} + +func (_c *MockOrganizationRepo_Delete_Call) RunAndReturn(run func(ctx context.Context, ID uuid.UUID) error) *MockOrganizationRepo_Delete_Call { + _c.Call.Return(run) + return _c +} + +// FindByID provides a mock function for the type MockOrganizationRepo +func (_mock *MockOrganizationRepo) FindByID(ctx context.Context, orgID uuid.UUID) (*Organization, error) { + ret := _mock.Called(ctx, orgID) + + if len(ret) == 0 { + panic("no return value specified for FindByID") + } + + var r0 *Organization + var r1 error + if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID) (*Organization, error)); ok { + return returnFunc(ctx, orgID) + } + if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID) *Organization); ok { + r0 = returnFunc(ctx, orgID) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*Organization) + } + } + if returnFunc, ok := ret.Get(1).(func(context.Context, uuid.UUID) error); ok { + r1 = returnFunc(ctx, orgID) + } else { + r1 = ret.Error(1) + } + return r0, r1 +} + +// MockOrganizationRepo_FindByID_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FindByID' +type MockOrganizationRepo_FindByID_Call struct { + *mock.Call +} + +// FindByID is a helper method to define mock.On call +// - ctx context.Context +// - orgID uuid.UUID +func (_e *MockOrganizationRepo_Expecter) FindByID(ctx interface{}, orgID interface{}) *MockOrganizationRepo_FindByID_Call { + return &MockOrganizationRepo_FindByID_Call{Call: _e.mock.On("FindByID", ctx, orgID)} +} + +func (_c *MockOrganizationRepo_FindByID_Call) Run(run func(ctx context.Context, orgID uuid.UUID)) *MockOrganizationRepo_FindByID_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 uuid.UUID + if args[1] != nil { + arg1 = args[1].(uuid.UUID) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *MockOrganizationRepo_FindByID_Call) Return(organization *Organization, err error) *MockOrganizationRepo_FindByID_Call { + _c.Call.Return(organization, err) + return _c +} + +func (_c *MockOrganizationRepo_FindByID_Call) RunAndReturn(run func(ctx context.Context, orgID uuid.UUID) (*Organization, error)) *MockOrganizationRepo_FindByID_Call { + _c.Call.Return(run) + return _c +} + +// FindByName provides a mock function for the type MockOrganizationRepo +func (_mock *MockOrganizationRepo) FindByName(ctx context.Context, name string) (*Organization, error) { + ret := _mock.Called(ctx, name) + + if len(ret) == 0 { + panic("no return value specified for FindByName") + } + + var r0 *Organization + var r1 error + if returnFunc, ok := ret.Get(0).(func(context.Context, string) (*Organization, error)); ok { + return returnFunc(ctx, name) + } + if returnFunc, ok := ret.Get(0).(func(context.Context, string) *Organization); ok { + r0 = returnFunc(ctx, name) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*Organization) + } + } + if returnFunc, ok := ret.Get(1).(func(context.Context, string) error); ok { + r1 = returnFunc(ctx, name) + } else { + r1 = ret.Error(1) + } + return r0, r1 +} + +// MockOrganizationRepo_FindByName_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FindByName' +type MockOrganizationRepo_FindByName_Call struct { + *mock.Call +} + +// FindByName is a helper method to define mock.On call +// - ctx context.Context +// - name string +func (_e *MockOrganizationRepo_Expecter) FindByName(ctx interface{}, name interface{}) *MockOrganizationRepo_FindByName_Call { + return &MockOrganizationRepo_FindByName_Call{Call: _e.mock.On("FindByName", ctx, name)} +} + +func (_c *MockOrganizationRepo_FindByName_Call) Run(run func(ctx context.Context, name string)) *MockOrganizationRepo_FindByName_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *MockOrganizationRepo_FindByName_Call) Return(organization *Organization, err error) *MockOrganizationRepo_FindByName_Call { + _c.Call.Return(organization, err) + return _c +} + +func (_c *MockOrganizationRepo_FindByName_Call) RunAndReturn(run func(ctx context.Context, name string) (*Organization, error)) *MockOrganizationRepo_FindByName_Call { + _c.Call.Return(run) + return _c +} + +// Update provides a mock function for the type MockOrganizationRepo +func (_mock *MockOrganizationRepo) Update(ctx context.Context, id uuid.UUID, blockOnPolicyViolation *bool, policiesAllowedHostnames []string) (*Organization, error) { + ret := _mock.Called(ctx, id, blockOnPolicyViolation, policiesAllowedHostnames) + + if len(ret) == 0 { + panic("no return value specified for Update") + } + + var r0 *Organization + var r1 error + if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID, *bool, []string) (*Organization, error)); ok { + return returnFunc(ctx, id, blockOnPolicyViolation, policiesAllowedHostnames) + } + if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID, *bool, []string) *Organization); ok { + r0 = returnFunc(ctx, id, blockOnPolicyViolation, policiesAllowedHostnames) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*Organization) + } + } + if returnFunc, ok := ret.Get(1).(func(context.Context, uuid.UUID, *bool, []string) error); ok { + r1 = returnFunc(ctx, id, blockOnPolicyViolation, policiesAllowedHostnames) + } else { + r1 = ret.Error(1) + } + return r0, r1 +} + +// MockOrganizationRepo_Update_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Update' +type MockOrganizationRepo_Update_Call struct { + *mock.Call +} + +// Update is a helper method to define mock.On call +// - ctx context.Context +// - id uuid.UUID +// - blockOnPolicyViolation *bool +// - policiesAllowedHostnames []string +func (_e *MockOrganizationRepo_Expecter) Update(ctx interface{}, id interface{}, blockOnPolicyViolation interface{}, policiesAllowedHostnames interface{}) *MockOrganizationRepo_Update_Call { + return &MockOrganizationRepo_Update_Call{Call: _e.mock.On("Update", ctx, id, blockOnPolicyViolation, policiesAllowedHostnames)} +} + +func (_c *MockOrganizationRepo_Update_Call) Run(run func(ctx context.Context, id uuid.UUID, blockOnPolicyViolation *bool, policiesAllowedHostnames []string)) *MockOrganizationRepo_Update_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 uuid.UUID + if args[1] != nil { + arg1 = args[1].(uuid.UUID) + } + var arg2 *bool + if args[2] != nil { + arg2 = args[2].(*bool) + } + var arg3 []string + if args[3] != nil { + arg3 = args[3].([]string) + } + run( + arg0, + arg1, + arg2, + arg3, + ) + }) + return _c +} + +func (_c *MockOrganizationRepo_Update_Call) Return(organization *Organization, err error) *MockOrganizationRepo_Update_Call { + _c.Call.Return(organization, err) + return _c +} + +func (_c *MockOrganizationRepo_Update_Call) RunAndReturn(run func(ctx context.Context, id uuid.UUID, blockOnPolicyViolation *bool, policiesAllowedHostnames []string) (*Organization, error)) *MockOrganizationRepo_Update_Call { + _c.Call.Return(run) + return _c +} diff --git a/app/controlplane/pkg/biz/testhelpers/wire.go b/app/controlplane/pkg/biz/testhelpers/wire.go index b0aa47d28..6d2922917 100644 --- a/app/controlplane/pkg/biz/testhelpers/wire.go +++ b/app/controlplane/pkg/biz/testhelpers/wire.go @@ -54,7 +54,7 @@ func WireTestData(*TestDatabase, *testing.T, log.Logger, credentials.ReaderWrite NewPromSpec, NewPolicyProviderConfig, policies.NewRegistry, - authz.NewDatabaseEnforcer, + authz.NewInMemoryEnforcer, newNatsConnection, auditor.NewAuditLogPublisher, NewCASBackendConfig, diff --git a/app/controlplane/pkg/biz/testhelpers/wire_gen.go b/app/controlplane/pkg/biz/testhelpers/wire_gen.go index a9fbb8d0e..e131c412f 100644 --- a/app/controlplane/pkg/biz/testhelpers/wire_gen.go +++ b/app/controlplane/pkg/biz/testhelpers/wire_gen.go @@ -139,7 +139,7 @@ func WireTestData(testDatabase *TestDatabase, t *testing.T, logger log.Logger, r apiTokenRepo := data.NewAPITokenRepo(dataData, logger) apiTokenJWTConfig := newJWTConfig(auth) config := authzConfig() - enforcer, err := authz.NewDatabaseEnforcer(databaseConfig, config) + enforcer, err := authz.NewInMemoryEnforcer(config) if err != nil { cleanup() return nil, nil, err diff --git a/app/controlplane/pkg/data/apitoken.go b/app/controlplane/pkg/data/apitoken.go index a53c2ac89..491d819cd 100644 --- a/app/controlplane/pkg/data/apitoken.go +++ b/app/controlplane/pkg/data/apitoken.go @@ -20,6 +20,7 @@ import ( "fmt" "time" + "github.com/chainloop-dev/chainloop/app/controlplane/pkg/authz" "github.com/chainloop-dev/chainloop/app/controlplane/pkg/biz" "github.com/chainloop-dev/chainloop/app/controlplane/pkg/data/ent" "github.com/chainloop-dev/chainloop/app/controlplane/pkg/data/ent/apitoken" @@ -41,13 +42,14 @@ func NewAPITokenRepo(data *Data, logger log.Logger) biz.APITokenRepo { } // Persist the APIToken to the database. -func (r *APITokenRepo) Create(ctx context.Context, name string, description *string, expiresAt *time.Time, organizationID uuid.UUID, projectID *uuid.UUID) (*biz.APIToken, error) { +func (r *APITokenRepo) Create(ctx context.Context, name string, description *string, expiresAt *time.Time, organizationID uuid.UUID, projectID *uuid.UUID, policies []*authz.Policy) (*biz.APIToken, error) { token, err := r.data.DB.APIToken.Create(). SetName(name). SetNillableDescription(description). SetNillableExpiresAt(expiresAt). SetOrganizationID(organizationID). SetNillableProjectID(projectID). + SetPolicies(policies). Save(ctx) if err != nil { if ent.IsConstraintError(err) { @@ -182,6 +184,7 @@ func entAPITokenToBiz(t *ent.APIToken) *biz.APIToken { RevokedAt: toTimePtr(t.RevokedAt), LastUsedAt: toTimePtr(t.LastUsedAt), OrganizationID: t.OrganizationID, + Policies: t.Policies, } // Add organization name if present diff --git a/app/controlplane/pkg/data/ent/apitoken.go b/app/controlplane/pkg/data/ent/apitoken.go index c1afe24a2..a74ae30a2 100644 --- a/app/controlplane/pkg/data/ent/apitoken.go +++ b/app/controlplane/pkg/data/ent/apitoken.go @@ -3,12 +3,14 @@ package ent import ( + "encoding/json" "fmt" "strings" "time" "entgo.io/ent" "entgo.io/ent/dialect/sql" + "github.com/chainloop-dev/chainloop/app/controlplane/pkg/authz" "github.com/chainloop-dev/chainloop/app/controlplane/pkg/data/ent/apitoken" "github.com/chainloop-dev/chainloop/app/controlplane/pkg/data/ent/organization" "github.com/chainloop-dev/chainloop/app/controlplane/pkg/data/ent/project" @@ -36,6 +38,8 @@ type APIToken struct { OrganizationID uuid.UUID `json:"organization_id,omitempty"` // ProjectID holds the value of the "project_id" field. ProjectID uuid.UUID `json:"project_id,omitempty"` + // Policies holds the value of the "policies" field. + Policies []*authz.Policy `json:"policies,omitempty"` // Edges holds the relations/edges for other nodes in the graph. // The values are being populated by the APITokenQuery when eager-loading is set. Edges APITokenEdges `json:"edges"` @@ -80,6 +84,8 @@ func (*APIToken) scanValues(columns []string) ([]any, error) { values := make([]any, len(columns)) for i := range columns { switch columns[i] { + case apitoken.FieldPolicies: + values[i] = new([]byte) case apitoken.FieldName, apitoken.FieldDescription: values[i] = new(sql.NullString) case apitoken.FieldCreatedAt, apitoken.FieldExpiresAt, apitoken.FieldRevokedAt, apitoken.FieldLastUsedAt: @@ -155,6 +161,14 @@ func (at *APIToken) assignValues(columns []string, values []any) error { } else if value != nil { at.ProjectID = *value } + case apitoken.FieldPolicies: + if value, ok := values[i].(*[]byte); !ok { + return fmt.Errorf("unexpected type %T for field policies", values[i]) + } else if value != nil && len(*value) > 0 { + if err := json.Unmarshal(*value, &at.Policies); err != nil { + return fmt.Errorf("unmarshal field policies: %w", err) + } + } default: at.selectValues.Set(columns[i], values[i]) } @@ -224,6 +238,9 @@ func (at *APIToken) String() string { builder.WriteString(", ") builder.WriteString("project_id=") builder.WriteString(fmt.Sprintf("%v", at.ProjectID)) + builder.WriteString(", ") + builder.WriteString("policies=") + builder.WriteString(fmt.Sprintf("%v", at.Policies)) builder.WriteByte(')') return builder.String() } diff --git a/app/controlplane/pkg/data/ent/apitoken/apitoken.go b/app/controlplane/pkg/data/ent/apitoken/apitoken.go index c6a46556d..c6856e00a 100644 --- a/app/controlplane/pkg/data/ent/apitoken/apitoken.go +++ b/app/controlplane/pkg/data/ent/apitoken/apitoken.go @@ -31,6 +31,8 @@ const ( FieldOrganizationID = "organization_id" // FieldProjectID holds the string denoting the project_id field in the database. FieldProjectID = "project_id" + // FieldPolicies holds the string denoting the policies field in the database. + FieldPolicies = "policies" // EdgeOrganization holds the string denoting the organization edge name in mutations. EdgeOrganization = "organization" // EdgeProject holds the string denoting the project edge name in mutations. @@ -64,6 +66,7 @@ var Columns = []string{ FieldLastUsedAt, FieldOrganizationID, FieldProjectID, + FieldPolicies, } // ValidColumn reports if the column name is valid (part of the table columns). diff --git a/app/controlplane/pkg/data/ent/apitoken/where.go b/app/controlplane/pkg/data/ent/apitoken/where.go index 77ab80780..0ca8398d8 100644 --- a/app/controlplane/pkg/data/ent/apitoken/where.go +++ b/app/controlplane/pkg/data/ent/apitoken/where.go @@ -476,6 +476,16 @@ func ProjectIDNotNil() predicate.APIToken { return predicate.APIToken(sql.FieldNotNull(FieldProjectID)) } +// PoliciesIsNil applies the IsNil predicate on the "policies" field. +func PoliciesIsNil() predicate.APIToken { + return predicate.APIToken(sql.FieldIsNull(FieldPolicies)) +} + +// PoliciesNotNil applies the NotNil predicate on the "policies" field. +func PoliciesNotNil() predicate.APIToken { + return predicate.APIToken(sql.FieldNotNull(FieldPolicies)) +} + // HasOrganization applies the HasEdge predicate on the "organization" edge. func HasOrganization() predicate.APIToken { return predicate.APIToken(func(s *sql.Selector) { diff --git a/app/controlplane/pkg/data/ent/apitoken_create.go b/app/controlplane/pkg/data/ent/apitoken_create.go index 536e23b92..39b9eebfc 100644 --- a/app/controlplane/pkg/data/ent/apitoken_create.go +++ b/app/controlplane/pkg/data/ent/apitoken_create.go @@ -12,6 +12,7 @@ import ( "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" + "github.com/chainloop-dev/chainloop/app/controlplane/pkg/authz" "github.com/chainloop-dev/chainloop/app/controlplane/pkg/data/ent/apitoken" "github.com/chainloop-dev/chainloop/app/controlplane/pkg/data/ent/organization" "github.com/chainloop-dev/chainloop/app/controlplane/pkg/data/ent/project" @@ -122,6 +123,12 @@ func (atc *APITokenCreate) SetNillableProjectID(u *uuid.UUID) *APITokenCreate { return atc } +// SetPolicies sets the "policies" field. +func (atc *APITokenCreate) SetPolicies(a []*authz.Policy) *APITokenCreate { + atc.mutation.SetPolicies(a) + return atc +} + // SetID sets the "id" field. func (atc *APITokenCreate) SetID(u uuid.UUID) *APITokenCreate { atc.mutation.SetID(u) @@ -265,6 +272,10 @@ func (atc *APITokenCreate) createSpec() (*APIToken, *sqlgraph.CreateSpec) { _spec.SetField(apitoken.FieldLastUsedAt, field.TypeTime, value) _node.LastUsedAt = value } + if value, ok := atc.mutation.Policies(); ok { + _spec.SetField(apitoken.FieldPolicies, field.TypeJSON, value) + _node.Policies = value + } if nodes := atc.mutation.OrganizationIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, @@ -453,6 +464,24 @@ func (u *APITokenUpsert) ClearProjectID() *APITokenUpsert { return u } +// SetPolicies sets the "policies" field. +func (u *APITokenUpsert) SetPolicies(v []*authz.Policy) *APITokenUpsert { + u.Set(apitoken.FieldPolicies, v) + return u +} + +// UpdatePolicies sets the "policies" field to the value that was provided on create. +func (u *APITokenUpsert) UpdatePolicies() *APITokenUpsert { + u.SetExcluded(apitoken.FieldPolicies) + return u +} + +// ClearPolicies clears the value of the "policies" field. +func (u *APITokenUpsert) ClearPolicies() *APITokenUpsert { + u.SetNull(apitoken.FieldPolicies) + return u +} + // UpdateNewValues updates the mutable fields using the new values that were set on create except the ID field. // Using this option is equivalent to using: // @@ -626,6 +655,27 @@ func (u *APITokenUpsertOne) ClearProjectID() *APITokenUpsertOne { }) } +// SetPolicies sets the "policies" field. +func (u *APITokenUpsertOne) SetPolicies(v []*authz.Policy) *APITokenUpsertOne { + return u.Update(func(s *APITokenUpsert) { + s.SetPolicies(v) + }) +} + +// UpdatePolicies sets the "policies" field to the value that was provided on create. +func (u *APITokenUpsertOne) UpdatePolicies() *APITokenUpsertOne { + return u.Update(func(s *APITokenUpsert) { + s.UpdatePolicies() + }) +} + +// ClearPolicies clears the value of the "policies" field. +func (u *APITokenUpsertOne) ClearPolicies() *APITokenUpsertOne { + return u.Update(func(s *APITokenUpsert) { + s.ClearPolicies() + }) +} + // Exec executes the query. func (u *APITokenUpsertOne) Exec(ctx context.Context) error { if len(u.create.conflict) == 0 { @@ -966,6 +1016,27 @@ func (u *APITokenUpsertBulk) ClearProjectID() *APITokenUpsertBulk { }) } +// SetPolicies sets the "policies" field. +func (u *APITokenUpsertBulk) SetPolicies(v []*authz.Policy) *APITokenUpsertBulk { + return u.Update(func(s *APITokenUpsert) { + s.SetPolicies(v) + }) +} + +// UpdatePolicies sets the "policies" field to the value that was provided on create. +func (u *APITokenUpsertBulk) UpdatePolicies() *APITokenUpsertBulk { + return u.Update(func(s *APITokenUpsert) { + s.UpdatePolicies() + }) +} + +// ClearPolicies clears the value of the "policies" field. +func (u *APITokenUpsertBulk) ClearPolicies() *APITokenUpsertBulk { + return u.Update(func(s *APITokenUpsert) { + s.ClearPolicies() + }) +} + // Exec executes the query. func (u *APITokenUpsertBulk) Exec(ctx context.Context) error { if u.create.err != nil { diff --git a/app/controlplane/pkg/data/ent/apitoken_update.go b/app/controlplane/pkg/data/ent/apitoken_update.go index 360fe50aa..36065597f 100644 --- a/app/controlplane/pkg/data/ent/apitoken_update.go +++ b/app/controlplane/pkg/data/ent/apitoken_update.go @@ -10,7 +10,9 @@ import ( "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/dialect/sql/sqljson" "entgo.io/ent/schema/field" + "github.com/chainloop-dev/chainloop/app/controlplane/pkg/authz" "github.com/chainloop-dev/chainloop/app/controlplane/pkg/data/ent/apitoken" "github.com/chainloop-dev/chainloop/app/controlplane/pkg/data/ent/organization" "github.com/chainloop-dev/chainloop/app/controlplane/pkg/data/ent/predicate" @@ -146,6 +148,24 @@ func (atu *APITokenUpdate) ClearProjectID() *APITokenUpdate { return atu } +// SetPolicies sets the "policies" field. +func (atu *APITokenUpdate) SetPolicies(a []*authz.Policy) *APITokenUpdate { + atu.mutation.SetPolicies(a) + return atu +} + +// AppendPolicies appends a to the "policies" field. +func (atu *APITokenUpdate) AppendPolicies(a []*authz.Policy) *APITokenUpdate { + atu.mutation.AppendPolicies(a) + return atu +} + +// ClearPolicies clears the value of the "policies" field. +func (atu *APITokenUpdate) ClearPolicies() *APITokenUpdate { + atu.mutation.ClearPolicies() + return atu +} + // SetOrganization sets the "organization" edge to the Organization entity. func (atu *APITokenUpdate) SetOrganization(o *Organization) *APITokenUpdate { return atu.SetOrganizationID(o.ID) @@ -250,6 +270,17 @@ func (atu *APITokenUpdate) sqlSave(ctx context.Context) (n int, err error) { if atu.mutation.LastUsedAtCleared() { _spec.ClearField(apitoken.FieldLastUsedAt, field.TypeTime) } + if value, ok := atu.mutation.Policies(); ok { + _spec.SetField(apitoken.FieldPolicies, field.TypeJSON, value) + } + if value, ok := atu.mutation.AppendedPolicies(); ok { + _spec.AddModifier(func(u *sql.UpdateBuilder) { + sqljson.Append(u, apitoken.FieldPolicies, value) + }) + } + if atu.mutation.PoliciesCleared() { + _spec.ClearField(apitoken.FieldPolicies, field.TypeJSON) + } if atu.mutation.OrganizationCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, @@ -444,6 +475,24 @@ func (atuo *APITokenUpdateOne) ClearProjectID() *APITokenUpdateOne { return atuo } +// SetPolicies sets the "policies" field. +func (atuo *APITokenUpdateOne) SetPolicies(a []*authz.Policy) *APITokenUpdateOne { + atuo.mutation.SetPolicies(a) + return atuo +} + +// AppendPolicies appends a to the "policies" field. +func (atuo *APITokenUpdateOne) AppendPolicies(a []*authz.Policy) *APITokenUpdateOne { + atuo.mutation.AppendPolicies(a) + return atuo +} + +// ClearPolicies clears the value of the "policies" field. +func (atuo *APITokenUpdateOne) ClearPolicies() *APITokenUpdateOne { + atuo.mutation.ClearPolicies() + return atuo +} + // SetOrganization sets the "organization" edge to the Organization entity. func (atuo *APITokenUpdateOne) SetOrganization(o *Organization) *APITokenUpdateOne { return atuo.SetOrganizationID(o.ID) @@ -578,6 +627,17 @@ func (atuo *APITokenUpdateOne) sqlSave(ctx context.Context) (_node *APIToken, er if atuo.mutation.LastUsedAtCleared() { _spec.ClearField(apitoken.FieldLastUsedAt, field.TypeTime) } + if value, ok := atuo.mutation.Policies(); ok { + _spec.SetField(apitoken.FieldPolicies, field.TypeJSON, value) + } + if value, ok := atuo.mutation.AppendedPolicies(); ok { + _spec.AddModifier(func(u *sql.UpdateBuilder) { + sqljson.Append(u, apitoken.FieldPolicies, value) + }) + } + if atuo.mutation.PoliciesCleared() { + _spec.ClearField(apitoken.FieldPolicies, field.TypeJSON) + } if atuo.mutation.OrganizationCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, diff --git a/app/controlplane/pkg/data/ent/migrate/migrations/atlas.sum b/app/controlplane/pkg/data/ent/migrate/migrations/atlas.sum index a3a6191ee..6a0e7d8d8 100644 --- a/app/controlplane/pkg/data/ent/migrate/migrations/atlas.sum +++ b/app/controlplane/pkg/data/ent/migrate/migrations/atlas.sum @@ -1,4 +1,4 @@ -h1:hspm2aeA53aPFKPqWqM6NdNeGc9R9kMrodA/EOV5Gyw= +h1:runk64PopaY0nuk0q8fDexF/N5jyI1iEzByvgscJFg4= 20230706165452_init-schema.sql h1:VvqbNFEQnCvUVyj2iDYVQQxDM0+sSXqocpt/5H64k8M= 20230710111950-cas-backend.sql h1:A8iBuSzZIEbdsv9ipBtscZQuaBp3V5/VMw7eZH6GX+g= 20230712094107-cas-backends-workflow-runs.sql h1:a5rzxpVGyd56nLRSsKrmCFc9sebg65RWzLghKHh5xvI= @@ -117,3 +117,4 @@ h1:hspm2aeA53aPFKPqWqM6NdNeGc9R9kMrodA/EOV5Gyw= 20251001215625.sql h1:adcp5r8CoL/JCfNgNZxBvY5pczlEHFH/IX64g/ji/4s= 20251007154203.sql h1:gRPipCNWs439gStSXVDxoSLqTw4SUPMiOe5fK1Y5V1Q= 20251010104841.sql h1:CRElEYC76B0I/Hg1wwYV2SpUX2CLAJyxN82sGCEBM7Y= +20251107233855.sql h1:fNK+hRlqzlM4qxKR7SPMEtbrYSAJfau6bKm1jecRDpE= diff --git a/app/controlplane/pkg/data/ent/migrate/schema.go b/app/controlplane/pkg/data/ent/migrate/schema.go index 088e89aec..acf4570f8 100644 --- a/app/controlplane/pkg/data/ent/migrate/schema.go +++ b/app/controlplane/pkg/data/ent/migrate/schema.go @@ -18,6 +18,7 @@ var ( {Name: "expires_at", Type: field.TypeTime, Nullable: true}, {Name: "revoked_at", Type: field.TypeTime, Nullable: true}, {Name: "last_used_at", Type: field.TypeTime, Nullable: true}, + {Name: "policies", Type: field.TypeJSON, Nullable: true}, {Name: "project_id", Type: field.TypeUUID, Nullable: true}, {Name: "organization_id", Type: field.TypeUUID}, } @@ -29,13 +30,13 @@ var ( ForeignKeys: []*schema.ForeignKey{ { Symbol: "api_tokens_projects_project", - Columns: []*schema.Column{APITokensColumns[7]}, + Columns: []*schema.Column{APITokensColumns[8]}, RefColumns: []*schema.Column{ProjectsColumns[0]}, OnDelete: schema.SetNull, }, { Symbol: "api_tokens_organizations_api_tokens", - Columns: []*schema.Column{APITokensColumns[8]}, + Columns: []*schema.Column{APITokensColumns[9]}, RefColumns: []*schema.Column{OrganizationsColumns[0]}, OnDelete: schema.Cascade, }, @@ -44,7 +45,7 @@ var ( { Name: "apitoken_name_organization_id", Unique: true, - Columns: []*schema.Column{APITokensColumns[1], APITokensColumns[8]}, + Columns: []*schema.Column{APITokensColumns[1], APITokensColumns[9]}, Annotation: &entsql.IndexAnnotation{ Where: "revoked_at IS NULL AND project_id IS NULL", }, @@ -52,7 +53,7 @@ var ( { Name: "apitoken_name_project_id", Unique: true, - Columns: []*schema.Column{APITokensColumns[1], APITokensColumns[7]}, + Columns: []*schema.Column{APITokensColumns[1], APITokensColumns[8]}, Annotation: &entsql.IndexAnnotation{ Where: "revoked_at IS NULL AND project_id IS NOT NULL", }, diff --git a/app/controlplane/pkg/data/ent/mutation.go b/app/controlplane/pkg/data/ent/mutation.go index 48d47b5d5..80145c4d3 100644 --- a/app/controlplane/pkg/data/ent/mutation.go +++ b/app/controlplane/pkg/data/ent/mutation.go @@ -82,6 +82,8 @@ type APITokenMutation struct { expires_at *time.Time revoked_at *time.Time last_used_at *time.Time + policies *[]*authz.Policy + appendpolicies []*authz.Policy clearedFields map[string]struct{} organization *uuid.UUID clearedorganization bool @@ -549,6 +551,71 @@ func (m *APITokenMutation) ResetProjectID() { delete(m.clearedFields, apitoken.FieldProjectID) } +// SetPolicies sets the "policies" field. +func (m *APITokenMutation) SetPolicies(a []*authz.Policy) { + m.policies = &a + m.appendpolicies = nil +} + +// Policies returns the value of the "policies" field in the mutation. +func (m *APITokenMutation) Policies() (r []*authz.Policy, exists bool) { + v := m.policies + if v == nil { + return + } + return *v, true +} + +// OldPolicies returns the old "policies" field's value of the APIToken entity. +// If the APIToken object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *APITokenMutation) OldPolicies(ctx context.Context) (v []*authz.Policy, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldPolicies is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldPolicies requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldPolicies: %w", err) + } + return oldValue.Policies, nil +} + +// AppendPolicies adds a to the "policies" field. +func (m *APITokenMutation) AppendPolicies(a []*authz.Policy) { + m.appendpolicies = append(m.appendpolicies, a...) +} + +// AppendedPolicies returns the list of values that were appended to the "policies" field in this mutation. +func (m *APITokenMutation) AppendedPolicies() ([]*authz.Policy, bool) { + if len(m.appendpolicies) == 0 { + return nil, false + } + return m.appendpolicies, true +} + +// ClearPolicies clears the value of the "policies" field. +func (m *APITokenMutation) ClearPolicies() { + m.policies = nil + m.appendpolicies = nil + m.clearedFields[apitoken.FieldPolicies] = struct{}{} +} + +// PoliciesCleared returns if the "policies" field was cleared in this mutation. +func (m *APITokenMutation) PoliciesCleared() bool { + _, ok := m.clearedFields[apitoken.FieldPolicies] + return ok +} + +// ResetPolicies resets all changes to the "policies" field. +func (m *APITokenMutation) ResetPolicies() { + m.policies = nil + m.appendpolicies = nil + delete(m.clearedFields, apitoken.FieldPolicies) +} + // ClearOrganization clears the "organization" edge to the Organization entity. func (m *APITokenMutation) ClearOrganization() { m.clearedorganization = true @@ -637,7 +704,7 @@ func (m *APITokenMutation) Type() string { // order to get all numeric fields that were incremented/decremented, call // AddedFields(). func (m *APITokenMutation) Fields() []string { - fields := make([]string, 0, 8) + fields := make([]string, 0, 9) if m.name != nil { fields = append(fields, apitoken.FieldName) } @@ -662,6 +729,9 @@ func (m *APITokenMutation) Fields() []string { if m.project != nil { fields = append(fields, apitoken.FieldProjectID) } + if m.policies != nil { + fields = append(fields, apitoken.FieldPolicies) + } return fields } @@ -686,6 +756,8 @@ func (m *APITokenMutation) Field(name string) (ent.Value, bool) { return m.OrganizationID() case apitoken.FieldProjectID: return m.ProjectID() + case apitoken.FieldPolicies: + return m.Policies() } return nil, false } @@ -711,6 +783,8 @@ func (m *APITokenMutation) OldField(ctx context.Context, name string) (ent.Value return m.OldOrganizationID(ctx) case apitoken.FieldProjectID: return m.OldProjectID(ctx) + case apitoken.FieldPolicies: + return m.OldPolicies(ctx) } return nil, fmt.Errorf("unknown APIToken field %s", name) } @@ -776,6 +850,13 @@ func (m *APITokenMutation) SetField(name string, value ent.Value) error { } m.SetProjectID(v) return nil + case apitoken.FieldPolicies: + v, ok := value.([]*authz.Policy) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetPolicies(v) + return nil } return fmt.Errorf("unknown APIToken field %s", name) } @@ -821,6 +902,9 @@ func (m *APITokenMutation) ClearedFields() []string { if m.FieldCleared(apitoken.FieldProjectID) { fields = append(fields, apitoken.FieldProjectID) } + if m.FieldCleared(apitoken.FieldPolicies) { + fields = append(fields, apitoken.FieldPolicies) + } return fields } @@ -850,6 +934,9 @@ func (m *APITokenMutation) ClearField(name string) error { case apitoken.FieldProjectID: m.ClearProjectID() return nil + case apitoken.FieldPolicies: + m.ClearPolicies() + return nil } return fmt.Errorf("unknown APIToken nullable field %s", name) } @@ -882,6 +969,9 @@ func (m *APITokenMutation) ResetField(name string) error { case apitoken.FieldProjectID: m.ResetProjectID() return nil + case apitoken.FieldPolicies: + m.ResetPolicies() + return nil } return fmt.Errorf("unknown APIToken field %s", name) } diff --git a/app/controlplane/pkg/data/ent/schema/apitoken.go b/app/controlplane/pkg/data/ent/schema/apitoken.go index 4a28e1336..53a3a9f04 100644 --- a/app/controlplane/pkg/data/ent/schema/apitoken.go +++ b/app/controlplane/pkg/data/ent/schema/apitoken.go @@ -23,6 +23,7 @@ import ( "entgo.io/ent/schema/edge" "entgo.io/ent/schema/field" "entgo.io/ent/schema/index" + "github.com/chainloop-dev/chainloop/app/controlplane/pkg/authz" "github.com/google/uuid" ) @@ -47,6 +48,9 @@ func (APIToken) Fields() []ent.Field { // Tokens can be associated with a project // if this value is not set, the token is an organization level token field.UUID("project_id", uuid.UUID{}).Optional(), + // ACL policies for this token. NULL means role-based token (future), non-NULL means ACL mode. + // When set, contains the list of policies this token is allowed to perform. + field.JSON("policies", []*authz.Policy{}).Optional(), } } diff --git a/go.mod b/go.mod index 5cb75a342..c556b9269 100644 --- a/go.mod +++ b/go.mod @@ -71,7 +71,6 @@ require ( github.com/bufbuild/protovalidate-go v0.6.1 github.com/bufbuild/protoyaml-go v0.1.11 github.com/casbin/casbin/v2 v2.103.0 - github.com/casbin/ent-adapter v0.5.0 github.com/denisbrodbeck/machineid v1.0.1 github.com/google/go-github/v66 v66.0.0 github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 @@ -243,7 +242,6 @@ require ( cloud.google.com/go/iam v1.5.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/keyvault/azsecrets v0.12.0 github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect - github.com/IguteChung/casbin-psql-watcher v1.0.0 github.com/Microsoft/go-winio v0.6.2 // indirect github.com/ProtonMail/go-crypto v1.1.6 // indirect github.com/ThalesIgnite/crypto11 v1.2.5 // indirect diff --git a/go.sum b/go.sum index 559f81d96..0b3e0616a 100644 --- a/go.sum +++ b/go.sum @@ -108,8 +108,6 @@ github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0 github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.50.0/go.mod h1:SZiPHWGOOk3bl8tkevxkoiwPgsIl6CwrWcbwjfHZpdM= github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.50.0 h1:ig/FpDD2JofP/NExKQUbn7uOSZzJAQqogfqluZK4ed4= github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.50.0/go.mod h1:otE2jQekW/PqXk1Awf5lmfokJx4uwuqcj1ab5SpGeW0= -github.com/IguteChung/casbin-psql-watcher v1.0.0 h1:GO5RvdHq5WZfuKt03Frk4/SvYvikMI5V1zjSt1P1suM= -github.com/IguteChung/casbin-psql-watcher v1.0.0/go.mod h1:mwQYBxiYGO05U8vogls8gf3KnOmdlc7GOLX7tS/V2TU= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= @@ -273,8 +271,6 @@ github.com/bytecodealliance/wasmtime-go/v3 v3.0.2/go.mod h1:RnUjnIXxEJcL6BgCvNyz github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/casbin/casbin/v2 v2.103.0 h1:dHElatNXNrr8XcseUov0ZSiWjauwmZZE6YMV3eU1yic= github.com/casbin/casbin/v2 v2.103.0/go.mod h1:Ee33aqGrmES+GNL17L0h9X28wXuo829wnNUnS0edAco= -github.com/casbin/ent-adapter v0.5.0 h1:ZS92OFmNkYF1G972Uy9XG3Zkr4rJ/glyzs98JxfH7Uc= -github.com/casbin/ent-adapter v0.5.0/go.mod h1:V4eFuva0HzqiQAyByjri1HYT9JlFd0zPULQIzqLht5U= github.com/casbin/govaluate v1.3.0 h1:VA0eSY0M2lA86dYd5kPPuNZMUD9QkWnOCnavGrw9myc= github.com/casbin/govaluate v1.3.0/go.mod h1:G/UnbIjZk/0uMNaLwZZmFQrR72tYRZWQkO70si/iR7A= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= From 9c3e5fa7146db3559ccecd8aa221ac266f2b4a8e Mon Sep 17 00:00:00 2001 From: Miguel Martinez Date: Sat, 8 Nov 2025 01:10:26 +0100 Subject: [PATCH 2/8] refactor: migrate Casbin to in-memory enforcer with database-stored token policies Refactored the authorization system to improve performance and simplify architecture by moving from database-stored Casbin policies to an in-memory enforcer for role-based access control while storing API token policies directly in the database. Benefits: - Improved performance by eliminating database queries for role policy lookups - Simplified architecture with clear separation between user RBAC and token ACL - Reduced infrastructure dependencies by removing PostgreSQL adapter requirement - More flexible token permissions management stored alongside token metadata - Easier to reason about authorization flow with explicit dual enforcement model Technical changes: - Casbin now uses in-memory adapter for static role policies - API token ACL policies stored in new policies JSONB field - Added EnforceWithPolicies method for token-based authorization - Migration populates existing tokens with default policies - Updated middleware to route users and tokens to appropriate enforcement methods - Removed database adapter dependencies and related sync logic Signed-off-by: Miguel Martinez --- .../pkg/authz/middleware/.mockery.yml | 17 ++ .../pkg/authz/middleware/mocks_test.go | 175 ++++++++++++++++++ .../ent/migrate/migrations/20251107233855.sql | 26 +++ 3 files changed, 218 insertions(+) create mode 100644 app/controlplane/pkg/authz/middleware/.mockery.yml create mode 100644 app/controlplane/pkg/authz/middleware/mocks_test.go create mode 100644 app/controlplane/pkg/data/ent/migrate/migrations/20251107233855.sql diff --git a/app/controlplane/pkg/authz/middleware/.mockery.yml b/app/controlplane/pkg/authz/middleware/.mockery.yml new file mode 100644 index 000000000..3d0f1bd4d --- /dev/null +++ b/app/controlplane/pkg/authz/middleware/.mockery.yml @@ -0,0 +1,17 @@ +all: false +dir: '{{.InterfaceDir}}' +filename: mocks_test.go +force-file-write: true +formatter: goimports +include-auto-generated: false +log-level: info +structname: '{{.Mock}}{{.InterfaceName}}' +pkgname: '{{.SrcPackageName}}' +recursive: false +require-template-schema-exists: true +template: testify +template-schema: '{{.Template}}.schema.json' +packages: + github.com/chainloop-dev/chainloop/app/controlplane/pkg/authz/middleware: + interfaces: + Enforcer: diff --git a/app/controlplane/pkg/authz/middleware/mocks_test.go b/app/controlplane/pkg/authz/middleware/mocks_test.go new file mode 100644 index 000000000..5ff102e86 --- /dev/null +++ b/app/controlplane/pkg/authz/middleware/mocks_test.go @@ -0,0 +1,175 @@ +// Code generated by mockery; DO NOT EDIT. +// github.com/vektra/mockery +// template: testify + +package middleware + +import ( + "github.com/chainloop-dev/chainloop/app/controlplane/pkg/authz" + mock "github.com/stretchr/testify/mock" +) + +// NewMockEnforcer creates a new instance of MockEnforcer. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockEnforcer(t interface { + mock.TestingT + Cleanup(func()) +}) *MockEnforcer { + mock := &MockEnforcer{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} + +// MockEnforcer is an autogenerated mock type for the Enforcer type +type MockEnforcer struct { + mock.Mock +} + +type MockEnforcer_Expecter struct { + mock *mock.Mock +} + +func (_m *MockEnforcer) EXPECT() *MockEnforcer_Expecter { + return &MockEnforcer_Expecter{mock: &_m.Mock} +} + +// Enforce provides a mock function for the type MockEnforcer +func (_mock *MockEnforcer) Enforce(sub string, p *authz.Policy) (bool, error) { + ret := _mock.Called(sub, p) + + if len(ret) == 0 { + panic("no return value specified for Enforce") + } + + var r0 bool + var r1 error + if returnFunc, ok := ret.Get(0).(func(string, *authz.Policy) (bool, error)); ok { + return returnFunc(sub, p) + } + if returnFunc, ok := ret.Get(0).(func(string, *authz.Policy) bool); ok { + r0 = returnFunc(sub, p) + } else { + r0 = ret.Get(0).(bool) + } + if returnFunc, ok := ret.Get(1).(func(string, *authz.Policy) error); ok { + r1 = returnFunc(sub, p) + } else { + r1 = ret.Error(1) + } + return r0, r1 +} + +// MockEnforcer_Enforce_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Enforce' +type MockEnforcer_Enforce_Call struct { + *mock.Call +} + +// Enforce is a helper method to define mock.On call +// - sub string +// - p *authz.Policy +func (_e *MockEnforcer_Expecter) Enforce(sub interface{}, p interface{}) *MockEnforcer_Enforce_Call { + return &MockEnforcer_Enforce_Call{Call: _e.mock.On("Enforce", sub, p)} +} + +func (_c *MockEnforcer_Enforce_Call) Run(run func(sub string, p *authz.Policy)) *MockEnforcer_Enforce_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + var arg1 *authz.Policy + if args[1] != nil { + arg1 = args[1].(*authz.Policy) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *MockEnforcer_Enforce_Call) Return(b bool, err error) *MockEnforcer_Enforce_Call { + _c.Call.Return(b, err) + return _c +} + +func (_c *MockEnforcer_Enforce_Call) RunAndReturn(run func(sub string, p *authz.Policy) (bool, error)) *MockEnforcer_Enforce_Call { + _c.Call.Return(run) + return _c +} + +// EnforceWithPolicies provides a mock function for the type MockEnforcer +func (_mock *MockEnforcer) EnforceWithPolicies(sub string, p *authz.Policy, allowedPolicies []*authz.Policy) (bool, error) { + ret := _mock.Called(sub, p, allowedPolicies) + + if len(ret) == 0 { + panic("no return value specified for EnforceWithPolicies") + } + + var r0 bool + var r1 error + if returnFunc, ok := ret.Get(0).(func(string, *authz.Policy, []*authz.Policy) (bool, error)); ok { + return returnFunc(sub, p, allowedPolicies) + } + if returnFunc, ok := ret.Get(0).(func(string, *authz.Policy, []*authz.Policy) bool); ok { + r0 = returnFunc(sub, p, allowedPolicies) + } else { + r0 = ret.Get(0).(bool) + } + if returnFunc, ok := ret.Get(1).(func(string, *authz.Policy, []*authz.Policy) error); ok { + r1 = returnFunc(sub, p, allowedPolicies) + } else { + r1 = ret.Error(1) + } + return r0, r1 +} + +// MockEnforcer_EnforceWithPolicies_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'EnforceWithPolicies' +type MockEnforcer_EnforceWithPolicies_Call struct { + *mock.Call +} + +// EnforceWithPolicies is a helper method to define mock.On call +// - sub string +// - p *authz.Policy +// - allowedPolicies []*authz.Policy +func (_e *MockEnforcer_Expecter) EnforceWithPolicies(sub interface{}, p interface{}, allowedPolicies interface{}) *MockEnforcer_EnforceWithPolicies_Call { + return &MockEnforcer_EnforceWithPolicies_Call{Call: _e.mock.On("EnforceWithPolicies", sub, p, allowedPolicies)} +} + +func (_c *MockEnforcer_EnforceWithPolicies_Call) Run(run func(sub string, p *authz.Policy, allowedPolicies []*authz.Policy)) *MockEnforcer_EnforceWithPolicies_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + var arg1 *authz.Policy + if args[1] != nil { + arg1 = args[1].(*authz.Policy) + } + var arg2 []*authz.Policy + if args[2] != nil { + arg2 = args[2].([]*authz.Policy) + } + run( + arg0, + arg1, + arg2, + ) + }) + return _c +} + +func (_c *MockEnforcer_EnforceWithPolicies_Call) Return(b bool, err error) *MockEnforcer_EnforceWithPolicies_Call { + _c.Call.Return(b, err) + return _c +} + +func (_c *MockEnforcer_EnforceWithPolicies_Call) RunAndReturn(run func(sub string, p *authz.Policy, allowedPolicies []*authz.Policy) (bool, error)) *MockEnforcer_EnforceWithPolicies_Call { + _c.Call.Return(run) + return _c +} diff --git a/app/controlplane/pkg/data/ent/migrate/migrations/20251107233855.sql b/app/controlplane/pkg/data/ent/migrate/migrations/20251107233855.sql new file mode 100644 index 000000000..fe961a921 --- /dev/null +++ b/app/controlplane/pkg/data/ent/migrate/migrations/20251107233855.sql @@ -0,0 +1,26 @@ +-- Modify "api_tokens" table +ALTER TABLE "api_tokens" ADD COLUMN "policies" jsonb NULL; +-- Populate existing tokens with default policies +UPDATE "api_tokens" SET "policies" = '[ + {"Resource": "workflow_run", "Action": "list"}, + {"Resource": "workflow_run", "Action": "read"}, + {"Resource": "workflow", "Action": "read"}, + {"Resource": "workflow", "Action": "list"}, + {"Resource": "workflow", "Action": "create"}, + {"Resource": "workflow_contract", "Action": "list"}, + {"Resource": "workflow_contract", "Action": "read"}, + {"Resource": "workflow_contract", "Action": "update"}, + {"Resource": "workflow_contract", "Action": "create"}, + {"Resource": "cas_artifact", "Action": "read"}, + {"Resource": "referrer", "Action": "read"}, + {"Resource": "organization", "Action": "read"}, + {"Resource": "robot_account", "Action": "create"}, + {"Resource": "integration_available", "Action": "read"}, + {"Resource": "integration_available", "Action": "list"}, + {"Resource": "integration_registered", "Action": "list"}, + {"Resource": "integration_registered", "Action": "read"}, + {"Resource": "integration_registered", "Action": "create"}, + {"Resource": "integration_attached", "Action": "list"}, + {"Resource": "integration_attached", "Action": "create"}, + {"Resource": "cas_artifact", "Action": "create"} +]'::jsonb WHERE "policies" IS NULL; From 8f2e4a0cd6174b47c6d1f2753d192b7c3713522a Mon Sep 17 00:00:00 2001 From: Miguel Martinez Date: Sat, 8 Nov 2025 01:30:48 +0100 Subject: [PATCH 3/8] chore: cleanup obsolete tests and consolidate mocks Removed obsolete test for database sync behavior and consolidated to mockery v3 mocks package. Changes: - Removed TestSyncMultipleEnforcers (tested database sync, no longer relevant with in-memory enforcer) - Migrated casbackend_test.go to use mocks package instead of mocks_test.go - Deleted pkg/biz/mocks_test.go (replaced by pkg/biz/mocks/ package) - Added mockery v3 and API token policies notes to CLAUDE.md Signed-off-by: Miguel Martinez --- CLAUDE.md | 3 + app/controlplane/pkg/authz/authz_test.go | 118 -- app/controlplane/pkg/biz/casbackend_test.go | 7 +- app/controlplane/pkg/biz/mocks_test.go | 1820 ------------------- 4 files changed, 7 insertions(+), 1941 deletions(-) delete mode 100644 app/controlplane/pkg/biz/mocks_test.go diff --git a/CLAUDE.md b/CLAUDE.md index de9c1263c..bd0777e60 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -217,9 +217,12 @@ The project heavily uses code generation: - **Wire**: Dependency injection - **Ent**: ORM models and queries - **Buf**: Protobuf tooling and validation +- **Mockery v3**: Test mocks - add interface to `.mockery.yml`, run `mockery` from that directory Always run `make generate` after modifying .proto files or Ent schemas. +**API Token Policies**: If modifying `DefaultAuthzPolicies` in `pkg/biz/apitoken.go`, create a migration to update existing tokens' `policies` field - they're stored in DB, not loaded dynamically. + ## Contract-Based Development Workflow Contracts define the structure and requirements for CI/CD attestations. They specify what materials must be collected and policies that must be evaluated. diff --git a/app/controlplane/pkg/authz/authz_test.go b/app/controlplane/pkg/authz/authz_test.go index 81bad1954..6621cc79c 100644 --- a/app/controlplane/pkg/authz/authz_test.go +++ b/app/controlplane/pkg/authz/authz_test.go @@ -24,124 +24,6 @@ import ( "github.com/stretchr/testify/require" ) - -// simulate 2 enforcers on the same database (by acting on the same file enforcer) -func TestSyncMultipleEnforcers(t *testing.T) { - testCases := []struct { - name string - newEnforcerConfig *Config - expectErr bool - numPolicies int - numSubjects int - numAdminActions int - }{ - { - name: "empty config", - newEnforcerConfig: &Config{}, - expectErr: false, - numPolicies: 3, - numSubjects: 2, - numAdminActions: 2, - }, - { - name: "new actions on different resources for same roles", - newEnforcerConfig: &Config{ - ManagedResources: []string{ResourceGroup}, - RolesMap: map[Role][]*Policy{ - RoleAdmin: {{ - Resource: ResourceGroup, - Action: ActionCreate, - }}, - }, - }, - expectErr: false, - numPolicies: 4, - numSubjects: 2, - numAdminActions: 3, - }, - { - name: "new actions on different resources for new roles", - newEnforcerConfig: &Config{ - ManagedResources: []string{ResourceGroup}, - RolesMap: map[Role][]*Policy{ - RoleProjectAdmin: {{ - Resource: ResourceGroup, - Action: ActionCreate, - }}, - }, - }, - expectErr: false, - numSubjects: 3, - numPolicies: 4, - numAdminActions: 2, - }, - { - name: "reset admin actions on same resource, collision", - newEnforcerConfig: &Config{ - ManagedResources: []string{ResourceWorkflow}, - RolesMap: map[Role][]*Policy{ - RoleAdmin: {}, // this should remove all admin actions from enforcer - }, - }, - expectErr: false, - numSubjects: 1, - numPolicies: 1, - numAdminActions: 0, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - e, c := testEnforcer(t) - defer c.Close() - - // initial import - err := syncRBACRoles(e, &Config{ - ManagedResources: []string{ResourceWorkflow, ResourceWorkflowRun}, - RolesMap: map[Role][]*Policy{ - RoleAdmin: {{ - Resource: ResourceWorkflow, - Action: ActionCreate, - }, { - Resource: ResourceWorkflow, - Action: ActionDelete, - }}, - RoleOrgMember: {{ - Resource: ResourceWorkflowRun, - Action: ActionList, - }}, - }, - }) - require.NoError(t, err) - - // sync with test case config - err = syncRBACRoles(e, tc.newEnforcerConfig) - if tc.expectErr { - assert.Error(t, err) - return - } - assert.NoError(t, err) - - policies, err := e.GetPolicy() - assert.NoError(t, err) - assert.Len(t, policies, tc.numPolicies) - - adminCount := 0 - for _, r := range policies { - if r[0] == string(RoleAdmin) { - adminCount++ - } - } - assert.Equal(t, tc.numAdminActions, adminCount) - - subs, err := e.GetAllSubjects() - assert.NoError(t, err) - assert.Len(t, subs, tc.numSubjects) // We need to count the Viewer role - }) - } -} - - func TestSyncRBACRoles(t *testing.T) { e, closer := testEnforcer(t) defer closer.Close() diff --git a/app/controlplane/pkg/biz/casbackend_test.go b/app/controlplane/pkg/biz/casbackend_test.go index e57b1bd99..54afa8141 100644 --- a/app/controlplane/pkg/biz/casbackend_test.go +++ b/app/controlplane/pkg/biz/casbackend_test.go @@ -1,5 +1,5 @@ // -// Copyright 2024 The Chainloop Authors. +// Copyright 2024-2025 The Chainloop Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ import ( "testing" "github.com/chainloop-dev/chainloop/app/controlplane/pkg/biz" + bizMocks "github.com/chainloop-dev/chainloop/app/controlplane/pkg/biz/mocks" backends "github.com/chainloop-dev/chainloop/pkg/blobmanager" blobM "github.com/chainloop-dev/chainloop/pkg/blobmanager/mocks" "github.com/chainloop-dev/chainloop/pkg/credentials" @@ -36,7 +37,7 @@ type casBackendTestSuite struct { validUUID uuid.UUID invalidUUID string useCase *biz.CASBackendUseCase - repo *biz.MockCASBackendRepo + repo *bizMocks.CASBackendRepo credsRW *credentialsM.ReaderWriter backendProvider *blobM.Provider } @@ -277,7 +278,7 @@ func (s *casBackendTestSuite) resetMock() { func (s *casBackendTestSuite) SetupTest() { s.validUUID = uuid.New() s.invalidUUID = "deadbeef" - s.repo = biz.NewMockCASBackendRepo(s.T()) + s.repo = bizMocks.NewCASBackendRepo(s.T()) s.credsRW = credentialsM.NewReaderWriter(s.T()) s.backendProvider = blobM.NewProvider(s.T()) var err error diff --git a/app/controlplane/pkg/biz/mocks_test.go b/app/controlplane/pkg/biz/mocks_test.go deleted file mode 100644 index 4452ecb26..000000000 --- a/app/controlplane/pkg/biz/mocks_test.go +++ /dev/null @@ -1,1820 +0,0 @@ -// Code generated by mockery; DO NOT EDIT. -// github.com/vektra/mockery -// template: testify - -package biz - -import ( - "context" - "time" - - "github.com/chainloop-dev/chainloop/app/controlplane/pkg/authz" - "github.com/google/uuid" - mock "github.com/stretchr/testify/mock" -) - -// NewMockAPITokenRepo creates a new instance of MockAPITokenRepo. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -// The first argument is typically a *testing.T value. -func NewMockAPITokenRepo(t interface { - mock.TestingT - Cleanup(func()) -}) *MockAPITokenRepo { - mock := &MockAPITokenRepo{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} - -// MockAPITokenRepo is an autogenerated mock type for the APITokenRepo type -type MockAPITokenRepo struct { - mock.Mock -} - -type MockAPITokenRepo_Expecter struct { - mock *mock.Mock -} - -func (_m *MockAPITokenRepo) EXPECT() *MockAPITokenRepo_Expecter { - return &MockAPITokenRepo_Expecter{mock: &_m.Mock} -} - -// Create provides a mock function for the type MockAPITokenRepo -func (_mock *MockAPITokenRepo) Create(ctx context.Context, name string, description *string, expiresAt *time.Time, organizationID uuid.UUID, projectID *uuid.UUID, policies []*authz.Policy) (*APIToken, error) { - ret := _mock.Called(ctx, name, description, expiresAt, organizationID, projectID, policies) - - if len(ret) == 0 { - panic("no return value specified for Create") - } - - var r0 *APIToken - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, string, *string, *time.Time, uuid.UUID, *uuid.UUID, []*authz.Policy) (*APIToken, error)); ok { - return returnFunc(ctx, name, description, expiresAt, organizationID, projectID, policies) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, string, *string, *time.Time, uuid.UUID, *uuid.UUID, []*authz.Policy) *APIToken); ok { - r0 = returnFunc(ctx, name, description, expiresAt, organizationID, projectID, policies) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*APIToken) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, string, *string, *time.Time, uuid.UUID, *uuid.UUID, []*authz.Policy) error); ok { - r1 = returnFunc(ctx, name, description, expiresAt, organizationID, projectID, policies) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// MockAPITokenRepo_Create_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Create' -type MockAPITokenRepo_Create_Call struct { - *mock.Call -} - -// Create is a helper method to define mock.On call -// - ctx context.Context -// - name string -// - description *string -// - expiresAt *time.Time -// - organizationID uuid.UUID -// - projectID *uuid.UUID -// - policies []*authz.Policy -func (_e *MockAPITokenRepo_Expecter) Create(ctx interface{}, name interface{}, description interface{}, expiresAt interface{}, organizationID interface{}, projectID interface{}, policies interface{}) *MockAPITokenRepo_Create_Call { - return &MockAPITokenRepo_Create_Call{Call: _e.mock.On("Create", ctx, name, description, expiresAt, organizationID, projectID, policies)} -} - -func (_c *MockAPITokenRepo_Create_Call) Run(run func(ctx context.Context, name string, description *string, expiresAt *time.Time, organizationID uuid.UUID, projectID *uuid.UUID, policies []*authz.Policy)) *MockAPITokenRepo_Create_Call { - _c.Call.Run(func(args mock.Arguments) { - var arg0 context.Context - if args[0] != nil { - arg0 = args[0].(context.Context) - } - var arg1 string - if args[1] != nil { - arg1 = args[1].(string) - } - var arg2 *string - if args[2] != nil { - arg2 = args[2].(*string) - } - var arg3 *time.Time - if args[3] != nil { - arg3 = args[3].(*time.Time) - } - var arg4 uuid.UUID - if args[4] != nil { - arg4 = args[4].(uuid.UUID) - } - var arg5 *uuid.UUID - if args[5] != nil { - arg5 = args[5].(*uuid.UUID) - } - var arg6 []*authz.Policy - if args[6] != nil { - arg6 = args[6].([]*authz.Policy) - } - run( - arg0, - arg1, - arg2, - arg3, - arg4, - arg5, - arg6, - ) - }) - return _c -} - -func (_c *MockAPITokenRepo_Create_Call) Return(aPIToken *APIToken, err error) *MockAPITokenRepo_Create_Call { - _c.Call.Return(aPIToken, err) - return _c -} - -func (_c *MockAPITokenRepo_Create_Call) RunAndReturn(run func(ctx context.Context, name string, description *string, expiresAt *time.Time, organizationID uuid.UUID, projectID *uuid.UUID, policies []*authz.Policy) (*APIToken, error)) *MockAPITokenRepo_Create_Call { - _c.Call.Return(run) - return _c -} - -// FindByID provides a mock function for the type MockAPITokenRepo -func (_mock *MockAPITokenRepo) FindByID(ctx context.Context, ID uuid.UUID) (*APIToken, error) { - ret := _mock.Called(ctx, ID) - - if len(ret) == 0 { - panic("no return value specified for FindByID") - } - - var r0 *APIToken - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID) (*APIToken, error)); ok { - return returnFunc(ctx, ID) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID) *APIToken); ok { - r0 = returnFunc(ctx, ID) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*APIToken) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, uuid.UUID) error); ok { - r1 = returnFunc(ctx, ID) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// MockAPITokenRepo_FindByID_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FindByID' -type MockAPITokenRepo_FindByID_Call struct { - *mock.Call -} - -// FindByID is a helper method to define mock.On call -// - ctx context.Context -// - ID uuid.UUID -func (_e *MockAPITokenRepo_Expecter) FindByID(ctx interface{}, ID interface{}) *MockAPITokenRepo_FindByID_Call { - return &MockAPITokenRepo_FindByID_Call{Call: _e.mock.On("FindByID", ctx, ID)} -} - -func (_c *MockAPITokenRepo_FindByID_Call) Run(run func(ctx context.Context, ID uuid.UUID)) *MockAPITokenRepo_FindByID_Call { - _c.Call.Run(func(args mock.Arguments) { - var arg0 context.Context - if args[0] != nil { - arg0 = args[0].(context.Context) - } - var arg1 uuid.UUID - if args[1] != nil { - arg1 = args[1].(uuid.UUID) - } - run( - arg0, - arg1, - ) - }) - return _c -} - -func (_c *MockAPITokenRepo_FindByID_Call) Return(aPIToken *APIToken, err error) *MockAPITokenRepo_FindByID_Call { - _c.Call.Return(aPIToken, err) - return _c -} - -func (_c *MockAPITokenRepo_FindByID_Call) RunAndReturn(run func(ctx context.Context, ID uuid.UUID) (*APIToken, error)) *MockAPITokenRepo_FindByID_Call { - _c.Call.Return(run) - return _c -} - -// FindByIDInOrg provides a mock function for the type MockAPITokenRepo -func (_mock *MockAPITokenRepo) FindByIDInOrg(ctx context.Context, orgID uuid.UUID, id uuid.UUID) (*APIToken, error) { - ret := _mock.Called(ctx, orgID, id) - - if len(ret) == 0 { - panic("no return value specified for FindByIDInOrg") - } - - var r0 *APIToken - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID, uuid.UUID) (*APIToken, error)); ok { - return returnFunc(ctx, orgID, id) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID, uuid.UUID) *APIToken); ok { - r0 = returnFunc(ctx, orgID, id) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*APIToken) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, uuid.UUID, uuid.UUID) error); ok { - r1 = returnFunc(ctx, orgID, id) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// MockAPITokenRepo_FindByIDInOrg_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FindByIDInOrg' -type MockAPITokenRepo_FindByIDInOrg_Call struct { - *mock.Call -} - -// FindByIDInOrg is a helper method to define mock.On call -// - ctx context.Context -// - orgID uuid.UUID -// - id uuid.UUID -func (_e *MockAPITokenRepo_Expecter) FindByIDInOrg(ctx interface{}, orgID interface{}, id interface{}) *MockAPITokenRepo_FindByIDInOrg_Call { - return &MockAPITokenRepo_FindByIDInOrg_Call{Call: _e.mock.On("FindByIDInOrg", ctx, orgID, id)} -} - -func (_c *MockAPITokenRepo_FindByIDInOrg_Call) Run(run func(ctx context.Context, orgID uuid.UUID, id uuid.UUID)) *MockAPITokenRepo_FindByIDInOrg_Call { - _c.Call.Run(func(args mock.Arguments) { - var arg0 context.Context - if args[0] != nil { - arg0 = args[0].(context.Context) - } - var arg1 uuid.UUID - if args[1] != nil { - arg1 = args[1].(uuid.UUID) - } - var arg2 uuid.UUID - if args[2] != nil { - arg2 = args[2].(uuid.UUID) - } - run( - arg0, - arg1, - arg2, - ) - }) - return _c -} - -func (_c *MockAPITokenRepo_FindByIDInOrg_Call) Return(aPIToken *APIToken, err error) *MockAPITokenRepo_FindByIDInOrg_Call { - _c.Call.Return(aPIToken, err) - return _c -} - -func (_c *MockAPITokenRepo_FindByIDInOrg_Call) RunAndReturn(run func(ctx context.Context, orgID uuid.UUID, id uuid.UUID) (*APIToken, error)) *MockAPITokenRepo_FindByIDInOrg_Call { - _c.Call.Return(run) - return _c -} - -// FindByNameInOrg provides a mock function for the type MockAPITokenRepo -func (_mock *MockAPITokenRepo) FindByNameInOrg(ctx context.Context, orgID uuid.UUID, name string) (*APIToken, error) { - ret := _mock.Called(ctx, orgID, name) - - if len(ret) == 0 { - panic("no return value specified for FindByNameInOrg") - } - - var r0 *APIToken - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID, string) (*APIToken, error)); ok { - return returnFunc(ctx, orgID, name) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID, string) *APIToken); ok { - r0 = returnFunc(ctx, orgID, name) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*APIToken) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, uuid.UUID, string) error); ok { - r1 = returnFunc(ctx, orgID, name) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// MockAPITokenRepo_FindByNameInOrg_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FindByNameInOrg' -type MockAPITokenRepo_FindByNameInOrg_Call struct { - *mock.Call -} - -// FindByNameInOrg is a helper method to define mock.On call -// - ctx context.Context -// - orgID uuid.UUID -// - name string -func (_e *MockAPITokenRepo_Expecter) FindByNameInOrg(ctx interface{}, orgID interface{}, name interface{}) *MockAPITokenRepo_FindByNameInOrg_Call { - return &MockAPITokenRepo_FindByNameInOrg_Call{Call: _e.mock.On("FindByNameInOrg", ctx, orgID, name)} -} - -func (_c *MockAPITokenRepo_FindByNameInOrg_Call) Run(run func(ctx context.Context, orgID uuid.UUID, name string)) *MockAPITokenRepo_FindByNameInOrg_Call { - _c.Call.Run(func(args mock.Arguments) { - var arg0 context.Context - if args[0] != nil { - arg0 = args[0].(context.Context) - } - var arg1 uuid.UUID - if args[1] != nil { - arg1 = args[1].(uuid.UUID) - } - var arg2 string - if args[2] != nil { - arg2 = args[2].(string) - } - run( - arg0, - arg1, - arg2, - ) - }) - return _c -} - -func (_c *MockAPITokenRepo_FindByNameInOrg_Call) Return(aPIToken *APIToken, err error) *MockAPITokenRepo_FindByNameInOrg_Call { - _c.Call.Return(aPIToken, err) - return _c -} - -func (_c *MockAPITokenRepo_FindByNameInOrg_Call) RunAndReturn(run func(ctx context.Context, orgID uuid.UUID, name string) (*APIToken, error)) *MockAPITokenRepo_FindByNameInOrg_Call { - _c.Call.Return(run) - return _c -} - -// List provides a mock function for the type MockAPITokenRepo -func (_mock *MockAPITokenRepo) List(ctx context.Context, orgID *uuid.UUID, filters *APITokenListFilters) ([]*APIToken, error) { - ret := _mock.Called(ctx, orgID, filters) - - if len(ret) == 0 { - panic("no return value specified for List") - } - - var r0 []*APIToken - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, *uuid.UUID, *APITokenListFilters) ([]*APIToken, error)); ok { - return returnFunc(ctx, orgID, filters) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, *uuid.UUID, *APITokenListFilters) []*APIToken); ok { - r0 = returnFunc(ctx, orgID, filters) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]*APIToken) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, *uuid.UUID, *APITokenListFilters) error); ok { - r1 = returnFunc(ctx, orgID, filters) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// MockAPITokenRepo_List_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'List' -type MockAPITokenRepo_List_Call struct { - *mock.Call -} - -// List is a helper method to define mock.On call -// - ctx context.Context -// - orgID *uuid.UUID -// - filters *APITokenListFilters -func (_e *MockAPITokenRepo_Expecter) List(ctx interface{}, orgID interface{}, filters interface{}) *MockAPITokenRepo_List_Call { - return &MockAPITokenRepo_List_Call{Call: _e.mock.On("List", ctx, orgID, filters)} -} - -func (_c *MockAPITokenRepo_List_Call) Run(run func(ctx context.Context, orgID *uuid.UUID, filters *APITokenListFilters)) *MockAPITokenRepo_List_Call { - _c.Call.Run(func(args mock.Arguments) { - var arg0 context.Context - if args[0] != nil { - arg0 = args[0].(context.Context) - } - var arg1 *uuid.UUID - if args[1] != nil { - arg1 = args[1].(*uuid.UUID) - } - var arg2 *APITokenListFilters - if args[2] != nil { - arg2 = args[2].(*APITokenListFilters) - } - run( - arg0, - arg1, - arg2, - ) - }) - return _c -} - -func (_c *MockAPITokenRepo_List_Call) Return(aPITokens []*APIToken, err error) *MockAPITokenRepo_List_Call { - _c.Call.Return(aPITokens, err) - return _c -} - -func (_c *MockAPITokenRepo_List_Call) RunAndReturn(run func(ctx context.Context, orgID *uuid.UUID, filters *APITokenListFilters) ([]*APIToken, error)) *MockAPITokenRepo_List_Call { - _c.Call.Return(run) - return _c -} - -// Revoke provides a mock function for the type MockAPITokenRepo -func (_mock *MockAPITokenRepo) Revoke(ctx context.Context, orgID uuid.UUID, ID uuid.UUID) error { - ret := _mock.Called(ctx, orgID, ID) - - if len(ret) == 0 { - panic("no return value specified for Revoke") - } - - var r0 error - if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID, uuid.UUID) error); ok { - r0 = returnFunc(ctx, orgID, ID) - } else { - r0 = ret.Error(0) - } - return r0 -} - -// MockAPITokenRepo_Revoke_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Revoke' -type MockAPITokenRepo_Revoke_Call struct { - *mock.Call -} - -// Revoke is a helper method to define mock.On call -// - ctx context.Context -// - orgID uuid.UUID -// - ID uuid.UUID -func (_e *MockAPITokenRepo_Expecter) Revoke(ctx interface{}, orgID interface{}, ID interface{}) *MockAPITokenRepo_Revoke_Call { - return &MockAPITokenRepo_Revoke_Call{Call: _e.mock.On("Revoke", ctx, orgID, ID)} -} - -func (_c *MockAPITokenRepo_Revoke_Call) Run(run func(ctx context.Context, orgID uuid.UUID, ID uuid.UUID)) *MockAPITokenRepo_Revoke_Call { - _c.Call.Run(func(args mock.Arguments) { - var arg0 context.Context - if args[0] != nil { - arg0 = args[0].(context.Context) - } - var arg1 uuid.UUID - if args[1] != nil { - arg1 = args[1].(uuid.UUID) - } - var arg2 uuid.UUID - if args[2] != nil { - arg2 = args[2].(uuid.UUID) - } - run( - arg0, - arg1, - arg2, - ) - }) - return _c -} - -func (_c *MockAPITokenRepo_Revoke_Call) Return(err error) *MockAPITokenRepo_Revoke_Call { - _c.Call.Return(err) - return _c -} - -func (_c *MockAPITokenRepo_Revoke_Call) RunAndReturn(run func(ctx context.Context, orgID uuid.UUID, ID uuid.UUID) error) *MockAPITokenRepo_Revoke_Call { - _c.Call.Return(run) - return _c -} - -// UpdateExpiration provides a mock function for the type MockAPITokenRepo -func (_mock *MockAPITokenRepo) UpdateExpiration(ctx context.Context, ID uuid.UUID, expiresAt time.Time) error { - ret := _mock.Called(ctx, ID, expiresAt) - - if len(ret) == 0 { - panic("no return value specified for UpdateExpiration") - } - - var r0 error - if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID, time.Time) error); ok { - r0 = returnFunc(ctx, ID, expiresAt) - } else { - r0 = ret.Error(0) - } - return r0 -} - -// MockAPITokenRepo_UpdateExpiration_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpdateExpiration' -type MockAPITokenRepo_UpdateExpiration_Call struct { - *mock.Call -} - -// UpdateExpiration is a helper method to define mock.On call -// - ctx context.Context -// - ID uuid.UUID -// - expiresAt time.Time -func (_e *MockAPITokenRepo_Expecter) UpdateExpiration(ctx interface{}, ID interface{}, expiresAt interface{}) *MockAPITokenRepo_UpdateExpiration_Call { - return &MockAPITokenRepo_UpdateExpiration_Call{Call: _e.mock.On("UpdateExpiration", ctx, ID, expiresAt)} -} - -func (_c *MockAPITokenRepo_UpdateExpiration_Call) Run(run func(ctx context.Context, ID uuid.UUID, expiresAt time.Time)) *MockAPITokenRepo_UpdateExpiration_Call { - _c.Call.Run(func(args mock.Arguments) { - var arg0 context.Context - if args[0] != nil { - arg0 = args[0].(context.Context) - } - var arg1 uuid.UUID - if args[1] != nil { - arg1 = args[1].(uuid.UUID) - } - var arg2 time.Time - if args[2] != nil { - arg2 = args[2].(time.Time) - } - run( - arg0, - arg1, - arg2, - ) - }) - return _c -} - -func (_c *MockAPITokenRepo_UpdateExpiration_Call) Return(err error) *MockAPITokenRepo_UpdateExpiration_Call { - _c.Call.Return(err) - return _c -} - -func (_c *MockAPITokenRepo_UpdateExpiration_Call) RunAndReturn(run func(ctx context.Context, ID uuid.UUID, expiresAt time.Time) error) *MockAPITokenRepo_UpdateExpiration_Call { - _c.Call.Return(run) - return _c -} - -// UpdateLastUsedAt provides a mock function for the type MockAPITokenRepo -func (_mock *MockAPITokenRepo) UpdateLastUsedAt(ctx context.Context, ID uuid.UUID, lastUsedAt time.Time) error { - ret := _mock.Called(ctx, ID, lastUsedAt) - - if len(ret) == 0 { - panic("no return value specified for UpdateLastUsedAt") - } - - var r0 error - if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID, time.Time) error); ok { - r0 = returnFunc(ctx, ID, lastUsedAt) - } else { - r0 = ret.Error(0) - } - return r0 -} - -// MockAPITokenRepo_UpdateLastUsedAt_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpdateLastUsedAt' -type MockAPITokenRepo_UpdateLastUsedAt_Call struct { - *mock.Call -} - -// UpdateLastUsedAt is a helper method to define mock.On call -// - ctx context.Context -// - ID uuid.UUID -// - lastUsedAt time.Time -func (_e *MockAPITokenRepo_Expecter) UpdateLastUsedAt(ctx interface{}, ID interface{}, lastUsedAt interface{}) *MockAPITokenRepo_UpdateLastUsedAt_Call { - return &MockAPITokenRepo_UpdateLastUsedAt_Call{Call: _e.mock.On("UpdateLastUsedAt", ctx, ID, lastUsedAt)} -} - -func (_c *MockAPITokenRepo_UpdateLastUsedAt_Call) Run(run func(ctx context.Context, ID uuid.UUID, lastUsedAt time.Time)) *MockAPITokenRepo_UpdateLastUsedAt_Call { - _c.Call.Run(func(args mock.Arguments) { - var arg0 context.Context - if args[0] != nil { - arg0 = args[0].(context.Context) - } - var arg1 uuid.UUID - if args[1] != nil { - arg1 = args[1].(uuid.UUID) - } - var arg2 time.Time - if args[2] != nil { - arg2 = args[2].(time.Time) - } - run( - arg0, - arg1, - arg2, - ) - }) - return _c -} - -func (_c *MockAPITokenRepo_UpdateLastUsedAt_Call) Return(err error) *MockAPITokenRepo_UpdateLastUsedAt_Call { - _c.Call.Return(err) - return _c -} - -func (_c *MockAPITokenRepo_UpdateLastUsedAt_Call) RunAndReturn(run func(ctx context.Context, ID uuid.UUID, lastUsedAt time.Time) error) *MockAPITokenRepo_UpdateLastUsedAt_Call { - _c.Call.Return(run) - return _c -} - -// NewMockCASBackendRepo creates a new instance of MockCASBackendRepo. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -// The first argument is typically a *testing.T value. -func NewMockCASBackendRepo(t interface { - mock.TestingT - Cleanup(func()) -}) *MockCASBackendRepo { - mock := &MockCASBackendRepo{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} - -// MockCASBackendRepo is an autogenerated mock type for the CASBackendRepo type -type MockCASBackendRepo struct { - mock.Mock -} - -type MockCASBackendRepo_Expecter struct { - mock *mock.Mock -} - -func (_m *MockCASBackendRepo) EXPECT() *MockCASBackendRepo_Expecter { - return &MockCASBackendRepo_Expecter{mock: &_m.Mock} -} - -// Create provides a mock function for the type MockCASBackendRepo -func (_mock *MockCASBackendRepo) Create(context1 context.Context, cASBackendCreateOpts *CASBackendCreateOpts) (*CASBackend, error) { - ret := _mock.Called(context1, cASBackendCreateOpts) - - if len(ret) == 0 { - panic("no return value specified for Create") - } - - var r0 *CASBackend - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, *CASBackendCreateOpts) (*CASBackend, error)); ok { - return returnFunc(context1, cASBackendCreateOpts) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, *CASBackendCreateOpts) *CASBackend); ok { - r0 = returnFunc(context1, cASBackendCreateOpts) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*CASBackend) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, *CASBackendCreateOpts) error); ok { - r1 = returnFunc(context1, cASBackendCreateOpts) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// MockCASBackendRepo_Create_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Create' -type MockCASBackendRepo_Create_Call struct { - *mock.Call -} - -// Create is a helper method to define mock.On call -// - context1 context.Context -// - cASBackendCreateOpts *CASBackendCreateOpts -func (_e *MockCASBackendRepo_Expecter) Create(context1 interface{}, cASBackendCreateOpts interface{}) *MockCASBackendRepo_Create_Call { - return &MockCASBackendRepo_Create_Call{Call: _e.mock.On("Create", context1, cASBackendCreateOpts)} -} - -func (_c *MockCASBackendRepo_Create_Call) Run(run func(context1 context.Context, cASBackendCreateOpts *CASBackendCreateOpts)) *MockCASBackendRepo_Create_Call { - _c.Call.Run(func(args mock.Arguments) { - var arg0 context.Context - if args[0] != nil { - arg0 = args[0].(context.Context) - } - var arg1 *CASBackendCreateOpts - if args[1] != nil { - arg1 = args[1].(*CASBackendCreateOpts) - } - run( - arg0, - arg1, - ) - }) - return _c -} - -func (_c *MockCASBackendRepo_Create_Call) Return(cASBackend *CASBackend, err error) *MockCASBackendRepo_Create_Call { - _c.Call.Return(cASBackend, err) - return _c -} - -func (_c *MockCASBackendRepo_Create_Call) RunAndReturn(run func(context1 context.Context, cASBackendCreateOpts *CASBackendCreateOpts) (*CASBackend, error)) *MockCASBackendRepo_Create_Call { - _c.Call.Return(run) - return _c -} - -// Delete provides a mock function for the type MockCASBackendRepo -func (_mock *MockCASBackendRepo) Delete(ctx context.Context, ID uuid.UUID) error { - ret := _mock.Called(ctx, ID) - - if len(ret) == 0 { - panic("no return value specified for Delete") - } - - var r0 error - if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID) error); ok { - r0 = returnFunc(ctx, ID) - } else { - r0 = ret.Error(0) - } - return r0 -} - -// MockCASBackendRepo_Delete_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Delete' -type MockCASBackendRepo_Delete_Call struct { - *mock.Call -} - -// Delete is a helper method to define mock.On call -// - ctx context.Context -// - ID uuid.UUID -func (_e *MockCASBackendRepo_Expecter) Delete(ctx interface{}, ID interface{}) *MockCASBackendRepo_Delete_Call { - return &MockCASBackendRepo_Delete_Call{Call: _e.mock.On("Delete", ctx, ID)} -} - -func (_c *MockCASBackendRepo_Delete_Call) Run(run func(ctx context.Context, ID uuid.UUID)) *MockCASBackendRepo_Delete_Call { - _c.Call.Run(func(args mock.Arguments) { - var arg0 context.Context - if args[0] != nil { - arg0 = args[0].(context.Context) - } - var arg1 uuid.UUID - if args[1] != nil { - arg1 = args[1].(uuid.UUID) - } - run( - arg0, - arg1, - ) - }) - return _c -} - -func (_c *MockCASBackendRepo_Delete_Call) Return(err error) *MockCASBackendRepo_Delete_Call { - _c.Call.Return(err) - return _c -} - -func (_c *MockCASBackendRepo_Delete_Call) RunAndReturn(run func(ctx context.Context, ID uuid.UUID) error) *MockCASBackendRepo_Delete_Call { - _c.Call.Return(run) - return _c -} - -// FindByID provides a mock function for the type MockCASBackendRepo -func (_mock *MockCASBackendRepo) FindByID(ctx context.Context, ID uuid.UUID) (*CASBackend, error) { - ret := _mock.Called(ctx, ID) - - if len(ret) == 0 { - panic("no return value specified for FindByID") - } - - var r0 *CASBackend - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID) (*CASBackend, error)); ok { - return returnFunc(ctx, ID) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID) *CASBackend); ok { - r0 = returnFunc(ctx, ID) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*CASBackend) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, uuid.UUID) error); ok { - r1 = returnFunc(ctx, ID) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// MockCASBackendRepo_FindByID_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FindByID' -type MockCASBackendRepo_FindByID_Call struct { - *mock.Call -} - -// FindByID is a helper method to define mock.On call -// - ctx context.Context -// - ID uuid.UUID -func (_e *MockCASBackendRepo_Expecter) FindByID(ctx interface{}, ID interface{}) *MockCASBackendRepo_FindByID_Call { - return &MockCASBackendRepo_FindByID_Call{Call: _e.mock.On("FindByID", ctx, ID)} -} - -func (_c *MockCASBackendRepo_FindByID_Call) Run(run func(ctx context.Context, ID uuid.UUID)) *MockCASBackendRepo_FindByID_Call { - _c.Call.Run(func(args mock.Arguments) { - var arg0 context.Context - if args[0] != nil { - arg0 = args[0].(context.Context) - } - var arg1 uuid.UUID - if args[1] != nil { - arg1 = args[1].(uuid.UUID) - } - run( - arg0, - arg1, - ) - }) - return _c -} - -func (_c *MockCASBackendRepo_FindByID_Call) Return(cASBackend *CASBackend, err error) *MockCASBackendRepo_FindByID_Call { - _c.Call.Return(cASBackend, err) - return _c -} - -func (_c *MockCASBackendRepo_FindByID_Call) RunAndReturn(run func(ctx context.Context, ID uuid.UUID) (*CASBackend, error)) *MockCASBackendRepo_FindByID_Call { - _c.Call.Return(run) - return _c -} - -// FindByIDInOrg provides a mock function for the type MockCASBackendRepo -func (_mock *MockCASBackendRepo) FindByIDInOrg(ctx context.Context, OrgID uuid.UUID, ID uuid.UUID) (*CASBackend, error) { - ret := _mock.Called(ctx, OrgID, ID) - - if len(ret) == 0 { - panic("no return value specified for FindByIDInOrg") - } - - var r0 *CASBackend - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID, uuid.UUID) (*CASBackend, error)); ok { - return returnFunc(ctx, OrgID, ID) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID, uuid.UUID) *CASBackend); ok { - r0 = returnFunc(ctx, OrgID, ID) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*CASBackend) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, uuid.UUID, uuid.UUID) error); ok { - r1 = returnFunc(ctx, OrgID, ID) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// MockCASBackendRepo_FindByIDInOrg_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FindByIDInOrg' -type MockCASBackendRepo_FindByIDInOrg_Call struct { - *mock.Call -} - -// FindByIDInOrg is a helper method to define mock.On call -// - ctx context.Context -// - OrgID uuid.UUID -// - ID uuid.UUID -func (_e *MockCASBackendRepo_Expecter) FindByIDInOrg(ctx interface{}, OrgID interface{}, ID interface{}) *MockCASBackendRepo_FindByIDInOrg_Call { - return &MockCASBackendRepo_FindByIDInOrg_Call{Call: _e.mock.On("FindByIDInOrg", ctx, OrgID, ID)} -} - -func (_c *MockCASBackendRepo_FindByIDInOrg_Call) Run(run func(ctx context.Context, OrgID uuid.UUID, ID uuid.UUID)) *MockCASBackendRepo_FindByIDInOrg_Call { - _c.Call.Run(func(args mock.Arguments) { - var arg0 context.Context - if args[0] != nil { - arg0 = args[0].(context.Context) - } - var arg1 uuid.UUID - if args[1] != nil { - arg1 = args[1].(uuid.UUID) - } - var arg2 uuid.UUID - if args[2] != nil { - arg2 = args[2].(uuid.UUID) - } - run( - arg0, - arg1, - arg2, - ) - }) - return _c -} - -func (_c *MockCASBackendRepo_FindByIDInOrg_Call) Return(cASBackend *CASBackend, err error) *MockCASBackendRepo_FindByIDInOrg_Call { - _c.Call.Return(cASBackend, err) - return _c -} - -func (_c *MockCASBackendRepo_FindByIDInOrg_Call) RunAndReturn(run func(ctx context.Context, OrgID uuid.UUID, ID uuid.UUID) (*CASBackend, error)) *MockCASBackendRepo_FindByIDInOrg_Call { - _c.Call.Return(run) - return _c -} - -// FindByNameInOrg provides a mock function for the type MockCASBackendRepo -func (_mock *MockCASBackendRepo) FindByNameInOrg(ctx context.Context, OrgID uuid.UUID, name string) (*CASBackend, error) { - ret := _mock.Called(ctx, OrgID, name) - - if len(ret) == 0 { - panic("no return value specified for FindByNameInOrg") - } - - var r0 *CASBackend - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID, string) (*CASBackend, error)); ok { - return returnFunc(ctx, OrgID, name) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID, string) *CASBackend); ok { - r0 = returnFunc(ctx, OrgID, name) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*CASBackend) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, uuid.UUID, string) error); ok { - r1 = returnFunc(ctx, OrgID, name) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// MockCASBackendRepo_FindByNameInOrg_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FindByNameInOrg' -type MockCASBackendRepo_FindByNameInOrg_Call struct { - *mock.Call -} - -// FindByNameInOrg is a helper method to define mock.On call -// - ctx context.Context -// - OrgID uuid.UUID -// - name string -func (_e *MockCASBackendRepo_Expecter) FindByNameInOrg(ctx interface{}, OrgID interface{}, name interface{}) *MockCASBackendRepo_FindByNameInOrg_Call { - return &MockCASBackendRepo_FindByNameInOrg_Call{Call: _e.mock.On("FindByNameInOrg", ctx, OrgID, name)} -} - -func (_c *MockCASBackendRepo_FindByNameInOrg_Call) Run(run func(ctx context.Context, OrgID uuid.UUID, name string)) *MockCASBackendRepo_FindByNameInOrg_Call { - _c.Call.Run(func(args mock.Arguments) { - var arg0 context.Context - if args[0] != nil { - arg0 = args[0].(context.Context) - } - var arg1 uuid.UUID - if args[1] != nil { - arg1 = args[1].(uuid.UUID) - } - var arg2 string - if args[2] != nil { - arg2 = args[2].(string) - } - run( - arg0, - arg1, - arg2, - ) - }) - return _c -} - -func (_c *MockCASBackendRepo_FindByNameInOrg_Call) Return(cASBackend *CASBackend, err error) *MockCASBackendRepo_FindByNameInOrg_Call { - _c.Call.Return(cASBackend, err) - return _c -} - -func (_c *MockCASBackendRepo_FindByNameInOrg_Call) RunAndReturn(run func(ctx context.Context, OrgID uuid.UUID, name string) (*CASBackend, error)) *MockCASBackendRepo_FindByNameInOrg_Call { - _c.Call.Return(run) - return _c -} - -// FindDefaultBackend provides a mock function for the type MockCASBackendRepo -func (_mock *MockCASBackendRepo) FindDefaultBackend(ctx context.Context, orgID uuid.UUID) (*CASBackend, error) { - ret := _mock.Called(ctx, orgID) - - if len(ret) == 0 { - panic("no return value specified for FindDefaultBackend") - } - - var r0 *CASBackend - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID) (*CASBackend, error)); ok { - return returnFunc(ctx, orgID) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID) *CASBackend); ok { - r0 = returnFunc(ctx, orgID) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*CASBackend) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, uuid.UUID) error); ok { - r1 = returnFunc(ctx, orgID) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// MockCASBackendRepo_FindDefaultBackend_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FindDefaultBackend' -type MockCASBackendRepo_FindDefaultBackend_Call struct { - *mock.Call -} - -// FindDefaultBackend is a helper method to define mock.On call -// - ctx context.Context -// - orgID uuid.UUID -func (_e *MockCASBackendRepo_Expecter) FindDefaultBackend(ctx interface{}, orgID interface{}) *MockCASBackendRepo_FindDefaultBackend_Call { - return &MockCASBackendRepo_FindDefaultBackend_Call{Call: _e.mock.On("FindDefaultBackend", ctx, orgID)} -} - -func (_c *MockCASBackendRepo_FindDefaultBackend_Call) Run(run func(ctx context.Context, orgID uuid.UUID)) *MockCASBackendRepo_FindDefaultBackend_Call { - _c.Call.Run(func(args mock.Arguments) { - var arg0 context.Context - if args[0] != nil { - arg0 = args[0].(context.Context) - } - var arg1 uuid.UUID - if args[1] != nil { - arg1 = args[1].(uuid.UUID) - } - run( - arg0, - arg1, - ) - }) - return _c -} - -func (_c *MockCASBackendRepo_FindDefaultBackend_Call) Return(cASBackend *CASBackend, err error) *MockCASBackendRepo_FindDefaultBackend_Call { - _c.Call.Return(cASBackend, err) - return _c -} - -func (_c *MockCASBackendRepo_FindDefaultBackend_Call) RunAndReturn(run func(ctx context.Context, orgID uuid.UUID) (*CASBackend, error)) *MockCASBackendRepo_FindDefaultBackend_Call { - _c.Call.Return(run) - return _c -} - -// FindFallbackBackend provides a mock function for the type MockCASBackendRepo -func (_mock *MockCASBackendRepo) FindFallbackBackend(ctx context.Context, orgID uuid.UUID) (*CASBackend, error) { - ret := _mock.Called(ctx, orgID) - - if len(ret) == 0 { - panic("no return value specified for FindFallbackBackend") - } - - var r0 *CASBackend - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID) (*CASBackend, error)); ok { - return returnFunc(ctx, orgID) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID) *CASBackend); ok { - r0 = returnFunc(ctx, orgID) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*CASBackend) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, uuid.UUID) error); ok { - r1 = returnFunc(ctx, orgID) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// MockCASBackendRepo_FindFallbackBackend_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FindFallbackBackend' -type MockCASBackendRepo_FindFallbackBackend_Call struct { - *mock.Call -} - -// FindFallbackBackend is a helper method to define mock.On call -// - ctx context.Context -// - orgID uuid.UUID -func (_e *MockCASBackendRepo_Expecter) FindFallbackBackend(ctx interface{}, orgID interface{}) *MockCASBackendRepo_FindFallbackBackend_Call { - return &MockCASBackendRepo_FindFallbackBackend_Call{Call: _e.mock.On("FindFallbackBackend", ctx, orgID)} -} - -func (_c *MockCASBackendRepo_FindFallbackBackend_Call) Run(run func(ctx context.Context, orgID uuid.UUID)) *MockCASBackendRepo_FindFallbackBackend_Call { - _c.Call.Run(func(args mock.Arguments) { - var arg0 context.Context - if args[0] != nil { - arg0 = args[0].(context.Context) - } - var arg1 uuid.UUID - if args[1] != nil { - arg1 = args[1].(uuid.UUID) - } - run( - arg0, - arg1, - ) - }) - return _c -} - -func (_c *MockCASBackendRepo_FindFallbackBackend_Call) Return(cASBackend *CASBackend, err error) *MockCASBackendRepo_FindFallbackBackend_Call { - _c.Call.Return(cASBackend, err) - return _c -} - -func (_c *MockCASBackendRepo_FindFallbackBackend_Call) RunAndReturn(run func(ctx context.Context, orgID uuid.UUID) (*CASBackend, error)) *MockCASBackendRepo_FindFallbackBackend_Call { - _c.Call.Return(run) - return _c -} - -// List provides a mock function for the type MockCASBackendRepo -func (_mock *MockCASBackendRepo) List(ctx context.Context, orgID uuid.UUID) ([]*CASBackend, error) { - ret := _mock.Called(ctx, orgID) - - if len(ret) == 0 { - panic("no return value specified for List") - } - - var r0 []*CASBackend - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID) ([]*CASBackend, error)); ok { - return returnFunc(ctx, orgID) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID) []*CASBackend); ok { - r0 = returnFunc(ctx, orgID) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]*CASBackend) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, uuid.UUID) error); ok { - r1 = returnFunc(ctx, orgID) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// MockCASBackendRepo_List_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'List' -type MockCASBackendRepo_List_Call struct { - *mock.Call -} - -// List is a helper method to define mock.On call -// - ctx context.Context -// - orgID uuid.UUID -func (_e *MockCASBackendRepo_Expecter) List(ctx interface{}, orgID interface{}) *MockCASBackendRepo_List_Call { - return &MockCASBackendRepo_List_Call{Call: _e.mock.On("List", ctx, orgID)} -} - -func (_c *MockCASBackendRepo_List_Call) Run(run func(ctx context.Context, orgID uuid.UUID)) *MockCASBackendRepo_List_Call { - _c.Call.Run(func(args mock.Arguments) { - var arg0 context.Context - if args[0] != nil { - arg0 = args[0].(context.Context) - } - var arg1 uuid.UUID - if args[1] != nil { - arg1 = args[1].(uuid.UUID) - } - run( - arg0, - arg1, - ) - }) - return _c -} - -func (_c *MockCASBackendRepo_List_Call) Return(cASBackends []*CASBackend, err error) *MockCASBackendRepo_List_Call { - _c.Call.Return(cASBackends, err) - return _c -} - -func (_c *MockCASBackendRepo_List_Call) RunAndReturn(run func(ctx context.Context, orgID uuid.UUID) ([]*CASBackend, error)) *MockCASBackendRepo_List_Call { - _c.Call.Return(run) - return _c -} - -// ListBackends provides a mock function for the type MockCASBackendRepo -func (_mock *MockCASBackendRepo) ListBackends(ctx context.Context, onlyDefaults bool) ([]*CASBackend, error) { - ret := _mock.Called(ctx, onlyDefaults) - - if len(ret) == 0 { - panic("no return value specified for ListBackends") - } - - var r0 []*CASBackend - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, bool) ([]*CASBackend, error)); ok { - return returnFunc(ctx, onlyDefaults) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, bool) []*CASBackend); ok { - r0 = returnFunc(ctx, onlyDefaults) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]*CASBackend) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, bool) error); ok { - r1 = returnFunc(ctx, onlyDefaults) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// MockCASBackendRepo_ListBackends_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ListBackends' -type MockCASBackendRepo_ListBackends_Call struct { - *mock.Call -} - -// ListBackends is a helper method to define mock.On call -// - ctx context.Context -// - onlyDefaults bool -func (_e *MockCASBackendRepo_Expecter) ListBackends(ctx interface{}, onlyDefaults interface{}) *MockCASBackendRepo_ListBackends_Call { - return &MockCASBackendRepo_ListBackends_Call{Call: _e.mock.On("ListBackends", ctx, onlyDefaults)} -} - -func (_c *MockCASBackendRepo_ListBackends_Call) Run(run func(ctx context.Context, onlyDefaults bool)) *MockCASBackendRepo_ListBackends_Call { - _c.Call.Run(func(args mock.Arguments) { - var arg0 context.Context - if args[0] != nil { - arg0 = args[0].(context.Context) - } - var arg1 bool - if args[1] != nil { - arg1 = args[1].(bool) - } - run( - arg0, - arg1, - ) - }) - return _c -} - -func (_c *MockCASBackendRepo_ListBackends_Call) Return(cASBackends []*CASBackend, err error) *MockCASBackendRepo_ListBackends_Call { - _c.Call.Return(cASBackends, err) - return _c -} - -func (_c *MockCASBackendRepo_ListBackends_Call) RunAndReturn(run func(ctx context.Context, onlyDefaults bool) ([]*CASBackend, error)) *MockCASBackendRepo_ListBackends_Call { - _c.Call.Return(run) - return _c -} - -// SoftDelete provides a mock function for the type MockCASBackendRepo -func (_mock *MockCASBackendRepo) SoftDelete(ctx context.Context, ID uuid.UUID) error { - ret := _mock.Called(ctx, ID) - - if len(ret) == 0 { - panic("no return value specified for SoftDelete") - } - - var r0 error - if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID) error); ok { - r0 = returnFunc(ctx, ID) - } else { - r0 = ret.Error(0) - } - return r0 -} - -// MockCASBackendRepo_SoftDelete_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SoftDelete' -type MockCASBackendRepo_SoftDelete_Call struct { - *mock.Call -} - -// SoftDelete is a helper method to define mock.On call -// - ctx context.Context -// - ID uuid.UUID -func (_e *MockCASBackendRepo_Expecter) SoftDelete(ctx interface{}, ID interface{}) *MockCASBackendRepo_SoftDelete_Call { - return &MockCASBackendRepo_SoftDelete_Call{Call: _e.mock.On("SoftDelete", ctx, ID)} -} - -func (_c *MockCASBackendRepo_SoftDelete_Call) Run(run func(ctx context.Context, ID uuid.UUID)) *MockCASBackendRepo_SoftDelete_Call { - _c.Call.Run(func(args mock.Arguments) { - var arg0 context.Context - if args[0] != nil { - arg0 = args[0].(context.Context) - } - var arg1 uuid.UUID - if args[1] != nil { - arg1 = args[1].(uuid.UUID) - } - run( - arg0, - arg1, - ) - }) - return _c -} - -func (_c *MockCASBackendRepo_SoftDelete_Call) Return(err error) *MockCASBackendRepo_SoftDelete_Call { - _c.Call.Return(err) - return _c -} - -func (_c *MockCASBackendRepo_SoftDelete_Call) RunAndReturn(run func(ctx context.Context, ID uuid.UUID) error) *MockCASBackendRepo_SoftDelete_Call { - _c.Call.Return(run) - return _c -} - -// Update provides a mock function for the type MockCASBackendRepo -func (_mock *MockCASBackendRepo) Update(context1 context.Context, cASBackendUpdateOpts *CASBackendUpdateOpts) (*CASBackend, error) { - ret := _mock.Called(context1, cASBackendUpdateOpts) - - if len(ret) == 0 { - panic("no return value specified for Update") - } - - var r0 *CASBackend - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, *CASBackendUpdateOpts) (*CASBackend, error)); ok { - return returnFunc(context1, cASBackendUpdateOpts) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, *CASBackendUpdateOpts) *CASBackend); ok { - r0 = returnFunc(context1, cASBackendUpdateOpts) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*CASBackend) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, *CASBackendUpdateOpts) error); ok { - r1 = returnFunc(context1, cASBackendUpdateOpts) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// MockCASBackendRepo_Update_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Update' -type MockCASBackendRepo_Update_Call struct { - *mock.Call -} - -// Update is a helper method to define mock.On call -// - context1 context.Context -// - cASBackendUpdateOpts *CASBackendUpdateOpts -func (_e *MockCASBackendRepo_Expecter) Update(context1 interface{}, cASBackendUpdateOpts interface{}) *MockCASBackendRepo_Update_Call { - return &MockCASBackendRepo_Update_Call{Call: _e.mock.On("Update", context1, cASBackendUpdateOpts)} -} - -func (_c *MockCASBackendRepo_Update_Call) Run(run func(context1 context.Context, cASBackendUpdateOpts *CASBackendUpdateOpts)) *MockCASBackendRepo_Update_Call { - _c.Call.Run(func(args mock.Arguments) { - var arg0 context.Context - if args[0] != nil { - arg0 = args[0].(context.Context) - } - var arg1 *CASBackendUpdateOpts - if args[1] != nil { - arg1 = args[1].(*CASBackendUpdateOpts) - } - run( - arg0, - arg1, - ) - }) - return _c -} - -func (_c *MockCASBackendRepo_Update_Call) Return(cASBackend *CASBackend, err error) *MockCASBackendRepo_Update_Call { - _c.Call.Return(cASBackend, err) - return _c -} - -func (_c *MockCASBackendRepo_Update_Call) RunAndReturn(run func(context1 context.Context, cASBackendUpdateOpts *CASBackendUpdateOpts) (*CASBackend, error)) *MockCASBackendRepo_Update_Call { - _c.Call.Return(run) - return _c -} - -// UpdateValidationStatus provides a mock function for the type MockCASBackendRepo -func (_mock *MockCASBackendRepo) UpdateValidationStatus(ctx context.Context, ID uuid.UUID, status CASBackendValidationStatus, validationError *string) error { - ret := _mock.Called(ctx, ID, status, validationError) - - if len(ret) == 0 { - panic("no return value specified for UpdateValidationStatus") - } - - var r0 error - if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID, CASBackendValidationStatus, *string) error); ok { - r0 = returnFunc(ctx, ID, status, validationError) - } else { - r0 = ret.Error(0) - } - return r0 -} - -// MockCASBackendRepo_UpdateValidationStatus_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpdateValidationStatus' -type MockCASBackendRepo_UpdateValidationStatus_Call struct { - *mock.Call -} - -// UpdateValidationStatus is a helper method to define mock.On call -// - ctx context.Context -// - ID uuid.UUID -// - status CASBackendValidationStatus -// - validationError *string -func (_e *MockCASBackendRepo_Expecter) UpdateValidationStatus(ctx interface{}, ID interface{}, status interface{}, validationError interface{}) *MockCASBackendRepo_UpdateValidationStatus_Call { - return &MockCASBackendRepo_UpdateValidationStatus_Call{Call: _e.mock.On("UpdateValidationStatus", ctx, ID, status, validationError)} -} - -func (_c *MockCASBackendRepo_UpdateValidationStatus_Call) Run(run func(ctx context.Context, ID uuid.UUID, status CASBackendValidationStatus, validationError *string)) *MockCASBackendRepo_UpdateValidationStatus_Call { - _c.Call.Run(func(args mock.Arguments) { - var arg0 context.Context - if args[0] != nil { - arg0 = args[0].(context.Context) - } - var arg1 uuid.UUID - if args[1] != nil { - arg1 = args[1].(uuid.UUID) - } - var arg2 CASBackendValidationStatus - if args[2] != nil { - arg2 = args[2].(CASBackendValidationStatus) - } - var arg3 *string - if args[3] != nil { - arg3 = args[3].(*string) - } - run( - arg0, - arg1, - arg2, - arg3, - ) - }) - return _c -} - -func (_c *MockCASBackendRepo_UpdateValidationStatus_Call) Return(err error) *MockCASBackendRepo_UpdateValidationStatus_Call { - _c.Call.Return(err) - return _c -} - -func (_c *MockCASBackendRepo_UpdateValidationStatus_Call) RunAndReturn(run func(ctx context.Context, ID uuid.UUID, status CASBackendValidationStatus, validationError *string) error) *MockCASBackendRepo_UpdateValidationStatus_Call { - _c.Call.Return(run) - return _c -} - -// NewMockOrganizationRepo creates a new instance of MockOrganizationRepo. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -// The first argument is typically a *testing.T value. -func NewMockOrganizationRepo(t interface { - mock.TestingT - Cleanup(func()) -}) *MockOrganizationRepo { - mock := &MockOrganizationRepo{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} - -// MockOrganizationRepo is an autogenerated mock type for the OrganizationRepo type -type MockOrganizationRepo struct { - mock.Mock -} - -type MockOrganizationRepo_Expecter struct { - mock *mock.Mock -} - -func (_m *MockOrganizationRepo) EXPECT() *MockOrganizationRepo_Expecter { - return &MockOrganizationRepo_Expecter{mock: &_m.Mock} -} - -// Create provides a mock function for the type MockOrganizationRepo -func (_mock *MockOrganizationRepo) Create(ctx context.Context, name string) (*Organization, error) { - ret := _mock.Called(ctx, name) - - if len(ret) == 0 { - panic("no return value specified for Create") - } - - var r0 *Organization - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, string) (*Organization, error)); ok { - return returnFunc(ctx, name) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, string) *Organization); ok { - r0 = returnFunc(ctx, name) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*Organization) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, string) error); ok { - r1 = returnFunc(ctx, name) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// MockOrganizationRepo_Create_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Create' -type MockOrganizationRepo_Create_Call struct { - *mock.Call -} - -// Create is a helper method to define mock.On call -// - ctx context.Context -// - name string -func (_e *MockOrganizationRepo_Expecter) Create(ctx interface{}, name interface{}) *MockOrganizationRepo_Create_Call { - return &MockOrganizationRepo_Create_Call{Call: _e.mock.On("Create", ctx, name)} -} - -func (_c *MockOrganizationRepo_Create_Call) Run(run func(ctx context.Context, name string)) *MockOrganizationRepo_Create_Call { - _c.Call.Run(func(args mock.Arguments) { - var arg0 context.Context - if args[0] != nil { - arg0 = args[0].(context.Context) - } - var arg1 string - if args[1] != nil { - arg1 = args[1].(string) - } - run( - arg0, - arg1, - ) - }) - return _c -} - -func (_c *MockOrganizationRepo_Create_Call) Return(organization *Organization, err error) *MockOrganizationRepo_Create_Call { - _c.Call.Return(organization, err) - return _c -} - -func (_c *MockOrganizationRepo_Create_Call) RunAndReturn(run func(ctx context.Context, name string) (*Organization, error)) *MockOrganizationRepo_Create_Call { - _c.Call.Return(run) - return _c -} - -// Delete provides a mock function for the type MockOrganizationRepo -func (_mock *MockOrganizationRepo) Delete(ctx context.Context, ID uuid.UUID) error { - ret := _mock.Called(ctx, ID) - - if len(ret) == 0 { - panic("no return value specified for Delete") - } - - var r0 error - if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID) error); ok { - r0 = returnFunc(ctx, ID) - } else { - r0 = ret.Error(0) - } - return r0 -} - -// MockOrganizationRepo_Delete_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Delete' -type MockOrganizationRepo_Delete_Call struct { - *mock.Call -} - -// Delete is a helper method to define mock.On call -// - ctx context.Context -// - ID uuid.UUID -func (_e *MockOrganizationRepo_Expecter) Delete(ctx interface{}, ID interface{}) *MockOrganizationRepo_Delete_Call { - return &MockOrganizationRepo_Delete_Call{Call: _e.mock.On("Delete", ctx, ID)} -} - -func (_c *MockOrganizationRepo_Delete_Call) Run(run func(ctx context.Context, ID uuid.UUID)) *MockOrganizationRepo_Delete_Call { - _c.Call.Run(func(args mock.Arguments) { - var arg0 context.Context - if args[0] != nil { - arg0 = args[0].(context.Context) - } - var arg1 uuid.UUID - if args[1] != nil { - arg1 = args[1].(uuid.UUID) - } - run( - arg0, - arg1, - ) - }) - return _c -} - -func (_c *MockOrganizationRepo_Delete_Call) Return(err error) *MockOrganizationRepo_Delete_Call { - _c.Call.Return(err) - return _c -} - -func (_c *MockOrganizationRepo_Delete_Call) RunAndReturn(run func(ctx context.Context, ID uuid.UUID) error) *MockOrganizationRepo_Delete_Call { - _c.Call.Return(run) - return _c -} - -// FindByID provides a mock function for the type MockOrganizationRepo -func (_mock *MockOrganizationRepo) FindByID(ctx context.Context, orgID uuid.UUID) (*Organization, error) { - ret := _mock.Called(ctx, orgID) - - if len(ret) == 0 { - panic("no return value specified for FindByID") - } - - var r0 *Organization - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID) (*Organization, error)); ok { - return returnFunc(ctx, orgID) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID) *Organization); ok { - r0 = returnFunc(ctx, orgID) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*Organization) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, uuid.UUID) error); ok { - r1 = returnFunc(ctx, orgID) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// MockOrganizationRepo_FindByID_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FindByID' -type MockOrganizationRepo_FindByID_Call struct { - *mock.Call -} - -// FindByID is a helper method to define mock.On call -// - ctx context.Context -// - orgID uuid.UUID -func (_e *MockOrganizationRepo_Expecter) FindByID(ctx interface{}, orgID interface{}) *MockOrganizationRepo_FindByID_Call { - return &MockOrganizationRepo_FindByID_Call{Call: _e.mock.On("FindByID", ctx, orgID)} -} - -func (_c *MockOrganizationRepo_FindByID_Call) Run(run func(ctx context.Context, orgID uuid.UUID)) *MockOrganizationRepo_FindByID_Call { - _c.Call.Run(func(args mock.Arguments) { - var arg0 context.Context - if args[0] != nil { - arg0 = args[0].(context.Context) - } - var arg1 uuid.UUID - if args[1] != nil { - arg1 = args[1].(uuid.UUID) - } - run( - arg0, - arg1, - ) - }) - return _c -} - -func (_c *MockOrganizationRepo_FindByID_Call) Return(organization *Organization, err error) *MockOrganizationRepo_FindByID_Call { - _c.Call.Return(organization, err) - return _c -} - -func (_c *MockOrganizationRepo_FindByID_Call) RunAndReturn(run func(ctx context.Context, orgID uuid.UUID) (*Organization, error)) *MockOrganizationRepo_FindByID_Call { - _c.Call.Return(run) - return _c -} - -// FindByName provides a mock function for the type MockOrganizationRepo -func (_mock *MockOrganizationRepo) FindByName(ctx context.Context, name string) (*Organization, error) { - ret := _mock.Called(ctx, name) - - if len(ret) == 0 { - panic("no return value specified for FindByName") - } - - var r0 *Organization - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, string) (*Organization, error)); ok { - return returnFunc(ctx, name) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, string) *Organization); ok { - r0 = returnFunc(ctx, name) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*Organization) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, string) error); ok { - r1 = returnFunc(ctx, name) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// MockOrganizationRepo_FindByName_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FindByName' -type MockOrganizationRepo_FindByName_Call struct { - *mock.Call -} - -// FindByName is a helper method to define mock.On call -// - ctx context.Context -// - name string -func (_e *MockOrganizationRepo_Expecter) FindByName(ctx interface{}, name interface{}) *MockOrganizationRepo_FindByName_Call { - return &MockOrganizationRepo_FindByName_Call{Call: _e.mock.On("FindByName", ctx, name)} -} - -func (_c *MockOrganizationRepo_FindByName_Call) Run(run func(ctx context.Context, name string)) *MockOrganizationRepo_FindByName_Call { - _c.Call.Run(func(args mock.Arguments) { - var arg0 context.Context - if args[0] != nil { - arg0 = args[0].(context.Context) - } - var arg1 string - if args[1] != nil { - arg1 = args[1].(string) - } - run( - arg0, - arg1, - ) - }) - return _c -} - -func (_c *MockOrganizationRepo_FindByName_Call) Return(organization *Organization, err error) *MockOrganizationRepo_FindByName_Call { - _c.Call.Return(organization, err) - return _c -} - -func (_c *MockOrganizationRepo_FindByName_Call) RunAndReturn(run func(ctx context.Context, name string) (*Organization, error)) *MockOrganizationRepo_FindByName_Call { - _c.Call.Return(run) - return _c -} - -// Update provides a mock function for the type MockOrganizationRepo -func (_mock *MockOrganizationRepo) Update(ctx context.Context, id uuid.UUID, blockOnPolicyViolation *bool, policiesAllowedHostnames []string) (*Organization, error) { - ret := _mock.Called(ctx, id, blockOnPolicyViolation, policiesAllowedHostnames) - - if len(ret) == 0 { - panic("no return value specified for Update") - } - - var r0 *Organization - var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID, *bool, []string) (*Organization, error)); ok { - return returnFunc(ctx, id, blockOnPolicyViolation, policiesAllowedHostnames) - } - if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID, *bool, []string) *Organization); ok { - r0 = returnFunc(ctx, id, blockOnPolicyViolation, policiesAllowedHostnames) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*Organization) - } - } - if returnFunc, ok := ret.Get(1).(func(context.Context, uuid.UUID, *bool, []string) error); ok { - r1 = returnFunc(ctx, id, blockOnPolicyViolation, policiesAllowedHostnames) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// MockOrganizationRepo_Update_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Update' -type MockOrganizationRepo_Update_Call struct { - *mock.Call -} - -// Update is a helper method to define mock.On call -// - ctx context.Context -// - id uuid.UUID -// - blockOnPolicyViolation *bool -// - policiesAllowedHostnames []string -func (_e *MockOrganizationRepo_Expecter) Update(ctx interface{}, id interface{}, blockOnPolicyViolation interface{}, policiesAllowedHostnames interface{}) *MockOrganizationRepo_Update_Call { - return &MockOrganizationRepo_Update_Call{Call: _e.mock.On("Update", ctx, id, blockOnPolicyViolation, policiesAllowedHostnames)} -} - -func (_c *MockOrganizationRepo_Update_Call) Run(run func(ctx context.Context, id uuid.UUID, blockOnPolicyViolation *bool, policiesAllowedHostnames []string)) *MockOrganizationRepo_Update_Call { - _c.Call.Run(func(args mock.Arguments) { - var arg0 context.Context - if args[0] != nil { - arg0 = args[0].(context.Context) - } - var arg1 uuid.UUID - if args[1] != nil { - arg1 = args[1].(uuid.UUID) - } - var arg2 *bool - if args[2] != nil { - arg2 = args[2].(*bool) - } - var arg3 []string - if args[3] != nil { - arg3 = args[3].([]string) - } - run( - arg0, - arg1, - arg2, - arg3, - ) - }) - return _c -} - -func (_c *MockOrganizationRepo_Update_Call) Return(organization *Organization, err error) *MockOrganizationRepo_Update_Call { - _c.Call.Return(organization, err) - return _c -} - -func (_c *MockOrganizationRepo_Update_Call) RunAndReturn(run func(ctx context.Context, id uuid.UUID, blockOnPolicyViolation *bool, policiesAllowedHostnames []string) (*Organization, error)) *MockOrganizationRepo_Update_Call { - _c.Call.Return(run) - return _c -} From c159a20f0a50312627e56f2b188426ffa0fee9f4 Mon Sep 17 00:00:00 2001 From: Miguel Martinez Date: Mon, 10 Nov 2025 13:00:53 +0100 Subject: [PATCH 4/8] fix connection nats Signed-off-by: Miguel Martinez --- app/artifact-cas/api/buf.yaml | 2 +- app/artifact-cas/internal/conf/buf.yaml | 2 +- app/controlplane/api/buf.yaml | 2 +- app/controlplane/cmd/wire.go | 2 +- app/controlplane/cmd/wire_gen.go | 2 +- app/controlplane/internal/conf/buf.yaml | 2 +- app/controlplane/pkg/authz/authz.go | 23 ------------------- app/controlplane/pkg/authz/authz_test.go | 5 ++-- app/controlplane/pkg/authz/enforcer.go | 9 ++------ app/controlplane/pkg/biz/testhelpers/wire.go | 2 +- .../pkg/biz/testhelpers/wire_gen.go | 2 +- app/controlplane/pkg/conf/buf.yaml | 2 +- 12 files changed, 13 insertions(+), 42 deletions(-) diff --git a/app/artifact-cas/api/buf.yaml b/app/artifact-cas/api/buf.yaml index fe7089ac2..590e81281 100644 --- a/app/artifact-cas/api/buf.yaml +++ b/app/artifact-cas/api/buf.yaml @@ -7,4 +7,4 @@ deps: - buf.build/bufbuild/protovalidate:b983156c5e994cc9892e0ce3e64e17e0 lint: use: - - DEFAULT + - STANDARD diff --git a/app/artifact-cas/internal/conf/buf.yaml b/app/artifact-cas/internal/conf/buf.yaml index 877fd716d..19b961ff8 100644 --- a/app/artifact-cas/internal/conf/buf.yaml +++ b/app/artifact-cas/internal/conf/buf.yaml @@ -7,7 +7,7 @@ deps: - buf.build/bufbuild/protovalidate:b983156c5e994cc9892e0ce3e64e17e0 lint: use: - - DEFAULT + - STANDARD ignore_only: PACKAGE_DEFINED: - ./conf.proto diff --git a/app/controlplane/api/buf.yaml b/app/controlplane/api/buf.yaml index 8e996f6d0..a23776e07 100644 --- a/app/controlplane/api/buf.yaml +++ b/app/controlplane/api/buf.yaml @@ -9,7 +9,7 @@ deps: - buf.build/grpc-ecosystem/grpc-gateway:v2.26.3 lint: use: - - DEFAULT + - STANDARD ignore_only: ENUM_ZERO_VALUE_SUFFIX: - controlplane/v1/pagination.proto diff --git a/app/controlplane/cmd/wire.go b/app/controlplane/cmd/wire.go index eec255a29..fba4229fc 100644 --- a/app/controlplane/cmd/wire.go +++ b/app/controlplane/cmd/wire.go @@ -71,7 +71,7 @@ func wireApp(*conf.Bootstrap, credentials.ReaderWriter, log.Logger, sdk.Availabl } func authzConfig(conf *conf.Bootstrap) *authz.Config { - return &authz.Config{ManagedResources: authz.ManagedResources, RolesMap: authz.RolesMap, RestrictOrgCreation: conf.RestrictOrgCreation} + return &authz.Config{RolesMap: authz.RolesMap, RestrictOrgCreation: conf.RestrictOrgCreation} } func newJWTConfig(conf *conf.Auth) *biz.APITokenJWTConfig { diff --git a/app/controlplane/cmd/wire_gen.go b/app/controlplane/cmd/wire_gen.go index 6e745b5b4..c3507fab8 100644 --- a/app/controlplane/cmd/wire_gen.go +++ b/app/controlplane/cmd/wire_gen.go @@ -321,7 +321,7 @@ var ( // wire.go: func authzConfig(conf2 *conf.Bootstrap) *authz.Config { - return &authz.Config{ManagedResources: authz.ManagedResources, RolesMap: authz.RolesMap, RestrictOrgCreation: conf2.RestrictOrgCreation} + return &authz.Config{RolesMap: authz.RolesMap, RestrictOrgCreation: conf2.RestrictOrgCreation} } func newJWTConfig(conf2 *conf.Auth) *biz.APITokenJWTConfig { diff --git a/app/controlplane/internal/conf/buf.yaml b/app/controlplane/internal/conf/buf.yaml index e1a1c3605..74ccb2956 100644 --- a/app/controlplane/internal/conf/buf.yaml +++ b/app/controlplane/internal/conf/buf.yaml @@ -8,7 +8,7 @@ deps: - buf.build/kratos-go/kratos:e1d52e944e3845c6862a566db322432d lint: use: - - DEFAULT + - STANDARD ignore_only: PACKAGE_DEFINED: - ./conf.proto diff --git a/app/controlplane/pkg/authz/authz.go b/app/controlplane/pkg/authz/authz.go index f7706dbf6..0afa0f0cf 100644 --- a/app/controlplane/pkg/authz/authz.go +++ b/app/controlplane/pkg/authz/authz.go @@ -100,29 +100,6 @@ const ( RoleProductAdmin Role = "role:product:admin" ) -// ManagedResources are the resources that are managed by Chainloop, considered during permissions sync -var ManagedResources = []string{ - ResourceWorkflowContract, - ResourceCASArtifact, - ResourceCASBackend, - ResourceReferrer, - ResourceAvailableIntegration, - ResourceRegisteredIntegration, - ResourceAttachedIntegration, - ResourceOrgMetric, - ResourceRobotAccount, - ResourceWorkflowRun, - ResourceWorkflow, - ResourceProject, - Organization, - OrganizationMemberships, - ResourceGroup, - ResourceGroupMembership, - ResourceAPIToken, - ResourceProjectMembership, - ResourceOrganizationInvitations, -} - var ( // Referrer PolicyReferrerRead = &Policy{ResourceReferrer, ActionRead} diff --git a/app/controlplane/pkg/authz/authz_test.go b/app/controlplane/pkg/authz/authz_test.go index 6621cc79c..7329b4b54 100644 --- a/app/controlplane/pkg/authz/authz_test.go +++ b/app/controlplane/pkg/authz/authz_test.go @@ -92,7 +92,7 @@ func TestDoSync(t *testing.T) { }, } - err = doSync(e, &Config{RolesMap: policiesM, ManagedResources: []string{ResourceWorkflowContract, ResourceCASArtifact}}) + err = doSync(e, &Config{RolesMap: policiesM}) assert.NoError(t, err) got, err = e.GetPolicy() assert.NoError(t, err) @@ -105,7 +105,7 @@ func TestDoSync(t *testing.T) { }, } - err = doSync(e, &Config{RolesMap: policiesM, ManagedResources: []string{ResourceWorkflowContract, ResourceCASArtifact}}) + err = doSync(e, &Config{RolesMap: policiesM}) assert.NoError(t, err) got, err = e.GetPolicy() assert.NoError(t, err) @@ -125,7 +125,6 @@ func TestDoSync(t *testing.T) { assert.Len(t, got, 2) } - func testEnforcer(t *testing.T) (*Enforcer, io.Closer) { f, err := os.CreateTemp(t.TempDir(), "policy*.csv") if err != nil { diff --git a/app/controlplane/pkg/authz/enforcer.go b/app/controlplane/pkg/authz/enforcer.go index 369690db6..46968f001 100644 --- a/app/controlplane/pkg/authz/enforcer.go +++ b/app/controlplane/pkg/authz/enforcer.go @@ -38,7 +38,6 @@ func (t *SubjectAPIToken) String() string { var modelFile []byte type Config struct { - ManagedResources []string RolesMap map[Role][]*Policy RestrictOrgCreation bool } @@ -57,7 +56,8 @@ func (e *Enforcer) Enforce(sub string, p *Policy) (bool, error) { // EnforceWithPolicies checks if the required policy exists in the provided list of allowed policies. // This is used for ACL-based authorization (e.g., API tokens) where policies are stored in the database // rather than in Casbin. Returns true if the required policy is found in the allowed list. -func (e *Enforcer) EnforceWithPolicies(sub string, p *Policy, allowedPolicies []*Policy) (bool, error) { +// in the future we will use this function to check if the policy is allowed for the subject by running the enforcer with the subject +func (e *Enforcer) EnforceWithPolicies(_ string, p *Policy, allowedPolicies []*Policy) (bool, error) { for _, allowed := range allowedPolicies { if allowed.Resource == p.Resource && allowed.Action == p.Action { return true, nil @@ -171,11 +171,6 @@ func doSync(e *Enforcer, c *Config) error { resource := p[1] action := p[2] - // if it's not a managed resource, skip deletion - if !slices.Contains(conf.ManagedResources, resource) { - continue - } - wantPolicies, ok := conf.RolesMap[Role(role)] // if the role does not exist in the map, we can delete the policy if !ok { diff --git a/app/controlplane/pkg/biz/testhelpers/wire.go b/app/controlplane/pkg/biz/testhelpers/wire.go index 6d2922917..4d8d4ffbc 100644 --- a/app/controlplane/pkg/biz/testhelpers/wire.go +++ b/app/controlplane/pkg/biz/testhelpers/wire.go @@ -68,7 +68,7 @@ func WireTestData(*TestDatabase, *testing.T, log.Logger, credentials.ReaderWrite } func authzConfig() *authz.Config { - return &authz.Config{ManagedResources: authz.ManagedResources, RolesMap: authz.RolesMap} + return &authz.Config{RolesMap: authz.RolesMap} } func newJWTConfig(conf *conf.Auth) *biz.APITokenJWTConfig { diff --git a/app/controlplane/pkg/biz/testhelpers/wire_gen.go b/app/controlplane/pkg/biz/testhelpers/wire_gen.go index e131c412f..da1c8ba67 100644 --- a/app/controlplane/pkg/biz/testhelpers/wire_gen.go +++ b/app/controlplane/pkg/biz/testhelpers/wire_gen.go @@ -208,7 +208,7 @@ var ( // wire.go: func authzConfig() *authz.Config { - return &authz.Config{ManagedResources: authz.ManagedResources, RolesMap: authz.RolesMap} + return &authz.Config{RolesMap: authz.RolesMap} } func newJWTConfig(conf2 *conf.Auth) *biz.APITokenJWTConfig { diff --git a/app/controlplane/pkg/conf/buf.yaml b/app/controlplane/pkg/conf/buf.yaml index fe7089ac2..590e81281 100644 --- a/app/controlplane/pkg/conf/buf.yaml +++ b/app/controlplane/pkg/conf/buf.yaml @@ -7,4 +7,4 @@ deps: - buf.build/bufbuild/protovalidate:b983156c5e994cc9892e0ce3e64e17e0 lint: use: - - DEFAULT + - STANDARD From 36a312a856d13abeb983502bc7040764401c98aa Mon Sep 17 00:00:00 2001 From: Miguel Martinez Date: Mon, 10 Nov 2025 13:13:53 +0100 Subject: [PATCH 5/8] fix connection nats Signed-off-by: Miguel Martinez --- app/controlplane/pkg/authz/authz.go | 1 - .../pkg/biz/apitoken_integration_test.go | 41 +++++++------------ 2 files changed, 15 insertions(+), 27 deletions(-) diff --git a/app/controlplane/pkg/authz/authz.go b/app/controlplane/pkg/authz/authz.go index 0afa0f0cf..d9f0b42ea 100644 --- a/app/controlplane/pkg/authz/authz.go +++ b/app/controlplane/pkg/authz/authz.go @@ -95,7 +95,6 @@ const ( RoleGroupMaintainer Role = "role:group:maintainer" // Product roles - RoleProductViewer Role = "role:product:viewer" RoleProductAdmin Role = "role:product:admin" ) diff --git a/app/controlplane/pkg/biz/apitoken_integration_test.go b/app/controlplane/pkg/biz/apitoken_integration_test.go index 0591bc6c2..5809eccc7 100644 --- a/app/controlplane/pkg/biz/apitoken_integration_test.go +++ b/app/controlplane/pkg/biz/apitoken_integration_test.go @@ -21,7 +21,6 @@ import ( "testing" "time" - "github.com/chainloop-dev/chainloop/app/controlplane/pkg/authz" "github.com/chainloop-dev/chainloop/app/controlplane/pkg/biz" "github.com/chainloop-dev/chainloop/app/controlplane/pkg/biz/testhelpers" "github.com/golang-jwt/jwt/v4" @@ -149,17 +148,21 @@ func (s *apiTokenTestSuite) TestAuthzPolicies() { token, err := s.APIToken.Create(context.Background(), randomName(), nil, nil, s.org.ID) require.NoError(s.T(), err) - subject := (&authz.SubjectAPIToken{ID: token.ID.String()}).String() - // load the policies associated with the token from the global enforcer - policies, err := s.Enforcer.GetFilteredPolicy(0, subject) - s.Require().NoError(err) - - // Check that only default policies are loaded - s.Len(policies, len(s.APIToken.DefaultAuthzPolicies)) - for _, p := range s.APIToken.DefaultAuthzPolicies { - ok, err := s.Enforcer.HasPolicy(subject, p.Resource, p.Action) - s.NoError(err) - s.True(ok, fmt.Sprintf("policy %s:%s not found", p.Resource, p.Action)) + // With the new architecture, API token policies are stored in the database, not in Casbin + // Verify that the token has the default policies stored + s.Require().NotNil(token.Policies) + s.Len(token.Policies, len(s.APIToken.DefaultAuthzPolicies)) + + // Check that all default policies are present + for _, expectedPolicy := range s.APIToken.DefaultAuthzPolicies { + found := false + for _, actualPolicy := range token.Policies { + if actualPolicy.Resource == expectedPolicy.Resource && actualPolicy.Action == expectedPolicy.Action { + found = true + break + } + } + s.True(found, fmt.Sprintf("policy %s:%s not found", expectedPolicy.Resource, expectedPolicy.Action)) } } @@ -184,20 +187,6 @@ func (s *apiTokenTestSuite) TestRevoke() { s.True(biz.IsNotFound(err)) }) - s.Run("the revoked token also get its policies cleared", func() { - sub := (&authz.SubjectAPIToken{ID: s.t2.ID.String()}).String() - // It has the default policies - gotPolicies, err := s.Enforcer.GetFilteredPolicy(0, sub) - s.NoError(err) - s.Len(gotPolicies, len(s.APIToken.DefaultAuthzPolicies)) - err = s.APIToken.Revoke(ctx, s.org.ID, s.t2.ID.String()) - s.NoError(err) - // once revoked, the policies are cleared - gotPolicies, err = s.Enforcer.GetFilteredPolicy(0, sub) - s.NoError(err) - s.Len(gotPolicies, 0) - }) - s.Run("token can be revoked once", func() { err := s.APIToken.Revoke(ctx, s.org.ID, s.t1.ID.String()) s.NoError(err) From 0e664f580c40520d3d123d2b325173afd7b600cc Mon Sep 17 00:00:00 2001 From: Miguel Martinez Date: Mon, 10 Nov 2025 13:28:03 +0100 Subject: [PATCH 6/8] fix connection nats Signed-off-by: Miguel Martinez --- app/controlplane/pkg/authz/authz_test.go | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/app/controlplane/pkg/authz/authz_test.go b/app/controlplane/pkg/authz/authz_test.go index 7329b4b54..0b7fef372 100644 --- a/app/controlplane/pkg/authz/authz_test.go +++ b/app/controlplane/pkg/authz/authz_test.go @@ -111,8 +111,7 @@ func TestDoSync(t *testing.T) { assert.NoError(t, err) assert.Len(t, got, 1) - // add additional policy, only deletes policies for "known" resources - // or deleting a whole section + // replace policy for a role - old policies are removed and new ones added policiesM = map[Role][]*Policy{ "bar": { PolicyAttachedIntegrationDetach, @@ -122,7 +121,12 @@ func TestDoSync(t *testing.T) { assert.NoError(t, err) got, err = e.GetPolicy() assert.NoError(t, err) - assert.Len(t, got, 2) + assert.Len(t, got, 1) + + // verify the new policy is present + assert.Equal(t, "bar", got[0][0]) + assert.Equal(t, "integration_attached", got[0][1]) + assert.Equal(t, "delete", got[0][2]) } func testEnforcer(t *testing.T) (*Enforcer, io.Closer) { From 08e3be8ba2ad54c2d71d78f18e1f8d9527ba5320 Mon Sep 17 00:00:00 2001 From: Miguel Martinez Date: Mon, 10 Nov 2025 21:59:05 +0100 Subject: [PATCH 7/8] chore: upgrade atlast image Signed-off-by: Miguel Martinez --- app/controlplane/cmd/main.go | 1 - 1 file changed, 1 deletion(-) diff --git a/app/controlplane/cmd/main.go b/app/controlplane/cmd/main.go index 2e9595604..8e897688b 100644 --- a/app/controlplane/cmd/main.go +++ b/app/controlplane/cmd/main.go @@ -152,7 +152,6 @@ func main() { // TODO: Make it configurable from the application config app.runsExpirer.Run(ctx, &biz.WorkflowRunExpirerOpts{CheckInterval: 1 * time.Minute, ExpirationWindow: 1 * time.Hour}) - // Since policies management is not enabled yet but instead is based on a hardcoded list of permissions // Sync user access go func() { if err := app.userAccessSyncer.SyncUserAccess(ctx); err != nil { From b0ddfc76ea719bb7fdd91adde2b7e102cb7b595d Mon Sep 17 00:00:00 2001 From: Miguel Martinez Date: Mon, 10 Nov 2025 22:04:29 +0100 Subject: [PATCH 8/8] cleanup Signed-off-by: Miguel Martinez --- app/controlplane/cmd/main.go | 5 ++--- app/controlplane/cmd/wire_gen.go | 3 +-- app/controlplane/pkg/biz/apitoken.go | 10 ---------- app/controlplane/pkg/biz/biz.go | 1 - 4 files changed, 3 insertions(+), 16 deletions(-) diff --git a/app/controlplane/cmd/main.go b/app/controlplane/cmd/main.go index 8e897688b..6211eaed5 100644 --- a/app/controlplane/cmd/main.go +++ b/app/controlplane/cmd/main.go @@ -64,7 +64,7 @@ func init() { } func newApp(logger log.Logger, gs *grpc.Server, hs *http.Server, ms *server.HTTPMetricsServer, profilerSvc *server.HTTPProfilerServer, - expirer *biz.WorkflowRunExpirerUseCase, plugins sdk.AvailablePlugins, tokenSync *biz.APITokenSyncerUseCase, + expirer *biz.WorkflowRunExpirerUseCase, plugins sdk.AvailablePlugins, userAccessSyncer *biz.UserAccessSyncerUseCase, casBackendChecker *biz.CASBackendChecker, cfg *conf.Bootstrap) *app { servers := []transport.Server{gs, hs, ms} if cfg.EnableProfiler { @@ -79,7 +79,7 @@ func newApp(logger log.Logger, gs *grpc.Server, hs *http.Server, ms *server.HTTP kratos.Metadata(map[string]string{}), kratos.Logger(logger), kratos.Server(servers...), - ), expirer, plugins, tokenSync, userAccessSyncer, casBackendChecker} + ), expirer, plugins, userAccessSyncer, casBackendChecker} } func main() { @@ -198,7 +198,6 @@ type app struct { // Periodic job that expires unfinished attestation processes older than a given threshold runsExpirer *biz.WorkflowRunExpirerUseCase availablePlugins sdk.AvailablePlugins - tokenAuthSyncer *biz.APITokenSyncerUseCase userAccessSyncer *biz.UserAccessSyncerUseCase // Background checker for CAS backends casBackendChecker *biz.CASBackendChecker diff --git a/app/controlplane/cmd/wire_gen.go b/app/controlplane/cmd/wire_gen.go index c3507fab8..e86b313f4 100644 --- a/app/controlplane/cmd/wire_gen.go +++ b/app/controlplane/cmd/wire_gen.go @@ -306,9 +306,8 @@ func wireApp(bootstrap *conf.Bootstrap, readerWriter credentials.ReaderWriter, l return nil, nil, err } workflowRunExpirerUseCase := biz.NewWorkflowRunExpirerUseCase(workflowRunRepo, prometheusUseCase, logger) - apiTokenSyncerUseCase := biz.NewAPITokenSyncerUseCase(apiTokenUseCase) casBackendChecker := biz.NewCASBackendChecker(logger, casBackendRepo, casBackendUseCase) - mainApp := newApp(logger, grpcServer, httpServer, httpMetricsServer, httpProfilerServer, workflowRunExpirerUseCase, availablePlugins, apiTokenSyncerUseCase, userAccessSyncerUseCase, casBackendChecker, bootstrap) + mainApp := newApp(logger, grpcServer, httpServer, httpMetricsServer, httpProfilerServer, workflowRunExpirerUseCase, availablePlugins, userAccessSyncerUseCase, casBackendChecker, bootstrap) return mainApp, func() { cleanup() }, nil diff --git a/app/controlplane/pkg/biz/apitoken.go b/app/controlplane/pkg/biz/apitoken.go index 179e2e993..0daba9b62 100644 --- a/app/controlplane/pkg/biz/apitoken.go +++ b/app/controlplane/pkg/biz/apitoken.go @@ -80,10 +80,6 @@ type APITokenUseCase struct { auditorUC *AuditorUseCase } -type APITokenSyncerUseCase struct { - base *APITokenUseCase -} - func NewAPITokenUseCase(apiTokenRepo APITokenRepo, jwtConfig *APITokenJWTConfig, authzE *authz.Enforcer, orgUseCase *OrganizationUseCase, auditorUC *AuditorUseCase, logger log.Logger) (*APITokenUseCase, error) { uc := &APITokenUseCase{ apiTokenRepo: apiTokenRepo, @@ -405,12 +401,6 @@ func (uc *APITokenUseCase) FindByNameInOrg(ctx context.Context, orgID, name stri return uc.apiTokenRepo.FindByNameInOrg(ctx, orgUUID, name) } -func NewAPITokenSyncerUseCase(tokenUC *APITokenUseCase) *APITokenSyncerUseCase { - return &APITokenSyncerUseCase{ - base: tokenUC, - } -} - func (uc *APITokenUseCase) UpdateLastUsedAt(ctx context.Context, tokenID string) error { id, err := uuid.Parse(tokenID) if err != nil { diff --git a/app/controlplane/pkg/biz/biz.go b/app/controlplane/pkg/biz/biz.go index ee83195e8..81c51b54a 100644 --- a/app/controlplane/pkg/biz/biz.go +++ b/app/controlplane/pkg/biz/biz.go @@ -48,7 +48,6 @@ var ProviderSet = wire.NewSet( NewCASMappingUseCase, NewReferrerUseCase, NewAPITokenUseCase, - NewAPITokenSyncerUseCase, NewAttestationStateUseCase, NewChainloopSigningUseCase, NewPrometheusUseCase,