useIsRuleEditable.ts 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. import { contextSrv } from 'app/core/services/context_srv';
  2. import { RulerRuleDTO } from 'app/types/unified-alerting-dto';
  3. import { getRulesPermissions } from '../utils/access-control';
  4. import { isGrafanaRulerRule } from '../utils/rules';
  5. import { useFolder } from './useFolder';
  6. import { useUnifiedAlertingSelector } from './useUnifiedAlertingSelector';
  7. interface ResultBag {
  8. isEditable?: boolean;
  9. isRemovable?: boolean;
  10. loading: boolean;
  11. }
  12. export function useIsRuleEditable(rulesSourceName: string, rule?: RulerRuleDTO): ResultBag {
  13. const dataSources = useUnifiedAlertingSelector((state) => state.dataSources);
  14. const folderUID = rule && isGrafanaRulerRule(rule) ? rule.grafana_alert.namespace_uid : undefined;
  15. const rulePermission = getRulesPermissions(rulesSourceName);
  16. const { folder, loading } = useFolder(folderUID);
  17. if (!rule) {
  18. return { isEditable: false, isRemovable: false, loading: false };
  19. }
  20. // Grafana rules can be edited if user can edit the folder they're in
  21. // When RBAC is disabled access to a folder is the only requirement for managing rules
  22. // When RBAC is enabled the appropriate alerting permissions need to be met
  23. if (isGrafanaRulerRule(rule)) {
  24. if (!folderUID) {
  25. throw new Error(
  26. `Rule ${rule.grafana_alert.title} does not have a folder uid, cannot determine if it is editable.`
  27. );
  28. }
  29. const canEditGrafanaRules = contextSrv.hasAccess(rulePermission.update, folder?.canSave ?? false);
  30. const canRemoveGrafanaRules = contextSrv.hasAccess(rulePermission.delete, folder?.canSave ?? false);
  31. return {
  32. isEditable: canEditGrafanaRules,
  33. isRemovable: canRemoveGrafanaRules,
  34. loading,
  35. };
  36. }
  37. // prom rules are only editable by users with Editor role and only if rules source supports editing
  38. const isRulerAvailable = Boolean(dataSources[rulesSourceName]?.result?.rulerConfig);
  39. const canEditCloudRules = contextSrv.hasAccess(rulePermission.update, contextSrv.isEditor);
  40. const canRemoveCloudRules = contextSrv.hasAccess(rulePermission.delete, contextSrv.isEditor);
  41. return {
  42. isEditable: canEditCloudRules && isRulerAvailable,
  43. isRemovable: canRemoveCloudRules && isRulerAvailable,
  44. loading: dataSources[rulesSourceName]?.loading,
  45. };
  46. }