acl.ts 4.9 KB

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