Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
N
nexpie-grafana-theme
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Registry
Registry
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Kornkitt Poolsup
nexpie-grafana-theme
Commits
8dd4d505
Commit
8dd4d505
authored
Feb 14, 2018
by
Torkel Ödegaard
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'dashboard-search-permissions-filter'
parents
b60b6690
162439a8
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
132 additions
and
136 deletions
+132
-136
pkg/api/api.go
+0
-2
pkg/api/dashboard.go
+0
-16
pkg/api/search.go
+7
-0
pkg/models/dashboards.go
+0
-12
pkg/services/search/handlers.go
+1
-0
pkg/services/search/models.go
+2
-1
pkg/services/sqlstore/dashboard.go
+1
-50
pkg/services/sqlstore/dashboard_folder_test.go
+40
-24
pkg/services/sqlstore/dashboard_test.go
+7
-4
pkg/services/sqlstore/search_builder.go
+6
-25
pkg/services/sqlstore/search_builder_test.go
+2
-1
pkg/services/sqlstore/sqlbuilder.go
+59
-0
public/app/features/dashboard/folder_picker/folder_picker.ts
+7
-1
No files found.
pkg/api/api.go
View file @
8dd4d505
...
@@ -261,8 +261,6 @@ func (hs *HttpServer) registerRoutes() {
...
@@ -261,8 +261,6 @@ func (hs *HttpServer) registerRoutes() {
dashboardRoute
.
Get
(
"/tags"
,
GetDashboardTags
)
dashboardRoute
.
Get
(
"/tags"
,
GetDashboardTags
)
dashboardRoute
.
Post
(
"/import"
,
bind
(
dtos
.
ImportDashboardCommand
{}),
wrap
(
ImportDashboard
))
dashboardRoute
.
Post
(
"/import"
,
bind
(
dtos
.
ImportDashboardCommand
{}),
wrap
(
ImportDashboard
))
dashboardRoute
.
Get
(
"/folders"
,
wrap
(
GetFoldersForSignedInUser
))
dashboardRoute
.
Group
(
"/id/:dashboardId"
,
func
(
dashIdRoute
RouteRegister
)
{
dashboardRoute
.
Group
(
"/id/:dashboardId"
,
func
(
dashIdRoute
RouteRegister
)
{
dashIdRoute
.
Get
(
"/versions"
,
wrap
(
GetDashboardVersions
))
dashIdRoute
.
Get
(
"/versions"
,
wrap
(
GetDashboardVersions
))
dashIdRoute
.
Get
(
"/versions/:id"
,
wrap
(
GetDashboardVersion
))
dashIdRoute
.
Get
(
"/versions/:id"
,
wrap
(
GetDashboardVersion
))
...
...
pkg/api/dashboard.go
View file @
8dd4d505
...
@@ -498,19 +498,3 @@ func GetDashboardTags(c *middleware.Context) {
...
@@ -498,19 +498,3 @@ func GetDashboardTags(c *middleware.Context) {
c
.
JSON
(
200
,
query
.
Result
)
c
.
JSON
(
200
,
query
.
Result
)
}
}
func
GetFoldersForSignedInUser
(
c
*
middleware
.
Context
)
Response
{
title
:=
c
.
Query
(
"query"
)
query
:=
m
.
GetFoldersForSignedInUserQuery
{
OrgId
:
c
.
OrgId
,
SignedInUser
:
c
.
SignedInUser
,
Title
:
title
,
}
err
:=
bus
.
Dispatch
(
&
query
)
if
err
!=
nil
{
return
ApiError
(
500
,
"Failed to get folders from database"
,
err
)
}
return
Json
(
200
,
query
.
Result
)
}
pkg/api/search.go
View file @
8dd4d505
...
@@ -6,6 +6,7 @@ import (
...
@@ -6,6 +6,7 @@ import (
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/metrics"
"github.com/grafana/grafana/pkg/metrics"
"github.com/grafana/grafana/pkg/middleware"
"github.com/grafana/grafana/pkg/middleware"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/search"
"github.com/grafana/grafana/pkg/services/search"
)
)
...
@@ -15,11 +16,16 @@ func Search(c *middleware.Context) {
...
@@ -15,11 +16,16 @@ func Search(c *middleware.Context) {
starred
:=
c
.
Query
(
"starred"
)
starred
:=
c
.
Query
(
"starred"
)
limit
:=
c
.
QueryInt
(
"limit"
)
limit
:=
c
.
QueryInt
(
"limit"
)
dashboardType
:=
c
.
Query
(
"type"
)
dashboardType
:=
c
.
Query
(
"type"
)
permission
:=
models
.
PERMISSION_VIEW
if
limit
==
0
{
if
limit
==
0
{
limit
=
1000
limit
=
1000
}
}
if
c
.
Query
(
"permission"
)
==
"Edit"
{
permission
=
models
.
PERMISSION_EDIT
}
dbids
:=
make
([]
int64
,
0
)
dbids
:=
make
([]
int64
,
0
)
for
_
,
id
:=
range
c
.
QueryStrings
(
"dashboardIds"
)
{
for
_
,
id
:=
range
c
.
QueryStrings
(
"dashboardIds"
)
{
dashboardId
,
err
:=
strconv
.
ParseInt
(
id
,
10
,
64
)
dashboardId
,
err
:=
strconv
.
ParseInt
(
id
,
10
,
64
)
...
@@ -46,6 +52,7 @@ func Search(c *middleware.Context) {
...
@@ -46,6 +52,7 @@ func Search(c *middleware.Context) {
DashboardIds
:
dbids
,
DashboardIds
:
dbids
,
Type
:
dashboardType
,
Type
:
dashboardType
,
FolderIds
:
folderIds
,
FolderIds
:
folderIds
,
Permission
:
permission
,
}
}
err
:=
bus
.
Dispatch
(
&
searchQuery
)
err
:=
bus
.
Dispatch
(
&
searchQuery
)
...
...
pkg/models/dashboards.go
View file @
8dd4d505
...
@@ -304,18 +304,6 @@ type GetDashboardsBySlugQuery struct {
...
@@ -304,18 +304,6 @@ type GetDashboardsBySlugQuery struct {
Result
[]
*
Dashboard
Result
[]
*
Dashboard
}
}
type
GetFoldersForSignedInUserQuery
struct
{
OrgId
int64
SignedInUser
*
SignedInUser
Title
string
Result
[]
*
DashboardFolder
}
type
DashboardFolder
struct
{
Id
int64
`json:"id"`
Title
string
`json:"title"`
}
type
DashboardPermissionForUser
struct
{
type
DashboardPermissionForUser
struct
{
DashboardId
int64
`json:"dashboardId"`
DashboardId
int64
`json:"dashboardId"`
Permission
PermissionType
`json:"permission"`
Permission
PermissionType
`json:"permission"`
...
...
pkg/services/search/handlers.go
View file @
8dd4d505
...
@@ -21,6 +21,7 @@ func searchHandler(query *Query) error {
...
@@ -21,6 +21,7 @@ func searchHandler(query *Query) error {
FolderIds
:
query
.
FolderIds
,
FolderIds
:
query
.
FolderIds
,
Tags
:
query
.
Tags
,
Tags
:
query
.
Tags
,
Limit
:
query
.
Limit
,
Limit
:
query
.
Limit
,
Permission
:
query
.
Permission
,
}
}
if
err
:=
bus
.
Dispatch
(
&
dashQuery
);
err
!=
nil
{
if
err
:=
bus
.
Dispatch
(
&
dashQuery
);
err
!=
nil
{
...
...
pkg/services/search/models.go
View file @
8dd4d505
...
@@ -52,6 +52,7 @@ type Query struct {
...
@@ -52,6 +52,7 @@ type Query struct {
Type
string
Type
string
DashboardIds
[]
int64
DashboardIds
[]
int64
FolderIds
[]
int64
FolderIds
[]
int64
Permission
models
.
PermissionType
Result
HitList
Result
HitList
}
}
...
@@ -66,7 +67,7 @@ type FindPersistedDashboardsQuery struct {
...
@@ -66,7 +67,7 @@ type FindPersistedDashboardsQuery struct {
FolderIds
[]
int64
FolderIds
[]
int64
Tags
[]
string
Tags
[]
string
Limit
int
Limit
int
IsBrowse
bool
Permission
models
.
PermissionType
Result
HitList
Result
HitList
}
}
pkg/services/sqlstore/dashboard.go
View file @
8dd4d505
...
@@ -21,7 +21,6 @@ func init() {
...
@@ -21,7 +21,6 @@ func init() {
bus
.
AddHandler
(
"sql"
,
GetDashboardSlugById
)
bus
.
AddHandler
(
"sql"
,
GetDashboardSlugById
)
bus
.
AddHandler
(
"sql"
,
GetDashboardUIDById
)
bus
.
AddHandler
(
"sql"
,
GetDashboardUIDById
)
bus
.
AddHandler
(
"sql"
,
GetDashboardsByPluginId
)
bus
.
AddHandler
(
"sql"
,
GetDashboardsByPluginId
)
bus
.
AddHandler
(
"sql"
,
GetFoldersForSignedInUser
)
bus
.
AddHandler
(
"sql"
,
GetDashboardPermissionsForUser
)
bus
.
AddHandler
(
"sql"
,
GetDashboardPermissionsForUser
)
bus
.
AddHandler
(
"sql"
,
GetDashboardsBySlug
)
bus
.
AddHandler
(
"sql"
,
GetDashboardsBySlug
)
}
}
...
@@ -294,7 +293,7 @@ func findDashboards(query *search.FindPersistedDashboardsQuery) ([]DashboardSear
...
@@ -294,7 +293,7 @@ func findDashboards(query *search.FindPersistedDashboardsQuery) ([]DashboardSear
limit
=
1000
limit
=
1000
}
}
sb
:=
NewSearchBuilder
(
query
.
SignedInUser
,
limit
)
.
sb
:=
NewSearchBuilder
(
query
.
SignedInUser
,
limit
,
query
.
Permission
)
.
WithTags
(
query
.
Tags
)
.
WithTags
(
query
.
Tags
)
.
WithDashboardIdsIn
(
query
.
DashboardIds
)
WithDashboardIdsIn
(
query
.
DashboardIds
)
...
@@ -395,54 +394,6 @@ func GetDashboardTags(query *m.GetDashboardTagsQuery) error {
...
@@ -395,54 +394,6 @@ func GetDashboardTags(query *m.GetDashboardTagsQuery) error {
return
err
return
err
}
}
func
GetFoldersForSignedInUser
(
query
*
m
.
GetFoldersForSignedInUserQuery
)
error
{
query
.
Result
=
make
([]
*
m
.
DashboardFolder
,
0
)
var
err
error
if
query
.
SignedInUser
.
OrgRole
==
m
.
ROLE_ADMIN
{
sql
:=
`SELECT distinct d.id, d.title
FROM dashboard AS d WHERE d.is_folder = ? AND d.org_id = ?
ORDER BY d.title ASC`
err
=
x
.
Sql
(
sql
,
dialect
.
BooleanStr
(
true
),
query
.
OrgId
)
.
Find
(
&
query
.
Result
)
}
else
{
params
:=
make
([]
interface
{},
0
)
sql
:=
`SELECT distinct d.id, d.title
FROM dashboard AS d
LEFT JOIN dashboard_acl AS da ON 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 AND ou.user_id = ?
LEFT JOIN org_user ouRole ON ouRole.role = 'Editor' AND ouRole.user_id = ? AND ouRole.org_id = ?`
params
=
append
(
params
,
query
.
SignedInUser
.
UserId
)
params
=
append
(
params
,
query
.
SignedInUser
.
UserId
)
params
=
append
(
params
,
query
.
OrgId
)
sql
+=
` WHERE
d.org_id = ? AND
d.is_folder = ? AND
(
(d.has_acl = ? AND da.permission > 1 AND (da.user_id = ? OR ugm.user_id = ? OR ou.id IS NOT NULL))
OR (d.has_acl = ? AND ouRole.id IS NOT NULL)
)`
params
=
append
(
params
,
query
.
OrgId
)
params
=
append
(
params
,
dialect
.
BooleanStr
(
true
))
params
=
append
(
params
,
dialect
.
BooleanStr
(
true
))
params
=
append
(
params
,
query
.
SignedInUser
.
UserId
)
params
=
append
(
params
,
query
.
SignedInUser
.
UserId
)
params
=
append
(
params
,
dialect
.
BooleanStr
(
false
))
if
len
(
query
.
Title
)
>
0
{
sql
+=
" AND d.title "
+
dialect
.
LikeStr
()
+
" ?"
params
=
append
(
params
,
"%"
+
query
.
Title
+
"%"
)
}
sql
+=
` ORDER BY d.title ASC`
err
=
x
.
Sql
(
sql
,
params
...
)
.
Find
(
&
query
.
Result
)
}
return
err
}
func
DeleteDashboard
(
cmd
*
m
.
DeleteDashboardCommand
)
error
{
func
DeleteDashboard
(
cmd
*
m
.
DeleteDashboardCommand
)
error
{
return
inTransaction
(
func
(
sess
*
DBSession
)
error
{
return
inTransaction
(
func
(
sess
*
DBSession
)
error
{
dashboard
:=
m
.
Dashboard
{
Id
:
cmd
.
Id
,
OrgId
:
cmd
.
OrgId
}
dashboard
:=
m
.
Dashboard
{
Id
:
cmd
.
Id
,
OrgId
:
cmd
.
OrgId
}
...
...
pkg/services/sqlstore/dashboard_folder_test.go
View file @
8dd4d505
...
@@ -26,7 +26,11 @@ func TestDashboardFolderDataAccess(t *testing.T) {
...
@@ -26,7 +26,11 @@ func TestDashboardFolderDataAccess(t *testing.T) {
Convey
(
"and no acls are set"
,
func
()
{
Convey
(
"and no acls are set"
,
func
()
{
Convey
(
"should return all dashboards"
,
func
()
{
Convey
(
"should return all dashboards"
,
func
()
{
query
:=
&
search
.
FindPersistedDashboardsQuery
{
SignedInUser
:
&
m
.
SignedInUser
{
UserId
:
currentUser
.
Id
,
OrgId
:
1
},
OrgId
:
1
,
DashboardIds
:
[]
int64
{
folder
.
Id
,
dashInRoot
.
Id
}}
query
:=
&
search
.
FindPersistedDashboardsQuery
{
SignedInUser
:
&
m
.
SignedInUser
{
UserId
:
currentUser
.
Id
,
OrgId
:
1
,
OrgRole
:
m
.
ROLE_VIEWER
},
OrgId
:
1
,
DashboardIds
:
[]
int64
{
folder
.
Id
,
dashInRoot
.
Id
},
}
err
:=
SearchDashboards
(
query
)
err
:=
SearchDashboards
(
query
)
So
(
err
,
ShouldBeNil
)
So
(
err
,
ShouldBeNil
)
So
(
len
(
query
.
Result
),
ShouldEqual
,
2
)
So
(
len
(
query
.
Result
),
ShouldEqual
,
2
)
...
@@ -40,7 +44,10 @@ func TestDashboardFolderDataAccess(t *testing.T) {
...
@@ -40,7 +44,10 @@ func TestDashboardFolderDataAccess(t *testing.T) {
updateTestDashboardWithAcl
(
folder
.
Id
,
otherUser
,
m
.
PERMISSION_EDIT
)
updateTestDashboardWithAcl
(
folder
.
Id
,
otherUser
,
m
.
PERMISSION_EDIT
)
Convey
(
"should not return folder"
,
func
()
{
Convey
(
"should not return folder"
,
func
()
{
query
:=
&
search
.
FindPersistedDashboardsQuery
{
SignedInUser
:
&
m
.
SignedInUser
{
UserId
:
currentUser
.
Id
,
OrgId
:
1
},
OrgId
:
1
,
DashboardIds
:
[]
int64
{
folder
.
Id
,
dashInRoot
.
Id
}}
query
:=
&
search
.
FindPersistedDashboardsQuery
{
SignedInUser
:
&
m
.
SignedInUser
{
UserId
:
currentUser
.
Id
,
OrgId
:
1
,
OrgRole
:
m
.
ROLE_VIEWER
},
OrgId
:
1
,
DashboardIds
:
[]
int64
{
folder
.
Id
,
dashInRoot
.
Id
},
}
err
:=
SearchDashboards
(
query
)
err
:=
SearchDashboards
(
query
)
So
(
err
,
ShouldBeNil
)
So
(
err
,
ShouldBeNil
)
So
(
len
(
query
.
Result
),
ShouldEqual
,
1
)
So
(
len
(
query
.
Result
),
ShouldEqual
,
1
)
...
@@ -51,7 +58,11 @@ func TestDashboardFolderDataAccess(t *testing.T) {
...
@@ -51,7 +58,11 @@ func TestDashboardFolderDataAccess(t *testing.T) {
updateTestDashboardWithAcl
(
folder
.
Id
,
currentUser
.
Id
,
m
.
PERMISSION_EDIT
)
updateTestDashboardWithAcl
(
folder
.
Id
,
currentUser
.
Id
,
m
.
PERMISSION_EDIT
)
Convey
(
"should be able to access folder"
,
func
()
{
Convey
(
"should be able to access folder"
,
func
()
{
query
:=
&
search
.
FindPersistedDashboardsQuery
{
SignedInUser
:
&
m
.
SignedInUser
{
UserId
:
currentUser
.
Id
,
OrgId
:
1
},
OrgId
:
1
,
DashboardIds
:
[]
int64
{
folder
.
Id
,
dashInRoot
.
Id
}}
query
:=
&
search
.
FindPersistedDashboardsQuery
{
SignedInUser
:
&
m
.
SignedInUser
{
UserId
:
currentUser
.
Id
,
OrgId
:
1
,
OrgRole
:
m
.
ROLE_VIEWER
},
OrgId
:
1
,
DashboardIds
:
[]
int64
{
folder
.
Id
,
dashInRoot
.
Id
},
}
err
:=
SearchDashboards
(
query
)
err
:=
SearchDashboards
(
query
)
So
(
err
,
ShouldBeNil
)
So
(
err
,
ShouldBeNil
)
So
(
len
(
query
.
Result
),
ShouldEqual
,
2
)
So
(
len
(
query
.
Result
),
ShouldEqual
,
2
)
...
@@ -87,7 +98,7 @@ func TestDashboardFolderDataAccess(t *testing.T) {
...
@@ -87,7 +98,7 @@ func TestDashboardFolderDataAccess(t *testing.T) {
updateTestDashboardWithAcl
(
childDash
.
Id
,
otherUser
,
m
.
PERMISSION_EDIT
)
updateTestDashboardWithAcl
(
childDash
.
Id
,
otherUser
,
m
.
PERMISSION_EDIT
)
Convey
(
"should not return folder or child"
,
func
()
{
Convey
(
"should not return folder or child"
,
func
()
{
query
:=
&
search
.
FindPersistedDashboardsQuery
{
SignedInUser
:
&
m
.
SignedInUser
{
UserId
:
currentUser
.
Id
,
OrgId
:
1
},
OrgId
:
1
,
DashboardIds
:
[]
int64
{
folder
.
Id
,
childDash
.
Id
,
dashInRoot
.
Id
}}
query
:=
&
search
.
FindPersistedDashboardsQuery
{
SignedInUser
:
&
m
.
SignedInUser
{
UserId
:
currentUser
.
Id
,
OrgId
:
1
,
OrgRole
:
m
.
ROLE_VIEWER
},
OrgId
:
1
,
DashboardIds
:
[]
int64
{
folder
.
Id
,
childDash
.
Id
,
dashInRoot
.
Id
}}
err
:=
SearchDashboards
(
query
)
err
:=
SearchDashboards
(
query
)
So
(
err
,
ShouldBeNil
)
So
(
err
,
ShouldBeNil
)
So
(
len
(
query
.
Result
),
ShouldEqual
,
1
)
So
(
len
(
query
.
Result
),
ShouldEqual
,
1
)
...
@@ -98,7 +109,7 @@ func TestDashboardFolderDataAccess(t *testing.T) {
...
@@ -98,7 +109,7 @@ func TestDashboardFolderDataAccess(t *testing.T) {
updateTestDashboardWithAcl
(
childDash
.
Id
,
currentUser
.
Id
,
m
.
PERMISSION_EDIT
)
updateTestDashboardWithAcl
(
childDash
.
Id
,
currentUser
.
Id
,
m
.
PERMISSION_EDIT
)
Convey
(
"should be able to search for child dashboard but not folder"
,
func
()
{
Convey
(
"should be able to search for child dashboard but not folder"
,
func
()
{
query
:=
&
search
.
FindPersistedDashboardsQuery
{
SignedInUser
:
&
m
.
SignedInUser
{
UserId
:
currentUser
.
Id
,
OrgId
:
1
},
OrgId
:
1
,
DashboardIds
:
[]
int64
{
folder
.
Id
,
childDash
.
Id
,
dashInRoot
.
Id
}}
query
:=
&
search
.
FindPersistedDashboardsQuery
{
SignedInUser
:
&
m
.
SignedInUser
{
UserId
:
currentUser
.
Id
,
OrgId
:
1
,
OrgRole
:
m
.
ROLE_VIEWER
},
OrgId
:
1
,
DashboardIds
:
[]
int64
{
folder
.
Id
,
childDash
.
Id
,
dashInRoot
.
Id
}}
err
:=
SearchDashboards
(
query
)
err
:=
SearchDashboards
(
query
)
So
(
err
,
ShouldBeNil
)
So
(
err
,
ShouldBeNil
)
So
(
len
(
query
.
Result
),
ShouldEqual
,
2
)
So
(
len
(
query
.
Result
),
ShouldEqual
,
2
)
...
@@ -141,7 +152,7 @@ func TestDashboardFolderDataAccess(t *testing.T) {
...
@@ -141,7 +152,7 @@ func TestDashboardFolderDataAccess(t *testing.T) {
Convey
(
"and one folder is expanded, the other collapsed"
,
func
()
{
Convey
(
"and one folder is expanded, the other collapsed"
,
func
()
{
Convey
(
"should return dashboards in root and expanded folder"
,
func
()
{
Convey
(
"should return dashboards in root and expanded folder"
,
func
()
{
query
:=
&
search
.
FindPersistedDashboardsQuery
{
FolderIds
:
[]
int64
{
rootFolderId
,
folder1
.
Id
},
SignedInUser
:
&
m
.
SignedInUser
{
UserId
:
currentUser
.
Id
,
OrgId
:
1
},
OrgId
:
1
}
query
:=
&
search
.
FindPersistedDashboardsQuery
{
FolderIds
:
[]
int64
{
rootFolderId
,
folder1
.
Id
},
SignedInUser
:
&
m
.
SignedInUser
{
UserId
:
currentUser
.
Id
,
OrgId
:
1
,
OrgRole
:
m
.
ROLE_VIEWER
},
OrgId
:
1
}
err
:=
SearchDashboards
(
query
)
err
:=
SearchDashboards
(
query
)
So
(
err
,
ShouldBeNil
)
So
(
err
,
ShouldBeNil
)
So
(
len
(
query
.
Result
),
ShouldEqual
,
4
)
So
(
len
(
query
.
Result
),
ShouldEqual
,
4
)
...
@@ -162,7 +173,7 @@ func TestDashboardFolderDataAccess(t *testing.T) {
...
@@ -162,7 +173,7 @@ func TestDashboardFolderDataAccess(t *testing.T) {
Convey
(
"should not return folder with acl or its children"
,
func
()
{
Convey
(
"should not return folder with acl or its children"
,
func
()
{
query
:=
&
search
.
FindPersistedDashboardsQuery
{
query
:=
&
search
.
FindPersistedDashboardsQuery
{
SignedInUser
:
&
m
.
SignedInUser
{
UserId
:
currentUser
.
Id
,
OrgId
:
1
},
SignedInUser
:
&
m
.
SignedInUser
{
UserId
:
currentUser
.
Id
,
OrgId
:
1
,
OrgRole
:
m
.
ROLE_VIEWER
},
OrgId
:
1
,
OrgId
:
1
,
DashboardIds
:
[]
int64
{
folder1
.
Id
,
childDash1
.
Id
,
childDash2
.
Id
,
dashInRoot
.
Id
},
DashboardIds
:
[]
int64
{
folder1
.
Id
,
childDash1
.
Id
,
childDash2
.
Id
,
dashInRoot
.
Id
},
}
}
...
@@ -172,14 +183,14 @@ func TestDashboardFolderDataAccess(t *testing.T) {
...
@@ -172,14 +183,14 @@ func TestDashboardFolderDataAccess(t *testing.T) {
So
(
query
.
Result
[
0
]
.
Id
,
ShouldEqual
,
dashInRoot
.
Id
)
So
(
query
.
Result
[
0
]
.
Id
,
ShouldEqual
,
dashInRoot
.
Id
)
})
})
})
})
Convey
(
"and a dashboard is moved from folder with acl to the folder without an acl"
,
func
()
{
Convey
(
"and a dashboard is moved from folder with acl to the folder without an acl"
,
func
()
{
movedDash
:=
moveDashboard
(
1
,
childDash1
.
Data
,
folder2
.
Id
)
movedDash
:=
moveDashboard
(
1
,
childDash1
.
Data
,
folder2
.
Id
)
So
(
movedDash
.
HasAcl
,
ShouldBeFalse
)
So
(
movedDash
.
HasAcl
,
ShouldBeFalse
)
Convey
(
"should return folder without acl and its children"
,
func
()
{
Convey
(
"should return folder without acl and its children"
,
func
()
{
query
:=
&
search
.
FindPersistedDashboardsQuery
{
query
:=
&
search
.
FindPersistedDashboardsQuery
{
SignedInUser
:
&
m
.
SignedInUser
{
UserId
:
currentUser
.
Id
,
OrgId
:
1
},
SignedInUser
:
&
m
.
SignedInUser
{
UserId
:
currentUser
.
Id
,
OrgId
:
1
,
OrgRole
:
m
.
ROLE_VIEWER
},
OrgId
:
1
,
OrgId
:
1
,
DashboardIds
:
[]
int64
{
folder2
.
Id
,
childDash1
.
Id
,
childDash2
.
Id
,
dashInRoot
.
Id
},
DashboardIds
:
[]
int64
{
folder2
.
Id
,
childDash1
.
Id
,
childDash2
.
Id
,
dashInRoot
.
Id
},
}
}
...
@@ -200,16 +211,17 @@ func TestDashboardFolderDataAccess(t *testing.T) {
...
@@ -200,16 +211,17 @@ func TestDashboardFolderDataAccess(t *testing.T) {
Convey
(
"should return folder without acl but not the dashboard with acl"
,
func
()
{
Convey
(
"should return folder without acl but not the dashboard with acl"
,
func
()
{
query
:=
&
search
.
FindPersistedDashboardsQuery
{
query
:=
&
search
.
FindPersistedDashboardsQuery
{
SignedInUser
:
&
m
.
SignedInUser
{
UserId
:
currentUser
.
Id
,
OrgId
:
1
},
SignedInUser
:
&
m
.
SignedInUser
{
UserId
:
currentUser
.
Id
,
OrgId
:
1
,
OrgRole
:
m
.
ROLE_VIEWER
},
OrgId
:
1
,
OrgId
:
1
,
DashboardIds
:
[]
int64
{
folder2
.
Id
,
childDash1
.
Id
,
childDash2
.
Id
,
dashInRoot
.
Id
},
DashboardIds
:
[]
int64
{
folder2
.
Id
,
childDash1
.
Id
,
childDash2
.
Id
,
dashInRoot
.
Id
},
}
}
err
:=
SearchDashboards
(
query
)
err
:=
SearchDashboards
(
query
)
So
(
err
,
ShouldBeNil
)
So
(
err
,
ShouldBeNil
)
So
(
len
(
query
.
Result
),
ShouldEqual
,
3
)
So
(
len
(
query
.
Result
),
ShouldEqual
,
4
)
So
(
query
.
Result
[
0
]
.
Id
,
ShouldEqual
,
folder2
.
Id
)
So
(
query
.
Result
[
0
]
.
Id
,
ShouldEqual
,
folder2
.
Id
)
So
(
query
.
Result
[
1
]
.
Id
,
ShouldEqual
,
childDash2
.
Id
)
So
(
query
.
Result
[
1
]
.
Id
,
ShouldEqual
,
childDash1
.
Id
)
So
(
query
.
Result
[
2
]
.
Id
,
ShouldEqual
,
dashInRoot
.
Id
)
So
(
query
.
Result
[
2
]
.
Id
,
ShouldEqual
,
childDash2
.
Id
)
So
(
query
.
Result
[
3
]
.
Id
,
ShouldEqual
,
dashInRoot
.
Id
)
})
})
})
})
})
})
...
@@ -227,12 +239,14 @@ func TestDashboardFolderDataAccess(t *testing.T) {
...
@@ -227,12 +239,14 @@ func TestDashboardFolderDataAccess(t *testing.T) {
Convey
(
"Admin users"
,
func
()
{
Convey
(
"Admin users"
,
func
()
{
Convey
(
"Should have write access to all dashboard folders in their org"
,
func
()
{
Convey
(
"Should have write access to all dashboard folders in their org"
,
func
()
{
query
:=
m
.
GetFoldersForSignedInUser
Query
{
query
:=
search
.
FindPersistedDashboards
Query
{
OrgId
:
1
,
OrgId
:
1
,
SignedInUser
:
&
m
.
SignedInUser
{
UserId
:
adminUser
.
Id
,
OrgRole
:
m
.
ROLE_ADMIN
},
SignedInUser
:
&
m
.
SignedInUser
{
UserId
:
adminUser
.
Id
,
OrgRole
:
m
.
ROLE_ADMIN
,
OrgId
:
1
},
Permission
:
m
.
PERMISSION_VIEW
,
Type
:
"dash-folder"
,
}
}
err
:=
GetFoldersForSignedInUser
(
&
query
)
err
:=
SearchDashboards
(
&
query
)
So
(
err
,
ShouldBeNil
)
So
(
err
,
ShouldBeNil
)
So
(
len
(
query
.
Result
),
ShouldEqual
,
2
)
So
(
len
(
query
.
Result
),
ShouldEqual
,
2
)
...
@@ -260,13 +274,14 @@ func TestDashboardFolderDataAccess(t *testing.T) {
...
@@ -260,13 +274,14 @@ func TestDashboardFolderDataAccess(t *testing.T) {
})
})
Convey
(
"Editor users"
,
func
()
{
Convey
(
"Editor users"
,
func
()
{
query
:=
m
.
GetFoldersForSignedInUser
Query
{
query
:=
search
.
FindPersistedDashboards
Query
{
OrgId
:
1
,
OrgId
:
1
,
SignedInUser
:
&
m
.
SignedInUser
{
UserId
:
editorUser
.
Id
,
OrgRole
:
m
.
ROLE_EDITOR
},
SignedInUser
:
&
m
.
SignedInUser
{
UserId
:
editorUser
.
Id
,
OrgRole
:
m
.
ROLE_EDITOR
,
OrgId
:
1
},
Permission
:
m
.
PERMISSION_EDIT
,
}
}
Convey
(
"Should have write access to all dashboard folders with default ACL"
,
func
()
{
Convey
(
"Should have write access to all dashboard folders with default ACL"
,
func
()
{
err
:=
GetFoldersForSignedInUser
(
&
query
)
err
:=
SearchDashboards
(
&
query
)
So
(
err
,
ShouldBeNil
)
So
(
err
,
ShouldBeNil
)
So
(
len
(
query
.
Result
),
ShouldEqual
,
2
)
So
(
len
(
query
.
Result
),
ShouldEqual
,
2
)
...
@@ -295,7 +310,7 @@ func TestDashboardFolderDataAccess(t *testing.T) {
...
@@ -295,7 +310,7 @@ func TestDashboardFolderDataAccess(t *testing.T) {
Convey
(
"Should have write access to one dashboard folder if default role changed to view for one folder"
,
func
()
{
Convey
(
"Should have write access to one dashboard folder if default role changed to view for one folder"
,
func
()
{
updateTestDashboardWithAcl
(
folder1
.
Id
,
editorUser
.
Id
,
m
.
PERMISSION_VIEW
)
updateTestDashboardWithAcl
(
folder1
.
Id
,
editorUser
.
Id
,
m
.
PERMISSION_VIEW
)
err
:=
GetFoldersForSignedInUser
(
&
query
)
err
:=
SearchDashboards
(
&
query
)
So
(
err
,
ShouldBeNil
)
So
(
err
,
ShouldBeNil
)
So
(
len
(
query
.
Result
),
ShouldEqual
,
1
)
So
(
len
(
query
.
Result
),
ShouldEqual
,
1
)
...
@@ -305,13 +320,14 @@ func TestDashboardFolderDataAccess(t *testing.T) {
...
@@ -305,13 +320,14 @@ func TestDashboardFolderDataAccess(t *testing.T) {
})
})
Convey
(
"Viewer users"
,
func
()
{
Convey
(
"Viewer users"
,
func
()
{
query
:=
m
.
GetFoldersForSignedInUser
Query
{
query
:=
search
.
FindPersistedDashboards
Query
{
OrgId
:
1
,
OrgId
:
1
,
SignedInUser
:
&
m
.
SignedInUser
{
UserId
:
viewerUser
.
Id
,
OrgRole
:
m
.
ROLE_VIEWER
},
SignedInUser
:
&
m
.
SignedInUser
{
UserId
:
viewerUser
.
Id
,
OrgRole
:
m
.
ROLE_VIEWER
,
OrgId
:
1
},
Permission
:
m
.
PERMISSION_EDIT
,
}
}
Convey
(
"Should have no write access to any dashboard folders with default ACL"
,
func
()
{
Convey
(
"Should have no write access to any dashboard folders with default ACL"
,
func
()
{
err
:=
GetFoldersForSignedInUser
(
&
query
)
err
:=
SearchDashboards
(
&
query
)
So
(
err
,
ShouldBeNil
)
So
(
err
,
ShouldBeNil
)
So
(
len
(
query
.
Result
),
ShouldEqual
,
0
)
So
(
len
(
query
.
Result
),
ShouldEqual
,
0
)
...
@@ -338,7 +354,7 @@ func TestDashboardFolderDataAccess(t *testing.T) {
...
@@ -338,7 +354,7 @@ func TestDashboardFolderDataAccess(t *testing.T) {
Convey
(
"Should be able to get one dashboard folder if default role changed to edit for one folder"
,
func
()
{
Convey
(
"Should be able to get one dashboard folder if default role changed to edit for one folder"
,
func
()
{
updateTestDashboardWithAcl
(
folder1
.
Id
,
viewerUser
.
Id
,
m
.
PERMISSION_EDIT
)
updateTestDashboardWithAcl
(
folder1
.
Id
,
viewerUser
.
Id
,
m
.
PERMISSION_EDIT
)
err
:=
GetFoldersForSignedInUser
(
&
query
)
err
:=
SearchDashboards
(
&
query
)
So
(
err
,
ShouldBeNil
)
So
(
err
,
ShouldBeNil
)
So
(
len
(
query
.
Result
),
ShouldEqual
,
1
)
So
(
len
(
query
.
Result
),
ShouldEqual
,
1
)
...
...
pkg/services/sqlstore/dashboard_test.go
View file @
8dd4d505
...
@@ -512,7 +512,7 @@ func TestDashboardDataAccess(t *testing.T) {
...
@@ -512,7 +512,7 @@ func TestDashboardDataAccess(t *testing.T) {
query
:=
search
.
FindPersistedDashboardsQuery
{
query
:=
search
.
FindPersistedDashboardsQuery
{
Title
:
"1 test dash folder"
,
Title
:
"1 test dash folder"
,
OrgId
:
1
,
OrgId
:
1
,
SignedInUser
:
&
m
.
SignedInUser
{
OrgId
:
1
},
SignedInUser
:
&
m
.
SignedInUser
{
OrgId
:
1
,
OrgRole
:
m
.
ROLE_EDITOR
},
}
}
err
:=
SearchDashboards
(
&
query
)
err
:=
SearchDashboards
(
&
query
)
...
@@ -529,7 +529,7 @@ func TestDashboardDataAccess(t *testing.T) {
...
@@ -529,7 +529,7 @@ func TestDashboardDataAccess(t *testing.T) {
query
:=
search
.
FindPersistedDashboardsQuery
{
query
:=
search
.
FindPersistedDashboardsQuery
{
OrgId
:
1
,
OrgId
:
1
,
FolderIds
:
[]
int64
{
savedFolder
.
Id
},
FolderIds
:
[]
int64
{
savedFolder
.
Id
},
SignedInUser
:
&
m
.
SignedInUser
{
OrgId
:
1
},
SignedInUser
:
&
m
.
SignedInUser
{
OrgId
:
1
,
OrgRole
:
m
.
ROLE_EDITOR
},
}
}
err
:=
SearchDashboards
(
&
query
)
err
:=
SearchDashboards
(
&
query
)
...
@@ -549,7 +549,7 @@ func TestDashboardDataAccess(t *testing.T) {
...
@@ -549,7 +549,7 @@ func TestDashboardDataAccess(t *testing.T) {
Convey
(
"should be able to find two dashboards by id"
,
func
()
{
Convey
(
"should be able to find two dashboards by id"
,
func
()
{
query
:=
search
.
FindPersistedDashboardsQuery
{
query
:=
search
.
FindPersistedDashboardsQuery
{
DashboardIds
:
[]
int64
{
2
,
3
},
DashboardIds
:
[]
int64
{
2
,
3
},
SignedInUser
:
&
m
.
SignedInUser
{
OrgId
:
1
},
SignedInUser
:
&
m
.
SignedInUser
{
OrgId
:
1
,
OrgRole
:
m
.
ROLE_EDITOR
},
}
}
err
:=
SearchDashboards
(
&
query
)
err
:=
SearchDashboards
(
&
query
)
...
@@ -578,7 +578,10 @@ func TestDashboardDataAccess(t *testing.T) {
...
@@ -578,7 +578,10 @@ func TestDashboardDataAccess(t *testing.T) {
})
})
Convey
(
"Should be able to search for starred dashboards"
,
func
()
{
Convey
(
"Should be able to search for starred dashboards"
,
func
()
{
query
:=
search
.
FindPersistedDashboardsQuery
{
SignedInUser
:
&
m
.
SignedInUser
{
UserId
:
10
,
OrgId
:
1
},
IsStarred
:
true
}
query
:=
search
.
FindPersistedDashboardsQuery
{
SignedInUser
:
&
m
.
SignedInUser
{
UserId
:
10
,
OrgId
:
1
,
OrgRole
:
m
.
ROLE_EDITOR
},
IsStarred
:
true
,
}
err
:=
SearchDashboards
(
&
query
)
err
:=
SearchDashboards
(
&
query
)
So
(
err
,
ShouldBeNil
)
So
(
err
,
ShouldBeNil
)
...
...
pkg/services/sqlstore/search_builder.go
View file @
8dd4d505
package
sqlstore
package
sqlstore
import
(
import
(
"bytes"
"strings"
"strings"
m
"github.com/grafana/grafana/pkg/models"
m
"github.com/grafana/grafana/pkg/models"
...
@@ -9,6 +8,7 @@ import (
...
@@ -9,6 +8,7 @@ import (
// SearchBuilder is a builder/object mother that builds a dashboard search query
// SearchBuilder is a builder/object mother that builds a dashboard search query
type
SearchBuilder
struct
{
type
SearchBuilder
struct
{
SqlBuilder
tags
[]
string
tags
[]
string
isStarred
bool
isStarred
bool
limit
int
limit
int
...
@@ -18,14 +18,14 @@ type SearchBuilder struct {
...
@@ -18,14 +18,14 @@ type SearchBuilder struct {
whereTypeFolder
bool
whereTypeFolder
bool
whereTypeDash
bool
whereTypeDash
bool
whereFolderIds
[]
int64
whereFolderIds
[]
int64
sql
bytes
.
Buffer
permission
m
.
PermissionType
params
[]
interface
{}
}
}
func
NewSearchBuilder
(
signedInUser
*
m
.
SignedInUser
,
limit
int
)
*
SearchBuilder
{
func
NewSearchBuilder
(
signedInUser
*
m
.
SignedInUser
,
limit
int
,
permission
m
.
PermissionType
)
*
SearchBuilder
{
searchBuilder
:=
&
SearchBuilder
{
searchBuilder
:=
&
SearchBuilder
{
signedInUser
:
signedInUser
,
signedInUser
:
signedInUser
,
limit
:
limit
,
limit
:
limit
,
permission
:
permission
,
}
}
return
searchBuilder
return
searchBuilder
...
@@ -153,10 +153,7 @@ func (sb *SearchBuilder) buildMainQuery() {
...
@@ -153,10 +153,7 @@ func (sb *SearchBuilder) buildMainQuery() {
sb
.
sql
.
WriteString
(
` WHERE `
)
sb
.
sql
.
WriteString
(
` WHERE `
)
sb
.
buildSearchWhereClause
()
sb
.
buildSearchWhereClause
()
sb
.
sql
.
WriteString
(
`
sb
.
sql
.
WriteString
(
` LIMIT ?) as ids INNER JOIN dashboard on ids.id = dashboard.id `
)
LIMIT ?) as ids
INNER JOIN dashboard on ids.id = dashboard.id
`
)
sb
.
params
=
append
(
sb
.
params
,
sb
.
limit
)
sb
.
params
=
append
(
sb
.
params
,
sb
.
limit
)
}
}
...
@@ -176,23 +173,7 @@ func (sb *SearchBuilder) buildSearchWhereClause() {
...
@@ -176,23 +173,7 @@ func (sb *SearchBuilder) buildSearchWhereClause() {
}
}
}
}
if
sb
.
signedInUser
.
OrgRole
!=
m
.
ROLE_ADMIN
{
sb
.
writeDashboardPermissionFilter
(
sb
.
signedInUser
,
sb
.
permission
)
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
)
}
if
len
(
sb
.
whereTitle
)
>
0
{
if
len
(
sb
.
whereTitle
)
>
0
{
sb
.
sql
.
WriteString
(
" AND dashboard.title "
+
dialect
.
LikeStr
()
+
" ?"
)
sb
.
sql
.
WriteString
(
" AND dashboard.title "
+
dialect
.
LikeStr
()
+
" ?"
)
...
...
pkg/services/sqlstore/search_builder_test.go
View file @
8dd4d505
...
@@ -16,7 +16,8 @@ func TestSearchBuilder(t *testing.T) {
...
@@ -16,7 +16,8 @@ func TestSearchBuilder(t *testing.T) {
OrgId
:
1
,
OrgId
:
1
,
UserId
:
1
,
UserId
:
1
,
}
}
sb
:=
NewSearchBuilder
(
signedInUser
,
1000
)
sb
:=
NewSearchBuilder
(
signedInUser
,
1000
,
m
.
PERMISSION_VIEW
)
Convey
(
"When building a normal search"
,
func
()
{
Convey
(
"When building a normal search"
,
func
()
{
sql
,
params
:=
sb
.
IsStarred
()
.
WithTitle
(
"test"
)
.
ToSql
()
sql
,
params
:=
sb
.
IsStarred
()
.
WithTitle
(
"test"
)
.
ToSql
()
...
...
pkg/services/sqlstore/sqlbuilder.go
0 → 100644
View file @
8dd4d505
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
,
permission
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
)
}
falseStr
:=
dialect
.
BooleanStr
(
false
)
sb
.
sql
.
WriteString
(
` AND
(
dashboard.id IN (
SELECT distinct d.id AS DashboardId
FROM dashboard AS d
LEFT JOIN dashboard folder on folder.id = d.folder_id
LEFT JOIN dashboard_acl AS da ON
da.dashboard_id = d.id OR
da.dashboard_id = d.folder_id OR
(
-- include default permissions -->
da.org_id = -1 AND (
(folder.id IS NOT NULL AND folder.has_acl = `
+
falseStr
+
`) OR
(folder.id IS NULL AND d.has_acl = `
+
falseStr
+
`)
)
)
LEFT JOIN team_member as ugm on ugm.team_id = da.team_id
WHERE
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
,
permission
,
user
.
UserId
,
user
.
UserId
)
sb
.
params
=
append
(
sb
.
params
,
okRoles
...
)
}
public/app/features/dashboard/folder_picker/folder_picker.ts
View file @
8dd4d505
...
@@ -30,7 +30,13 @@ export class FolderPickerCtrl {
...
@@ -30,7 +30,13 @@ export class FolderPickerCtrl {
}
}
getOptions
(
query
)
{
getOptions
(
query
)
{
return
this
.
backendSrv
.
get
(
'api/dashboards/folders'
,
{
query
:
query
}).
then
(
result
=>
{
const
params
=
{
query
:
query
,
type
:
'dash-folder'
,
permission
:
'Edit'
,
};
return
this
.
backendSrv
.
get
(
'api/search'
,
params
).
then
(
result
=>
{
if
(
if
(
query
===
''
||
query
===
''
||
query
.
toLowerCase
()
===
'g'
||
query
.
toLowerCase
()
===
'g'
||
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment