Ver código fonte

acl: more acl work

Torkel Ödegaard 8 anos atrás
pai
commit
a82b25eb79

+ 9 - 3
pkg/services/sqlstore/dashboard_acl.go

@@ -1,6 +1,7 @@
 package sqlstore
 
 import (
+	"fmt"
 	"time"
 
 	"github.com/grafana/grafana/pkg/bus"
@@ -148,6 +149,12 @@ func GetInheritedDashboardAcl(query *m.GetInheritedDashboardAclQuery) 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 := `
 	SELECT
 		da.id,
@@ -165,7 +172,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 = ?
+	WHERE dashboard_id ` + dashboardFilter + `
 
 	-- Also include default permission if has_acl = 0
 
@@ -188,8 +195,7 @@ func GetDashboardAclInfoList(query *m.GetDashboardAclInfoListQuery) error {
 	`
 
 	query.Result = make([]*m.DashboardAclInfoDTO, 0)
-
-	err := x.SQL(rawSQL, query.DashboardId, query.DashboardId).Find(&query.Result)
+	err := x.SQL(rawSQL, query.DashboardId).Find(&query.Result)
 
 	for _, p := range query.Result {
 		p.PermissionName = p.Permission.String()

+ 6 - 3
public/app/features/dashboard/acl/acl.html

@@ -12,19 +12,22 @@
 
   <div class="modal-content">
     <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%;">
           <i class="{{acl.icon}}"></i>
           <span ng-bind-html="acl.nameHtml"></span>
         </td>
+        <td>
+          <em class="muted no-wrap" ng-show="acl.inherited">Inherited from folder</em>
+        </td>
         <td class="query-keyword">Can</td>
         <td>
           <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>
         </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>
           </a>
         </td>

+ 56 - 26
public/app/features/dashboard/acl/acl.ts

@@ -39,36 +39,67 @@ export class AclCtrl {
     return this.backendSrv.get(`/api/dashboards/id/${dashboardId}/acl`)
       .then(result => {
         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 {
+    item.inherited = this.dashboard.id !== item.dashboardId;
+    item.sortRank = 0;
+
     if (item.userId > 0) {
       item.icon = "fa fa-fw fa-user";
       item.nameHtml = this.$sce.trustAsHtml(item.userLogin);
+      item.sortName = item.userLogin;
+      item.sortRank = 10;
     } else if (item.userGroupId > 0) {
       item.icon = "fa fa-fw fa-users";
       item.nameHtml = this.$sce.trustAsHtml(item.userGroup);
+      item.sortName = item.userGroup;
+      item.sortRank = 20;
     } else if (item.role) {
       item.icon = "fa fa-fw fa-street-view";
       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;
   }
 
   update() {
-    return this.backendSrv.post(`/api/dashboards/id/${this.dashboard.id}/acl`, {
-      items: this.items.map(item => {
-        return {
-          id: item.id,
-          userId: item.userId,
-          userGroupId: item.userGroupId,
-          role: item.role,
-          permission: item.permission,
-        };
-      })
-    }).then(() => {
+    var updated = [];
+    for (let item of this.items) {
+      if (item.inherited) {
+        continue;
+      }
+      updated.push({
+        id: item.id,
+        userId: item.userId,
+        userGroupId: item.userGroupId,
+        role: item.role,
+        permission: item.permission,
+      });
+    }
+
+    return this.backendSrv.post(`/api/dashboards/id/${this.dashboard.id}/acl`, { items: updated }).then(() => {
       this.dismiss();
     });
   }
@@ -89,26 +120,22 @@ export class AclCtrl {
     this.canUpdate = true;
   }
 
-  userPicked(user) {
-    this.items.push(this.prepareViewModel({
-      userId: user.id,
-      userLogin: user.login,
-      permission: 1,
-    }));
+  addNewItem(item) {
+    item.dashboardId = this.dashboard.id;
+
+    this.items.push(this.prepareViewModel(item));
+    this.sortItems();
 
     this.canUpdate = true;
+  }
+
+  userPicked(user) {
+    this.addNewItem({userId: user.id, userLogin: user.login, permission: 1,});
     this.$scope.$broadcast('user-picker-reset');
   }
 
   groupPicked(group) {
-    console.log(group);
-    this.items.push(this.prepareViewModel({
-      userGroupId: group.id,
-      userGroup: group.name,
-      permission: 1,
-    }));
-
-    this.canUpdate = true;
+    this.addNewItem({userGroupId: group.id, userGroup: group.name, permission: 1});
     this.$scope.$broadcast('user-group-picker-reset');
   }
 
@@ -142,7 +169,7 @@ export interface DashboardAcl {
   id?: number;
   dashboardId?: number;
   userId?: number;
-  userLogin?: number;
+  userLogin?: string;
   userEmail?: string;
   userGroupId?: number;
   userGroup?: string;
@@ -151,6 +178,9 @@ export interface DashboardAcl {
   role?: string;
   icon?: string;
   nameHtml?: string;
+  inherited?: boolean;
+  sortName?: string;
+  sortRank?: number;
 }
 
 coreModule.directive('dashAclModal', dashAclModal);

+ 4 - 0
public/sass/base/_type.scss

@@ -333,3 +333,7 @@ a.external-link {
   }
 }
 
+.no-wrap {
+  white-space: nowrap;
+}
+

+ 8 - 9
public/sass/components/_gf-form.scss

@@ -21,7 +21,6 @@ $gf-form-margin: 0.25rem;
 .gf-form-disabled {
   color: $text-color-weak;
 
-  .query-keyword,
   a,
   .gf-form-input {
     color: $text-color-weak;
@@ -101,7 +100,6 @@ $gf-form-margin: 0.25rem;
   display: block;
   width: 100%;
   padding: $input-padding-y $input-padding-x;
-  margin-right: $gf-form-margin;
   font-size: $font-size-base;
   margin-right: $gf-form-margin;
   line-height: $input-line-height;
@@ -153,10 +151,11 @@ $gf-form-margin: 0.25rem;
 
     &::after {
       position: absolute;
-      top: 35%;
-      right: $input-padding-x;
+      top: 36%;
+      right: 11px;
+      font-size: 11px;
       background-color: transparent;
-      color: $input-color;
+      color: $text-color;
       font: normal normal normal $font-size-sm/1 FontAwesome;
       content: '\f0d7';
       pointer-events: none;
@@ -177,7 +176,6 @@ $gf-form-margin: 0.25rem;
 .gf-form-select-wrapper {
   margin-right: $gf-form-margin;
   position: relative;
-  background-color: $input-bg;
 
   select.gf-form-input {
     text-indent: .01px;
@@ -200,13 +198,14 @@ $gf-form-margin: 0.25rem;
 
   &::after {
     position: absolute;
-    top: 35%;
-    right: $input-padding-x/2;
+    top: 36%;
+    right: 11px;
     background-color: transparent;
-    color: $input-color;
+    color: $text-color;
     font: normal normal normal $font-size-sm/1 FontAwesome;
     content: '\f0d7';
     pointer-events: none;
+    font-size: 11px;
   }
 
   &--has-help-icon {

+ 6 - 0
public/sass/components/_query_editor.scss

@@ -3,6 +3,12 @@
   color: $blue;
 }
 
+.gf-form-disabled {
+  .query-keyword {
+    color: darken($blue, 20%);
+  }
+}
+
 .query-segment-key {
   //border-right: none;
   //padding-right: 1px;