AuthN: Change the external service account state on plugin state change (#77157)

* Disable plugin service account

* Revert extsvc injection

* handle plugin state changes

* Use isProxyEnabled

* Remove plugininteg changes

* Change update function to also work for mysql 😩

* Change test to also check no collateral update

* Update pkg/services/serviceaccounts/database/store_test.go

* Update pkg/services/serviceaccounts/database/store_test.go
This commit is contained in:
Gabriel MABILLE 2023-10-27 13:46:25 +02:00 committed by GitHub
parent 57335cb173
commit 2727f41474
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 441 additions and 62 deletions

View File

@ -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{}

View File

@ -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())
})
}
}

View File

@ -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
}

View File

@ -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

View File

@ -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

View File

@ -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)
}

View File

@ -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),

View File

@ -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)
}

View File

@ -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

View File

@ -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)

View File

@ -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
}

View File

@ -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
}