You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@causeway.apache.org by ah...@apache.org on 2023/02/10 09:38:10 UTC

[causeway] branch 3358-allow_safe_act_w_view_perm created (now 18ff04ca21)

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

ahuber pushed a change to branch 3358-allow_safe_act_w_view_perm
in repository https://gitbox.apache.org/repos/asf/causeway.git


      at 18ff04ca21 CAUSEWAY-3358: modifies AuthorizationManager to consider action semantics

This branch includes the following new commits:

     new 18ff04ca21 CAUSEWAY-3358: modifies AuthorizationManager to consider action semantics

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[causeway] 01/01: CAUSEWAY-3358: modifies AuthorizationManager to consider action semantics

Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ahuber pushed a commit to branch 3358-allow_safe_act_w_view_perm
in repository https://gitbox.apache.org/repos/asf/causeway.git

commit 18ff04ca21f2d9312ef5bdabfa3aad0445a9ae84
Author: andi-huber <ah...@apache.org>
AuthorDate: Fri Feb 10 10:38:01 2023 +0100

    CAUSEWAY-3358: modifies AuthorizationManager to consider action
    semantics
---
 .../core/config/CausewayConfiguration.java         | 10 ++++--
 .../specloader/SpecificationLoaderDefault.java     | 20 +++++++++++-
 core/security/src/main/java/module-info.java       |  1 +
 .../manager/ActionSemanticsResolver.java           | 37 ++++++++++++++++++++++
 .../manager/AuthorizationManager.java              | 21 ++++++++++++
 5 files changed, 86 insertions(+), 3 deletions(-)

diff --git a/core/config/src/main/java/org/apache/causeway/core/config/CausewayConfiguration.java b/core/config/src/main/java/org/apache/causeway/core/config/CausewayConfiguration.java
index 20c2ea7efe..bd85548840 100644
--- a/core/config/src/main/java/org/apache/causeway/core/config/CausewayConfiguration.java
+++ b/core/config/src/main/java/org/apache/causeway/core/config/CausewayConfiguration.java
@@ -74,8 +74,6 @@ import org.apache.causeway.applib.services.userui.UserMenu;
 import org.apache.causeway.applib.value.semantics.TemporalValueSemantics.TemporalEditingPattern;
 import org.apache.causeway.commons.internal.base._NullSafe;
 import org.apache.causeway.commons.internal.context._Context;
-import org.apache.causeway.core.config.CausewayConfiguration.Core;
-import org.apache.causeway.core.config.CausewayConfiguration.Viewer;
 import org.apache.causeway.core.config.metamodel.facets.ActionConfigOptions;
 import org.apache.causeway.core.config.metamodel.facets.CollectionLayoutConfigOptions;
 import org.apache.causeway.core.config.metamodel.facets.DomainObjectConfigOptions;
