mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Auth: Move Service Account service to SignedInUser Interface (#73142)
* move service account service to identity interface * Update pkg/services/auth/identity/requester.go
This commit is contained in:
@@ -11,6 +11,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/apikey"
|
||||
"github.com/grafana/grafana/pkg/services/auth/identity"
|
||||
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
|
||||
"github.com/grafana/grafana/pkg/services/org"
|
||||
"github.com/grafana/grafana/pkg/services/serviceaccounts"
|
||||
@@ -101,17 +102,26 @@ func (api *ServiceAccountsAPI) CreateServiceAccount(c *contextmodel.ReqContext)
|
||||
return response.Error(http.StatusBadRequest, "Bad request data", err)
|
||||
}
|
||||
|
||||
if err := api.validateRole(cmd.Role, &c.OrgRole); err != nil {
|
||||
if err := api.validateRole(cmd.Role, c.SignedInUser.GetOrgRole()); err != nil {
|
||||
return response.ErrOrFallback(http.StatusInternalServerError, "failed to create service account", err)
|
||||
}
|
||||
|
||||
serviceAccount, err := api.service.CreateServiceAccount(c.Req.Context(), c.OrgID, &cmd)
|
||||
serviceAccount, err := api.service.CreateServiceAccount(c.Req.Context(), c.SignedInUser.GetOrgID(), &cmd)
|
||||
if err != nil {
|
||||
return response.ErrOrFallback(http.StatusInternalServerError, "Failed to create service account", err)
|
||||
}
|
||||
|
||||
if c.SignedInUser.IsRealUser() {
|
||||
if _, err := api.permissionService.SetUserPermission(c.Req.Context(), c.OrgID, accesscontrol.User{ID: c.SignedInUser.UserID}, strconv.FormatInt(serviceAccount.Id, 10), "Admin"); err != nil {
|
||||
namespace, identifier := c.SignedInUser.GetNamespacedID()
|
||||
|
||||
if namespace == identity.NamespaceUser {
|
||||
userID, err := identity.IntIdentifier(namespace, identifier)
|
||||
if err != nil {
|
||||
return response.Error(http.StatusInternalServerError, "Failed to parse user id", err)
|
||||
}
|
||||
|
||||
if _, err := api.permissionService.SetUserPermission(c.Req.Context(),
|
||||
c.SignedInUser.GetOrgID(), accesscontrol.User{ID: userID},
|
||||
strconv.FormatInt(serviceAccount.Id, 10), "Admin"); err != nil {
|
||||
return response.Error(http.StatusInternalServerError, "Failed to set permissions for service account creator", err)
|
||||
}
|
||||
}
|
||||
@@ -143,7 +153,7 @@ func (api *ServiceAccountsAPI) RetrieveServiceAccount(ctx *contextmodel.ReqConte
|
||||
return response.Error(http.StatusBadRequest, "Service Account ID is invalid", err)
|
||||
}
|
||||
|
||||
serviceAccount, err := api.service.RetrieveServiceAccount(ctx.Req.Context(), ctx.OrgID, scopeID)
|
||||
serviceAccount, err := api.service.RetrieveServiceAccount(ctx.Req.Context(), ctx.SignedInUser.GetOrgID(), scopeID)
|
||||
if err != nil {
|
||||
return response.ErrOrFallback(http.StatusInternalServerError, "Failed to retrieve service account", err)
|
||||
}
|
||||
@@ -190,11 +200,11 @@ func (api *ServiceAccountsAPI) UpdateServiceAccount(c *contextmodel.ReqContext)
|
||||
return response.Error(http.StatusBadRequest, "Bad request data", err)
|
||||
}
|
||||
|
||||
if err := api.validateRole(cmd.Role, &c.OrgRole); err != nil {
|
||||
if err := api.validateRole(cmd.Role, c.SignedInUser.GetOrgRole()); err != nil {
|
||||
return response.ErrOrFallback(http.StatusInternalServerError, "failed to update service account", err)
|
||||
}
|
||||
|
||||
resp, err := api.service.UpdateServiceAccount(c.Req.Context(), c.OrgID, scopeID, &cmd)
|
||||
resp, err := api.service.UpdateServiceAccount(c.Req.Context(), c.SignedInUser.GetOrgID(), scopeID, &cmd)
|
||||
if err != nil {
|
||||
return response.ErrOrFallback(http.StatusInternalServerError, "Failed update service account", err)
|
||||
}
|
||||
@@ -212,7 +222,7 @@ func (api *ServiceAccountsAPI) UpdateServiceAccount(c *contextmodel.ReqContext)
|
||||
})
|
||||
}
|
||||
|
||||
func (api *ServiceAccountsAPI) validateRole(r *org.RoleType, orgRole *org.RoleType) error {
|
||||
func (api *ServiceAccountsAPI) validateRole(r *org.RoleType, orgRole org.RoleType) error {
|
||||
if r != nil && !r.IsValid() {
|
||||
return serviceaccounts.ErrServiceAccountInvalidRole.Errorf("invalid role specified")
|
||||
}
|
||||
@@ -240,7 +250,7 @@ func (api *ServiceAccountsAPI) DeleteServiceAccount(ctx *contextmodel.ReqContext
|
||||
if err != nil {
|
||||
return response.Error(http.StatusBadRequest, "Service account ID is invalid", err)
|
||||
}
|
||||
err = api.service.DeleteServiceAccount(ctx.Req.Context(), ctx.OrgID, scopeID)
|
||||
err = api.service.DeleteServiceAccount(ctx.Req.Context(), ctx.SignedInUser.GetOrgID(), scopeID)
|
||||
if err != nil {
|
||||
return response.Error(http.StatusInternalServerError, "Service account deletion error", err)
|
||||
}
|
||||
@@ -280,7 +290,7 @@ func (api *ServiceAccountsAPI) SearchOrgServiceAccountsWithPaging(c *contextmode
|
||||
filter = serviceaccounts.FilterOnlyDisabled
|
||||
}
|
||||
q := serviceaccounts.SearchOrgServiceAccountsQuery{
|
||||
OrgID: c.OrgID,
|
||||
OrgID: c.SignedInUser.GetOrgID(),
|
||||
Query: c.Query("query"),
|
||||
Page: page,
|
||||
Limit: perPage,
|
||||
@@ -315,7 +325,7 @@ func (api *ServiceAccountsAPI) SearchOrgServiceAccountsWithPaging(c *contextmode
|
||||
|
||||
// POST /api/serviceaccounts/migrate
|
||||
func (api *ServiceAccountsAPI) MigrateApiKeysToServiceAccounts(ctx *contextmodel.ReqContext) response.Response {
|
||||
results, err := api.service.MigrateApiKeysToServiceAccounts(ctx.Req.Context(), ctx.OrgID)
|
||||
results, err := api.service.MigrateApiKeysToServiceAccounts(ctx.Req.Context(), ctx.SignedInUser.GetOrgID())
|
||||
if err != nil {
|
||||
return response.JSON(http.StatusInternalServerError, results)
|
||||
}
|
||||
@@ -330,7 +340,7 @@ func (api *ServiceAccountsAPI) ConvertToServiceAccount(ctx *contextmodel.ReqCont
|
||||
return response.Error(http.StatusBadRequest, "Key ID is invalid", err)
|
||||
}
|
||||
|
||||
if err := api.service.MigrateApiKey(ctx.Req.Context(), ctx.OrgID, keyId); err != nil {
|
||||
if err := api.service.MigrateApiKey(ctx.Req.Context(), ctx.SignedInUser.GetOrgID(), keyId); err != nil {
|
||||
return response.Error(http.StatusInternalServerError, "Error converting API key", err)
|
||||
}
|
||||
|
||||
@@ -342,15 +352,11 @@ func (api *ServiceAccountsAPI) getAccessControlMetadata(c *contextmodel.ReqConte
|
||||
return map[string]accesscontrol.Metadata{}
|
||||
}
|
||||
|
||||
if c.SignedInUser.Permissions == nil {
|
||||
return map[string]accesscontrol.Metadata{}
|
||||
}
|
||||
|
||||
permissions, ok := c.SignedInUser.Permissions[c.OrgID]
|
||||
if !ok {
|
||||
if len(c.SignedInUser.GetPermissions()) == 0 {
|
||||
return map[string]accesscontrol.Metadata{}
|
||||
}
|
||||
|
||||
permissions := c.SignedInUser.GetPermissions()
|
||||
return accesscontrol.GetResourcesMetadata(c.Req.Context(), permissions, "serviceaccounts:id:", saIDs)
|
||||
}
|
||||
|
||||
|
||||
@@ -85,7 +85,9 @@ func TestServiceAccountsAPI_CreateServiceAccount(t *testing.T) {
|
||||
a.service = &fakeServiceAccountService{ExpectedServiceAccount: tt.expectedSA, ExpectedErr: tt.expectedErr}
|
||||
})
|
||||
req := server.NewRequest(http.MethodPost, "/api/serviceaccounts/", strings.NewReader(tt.body))
|
||||
webtest.RequestWithSignedInUser(req, &user.SignedInUser{OrgRole: tt.basicRole, OrgID: 1, Permissions: map[int64]map[string][]string{1: accesscontrol.GroupScopesByAction(tt.permissions)}})
|
||||
webtest.RequestWithSignedInUser(req, &user.SignedInUser{
|
||||
OrgRole: tt.basicRole, OrgID: 1, IsAnonymous: true,
|
||||
Permissions: map[int64]map[string][]string{1: accesscontrol.GroupScopesByAction(tt.permissions)}})
|
||||
res, err := server.SendJSON(req)
|
||||
require.NoError(t, err)
|
||||
|
||||
|
||||
@@ -69,8 +69,9 @@ func (api *ServiceAccountsAPI) ListTokens(ctx *contextmodel.ReqContext) response
|
||||
return response.Error(http.StatusBadRequest, "Service Account ID is invalid", err)
|
||||
}
|
||||
|
||||
orgID := ctx.SignedInUser.GetOrgID()
|
||||
saTokens, err := api.service.ListTokens(ctx.Req.Context(), &serviceaccounts.GetSATokensQuery{
|
||||
OrgID: &ctx.OrgID,
|
||||
OrgID: &orgID,
|
||||
ServiceAccountID: &saID,
|
||||
})
|
||||
if err != nil {
|
||||
@@ -131,7 +132,7 @@ func (api *ServiceAccountsAPI) CreateToken(c *contextmodel.ReqContext) response.
|
||||
}
|
||||
|
||||
// confirm service account exists
|
||||
if _, err = api.service.RetrieveServiceAccount(c.Req.Context(), c.OrgID, saID); err != nil {
|
||||
if _, err = api.service.RetrieveServiceAccount(c.Req.Context(), c.SignedInUser.GetOrgID(), saID); err != nil {
|
||||
return response.ErrOrFallback(http.StatusInternalServerError, "Failed to retrieve service account", err)
|
||||
}
|
||||
|
||||
@@ -141,7 +142,7 @@ func (api *ServiceAccountsAPI) CreateToken(c *contextmodel.ReqContext) response.
|
||||
}
|
||||
|
||||
// Force affected service account to be the one referenced in the URL
|
||||
cmd.OrgId = c.OrgID
|
||||
cmd.OrgId = c.SignedInUser.GetOrgID()
|
||||
|
||||
if api.cfg.ApiKeyMaxSecondsToLive != -1 {
|
||||
if cmd.SecondsToLive == 0 {
|
||||
@@ -204,7 +205,7 @@ func (api *ServiceAccountsAPI) DeleteToken(c *contextmodel.ReqContext) response.
|
||||
}
|
||||
|
||||
// confirm service account exists
|
||||
if _, err := api.service.RetrieveServiceAccount(c.Req.Context(), c.OrgID, saID); err != nil {
|
||||
if _, err := api.service.RetrieveServiceAccount(c.Req.Context(), c.SignedInUser.GetOrgID(), saID); err != nil {
|
||||
return response.ErrOrFallback(http.StatusInternalServerError, "Failed to retrieve service account", err)
|
||||
}
|
||||
|
||||
@@ -213,7 +214,7 @@ func (api *ServiceAccountsAPI) DeleteToken(c *contextmodel.ReqContext) response.
|
||||
return response.Error(http.StatusBadRequest, "Token ID is invalid", err)
|
||||
}
|
||||
|
||||
if err = api.service.DeleteServiceAccountToken(c.Req.Context(), c.OrgID, saID, tokenID); err != nil {
|
||||
if err = api.service.DeleteServiceAccountToken(c.Req.Context(), c.SignedInUser.GetOrgID(), saID, tokenID); err != nil {
|
||||
return response.ErrOrFallback(http.StatusInternalServerError, failedToDeleteMsg, err)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user