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
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 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 // RetrieveServiceAccount returns a service account by its ID
func (s *ServiceAccountsStoreImpl) RetrieveServiceAccount(ctx context.Context, orgId, serviceAccountId int64) (*serviceaccounts.ServiceAccountProfileDTO, error) { func (s *ServiceAccountsStoreImpl) RetrieveServiceAccount(ctx context.Context, orgId, serviceAccountId int64) (*serviceaccounts.ServiceAccountProfileDTO, error) {
serviceAccount := &serviceaccounts.ServiceAccountProfileDTO{} 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/prometheus/client_golang/prometheus"
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/components/satokengen" "github.com/grafana/grafana/pkg/components/satokengen"
"github.com/grafana/grafana/pkg/infra/db" "github.com/grafana/grafana/pkg/infra/db"
"github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/infra/log"
@@ -14,6 +15,7 @@ import (
ac "github.com/grafana/grafana/pkg/services/accesscontrol" ac "github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/extsvcauth" "github.com/grafana/grafana/pkg/services/extsvcauth"
"github.com/grafana/grafana/pkg/services/featuremgmt" "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"
"github.com/grafana/grafana/pkg/services/secrets/kvstore" "github.com/grafana/grafana/pkg/services/secrets/kvstore"
sa "github.com/grafana/grafana/pkg/services/serviceaccounts" sa "github.com/grafana/grafana/pkg/services/serviceaccounts"
@@ -29,7 +31,7 @@ type ExtSvcAccountsService struct {
skvStore kvstore.SecretsKVStore 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") logger := log.New("serviceauth.extsvcaccounts")
esa := &ExtSvcAccountsService{ esa := &ExtSvcAccountsService{
acSvc: acSvc, 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 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) { if features.IsEnabled(featuremgmt.FlagExternalServiceAccounts) || features.IsEnabled(featuremgmt.FlagExternalServiceAuth) {
// Register the metrics
esa.metrics = newMetrics(reg, saSvc, logger) esa.metrics = newMetrics(reg, saSvc, logger)
// Register a listener to enable/disable service accounts
bus.AddEventListener(esa.handlePluginStateChanged)
} }
return esa 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 // RetrieveExtSvcAccount fetches an external service account by ID
func (esa *ExtSvcAccountsService) RetrieveExtSvcAccount(ctx context.Context, orgID, saID int64) (*sa.ExtSvcAccount, error) { func (esa *ExtSvcAccountsService) RetrieveExtSvcAccount(ctx context.Context, orgID, saID int64) (*sa.ExtSvcAccount, error) {
svcAcc, err := esa.saSvc.RetrieveServiceAccount(ctx, orgID, saID) 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) esa.logger.Debug("Delete service account token from skv", "service", extSvcSlug, "orgID", orgID)
return esa.skvStore.Del(ctx, orgID, extSvcSlug, kvStoreType) 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) 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) { func (sa *ServiceAccountsService) UpdateServiceAccount(ctx context.Context, orgID int64, serviceAccountID int64, saForm *serviceaccounts.UpdateServiceAccountForm) (*serviceaccounts.ServiceAccountProfileDTO, error) {
if err := validOrgID(orgID); err != nil { if err := validOrgID(orgID); err != nil {
return nil, err return nil, err

View File

@@ -25,6 +25,8 @@ type FakeServiceAccountStore struct {
ExpectedError error ExpectedError error
} }
var _ store = (*FakeServiceAccountStore)(nil)
func newServiceAccountStoreFake() *FakeServiceAccountStore { func newServiceAccountStoreFake() *FakeServiceAccountStore {
return &FakeServiceAccountStore{} return &FakeServiceAccountStore{}
} }
@@ -44,6 +46,11 @@ func (f *FakeServiceAccountStore) CreateServiceAccount(ctx context.Context, orgI
return f.ExpectedServiceAccountDTO, f.ExpectedError 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. // SearchOrgServiceAccounts is a fake searching for service accounts.
func (f *FakeServiceAccountStore) SearchOrgServiceAccounts(ctx context.Context, query *serviceaccounts.SearchOrgServiceAccountsQuery) (*serviceaccounts.SearchOrgServiceAccountsResult, error) { func (f *FakeServiceAccountStore) SearchOrgServiceAccounts(ctx context.Context, query *serviceaccounts.SearchOrgServiceAccountsQuery) (*serviceaccounts.SearchOrgServiceAccountsResult, error) {
return f.ExpectedSearchServiceAccountQueryResult, f.ExpectedError return f.ExpectedSearchServiceAccountQueryResult, f.ExpectedError

View File

@@ -8,18 +8,19 @@ import (
) )
type store interface { 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) 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) SearchOrgServiceAccounts(ctx context.Context, query *serviceaccounts.SearchOrgServiceAccountsQuery) (*serviceaccounts.SearchOrgServiceAccountsResult, error)
UpdateServiceAccount(ctx context.Context, orgID, serviceAccountID int64, UpdateServiceAccount(ctx context.Context, orgID, serviceAccountID int64,
saForm *serviceaccounts.UpdateServiceAccountForm) (*serviceaccounts.ServiceAccountProfileDTO, error) 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 Permissions []accesscontrol.Permission
} }
type EnableExtSvcAccountCmd struct {
ExtSvcSlug string
Enabled bool
OrgID int64
}
// AccessEvaluator is used to protect the "Configuration > Service accounts" page access // AccessEvaluator is used to protect the "Configuration > Service accounts" page access
var AccessEvaluator = accesscontrol.EvalAny( var AccessEvaluator = accesscontrol.EvalAny(
accesscontrol.EvalPermission(ActionRead), 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) 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) { func (s *ServiceAccountsProxy) ListTokens(ctx context.Context, query *serviceaccounts.GetSATokensQuery) ([]apikey.APIKey, error) {
return s.proxiedService.ListTokens(ctx, query) 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 Service accounts are used to authenticate API requests. They are not users and
do not have a password. do not have a password.
*/ */
//go:generate mockery --name Service --structname MockServiceAccountService --output tests --outpkg tests --filename mocks.go
type Service interface { type Service interface {
CreateServiceAccount(ctx context.Context, orgID int64, saForm *CreateServiceAccountForm) (*ServiceAccountDTO, error) CreateServiceAccount(ctx context.Context, orgID int64, saForm *CreateServiceAccountForm) (*ServiceAccountDTO, error)
DeleteServiceAccount(ctx context.Context, orgID, serviceAccountID int64) error DeleteServiceAccount(ctx context.Context, orgID, serviceAccountID int64) error
RetrieveServiceAccount(ctx context.Context, orgID, serviceAccountID int64) (*ServiceAccountProfileDTO, error) RetrieveServiceAccount(ctx context.Context, orgID, serviceAccountID int64) (*ServiceAccountProfileDTO, error)
RetrieveServiceAccountIdByName(ctx context.Context, orgID int64, name string) (int64, error) RetrieveServiceAccountIdByName(ctx context.Context, orgID int64, name string) (int64, error)
SearchOrgServiceAccounts(ctx context.Context, query *SearchOrgServiceAccountsQuery) (*SearchOrgServiceAccountsResult, 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, UpdateServiceAccount(ctx context.Context, orgID, serviceAccountID int64,
saForm *UpdateServiceAccountForm) (*ServiceAccountProfileDTO, error) 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 //go:generate mockery --name ExtSvcAccountsService --structname MockExtSvcAccountsService --output tests --outpkg tests --filename extsvcaccmock.go
type ExtSvcAccountsService interface { 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 creates, updates or deletes the service account associated with an external service
ManageExtSvcAccount(ctx context.Context, cmd *ManageExtSvcAccountCmd) (int64, error) ManageExtSvcAccount(ctx context.Context, cmd *ManageExtSvcAccountCmd) (int64, error)
// RetrieveExtSvcAccount fetches an external service account by ID // RetrieveExtSvcAccount fetches an external service account by ID

View File

@@ -14,6 +14,20 @@ type MockExtSvcAccountsService struct {
mock.Mock 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 // ManageExtSvcAccount provides a mock function with given fields: ctx, cmd
func (_m *MockExtSvcAccountsService) ManageExtSvcAccount(ctx context.Context, cmd *serviceaccounts.ManageExtSvcAccountCmd) (int64, error) { func (_m *MockExtSvcAccountsService) ManageExtSvcAccount(ctx context.Context, cmd *serviceaccounts.ManageExtSvcAccountCmd) (int64, error) {
ret := _m.Called(ctx, cmd) ret := _m.Called(ctx, cmd)

View File

@@ -33,6 +33,10 @@ func (f *FakeServiceAccountService) DeleteServiceAccount(ctx context.Context, or
return f.ExpectedErr 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) { func (f *FakeServiceAccountService) RetrieveServiceAccount(ctx context.Context, orgID, id int64) (*serviceaccounts.ServiceAccountProfileDTO, error) {
return f.ExpectedServiceAccountProfile, f.ExpectedErr return f.ExpectedServiceAccountProfile, f.ExpectedErr
} }

View File

@@ -1,82 +1,294 @@
// Code generated by mockery v2.35.2. DO NOT EDIT.
package tests package tests
import ( import (
"context" context "context"
"github.com/stretchr/testify/mock" apikey "github.com/grafana/grafana/pkg/services/apikey"
"github.com/grafana/grafana/pkg/services/apikey" mock "github.com/stretchr/testify/mock"
"github.com/grafana/grafana/pkg/services/serviceaccounts"
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 { type MockServiceAccountService struct {
mock.Mock mock.Mock
} }
// AddServiceAccountToken implements serviceaccounts.Service // AddServiceAccountToken provides a mock function with given fields: ctx, serviceAccountID, cmd
func (s *MockServiceAccountService) AddServiceAccountToken(ctx context.Context, serviceAccountID int64, cmd *serviceaccounts.AddServiceAccountTokenCommand) (*apikey.APIKey, error) { func (_m *MockServiceAccountService) AddServiceAccountToken(ctx context.Context, serviceAccountID int64, cmd *serviceaccounts.AddServiceAccountTokenCommand) (*apikey.APIKey, error) {
mockedArgs := s.Called(ctx, serviceAccountID, cmd) ret := _m.Called(ctx, serviceAccountID, cmd)
return mockedArgs.Get(0).(*apikey.APIKey), mockedArgs.Error(1)
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 // CreateServiceAccount provides a mock function with given fields: ctx, orgID, saForm
func (s *MockServiceAccountService) CreateServiceAccount(ctx context.Context, orgID int64, saForm *serviceaccounts.CreateServiceAccountForm) (*serviceaccounts.ServiceAccountDTO, error) { func (_m *MockServiceAccountService) CreateServiceAccount(ctx context.Context, orgID int64, saForm *serviceaccounts.CreateServiceAccountForm) (*serviceaccounts.ServiceAccountDTO, error) {
mockedArgs := s.Called(ctx, orgID, saForm) ret := _m.Called(ctx, orgID, saForm)
return mockedArgs.Get(0).(*serviceaccounts.ServiceAccountDTO), mockedArgs.Error(1)
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 // DeleteServiceAccount provides a mock function with given fields: ctx, orgID, serviceAccountID
func (s *MockServiceAccountService) DeleteServiceAccount(ctx context.Context, orgID int64, serviceAccountID int64) error { func (_m *MockServiceAccountService) DeleteServiceAccount(ctx context.Context, orgID int64, serviceAccountID int64) error {
mockedArgs := s.Called(ctx, orgID, serviceAccountID) ret := _m.Called(ctx, orgID, serviceAccountID)
return mockedArgs.Error(0)
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 // DeleteServiceAccountToken provides a mock function with given fields: ctx, orgID, serviceAccountID, tokenID
func (s *MockServiceAccountService) DeleteServiceAccountToken(ctx context.Context, orgID, serviceAccountID, tokenID int64) error { func (_m *MockServiceAccountService) DeleteServiceAccountToken(ctx context.Context, orgID int64, serviceAccountID int64, tokenID int64) error {
mockedArgs := s.Called(ctx, orgID, serviceAccountID, tokenID) ret := _m.Called(ctx, orgID, serviceAccountID, tokenID)
return mockedArgs.Error(0)
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 // EnableServiceAccount provides a mock function with given fields: ctx, orgID, serviceAccountID, enable
func (s *MockServiceAccountService) ListTokens(ctx context.Context, query *serviceaccounts.GetSATokensQuery) ([]apikey.APIKey, error) { func (_m *MockServiceAccountService) EnableServiceAccount(ctx context.Context, orgID int64, serviceAccountID int64, enable bool) error {
mockedArgs := s.Called(ctx, query) ret := _m.Called(ctx, orgID, serviceAccountID, enable)
return mockedArgs.Get(0).([]apikey.APIKey), mockedArgs.Error(1)
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 // ListTokens provides a mock function with given fields: ctx, query
func (s *MockServiceAccountService) MigrateApiKey(ctx context.Context, orgID int64, keyId int64) error { func (_m *MockServiceAccountService) ListTokens(ctx context.Context, query *serviceaccounts.GetSATokensQuery) ([]apikey.APIKey, error) {
mockedArgs := s.Called(ctx, orgID, keyId) ret := _m.Called(ctx, query)
return mockedArgs.Error(0)
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 // MigrateApiKey provides a mock function with given fields: ctx, orgID, keyId
func (s *MockServiceAccountService) MigrateApiKeysToServiceAccounts(ctx context.Context, orgID int64) (*serviceaccounts.MigrationResult, error) { func (_m *MockServiceAccountService) MigrateApiKey(ctx context.Context, orgID int64, keyId int64) error {
mockedArgs := s.Called(ctx, orgID) ret := _m.Called(ctx, orgID, keyId)
return mockedArgs.Get(0).(*serviceaccounts.MigrationResult), mockedArgs.Error(1)
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 // MigrateApiKeysToServiceAccounts provides a mock function with given fields: ctx, orgID
func (s *MockServiceAccountService) RetrieveServiceAccount(ctx context.Context, orgID int64, serviceAccountID int64) (*serviceaccounts.ServiceAccountProfileDTO, error) { func (_m *MockServiceAccountService) MigrateApiKeysToServiceAccounts(ctx context.Context, orgID int64) (*serviceaccounts.MigrationResult, error) {
mockedArgs := s.Called(ctx, orgID, serviceAccountID) ret := _m.Called(ctx, orgID)
return mockedArgs.Get(0).(*serviceaccounts.ServiceAccountProfileDTO), mockedArgs.Error(1)
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 // RetrieveServiceAccount provides a mock function with given fields: ctx, orgID, serviceAccountID
func (s *MockServiceAccountService) RetrieveServiceAccountIdByName(ctx context.Context, orgID int64, name string) (int64, error) { func (_m *MockServiceAccountService) RetrieveServiceAccount(ctx context.Context, orgID int64, serviceAccountID int64) (*serviceaccounts.ServiceAccountProfileDTO, error) {
mockedArgs := s.Called(ctx, orgID, name) ret := _m.Called(ctx, orgID, serviceAccountID)
return mockedArgs.Get(0).(int64), mockedArgs.Error(1)
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 // RetrieveServiceAccountIdByName provides a mock function with given fields: ctx, orgID, name
func (s *MockServiceAccountService) SearchOrgServiceAccounts(ctx context.Context, query *serviceaccounts.SearchOrgServiceAccountsQuery) (*serviceaccounts.SearchOrgServiceAccountsResult, error) { func (_m *MockServiceAccountService) RetrieveServiceAccountIdByName(ctx context.Context, orgID int64, name string) (int64, error) {
mockedArgs := s.Called(ctx, query) ret := _m.Called(ctx, orgID, name)
return mockedArgs.Get(0).(*serviceaccounts.SearchOrgServiceAccountsResult), mockedArgs.Error(1)
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 // SearchOrgServiceAccounts provides a mock function with given fields: ctx, query
func (s *MockServiceAccountService) UpdateServiceAccount(ctx context.Context, orgID int64, serviceAccountID int64, saForm *serviceaccounts.UpdateServiceAccountForm) (*serviceaccounts.ServiceAccountProfileDTO, error) { func (_m *MockServiceAccountService) SearchOrgServiceAccounts(ctx context.Context, query *serviceaccounts.SearchOrgServiceAccountsQuery) (*serviceaccounts.SearchOrgServiceAccountsResult, error) {
mockedArgs := s.Called(ctx, orgID, serviceAccountID) ret := _m.Called(ctx, query)
return mockedArgs.Get(0).(*serviceaccounts.ServiceAccountProfileDTO), mockedArgs.Error(1)
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
} }