2018-02-21 01:11:50 +08:00
package api
import (
2020-11-13 16:52:38 +08:00
"fmt"
2018-02-21 01:11:50 +08:00
"testing"
"github.com/grafana/grafana/pkg/api/dtos"
"github.com/grafana/grafana/pkg/bus"
2018-02-27 03:14:21 +08:00
"github.com/grafana/grafana/pkg/components/simplejson"
2020-03-04 19:57:20 +08:00
"github.com/grafana/grafana/pkg/models"
2018-02-21 01:11:50 +08:00
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/guardian"
2020-11-13 16:52:38 +08:00
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
2018-02-21 01:11:50 +08:00
)
2020-11-13 16:52:38 +08:00
func TestFolderPermissionAPIEndpoint ( t * testing . T ) {
t . Run ( "Given folder not exists" , func ( t * testing . T ) {
mock := & fakeFolderService {
GetFolderByUIDError : models . ErrFolderNotFound ,
}
origNewFolderService := dashboards . NewFolderService
t . Cleanup ( func ( ) {
dashboards . NewFolderService = origNewFolderService
} )
mockFolderService ( mock )
loggedInUserScenarioWithRole ( t , "When calling GET on" , "GET" , "/api/folders/uid/permissions" , "/api/folders/:uid/permissions" , models . ROLE_EDITOR , func ( sc * scenarioContext ) {
callGetFolderPermissions ( sc )
assert . Equal ( t , 404 , sc . resp . Code )
} )
cmd := dtos . UpdateDashboardAclCommand {
Items : [ ] dtos . DashboardAclUpdateItem {
2020-11-18 00:09:14 +08:00
{ UserID : 1000 , Permission : models . PERMISSION_ADMIN } ,
2020-11-13 16:52:38 +08:00
} ,
}
updateFolderPermissionScenario ( t , "When calling POST on" , "/api/folders/uid/permissions" , "/api/folders/:uid/permissions" , cmd , func ( sc * scenarioContext ) {
callUpdateFolderPermissions ( sc )
assert . Equal ( t , 404 , sc . resp . Code )
} )
} )
t . Run ( "Given user has no admin permissions" , func ( t * testing . T ) {
origNewGuardian := guardian . New
origNewFolderService := dashboards . NewFolderService
t . Cleanup ( func ( ) {
guardian . New = origNewGuardian
dashboards . NewFolderService = origNewFolderService
} )
guardian . MockDashboardGuardian ( & guardian . FakeDashboardGuardian { CanAdminValue : false } )
mock := & fakeFolderService {
GetFolderByUIDResult : & models . Folder {
Id : 1 ,
Uid : "uid" ,
Title : "Folder" ,
} ,
}
mockFolderService ( mock )
loggedInUserScenarioWithRole ( t , "When calling GET on" , "GET" , "/api/folders/uid/permissions" , "/api/folders/:uid/permissions" , models . ROLE_EDITOR , func ( sc * scenarioContext ) {
callGetFolderPermissions ( sc )
assert . Equal ( t , 403 , sc . resp . Code )
} )
cmd := dtos . UpdateDashboardAclCommand {
Items : [ ] dtos . DashboardAclUpdateItem {
2020-11-18 00:09:14 +08:00
{ UserID : 1000 , Permission : models . PERMISSION_ADMIN } ,
2020-11-13 16:52:38 +08:00
} ,
}
updateFolderPermissionScenario ( t , "When calling POST on" , "/api/folders/uid/permissions" , "/api/folders/:uid/permissions" , cmd , func ( sc * scenarioContext ) {
callUpdateFolderPermissions ( sc )
assert . Equal ( t , 403 , sc . resp . Code )
} )
} )
t . Run ( "Given user has admin permissions and permissions to update" , func ( t * testing . T ) {
origNewGuardian := guardian . New
origNewFolderService := dashboards . NewFolderService
t . Cleanup ( func ( ) {
guardian . New = origNewGuardian
dashboards . NewFolderService = origNewFolderService
} )
guardian . MockDashboardGuardian ( & guardian . FakeDashboardGuardian {
CanAdminValue : true ,
CheckPermissionBeforeUpdateValue : true ,
GetAclValue : [ ] * models . DashboardAclInfoDTO {
{ OrgId : 1 , DashboardId : 1 , UserId : 2 , Permission : models . PERMISSION_VIEW } ,
{ OrgId : 1 , DashboardId : 1 , UserId : 3 , Permission : models . PERMISSION_EDIT } ,
{ OrgId : 1 , DashboardId : 1 , UserId : 4 , Permission : models . PERMISSION_ADMIN } ,
{ OrgId : 1 , DashboardId : 1 , TeamId : 1 , Permission : models . PERMISSION_VIEW } ,
{ OrgId : 1 , DashboardId : 1 , TeamId : 2 , Permission : models . PERMISSION_ADMIN } ,
} ,
} )
mock := & fakeFolderService {
GetFolderByUIDResult : & models . Folder {
Id : 1 ,
Uid : "uid" ,
Title : "Folder" ,
} ,
}
mockFolderService ( mock )
loggedInUserScenarioWithRole ( t , "When calling GET on" , "GET" , "/api/folders/uid/permissions" , "/api/folders/:uid/permissions" , models . ROLE_ADMIN , func ( sc * scenarioContext ) {
callGetFolderPermissions ( sc )
assert . Equal ( t , 200 , sc . resp . Code )
respJSON , err := simplejson . NewJson ( sc . resp . Body . Bytes ( ) )
require . NoError ( t , err )
assert . Equal ( t , 5 , len ( respJSON . MustArray ( ) ) )
assert . Equal ( t , 2 , respJSON . GetIndex ( 0 ) . Get ( "userId" ) . MustInt ( ) )
assert . Equal ( t , int ( models . PERMISSION_VIEW ) , respJSON . GetIndex ( 0 ) . Get ( "permission" ) . MustInt ( ) )
} )
cmd := dtos . UpdateDashboardAclCommand {
Items : [ ] dtos . DashboardAclUpdateItem {
2020-11-18 00:09:14 +08:00
{ UserID : 1000 , Permission : models . PERMISSION_ADMIN } ,
2020-11-13 16:52:38 +08:00
} ,
}
updateFolderPermissionScenario ( t , "When calling POST on" , "/api/folders/uid/permissions" , "/api/folders/:uid/permissions" , cmd , func ( sc * scenarioContext ) {
callUpdateFolderPermissions ( sc )
assert . Equal ( t , 200 , sc . resp . Code )
respJSON , err := simplejson . NewJson ( sc . resp . Body . Bytes ( ) )
require . NoError ( t , err )
assert . Equal ( t , 1 , respJSON . Get ( "id" ) . MustInt ( ) )
assert . Equal ( t , "Folder" , respJSON . Get ( "title" ) . MustString ( ) )
} )
} )
t . Run ( "When trying to update permissions with duplicate permissions" , func ( t * testing . T ) {
origNewGuardian := guardian . New
origNewFolderService := dashboards . NewFolderService
t . Cleanup ( func ( ) {
guardian . New = origNewGuardian
dashboards . NewFolderService = origNewFolderService
} )
guardian . MockDashboardGuardian ( & guardian . FakeDashboardGuardian {
CanAdminValue : true ,
CheckPermissionBeforeUpdateValue : false ,
CheckPermissionBeforeUpdateError : guardian . ErrGuardianPermissionExists ,
} )
mock := & fakeFolderService {
GetFolderByUIDResult : & models . Folder {
Id : 1 ,
Uid : "uid" ,
Title : "Folder" ,
} ,
}
mockFolderService ( mock )
cmd := dtos . UpdateDashboardAclCommand {
Items : [ ] dtos . DashboardAclUpdateItem {
2020-11-18 00:09:14 +08:00
{ UserID : 1000 , Permission : models . PERMISSION_ADMIN } ,
2020-11-13 16:52:38 +08:00
} ,
}
updateFolderPermissionScenario ( t , "When calling POST on" , "/api/folders/uid/permissions" , "/api/folders/:uid/permissions" , cmd , func ( sc * scenarioContext ) {
callUpdateFolderPermissions ( sc )
assert . Equal ( t , 400 , sc . resp . Code )
} )
} )
t . Run ( "When trying to override inherited permissions with lower precedence" , func ( t * testing . T ) {
origNewGuardian := guardian . New
origNewFolderService := dashboards . NewFolderService
t . Cleanup ( func ( ) {
guardian . New = origNewGuardian
dashboards . NewFolderService = origNewFolderService
} )
guardian . MockDashboardGuardian ( & guardian . FakeDashboardGuardian {
CanAdminValue : true ,
CheckPermissionBeforeUpdateValue : false ,
CheckPermissionBeforeUpdateError : guardian . ErrGuardianOverride } ,
)
mock := & fakeFolderService {
GetFolderByUIDResult : & models . Folder {
Id : 1 ,
Uid : "uid" ,
Title : "Folder" ,
} ,
}
mockFolderService ( mock )
cmd := dtos . UpdateDashboardAclCommand {
Items : [ ] dtos . DashboardAclUpdateItem {
2020-11-18 00:09:14 +08:00
{ UserID : 1000 , Permission : models . PERMISSION_ADMIN } ,
2020-11-13 16:52:38 +08:00
} ,
}
updateFolderPermissionScenario ( t , "When calling POST on" , "/api/folders/uid/permissions" , "/api/folders/:uid/permissions" , cmd , func ( sc * scenarioContext ) {
callUpdateFolderPermissions ( sc )
assert . Equal ( t , 400 , sc . resp . Code )
2018-02-27 03:14:21 +08:00
} )
2018-02-21 01:11:50 +08:00
} )
}
func callGetFolderPermissions ( sc * scenarioContext ) {
sc . handlerFunc = GetFolderPermissionList
sc . fakeReqWithParams ( "GET" , sc . url , map [ string ] string { } ) . exec ( )
}
func callUpdateFolderPermissions ( sc * scenarioContext ) {
2020-03-04 19:57:20 +08:00
bus . AddHandler ( "test" , func ( cmd * models . UpdateDashboardAclCommand ) error {
2018-02-21 01:11:50 +08:00
return nil
} )
sc . fakeReqWithParams ( "POST" , sc . url , map [ string ] string { } ) . exec ( )
}
2020-11-13 16:52:38 +08:00
func updateFolderPermissionScenario ( t * testing . T , desc string , url string , routePattern string , cmd dtos . UpdateDashboardAclCommand , fn scenarioFunc ) {
t . Run ( fmt . Sprintf ( "%s %s" , desc , url ) , func ( t * testing . T ) {
2018-02-21 01:11:50 +08:00
defer bus . ClearBusHandlers ( )
2020-11-13 16:52:38 +08:00
sc := setupScenarioContext ( t , url )
2018-02-21 01:11:50 +08:00
2020-03-04 19:57:20 +08:00
sc . defaultHandler = Wrap ( func ( c * models . ReqContext ) Response {
2018-02-21 01:11:50 +08:00
sc . context = c
2020-11-13 16:52:38 +08:00
sc . context . OrgId = testOrgID
sc . context . UserId = testUserID
2018-02-21 01:11:50 +08:00
return UpdateFolderPermissions ( c , cmd )
} )
sc . m . Post ( routePattern , sc . defaultHandler )
fn ( sc )
} )
}