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; + }