@@ -115,6 +113,14 @@ public class CausewayConfiguration {
     private final Security security = new Security();
     @Data
     public static class Security {
+
+        /**
+         * If set, allows <i>Actions</i> with SAFE Semantics to be invoked with only VIEWING permissions.
+         * <p>
+         * default: false
+         */
+        private boolean allowActionsWithSafeSemanticsToBeInvokedWithOnlyViewingPermission = false;
+
         private final Shiro shiro = new Shiro();
         @Data
         public static class Shiro {
diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/specloader/SpecificationLoaderDefault.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/specloader/SpecificationLoaderDefault.java
index c45b6c46b9..2fb788992f 100644
--- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/specloader/SpecificationLoaderDefault.java
+++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/specloader/SpecificationLoaderDefault.java
@@ -40,7 +40,9 @@ import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.lang.Nullable;
 import org.springframework.stereotype.Service;
 
+import org.apache.causeway.applib.Identifier;
 import org.apache.causeway.applib.annotation.PriorityPrecedence;
+import org.apache.causeway.applib.annotation.SemanticsOf;
 import org.apache.causeway.applib.id.LogicalType;
 import org.apache.causeway.applib.services.menu.MenuBarsService;
 import org.apache.causeway.applib.services.metamodel.BeanSort;
@@ -73,6 +75,7 @@ import org.apache.causeway.core.metamodel.services.classsubstitutor.ClassSubstit
 import org.apache.causeway.core.metamodel.services.classsubstitutor.ClassSubstitutor.Substitution;
 import org.apache.causeway.core.metamodel.services.classsubstitutor.ClassSubstitutorRegistry;
 import org.apache.causeway.core.metamodel.spec.ObjectSpecification;
+import org.apache.causeway.core.metamodel.spec.feature.ObjectAction;
 import org.apache.causeway.core.metamodel.specloader.facetprocessor.FacetProcessor;
 import org.apache.causeway.core.metamodel.specloader.postprocessor.PostProcessor;
 import org.apache.causeway.core.metamodel.specloader.specimpl.IntrospectionState;
@@ -81,6 +84,7 @@ import org.apache.causeway.core.metamodel.specloader.validator.MetaModelValidato
 import org.apache.causeway.core.metamodel.specloader.validator.ValidationFailure;
 import org.apache.causeway.core.metamodel.specloader.validator.ValidationFailures;
 import org.apache.causeway.core.metamodel.valuetypes.ValueSemanticsResolverDefault;
+import org.apache.causeway.core.security.authorization.manager.ActionSemanticsResolver;
 
 import lombok.Getter;
 import lombok.NonNull;
@@ -107,7 +111,10 @@ import lombok.extern.log4j.Log4j2;
 @Priority(PriorityPrecedence.EARLY)
 @Qualifier("Default")
 @Log4j2
-public class SpecificationLoaderDefault implements SpecificationLoader {
+public class SpecificationLoaderDefault
+implements
+    SpecificationLoader,
+    ActionSemanticsResolver {
 
     private final CausewayConfiguration causewayConfiguration;
     private final CausewaySystemEnvironment causewaySystemEnvironment;
@@ -532,6 +539,17 @@ public class SpecificationLoaderDefault implements SpecificationLoader {
         return validationFailures;
     }
 
+    // -- ACTION SEMANTICS RESOLVER
+
+    @Override
+    public Optional<SemanticsOf> getActionSemanticsOf(final Identifier identifier) {
+        if(!identifier.getType().isAction()) {
+            return Optional.empty();
+        }
+        return specForLogicalType(identifier.getLogicalType())
+            .flatMap(objSpec->objSpec.getAction(identifier.getMemberLogicalName()))
+            .map(ObjectAction::getSemantics);
+    }
 
     // -- HELPER
 
diff --git a/core/security/src/main/java/module-info.java b/core/security/src/main/java/module-info.java
index 41e034b5bc..8a2e34aaa7 100644
--- a/core/security/src/main/java/module-info.java
+++ b/core/security/src/main/java/module-info.java
@@ -42,4 +42,5 @@ module org.apache.causeway.security.api {
     requires spring.context;
     requires spring.core;
     requires spring.tx;
+    requires org.apache.causeway.core.config;
 }
\ No newline at end of file
diff --git a/core/security/src/main/java/org/apache/causeway/core/security/authorization/manager/ActionSemanticsResolver.java b/core/security/src/main/java/org/apache/causeway/core/security/authorization/manager/ActionSemanticsResolver.java
new file mode 100644
index 0000000000..4a15c1d37e
--- /dev/null
+++ b/core/security/src/main/java/org/apache/causeway/core/security/authorization/manager/ActionSemanticsResolver.java
@@ -0,0 +1,37 @@
+/*
+ *  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.core.security.authorization.manager;
+
+import java.util.Optional;
+
+import org.apache.causeway.applib.Identifier;
+import org.apache.causeway.applib.annotation.SemanticsOf;
+
+/**
+ * Internal service, to resolve <i>Action's</i> {@link SemanticsOf} given their {@link Identifier}.
+ */
+public interface ActionSemanticsResolver {
+
+    /**
+     * Optionally the {@link SemanticsOf} of the <i>Action</i> represented by {@link Identifier},
+     * based on whether the identifier represents an <i>Action</i>.
+     */
+    Optional<SemanticsOf> getActionSemanticsOf(Identifier identifier);
+
+}
diff --git a/core/security/src/main/java/org/apache/causeway/core/security/authorization/manager/AuthorizationManager.java b/core/security/src/main/java/org/apache/causeway/core/security/authorization/manager/AuthorizationManager.java
index cbf04f1b89..f5a8f69955 100644
--- a/core/security/src/main/java/org/apache/causeway/core/security/authorization/manager/AuthorizationManager.java
+++ b/core/security/src/main/java/org/apache/causeway/core/security/authorization/manager/AuthorizationManager.java
@@ -31,10 +31,12 @@ import org.springframework.stereotype.Service;
 
 import org.apache.causeway.applib.Identifier;
 import org.apache.causeway.applib.annotation.PriorityPrecedence;
+import org.apache.causeway.applib.annotation.SemanticsOf;
 import org.apache.causeway.applib.services.iactnlayer.InteractionContext;
 import org.apache.causeway.applib.services.sudo.SudoService;
 import org.apache.causeway.commons.internal.assertions._Assert;
 import org.apache.causeway.commons.internal.base._NullSafe;
+import org.apache.causeway.core.config.CausewayConfiguration;
 import org.apache.causeway.core.security.authorization.Authorizor;
 
 /**
@@ -49,12 +51,20 @@ import org.apache.causeway.core.security.authorization.Authorizor;
 public class AuthorizationManager {
 
     private final Authorizor authorizor;
+    private final ActionSemanticsResolver actionSemanticsResolver;
+    private final boolean allowActionsWithSafeSemanticsToBeInvokedWithOnlyViewingPermission;
 
     @Inject
     public AuthorizationManager(
+            final CausewayConfiguration config,
+            final ActionSemanticsResolver actionSemanticsResolver,
             final List<Authorizor> authorizors,
             final Optional<AuthorizorChooser> authorizorChooserIfAny) {
 
+        this.allowActionsWithSafeSemanticsToBeInvokedWithOnlyViewingPermission =
+                config.getSecurity().isAllowActionsWithSafeSemanticsToBeInvokedWithOnlyViewingPermission();
+        this.actionSemanticsResolver = actionSemanticsResolver;
+
         _Assert.assertTrue(_NullSafe.size(authorizors)>0, ()->
             String.format(
                     "At least one %s is required to be registered for injection.",
@@ -86,6 +96,11 @@ public class AuthorizationManager {
         if (authorizor.isUsable(authentication, identifier)) {
             return true;
         }
+        if (allowActionsWithSafeSemanticsToBeInvokedWithOnlyViewingPermission
+                && isActionWithSafeSemantics(identifier)
+                && this.isVisible(authentication, identifier)) {
+            return true;
+        }
         return false;
     }
 
@@ -130,4 +145,10 @@ public class AuthorizationManager {
         return (identifier.getClassName().equals(""));
     }
 
+    private boolean isActionWithSafeSemantics(final Identifier identifier) {
+        return actionSemanticsResolver.getActionSemanticsOf(identifier)
+            .map(SemanticsOf::isSafeInNature)
+            .orElse(false);
+    }
+
 }