Commit a82b25eb by Torkel Ödegaard

acl: more acl work

parent 446104d1
package sqlstore package sqlstore
import ( import (
"fmt"
"time" "time"
"github.com/grafana/grafana/pkg/bus" "github.com/grafana/grafana/pkg/bus"
...@@ -148,6 +149,12 @@ func GetInheritedDashboardAcl(query *m.GetInheritedDashboardAclQuery) error { ...@@ -148,6 +149,12 @@ func GetInheritedDashboardAcl(query *m.GetInheritedDashboardAclQuery) error {
} }
func GetDashboardAclInfoList(query *m.GetDashboardAclInfoListQuery) error { func GetDashboardAclInfoList(query *m.GetDashboardAclInfoListQuery) error {
dashboardFilter := fmt.Sprintf(`IN (
SELECT id FROM dashboard where id = %d
UNION
SELECT parent_id from dashboard where id = %d
)`, query.DashboardId, query.DashboardId)
rawSQL := ` rawSQL := `
SELECT SELECT
da.id, da.id,
...@@ -165,7 +172,7 @@ func GetDashboardAclInfoList(query *m.GetDashboardAclInfoListQuery) error { ...@@ -165,7 +172,7 @@ func GetDashboardAclInfoList(query *m.GetDashboardAclInfoListQuery) error {
FROM` + dialect.Quote("dashboard_acl") + ` as da FROM` + dialect.Quote("dashboard_acl") + ` as da
LEFT OUTER JOIN ` + dialect.Quote("user") + ` AS u ON u.id = da.user_id 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 LEFT OUTER JOIN user_group ug on ug.id = da.user_group_id
WHERE dashboard_id = ? WHERE dashboard_id ` + dashboardFilter + `
-- Also include default permission if has_acl = 0 -- Also include default permission if has_acl = 0
...@@ -188,8 +195,7 @@ func GetDashboardAclInfoList(query *m.GetDashboardAclInfoListQuery) error { ...@@ -188,8 +195,7 @@ func GetDashboardAclInfoList(query *m.GetDashboardAclInfoListQuery) error {
` `
query.Result = make([]*m.DashboardAclInfoDTO, 0) query.Result = make([]*m.DashboardAclInfoDTO, 0)
err := x.SQL(rawSQL, query.DashboardId).Find(&query.Result)
err := x.SQL(rawSQL, query.DashboardId, query.DashboardId).Find(&query.Result)
for _, p := range query.Result { for _, p := range query.Result {
p.PermissionName = p.Permission.String() p.PermissionName = p.Permission.String()
......
...@@ -12,19 +12,22 @@ ...@@ -12,19 +12,22 @@
<div class="modal-content"> <div class="modal-content">
<table class="filter-table gf-form-group"> <table class="filter-table gf-form-group">
<tr ng-repeat="acl in ctrl.items"> <tr ng-repeat="acl in ctrl.items" ng-class="{'gf-form-disabled': acl.inherited}">
<td style="width: 100%;"> <td style="width: 100%;">
<i class="{{acl.icon}}"></i> <i class="{{acl.icon}}"></i>
<span ng-bind-html="acl.nameHtml"></span> <span ng-bind-html="acl.nameHtml"></span>
</td> </td>
<td>
<em class="muted no-wrap" ng-show="acl.inherited">Inherited from folder</em>
</td>
<td class="query-keyword">Can</td> <td class="query-keyword">Can</td>
<td> <td>
<div class="gf-form-select-wrapper"> <div class="gf-form-select-wrapper">
<select class="gf-form-input gf-size-auto" ng-model="acl.permission" ng-options="p.value as p.text for p in ctrl.permissionOptions" ng-change="ctrl.permissionChanged(acl)"></select> <select class="gf-form-input gf-size-auto" ng-model="acl.permission" ng-options="p.value as p.text for p in ctrl.permissionOptions" ng-change="ctrl.permissionChanged(acl)" ng-disabled="acl.inherited"></select>
</div> </div>
</td> </td>
<td> <td>
<a class="btn btn-inverse btn-small" ng-click="ctrl.removeItem($index)"> <a class="btn btn-inverse btn-small" ng-click="ctrl.removeItem($index)" ng-hide="acl.inherited">
<i class="fa fa-remove"></i> <i class="fa fa-remove"></i>
</a> </a>
</td> </td>
......
...@@ -39,36 +39,67 @@ export class AclCtrl { ...@@ -39,36 +39,67 @@ export class AclCtrl {
return this.backendSrv.get(`/api/dashboards/id/${dashboardId}/acl`) return this.backendSrv.get(`/api/dashboards/id/${dashboardId}/acl`)
.then(result => { .then(result => {
this.items = _.map(result, this.prepareViewModel.bind(this)); this.items = _.map(result, this.prepareViewModel.bind(this));
this.sortItems();
}); });
} }
sortItems() {
this.items = _.orderBy(this.items, ['sortRank', 'sortName'], ['desc', 'asc']);
for (let i of this.items) {
console.log(i.sortRank);
}
}
prepareViewModel(item: DashboardAcl): DashboardAcl { prepareViewModel(item: DashboardAcl): DashboardAcl {
item.inherited = this.dashboard.id !== item.dashboardId;
item.sortRank = 0;
if (item.userId > 0) { if (item.userId > 0) {
item.icon = "fa fa-fw fa-user"; item.icon = "fa fa-fw fa-user";
item.nameHtml = this.$sce.trustAsHtml(item.userLogin); item.nameHtml = this.$sce.trustAsHtml(item.userLogin);
item.sortName = item.userLogin;
item.sortRank = 10;
} else if (item.userGroupId > 0) { } else if (item.userGroupId > 0) {
item.icon = "fa fa-fw fa-users"; item.icon = "fa fa-fw fa-users";
item.nameHtml = this.$sce.trustAsHtml(item.userGroup); item.nameHtml = this.$sce.trustAsHtml(item.userGroup);
item.sortName = item.userGroup;
item.sortRank = 20;
} else if (item.role) { } else if (item.role) {
item.icon = "fa fa-fw fa-street-view"; item.icon = "fa fa-fw fa-street-view";
item.nameHtml = this.$sce.trustAsHtml(`Everyone with <span class="query-keyword">${item.role}</span> Role`); item.nameHtml = this.$sce.trustAsHtml(`Everyone with <span class="query-keyword">${item.role}</span> Role`);
item.sortName = item.role;
item.sortRank = 30;
if (item.role === 'Viewer') {
item.sortRank += 2;
}
if (item.role === 'Viewer') {
item.sortRank += 1;
}
}
if (item.inherited) {
item.sortRank += 100;
} }
return item; return item;
} }
update() { update() {
return this.backendSrv.post(`/api/dashboards/id/${this.dashboard.id}/acl`, { var updated = [];
items: this.items.map(item => { for (let item of this.items) {
return { if (item.inherited) {
id: item.id, continue;
userId: item.userId, }
userGroupId: item.userGroupId, updated.push({
role: item.role, id: item.id,
permission: item.permission, userId: item.userId,
}; userGroupId: item.userGroupId,
}) role: item.role,
}).then(() => { permission: item.permission,
});
}
return this.backendSrv.post(`/api/dashboards/id/${this.dashboard.id}/acl`, { items: updated }).then(() => {
this.dismiss(); this.dismiss();
}); });
} }
...@@ -89,26 +120,22 @@ export class AclCtrl { ...@@ -89,26 +120,22 @@ export class AclCtrl {
this.canUpdate = true; this.canUpdate = true;
} }
userPicked(user) { addNewItem(item) {
this.items.push(this.prepareViewModel({ item.dashboardId = this.dashboard.id;
userId: user.id,
userLogin: user.login, this.items.push(this.prepareViewModel(item));
permission: 1, this.sortItems();
}));
this.canUpdate = true; this.canUpdate = true;
}
userPicked(user) {
this.addNewItem({userId: user.id, userLogin: user.login, permission: 1,});
this.$scope.$broadcast('user-picker-reset'); this.$scope.$broadcast('user-picker-reset');
} }
groupPicked(group) { groupPicked(group) {
console.log(group); this.addNewItem({userGroupId: group.id, userGroup: group.name, permission: 1});
this.items.push(this.prepareViewModel({
userGroupId: group.id,
userGroup: group.name,
permission: 1,
}));
this.canUpdate = true;
this.$scope.$broadcast('user-group-picker-reset'); this.$scope.$broadcast('user-group-picker-reset');
} }
...@@ -142,7 +169,7 @@ export interface DashboardAcl { ...@@ -142,7 +169,7 @@ export interface DashboardAcl {
id?: number; id?: number;
dashboardId?: number; dashboardId?: number;
userId?: number; userId?: number;
userLogin?: number; userLogin?: string;
userEmail?: string; userEmail?: string;
userGroupId?: number; userGroupId?: number;
userGroup?: string; userGroup?: string;
...@@ -151,6 +178,9 @@ export interface DashboardAcl { ...@@ -151,6 +178,9 @@ export interface DashboardAcl {
role?: string; role?: string;
icon?: string; icon?: string;
nameHtml?: string; nameHtml?: string;
inherited?: boolean;
sortName?: string;
sortRank?: number;
} }
coreModule.directive('dashAclModal', dashAclModal); coreModule.directive('dashAclModal', dashAclModal);
...@@ -333,3 +333,7 @@ a.external-link { ...@@ -333,3 +333,7 @@ a.external-link {
} }
} }
.no-wrap {
white-space: nowrap;
}
...@@ -21,7 +21,6 @@ $gf-form-margin: 0.25rem; ...@@ -21,7 +21,6 @@ $gf-form-margin: 0.25rem;
.gf-form-disabled { .gf-form-disabled {
color: $text-color-weak; color: $text-color-weak;
.query-keyword,
a, a,
.gf-form-input { .gf-form-input {
color: $text-color-weak; color: $text-color-weak;
...@@ -101,7 +100,6 @@ $gf-form-margin: 0.25rem; ...@@ -101,7 +100,6 @@ $gf-form-margin: 0.25rem;
display: block; display: block;
width: 100%; width: 100%;
padding: $input-padding-y $input-padding-x; padding: $input-padding-y $input-padding-x;
margin-right: $gf-form-margin;
font-size: $font-size-base; font-size: $font-size-base;
margin-right: $gf-form-margin; margin-right: $gf-form-margin;
line-height: $input-line-height; line-height: $input-line-height;
...@@ -153,10 +151,11 @@ $gf-form-margin: 0.25rem; ...@@ -153,10 +151,11 @@ $gf-form-margin: 0.25rem;
&::after { &::after {
position: absolute; position: absolute;
top: 35%; top: 36%;
right: $input-padding-x; right: 11px;
font-size: 11px;
background-color: transparent; background-color: transparent;
color: $input-color; color: $text-color;
font: normal normal normal $font-size-sm/1 FontAwesome; font: normal normal normal $font-size-sm/1 FontAwesome;
content: '\f0d7'; content: '\f0d7';
pointer-events: none; pointer-events: none;
...@@ -177,7 +176,6 @@ $gf-form-margin: 0.25rem; ...@@ -177,7 +176,6 @@ $gf-form-margin: 0.25rem;
.gf-form-select-wrapper { .gf-form-select-wrapper {
margin-right: $gf-form-margin; margin-right: $gf-form-margin;
position: relative; position: relative;
background-color: $input-bg;
select.gf-form-input { select.gf-form-input {
text-indent: .01px; text-indent: .01px;
...@@ -200,13 +198,14 @@ $gf-form-margin: 0.25rem; ...@@ -200,13 +198,14 @@ $gf-form-margin: 0.25rem;
&::after { &::after {
position: absolute; position: absolute;
top: 35%; top: 36%;
right: $input-padding-x/2; right: 11px;
background-color: transparent; background-color: transparent;
color: $input-color; color: $text-color;
font: normal normal normal $font-size-sm/1 FontAwesome; font: normal normal normal $font-size-sm/1 FontAwesome;
content: '\f0d7'; content: '\f0d7';
pointer-events: none; pointer-events: none;
font-size: 11px;
} }
&--has-help-icon { &--has-help-icon {
......
...@@ -3,6 +3,12 @@ ...@@ -3,6 +3,12 @@
color: $blue; color: $blue;
} }
.gf-form-disabled {
.query-keyword {
color: darken($blue, 20%);
}
}
.query-segment-key { .query-segment-key {
//border-right: none; //border-right: none;
//padding-right: 1px; //padding-right: 1px;
......
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