2021-05-11 00:10:19 -05:00
package libraryelements
2021-03-01 08:33:17 -06:00
import (
"encoding/json"
"fmt"
"testing"
"github.com/google/go-cmp/cmp"
"github.com/grafana/grafana/pkg/models"
2021-10-11 07:30:59 -05:00
"github.com/grafana/grafana/pkg/web"
"github.com/stretchr/testify/require"
2021-03-01 08:33:17 -06:00
)
2021-05-11 00:10:19 -05:00
func TestLibraryElementPermissions ( t * testing . T ) {
2021-03-01 08:33:17 -06:00
var defaultPermissions = [ ] folderACLItem { }
var adminOnlyPermissions = [ ] folderACLItem { { models . ROLE_ADMIN , models . PERMISSION_EDIT } }
var editorOnlyPermissions = [ ] folderACLItem { { models . ROLE_EDITOR , models . PERMISSION_EDIT } }
var editorAndViewerPermissions = [ ] folderACLItem { { models . ROLE_EDITOR , models . PERMISSION_EDIT } , { models . ROLE_VIEWER , models . PERMISSION_EDIT } }
var viewerOnlyPermissions = [ ] folderACLItem { { models . ROLE_VIEWER , models . PERMISSION_EDIT } }
var everyonePermissions = [ ] folderACLItem { { models . ROLE_ADMIN , models . PERMISSION_EDIT } , { models . ROLE_EDITOR , models . PERMISSION_EDIT } , { models . ROLE_VIEWER , models . PERMISSION_EDIT } }
var noPermissions = [ ] folderACLItem { { models . ROLE_VIEWER , models . PERMISSION_VIEW } }
var folderCases = [ ] [ ] folderACLItem {
defaultPermissions ,
adminOnlyPermissions ,
editorOnlyPermissions ,
editorAndViewerPermissions ,
viewerOnlyPermissions ,
everyonePermissions ,
noPermissions ,
}
var defaultDesc = "default permissions"
var adminOnlyDesc = "admin only permissions"
var editorOnlyDesc = "editor only permissions"
var editorAndViewerDesc = "editor and viewer permissions"
var viewerOnlyDesc = "viewer only permissions"
var everyoneDesc = "everyone has editor permissions"
var noDesc = "everyone has view permissions"
var accessCases = [ ] struct {
role models . RoleType
items [ ] folderACLItem
desc string
status int
} {
{ models . ROLE_ADMIN , defaultPermissions , defaultDesc , 200 } ,
{ models . ROLE_ADMIN , adminOnlyPermissions , adminOnlyDesc , 200 } ,
{ models . ROLE_ADMIN , editorOnlyPermissions , editorOnlyDesc , 200 } ,
{ models . ROLE_ADMIN , editorAndViewerPermissions , editorAndViewerDesc , 200 } ,
{ models . ROLE_ADMIN , viewerOnlyPermissions , viewerOnlyDesc , 200 } ,
{ models . ROLE_ADMIN , everyonePermissions , everyoneDesc , 200 } ,
{ models . ROLE_ADMIN , noPermissions , noDesc , 200 } ,
{ models . ROLE_EDITOR , defaultPermissions , defaultDesc , 200 } ,
{ models . ROLE_EDITOR , adminOnlyPermissions , adminOnlyDesc , 403 } ,
{ models . ROLE_EDITOR , editorOnlyPermissions , editorOnlyDesc , 200 } ,
{ models . ROLE_EDITOR , editorAndViewerPermissions , editorAndViewerDesc , 200 } ,
{ models . ROLE_EDITOR , viewerOnlyPermissions , viewerOnlyDesc , 403 } ,
{ models . ROLE_EDITOR , everyonePermissions , everyoneDesc , 200 } ,
{ models . ROLE_EDITOR , noPermissions , noDesc , 403 } ,
{ models . ROLE_VIEWER , defaultPermissions , defaultDesc , 403 } ,
{ models . ROLE_VIEWER , adminOnlyPermissions , adminOnlyDesc , 403 } ,
{ models . ROLE_VIEWER , editorOnlyPermissions , editorOnlyDesc , 403 } ,
{ models . ROLE_VIEWER , editorAndViewerPermissions , editorAndViewerDesc , 200 } ,
{ models . ROLE_VIEWER , viewerOnlyPermissions , viewerOnlyDesc , 200 } ,
{ models . ROLE_VIEWER , everyonePermissions , everyoneDesc , 200 } ,
{ models . ROLE_VIEWER , noPermissions , noDesc , 403 } ,
}
for _ , testCase := range accessCases {
testScenario ( t , fmt . Sprintf ( "When %s tries to create a library panel in a folder with %s, it should return correct status" , testCase . role , testCase . desc ) ,
func ( t * testing . T , sc scenarioContext ) {
2021-03-17 10:06:10 -05:00
folder := createFolderWithACL ( t , sc . sqlStore , "Folder" , sc . user , testCase . items )
2021-03-01 08:33:17 -06:00
sc . reqContext . SignedInUser . OrgRole = testCase . role
2021-05-11 00:10:19 -05:00
command := getCreatePanelCommand ( folder . Id , "Library Panel Name" )
2021-03-01 08:33:17 -06:00
resp := sc . service . createHandler ( sc . reqContext , command )
require . Equal ( t , testCase . status , resp . Status ( ) )
} )
testScenario ( t , fmt . Sprintf ( "When %s tries to patch a library panel by moving it to a folder with %s, it should return correct status" , testCase . role , testCase . desc ) ,
func ( t * testing . T , sc scenarioContext ) {
2021-03-17 10:06:10 -05:00
fromFolder := createFolderWithACL ( t , sc . sqlStore , "Everyone" , sc . user , everyonePermissions )
2021-05-11 00:10:19 -05:00
command := getCreatePanelCommand ( fromFolder . Id , "Library Panel Name" )
2021-03-01 08:33:17 -06:00
resp := sc . service . createHandler ( sc . reqContext , command )
result := validateAndUnMarshalResponse ( t , resp )
2021-03-17 10:06:10 -05:00
toFolder := createFolderWithACL ( t , sc . sqlStore , "Folder" , sc . user , testCase . items )
2021-03-01 08:33:17 -06:00
sc . reqContext . SignedInUser . OrgRole = testCase . role
2021-05-23 23:11:01 -05:00
cmd := patchLibraryElementCommand { FolderID : toFolder . Id , Version : 1 , Kind : int64 ( models . PanelElement ) }
2021-10-11 07:30:59 -05:00
sc . ctx . Req = web . SetURLParams ( sc . ctx . Req , map [ string ] string { ":uid" : result . Result . UID } )
2021-03-01 08:33:17 -06:00
resp = sc . service . patchHandler ( sc . reqContext , cmd )
require . Equal ( t , testCase . status , resp . Status ( ) )
} )
testScenario ( t , fmt . Sprintf ( "When %s tries to patch a library panel by moving it from a folder with %s, it should return correct status" , testCase . role , testCase . desc ) ,
func ( t * testing . T , sc scenarioContext ) {
2021-03-17 10:06:10 -05:00
fromFolder := createFolderWithACL ( t , sc . sqlStore , "Everyone" , sc . user , testCase . items )
2021-05-11 00:10:19 -05:00
command := getCreatePanelCommand ( fromFolder . Id , "Library Panel Name" )
2021-03-01 08:33:17 -06:00
resp := sc . service . createHandler ( sc . reqContext , command )
result := validateAndUnMarshalResponse ( t , resp )
2021-03-17 10:06:10 -05:00
toFolder := createFolderWithACL ( t , sc . sqlStore , "Folder" , sc . user , everyonePermissions )
2021-03-01 08:33:17 -06:00
sc . reqContext . SignedInUser . OrgRole = testCase . role
2021-05-23 23:11:01 -05:00
cmd := patchLibraryElementCommand { FolderID : toFolder . Id , Version : 1 , Kind : int64 ( models . PanelElement ) }
2021-10-11 07:30:59 -05:00
sc . ctx . Req = web . SetURLParams ( sc . ctx . Req , map [ string ] string { ":uid" : result . Result . UID } )
2021-03-01 08:33:17 -06:00
resp = sc . service . patchHandler ( sc . reqContext , cmd )
require . Equal ( t , testCase . status , resp . Status ( ) )
} )
testScenario ( t , fmt . Sprintf ( "When %s tries to delete a library panel in a folder with %s, it should return correct status" , testCase . role , testCase . desc ) ,
func ( t * testing . T , sc scenarioContext ) {
2021-03-17 10:06:10 -05:00
folder := createFolderWithACL ( t , sc . sqlStore , "Folder" , sc . user , testCase . items )
2021-05-11 00:10:19 -05:00
cmd := getCreatePanelCommand ( folder . Id , "Library Panel Name" )
2021-03-01 08:33:17 -06:00
resp := sc . service . createHandler ( sc . reqContext , cmd )
result := validateAndUnMarshalResponse ( t , resp )
sc . reqContext . SignedInUser . OrgRole = testCase . role
2021-10-11 07:30:59 -05:00
sc . ctx . Req = web . SetURLParams ( sc . ctx . Req , map [ string ] string { ":uid" : result . Result . UID } )
2021-03-01 08:33:17 -06:00
resp = sc . service . deleteHandler ( sc . reqContext )
require . Equal ( t , testCase . status , resp . Status ( ) )
} )
}
var generalFolderCases = [ ] struct {
role models . RoleType
status int
} {
{ models . ROLE_ADMIN , 200 } ,
{ models . ROLE_EDITOR , 200 } ,
{ models . ROLE_VIEWER , 403 } ,
}
for _ , testCase := range generalFolderCases {
testScenario ( t , fmt . Sprintf ( "When %s tries to create a library panel in the General folder, it should return correct status" , testCase . role ) ,
func ( t * testing . T , sc scenarioContext ) {
sc . reqContext . SignedInUser . OrgRole = testCase . role
2021-05-11 00:10:19 -05:00
command := getCreatePanelCommand ( 0 , "Library Panel Name" )
2021-03-01 08:33:17 -06:00
resp := sc . service . createHandler ( sc . reqContext , command )
require . Equal ( t , testCase . status , resp . Status ( ) )
} )
testScenario ( t , fmt . Sprintf ( "When %s tries to patch a library panel by moving it to the General folder, it should return correct status" , testCase . role ) ,
func ( t * testing . T , sc scenarioContext ) {
2021-03-17 10:06:10 -05:00
folder := createFolderWithACL ( t , sc . sqlStore , "Folder" , sc . user , everyonePermissions )
2021-05-11 00:10:19 -05:00
command := getCreatePanelCommand ( folder . Id , "Library Panel Name" )
2021-03-01 08:33:17 -06:00
resp := sc . service . createHandler ( sc . reqContext , command )
result := validateAndUnMarshalResponse ( t , resp )
sc . reqContext . SignedInUser . OrgRole = testCase . role
2021-05-23 23:11:01 -05:00
cmd := patchLibraryElementCommand { FolderID : 0 , Version : 1 , Kind : int64 ( models . PanelElement ) }
2021-10-11 07:30:59 -05:00
sc . ctx . Req = web . SetURLParams ( sc . ctx . Req , map [ string ] string { ":uid" : result . Result . UID } )
2021-03-01 08:33:17 -06:00
resp = sc . service . patchHandler ( sc . reqContext , cmd )
require . Equal ( t , testCase . status , resp . Status ( ) )
} )
testScenario ( t , fmt . Sprintf ( "When %s tries to patch a library panel by moving it from the General folder, it should return correct status" , testCase . role ) ,
func ( t * testing . T , sc scenarioContext ) {
2021-03-17 10:06:10 -05:00
folder := createFolderWithACL ( t , sc . sqlStore , "Folder" , sc . user , everyonePermissions )
2021-05-11 00:10:19 -05:00
command := getCreatePanelCommand ( 0 , "Library Panel Name" )
2021-03-01 08:33:17 -06:00
resp := sc . service . createHandler ( sc . reqContext , command )
result := validateAndUnMarshalResponse ( t , resp )
sc . reqContext . SignedInUser . OrgRole = testCase . role
2021-05-23 23:11:01 -05:00
cmd := patchLibraryElementCommand { FolderID : folder . Id , Version : 1 , Kind : int64 ( models . PanelElement ) }
2021-10-11 07:30:59 -05:00
sc . ctx . Req = web . SetURLParams ( sc . ctx . Req , map [ string ] string { ":uid" : result . Result . UID } )
2021-03-01 08:33:17 -06:00
resp = sc . service . patchHandler ( sc . reqContext , cmd )
require . Equal ( t , testCase . status , resp . Status ( ) )
} )
testScenario ( t , fmt . Sprintf ( "When %s tries to delete a library panel in the General folder, it should return correct status" , testCase . role ) ,
func ( t * testing . T , sc scenarioContext ) {
2021-05-11 00:10:19 -05:00
cmd := getCreatePanelCommand ( 0 , "Library Panel Name" )
2021-03-01 08:33:17 -06:00
resp := sc . service . createHandler ( sc . reqContext , cmd )
result := validateAndUnMarshalResponse ( t , resp )
sc . reqContext . SignedInUser . OrgRole = testCase . role
2021-10-11 07:30:59 -05:00
sc . ctx . Req = web . SetURLParams ( sc . ctx . Req , map [ string ] string { ":uid" : result . Result . UID } )
2021-03-01 08:33:17 -06:00
resp = sc . service . deleteHandler ( sc . reqContext )
require . Equal ( t , testCase . status , resp . Status ( ) )
} )
}
var missingFolderCases = [ ] struct {
role models . RoleType
} {
{ models . ROLE_ADMIN } ,
{ models . ROLE_EDITOR } ,
{ models . ROLE_VIEWER } ,
}
for _ , testCase := range missingFolderCases {
testScenario ( t , fmt . Sprintf ( "When %s tries to create a library panel in a folder that doesn't exist, it should fail" , testCase . role ) ,
func ( t * testing . T , sc scenarioContext ) {
sc . reqContext . SignedInUser . OrgRole = testCase . role
2021-05-11 00:10:19 -05:00
command := getCreatePanelCommand ( - 100 , "Library Panel Name" )
2021-03-01 08:33:17 -06:00
resp := sc . service . createHandler ( sc . reqContext , command )
require . Equal ( t , 404 , resp . Status ( ) )
} )
testScenario ( t , fmt . Sprintf ( "When %s tries to patch a library panel by moving it to a folder that doesn't exist, it should fail" , testCase . role ) ,
func ( t * testing . T , sc scenarioContext ) {
2021-03-17 10:06:10 -05:00
folder := createFolderWithACL ( t , sc . sqlStore , "Folder" , sc . user , everyonePermissions )
2021-05-11 00:10:19 -05:00
command := getCreatePanelCommand ( folder . Id , "Library Panel Name" )
2021-03-01 08:33:17 -06:00
resp := sc . service . createHandler ( sc . reqContext , command )
result := validateAndUnMarshalResponse ( t , resp )
sc . reqContext . SignedInUser . OrgRole = testCase . role
2021-05-23 23:11:01 -05:00
cmd := patchLibraryElementCommand { FolderID : - 100 , Version : 1 , Kind : int64 ( models . PanelElement ) }
2021-10-11 07:30:59 -05:00
sc . ctx . Req = web . SetURLParams ( sc . ctx . Req , map [ string ] string { ":uid" : result . Result . UID } )
2021-03-01 08:33:17 -06:00
resp = sc . service . patchHandler ( sc . reqContext , cmd )
require . Equal ( t , 404 , resp . Status ( ) )
} )
}
2021-05-11 00:10:19 -05:00
var getCases = [ ] struct {
role models . RoleType
statuses [ ] int
} {
{ models . ROLE_ADMIN , [ ] int { 200 , 200 , 200 , 200 , 200 , 200 , 200 } } ,
{ models . ROLE_EDITOR , [ ] int { 200 , 404 , 200 , 200 , 200 , 200 , 200 } } ,
{ models . ROLE_VIEWER , [ ] int { 200 , 404 , 404 , 200 , 200 , 200 , 200 } } ,
}
for _ , testCase := range getCases {
testScenario ( t , fmt . Sprintf ( "When %s tries to get a library panel, it should return correct response" , testCase . role ) ,
func ( t * testing . T , sc scenarioContext ) {
var results [ ] libraryElement
for i , folderCase := range folderCases {
folder := createFolderWithACL ( t , sc . sqlStore , fmt . Sprintf ( "Folder%v" , i ) , sc . user , folderCase )
cmd := getCreatePanelCommand ( folder . Id , fmt . Sprintf ( "Library Panel in Folder%v" , i ) )
resp := sc . service . createHandler ( sc . reqContext , cmd )
result := validateAndUnMarshalResponse ( t , resp )
result . Result . Meta . CreatedBy . Name = userInDbName
result . Result . Meta . CreatedBy . AvatarURL = userInDbAvatar
result . Result . Meta . UpdatedBy . Name = userInDbName
result . Result . Meta . UpdatedBy . AvatarURL = userInDbAvatar
result . Result . Meta . FolderName = folder . Title
result . Result . Meta . FolderUID = folder . Uid
results = append ( results , result . Result )
}
sc . reqContext . SignedInUser . OrgRole = testCase . role
for i , result := range results {
2021-10-11 07:30:59 -05:00
sc . ctx . Req = web . SetURLParams ( sc . ctx . Req , map [ string ] string { ":uid" : result . UID } )
2021-05-11 00:10:19 -05:00
resp := sc . service . getHandler ( sc . reqContext )
require . Equal ( t , testCase . statuses [ i ] , resp . Status ( ) )
}
} )
testScenario ( t , fmt . Sprintf ( "When %s tries to get a library panel from General folder, it should return correct response" , testCase . role ) ,
func ( t * testing . T , sc scenarioContext ) {
cmd := getCreatePanelCommand ( 0 , "Library Panel in General Folder" )
resp := sc . service . createHandler ( sc . reqContext , cmd )
result := validateAndUnMarshalResponse ( t , resp )
result . Result . Meta . CreatedBy . Name = userInDbName
result . Result . Meta . CreatedBy . AvatarURL = userInDbAvatar
result . Result . Meta . UpdatedBy . Name = userInDbName
result . Result . Meta . UpdatedBy . AvatarURL = userInDbAvatar
result . Result . Meta . FolderName = "General"
result . Result . Meta . FolderUID = ""
sc . reqContext . SignedInUser . OrgRole = testCase . role
2021-10-11 07:30:59 -05:00
sc . ctx . Req = web . SetURLParams ( sc . ctx . Req , map [ string ] string { ":uid" : result . Result . UID } )
2021-05-11 00:10:19 -05:00
resp = sc . service . getHandler ( sc . reqContext )
require . Equal ( t , 200 , resp . Status ( ) )
var actual libraryElementResult
err := json . Unmarshal ( resp . Body ( ) , & actual )
require . NoError ( t , err )
if diff := cmp . Diff ( result . Result , actual . Result , getCompareOptions ( ) ... ) ; diff != "" {
t . Fatalf ( "Result mismatch (-want +got):\n%s" , diff )
}
} )
}
2021-03-01 08:33:17 -06:00
var getAllCases = [ ] struct {
role models . RoleType
panels int
folderIndexes [ ] int
} {
{ models . ROLE_ADMIN , 7 , [ ] int { 0 , 1 , 2 , 3 , 4 , 5 , 6 } } ,
{ models . ROLE_EDITOR , 6 , [ ] int { 0 , 2 , 3 , 4 , 5 , 6 } } ,
{ models . ROLE_VIEWER , 5 , [ ] int { 0 , 3 , 4 , 5 , 6 } } ,
}
for _ , testCase := range getAllCases {
testScenario ( t , fmt . Sprintf ( "When %s tries to get all library panels, it should return correct response" , testCase . role ) ,
func ( t * testing . T , sc scenarioContext ) {
2021-05-11 00:10:19 -05:00
var results [ ] libraryElement
2021-03-01 08:33:17 -06:00
for i , folderCase := range folderCases {
2021-03-17 10:06:10 -05:00
folder := createFolderWithACL ( t , sc . sqlStore , fmt . Sprintf ( "Folder%v" , i ) , sc . user , folderCase )
2021-05-11 00:10:19 -05:00
cmd := getCreatePanelCommand ( folder . Id , fmt . Sprintf ( "Library Panel in Folder%v" , i ) )
2021-03-01 08:33:17 -06:00
resp := sc . service . createHandler ( sc . reqContext , cmd )
result := validateAndUnMarshalResponse ( t , resp )
2021-05-11 00:10:19 -05:00
result . Result . Meta . CreatedBy . Name = userInDbName
result . Result . Meta . CreatedBy . AvatarURL = userInDbAvatar
result . Result . Meta . UpdatedBy . Name = userInDbName
result . Result . Meta . UpdatedBy . AvatarURL = userInDbAvatar
2021-05-05 04:09:12 -05:00
result . Result . Meta . FolderName = folder . Title
result . Result . Meta . FolderUID = folder . Uid
2021-03-01 08:33:17 -06:00
results = append ( results , result . Result )
}
sc . reqContext . SignedInUser . OrgRole = testCase . role
resp := sc . service . getAllHandler ( sc . reqContext )
require . Equal ( t , 200 , resp . Status ( ) )
2021-05-11 00:10:19 -05:00
var actual libraryElementsSearch
2021-03-01 08:33:17 -06:00
err := json . Unmarshal ( resp . Body ( ) , & actual )
require . NoError ( t , err )
2021-05-11 00:10:19 -05:00
require . Equal ( t , testCase . panels , len ( actual . Result . Elements ) )
2021-03-01 08:33:17 -06:00
for _ , folderIndex := range testCase . folderIndexes {
var folderID = int64 ( folderIndex + 2 ) // testScenario creates one folder and general folder doesn't count
2021-05-11 00:10:19 -05:00
var foundExists = false
var foundResult libraryElement
var actualExists = false
var actualResult libraryElement
2021-03-01 08:33:17 -06:00
for _ , result := range results {
if result . FolderID == folderID {
2021-05-11 00:10:19 -05:00
foundExists = true
2021-03-01 08:33:17 -06:00
foundResult = result
break
}
}
2021-05-11 00:10:19 -05:00
require . Equal ( t , foundExists , true )
2021-03-01 08:33:17 -06:00
2021-05-11 00:10:19 -05:00
for _ , result := range actual . Result . Elements {
2021-03-01 08:33:17 -06:00
if result . FolderID == folderID {
2021-05-11 00:10:19 -05:00
actualExists = true
2021-03-01 08:33:17 -06:00
actualResult = result
break
}
}
2021-05-11 00:10:19 -05:00
require . Equal ( t , actualExists , true )
2021-03-01 08:33:17 -06:00
if diff := cmp . Diff ( foundResult , actualResult , getCompareOptions ( ) ... ) ; diff != "" {
t . Fatalf ( "Result mismatch (-want +got):\n%s" , diff )
}
}
} )
testScenario ( t , fmt . Sprintf ( "When %s tries to get all library panels from General folder, it should return correct response" , testCase . role ) ,
func ( t * testing . T , sc scenarioContext ) {
2021-05-11 00:10:19 -05:00
cmd := getCreatePanelCommand ( 0 , "Library Panel in General Folder" )
2021-03-01 08:33:17 -06:00
resp := sc . service . createHandler ( sc . reqContext , cmd )
result := validateAndUnMarshalResponse ( t , resp )
2021-05-11 00:10:19 -05:00
result . Result . Meta . CreatedBy . Name = userInDbName
result . Result . Meta . CreatedBy . AvatarURL = userInDbAvatar
result . Result . Meta . UpdatedBy . Name = userInDbName
result . Result . Meta . UpdatedBy . AvatarURL = userInDbAvatar
2021-05-05 04:09:12 -05:00
result . Result . Meta . FolderName = "General"
2021-03-01 08:33:17 -06:00
sc . reqContext . SignedInUser . OrgRole = testCase . role
resp = sc . service . getAllHandler ( sc . reqContext )
require . Equal ( t , 200 , resp . Status ( ) )
2021-05-11 00:10:19 -05:00
var actual libraryElementsSearch
2021-03-01 08:33:17 -06:00
err := json . Unmarshal ( resp . Body ( ) , & actual )
require . NoError ( t , err )
2021-05-11 00:10:19 -05:00
require . Equal ( t , 1 , len ( actual . Result . Elements ) )
if diff := cmp . Diff ( result . Result , actual . Result . Elements [ 0 ] , getCompareOptions ( ) ... ) ; diff != "" {
2021-03-01 08:33:17 -06:00
t . Fatalf ( "Result mismatch (-want +got):\n%s" , diff )
}
} )
}
}