mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
acl fixes
This commit is contained in:
parent
f6b52cd6d7
commit
9c6c8c0f3f
@ -20,13 +20,12 @@ func GetDashboardAclList(c *middleware.Context) Response {
|
||||
return dashboardGuardianResponse(err)
|
||||
}
|
||||
|
||||
query := m.GetDashboardAclInfoListQuery{DashboardId: dashId}
|
||||
if err := bus.Dispatch(&query); err != nil {
|
||||
return ApiError(500, "Failed to get Dashboard ACL", err)
|
||||
acl, err := guardian.GetAcl()
|
||||
if err != nil {
|
||||
return ApiError(500, "Failed to get dashboard acl", err)
|
||||
}
|
||||
|
||||
list := query.Result
|
||||
return Json(200, list)
|
||||
return Json(200, acl)
|
||||
}
|
||||
|
||||
func UpdateDashboardAcl(c *middleware.Context, apiCmd dtos.UpdateDashboardAclCommand) Response {
|
||||
|
@ -30,7 +30,7 @@ func TestDashboardAclApiEndpoint(t *testing.T) {
|
||||
return nil
|
||||
})
|
||||
|
||||
bus.AddHandler("test", func(query *models.GetInheritedDashboardAclQuery) error {
|
||||
bus.AddHandler("test", func(query *models.GetDashboardAclInfoListQuery) error {
|
||||
query.Result = mockResult
|
||||
return nil
|
||||
})
|
||||
|
@ -31,7 +31,7 @@ func TestDashboardApiEndpoint(t *testing.T) {
|
||||
})
|
||||
|
||||
aclMockResp := []*models.DashboardAcl{}
|
||||
bus.AddHandler("test", func(query *models.GetInheritedDashboardAclQuery) error {
|
||||
bus.AddHandler("test", func(query *models.GetDashboardAclInfoListQuery) error {
|
||||
query.Result = aclMockResp
|
||||
return nil
|
||||
})
|
||||
@ -179,7 +179,7 @@ func TestDashboardApiEndpoint(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
bus.AddHandler("test", func(query *models.GetInheritedDashboardAclQuery) error {
|
||||
bus.AddHandler("test", func(query *models.GetDashboardAclInfoListQuery) error {
|
||||
query.Result = aclMockResp
|
||||
return nil
|
||||
})
|
||||
@ -276,7 +276,7 @@ func TestDashboardApiEndpoint(t *testing.T) {
|
||||
{Id: 1, OrgId: 1, DashboardId: 2, UserId: 1, Permission: models.PERMISSION_EDIT},
|
||||
}
|
||||
|
||||
bus.AddHandler("test", func(query *models.GetInheritedDashboardAclQuery) error {
|
||||
bus.AddHandler("test", func(query *models.GetDashboardAclInfoListQuery) error {
|
||||
query.Result = mockResult
|
||||
return nil
|
||||
})
|
||||
@ -318,7 +318,7 @@ func TestDashboardApiEndpoint(t *testing.T) {
|
||||
{Id: 1, OrgId: 1, DashboardId: 2, UserId: 1, Permission: models.PERMISSION_VIEW},
|
||||
}
|
||||
|
||||
bus.AddHandler("test", func(query *models.GetInheritedDashboardAclQuery) error {
|
||||
bus.AddHandler("test", func(query *models.GetDashboardAclInfoListQuery) error {
|
||||
query.Result = mockResult
|
||||
return nil
|
||||
})
|
||||
|
@ -11,6 +11,6 @@ type UpdateDashboardAclCommand struct {
|
||||
type DashboardAclUpdateItem struct {
|
||||
UserId int64 `json:"userId"`
|
||||
UserGroupId int64 `json:"userGroupId"`
|
||||
Role m.RoleType `json:"role"`
|
||||
Role *m.RoleType `json:"role,omitempty"`
|
||||
Permission m.PermissionType `json:"permission"`
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ type DashboardAcl struct {
|
||||
|
||||
UserId int64
|
||||
UserGroupId int64
|
||||
Role RoleType
|
||||
Role *RoleType // pointer to be nullable
|
||||
Permission PermissionType
|
||||
|
||||
Created time.Time
|
||||
@ -56,7 +56,7 @@ type DashboardAclInfoDTO struct {
|
||||
UserEmail string `json:"userEmail"`
|
||||
UserGroupId int64 `json:"userGroupId"`
|
||||
UserGroup string `json:"userGroup"`
|
||||
Role RoleType `json:"role"`
|
||||
Role *RoleType `json:"role,omitempty"`
|
||||
Permission PermissionType `json:"permission"`
|
||||
PermissionName string `json:"permissionName"`
|
||||
}
|
||||
@ -90,12 +90,6 @@ type RemoveDashboardAclCommand struct {
|
||||
//
|
||||
type GetDashboardAclInfoListQuery struct {
|
||||
DashboardId int64
|
||||
OrgId int64
|
||||
Result []*DashboardAclInfoDTO
|
||||
}
|
||||
|
||||
// Returns dashboard acl list items and parent folder items
|
||||
type GetInheritedDashboardAclQuery struct {
|
||||
DashboardId int64
|
||||
OrgId int64
|
||||
Result []*DashboardAcl
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ type DashboardGuardian struct {
|
||||
user *m.SignedInUser
|
||||
dashId int64
|
||||
orgId int64
|
||||
acl []*m.DashboardAcl
|
||||
acl []*m.DashboardAclInfoDTO
|
||||
groups []*m.UserGroup
|
||||
log log.Logger
|
||||
}
|
||||
@ -41,7 +41,7 @@ func (g *DashboardGuardian) HasPermission(permission m.PermissionType) (bool, er
|
||||
return true, nil
|
||||
}
|
||||
|
||||
acl, err := g.getAcl()
|
||||
acl, err := g.GetAcl()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@ -62,8 +62,8 @@ func (g *DashboardGuardian) HasPermission(permission m.PermissionType) (bool, er
|
||||
}
|
||||
}
|
||||
|
||||
if p.Role.IsValid() {
|
||||
if p.Role == g.user.OrgRole && p.Permission >= permission {
|
||||
if p.Role != nil {
|
||||
if *p.Role == g.user.OrgRole && p.Permission >= permission {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
@ -73,12 +73,12 @@ func (g *DashboardGuardian) HasPermission(permission m.PermissionType) (bool, er
|
||||
}
|
||||
|
||||
// Returns dashboard acl
|
||||
func (g *DashboardGuardian) getAcl() ([]*m.DashboardAcl, error) {
|
||||
func (g *DashboardGuardian) GetAcl() ([]*m.DashboardAclInfoDTO, error) {
|
||||
if g.acl != nil {
|
||||
return g.acl, nil
|
||||
}
|
||||
|
||||
query := m.GetInheritedDashboardAclQuery{DashboardId: g.dashId, OrgId: g.orgId}
|
||||
query := m.GetDashboardAclInfoListQuery{DashboardId: g.dashId, OrgId: g.orgId}
|
||||
if err := bus.Dispatch(&query); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -13,7 +13,6 @@ func init() {
|
||||
bus.AddHandler("sql", UpdateDashboardAcl)
|
||||
bus.AddHandler("sql", RemoveDashboardAcl)
|
||||
bus.AddHandler("sql", GetDashboardAclInfoList)
|
||||
bus.AddHandler("sql", GetInheritedDashboardAcl)
|
||||
}
|
||||
|
||||
func UpdateDashboardAcl(cmd *m.UpdateDashboardAclCommand) error {
|
||||
@ -126,31 +125,9 @@ func RemoveDashboardAcl(cmd *m.RemoveDashboardAclCommand) error {
|
||||
})
|
||||
}
|
||||
|
||||
func GetInheritedDashboardAcl(query *m.GetInheritedDashboardAclQuery) error {
|
||||
rawSQL := `SELECT
|
||||
da.id,
|
||||
da.org_id,
|
||||
da.dashboard_id,
|
||||
da.user_id,
|
||||
da.user_group_id,
|
||||
da.role,
|
||||
da.permission,
|
||||
da.created,
|
||||
da.updated
|
||||
FROM dashboard_acl as da
|
||||
WHERE da.dashboard_id IN (
|
||||
SELECT id FROM dashboard where id = ?
|
||||
UNION
|
||||
SELECT parent_id from dashboard where id = ?
|
||||
) AND org_id = ?`
|
||||
|
||||
query.Result = make([]*m.DashboardAcl, 0)
|
||||
return x.SQL(rawSQL, query.DashboardId, query.DashboardId, query.OrgId).Find(&query.Result)
|
||||
}
|
||||
|
||||
func GetDashboardAclInfoList(query *m.GetDashboardAclInfoListQuery) error {
|
||||
dashboardFilter := fmt.Sprintf(`IN (
|
||||
SELECT id FROM dashboard where id = %d
|
||||
SELECT %d
|
||||
UNION
|
||||
SELECT parent_id from dashboard where id = %d
|
||||
)`, query.DashboardId, query.DashboardId)
|
||||
@ -172,7 +149,7 @@ func GetDashboardAclInfoList(query *m.GetDashboardAclInfoListQuery) error {
|
||||
FROM` + dialect.Quote("dashboard_acl") + ` as da
|
||||
LEFT OUTER JOIN ` + dialect.Quote("user") + ` AS u ON u.id = da.user_id
|
||||
LEFT OUTER JOIN user_group ug on ug.id = da.user_group_id
|
||||
WHERE dashboard_id ` + dashboardFilter + `
|
||||
WHERE dashboard_id ` + dashboardFilter + ` AND da.org_id = ?
|
||||
|
||||
-- Also include default permission if has_acl = 0
|
||||
|
||||
@ -195,7 +172,7 @@ func GetDashboardAclInfoList(query *m.GetDashboardAclInfoListQuery) error {
|
||||
`
|
||||
|
||||
query.Result = make([]*m.DashboardAclInfoDTO, 0)
|
||||
err := x.SQL(rawSQL, query.DashboardId).Find(&query.Result)
|
||||
err := x.SQL(rawSQL, query.OrgId, query.DashboardId).Find(&query.Result)
|
||||
|
||||
for _, p := range query.Result {
|
||||
p.PermissionName = p.Permission.String()
|
||||
|
@ -35,9 +35,9 @@ func TestDashboardAclDataAccess(t *testing.T) {
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
Convey("When reading dashboard acl should include acl for parent folder", func() {
|
||||
query := m.GetInheritedDashboardAclQuery{OrgId: 1, DashboardId: childDash.Id}
|
||||
query := m.GetDashboardAclInfoListQuery{DashboardId: childDash.Id, OrgId: 1}
|
||||
|
||||
err := GetInheritedDashboardAcl(&query)
|
||||
err := GetDashboardAclInfoList(&query)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
So(len(query.Result), ShouldEqual, 1)
|
||||
@ -54,9 +54,9 @@ func TestDashboardAclDataAccess(t *testing.T) {
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
Convey("When reading dashboard acl should include acl for parent folder and child", func() {
|
||||
query := m.GetInheritedDashboardAclQuery{OrgId: 1, DashboardId: childDash.Id}
|
||||
query := m.GetDashboardAclInfoListQuery{OrgId: 1, DashboardId: childDash.Id}
|
||||
|
||||
err := GetInheritedDashboardAcl(&query)
|
||||
err := GetDashboardAclInfoList(&query)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
So(len(query.Result), ShouldEqual, 2)
|
||||
@ -79,7 +79,7 @@ func TestDashboardAclDataAccess(t *testing.T) {
|
||||
|
||||
So(setDashAclCmd.Result.Id, ShouldEqual, 3)
|
||||
|
||||
q1 := &m.GetDashboardAclInfoListQuery{DashboardId: savedFolder.Id}
|
||||
q1 := &m.GetDashboardAclInfoListQuery{DashboardId: savedFolder.Id, OrgId: 1}
|
||||
err = GetDashboardAclInfoList(q1)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
@ -109,7 +109,7 @@ func TestDashboardAclDataAccess(t *testing.T) {
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
q3 := &m.GetDashboardAclInfoListQuery{DashboardId: savedFolder.Id}
|
||||
q3 := &m.GetDashboardAclInfoListQuery{DashboardId: savedFolder.Id, OrgId: 1}
|
||||
err = GetDashboardAclInfoList(q3)
|
||||
So(err, ShouldBeNil)
|
||||
So(len(q3.Result), ShouldEqual, 1)
|
||||
@ -127,7 +127,7 @@ func TestDashboardAclDataAccess(t *testing.T) {
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
q3 := &m.GetDashboardAclInfoListQuery{DashboardId: savedFolder.Id}
|
||||
q3 := &m.GetDashboardAclInfoListQuery{DashboardId: savedFolder.Id, OrgId: 1}
|
||||
err = GetDashboardAclInfoList(q3)
|
||||
So(err, ShouldBeNil)
|
||||
So(len(q3.Result), ShouldEqual, 0)
|
||||
@ -150,7 +150,7 @@ func TestDashboardAclDataAccess(t *testing.T) {
|
||||
err := SetDashboardAcl(&setDashAclCmd)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
q1 := &m.GetDashboardAclInfoListQuery{DashboardId: savedFolder.Id}
|
||||
q1 := &m.GetDashboardAclInfoListQuery{DashboardId: savedFolder.Id, OrgId: 1}
|
||||
err = GetDashboardAclInfoList(q1)
|
||||
So(err, ShouldBeNil)
|
||||
So(q1.Result[0].DashboardId, ShouldEqual, savedFolder.Id)
|
||||
@ -164,7 +164,7 @@ func TestDashboardAclDataAccess(t *testing.T) {
|
||||
})
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
q3 := &m.GetDashboardAclInfoListQuery{DashboardId: savedFolder.Id}
|
||||
q3 := &m.GetDashboardAclInfoListQuery{DashboardId: savedFolder.Id, OrgId: 1}
|
||||
err = GetDashboardAclInfoList(q3)
|
||||
So(err, ShouldBeNil)
|
||||
So(len(q3.Result), ShouldEqual, 0)
|
||||
@ -180,7 +180,7 @@ func TestDashboardAclDataAccess(t *testing.T) {
|
||||
})
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
q3 := &m.GetDashboardAclInfoListQuery{DashboardId: savedFolder.Id}
|
||||
q3 := &m.GetDashboardAclInfoListQuery{DashboardId: savedFolder.Id, OrgId: 1}
|
||||
err = GetDashboardAclInfoList(q3)
|
||||
So(err, ShouldBeNil)
|
||||
So(len(q3.Result), ShouldEqual, 1)
|
||||
|
@ -169,7 +169,7 @@ func TestAccountDataAccess(t *testing.T) {
|
||||
err = AddOrgUser(&orgUserCmd)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
query := m.GetOrgUsersQuery{OrgId: orgUserCmd.OrgId}
|
||||
query := m.GetOrgUsersQuery{OrgId: ac1.OrgId}
|
||||
err = GetOrgUsers(&query)
|
||||
So(err, ShouldBeNil)
|
||||
So(len(query.Result), ShouldEqual, 3)
|
||||
@ -181,12 +181,12 @@ func TestAccountDataAccess(t *testing.T) {
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
Convey("When org user is deleted", func() {
|
||||
cmdRemove := m.RemoveOrgUserCommand{OrgId: orgUserCmd.OrgId, UserId: ac3.Id}
|
||||
cmdRemove := m.RemoveOrgUserCommand{OrgId: ac1.OrgId, UserId: ac3.Id}
|
||||
err := RemoveOrgUser(&cmdRemove)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
Convey("Should remove dependent permissions for deleted org user", func() {
|
||||
permQuery := &m.GetDashboardAclInfoListQuery{DashboardId: 1}
|
||||
permQuery := &m.GetDashboardAclInfoListQuery{DashboardId: 1, OrgId: ac1.OrgId}
|
||||
err = GetDashboardAclInfoList(permQuery)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
@ -194,10 +194,11 @@ func TestAccountDataAccess(t *testing.T) {
|
||||
})
|
||||
|
||||
Convey("Should not remove dashboard permissions for same user in another org", func() {
|
||||
permQuery := &m.GetDashboardAclInfoListQuery{DashboardId: 2}
|
||||
permQuery := &m.GetDashboardAclInfoListQuery{DashboardId: 2, OrgId: ac3.OrgId}
|
||||
err = GetDashboardAclInfoList(permQuery)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
So(len(permQuery.Result), ShouldEqual, 1)
|
||||
So(permQuery.Result[0].OrgId, ShouldEqual, ac3.OrgId)
|
||||
So(permQuery.Result[0].UserId, ShouldEqual, ac3.Id)
|
||||
})
|
||||
|
@ -103,7 +103,7 @@ func TestUserGroupCommandsAndQueries(t *testing.T) {
|
||||
err = GetUserGroupById(query)
|
||||
So(err, ShouldEqual, m.ErrUserGroupNotFound)
|
||||
|
||||
permQuery := &m.GetDashboardAclInfoListQuery{DashboardId: 1}
|
||||
permQuery := &m.GetDashboardAclInfoListQuery{DashboardId: 1, OrgId: 1}
|
||||
err = GetDashboardAclInfoList(permQuery)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
|
@ -116,7 +116,7 @@ func TestUserDataAccess(t *testing.T) {
|
||||
|
||||
So(len(query.Result), ShouldEqual, 1)
|
||||
|
||||
permQuery := &m.GetDashboardAclInfoListQuery{DashboardId: 1}
|
||||
permQuery := &m.GetDashboardAclInfoListQuery{DashboardId: 1, OrgId: 1}
|
||||
err = GetDashboardAclInfoList(permQuery)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
|
@ -106,11 +106,7 @@ export class AclCtrl {
|
||||
|
||||
typeChanged() {
|
||||
if (this.newType === 'Viewer' || this.newType === 'Editor') {
|
||||
this.items.push(this.prepareViewModel({
|
||||
permission: 1,
|
||||
role: this.newType
|
||||
}));
|
||||
|
||||
this.addNewItem({permission: 1, role: this.newType});
|
||||
this.canUpdate = true;
|
||||
this.resetNewType();
|
||||
}
|
||||
|
@ -21,6 +21,10 @@ $gf-form-margin: 0.25rem;
|
||||
.gf-form-disabled {
|
||||
color: $text-color-weak;
|
||||
|
||||
.gf-form-select-wrapper::after {
|
||||
color: $text-color-weak;
|
||||
}
|
||||
|
||||
a,
|
||||
.gf-form-input {
|
||||
color: $text-color-weak;
|
||||
|
Loading…
Reference in New Issue
Block a user