This is an automated email from the ASF dual-hosted git repository.

danhaywood pushed a commit to branch CAUSEWAY-3524
in repository https://gitbox.apache.org/repos/asf/causeway.git

commit a2cbeebd19306119e6fad4321c81306cb9044535
Author: danhaywood <[email protected]>
AuthorDate: Fri Jul 7 19:02:13 2023 +0200

    CAUSEWAY-3524: introduce ApplicationFeatureIdTransformer for secman
    
    to provide an SPI allowing backward compatibility of security perms
---
 antora/supplemental-ui/index.html                  | 25 ++++++++
 .../permission/dom/ApplicationPermissionValue.java |  4 ++
 .../CausewayModuleExtSecmanIntegration.java        |  3 +
 .../ApplicationFeatureIdTransformer.java           | 72 ++++++++++++++++++++++
 .../PermissionsEvaluationServiceForSecman.java     | 18 +++++-
 5 files changed, 120 insertions(+), 2 deletions(-)

diff --git a/antora/supplemental-ui/index.html 
b/antora/supplemental-ui/index.html
index 7a64519157..f7bea3b86f 100644
--- a/antora/supplemental-ui/index.html
+++ b/antora/supplemental-ui/index.html
@@ -791,5 +791,30 @@ docker run -p 8080:8080 
apache/causeway-app-demo-jdo:latest</pre>
 <!-- Template Main JavaScript File -->
 <script src="_/js/home/main.js"></script>
 
+<script 
src="https://cdn.jsdelivr.net/npm/docsearch.js@2/dist/cdn/docsearch.min.js";></script>
+<script>
+  function focusSearchInput () { 
document.querySelector('#algolia-search-input').focus() }
+  var search = docsearch({
+    appId: '5ISP5TFAEN',
+    apiKey: '0fc51c28b4ad46e7318e96d4e97fab7c',
+    indexName: 'causeway-apache-org',
+    inputSelector: '#algolia-search-input',
+    autocompleteOptions: { hint: false, keyboardShortcuts: ['s'] },
+    debug: false,
+  }).autocomplete
+  search.on('autocomplete:closed', function () { search.autocomplete.setVal() 
})
+  focusSearchInput()
+  window.addEventListener('load', focusSearchInput);
+</script>
+
+<!--
+  docsearch options:
+  https://docsearch.algolia.com/docs/behavior/
+-->
+<!--
+  https://www.algolia.com/doc/api-reference/api-parameters/
+  algoliaOptions: { hitsPerPage: 6 },
+-->
+
 </body>
 </html>
diff --git 
a/extensions/security/secman/applib/src/main/java/org/apache/causeway/extensions/secman/applib/permission/dom/ApplicationPermissionValue.java
 
b/extensions/security/secman/applib/src/main/java/org/apache/causeway/extensions/secman/applib/permission/dom/ApplicationPermissionValue.java
index 3aff46724d..77ed07c631 100644
--- 
a/extensions/security/secman/applib/src/main/java/org/apache/causeway/extensions/secman/applib/permission/dom/ApplicationPermissionValue.java
+++ 
b/extensions/security/secman/applib/src/main/java/org/apache/causeway/extensions/secman/applib/permission/dom/ApplicationPermissionValue.java
@@ -117,6 +117,10 @@ public class ApplicationPermissionValue implements 
Comparable<ApplicationPermiss
         return false;
     }
 
+    @Programmatic
+    public ApplicationPermissionValue withFeatureId(ApplicationFeatureId 
applicationFeatureId) {
+        return new ApplicationPermissionValue(applicationFeatureId, this.rule, 
this.mode);
+    }
 
 
     // -- Comparators
diff --git 
a/extensions/security/secman/integration/src/main/java/org/apache/causeway/extensions/secman/integration/CausewayModuleExtSecmanIntegration.java
 
b/extensions/security/secman/integration/src/main/java/org/apache/causeway/extensions/secman/integration/CausewayModuleExtSecmanIntegration.java
index 6e45015dcd..b8c8bb0ef3 100644
--- 
a/extensions/security/secman/integration/src/main/java/org/apache/causeway/extensions/secman/integration/CausewayModuleExtSecmanIntegration.java
+++ 
b/extensions/security/secman/integration/src/main/java/org/apache/causeway/extensions/secman/integration/CausewayModuleExtSecmanIntegration.java
@@ -18,6 +18,8 @@
  */
 package org.apache.causeway.extensions.secman.integration;
 
+import 
org.apache.causeway.extensions.secman.integration.permissions.ApplicationFeatureIdTransformer;
+
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Import;
 
@@ -44,6 +46,7 @@ import 
org.apache.causeway.extensions.secman.integration.userreg.UserRegistratio
         TableColumnVisibilityServiceForSecman.class,
         ImpersonateMenuAdvisorForSecman.class, //not activated by default yet
         PermissionsEvaluationServiceForSecman.class,
+        ApplicationFeatureIdTransformer.Identity.class,
         UserRegistrationServiceForSecman.class,
 
         UserMementoRefinerFromApplicationUser.class,
diff --git 
a/extensions/security/secman/integration/src/main/java/org/apache/causeway/extensions/secman/integration/permissions/ApplicationFeatureIdTransformer.java
 
