acl.ts 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. ///<reference path="../../../headers/common.d.ts" />
  2. import coreModule from 'app/core/core_module';
  3. import _ from 'lodash';
  4. export class AclCtrl {
  5. dashboard: any;
  6. items: DashboardAcl[];
  7. permissionOptions = [{ value: 1, text: 'View' }, { value: 2, text: 'Edit' }, { value: 4, text: 'Admin' }];
  8. aclTypes = [
  9. { value: 'Group', text: 'Team' },
  10. { value: 'User', text: 'User' },
  11. { value: 'Viewer', text: 'Everyone With Viewer Role' },
  12. { value: 'Editor', text: 'Everyone With Editor Role' },
  13. ];
  14. dismiss: () => void;
  15. newType: string;
  16. canUpdate: boolean;
  17. error: string;
  18. readonly duplicateError = 'This permission exists already.';
  19. /** @ngInject */
  20. constructor(private backendSrv, dashboardSrv, private $sce, private $scope) {
  21. this.items = [];
  22. this.resetNewType();
  23. this.dashboard = dashboardSrv.getCurrent();
  24. this.get(this.dashboard.id);
  25. }
  26. resetNewType() {
  27. this.newType = 'Group';
  28. }
  29. get(dashboardId: number) {
  30. return this.backendSrv.get(`/api/dashboards/id/${dashboardId}/acl`).then(result => {
  31. this.items = _.map(result, this.prepareViewModel.bind(this));
  32. this.sortItems();
  33. });
  34. }
  35. sortItems() {
  36. this.items = _.orderBy(this.items, ['sortRank', 'sortName'], ['desc', 'asc']);
  37. }
  38. prepareViewModel(item: DashboardAcl): DashboardAcl {
  39. item.inherited = !this.dashboard.meta.isFolder && this.dashboard.id !== item.dashboardId;
  40. item.sortRank = 0;
  41. if (item.userId > 0) {
  42. item.icon = 'fa fa-fw fa-user';
  43. item.nameHtml = this.$sce.trustAsHtml(item.userLogin);
  44. item.sortName = item.userLogin;
  45. item.sortRank = 10;
  46. } else if (item.teamId > 0) {
  47. item.icon = 'fa fa-fw fa-users';
  48. item.nameHtml = this.$sce.trustAsHtml(item.team);
  49. item.sortName = item.team;
  50. item.sortRank = 20;
  51. } else if (item.role) {
  52. item.icon = 'fa fa-fw fa-street-view';
  53. item.nameHtml = this.$sce.trustAsHtml(`Everyone with <span class="query-keyword">${item.role}</span> Role`);
  54. item.sortName = item.role;
  55. item.sortRank = 30;
  56. if (item.role === 'Viewer') {
  57. item.sortRank += 1;
  58. }
  59. }
  60. if (item.inherited) {
  61. item.sortRank += 100;
  62. }
  63. return item;
  64. }
  65. update() {
  66. var updated = [];
  67. for (let item of this.items) {
  68. if (item.inherited) {
  69. continue;
  70. }
  71. updated.push({
  72. id: item.id,
  73. userId: item.userId,
  74. teamId: item.teamId,
  75. role: item.role,
  76. permission: item.permission,
  77. });
  78. }
  79. return this.backendSrv.post(`/api/dashboards/id/${this.dashboard.id}/acl`, { items: updated }).then(() => {
  80. return this.dismiss();
  81. });
  82. }
  83. typeChanged() {
  84. if (this.newType === 'Viewer' || this.newType === 'Editor') {
  85. this.addNewItem({ permission: 1, role: this.newType });
  86. this.canUpdate = true;
  87. this.resetNewType();
  88. }
  89. }
  90. permissionChanged() {
  91. this.canUpdate = true;
  92. }
  93. addNewItem(item) {
  94. if (!this.isValid(item)) {
  95. return;
  96. }
  97. this.error = '';
  98. item.dashboardId = this.dashboard.id;
  99. this.items.push(this.prepareViewModel(item));
  100. this.sortItems();
  101. this.canUpdate = true;
  102. }
  103. isValid(item) {
  104. const dupe = _.find(this.items, it => {
  105. return this.isDuplicate(it, item);
  106. });
  107. if (dupe) {
  108. this.error = this.duplicateError;
  109. return false;
  110. }
  111. return true;
  112. }
  113. isDuplicate(origItem, newItem) {
  114. if (origItem.inherited) {
  115. return false;
  116. }
  117. return (
  118. (origItem.role && newItem.role && origItem.role === newItem.role) ||
  119. (origItem.userId && newItem.userId && origItem.userId === newItem.userId) ||
  120. (origItem.teamId && newItem.teamId && origItem.teamId === newItem.teamId)
  121. );
  122. }
  123. userPicked(user) {
  124. this.addNewItem({ userId: user.id, userLogin: user.login, permission: 1 });
  125. this.$scope.$broadcast('user-picker-reset');
  126. }
  127. groupPicked(group) {
  128. this.addNewItem({ teamId: group.id, team: group.name, permission: 1 });
  129. this.$scope.$broadcast('team-picker-reset');
  130. }
  131. removeItem(index) {
  132. this.items.splice(index, 1);
  133. this.canUpdate = true;
  134. }
  135. }
  136. export function dashAclModal() {
  137. return {
  138. restrict: 'E',
  139. templateUrl: 'public/app/features/dashboard/acl/acl.html',
  140. controller: AclCtrl,
  141. bindToController: true,
  142. controllerAs: 'ctrl',
  143. scope: {
  144. dismiss: '&',
  145. },
  146. };
  147. }
  148. export interface FormModel {
  149. dashboardId: number;
  150. userId?: number;
  151. teamId?: number;
  152. PermissionType: number;
  153. }
  154. export interface DashboardAcl {
  155. id?: number;
  156. dashboardId?: number;
  157. userId?: number;
  158. userLogin?: string;
  159. userEmail?: string;
  160. teamId?: number;
  161. team?: string;
  162. permission?: number;
  163. permissionName?: string;
  164. role?: string;
  165. icon?: string;
  166. nameHtml?: string;
  167. inherited?: boolean;
  168. sortName?: string;
  169. sortRank?: number;
  170. }
  171. coreModule.directive('dashAclModal', dashAclModal);