ServiceAccounts: Add access control metadata to service accounts (#45096)

* add role to DTO

* add access control metadata
This commit is contained in:
J Guerreiro 2022-02-08 19:19:22 +00:00 committed by GitHub
parent e3dd5cdc51
commit 2cf421dfe3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 48 additions and 10 deletions

View File

@ -6,8 +6,10 @@ import (
"net/http"
"strconv"
"github.com/grafana/grafana/pkg/api/dtos"
"github.com/grafana/grafana/pkg/api/response"
"github.com/grafana/grafana/pkg/api/routing"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/middleware"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
@ -31,6 +33,7 @@ type ServiceAccountsAPI struct {
RouterRegister routing.RouteRegister
store serviceaccounts.Store
apiKeyStore APIKeyStore
log log.Logger
}
type serviceAccountIdDTO struct {
@ -53,6 +56,7 @@ func NewServiceAccountsAPI(
RouterRegister: routerRegister,
store: store,
apiKeyStore: apiKeyStore,
log: log.New("serviceaccounts.api"),
}
}
@ -132,14 +136,42 @@ func (api *ServiceAccountsAPI) ConvertToServiceAccount(ctx *models.ReqContext) r
}
}
func (api *ServiceAccountsAPI) ListServiceAccounts(ctx *models.ReqContext) response.Response {
serviceAccounts, err := api.store.ListServiceAccounts(ctx.Req.Context(), ctx.OrgId, -1)
func (api *ServiceAccountsAPI) ListServiceAccounts(c *models.ReqContext) response.Response {
serviceAccounts, err := api.store.ListServiceAccounts(c.Req.Context(), c.OrgId, -1)
if err != nil {
return response.Error(http.StatusInternalServerError, "Failed to list service accounts", err)
}
saIDs := map[string]bool{}
for i := range serviceAccounts {
serviceAccounts[i].AvatarUrl = dtos.GetGravatarUrlWithDefault("", serviceAccounts[i].Name)
saIDs[strconv.FormatInt(serviceAccounts[i].Id, 10)] = true
}
metadata, err := api.getAccessControlMetadata(c, saIDs)
if err == nil && len(metadata) != 0 {
for i := range serviceAccounts {
serviceAccounts[i].AccessControl = metadata[strconv.FormatInt(serviceAccounts[i].Id, 10)]
}
}
return response.JSON(http.StatusOK, serviceAccounts)
}
func (api *ServiceAccountsAPI) getAccessControlMetadata(c *models.ReqContext, saIDs map[string]bool) (map[string]accesscontrol.Metadata, error) {
if api.accesscontrol.IsDisabled() || !c.QueryBool("accesscontrol") {
return nil, nil
}
userPermissions, err := api.accesscontrol.GetUserPermissions(c.Req.Context(), c.SignedInUser)
if err != nil || len(userPermissions) == 0 {
api.log.Warn("could not fetch accesscontrol metadata for teams", "error", err)
return nil, err
}
return accesscontrol.GetResourcesMetadata(c.Req.Context(), userPermissions, "serviceaccounts", saIDs), nil
}
func (api *ServiceAccountsAPI) RetrieveServiceAccount(ctx *models.ReqContext) response.Response {
scopeID, err := strconv.ParseInt(web.Params(ctx.Req)[":serviceAccountId"], 10, 64)
if err != nil {

View File

@ -143,10 +143,11 @@ func (s *ServiceAccountsStoreImpl) ListServiceAccounts(ctx context.Context, orgI
if serviceAccountID > 0 {
query.UserID = serviceAccountID
}
err := s.sqlStore.GetOrgUsers(ctx, &query)
if err != nil {
if err := s.sqlStore.GetOrgUsers(ctx, &query); err != nil {
return nil, err
}
saDTOs := make([]*serviceaccounts.ServiceAccountDTO, len(query.Result))
for i, user := range query.Result {
saDTOs[i] = &serviceaccounts.ServiceAccountDTO{
@ -154,6 +155,7 @@ func (s *ServiceAccountsStoreImpl) ListServiceAccounts(ctx context.Context, orgI
OrgId: user.OrgId,
Name: user.Name,
Login: user.Login,
Role: user.Role,
}
tokens, err := s.ListTokens(ctx, user.OrgId, user.UserId)
if err != nil {
@ -161,7 +163,8 @@ func (s *ServiceAccountsStoreImpl) ListServiceAccounts(ctx context.Context, orgI
}
saDTOs[i].Tokens = int64(len(tokens))
}
return saDTOs, err
return saDTOs, nil
}
// RetrieveServiceAccountByID returns a service account by its ID

View File

@ -28,11 +28,14 @@ type CreateServiceaccountForm struct {
}
type ServiceAccountDTO struct {
Id int64 `json:"id"`
Name string `json:"name"`
Login string `json:"login"`
OrgId int64 `json:"orgId"`
Tokens int64 `json:"tokens"`
Id int64 `json:"id"`
Name string `json:"name"`
Login string `json:"login"`
OrgId int64 `json:"orgId"`
Tokens int64 `json:"tokens"`
Role string `json:"role"`
AvatarUrl string `json:"avatarUrl"`
AccessControl map[string]bool `json:"accessControl,omitempty"`
}
type ServiceAccountProfileDTO struct {