b/extensions/security/secman/integration/src/main/java/org/apache/causeway/extensions/secman/integration/permissions/ApplicationFeatureIdTransformer.java
new file mode 100644
index 0000000000..a843a19710
--- /dev/null
+++ 
b/extensions/security/secman/integration/src/main/java/org/apache/causeway/extensions/secman/integration/permissions/ApplicationFeatureIdTransformer.java
@@ -0,0 +1,72 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.causeway.extensions.secman.integration.permissions;
+
+import org.apache.causeway.applib.annotation.PriorityPrecedence;
+import org.apache.causeway.applib.annotation.Programmatic;
+import org.apache.causeway.applib.services.appfeat.ApplicationFeatureId;
+
+import 
org.apache.causeway.extensions.secman.applib.permission.dom.ApplicationPermissionValue;
+
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Priority;
+
+import java.util.Collection;
+import java.util.stream.Collectors;
+
+/**
+ * Provides an SPI used by {@link PermissionsEvaluationServiceForSecman} that
+ * pre-processes {@link ApplicationFeatureId}s before evaluating them.
+ *
+ * <p>
+ *     The primary use case is to enable backward compatibility; rather than 
evaluating using the
+ *     logicalTypeName#memberId, an alternative transformer could use the 
packageName#memberId (as was done in v1).
+ * </p>
+ *
+ */
+public interface ApplicationFeatureIdTransformer {
+
+    @Programmatic
+    ApplicationFeatureId transform(ApplicationFeatureId applicationFeatureId);
+
+    @Programmatic
+    default Collection<ApplicationPermissionValue> 
transform(Collection<ApplicationPermissionValue> permissionValues) {
+        return permissionValues.stream()
+                .map(apv -> apv.withFeatureId(transform(apv.getFeatureId())))
+                .collect(Collectors.toList());
+    }
+
+    @Service
+    @Priority(PriorityPrecedence.LATE)
+    class Identity implements ApplicationFeatureIdTransformer {
+
+        @Programmatic
+        @Override
+        public ApplicationFeatureId transform(ApplicationFeatureId 
applicationFeatureId) {
+            return applicationFeatureId;
+        }
+
+        @Programmatic
+        @Override
+        public Collection<ApplicationPermissionValue> 
transform(Collection<ApplicationPermissionValue> permissionValues) {
+            return permissionValues;
+        }
+    }
+}
diff --git 
a/extensions/security/secman/integration/src/main/java/org/apache/causeway/extensions/secman/integration/permissions/PermissionsEvaluationServiceForSecman.java
 
b/extensions/security/secman/integration/src/main/java/org/apache/causeway/extensions/secman/integration/permissions/PermissionsEvaluationServiceForSecman.java
index 3496bb1b6a..b0991ec9fc 100644
--- 
a/extensions/security/secman/integration/src/main/java/org/apache/causeway/extensions/secman/integration/permissions/PermissionsEvaluationServiceForSecman.java
+++ 
b/extensions/security/secman/integration/src/main/java/org/apache/causeway/extensions/secman/integration/permissions/PermissionsEvaluationServiceForSecman.java
@@ -20,6 +20,7 @@ package 
org.apache.causeway.extensions.secman.integration.permissions;
 
 import java.util.Collection;
 import java.util.Collections;
+import java.util.List;
 import java.util.Optional;
 
 import javax.inject.Inject;
@@ -71,9 +72,12 @@ implements PermissionsEvaluationService {
 
     @Override
     public ApplicationPermissionValueSet.Evaluation evaluate(
-            final ApplicationFeatureId targetMemberId,
+            final ApplicationFeatureId targetMemberIdInput,
             final ApplicationPermissionMode mode,
-            final Collection<ApplicationPermissionValue> permissionValues) {
+            final Collection<ApplicationPermissionValue> 
permissionValuesInput) {
+
+        final ApplicationFeatureId targetMemberId = 
applicationFeatureIdTransformer().transform(targetMemberIdInput);
+        final Collection<ApplicationPermissionValue> permissionValues = 
applicationFeatureIdTransformer().transform(permissionValuesInput);
 
         if(_NullSafe.isEmpty(permissionValues)) {
             return null;
@@ -112,4 +116,14 @@ implements PermissionsEvaluationService {
         throw _Exceptions.illegalArgument("PermissionsEvaluationPolicy '%s' 
not recognised", policy);
     }
 
+    private ApplicationFeatureIdTransformer 
applicationFeatureIdTransformerCached;
+    ApplicationFeatureIdTransformer applicationFeatureIdTransformer() {
+        if (applicationFeatureIdTransformerCached == null) {
+            applicationFeatureIdTransformerCached = 
applicationFeatureIdTransformers == null || 
applicationFeatureIdTransformers.isEmpty() ? new 
ApplicationFeatureIdTransformer.Identity() : 
applicationFeatureIdTransformers.get(0);
+        }
+        return applicationFeatureIdTransformerCached;
+    };
+
+    @Inject List<ApplicationFeatureIdTransformer> 
applicationFeatureIdTransformers;
+
 }

Reply via email to