Service account: Update service accounts creation (#51848)
This commit is contained in:
@@ -84,7 +84,18 @@ func (api *ServiceAccountsAPI) CreateServiceAccount(c *models.ReqContext) respon
|
||||
return response.Error(http.StatusBadRequest, "Bad request data", err)
|
||||
}
|
||||
|
||||
serviceAccount, err := api.store.CreateServiceAccount(c.Req.Context(), c.OrgId, cmd.Name)
|
||||
if err := api.validateRole(cmd.Role, &c.OrgRole); err != nil {
|
||||
switch {
|
||||
case errors.Is(err, serviceaccounts.ErrServiceAccountInvalidRole):
|
||||
return response.Error(http.StatusBadRequest, err.Error(), err)
|
||||
case errors.Is(err, serviceaccounts.ErrServiceAccountRolePrivilegeDenied):
|
||||
return response.Error(http.StatusForbidden, err.Error(), err)
|
||||
default:
|
||||
return response.Error(http.StatusInternalServerError, "failed to create service account", err)
|
||||
}
|
||||
}
|
||||
|
||||
serviceAccount, err := api.store.CreateServiceAccount(c.Req.Context(), c.OrgId, &cmd)
|
||||
switch {
|
||||
case errors.Is(err, database.ErrServiceAccountAlreadyExists):
|
||||
return response.Error(http.StatusBadRequest, "Failed to create service account", err)
|
||||
@@ -138,11 +149,15 @@ func (api *ServiceAccountsAPI) UpdateServiceAccount(c *models.ReqContext) respon
|
||||
return response.Error(http.StatusBadRequest, "Bad request data", err)
|
||||
}
|
||||
|
||||
if cmd.Role != nil && !cmd.Role.IsValid() {
|
||||
return response.Error(http.StatusBadRequest, "Invalid role specified", nil)
|
||||
}
|
||||
if cmd.Role != nil && !c.OrgRole.Includes(*cmd.Role) {
|
||||
return response.Error(http.StatusForbidden, "Cannot assign a role higher than user's role", nil)
|
||||
if err := api.validateRole(cmd.Role, &c.OrgRole); err != nil {
|
||||
switch {
|
||||
case errors.Is(err, serviceaccounts.ErrServiceAccountInvalidRole):
|
||||
return response.Error(http.StatusBadRequest, err.Error(), err)
|
||||
case errors.Is(err, serviceaccounts.ErrServiceAccountRolePrivilegeDenied):
|
||||
return response.Error(http.StatusForbidden, err.Error(), err)
|
||||
default:
|
||||
return response.Error(http.StatusInternalServerError, "failed to update service account", err)
|
||||
}
|
||||
}
|
||||
|
||||
resp, err := api.store.UpdateServiceAccount(c.Req.Context(), c.OrgId, scopeID, &cmd)
|
||||
@@ -168,6 +183,16 @@ func (api *ServiceAccountsAPI) UpdateServiceAccount(c *models.ReqContext) respon
|
||||
})
|
||||
}
|
||||
|
||||
func (api *ServiceAccountsAPI) validateRole(r *models.RoleType, orgRole *models.RoleType) error {
|
||||
if r != nil && !r.IsValid() {
|
||||
return serviceaccounts.ErrServiceAccountInvalidRole
|
||||
}
|
||||
if r != nil && !orgRole.Includes(*r) {
|
||||
return serviceaccounts.ErrServiceAccountRolePrivilegeDenied
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DELETE /api/serviceaccounts/:serviceAccountId
|
||||
func (api *ServiceAccountsAPI) DeleteServiceAccount(ctx *models.ReqContext) response.Response {
|
||||
scopeID, err := strconv.ParseInt(web.Params(ctx.Req)[":serviceAccountId"], 10, 64)
|
||||
|
||||
@@ -58,8 +58,8 @@ func TestServiceAccountsAPI_CreateServiceAccount(t *testing.T) {
|
||||
}
|
||||
testCases := []testCreateSATestCase{
|
||||
{
|
||||
desc: "should be ok to create serviceaccount with permissions",
|
||||
body: map[string]interface{}{"name": "New SA"},
|
||||
desc: "should be ok to create service account with permissions",
|
||||
body: map[string]interface{}{"name": "New SA", "role": "Viewer", "is_disabled": "false"},
|
||||
wantID: "sa-new-sa",
|
||||
acmock: tests.SetupMockAccesscontrol(
|
||||
t,
|
||||
@@ -70,6 +70,33 @@ func TestServiceAccountsAPI_CreateServiceAccount(t *testing.T) {
|
||||
),
|
||||
expectedCode: http.StatusCreated,
|
||||
},
|
||||
{
|
||||
desc: "should fail to create a service account with higher privilege",
|
||||
body: map[string]interface{}{"name": "New SA HP", "role": "Admin"},
|
||||
wantID: "sa-new-sa-hp",
|
||||
acmock: tests.SetupMockAccesscontrol(
|
||||
t,
|
||||
func(c context.Context, siu *models.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) {
|
||||
return []accesscontrol.Permission{{Action: serviceaccounts.ActionCreate}}, nil
|
||||
},
|
||||
false,
|
||||
),
|
||||
expectedCode: http.StatusForbidden,
|
||||
},
|
||||
{
|
||||
desc: "should fail to create a service account with invalid role",
|
||||
body: map[string]interface{}{"name": "New SA", "role": "Random"},
|
||||
wantID: "sa-new-sa",
|
||||
wantError: "invalid role value: Random",
|
||||
acmock: tests.SetupMockAccesscontrol(
|
||||
t,
|
||||
func(c context.Context, siu *models.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) {
|
||||
return []accesscontrol.Permission{{Action: serviceaccounts.ActionCreate}}, nil
|
||||
},
|
||||
false,
|
||||
),
|
||||
expectedCode: http.StatusBadRequest,
|
||||
},
|
||||
{
|
||||
desc: "not ok - duplicate name",
|
||||
body: map[string]interface{}{"name": "New SA"},
|
||||
@@ -97,7 +124,7 @@ func TestServiceAccountsAPI_CreateServiceAccount(t *testing.T) {
|
||||
expectedCode: http.StatusBadRequest,
|
||||
},
|
||||
{
|
||||
desc: "should be forbidden to create serviceaccount if no permissions",
|
||||
desc: "should be forbidden to create service account if no permissions",
|
||||
body: map[string]interface{}{},
|
||||
acmock: tests.SetupMockAccesscontrol(
|
||||
t,
|
||||
|
||||
Reference in New Issue
Block a user