You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2021/05/30 19:14:57 UTC

[isis] 01/01: ISIS-2699: deprecates SecmanConfiguration in favour of config properties

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

danhaywood pushed a commit to branch ISIS-2699
in repository https://gitbox.apache.org/repos/asf/isis.git

commit 2329561f058c4a52e705ec14772488ec70b69dad
Author: danhaywood <da...@haywood-associates.co.uk>
AuthorDate: Sun May 30 20:14:15 2021 +0100

    ISIS-2699: deprecates SecmanConfiguration in favour of config properties
---
 .../apache/isis/core/config/IsisConfiguration.java | 173 +++++++++++++++++++++
 .../secman/applib/IsisModuleExtSecmanApplib.java   |   6 +-
 .../secman/applib/SecmanAutoConfiguration.java     |  61 ++++++++
 .../secman/applib/SecmanConfiguration.java         | 137 +++++-----------
 .../src/main/resources/META-INF/spring.factories   |   2 +
 5 files changed, 284 insertions(+), 95 deletions(-)

diff --git a/core/config/src/main/java/org/apache/isis/core/config/IsisConfiguration.java b/core/config/src/main/java/org/apache/isis/core/config/IsisConfiguration.java
index 3e23bdb..f790afd 100644
--- a/core/config/src/main/java/org/apache/isis/core/config/IsisConfiguration.java
+++ b/core/config/src/main/java/org/apache/isis/core/config/IsisConfiguration.java
@@ -32,6 +32,7 @@ import java.util.Locale;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Optional;
+import java.util.Set;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 
@@ -54,6 +55,7 @@ import org.springframework.boot.convert.DurationUnit;
 import org.springframework.core.env.ConfigurableEnvironment;
 import org.springframework.validation.annotation.Validated;
 
+import org.apache.isis.applib.IsisModuleApplib;
 import org.apache.isis.applib.annotation.ActionLayout;
 import org.apache.isis.applib.annotation.DomainObject;
 import org.apache.isis.applib.annotation.DomainService;
@@ -75,8 +77,12 @@ import org.apache.isis.core.config.metamodel.services.ApplicationFeaturesInitCon
 import org.apache.isis.core.config.metamodel.specloader.IntrospectionMode;
 import org.apache.isis.core.config.viewer.wicket.DialogMode;
 
+import lombok.Builder;
 import lombok.Data;
 import lombok.Getter;
+import lombok.NonNull;
+import lombok.Setter;
+import lombok.Singular;
 import lombok.Value;
 import lombok.val;
 
