2020-04-20 22:20:45 +08:00
|
|
|
package permissions
|
|
|
|
|
|
|
|
|
|
import (
|
2022-03-03 22:05:47 +08:00
|
|
|
"context"
|
2020-06-29 20:08:32 +08:00
|
|
|
"strings"
|
|
|
|
|
|
2020-04-20 22:20:45 +08:00
|
|
|
"github.com/grafana/grafana/pkg/models"
|
2022-03-03 22:05:47 +08:00
|
|
|
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
2020-04-20 22:20:45 +08:00
|
|
|
"github.com/grafana/grafana/pkg/services/sqlstore/migrator"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type DashboardPermissionFilter struct {
|
|
|
|
|
OrgRole models.RoleType
|
|
|
|
|
Dialect migrator.Dialect
|
|
|
|
|
UserId int64
|
|
|
|
|
OrgId int64
|
|
|
|
|
PermissionLevel models.PermissionType
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (d DashboardPermissionFilter) Where() (string, []interface{}) {
|
|
|
|
|
if d.OrgRole == models.ROLE_ADMIN {
|
|
|
|
|
return "", nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
okRoles := []interface{}{d.OrgRole}
|
|
|
|
|
if d.OrgRole == models.ROLE_EDITOR {
|
|
|
|
|
okRoles = append(okRoles, models.ROLE_VIEWER)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
falseStr := d.Dialect.BooleanStr(false)
|
|
|
|
|
|
|
|
|
|
sql := `(
|
|
|
|
|
dashboard.id IN (
|
|
|
|
|
SELECT distinct DashboardId from (
|
|
|
|
|
SELECT d.id AS DashboardId
|
|
|
|
|
FROM dashboard AS d
|
|
|
|
|
LEFT JOIN dashboard_acl AS da ON
|
|
|
|
|
da.dashboard_id = d.id OR
|
|
|
|
|
da.dashboard_id = d.folder_id
|
|
|
|
|
WHERE
|
|
|
|
|
d.org_id = ? AND
|
|
|
|
|
da.permission >= ? AND
|
|
|
|
|
(
|
|
|
|
|
da.user_id = ? OR
|
2022-01-04 20:04:02 +08:00
|
|
|
da.team_id IN (SELECT team_id from team_member AS tm WHERE tm.user_id = ?) OR
|
2020-04-20 22:20:45 +08:00
|
|
|
da.role IN (?` + strings.Repeat(",?", len(okRoles)-1) + `)
|
|
|
|
|
)
|
|
|
|
|
UNION
|
|
|
|
|
SELECT d.id AS DashboardId
|
|
|
|
|
FROM dashboard AS d
|
|
|
|
|
LEFT JOIN dashboard AS folder on folder.id = d.folder_id
|
|
|
|
|
LEFT JOIN dashboard_acl AS da ON
|
|
|
|
|
(
|
|
|
|
|
-- include default permissions -->
|
|
|
|
|
da.org_id = -1 AND (
|
|
|
|
|
(folder.id IS NOT NULL AND folder.has_acl = ` + falseStr + `) OR
|
2022-03-03 22:05:47 +08:00
|
|
|
(folder.id IS NULL AND d.has_acl = ` + falseStr + `)
|
2020-04-20 22:20:45 +08:00
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
WHERE
|
|
|
|
|
d.org_id = ? AND
|
|
|
|
|
da.permission >= ? AND
|
|
|
|
|
(
|
|
|
|
|
da.user_id = ? OR
|
|
|
|
|
da.role IN (?` + strings.Repeat(",?", len(okRoles)-1) + `)
|
|
|
|
|
)
|
|
|
|
|
) AS a
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
`
|
|
|
|
|
|
|
|
|
|
params := []interface{}{d.OrgId, d.PermissionLevel, d.UserId, d.UserId}
|
|
|
|
|
params = append(params, okRoles...)
|
|
|
|
|
params = append(params, d.OrgId, d.PermissionLevel, d.UserId)
|
|
|
|
|
params = append(params, okRoles...)
|
|
|
|
|
return sql, params
|
|
|
|
|
}
|
2022-03-03 22:05:47 +08:00
|
|
|
|
|
|
|
|
type AccessControlDashboardPermissionFilter struct {
|
2022-03-08 19:46:49 +08:00
|
|
|
User *models.SignedInUser
|
|
|
|
|
PermissionLevel models.PermissionType
|
2022-03-03 22:05:47 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (f AccessControlDashboardPermissionFilter) Where() (string, []interface{}) {
|
2022-03-08 19:46:49 +08:00
|
|
|
folderAction := accesscontrol.ActionFoldersRead
|
|
|
|
|
dashboardAction := accesscontrol.ActionDashboardsRead
|
|
|
|
|
if f.PermissionLevel == models.PERMISSION_EDIT {
|
|
|
|
|
folderAction = accesscontrol.ActionDashboardsCreate
|
|
|
|
|
dashboardAction = accesscontrol.ActionDashboardsWrite
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-03 22:05:47 +08:00
|
|
|
builder := strings.Builder{}
|
|
|
|
|
|
|
|
|
|
builder.WriteString("(((")
|
|
|
|
|
|
2022-03-08 19:46:49 +08:00
|
|
|
dashFilter, _ := accesscontrol.Filter(context.Background(), "dashboard.id", "dashboards", dashboardAction, f.User)
|
2022-03-03 22:05:47 +08:00
|
|
|
builder.WriteString(dashFilter.Where)
|
|
|
|
|
|
|
|
|
|
builder.WriteString(" OR ")
|
|
|
|
|
|
2022-03-08 19:46:49 +08:00
|
|
|
dashFolderFilter, _ := accesscontrol.Filter(context.Background(), "dashboard.folder_id", "folders", dashboardAction, f.User)
|
2022-03-03 22:05:47 +08:00
|
|
|
builder.WriteString(dashFolderFilter.Where)
|
|
|
|
|
|
|
|
|
|
builder.WriteString(") AND NOT dashboard.is_folder) OR (")
|
|
|
|
|
|
2022-03-08 19:46:49 +08:00
|
|
|
folderFilter, _ := accesscontrol.Filter(context.Background(), "dashboard.id", "folders", folderAction, f.User)
|
2022-03-03 22:05:47 +08:00
|
|
|
builder.WriteString(folderFilter.Where)
|
|
|
|
|
builder.WriteString(" AND dashboard.is_folder))")
|
|
|
|
|
|
|
|
|
|
return builder.String(), append(dashFilter.Args, append(dashFolderFilter.Args, folderFilter.Args...)...)
|
|
|
|
|
}
|