From aade6bb2ae5b3abcab1b742a0ec32af0d53123ef Mon Sep 17 00:00:00 2001 From: James Maes Date: Fri, 16 Oct 2026 14:30:54 -0500 Subject: [PATCH] test(routing): recipient checks have exactly the recipient's access Owner decision 2026-10-16 (QQQ DelegatedAccess.USER): the alerts principal's checks see what the recipient sees. Needs the QQQ RC with qqq#1265. Co-Authored-By: Claude Opus 5.5 --- .../alerts/AlertsServicePrincipalTest.java | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/test/java/com/kingsrook/qbits/alerts/AlertsServicePrincipalTest.java b/src/test/java/com/kingsrook/qbits/alerts/AlertsServicePrincipalTest.java index 3d3904a..a10a6c6 100644 --- a/src/test/java/com/kingsrook/qbits/alerts/AlertsServicePrincipalTest.java +++ b/src/test/java/com/kingsrook/qbits/alerts/AlertsServicePrincipalTest.java @@ -49,4 +49,41 @@ class AlertsServicePrincipalTest extends BaseAlertsTest assertThat(ServiceIdentities.principalOf(after)).isEqualTo("alerts"); assertThat(ServiceIdentities.attributionName(after)).endsWith("via service:alerts"); } + + + + /******************************************************************************* + ** Owner decision 2026-10-16: a recipient check sees exactly what the + ** recipient can see - the recipient's own permissions and record-lock keys, + ** even though the alerts principal itself holds nothing. + *******************************************************************************/ + @Test + void recipientCheckHasExactlyTheRecipientsAccess() throws Exception + { + qInstance.getAuthentication().setCustomizer(new com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference(RecipientCustomizer.class)); + ServiceIdentitiesMetaData.declare(qInstance, new QServicePrincipalMetaData().withName("alerts").withMayActOnBehalfOfUsers(true)); + + QSession own = new com.kingsrook.qqq.backend.core.modules.authentication.implementations.MockAuthenticationModule().createAutomatedSessionForUser(qInstance, "alice"); + QSession viaAlert = AlertsSecurity.recipientSession(qInstance, config.getServicePrincipal(), "alice"); + assertThat(viaAlert.getPermissions()).isEqualTo(own.getPermissions()).contains("widget.read"); + assertThat(new java.util.HashMap<>(viaAlert.getSecurityKeyValues())).isEqualTo(new java.util.HashMap<>(own.getSecurityKeyValues())); + } + + + + /******************************************************************************* + ** A recipient with a table grant and a record-lock key of their own. + *******************************************************************************/ + public static class RecipientCustomizer implements com.kingsrook.qqq.backend.core.modules.authentication.QAuthenticationModuleCustomizerInterface + { + /*************************************************************************** + ** + ***************************************************************************/ + @Override + public void customizeAutomatedSessionForUser(com.kingsrook.qqq.backend.core.model.metadata.QInstance qInstance, QSession session, java.io.Serializable userId) + { + session.withPermissions("widget.read", "alerts_alert.read"); + session.withSecurityKeyValue("recipientOnly", String.valueOf(userId)); + } + } } -- 2.54.0