diff --git a/pkg/services/serviceaccounts/database/store.go b/pkg/services/serviceaccounts/database/store.go index 5790b755baa..5621f5743a8 100644 --- a/pkg/services/serviceaccounts/database/store.go +++ b/pkg/services/serviceaccounts/database/store.go @@ -171,6 +171,15 @@ func (s *ServiceAccountsStoreImpl) deleteServiceAccount(sess *db.Session, orgId, return nil } +// EnableServiceAccount enable/disable service account +func (s *ServiceAccountsStoreImpl) EnableServiceAccount(ctx context.Context, orgID, serviceAccountID int64, enable bool) error { + return s.sqlStore.WithTransactionalDbSession(ctx, func(sess *db.Session) error { + query := "UPDATE " + s.sqlStore.GetDialect().Quote("user") + " SET is_disabled = ? WHERE id = ? AND is_service_account = ?" + _, err := sess.Exec(query, !enable, serviceAccountID, true) + return err + }) +} + // RetrieveServiceAccount returns a service account by its ID func (s *ServiceAccountsStoreImpl) RetrieveServiceAccount(ctx context.Context, orgId, serviceAccountId int64) (*serviceaccounts.ServiceAccountProfileDTO, error) { serviceAccount := &serviceaccounts.ServiceAccountProfileDTO{} diff --git a/pkg/services/serviceaccounts/database/store_test.go b/pkg/services/serviceaccounts/database/store_test.go index e9e11d5f3ba..c3cb7782496 100644 --- a/pkg/services/serviceaccounts/database/store_test.go +++ b/pkg/services/serviceaccounts/database/store_test.go @@ -495,3 +495,66 @@ func TestServiceAccountsStoreImpl_SearchOrgServiceAccounts(t *testing.T) { }) } } + +func TestServiceAccountsStoreImpl_EnableServiceAccounts(t *testing.T) { + ctx := context.Background() + + initUsers := []tests.TestUser{ + {Name: "satest-1", Role: string(org.RoleViewer), Login: "sa-satest-1", IsServiceAccount: true}, + {Name: "satest-2", Role: string(org.RoleEditor), Login: "sa-satest-2", IsServiceAccount: true}, + {Name: "usertest-3", Role: string(org.RoleEditor), Login: "usertest-3", IsServiceAccount: false}, + } + + db, store := setupTestDatabase(t) + orgID := tests.SetupUsersServiceAccounts(t, db, initUsers) + + fetchStates := func() map[int64]bool { + sa1, err := store.RetrieveServiceAccount(ctx, orgID, 1) + require.NoError(t, err) + sa2, err := store.RetrieveServiceAccount(ctx, orgID, 2) + require.NoError(t, err) + user, err := store.userService.GetByID(ctx, &user.GetUserByIDQuery{ID: 3}) + require.NoError(t, err) + return map[int64]bool{1: !sa1.IsDisabled, 2: !sa2.IsDisabled, 3: !user.IsDisabled} + } + + tt := []struct { + desc string + id int64 + enable bool + wantStates map[int64]bool + }{ + { + desc: "should disable service account", + id: 1, + enable: false, + wantStates: map[int64]bool{1: false, 2: true, 3: true}, + }, + { + desc: "should disable service account again", + id: 1, + enable: false, + wantStates: map[int64]bool{1: false, 2: true, 3: true}, + }, + { + desc: "should enable service account", + id: 1, + enable: true, + wantStates: map[int64]bool{1: true, 2: true, 3: true}, + }, + { + desc: "should not disable user", + id: 3, + enable: false, + wantStates: map[int64]bool{1: true, 2: true, 3: true}, + }, + } + for _, tc := range tt { + t.Run(tc.desc, func(t *testing.T) { + err := store.EnableServiceAccount(ctx, orgID, tc.id, tc.enable) + require.NoError(t, err) + + require.Equal(t, tc.wantStates, fetchStates()) + }) + } +} diff --git a/pkg/services/serviceaccounts/extsvcaccounts/service.go b/pkg/services/serviceaccounts/extsvcaccounts/service.go index ae29ccaedab..0562b5f74db 100644 --- a/pkg/services/serviceaccounts/extsvcaccounts/service.go +++ b/pkg/services/serviceaccounts/extsvcaccounts/service.go @@ -6,6 +6,7 @@ import ( "github.com/prometheus/client_golang/prometheus" + "github.com/grafana/grafana/pkg/bus" "github.com/grafana/grafana/pkg/components/satokengen" "github.com/grafana/grafana/pkg/infra/db" "github.com/grafana/grafana/pkg/infra/log" @@ -14,6 +15,7 @@ import ( ac "github.com/grafana/grafana/pkg/services/accesscontrol" "github.com/grafana/grafana/pkg/services/extsvcauth" "github.com/grafana/grafana/pkg/services/featuremgmt" + "github.com/grafana/grafana/pkg/services/pluginsintegration/pluginsettings" "github.com/grafana/grafana/pkg/services/secrets" "github.com/grafana/grafana/pkg/services/secrets/kvstore" sa "github.com/grafana/grafana/pkg/services/serviceaccounts" @@ -29,7 +31,7 @@ type ExtSvcAccountsService struct { skvStore kvstore.SecretsKVStore } -func ProvideExtSvcAccountsService(acSvc ac.Service, db db.DB, features *featuremgmt.FeatureManager, reg prometheus.Registerer, saSvc *manager.ServiceAccountsService, secretsSvc secrets.Service) *ExtSvcAccountsService { +func ProvideExtSvcAccountsService(acSvc ac.Service, bus bus.Bus, db db.DB, features *featuremgmt.FeatureManager, reg prometheus.Registerer, saSvc *manager.ServiceAccountsService, secretsSvc secrets.Service) *ExtSvcAccountsService { logger := log.New("serviceauth.extsvcaccounts") esa := &ExtSvcAccountsService{ acSvc: acSvc, @@ -39,14 +41,29 @@ func ProvideExtSvcAccountsService(acSvc ac.Service, db db.DB, features *featurem skvStore: kvstore.NewSQLSecretsKVStore(db, secretsSvc, logger), // Using SQL store to avoid a cyclic dependency } - // Register the metrics if features.IsEnabled(featuremgmt.FlagExternalServiceAccounts) || features.IsEnabled(featuremgmt.FlagExternalServiceAuth) { + // Register the metrics esa.metrics = newMetrics(reg, saSvc, logger) + + // Register a listener to enable/disable service accounts + bus.AddEventListener(esa.handlePluginStateChanged) } return esa } +// EnableExtSvcAccount enables or disables the service account associated to an external service +func (esa *ExtSvcAccountsService) EnableExtSvcAccount(ctx context.Context, cmd *sa.EnableExtSvcAccountCmd) error { + saName := sa.ExtSvcPrefix + slugify.Slugify(cmd.ExtSvcSlug) + + saID, errRetrieve := esa.saSvc.RetrieveServiceAccountIdByName(ctx, cmd.OrgID, saName) + if errRetrieve != nil { + return errRetrieve + } + + return esa.saSvc.EnableServiceAccount(ctx, cmd.OrgID, saID, cmd.Enabled) +} + // RetrieveExtSvcAccount fetches an external service account by ID func (esa *ExtSvcAccountsService) RetrieveExtSvcAccount(ctx context.Context, orgID, saID int64) (*sa.ExtSvcAccount, error) { svcAcc, err := esa.saSvc.RetrieveServiceAccount(ctx, orgID, saID) @@ -266,3 +283,20 @@ func (esa *ExtSvcAccountsService) DeleteExtSvcCredentials(ctx context.Context, o esa.logger.Debug("Delete service account token from skv", "service", extSvcSlug, "orgID", orgID) return esa.skvStore.Del(ctx, orgID, extSvcSlug, kvStoreType) } + +func (esa *ExtSvcAccountsService) handlePluginStateChanged(ctx context.Context, event *pluginsettings.PluginStateChangedEvent) error { + esa.logger.Info("Plugin state changed", "pluginId", event.PluginId, "enabled", event.Enabled) + + errEnable := esa.EnableExtSvcAccount(ctx, &sa.EnableExtSvcAccountCmd{ + ExtSvcSlug: event.PluginId, + Enabled: event.Enabled, + OrgID: extsvcauth.TmpOrgID, + }) + + // Ignore service account not found error + if errors.Is(errEnable, sa.ErrServiceAccountNotFound) { + esa.logger.Debug("No ext svc account with this plugin", "pluginId", event.PluginId) + return nil + } + return errEnable +} diff --git a/pkg/services/serviceaccounts/manager/service.go b/pkg/services/serviceaccounts/manager/service.go index 0d037f230e2..8a9b557c145 100644 --- a/pkg/services/serviceaccounts/manager/service.go +++ b/pkg/services/serviceaccounts/manager/service.go @@ -183,6 +183,16 @@ func (sa *ServiceAccountsService) DeleteServiceAccount(ctx context.Context, orgI return sa.store.DeleteServiceAccount(ctx, orgID, serviceAccountID) } +func (sa *ServiceAccountsService) EnableServiceAccount(ctx context.Context, orgID, serviceAccountID int64, enable bool) error { + if err := validOrgID(orgID); err != nil { + return err + } + if err := validServiceAccountID(serviceAccountID); err != nil { + return err + } + return sa.store.EnableServiceAccount(ctx, orgID, serviceAccountID, enable) +} + func (sa *ServiceAccountsService) UpdateServiceAccount(ctx context.Context, orgID int64, serviceAccountID int64, saForm *serviceaccounts.UpdateServiceAccountForm) (*serviceaccounts.ServiceAccountProfileDTO, error) { if err := validOrgID(orgID); err != nil { return nil, err diff --git a/pkg/services/serviceaccounts/manager/service_test.go b/pkg/services/serviceaccounts/manager/service_test.go index 31dce8ef1c4..bf0633bf1eb 100644 --- a/pkg/services/serviceaccounts/manager/service_test.go +++ b/pkg/services/serviceaccounts/manager/service_test.go @@ -25,6 +25,8 @@ type FakeServiceAccountStore struct { ExpectedError error } +var _ store = (*FakeServiceAccountStore)(nil) + func newServiceAccountStoreFake() *FakeServiceAccountStore { return &FakeServiceAccountStore{} } @@ -44,6 +46,11 @@ func (f *FakeServiceAccountStore) CreateServiceAccount(ctx context.Context, orgI return f.ExpectedServiceAccountDTO, f.ExpectedError } +// EnableServiceAccount implements store. +func (f *FakeServiceAccountStore) EnableServiceAccount(ctx context.Context, orgID int64, serviceAccountID int64, enable bool) error { + return f.ExpectedError +} + // SearchOrgServiceAccounts is a fake searching for service accounts. func (f *FakeServiceAccountStore) SearchOrgServiceAccounts(ctx context.Context, query *serviceaccounts.SearchOrgServiceAccountsQuery) (*serviceaccounts.SearchOrgServiceAccountsResult, error) { return f.ExpectedSearchServiceAccountQueryResult, f.ExpectedError diff --git a/pkg/services/serviceaccounts/manager/store.go b/pkg/services/serviceaccounts/manager/store.go index 187ed7e0d86..b64e67d7522 100644 --- a/pkg/services/serviceaccounts/manager/store.go +++ b/pkg/services/serviceaccounts/manager/store.go @@ -8,18 +8,19 @@ import ( ) type store interface { + AddServiceAccountToken(ctx context.Context, serviceAccountID int64, cmd *serviceaccounts.AddServiceAccountTokenCommand) (*apikey.APIKey, error) CreateServiceAccount(ctx context.Context, orgID int64, saForm *serviceaccounts.CreateServiceAccountForm) (*serviceaccounts.ServiceAccountDTO, error) + DeleteServiceAccount(ctx context.Context, orgID, serviceAccountID int64) error + DeleteServiceAccountToken(ctx context.Context, orgID, serviceAccountID, tokenID int64) error + EnableServiceAccount(ctx context.Context, orgID, serviceAccountID int64, enable bool) error + GetUsageMetrics(ctx context.Context) (*serviceaccounts.Stats, error) + ListTokens(ctx context.Context, query *serviceaccounts.GetSATokensQuery) ([]apikey.APIKey, error) + MigrateApiKey(ctx context.Context, orgID int64, keyId int64) error + MigrateApiKeysToServiceAccounts(ctx context.Context, orgID int64) (*serviceaccounts.MigrationResult, error) + RetrieveServiceAccount(ctx context.Context, orgID, serviceAccountID int64) (*serviceaccounts.ServiceAccountProfileDTO, error) + RetrieveServiceAccountIdByName(ctx context.Context, orgID int64, name string) (int64, error) + RevokeServiceAccountToken(ctx context.Context, orgId, serviceAccountId, tokenId int64) error SearchOrgServiceAccounts(ctx context.Context, query *serviceaccounts.SearchOrgServiceAccountsQuery) (*serviceaccounts.SearchOrgServiceAccountsResult, error) UpdateServiceAccount(ctx context.Context, orgID, serviceAccountID int64, saForm *serviceaccounts.UpdateServiceAccountForm) (*serviceaccounts.ServiceAccountProfileDTO, error) - RetrieveServiceAccount(ctx context.Context, orgID, serviceAccountID int64) (*serviceaccounts.ServiceAccountProfileDTO, error) - RetrieveServiceAccountIdByName(ctx context.Context, orgID int64, name string) (int64, error) - DeleteServiceAccount(ctx context.Context, orgID, serviceAccountID int64) error - MigrateApiKeysToServiceAccounts(ctx context.Context, orgID int64) (*serviceaccounts.MigrationResult, error) - MigrateApiKey(ctx context.Context, orgID int64, keyId int64) error - ListTokens(ctx context.Context, query *serviceaccounts.GetSATokensQuery) ([]apikey.APIKey, error) - RevokeServiceAccountToken(ctx context.Context, orgId, serviceAccountId, tokenId int64) error - AddServiceAccountToken(ctx context.Context, serviceAccountID int64, cmd *serviceaccounts.AddServiceAccountTokenCommand) (*apikey.APIKey, error) - DeleteServiceAccountToken(ctx context.Context, orgID, serviceAccountID, tokenID int64) error - GetUsageMetrics(ctx context.Context) (*serviceaccounts.Stats, error) } diff --git a/pkg/services/serviceaccounts/models.go b/pkg/services/serviceaccounts/models.go index 595818bc0e0..411b6f995b1 100644 --- a/pkg/services/serviceaccounts/models.go +++ b/pkg/services/serviceaccounts/models.go @@ -196,6 +196,12 @@ type ManageExtSvcAccountCmd struct { Permissions []accesscontrol.Permission } +type EnableExtSvcAccountCmd struct { + ExtSvcSlug string + Enabled bool + OrgID int64 +} + // AccessEvaluator is used to protect the "Configuration > Service accounts" page access var AccessEvaluator = accesscontrol.EvalAny( accesscontrol.EvalPermission(ActionRead), diff --git a/pkg/services/serviceaccounts/proxy/service.go b/pkg/services/serviceaccounts/proxy/service.go index 312fa8c2990..929a527189e 100644 --- a/pkg/services/serviceaccounts/proxy/service.go +++ b/pkg/services/serviceaccounts/proxy/service.go @@ -92,6 +92,20 @@ func (s *ServiceAccountsProxy) DeleteServiceAccountToken(ctx context.Context, or return s.proxiedService.DeleteServiceAccountToken(ctx, orgID, serviceAccountID, tokenID) } +func (s *ServiceAccountsProxy) EnableServiceAccount(ctx context.Context, orgID int64, serviceAccountID int64, enable bool) error { + if s.isProxyEnabled { + sa, err := s.proxiedService.RetrieveServiceAccount(ctx, orgID, serviceAccountID) + if err != nil { + return err + } + if isExternalServiceAccount(sa.Login) { + s.log.Error("unable to enable/disable external service accounts", "serviceAccountID", serviceAccountID) + return extsvcaccounts.ErrCannotBeUpdated + } + } + return s.proxiedService.EnableServiceAccount(ctx, orgID, serviceAccountID, enable) +} + func (s *ServiceAccountsProxy) ListTokens(ctx context.Context, query *serviceaccounts.GetSATokensQuery) ([]apikey.APIKey, error) { return s.proxiedService.ListTokens(ctx, query) } diff --git a/pkg/services/serviceaccounts/serviceaccounts.go b/pkg/services/serviceaccounts/serviceaccounts.go index 535e2b50625..caef539eaaa 100644 --- a/pkg/services/serviceaccounts/serviceaccounts.go +++ b/pkg/services/serviceaccounts/serviceaccounts.go @@ -12,12 +12,15 @@ ServiceAccountService is the service that manages service accounts. Service accounts are used to authenticate API requests. They are not users and do not have a password. */ + +//go:generate mockery --name Service --structname MockServiceAccountService --output tests --outpkg tests --filename mocks.go type Service interface { CreateServiceAccount(ctx context.Context, orgID int64, saForm *CreateServiceAccountForm) (*ServiceAccountDTO, error) DeleteServiceAccount(ctx context.Context, orgID, serviceAccountID int64) error RetrieveServiceAccount(ctx context.Context, orgID, serviceAccountID int64) (*ServiceAccountProfileDTO, error) RetrieveServiceAccountIdByName(ctx context.Context, orgID int64, name string) (int64, error) SearchOrgServiceAccounts(ctx context.Context, query *SearchOrgServiceAccountsQuery) (*SearchOrgServiceAccountsResult, error) + EnableServiceAccount(ctx context.Context, orgID, serviceAccountID int64, enable bool) error UpdateServiceAccount(ctx context.Context, orgID, serviceAccountID int64, saForm *UpdateServiceAccountForm) (*ServiceAccountProfileDTO, error) @@ -34,6 +37,8 @@ type Service interface { //go:generate mockery --name ExtSvcAccountsService --structname MockExtSvcAccountsService --output tests --outpkg tests --filename extsvcaccmock.go type ExtSvcAccountsService interface { + // EnableExtSvcAccount enables or disables the service account associated to an external service + EnableExtSvcAccount(ctx context.Context, cmd *EnableExtSvcAccountCmd) error // ManageExtSvcAccount creates, updates or deletes the service account associated with an external service ManageExtSvcAccount(ctx context.Context, cmd *ManageExtSvcAccountCmd) (int64, error) // RetrieveExtSvcAccount fetches an external service account by ID diff --git a/pkg/services/serviceaccounts/tests/extsvcaccmock.go b/pkg/services/serviceaccounts/tests/extsvcaccmock.go index 62dd0ef4abf..50b8d9b56d3 100644 --- a/pkg/services/serviceaccounts/tests/extsvcaccmock.go +++ b/pkg/services/serviceaccounts/tests/extsvcaccmock.go @@ -14,6 +14,20 @@ type MockExtSvcAccountsService struct { mock.Mock } +// EnableExtSvcAccount provides a mock function with given fields: ctx, cmd +func (_m *MockExtSvcAccountsService) EnableExtSvcAccount(ctx context.Context, cmd *serviceaccounts.EnableExtSvcAccountCmd) error { + ret := _m.Called(ctx, cmd) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, *serviceaccounts.EnableExtSvcAccountCmd) error); ok { + r0 = rf(ctx, cmd) + } else { + r0 = ret.Error(0) + } + + return r0 +} + // ManageExtSvcAccount provides a mock function with given fields: ctx, cmd func (_m *MockExtSvcAccountsService) ManageExtSvcAccount(ctx context.Context, cmd *serviceaccounts.ManageExtSvcAccountCmd) (int64, error) { ret := _m.Called(ctx, cmd) diff --git a/pkg/services/serviceaccounts/tests/fakes.go b/pkg/services/serviceaccounts/tests/fakes.go index 016c1ec9585..df067ad5ae1 100644 --- a/pkg/services/serviceaccounts/tests/fakes.go +++ b/pkg/services/serviceaccounts/tests/fakes.go @@ -33,6 +33,10 @@ func (f *FakeServiceAccountService) DeleteServiceAccount(ctx context.Context, or return f.ExpectedErr } +func (f *FakeServiceAccountService) EnableServiceAccount(ctx context.Context, orgID int64, serviceAccountID int64, enable bool) error { + return f.ExpectedErr +} + func (f *FakeServiceAccountService) RetrieveServiceAccount(ctx context.Context, orgID, id int64) (*serviceaccounts.ServiceAccountProfileDTO, error) { return f.ExpectedServiceAccountProfile, f.ExpectedErr } diff --git a/pkg/services/serviceaccounts/tests/mocks.go b/pkg/services/serviceaccounts/tests/mocks.go index 3e310802f9d..5cd884fcf8d 100644 --- a/pkg/services/serviceaccounts/tests/mocks.go +++ b/pkg/services/serviceaccounts/tests/mocks.go @@ -1,82 +1,294 @@ +// Code generated by mockery v2.35.2. DO NOT EDIT. + package tests import ( - "context" + context "context" - "github.com/stretchr/testify/mock" + apikey "github.com/grafana/grafana/pkg/services/apikey" - "github.com/grafana/grafana/pkg/services/apikey" - "github.com/grafana/grafana/pkg/services/serviceaccounts" + mock "github.com/stretchr/testify/mock" + + serviceaccounts "github.com/grafana/grafana/pkg/services/serviceaccounts" ) -var _ serviceaccounts.Service = &MockServiceAccountService{} - +// MockServiceAccountService is an autogenerated mock type for the Service type type MockServiceAccountService struct { mock.Mock } -// AddServiceAccountToken implements serviceaccounts.Service -func (s *MockServiceAccountService) AddServiceAccountToken(ctx context.Context, serviceAccountID int64, cmd *serviceaccounts.AddServiceAccountTokenCommand) (*apikey.APIKey, error) { - mockedArgs := s.Called(ctx, serviceAccountID, cmd) - return mockedArgs.Get(0).(*apikey.APIKey), mockedArgs.Error(1) +// AddServiceAccountToken provides a mock function with given fields: ctx, serviceAccountID, cmd +func (_m *MockServiceAccountService) AddServiceAccountToken(ctx context.Context, serviceAccountID int64, cmd *serviceaccounts.AddServiceAccountTokenCommand) (*apikey.APIKey, error) { + ret := _m.Called(ctx, serviceAccountID, cmd) + + var r0 *apikey.APIKey + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, int64, *serviceaccounts.AddServiceAccountTokenCommand) (*apikey.APIKey, error)); ok { + return rf(ctx, serviceAccountID, cmd) + } + if rf, ok := ret.Get(0).(func(context.Context, int64, *serviceaccounts.AddServiceAccountTokenCommand) *apikey.APIKey); ok { + r0 = rf(ctx, serviceAccountID, cmd) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*apikey.APIKey) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, int64, *serviceaccounts.AddServiceAccountTokenCommand) error); ok { + r1 = rf(ctx, serviceAccountID, cmd) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } -// CreateServiceAccount implements serviceaccounts.Service -func (s *MockServiceAccountService) CreateServiceAccount(ctx context.Context, orgID int64, saForm *serviceaccounts.CreateServiceAccountForm) (*serviceaccounts.ServiceAccountDTO, error) { - mockedArgs := s.Called(ctx, orgID, saForm) - return mockedArgs.Get(0).(*serviceaccounts.ServiceAccountDTO), mockedArgs.Error(1) +// CreateServiceAccount provides a mock function with given fields: ctx, orgID, saForm +func (_m *MockServiceAccountService) CreateServiceAccount(ctx context.Context, orgID int64, saForm *serviceaccounts.CreateServiceAccountForm) (*serviceaccounts.ServiceAccountDTO, error) { + ret := _m.Called(ctx, orgID, saForm) + + var r0 *serviceaccounts.ServiceAccountDTO + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, int64, *serviceaccounts.CreateServiceAccountForm) (*serviceaccounts.ServiceAccountDTO, error)); ok { + return rf(ctx, orgID, saForm) + } + if rf, ok := ret.Get(0).(func(context.Context, int64, *serviceaccounts.CreateServiceAccountForm) *serviceaccounts.ServiceAccountDTO); ok { + r0 = rf(ctx, orgID, saForm) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*serviceaccounts.ServiceAccountDTO) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, int64, *serviceaccounts.CreateServiceAccountForm) error); ok { + r1 = rf(ctx, orgID, saForm) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } -// DeleteServiceAccount implements serviceaccounts.Service -func (s *MockServiceAccountService) DeleteServiceAccount(ctx context.Context, orgID int64, serviceAccountID int64) error { - mockedArgs := s.Called(ctx, orgID, serviceAccountID) - return mockedArgs.Error(0) +// DeleteServiceAccount provides a mock function with given fields: ctx, orgID, serviceAccountID +func (_m *MockServiceAccountService) DeleteServiceAccount(ctx context.Context, orgID int64, serviceAccountID int64) error { + ret := _m.Called(ctx, orgID, serviceAccountID) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, int64, int64) error); ok { + r0 = rf(ctx, orgID, serviceAccountID) + } else { + r0 = ret.Error(0) + } + + return r0 } -// DeleteServiceAccountToken implements serviceaccounts.Service -func (s *MockServiceAccountService) DeleteServiceAccountToken(ctx context.Context, orgID, serviceAccountID, tokenID int64) error { - mockedArgs := s.Called(ctx, orgID, serviceAccountID, tokenID) - return mockedArgs.Error(0) +// DeleteServiceAccountToken provides a mock function with given fields: ctx, orgID, serviceAccountID, tokenID +func (_m *MockServiceAccountService) DeleteServiceAccountToken(ctx context.Context, orgID int64, serviceAccountID int64, tokenID int64) error { + ret := _m.Called(ctx, orgID, serviceAccountID, tokenID) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, int64, int64, int64) error); ok { + r0 = rf(ctx, orgID, serviceAccountID, tokenID) + } else { + r0 = ret.Error(0) + } + + return r0 } -// ListTokens implements serviceaccounts.Service -func (s *MockServiceAccountService) ListTokens(ctx context.Context, query *serviceaccounts.GetSATokensQuery) ([]apikey.APIKey, error) { - mockedArgs := s.Called(ctx, query) - return mockedArgs.Get(0).([]apikey.APIKey), mockedArgs.Error(1) +// EnableServiceAccount provides a mock function with given fields: ctx, orgID, serviceAccountID, enable +func (_m *MockServiceAccountService) EnableServiceAccount(ctx context.Context, orgID int64, serviceAccountID int64, enable bool) error { + ret := _m.Called(ctx, orgID, serviceAccountID, enable) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, int64, int64, bool) error); ok { + r0 = rf(ctx, orgID, serviceAccountID, enable) + } else { + r0 = ret.Error(0) + } + + return r0 } -// MigrateApiKey implements serviceaccounts.Service -func (s *MockServiceAccountService) MigrateApiKey(ctx context.Context, orgID int64, keyId int64) error { - mockedArgs := s.Called(ctx, orgID, keyId) - return mockedArgs.Error(0) +// ListTokens provides a mock function with given fields: ctx, query +func (_m *MockServiceAccountService) ListTokens(ctx context.Context, query *serviceaccounts.GetSATokensQuery) ([]apikey.APIKey, error) { + ret := _m.Called(ctx, query) + + var r0 []apikey.APIKey + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *serviceaccounts.GetSATokensQuery) ([]apikey.APIKey, error)); ok { + return rf(ctx, query) + } + if rf, ok := ret.Get(0).(func(context.Context, *serviceaccounts.GetSATokensQuery) []apikey.APIKey); ok { + r0 = rf(ctx, query) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]apikey.APIKey) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *serviceaccounts.GetSATokensQuery) error); ok { + r1 = rf(ctx, query) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } -// MigrateApiKeysToServiceAccounts implements serviceaccounts.Service -func (s *MockServiceAccountService) MigrateApiKeysToServiceAccounts(ctx context.Context, orgID int64) (*serviceaccounts.MigrationResult, error) { - mockedArgs := s.Called(ctx, orgID) - return mockedArgs.Get(0).(*serviceaccounts.MigrationResult), mockedArgs.Error(1) +// MigrateApiKey provides a mock function with given fields: ctx, orgID, keyId +func (_m *MockServiceAccountService) MigrateApiKey(ctx context.Context, orgID int64, keyId int64) error { + ret := _m.Called(ctx, orgID, keyId) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, int64, int64) error); ok { + r0 = rf(ctx, orgID, keyId) + } else { + r0 = ret.Error(0) + } + + return r0 } -// RetrieveServiceAccount implements serviceaccounts.Service -func (s *MockServiceAccountService) RetrieveServiceAccount(ctx context.Context, orgID int64, serviceAccountID int64) (*serviceaccounts.ServiceAccountProfileDTO, error) { - mockedArgs := s.Called(ctx, orgID, serviceAccountID) - return mockedArgs.Get(0).(*serviceaccounts.ServiceAccountProfileDTO), mockedArgs.Error(1) +// MigrateApiKeysToServiceAccounts provides a mock function with given fields: ctx, orgID +func (_m *MockServiceAccountService) MigrateApiKeysToServiceAccounts(ctx context.Context, orgID int64) (*serviceaccounts.MigrationResult, error) { + ret := _m.Called(ctx, orgID) + + var r0 *serviceaccounts.MigrationResult + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, int64) (*serviceaccounts.MigrationResult, error)); ok { + return rf(ctx, orgID) + } + if rf, ok := ret.Get(0).(func(context.Context, int64) *serviceaccounts.MigrationResult); ok { + r0 = rf(ctx, orgID) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*serviceaccounts.MigrationResult) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, int64) error); ok { + r1 = rf(ctx, orgID) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } -// RetrieveServiceAccountIdByName implements serviceaccounts.Service -func (s *MockServiceAccountService) RetrieveServiceAccountIdByName(ctx context.Context, orgID int64, name string) (int64, error) { - mockedArgs := s.Called(ctx, orgID, name) - return mockedArgs.Get(0).(int64), mockedArgs.Error(1) +// RetrieveServiceAccount provides a mock function with given fields: ctx, orgID, serviceAccountID +func (_m *MockServiceAccountService) RetrieveServiceAccount(ctx context.Context, orgID int64, serviceAccountID int64) (*serviceaccounts.ServiceAccountProfileDTO, error) { + ret := _m.Called(ctx, orgID, serviceAccountID) + + var r0 *serviceaccounts.ServiceAccountProfileDTO + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, int64, int64) (*serviceaccounts.ServiceAccountProfileDTO, error)); ok { + return rf(ctx, orgID, serviceAccountID) + } + if rf, ok := ret.Get(0).(func(context.Context, int64, int64) *serviceaccounts.ServiceAccountProfileDTO); ok { + r0 = rf(ctx, orgID, serviceAccountID) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*serviceaccounts.ServiceAccountProfileDTO) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, int64, int64) error); ok { + r1 = rf(ctx, orgID, serviceAccountID) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } -// SearchOrgServiceAccounts implements serviceaccounts.Service -func (s *MockServiceAccountService) SearchOrgServiceAccounts(ctx context.Context, query *serviceaccounts.SearchOrgServiceAccountsQuery) (*serviceaccounts.SearchOrgServiceAccountsResult, error) { - mockedArgs := s.Called(ctx, query) - return mockedArgs.Get(0).(*serviceaccounts.SearchOrgServiceAccountsResult), mockedArgs.Error(1) +// RetrieveServiceAccountIdByName provides a mock function with given fields: ctx, orgID, name +func (_m *MockServiceAccountService) RetrieveServiceAccountIdByName(ctx context.Context, orgID int64, name string) (int64, error) { + ret := _m.Called(ctx, orgID, name) + + var r0 int64 + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, int64, string) (int64, error)); ok { + return rf(ctx, orgID, name) + } + if rf, ok := ret.Get(0).(func(context.Context, int64, string) int64); ok { + r0 = rf(ctx, orgID, name) + } else { + r0 = ret.Get(0).(int64) + } + + if rf, ok := ret.Get(1).(func(context.Context, int64, string) error); ok { + r1 = rf(ctx, orgID, name) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } -// UpdateServiceAccount implements serviceaccounts.Service -func (s *MockServiceAccountService) UpdateServiceAccount(ctx context.Context, orgID int64, serviceAccountID int64, saForm *serviceaccounts.UpdateServiceAccountForm) (*serviceaccounts.ServiceAccountProfileDTO, error) { - mockedArgs := s.Called(ctx, orgID, serviceAccountID) - return mockedArgs.Get(0).(*serviceaccounts.ServiceAccountProfileDTO), mockedArgs.Error(1) +// SearchOrgServiceAccounts provides a mock function with given fields: ctx, query +func (_m *MockServiceAccountService) SearchOrgServiceAccounts(ctx context.Context, query *serviceaccounts.SearchOrgServiceAccountsQuery) (*serviceaccounts.SearchOrgServiceAccountsResult, error) { + ret := _m.Called(ctx, query) + + var r0 *serviceaccounts.SearchOrgServiceAccountsResult + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *serviceaccounts.SearchOrgServiceAccountsQuery) (*serviceaccounts.SearchOrgServiceAccountsResult, error)); ok { + return rf(ctx, query) + } + if rf, ok := ret.Get(0).(func(context.Context, *serviceaccounts.SearchOrgServiceAccountsQuery) *serviceaccounts.SearchOrgServiceAccountsResult); ok { + r0 = rf(ctx, query) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*serviceaccounts.SearchOrgServiceAccountsResult) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *serviceaccounts.SearchOrgServiceAccountsQuery) error); ok { + r1 = rf(ctx, query) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// UpdateServiceAccount provides a mock function with given fields: ctx, orgID, serviceAccountID, saForm +func (_m *MockServiceAccountService) UpdateServiceAccount(ctx context.Context, orgID int64, serviceAccountID int64, saForm *serviceaccounts.UpdateServiceAccountForm) (*serviceaccounts.ServiceAccountProfileDTO, error) { + ret := _m.Called(ctx, orgID, serviceAccountID, saForm) + + var r0 *serviceaccounts.ServiceAccountProfileDTO + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, int64, int64, *serviceaccounts.UpdateServiceAccountForm) (*serviceaccounts.ServiceAccountProfileDTO, error)); ok { + return rf(ctx, orgID, serviceAccountID, saForm) + } + if rf, ok := ret.Get(0).(func(context.Context, int64, int64, *serviceaccounts.UpdateServiceAccountForm) *serviceaccounts.ServiceAccountProfileDTO); ok { + r0 = rf(ctx, orgID, serviceAccountID, saForm) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*serviceaccounts.ServiceAccountProfileDTO) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, int64, int64, *serviceaccounts.UpdateServiceAccountForm) error); ok { + r1 = rf(ctx, orgID, serviceAccountID, saForm) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// NewMockServiceAccountService creates a new instance of MockServiceAccountService. 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 NewMockServiceAccountService(t interface { + mock.TestingT + Cleanup(func()) +}) *MockServiceAccountService { + mock := &MockServiceAccountService{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock }