Commit 2257c1f8 by Torkel Ödegaard

dashboard acl work

parent aab6c98e
......@@ -250,7 +250,7 @@ func (hs *HttpServer) registerRoutes() {
r.Group("/acl", func() {
r.Get("/", wrap(GetDashboardAclList))
r.Post("/", bind(m.SetDashboardAclCommand{}), wrap(PostDashboardAcl))
r.Post("/", bind(dtos.UpdateDashboardAclCommand{}), wrap(UpdateDashboardAcl))
r.Delete("/:aclId", wrap(DeleteDashboardAcl))
})
}, reqSignedIn)
......
package api
import (
"time"
"github.com/grafana/grafana/pkg/api/dtos"
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/metrics"
"github.com/grafana/grafana/pkg/middleware"
m "github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/guardian"
"github.com/grafana/grafana/pkg/util"
)
func GetDashboardAclList(c *middleware.Context) Response {
......@@ -27,7 +29,7 @@ func GetDashboardAclList(c *middleware.Context) Response {
return Json(200, list)
}
func PostDashboardAcl(c *middleware.Context, cmd m.SetDashboardAclCommand) Response {
func UpdateDashboardAcl(c *middleware.Context, apiCmd dtos.UpdateDashboardAclCommand) Response {
dashId := c.ParamsInt64(":dashboardId")
guardian := guardian.NewDashboardGuardian(dashId, c.OrgId, c.SignedInUser)
......@@ -35,9 +37,22 @@ func PostDashboardAcl(c *middleware.Context, cmd m.SetDashboardAclCommand) Respo
return dashboardGuardianResponse(err)
}
cmd.OrgId = c.OrgId
cmd := m.UpdateDashboardAclCommand{}
cmd.DashboardId = dashId
for _, item := range apiCmd.Items {
cmd.Items = append(cmd.Items, &m.DashboardAcl{
OrgId: c.OrgId,
DashboardId: dashId,
UserId: item.UserId,
UserGroupId: item.UserGroupId,
Role: item.Role,
Permission: item.Permission,
Created: time.Now(),
Updated: time.Now(),
})
}
if err := bus.Dispatch(&cmd); err != nil {
if err == m.ErrDashboardAclInfoMissing || err == m.ErrDashboardPermissionDashboardEmpty {
return ApiError(409, err.Error(), err)
......@@ -45,12 +60,8 @@ func PostDashboardAcl(c *middleware.Context, cmd m.SetDashboardAclCommand) Respo
return ApiError(500, "Failed to create permission", err)
}
metrics.M_Api_Dashboard_Acl_Create.Inc(1)
return Json(200, &util.DynMap{
"permissionId": cmd.Result.Id,
"message": "Permission created",
})
metrics.M_Api_Dashboard_Acl_Update.Inc(1)
return ApiSuccess("Dashboard acl updated")
}
func DeleteDashboardAcl(c *middleware.Context) Response {
......
package dtos
import (
m "github.com/grafana/grafana/pkg/models"
)
type UpdateDashboardAclCommand struct {
Items []DashboardAclUpdateItem `json:"items"`
}
type DashboardAclUpdateItem struct {
UserId int64 `json:"userId"`
UserGroupId int64 `json:"userGroupId"`
Role m.RoleType `json:"role"`
Permission m.PermissionType `json:"permission"`
}
......@@ -36,7 +36,7 @@ var (
M_Api_Dashboard_Snapshot_External Counter
M_Api_Dashboard_Snapshot_Get Counter
M_Api_UserGroup_Create Counter
M_Api_Dashboard_Acl_Create Counter
M_Api_Dashboard_Acl_Update Counter
M_Models_Dashboard_Insert Counter
M_Alerting_Result_State_Alerting Counter
M_Alerting_Result_State_Ok Counter
......@@ -95,7 +95,7 @@ func initMetricVars(settings *MetricSettings) {
M_Api_User_SignUpInvite = RegCounter("api.user.signup_invite")
M_Api_UserGroup_Create = RegCounter("api.usergroup.create")
M_Api_Dashboard_Acl_Create = RegCounter("api.dashboard.acl.create")
M_Api_Dashboard_Acl_Update = RegCounter("api.dashboard.acl.update")
M_Api_Dashboard_Save = RegTimer("api.dashboard.save")
M_Api_Dashboard_Get = RegTimer("api.dashboard.get")
......
......@@ -36,6 +36,7 @@ type DashboardAcl struct {
UserId int64
UserGroupId int64
Role RoleType
Permission PermissionType
Created time.Time
......@@ -64,14 +65,19 @@ type DashboardAclInfoDTO struct {
// COMMANDS
//
type UpdateDashboardAclCommand struct {
DashboardId int64
Items []*DashboardAcl
}
type SetDashboardAclCommand struct {
DashboardId int64 `json:"-"`
OrgId int64 `json:"-"`
UserId int64 `json:"userId"`
UserGroupId int64 `json:"userGroupId"`
Permission PermissionType `json:"permission" binding:"Required"`
DashboardId int64
OrgId int64
UserId int64
UserGroupId int64
Permission PermissionType
Result DashboardAcl `json:"-"`
Result DashboardAcl
}
type RemoveDashboardAclCommand struct {
......
......@@ -9,11 +9,44 @@ import (
func init() {
bus.AddHandler("sql", SetDashboardAcl)
bus.AddHandler("sql", UpdateDashboardAcl)
bus.AddHandler("sql", RemoveDashboardAcl)
bus.AddHandler("sql", GetDashboardAclInfoList)
bus.AddHandler("sql", GetInheritedDashboardAcl)
}
func UpdateDashboardAcl(cmd *m.UpdateDashboardAclCommand) error {
return inTransaction(func(sess *DBSession) error {
// delete existing items
_, err := sess.Exec("DELETE FROM dashboard_acl WHERE dashboard_id=?", cmd.DashboardId)
if err != nil {
return err
}
for _, item := range cmd.Items {
if item.UserId == 0 && item.UserGroupId == 0 && !item.Role.IsValid() {
return m.ErrDashboardAclInfoMissing
}
if item.DashboardId == 0 {
return m.ErrDashboardPermissionDashboardEmpty
}
sess.Nullable("user_id", "user_group_id")
if _, err := sess.Insert(item); err != nil {
return err
}
}
// Update dashboard HasAcl flag
dashboard := m.Dashboard{HasAcl: true}
if _, err := sess.Cols("has_acl").Where("id=? OR parent_id=?", cmd.DashboardId, cmd.DashboardId).Update(&dashboard); err != nil {
return err
}
return nil
})
}
func SetDashboardAcl(cmd *m.SetDashboardAclCommand) error {
return inTransaction(func(sess *DBSession) error {
if cmd.UserId == 0 && cmd.UserGroupId == 0 {
......
......@@ -12,7 +12,7 @@
<div class="modal-content">
<table class="filter-table gf-form-group">
<tr ng-repeat="acl in ctrl.aclItems">
<tr ng-repeat="acl in ctrl.items">
<td style="width: 100%;">
<i class="{{acl.icon}}"></i>
<span ng-bind-html="acl.nameHtml"></span>
......
......@@ -6,7 +6,7 @@ import _ from 'lodash';
export class AclCtrl {
dashboard: any;
aclItems: DashboardAcl[];
items: DashboardAcl[];
permissionOptions = [
{value: 1, text: 'View'},
{value: 2, text: 'Edit'},
......@@ -19,12 +19,13 @@ export class AclCtrl {
{value: 'Editor', text: 'Everyone With Editor Role'}
];
dismiss: () => void;
newType: string;
canUpdate: boolean;
/** @ngInject */
constructor(private backendSrv, private dashboardSrv, private $sce, private $scope) {
this.aclItems = [];
this.items = [];
this.resetNewType();
this.dashboard = dashboardSrv.getCurrent();
this.get(this.dashboard.id);
......@@ -37,7 +38,7 @@ export class AclCtrl {
get(dashboardId: number) {
return this.backendSrv.get(`/api/dashboards/id/${dashboardId}/acl`)
.then(result => {
this.aclItems = _.map(result, this.prepareViewModel.bind(this));
this.items = _.map(result, this.prepareViewModel.bind(this));
});
}
......@@ -58,7 +59,7 @@ export class AclCtrl {
update() {
return this.backendSrv.post(`/api/dashboards/id/${this.dashboard.id}/acl`, {
acl: this.aclItems.map(item => {
items: this.items.map(item => {
return {
id: item.id,
userId: item.userId,
......@@ -67,12 +68,14 @@ export class AclCtrl {
permission: item.permission,
};
})
}).then(() => {
this.dismiss();
});
}
typeChanged() {
if (this.newType === 'Viewer' || this.newType === 'Editor') {
this.aclItems.push(this.prepareViewModel({
this.items.push(this.prepareViewModel({
permission: 1,
role: this.newType
}));
......@@ -87,7 +90,7 @@ export class AclCtrl {
}
userPicked(user) {
this.aclItems.push(this.prepareViewModel({
this.items.push(this.prepareViewModel({
userId: user.id,
userLogin: user.login,
permission: 1,
......@@ -99,7 +102,7 @@ export class AclCtrl {
groupPicked(group) {
console.log(group);
this.aclItems.push(this.prepareViewModel({
this.items.push(this.prepareViewModel({
userGroupId: group.id,
userGroup: group.name,
permission: 1,
......@@ -110,7 +113,7 @@ export class AclCtrl {
}
removeItem(index) {
this.aclItems.splice(index, 1);
this.items.splice(index, 1);
this.canUpdate = true;
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment