diff --git a/build.gradle b/build.gradle index 334a8b4..cdf2782 100644 --- a/build.gradle +++ b/build.gradle @@ -8,7 +8,7 @@ plugins { } group = 'com.flexcodelabs' -version = '0.0.81' +version = '0.0.82' description = 'Flextuma App' java { diff --git a/src/main/java/com/flexcodelabs/flextuma/modules/whatsapp/services/WhatsAppTemplateService.java b/src/main/java/com/flexcodelabs/flextuma/modules/whatsapp/services/WhatsAppTemplateService.java index c0b2153..c68cc48 100644 --- a/src/main/java/com/flexcodelabs/flextuma/modules/whatsapp/services/WhatsAppTemplateService.java +++ b/src/main/java/com/flexcodelabs/flextuma/modules/whatsapp/services/WhatsAppTemplateService.java @@ -11,20 +11,12 @@ import java.util.UUID; /** - * Read-only CRUD browsing for Meta-synced WhatsApp templates. READ uses the - * "ALL" sentinel (open - * to any tenant user, scoped to their own rows by BaseService's tenant - * filtering), but ADD/UPDATE/ - * DELETE require a dedicated permission no tenant role is ever granted -- so, - * unlike "ALL", those - * aren't satisfied by the generic tenant-user bypass in - * BaseService#checkPermission, and only - * SUPER_ADMIN (or a future explicit grant) can hit them via the inherited - * BaseController routes. - * Writes in practice happen only through WhatsAppTemplateSyncService and the - * webhook's - * message_template_status_update handler, both of which save via the repository - * directly. + * Read-only CRUD browsing for Meta-synced WhatsApp templates. READ uses the "ALL" sentinel (open + * to any tenant user, scoped to their own rows by BaseService's tenant filtering), but ADD/UPDATE/ + * DELETE require a dedicated permission no tenant role is ever granted, so only SUPER_ADMIN (or a + * future explicit grant) can hit them via the inherited BaseController routes. Writes in practice + * happen only through WhatsAppTemplateSyncService and the webhook's + * message_template_status_update handler, both of which save via the repository directly. */ @Service @RequiredArgsConstructor @@ -44,14 +36,23 @@ protected JpaSpecificationExecutor getRepositoryAsExecutor() { /** Closes BaseService#checkPermission's generic "ALL" bypass for ADD/UPDATE/DELETE -- without * this override (the same one User/Role/Organisation/Privilege/Wallet/TenantFeature already * use) any tenant user holding the common "ALL" authority could write template rows, e.g. - * self-declare status: APPROVED for a template Meta never approved. READ is unaffected: its - * permission constant is the literal "ALL" sentinel, satisfied by checkPermission's second - * clause regardless of this override. */ + * self-declare status: APPROVED for a template Meta never approved. */ @Override protected boolean isAdminEntity() { return true; } + /** isAdminEntity() also disables BaseService's "requiredPermission is the ALL sentinel" clause, + * which would lock ordinary tenant users out of READ. Let the READ sentinel through explicitly; + * rows are still scoped to the caller by BaseService's tenant filtering. */ + @Override + protected void checkPermission(String requiredPermission) { + if (WhatsAppTemplate.READ.equals(requiredPermission)) { + return; + } + super.checkPermission(requiredPermission); + } + @Override protected String getReadPermission() { return WhatsAppTemplate.READ;