14. Permissions
14.1 Two separate permission catalogs
| Catalog | Class | Used by |
|---|---|---|
| Active framework | PermissionConstants (Shumoul.Domain\Constants\PermissionConstants.cs) | All 12 controllers in §9.1–9.12 |
| Legacy MultiTenancyApi | TenancyPermissions (Shumoul.Framework.MultiTenancy.Api\Constants\TenancyPermissions.cs) | The 5 legacy controllers in §9.13 |
A mirror copy of the active catalog's permission strings also ships as
Shumoul.Notification.Contracts.Permissions.NotificationPermissions for framework-package consumers that
don't reference Shumoul.Domain directly.
14.2 PermissionConstants — full catalog
| Nested class | Permissions |
|---|---|
AppNotifications | View, ViewAll (unused by any controller action — reserved), Delete, MarkRead |
AppNotificationTemplates | View, ViewAll, Create, Edit, Delete, Active, Deactive |
DeviceTokens | View, ViewAll, Register, Edit, Delete, Active, Deactive |
NotificationEventConfigurations | View, ViewAll, Create, Edit, Delete, Active, Deactive |
NotificationDeliveryPolicies | View, ViewAll, Create, Edit, Delete, Active, Deactive |
NotificationRetryQueues | View, ViewAll, RetryNow, Cancel |
NotificationDeadLetters | View, ViewAll, Requeue, Cancel, Delete |
NotificationAnalytics | View, ViewAll |
NotificationReceipts | View, ViewAll, Export (unused by any controller action — reserved) |
NotificationCampaigns | View, ViewAll, Create, Edit, Delete, Execute (unused — reserved), Cancel, Schedule, Analytics, Approve (unused — reserved), DryRun, Preview, Manage |
NotificationHistory | View, ViewAll, Retry |
"Unused — reserved" permissions are real constants that exist in code today but are not checked by any
[MustHavePermission] attribute found in this framework's controllers. They may be intended for a future
endpoint, or checked programmatically elsewhere outside the controllers documented here — do not assume they
are dead code without confirming against current source before removing them.
14.3 TenancyPermissions — legacy catalog
| Nested class | Permissions | Enforcement status |
|---|---|---|
Notifications | ViewAll, View, Create, Edit, Delete | Enforced — NotificationsController |
NotificationTemplates | ViewAll, View, Create, Edit, Delete | Enforced — NotificationTemplatesController |
NotificationTopics | ViewAll, View, Create, Edit, Delete | ⚠ Not enforced — every [MustHavePermission] referencing these is commented out in NotificationTopicsController; see §9.13.3 |
NotificationTopicSubscribers | Subscribe, Unsubscribe | ⚠ Not enforced — same as above, see §9.13.4 |
14.4 Where each permission is checked
Every active-framework endpoint applies [MustHavePermission("Permissions.{Class}.{Action}")] directly on
the controller action — see the per-endpoint tables throughout Chapter 9 for
the exact permission string per route. [Authorize] on the controller/base class only proves the caller is
authenticated; [MustHavePermission] is the authorization check.
14.5 Required roles
This documentation does not assert a specific role→permission mapping (e.g. "Admin has X, Manager has Y") —
role-to-permission assignment is tenant-configurable data (ApplicationRoleClaim rows with
ClaimType = "Permission"), not a fixed constant. Consult your tenant's role configuration screen (or the
platform's identity/role management API, out of scope for this document) to see which roles currently carry
which of the permissions listed above.
14.6 Practical guidance for API consumers
- Always request the specific permission you need in your integration's service-account role — do not
request
ViewAll/Manage-level permissions for read-only integrations; use the narrowest permission that satisfies the endpoint (e.g.NotificationCampaigns.Analytics, notNotificationCampaigns.Manage, for a reporting integration). - If you build against a reserved-but-unused permission constant (
AppNotifications.ViewAll,NotificationCampaigns.Execute/Approve,NotificationReceipts.Export), confirm with the platform team first — it may not be wired to any endpoint yet.