API keys: Remove state hideAPIkeys and refactor interface to IsDisabled (#64018)

* remove state and refactor interface to IsDisabled

* update docs and span

* Update pkg/services/apikey/apikey.go

Co-authored-by: Alexander Zobnin <alexanderzobnin@gmail.com>

---------

Co-authored-by: Alexander Zobnin <alexanderzobnin@gmail.com>
This commit is contained in:
Eric Leijonmarck
2023-03-03 16:12:34 +00:00
committed by GitHub
co-authored by Alexander Zobnin
parent e6e8351ee9
commit ad4b053231
16 changed files with 87 additions and 216 deletions
+2 -1
View File
@@ -7,11 +7,12 @@ import (
type Service interface {
GetAPIKeys(ctx context.Context, query *GetApiKeysQuery) error
GetAllAPIKeys(ctx context.Context, orgID int64) ([]*APIKey, error)
CountAPIKeys(ctx context.Context, orgID int64) (int64, error)
DeleteApiKey(ctx context.Context, cmd *DeleteCommand) error
AddAPIKey(ctx context.Context, cmd *AddCommand) error
GetApiKeyById(ctx context.Context, query *GetByIDQuery) error
GetApiKeyByName(ctx context.Context, query *GetByNameQuery) error
GetAPIKeyByHash(ctx context.Context, hash string) (*APIKey, error)
UpdateAPIKeyLastUsedDate(ctx context.Context, tokenID int64) error
// IsDisabled returns true if the API key is not available for use.
IsDisabled(ctx context.Context, orgID int64) (bool, error)
}
+9 -2
View File
@@ -68,8 +68,15 @@ func (s *Service) AddAPIKey(ctx context.Context, cmd *apikey.AddCommand) error {
func (s *Service) UpdateAPIKeyLastUsedDate(ctx context.Context, tokenID int64) error {
return s.store.UpdateAPIKeyLastUsedDate(ctx, tokenID)
}
func (s *Service) CountAPIKeys(ctx context.Context, orgID int64) (int64, error) {
return s.store.CountAPIKeys(ctx, orgID)
// IsDisabled returns true if the apikey service is disabled for the given org.
// This is the case if the org has no apikeys.
func (s *Service) IsDisabled(ctx context.Context, orgID int64) (bool, error) {
apikeys, err := s.store.CountAPIKeys(ctx, orgID)
if err != nil {
return false, err
}
return apikeys == 0, nil
}
func readQuotaConfig(cfg *setting.Cfg) (*quota.Map, error) {
+4 -4
View File
@@ -8,7 +8,7 @@ import (
type Service struct {
ExpectedError error
ExpectedCount int64
ExpectedBool bool
ExpectedAPIKeys []*apikey.APIKey
ExpectedAPIKey *apikey.APIKey
}
@@ -20,9 +20,6 @@ func (s *Service) GetAPIKeys(ctx context.Context, query *apikey.GetApiKeysQuery)
func (s *Service) GetAllAPIKeys(ctx context.Context, orgID int64) ([]*apikey.APIKey, error) {
return s.ExpectedAPIKeys, s.ExpectedError
}
func (s *Service) CountAPIKeys(ctx context.Context, orgID int64) (int64, error) {
return s.ExpectedCount, s.ExpectedError
}
func (s *Service) GetApiKeyById(ctx context.Context, query *apikey.GetByIDQuery) error {
query.Result = s.ExpectedAPIKey
return s.ExpectedError
@@ -44,3 +41,6 @@ func (s *Service) AddAPIKey(ctx context.Context, cmd *apikey.AddCommand) error {
func (s *Service) UpdateAPIKeyLastUsedDate(ctx context.Context, tokenID int64) error {
return s.ExpectedError
}
func (s *Service) IsDisabled(ctx context.Context, orgID int64) (bool, error) {
return s.ExpectedBool, s.ExpectedError
}
+2 -6
View File
@@ -79,15 +79,11 @@ func (s *ServiceImpl) getOrgAdminNode(c *contextmodel.ReqContext) (*navtree.NavL
})
}
hideApiKeys, _, _ := s.kvStore.Get(c.Req.Context(), c.OrgID, "serviceaccounts", "hideApiKeys")
apiKeys, err := s.apiKeyService.CountAPIKeys(c.Req.Context(), c.OrgID)
disabled, err := s.apiKeyService.IsDisabled(c.Req.Context(), c.OrgID)
if err != nil {
return nil, err
}
// Hide API keys if the global setting is set or if the org setting is set and there are no API keys
apiKeysHidden := hideApiKeys == "1" && apiKeys == 0
if hasAccess(ac.ReqOrgAdmin, ac.ApiKeyAccessEvaluator) && !apiKeysHidden {
if hasAccess(ac.ReqOrgAdmin, ac.ApiKeyAccessEvaluator) && !disabled {
configNodes = append(configNodes, &navtree.NavLink{
Text: "API keys",
Id: "apikeys",
-11
View File
@@ -40,7 +40,6 @@ type service interface {
SearchOrgServiceAccounts(ctx context.Context, query *serviceaccounts.SearchOrgServiceAccountsQuery) (*serviceaccounts.SearchOrgServiceAccountsResult, error)
ListTokens(ctx context.Context, query *serviceaccounts.GetSATokensQuery) ([]apikey.APIKey, error)
DeleteServiceAccount(ctx context.Context, orgID, serviceAccountID int64) error
HideApiKeysTab(ctx context.Context, orgID int64) error
MigrateApiKeysToServiceAccounts(ctx context.Context, orgID int64) error
MigrateApiKey(ctx context.Context, orgID int64, keyId int64) error
// Service account tokens
@@ -86,8 +85,6 @@ func (api *ServiceAccountsAPI) RegisterAPIEndpoints() {
accesscontrol.EvalPermission(serviceaccounts.ActionWrite, serviceaccounts.ScopeID)), routing.Wrap(api.CreateToken))
serviceAccountsRoute.Delete("/:serviceAccountId/tokens/:tokenId", auth(middleware.ReqOrgAdmin,
accesscontrol.EvalPermission(serviceaccounts.ActionWrite, serviceaccounts.ScopeID)), routing.Wrap(api.DeleteToken))
serviceAccountsRoute.Post("/hideApiKeys", auth(middleware.ReqOrgAdmin,
accesscontrol.EvalPermission(serviceaccounts.ActionCreate)), routing.Wrap(api.HideApiKeysTab))
serviceAccountsRoute.Post("/migrate", auth(middleware.ReqOrgAdmin,
accesscontrol.EvalPermission(serviceaccounts.ActionCreate)), routing.Wrap(api.MigrateApiKeysToServiceAccounts))
serviceAccountsRoute.Post("/migrate/:keyId", auth(middleware.ReqOrgAdmin,
@@ -357,14 +354,6 @@ func (api *ServiceAccountsAPI) SearchOrgServiceAccountsWithPaging(c *contextmode
return response.JSON(http.StatusOK, serviceAccountSearch)
}
// POST /api/serviceaccounts/hideapikeys
func (api *ServiceAccountsAPI) HideApiKeysTab(ctx *contextmodel.ReqContext) response.Response {
if err := api.service.HideApiKeysTab(ctx.Req.Context(), ctx.OrgID); err != nil {
return response.Error(http.StatusInternalServerError, "Internal server error", err)
}
return response.Success("API keys hidden")
}
// POST /api/serviceaccounts/migrate
func (api *ServiceAccountsAPI) MigrateApiKeysToServiceAccounts(ctx *contextmodel.ReqContext) response.Response {
if err := api.service.MigrateApiKeysToServiceAccounts(ctx.Req.Context(), ctx.OrgID); err != nil {
@@ -364,13 +364,6 @@ func (s *ServiceAccountsStoreImpl) SearchOrgServiceAccounts(ctx context.Context,
return searchResult, nil
}
func (s *ServiceAccountsStoreImpl) HideApiKeysTab(ctx context.Context, orgId int64) error {
if err := s.kvStore.Set(ctx, orgId, "serviceaccounts", "hideApiKeys", "1"); err != nil {
s.log.Error("Failed to hide API keys tab", err)
}
return nil
}
func (s *ServiceAccountsStoreImpl) MigrateApiKeysToServiceAccounts(ctx context.Context, orgId int64) error {
basicKeys, err := s.apiKeyService.GetAllAPIKeys(ctx, orgId)
if err != nil {
@@ -226,13 +226,6 @@ func (sa *ServiceAccountsService) DeleteServiceAccountToken(ctx context.Context,
return sa.store.DeleteServiceAccountToken(ctx, orgID, serviceAccountID, tokenID)
}
func (sa *ServiceAccountsService) HideApiKeysTab(ctx context.Context, orgID int64) error {
if err := validOrgID(orgID); err != nil {
return err
}
return sa.store.HideApiKeysTab(ctx, orgID)
}
func (sa *ServiceAccountsService) MigrateApiKey(ctx context.Context, orgID, keyID int64) error {
if err := validOrgID(orgID); err != nil {
return err
@@ -59,11 +59,6 @@ func (f *FakeServiceAccountStore) DeleteServiceAccount(ctx context.Context, orgI
return f.ExpectedError
}
// HideApiKeysTab is a fake hiding the api keys tab.
func (f *FakeServiceAccountStore) HideApiKeysTab(ctx context.Context, orgID int64) error {
return f.ExpectedError
}
// MigrateApiKeysToServiceAccounts is a fake migrating api keys to service accounts.
func (f *FakeServiceAccountStore) MigrateApiKeysToServiceAccounts(ctx context.Context, orgID int64) error {
return f.ExpectedError
@@ -7,17 +7,6 @@ import (
"github.com/grafana/grafana/pkg/services/serviceaccounts"
)
/*
Store is the database store for service accounts.
migration from apikeys to service accounts:
HideApiKeyTab is used to hide the api key tab in the UI.
MigrateApiKeysToServiceAccounts migrates all API keys to service accounts.
MigrateApiKey migrates a single API key to a service account.
// only used for interal api calls
RevertApiKey reverts a single service account to an API key.
*/
type store interface {
CreateServiceAccount(ctx context.Context, orgID int64, saForm *serviceaccounts.CreateServiceAccountForm) (*serviceaccounts.ServiceAccountDTO, error)
SearchOrgServiceAccounts(ctx context.Context, query *serviceaccounts.SearchOrgServiceAccountsQuery) (*serviceaccounts.SearchOrgServiceAccountsResult, error)
@@ -26,7 +15,6 @@ type store interface {
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
HideApiKeysTab(ctx context.Context, orgID int64) error
MigrateApiKeysToServiceAccounts(ctx context.Context, orgID int64) error
MigrateApiKey(ctx context.Context, orgID int64, keyId int64) error
ListTokens(ctx context.Context, query *serviceaccounts.GetSATokensQuery) ([]apikey.APIKey, error)