acl.ts 4.8 KB

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