From b84fd3a7aea83f894bcc2dc9246507fc84aa49fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Wed, 7 Feb 2018 17:54:21 +0100 Subject: [PATCH] fix: initial fix for #10822 --- pkg/services/sqlstore/dashboard.go | 1 + pkg/services/sqlstore/search_builder.go | 22 ++---------- pkg/services/sqlstore/sqlbuilder.go | 45 +++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 20 deletions(-) create mode 100644 pkg/services/sqlstore/sqlbuilder.go diff --git a/pkg/services/sqlstore/dashboard.go b/pkg/services/sqlstore/dashboard.go index be8b11b1f5b..c187360dc33 100644 --- a/pkg/services/sqlstore/dashboard.go +++ b/pkg/services/sqlstore/dashboard.go @@ -279,6 +279,7 @@ func findDashboards(query *search.FindPersistedDashboardsQuery) ([]DashboardSear var res []DashboardSearchProjection sql, params := sb.ToSql() + sqlog.Info("sql", "sql", sql, "params", params) err := x.Sql(sql, params...).Find(&res) if err != nil { return nil, err diff --git a/pkg/services/sqlstore/search_builder.go b/pkg/services/sqlstore/search_builder.go index 627074d5453..91e2742e165 100644 --- a/pkg/services/sqlstore/search_builder.go +++ b/pkg/services/sqlstore/search_builder.go @@ -1,7 +1,6 @@ package sqlstore import ( - "bytes" "strings" m "github.com/grafana/grafana/pkg/models" @@ -9,6 +8,7 @@ import ( // SearchBuilder is a builder/object mother that builds a dashboard search query type SearchBuilder struct { + SqlBuilder tags []string isStarred bool limit int @@ -18,8 +18,6 @@ type SearchBuilder struct { whereTypeFolder bool whereTypeDash bool whereFolderIds []int64 - sql bytes.Buffer - params []interface{} } func NewSearchBuilder(signedInUser *m.SignedInUser, limit int) *SearchBuilder { @@ -176,23 +174,7 @@ func (sb *SearchBuilder) buildSearchWhereClause() { } } - if sb.signedInUser.OrgRole != m.ROLE_ADMIN { - allowedDashboardsSubQuery := ` AND (dashboard.has_acl = ` + dialect.BooleanStr(false) + ` OR dashboard.id in ( - SELECT distinct d.id AS DashboardId - FROM dashboard AS d - LEFT JOIN dashboard_acl as da on d.folder_id = da.dashboard_id or d.id = da.dashboard_id - LEFT JOIN team_member as ugm on ugm.team_id = da.team_id - LEFT JOIN org_user ou on ou.role = da.role - WHERE - d.has_acl = ` + dialect.BooleanStr(true) + ` and - (da.user_id = ? or ugm.user_id = ? or ou.id is not null) - and d.org_id = ? - ) - )` - - sb.sql.WriteString(allowedDashboardsSubQuery) - sb.params = append(sb.params, sb.signedInUser.UserId, sb.signedInUser.UserId, sb.signedInUser.OrgId) - } + sb.writeDashboardPermissionFilter(sb.signedInUser, m.PERMISSION_VIEW) if len(sb.whereTitle) > 0 { sb.sql.WriteString(" AND dashboard.title " + dialect.LikeStr() + " ?") diff --git a/pkg/services/sqlstore/sqlbuilder.go b/pkg/services/sqlstore/sqlbuilder.go new file mode 100644 index 00000000000..9a0dd0d3989 --- /dev/null +++ b/pkg/services/sqlstore/sqlbuilder.go @@ -0,0 +1,45 @@ +package sqlstore + +import ( + "bytes" + "strings" + + m "github.com/grafana/grafana/pkg/models" +) + +type SqlBuilder struct { + sql bytes.Buffer + params []interface{} +} + +func (sb *SqlBuilder) writeDashboardPermissionFilter(user *m.SignedInUser, minPermission m.PermissionType) { + + if user.OrgRole == m.ROLE_ADMIN { + return + } + + okRoles := []interface{}{user.OrgRole} + + if user.OrgRole == m.ROLE_EDITOR { + okRoles = append(okRoles, m.ROLE_VIEWER) + } + + sb.sql.WriteString(` AND + ( + dashboard.has_acl = ` + dialect.BooleanStr(false) + ` OR + dashboard.id in ( + SELECT distinct d.id AS DashboardId + FROM dashboard AS d + LEFT JOIN dashboard_acl as da on d.folder_id = da.dashboard_id or d.id = da.dashboard_id + LEFT JOIN team_member as ugm on ugm.team_id = da.team_id + WHERE + d.has_acl = ` + dialect.BooleanStr(true) + ` AND + d.org_id = ? AND + da.permission >= ? AND + (da.user_id = ? or ugm.user_id = ? or da.role IN (?` + strings.Repeat(",?", len(okRoles)-1) + `)) + ) + )`) + + sb.params = append(sb.params, user.OrgId, minPermission, user.UserId, user.UserId) + sb.params = append(sb.params, okRoles...) +}