@@ -3010,6 +3016,173 @@ public class IsisConfiguration {
         @Data
         public static class Secman {
 
+            private final Seed seed = new Seed();
+            public static class Seed {
+
+                public static final String ADMIN_USER_NAME_DEFAULT = "secman-admin";
+                public static final String ADMIN_PASSWORD_DEFAULT = "pass";
+                public static final String ADMIN_ROLE_NAME_DEFAULT = "isis-ext-secman-admin";
+                public static final List<String> ADMIN_STICKY_NAMESPACE_PERMISSIONS_DEFAULT =
+                        Collections.unmodifiableList(listOf(
+                                IsisModuleApplib.NAMESPACE,
+                                IsisModuleApplib.NAMESPACE_SUDO,
+                                IsisModuleApplib.NAMESPACE_CONF,
+                                IsisModuleApplib.NAMESPACE_FEAT,
+                                "isis.security",
+                                "isis.ext.h2Console",
+                                "isis.ext.secman"
+                        ));
+                public static final List<String> ADMIN_ADDITIONAL_NAMESPACE_PERMISSIONS =
+                        Collections.unmodifiableList(listOf());
+                public static final String REGULAR_USER_ROLE_NAME_DEFAULT = "isis-ext-secman-user";
+                public static final boolean AUTO_UNLOCK_IF_DELEGATED_AND_AUTHENTICATED_DEFAULT = false;
+
+                @Getter @Setter
+                private final Admin admin = new Admin();
+                @Data
+                public static class Admin {
+
+                    /**
+                     * The name of the security super user.
+                     *
+                     * <p>
+                     * This user is automatically made a member of the
+                     * {@link #getRoleName() admin role}, from which it is granted
+                     * permissions to administer other users.
+                     * </p>
+                     *
+                     * <p>
+                     * The password for this user is set in {@link #getAdminPassword()}.
+                     * </p>
+                     *
+                     * @see #getPassword()
+                     * @see #getRoleName()
+                     */
+                    private String userName = ADMIN_USER_NAME_DEFAULT;
+
+
+                    // sonar-ignore-on (detects potential security risk, which we are aware of)
+                    /**
+                     * The corresponding password for {@link #getUserName() admin user}.
+                     *
+                     * @see #getUserName()
+                     */
+                    private String password = ADMIN_PASSWORD_DEFAULT;
+                    // sonar-ignore-off
+
+                    /**
+                     * The name of security admin role.
+                     *
+                     * <p>
+                     * Users with this role (in particular, the default
+                     * {@link Admin#getUserName() admin user} are granted access to a set of
+                     * namespaces ({@link NamespacePermissions#getSticky()} and
+                     * {@link NamespacePermissions#getAdditional()}) which are intended to
+                     * be sufficient to allow users with this admin role to be able to
+                     * administer the security module itself, for example to manage users and
+                     * roles.
+                     * </p>
+                     *
+                     * @see Admin#getUserName()
+                     * @see NamespacePermissions#getSticky()
+                     * @see NamespacePermissions#getAdditional()
+                     */
+                    private String roleName = ADMIN_ROLE_NAME_DEFAULT;
+
+                    private final NamespacePermissions namespacePermissions = new NamespacePermissions();
+                    @Data
+                    public static class NamespacePermissions {
+
+                        /**
+                         * The set of namespaces to which the {@link Admin#getRoleName() admin role}
+                         * is granted.
+                         *
+                         * <p>
+                         * These namespaces are intended to be sufficient to allow users with
+                         * this admin role to be able to administer the security module itself,
+                         * for example to manage users and roles.  The security user is not
+                         * necessarily able to use the main business logic within the domain
+                         * application itself, though.
+                         * </p>
+                         *
+                         * <p>
+                         * These roles cannot be removed via user interface
+                         * </p>
+                         *
+                         * <p>
+                         * WARNING: normally these should not be overridden.  Instead, specify
+                         * additional namespaces using
+                         * {@link NamespacePermissions#getAdditional()}.
+                         * </p>
+                         *
+                         * @see #getAdminAdditionalNamespacePermissions()
+                         */
+                        private List<String> sticky = ADMIN_STICKY_NAMESPACE_PERMISSIONS_DEFAULT;
+
+
+                        /**
+                         * An (optional) additional set of namespaces that the
+                         * {@link Admin#getRoleName() admin role} is granted.
+                         *
+                         * <p>
+                         * These are in addition to the main
+                         * {@link NamespacePermissions#getSticky() namespaces} granted.
+                         * </p>
+                         *
+                         * @see NamespacePermissions#getSticky()
+                         */
+                        @Getter @Setter
+                        private List<String> additional = ADMIN_ADDITIONAL_NAMESPACE_PERMISSIONS;
+
+                    }
+
+                }
+
+                @Getter @Setter
+                private final RegularUser regularUser = new RegularUser();
+                @Data
+                public static class RegularUser {
+
+                    /**
+                     * The role name for regular users of the application, granting them access
+                     * to basic security features.
+                     *
+                     * <p>
+                     *     The exact set of permissions is hard-wired in the
+                     *     <code>IsisExtSecmanRegularUserRoleAndPermissions</code> fixture.
+                     * </p>
+                     */
+                    private String roleName = REGULAR_USER_ROLE_NAME_DEFAULT;
+
+                }
+
+            }
+
+            private final DelegatedUsers delegatedUsers = new DelegatedUsers();
+
+            @Data
+            public static class DelegatedUsers {
+
+                public enum AutoCreatePolicy {
+                    AUTO_CREATE_AS_LOCKED,
+                    AUTO_CREATE_AS_UNLOCKED,
+                    // NO_AUTO_CREATE
+                }
+
+                /**
+                 * Whether delegated users should be autocreated as locked (the default) or unlocked.
+                 *
+                 * <p>
+                 * BE AWARE THAT if any users are auto-created as unlocked, then the set of roles that
+                 * they are given should be highly restricted !!!
+                 * </p>
+                 */
+                @Getter @Setter
+                private AutoCreatePolicy autoCreatePolicy = AutoCreatePolicy.AUTO_CREATE_AS_LOCKED;
+
+            }
+
+
             private final UserRegistration userRegistration = new UserRegistration();
             @Data
             public static class UserRegistration {
diff --git a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/IsisModuleExtSecmanApplib.java b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/IsisModuleExtSecmanApplib.java
index 9a19c6e..c0db454 100644
--- a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/IsisModuleExtSecmanApplib.java
+++ b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/IsisModuleExtSecmanApplib.java
@@ -18,6 +18,7 @@
  */
 package org.apache.isis.extensions.secman.applib;
 
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Import;
 
@@ -70,8 +71,8 @@ import org.apache.isis.extensions.secman.applib.user.dom.mixins.ApplicationUser_
 import org.apache.isis.extensions.secman.applib.user.dom.mixins.ApplicationUser_updatePassword;
 import org.apache.isis.extensions.secman.applib.user.dom.mixins.ApplicationUser_updatePhoneNumber;
 import org.apache.isis.extensions.secman.applib.user.dom.mixins.ApplicationUser_updateUsername;
-import org.apache.isis.extensions.secman.applib.user.dom.mixins.perms.ApplicationUser_filterEffectiveMemberPermissions;
 import org.apache.isis.extensions.secman.applib.user.dom.mixins.perms.ApplicationUser_effectiveMemberPermissions;
+import org.apache.isis.extensions.secman.applib.user.dom.mixins.perms.ApplicationUser_filterEffectiveMemberPermissions;
 import org.apache.isis.extensions.secman.applib.user.dom.mixins.perms.UserPermissionViewModel;
 import org.apache.isis.extensions.secman.applib.user.menu.ApplicationUserMenu;
 import org.apache.isis.extensions.secman.applib.user.menu.MeService;
@@ -163,8 +164,10 @@ import org.apache.isis.extensions.secman.applib.user.menu.MeService;
 
         // other @Services
         SeedSecurityModuleService.class,
+//        SecmanAutoConfiguration.class,
 
 })
+//@EnableAutoConfiguration()
 public class IsisModuleExtSecmanApplib {
 
     public static final String NAMESPACE = "isis.ext.secman";
@@ -177,4 +180,5 @@ public class IsisModuleExtSecmanApplib {
 
     public abstract static class PropertyDomainEvent<S, T>
     extends org.apache.isis.applib.events.domain.PropertyDomainEvent<S, T> {}
+
 }
diff --git a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/SecmanAutoConfiguration.java b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/SecmanAutoConfiguration.java
new file mode 100644
index 0000000..df8b7d8
--- /dev/null
+++ b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/SecmanAutoConfiguration.java
@@ -0,0 +1,61 @@
+/*
+ *  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.isis.extensions.secman.applib;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.autoconfigure.AutoConfigureOrder;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Service;
+
+import org.apache.isis.applib.annotation.OrderPrecedence;
+import org.apache.isis.core.config.IsisConfiguration;
+
+import lombok.RequiredArgsConstructor;
+import lombok.extern.log4j.Log4j2;
+import lombok.val;
+
+@AutoConfigureOrder(OrderPrecedence.LAST)
+@Configuration
+public class SecmanAutoConfiguration {
+
+    /**
+     * Provides a default implementation of {@link SecmanConfiguration}.
+     */
+    @Bean
+    @ConditionalOnMissingBean(SecmanConfiguration.class)
+    public SecmanConfiguration bean(final IsisConfiguration isisConfiguration) {
+        val secman = isisConfiguration.getExtensions().getSecman();
+        return SecmanConfiguration.builder()
+                .adminUserName(secman.getSeed().getAdmin().getUserName())
+                .adminPassword(secman.getSeed().getAdmin().getPassword())
+                .adminRoleName(secman.getSeed().getAdmin().getRoleName())
+                .adminStickyNamespacePermissions(secman.getSeed().getAdmin().getNamespacePermissions().getSticky().toArray(new String[]{}))
+                .adminAdditionalNamespacePermissions(secman.getSeed().getAdmin().getNamespacePermissions().getAdditional())
+                .regularUserRoleName(secman.getSeed().getRegularUser().getRoleName())
+                .autoUnlockIfDelegatedAndAuthenticated(secman.getDelegatedUsers().getAutoCreatePolicy() == IsisConfiguration.Extensions.Secman.DelegatedUsers.AutoCreatePolicy.AUTO_CREATE_AS_UNLOCKED)
+                .build();
+    }
+
+}
diff --git a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/SecmanConfiguration.java b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/SecmanConfiguration.java
index 69e200e..88dfcfb 100644
--- a/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/SecmanConfiguration.java
+++ b/extensions/security/secman/applib/src/main/java/org/apache/isis/extensions/secman/applib/SecmanConfiguration.java
@@ -18,13 +18,14 @@
  */
 package org.apache.isis.extensions.secman.applib;
 
+import java.util.Collection;
+import java.util.List;
 import java.util.Set;
 import java.util.stream.Stream;
 
-import org.apache.isis.applib.IsisModuleApplib;
 import org.apache.isis.commons.internal.base._NullSafe;
-import org.apache.isis.core.security.IsisModuleCoreSecurity;
-import org.apache.isis.extensions.secman.applib.role.seed.IsisExtH2ConsoleRoleAndPermissions;
+import org.apache.isis.commons.internal.collections._Sets;
+import org.apache.isis.core.config.IsisConfiguration;
 
 import lombok.Builder;
 import lombok.Getter;
@@ -47,156 +48,97 @@ import lombok.Singular;
  * provides reasonable defaults.
  * </p>
  *
+ * @deprecated - use <code>application.yml</code> config properties instead.
+ *
  * @since 2.0 {@index}
  */
+@Deprecated
 @Builder
 public class SecmanConfiguration {
 
     // -- ADMIN
 
     /**
-     * The name of the security super user.
-     *
-     * <p>
-     * This user is automatically made a member of the
-     * {@link #getAdminRoleName() admin role}, from which it is granted
-     * permissions to administer other users.
-     * </p>
+     * @see IsisConfiguration.Extensions.Secman.Seed.Admin#getUserName()
      *
-     * <p>
-     * The password for this user is set in {@link #getAdminPassword()}.
-     * </p>
-     *
-     * @see #getAdminPassword()
-     * @see #getAdminRoleName()
+     * @deprecated
      */
+    @Deprecated
     @Getter
     @Builder.Default
     @NonNull
-    final String adminUserName = "secman-admin";
+    final String adminUserName = IsisConfiguration.Extensions.Secman.Seed.ADMIN_USER_NAME_DEFAULT;
 
     // sonar-ignore-on (detects potential security risk, which we are aware of)
+
     /**
-     * The corresponding password for {@link #getAdminUserName() admin user}.
+     * @see IsisConfiguration.Extensions.Secman.Seed.Admin#getPassword()
      *
-     * @see #getAdminUserName()
+     * @deprecated
      */
+    @Deprecated
     @Getter
     @Builder.Default
     @NonNull
-    final String adminPassword = "pass";
+    final String adminPassword = IsisConfiguration.Extensions.Secman.Seed.ADMIN_PASSWORD_DEFAULT;
     // sonar-ignore-off
 
     /**
-     * The name of security admin role.
+     * @see IsisConfiguration.Extensions.Secman.Seed.Admin#getRoleName()
      *
-     * <p>
-     * Users with this role (in particular, the default
-     * {@link #getAdminUserName() admin user} are granted access to a set of
-     * namespaces ({@link #getAdminStickyNamespacePermissions()} and
-     * {@link #getAdminAdditionalNamespacePermissions()}) which are intended to
-     * be sufficient to allow users with this admin role to be able to
-     * administer the security module itself, for example to manage users and
-     * roles.
-     * </p>
-     *
-     * @see #getAdminUserName()
-     * @see #getAdminStickyNamespacePermissions()
-     * @see #getAdminAdditionalNamespacePermissions()
+     * @deprecated
      */
+    @Deprecated
     @Getter
     @Builder.Default
     @NonNull
-    final String adminRoleName = ADMIN_ROLE_DEFAULT_NAME;
-
-    public static String ADMIN_ROLE_DEFAULT_NAME = "isis-ext-secman-admin";
+    final String adminRoleName = IsisConfiguration.Extensions.Secman.Seed.ADMIN_ROLE_NAME_DEFAULT;
 
     /**
-     * The set of namespaces to which the {@link #getAdminRoleName() admin role}
-     * is granted.
-     *
-     * <p>
-     * These namespaces are intended to be sufficient to allow users with
-     * this admin role to be able to administer the security module itself,
-     * for example to manage users and roles.  The security user is not
-     * necessarily able to use the main business logic within the domain
-     * application itself, though.
-     * </p>
-     *
-     * <p>
-     * These roles cannot be removed via user interface
-     * </p>
+     * @see IsisConfiguration.Extensions.Secman.Seed.Admin.NamespacePermissions#getSticky()
      *
-     * <p>
-     * WARNING: normally these should not be overridden.  Instead, specify
-     * additional namespaces using
-     * {@link #getAdminAdditionalNamespacePermissions()}.
-     * </p>
-     *
-     * @see #getAdminAdditionalNamespacePermissions()
+     * @deprecated
      */
+    @Deprecated
     @Getter
     @Builder.Default
     @NonNull
-    final String[] adminStickyNamespacePermissions = new String[]{
-            IsisModuleCoreSecurity.NAMESPACE,
-            IsisModuleApplib.NAMESPACE_SUDO,
-            IsisModuleApplib.NAMESPACE_CONF,
-            IsisModuleApplib.NAMESPACE_FEAT,
-            IsisExtH2ConsoleRoleAndPermissions.NAMESPACE,
-            IsisModuleExtSecmanApplib.NAMESPACE
-    };
+    final String[] adminStickyNamespacePermissions = arrayOf(IsisConfiguration.Extensions.Secman.Seed.ADMIN_STICKY_NAMESPACE_PERMISSIONS_DEFAULT);
 
     /**
-     * An (optional) additional set of namespaces that the
-     * {@link #getAdminRoleName() admin role} is granted.
-     *
-     * <p>
-     * These are in addition to the main
-     * {@link #getAdminStickyNamespacePermissions() namespaces} granted.
-     * </p>
+     * @see IsisConfiguration.Extensions.Secman.Seed.Admin.NamespacePermissions#getAdditional()
      *
-     * @see #getAdminStickyNamespacePermissions()
+     * @deprecated
      */
+    @Deprecated
     @Getter
     @Singular
     final Set<String> adminAdditionalNamespacePermissions;
 
 
+
     // -- REGULAR USER
 
     /**
-     * The role name for regular users of the application, granting them access
-     * to basic security features.
+     * @see IsisConfiguration.Extensions.Secman.Seed.RegularUser#getRoleName()
      *
-     * <p>
-     *     The exact set of permissions is hard-wired in the
-     *     <code>IsisExtSecmanRegularUserRoleAndPermissions</code> fixture.
-     * </p>
+     * @deprecated
      */
+    @Deprecated
     @Getter
     @Builder.Default
     @NonNull
-    final String regularUserRoleName = REGULAR_USER_ROLE_DEFAULT_NAME;
-
-    public static String REGULAR_USER_ROLE_DEFAULT_NAME = "isis-ext-secman-user";
-
+    final String regularUserRoleName = IsisConfiguration.Extensions.Secman.Seed.REGULAR_USER_ROLE_NAME_DEFAULT;
 
     /**
-     * Delegated users, on first successful logon, are auto-created but locked (by default).
-     * <p>
-     * This option allows to override this behavior, such that authenticated
-     * users are also auto-unlocked.
-     * <p>
+     * @see IsisConfiguration.Extensions.Secman.DelegatedUsers#getAutoCreatePolicy()
      *
-     * <p>
-     * BE AWARE THAT if any users are auto-created unlocked, then the set of roles that
-     * they are given should be highly restricted !!!
-     * </p>
+     * @deprecated
      */
+    @Deprecated
     @Getter
     @Builder.Default
-    final boolean autoUnlockIfDelegatedAndAuthenticated = false;
+    final boolean autoUnlockIfDelegatedAndAuthenticated = IsisConfiguration.Extensions.Secman.Seed.AUTO_UNLOCK_IF_DELEGATED_AND_AUTHENTICATED_DEFAULT;
 
 
     // -- UTILITIES
@@ -212,4 +154,11 @@ public class SecmanConfiguration {
                 .anyMatch(stickyPackage -> stickyPackage.equals(featureFqn));
     }
 
+    private static Set<String> setOf(Collection<String> coll) {
+        return _Sets.newTreeSet(coll);
+    }
+    private static String[] arrayOf(List<String> list) {
+        return list.toArray(new String[]{});
+    }
+
 }
diff --git a/extensions/security/secman/applib/src/main/resources/META-INF/spring.factories b/extensions/security/secman/applib/src/main/resources/META-INF/spring.factories
new file mode 100644
index 0000000..c505230
--- /dev/null
+++ b/extensions/security/secman/applib/src/main/resources/META-INF/spring.factories
@@ -0,0 +1,2 @@
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
+  org.apache.isis.extensions.secman.applib.SecmanAutoConfiguration