grafana/pkg/api/folder_permission.go

194 lines
5.7 KiB
Go
Raw Normal View History

2018-02-20 08:25:16 -06:00
package api
import (
"context"
"net/http"
2018-02-20 08:25:16 -06:00
"time"
"github.com/grafana/grafana/pkg/api/apierrors"
2018-02-20 08:25:16 -06:00
"github.com/grafana/grafana/pkg/api/dtos"
"github.com/grafana/grafana/pkg/api/response"
"github.com/grafana/grafana/pkg/services/auth/identity"
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/folder"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/web"
2018-02-20 08:25:16 -06:00
)
// swagger:route GET /folders/{folder_uid}/permissions folder_permissions getFolderPermissionList
//
// Gets all existing permissions for the folder with the given `uid`.
//
// Responses:
// 200: getFolderPermissionListResponse
// 401: unauthorisedError
// 403: forbiddenError
// 404: notFoundError
// 500: internalServerError
func (hs *HTTPServer) GetFolderPermissionList(c *contextmodel.ReqContext) response.Response {
uid := web.Params(c.Req)[":uid"]
folder, err := hs.folderService.Get(c.Req.Context(), &folder.GetFolderQuery{OrgID: c.OrgID, UID: &uid, SignedInUser: c.SignedInUser})
2018-02-20 08:25:16 -06:00
if err != nil {
return apierrors.ToFolderErrorResponse(err)
2018-02-20 08:25:16 -06:00
}
acl, err := hs.getFolderACL(c.Req.Context(), c.SignedInUser, folder)
2018-02-20 08:25:16 -06:00
if err != nil {
return response.Error(500, "Failed to get folder permissions", err)
2018-02-20 08:25:16 -06:00
}
filteredACLs := make([]*dashboards.DashboardACLInfoDTO, 0, len(acl))
2018-02-20 08:25:16 -06:00
for _, perm := range acl {
if perm.UserID > 0 && dtos.IsHiddenUser(perm.UserLogin, c.SignedInUser, hs.Cfg) {
continue
}
perm.FolderID = folder.ID
perm.DashboardID = 0
2018-02-20 08:25:16 -06:00
perm.UserAvatarURL = dtos.GetGravatarUrl(perm.UserEmail)
if perm.TeamID > 0 {
perm.TeamAvatarURL = dtos.GetGravatarUrlWithDefault(perm.TeamEmail, perm.Team)
}
2018-02-20 08:25:16 -06:00
if perm.Slug != "" {
perm.URL = dashboards.GetDashboardFolderURL(perm.IsFolder, perm.UID, perm.Slug)
2018-02-20 08:25:16 -06:00
}
filteredACLs = append(filteredACLs, perm)
2018-02-20 08:25:16 -06:00
}
return response.JSON(http.StatusOK, filteredACLs)
2018-02-20 08:25:16 -06:00
}
// swagger:route POST /folders/{folder_uid}/permissions folder_permissions updateFolderPermissions
//
// Updates permissions for a folder. This operation will remove existing permissions if theyre not included in the request.
//
// Responses:
// 200: okResponse
// 401: unauthorisedError
// 403: forbiddenError
// 404: notFoundError
// 500: internalServerError
func (hs *HTTPServer) UpdateFolderPermissions(c *contextmodel.ReqContext) response.Response {
apiCmd := dtos.UpdateDashboardACLCommand{}
if err := web.Bind(c.Req, &apiCmd); err != nil {
return response.Error(http.StatusBadRequest, "bad request data", err)
}
if err := validatePermissionsUpdate(apiCmd); err != nil {
return response.Error(400, err.Error(), err)
}
uid := web.Params(c.Req)[":uid"]
folder, err := hs.folderService.Get(c.Req.Context(), &folder.GetFolderQuery{OrgID: c.OrgID, UID: &uid, SignedInUser: c.SignedInUser})
2018-02-20 08:25:16 -06:00
if err != nil {
return apierrors.ToFolderErrorResponse(err)
2018-02-20 08:25:16 -06:00
}
items := make([]*dashboards.DashboardACL, 0, len(apiCmd.Items))
2018-02-20 08:25:16 -06:00
for _, item := range apiCmd.Items {
items = append(items, &dashboards.DashboardACL{
OrgID: c.OrgID,
DashboardID: folder.ID,
UserID: item.UserID,
TeamID: item.TeamID,
2018-02-20 08:25:16 -06:00
Role: item.Role,
Permission: item.Permission,
Created: time.Now(),
Updated: time.Now(),
})
}
acl, err := hs.getFolderACL(c.Req.Context(), c.SignedInUser, folder)
if err != nil {
return response.Error(http.StatusInternalServerError, "Error while checking folder permissions", err)
}
items = append(items, hs.filterHiddenACL(c.SignedInUser, acl)...)
2018-02-20 08:25:16 -06:00
if err := hs.updateDashboardAccessControl(c.Req.Context(), c.OrgID, folder.UID, true, items, acl); err != nil {
return response.Error(http.StatusInternalServerError, "Failed to create permission", err)
2018-02-20 08:25:16 -06:00
}
return response.Success("Folder permissions updated")
}
var folderPermissionMap = map[string]dashboards.PermissionType{
"View": dashboards.PERMISSION_VIEW,
"Edit": dashboards.PERMISSION_EDIT,
"Admin": dashboards.PERMISSION_ADMIN,
}
func (hs *HTTPServer) getFolderACL(ctx context.Context, user identity.Requester, folder *folder.Folder) ([]*dashboards.DashboardACLInfoDTO, error) {
permissions, err := hs.folderPermissionsService.GetPermissions(ctx, user, folder.UID)
if err != nil {
return nil, err
Access control: Use access control for dashboard and folder (#44702) * Add actions and scopes * add resource service for dashboard and folder * Add dashboard guardian with fgac permission evaluation * Add CanDelete function to guardian interface * Add CanDelete property to folder and dashboard dto and set values * change to correct function name * Add accesscontrol to folder endpoints * add access control to dashboard endpoints * check access for nav links * Add fixed roles for dashboard and folders * use correct package * add hack to override guardian Constructor if accesscontrol is enabled * Add services * Add function to handle api backward compatability * Add permissionServices to HttpServer * Set permission when new dashboard is created * Add default permission when creating new dashboard * Set default permission when creating folder and dashboard * Add access control filter for dashboard search * Add to accept list * Add accesscontrol to dashboardimport * Disable access control in tests * Add check to see if user is allow to create a dashboard * Use SetPermissions * Use function to set several permissions at once * remove permissions for folder and dashboard on delete * update required permission * set permission for provisioning * Add CanCreate to dashboard guardian and set correct permisisons for provisioning * Dont set admin on folder / dashboard creation * Add dashboard and folder permission migrations * Add tests for CanCreate * Add roles and update descriptions * Solve uid to id for dashboard and folder permissions * Add folder and dashboard actions to permission filter * Handle viewer_can_edit flag * set folder and dashboard permissions services * Add dashboard permissions when importing a new dashboard * Set access control permissions on provisioning * Pass feature flags and only set permissions if access control is enabled * only add default permissions for folders and dashboards without folders * Batch create permissions in migrations * Remove `dashboards:edit` action * Remove unused function from interface * Update pkg/services/guardian/accesscontrol_guardian_test.go Co-authored-by: Gabriel MABILLE <gamab@users.noreply.github.com> Co-authored-by: Ieva <ieva.vasiljeva@grafana.com>
2022-03-03 08:05:47 -06:00
}
acl := make([]*dashboards.DashboardACLInfoDTO, 0, len(permissions))
for _, p := range permissions {
if !p.IsManaged {
continue
}
var role *org.RoleType
if p.BuiltInRole != "" {
tmp := org.RoleType(p.BuiltInRole)
role = &tmp
}
permission := folderPermissionMap[hs.folderPermissionsService.MapActions(p)]
acl = append(acl, &dashboards.DashboardACLInfoDTO{
OrgID: folder.OrgID,
DashboardID: folder.ID,
FolderUID: folder.ParentUID,
Created: p.Created,
Updated: p.Updated,
UserID: p.UserId,
UserLogin: p.UserLogin,
UserEmail: p.UserEmail,
TeamID: p.TeamId,
TeamEmail: p.TeamEmail,
Team: p.Team,
Role: role,
Permission: permission,
PermissionName: permission.String(),
UID: folder.UID,
Title: folder.Title,
URL: folder.WithURL().URL,
IsFolder: true,
Inherited: false,
})
2018-02-20 08:25:16 -06:00
}
return acl, nil
2018-02-20 08:25:16 -06:00
}
// swagger:parameters getFolderPermissionList
type GetFolderPermissionListParams struct {
// in:path
// required:true
FolderUID string `json:"folder_uid"`
}
// swagger:parameters updateFolderPermissions
type UpdateFolderPermissionsParams struct {
// in:path
// required:true
FolderUID string `json:"folder_uid"`
// in:body
// required:true
Body dtos.UpdateDashboardACLCommand
}
// swagger:response getFolderPermissionListResponse
type GetFolderPermissionsResponse struct {
// in: body
Body []*dashboards.DashboardACLInfoDTO `json:"body"`
}