You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2021/04/20 14:21:31 UTC

[isis] branch master updated: ISIS-2562: remove 'newUser' actions from main menu;

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

ahuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git


The following commit(s) were added to refs/heads/master by this push:
     new 8d9d5b3  ISIS-2562: remove 'newUser' actions from main menu;
8d9d5b3 is described below

commit 8d9d5b3f0f76329ee7820ac9be4b4819eaadbb12
Author: Andi Huber <ah...@apache.org>
AuthorDate: Tue Apr 20 16:21:14 2021 +0200

    ISIS-2562: remove 'newUser' actions from main menu;
    
    instead provide a UserManager that mixins can contribute actions to
---
 .../applib/services/factory/FactoryService.java    |   1 -
 .../DomainObjectAnnotationFacetFactory.java        |   3 +-
 .../factory/FactoryServiceDefault.java             |   3 +
 .../src/main/java/demoapp/dom/menubars.layout.xml  |  23 ++-
 .../model/dom/user/ApplicationUserManager.java     |   5 +-
 .../ApplicationUserManager_newDelegateUser.java    |  60 ++++--
 .../user/ApplicationUserManager_newLocalUser.java  |  45 ++--
 .../secman/model/dom/user/ApplicationUserMenu.java | 229 +++++++++++----------
 .../ApplicationUserManager_newDelegateUser.java    |  55 ++---
 .../user/ApplicationUserManager_newLocalUser.java  |  90 ++++++++
 .../ApplicationUserManager_newDelegateUser.java    |  55 ++---
 .../user/ApplicationUserManager_newLocalUser.java  |  89 ++++++++
 12 files changed, 448 insertions(+), 210 deletions(-)

diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/factory/FactoryService.java b/api/applib/src/main/java/org/apache/isis/applib/services/factory/FactoryService.java
index 665f96f..a0a1cdc 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/factory/FactoryService.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/factory/FactoryService.java
@@ -60,7 +60,6 @@ public interface FactoryService {
      * life-cycle callback processed.
      * @param requiredType
      * @param <T>
-     * @return
      */
     <T> T getOrCreate(@NonNull Class<T> requiredType);
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactory.java
index 9f2d592..0f466b5 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactory.java
@@ -494,7 +494,8 @@ implements
 
                     @Override
                     public void validate(ObjectSpecification objSpec) {
-                        if(objSpec.isManagedBean()) {
+                        if(objSpec.isManagedBean()
+                                || objSpec.isAbstract()) {
                             return;
                         }
                         collidingSpecsByLogicalTypeName.putElement(objSpec.getLogicalTypeName() , objSpec);
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/factory/FactoryServiceDefault.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/factory/FactoryServiceDefault.java
index 956d07b..91873af 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/factory/FactoryServiceDefault.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/factory/FactoryServiceDefault.java
@@ -106,6 +106,9 @@ public class FactoryServiceDefault implements FactoryService {
         if(mixinFacet == null) {
             throw _Exceptions.illegalArgument("Class '%s' is not a mixin", mixinClass.getName());
         }
+        if(mixinSpec.isAbstract()) {
+            throw _Exceptions.illegalArgument("Cannot instantiate abstract type '%s' as a mixin", mixinClass.getName());
+        }
         if(!mixinFacet.isMixinFor(mixedIn.getClass())) {
             throw _Exceptions.illegalArgument("Mixin class '%s' is not a mixin for supplied object '%s'",
                     mixinClass.getName(), mixedIn);
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/menubars.layout.xml b/examples/demo/domain/src/main/java/demoapp/dom/menubars.layout.xml
index c902c7d..9cd74ca 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/menubars.layout.xml
+++ b/examples/demo/domain/src/main/java/demoapp/dom/menubars.layout.xml
@@ -422,18 +422,21 @@ For latest we use: https://raw.githubusercontent.com/apache/isis/master/antora/s
                 </mb3:serviceAction>
             </mb3:section>
             <mb3:section>
-                <mb3:serviceAction objectType="isis.ext.secman.ApplicationUserMenu" id="findUsers">
+            	<mb3:serviceAction objectType="isis.ext.secman.ApplicationUserMenu" id="findUsers">
                     <cpt:named>Find Users</cpt:named>
                 </mb3:serviceAction>
-                <mb3:serviceAction objectType="isis.ext.secman.ApplicationUserMenu" id="newLocalUser">
-                    <cpt:named>New Local User</cpt:named>
-                </mb3:serviceAction>
-                <mb3:serviceAction objectType="isis.ext.secman.ApplicationUserMenu" id="allUsers">
-                    <cpt:named>All Users</cpt:named>
-                </mb3:serviceAction>
-                <mb3:serviceAction objectType="isis.ext.secman.ApplicationUserMenu" id="newDelegateUser">
-                    <cpt:named>New Delegate User</cpt:named>
-                </mb3:serviceAction>
+            	<mb3:serviceAction objectType="isis.ext.secman.ApplicationUserMenu" id="userManager">
+                    <cpt:named>User Manager</cpt:named>
+                </mb3:serviceAction>
+<!--                 <mb3:serviceAction objectType="isis.ext.secman.ApplicationUserMenu" id="newLocalUser"> -->
+<!--                     <cpt:named>New Local User</cpt:named> -->
+<!--                 </mb3:serviceAction> -->
+<!--                 <mb3:serviceAction objectType="isis.ext.secman.ApplicationUserMenu" id="allUsers"> -->
+<!--                     <cpt:named>All Users</cpt:named> -->
+<!--                 </mb3:serviceAction> -->
+<!--                 <mb3:serviceAction objectType="isis.ext.secman.ApplicationUserMenu" id="newDelegateUser"> -->
+<!--                     <cpt:named>New Delegate User</cpt:named> -->
+<!--                 </mb3:serviceAction> -->
             </mb3:section>
         </mb3:menu>
     </mb3:secondary>
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUserManager.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUserManager.java
index 8ae18cd..7bda584 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUserManager.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUserManager.java
@@ -34,10 +34,13 @@ public class ApplicationUserManager {
 
     @Inject private ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository;
 
+    public String title() {
+        return "ApplicationUserManager"; 
+    }
+    
     @Collection
     public java.util.Collection<? extends ApplicationUser> getAllUsers() {
         return applicationUserRepository.allUsers();
     }
     
-    
 }
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUserManager_newDelegateUser.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUserManager_newDelegateUser.java
index c8a013b..30395b2 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUserManager_newDelegateUser.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUserManager_newDelegateUser.java
@@ -20,36 +20,40 @@ package org.apache.isis.extensions.secman.model.dom.user;
 
 import javax.inject.Inject;
 
-import org.apache.isis.applib.annotation.Action;
-import org.apache.isis.applib.annotation.MemberSupport;
 import org.apache.isis.applib.services.repository.RepositoryService;
+import org.apache.isis.extensions.secman.api.SecmanConfiguration;
+import org.apache.isis.extensions.secman.api.SecurityRealmCharacteristic;
+import org.apache.isis.extensions.secman.api.SecurityRealmService;
 import org.apache.isis.extensions.secman.api.role.ApplicationRole;
 import org.apache.isis.extensions.secman.api.role.ApplicationRoleRepository;
 import org.apache.isis.extensions.secman.api.user.ApplicationUser;
-import org.apache.isis.extensions.secman.api.user.ApplicationUser.NewDelegateUserDomainEvent;
 import org.apache.isis.extensions.secman.api.user.ApplicationUserRepository;
 import org.apache.isis.extensions.secman.api.user.ApplicationUserStatus;
 
-import lombok.RequiredArgsConstructor;
+import lombok.val;
 
-@Action(
-        domainEvent = NewDelegateUserDomainEvent.class, 
-        associateWith = "allUsers")
-@RequiredArgsConstructor
-public class ApplicationUserManager_newDelegateUser {
+/**
+ * @apiNote This mixin requires concrete implementations associated with JPA and JDO,
+ * since action's type parameters are inspected for their compile time types 
+ * and the ApplicationRole here is just an interface that the framework has not much 
+ * meta-model information to derive UI behavior from.
+ * 
+ * @implNote due to current limitations, both the main and its supporting methods have to be
+ * overridden with the concrete subclasses. 
+ * 
+ */
+public abstract class ApplicationUserManager_newDelegateUser<R extends ApplicationRole> {
     
-    @Inject private ApplicationRoleRepository<? extends ApplicationRole> applicationRoleRepository;
+    @Inject private ApplicationRoleRepository<R> applicationRoleRepository;
     @Inject private ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository;
+    @Inject private SecmanConfiguration configBean;
     @Inject private RepositoryService repository;
+    @Inject private SecurityRealmService securityRealmService;
 
-    @SuppressWarnings("unused")
-    private final ApplicationUserManager target;
-    
-    @MemberSupport
-    public ApplicationUser act(
-            final String username,
-            final ApplicationRole initialRole,
-            final Boolean enabled) {
+    protected ApplicationUser doAct(
+          final String username,
+          final R initialRole,
+          final Boolean enabled) {
         
         final ApplicationUser user = applicationUserRepository
                 .newDelegateUser(username, ApplicationUserStatus.parse(enabled));
@@ -60,5 +64,25 @@ public class ApplicationUserManager_newDelegateUser {
         repository.persist(user);
         return user;
     }
+    
+    protected boolean doHide() {
+        return hasNoDelegateAuthenticationRealm();
+    }
+
+    protected R doDefault1() {
+        return applicationRoleRepository
+                .findByNameCached(configBean.getRegularUserRoleName())
+                .orElse(null);
+    }
+    
+    // -- HELPER
+    
+    private boolean hasNoDelegateAuthenticationRealm() {
+        val realm = securityRealmService.getCurrentRealm();
+        return realm == null 
+                || !realm.getCharacteristics()
+                    .contains(SecurityRealmCharacteristic.DELEGATING);
+    }
+
 
 }
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUserManager_newLocalUser.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUserManager_newLocalUser.java
index 2a84403..b440c60 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUserManager_newLocalUser.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUserManager_newLocalUser.java
@@ -22,40 +22,39 @@ import java.util.Objects;
 
 import javax.inject.Inject;
 
-import org.apache.isis.applib.annotation.Action;
-import org.apache.isis.applib.annotation.MemberSupport;
 import org.apache.isis.applib.services.factory.FactoryService;
 import org.apache.isis.applib.services.repository.RepositoryService;
 import org.apache.isis.applib.value.Password;
+import org.apache.isis.extensions.secman.api.SecmanConfiguration;
 import org.apache.isis.extensions.secman.api.role.ApplicationRole;
 import org.apache.isis.extensions.secman.api.role.ApplicationRoleRepository;
 import org.apache.isis.extensions.secman.api.user.ApplicationUser;
-import org.apache.isis.extensions.secman.api.user.ApplicationUser.NewLocalUserDomainEvent;
 import org.apache.isis.extensions.secman.api.user.ApplicationUserRepository;
 import org.apache.isis.extensions.secman.api.user.ApplicationUserStatus;
 
-import lombok.RequiredArgsConstructor;
-
-@Action(
-        domainEvent = NewLocalUserDomainEvent.class, 
-        associateWith = "allUsers")
-@RequiredArgsConstructor
-public class ApplicationUserManager_newLocalUser {
+/**
+ * @apiNote This mixin requires concrete implementations associated with JPA and JDO,
+ * since action's type parameters are inspected for their compile time types 
+ * and the ApplicationRole here is just an interface that the framework has not much 
+ * meta-model information to derive UI behavior from.
+ * 
+ * @implNote due to current limitations, both the main and its supporting methods have to be
+ * overridden with the concrete subclasses. 
+ * 
+ */
+public abstract class ApplicationUserManager_newLocalUser<R extends ApplicationRole> {
     
-    @Inject private ApplicationRoleRepository<? extends ApplicationRole> applicationRoleRepository;
+    @Inject private ApplicationRoleRepository<R> applicationRoleRepository;
     @Inject private ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository;
+    @Inject private SecmanConfiguration configBean;
     @Inject private FactoryService factory;
     @Inject private RepositoryService repository;
     
-    @SuppressWarnings("unused")
-    private final ApplicationUserManager target;
-
-    @MemberSupport
-    public ApplicationUser act(
+    protected ApplicationUser doAct(
             final String username,
             final Password password,
             final Password passwordRepeat,
-            final org.apache.isis.extensions.secman.api.role.ApplicationRole initialRole,
+            final R initialRole,
             final Boolean enabled,
             final String emailAddress) {
         
@@ -75,12 +74,11 @@ public class ApplicationUserManager_newLocalUser {
         return user;
     }
 
-    @MemberSupport
-    public String validateAct(
+    protected String doValidate(
             final String username,
             final Password newPassword,
             final Password newPasswordRepeat,
-            final org.apache.isis.extensions.secman.api.role.ApplicationRole initialRole,
+            final R initialRole,
             final Boolean enabled,
             final String emailAddress) {
         
@@ -89,8 +87,13 @@ public class ApplicationUserManager_newLocalUser {
         }
 
         return null;
-
     }
     
+    protected R doDefault3() {
+        return applicationRoleRepository
+                .findByNameCached(configBean.getRegularUserRoleName())
+                .orElse(null);
+    }
+   
 
 }
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUserMenu.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUserMenu.java
index fba5bbf..902eb4d 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUserMenu.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUserMenu.java
@@ -27,18 +27,10 @@ import org.apache.isis.applib.annotation.ActionLayout;
 import org.apache.isis.applib.annotation.DomainService;
 import org.apache.isis.applib.annotation.DomainServiceLayout;
 import org.apache.isis.applib.annotation.NatureOfService;
-import org.apache.isis.applib.annotation.Optionality;
-import org.apache.isis.applib.annotation.Parameter;
 import org.apache.isis.applib.annotation.ParameterLayout;
 import org.apache.isis.applib.annotation.SemanticsOf;
 import org.apache.isis.applib.services.factory.FactoryService;
-import org.apache.isis.applib.value.Password;
 import org.apache.isis.extensions.secman.api.IsisModuleExtSecmanApi;
-import org.apache.isis.extensions.secman.api.SecmanConfiguration;
-import org.apache.isis.extensions.secman.api.SecurityRealmCharacteristic;
-import org.apache.isis.extensions.secman.api.SecurityRealmService;
-import org.apache.isis.extensions.secman.api.role.ApplicationRole;
-import org.apache.isis.extensions.secman.api.role.ApplicationRoleRepository;
 import org.apache.isis.extensions.secman.api.user.ApplicationUser;
 import org.apache.isis.extensions.secman.api.user.ApplicationUserRepository;
 
@@ -54,10 +46,10 @@ import lombok.val;
         )
 public class ApplicationUserMenu {
 
-    @Inject private SecmanConfiguration configBean;
-    @Inject private ApplicationRoleRepository<? extends ApplicationRole> applicationRoleRepository;
+    //@Inject private SecmanConfiguration configBean;
+    //@Inject private ApplicationRoleRepository<? extends ApplicationRole> applicationRoleRepository;
     @Inject private ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository;
-    @Inject private SecurityRealmService securityRealmService;
+    //@Inject private SecurityRealmService securityRealmService;
     @Inject private FactoryService factory;
 
     public static abstract class PropertyDomainEvent<T> 
@@ -89,112 +81,125 @@ public class ApplicationUserMenu {
             final @ParameterLayout(named = "Search") String search) {
         return applicationUserRepository.find(search);
     }
-
-    public static class NewDelegateUserDomainEvent extends ActionDomainEvent {
-    }
-
-    @Action(
-            domainEvent = NewDelegateUserDomainEvent.class,
-            semantics = SemanticsOf.NON_IDEMPOTENT
-            )
-    @ActionLayout(sequence = "100.10.3")
-    @Deprecated
-    public ApplicationUser newDelegateUser(
-            @Parameter(maxLength = ApplicationUser.MAX_LENGTH_USERNAME)
-            @ParameterLayout(named = "Name")
-            final String username,
-            @Parameter(optionality = Optionality.OPTIONAL)
-            @ParameterLayout(named = "Initial role")
-            final ApplicationRole initialRole,
-            @Parameter(optionality = Optionality.OPTIONAL)
-            @ParameterLayout(named = "Enabled?")
-            final Boolean enabled) {
-        
-        val applicationUserManager = factory.viewModel(new ApplicationUserManager());
-        val newDelegateUserMixin = factory.mixin(
-                ApplicationUserManager_newDelegateUser.class, applicationUserManager);
-        return newDelegateUserMixin.act(username, initialRole, enabled);
-    }
-
-    public boolean hideNewDelegateUser() {
-        return hasNoDelegateAuthenticationRealm();
-    }
-
-    public ApplicationRole default1NewDelegateUser() {
-        return applicationRoleRepository.findByNameCached(configBean.getRegularUserRoleName()).orElse(null);
+    
+    public static class ApplicationUserManagerDomainEvent extends ActionDomainEvent {
     }
-
-    public static class NewLocalUserDomainEvent extends ActionDomainEvent {
-    }
-
+    
     @Action(
-            domainEvent = NewLocalUserDomainEvent.class,
+            domainEvent = ApplicationUserManagerDomainEvent.class,
             semantics = SemanticsOf.IDEMPOTENT
             )
-    @ActionLayout(sequence = "100.10.4")
-    @Deprecated
-    public ApplicationUser newLocalUser(
-            @Parameter(maxLength = ApplicationUser.MAX_LENGTH_USERNAME)
-            @ParameterLayout(named = "Name")
-            final String username,
-            @Parameter(optionality = Optionality.OPTIONAL)
-            @ParameterLayout(named = "Password")
-            final Password password,
-            @Parameter(optionality = Optionality.OPTIONAL)
-            @ParameterLayout(named = "Repeat password")
-            final Password passwordRepeat,
-            @Parameter(optionality = Optionality.OPTIONAL)
-            @ParameterLayout(named = "Initial role")
-            final ApplicationRole initialRole,
-            @Parameter(optionality = Optionality.OPTIONAL)
-            @ParameterLayout(named = "Enabled?")
-            final Boolean enabled,
-            @Parameter(optionality = Optionality.OPTIONAL)
-            @ParameterLayout(named = "Email Address")
-            final String emailAddress) {
-        
-        val applicationUserManager = factory.viewModel(new ApplicationUserManager());
-        val newLocalUserMixin = factory.mixin(
-                ApplicationUserManager_newLocalUser.class, applicationUserManager);
-        return newLocalUserMixin.act(username, password, passwordRepeat, initialRole, enabled, emailAddress);
-    }
-
-    public String validateNewLocalUser(
-            final String username,
-            final Password password,
-            final Password passwordRepeat,
-            final ApplicationRole initialRole,
-            final Boolean enabled,
-            final String emailAddress) {
-        
+    @ActionLayout(
+            sequence = "100.10.3",
+            cssClassFa = "user-plus" )
+    public ApplicationUserManager userManager() {
         val applicationUserManager = factory.viewModel(new ApplicationUserManager());
-        val newLocalUserMixin = factory.mixin(
-                ApplicationUserManager_newLocalUser.class, applicationUserManager);
-        
-        return newLocalUserMixin.validateAct(
-                username, password, passwordRepeat, initialRole, enabled, emailAddress);
-    }
-
-    public ApplicationRole default3NewLocalUser() {
-        return applicationRoleRepository.findByNameCached(configBean.getRegularUserRoleName()).orElse(null);
-    }
-
-    public static class AllUsersDomainEvent extends ActionDomainEvent {
-    }
-
-    @Action(
-            domainEvent = AllUsersDomainEvent.class,
-            semantics = SemanticsOf.SAFE
-            )
-    @ActionLayout(sequence = "100.10.5")
-    public Collection<? extends ApplicationUser> allUsers() {
-        return applicationUserRepository.allUsers();
-    }
-
-    private boolean hasNoDelegateAuthenticationRealm() {
-        val realm = securityRealmService.getCurrentRealm();
-        return realm == null || !realm.getCharacteristics().contains(SecurityRealmCharacteristic.DELEGATING);
-    }
+        return applicationUserManager;
+    }
+
+//    public static class NewDelegateUserDomainEvent extends ActionDomainEvent {
+//    }
+//
+//    @Action(
+//            domainEvent = NewDelegateUserDomainEvent.class,
+//            semantics = SemanticsOf.NON_IDEMPOTENT
+//            )
+//    @ActionLayout(sequence = "100.10.3", cssClassFa = "user-plus")
+//    public ApplicationUser newDelegateUser(
+//            @Parameter(maxLength = ApplicationUser.MAX_LENGTH_USERNAME)
+//            @ParameterLayout(named = "Name")
+//            final String username,
+//            @Parameter(optionality = Optionality.OPTIONAL)
+//            @ParameterLayout(named = "Initial role")
+//            final ApplicationRole initialRole,
+//            @Parameter(optionality = Optionality.OPTIONAL)
+//            @ParameterLayout(named = "Enabled?")
+//            final Boolean enabled) {
+//        
+//        val applicationUserManager = factory.viewModel(new ApplicationUserManager());
+//        val newDelegateUserMixin = factory.mixin(
+//                ApplicationUserManager_newDelegateUser.class, applicationUserManager);
+//        return newDelegateUserMixin.act(username, initialRole, enabled);
+//    }
+//
+//    public boolean hideNewDelegateUser() {
+//        return hasNoDelegateAuthenticationRealm();
+//    }
+//
+//    public ApplicationRole default1NewDelegateUser() {
+//        return applicationRoleRepository.findByNameCached(configBean.getRegularUserRoleName()).orElse(null);
+//    }
+
+//    public static class NewLocalUserDomainEvent extends ActionDomainEvent {
+//    }
+//
+//    @Action(
+//            domainEvent = NewLocalUserDomainEvent.class,
+//            semantics = SemanticsOf.IDEMPOTENT
+//            )
+//    @ActionLayout(sequence = "100.10.4", cssClassFa = "user-plus")
+//    public ApplicationUser newLocalUser(
+//            @Parameter(maxLength = ApplicationUser.MAX_LENGTH_USERNAME)
+//            @ParameterLayout(named = "Name")
+//            final String username,
+//            @Parameter(optionality = Optionality.OPTIONAL)
+//            @ParameterLayout(named = "Password")
+//            final Password password,
+//            @Parameter(optionality = Optionality.OPTIONAL)
+//            @ParameterLayout(named = "Repeat password")
+//            final Password passwordRepeat,
+//            @Parameter(optionality = Optionality.OPTIONAL)
+//            @ParameterLayout(named = "Initial role")
+//            final ApplicationRole initialRole,
+//            @Parameter(optionality = Optionality.OPTIONAL)
+//            @ParameterLayout(named = "Enabled?")
+//            final Boolean enabled,
+//            @Parameter(optionality = Optionality.OPTIONAL)
+//            @ParameterLayout(named = "Email Address")
+//            final String emailAddress) {
+//        
+//        val applicationUserManager = factory.viewModel(new ApplicationUserManager());
+//        val newLocalUserMixin = factory.mixin(
+//                ApplicationUserManager_newLocalUser.class, applicationUserManager);
+//        return newLocalUserMixin.doAct(username, password, passwordRepeat, initialRole, enabled, emailAddress);
+//    }
+//
+//    public String validateNewLocalUser(
+//            final String username,
+//            final Password password,
+//            final Password passwordRepeat,
+//            final ApplicationRole initialRole,
+//            final Boolean enabled,
+//            final String emailAddress) {
+//        
+//        val applicationUserManager = factory.viewModel(new ApplicationUserManager());
+//        val newLocalUserMixin = factory.mixin(
+//                ApplicationUserManager_newLocalUser.class, applicationUserManager);
+//        
+//        return newLocalUserMixin.doValidate(
+//                username, password, passwordRepeat, initialRole, enabled, emailAddress);
+//    }
+//
+//    public ApplicationRole default3NewLocalUser() {
+//        return applicationRoleRepository.findByNameCached(configBean.getRegularUserRoleName()).orElse(null);
+//    }
+
+//    public static class AllUsersDomainEvent extends ActionDomainEvent {
+//    }
+//
+//    @Action(
+//            domainEvent = AllUsersDomainEvent.class,
+//            semantics = SemanticsOf.SAFE
+//            )
+//    @ActionLayout(sequence = "100.10.5")
+//    public Collection<? extends ApplicationUser> allUsers() {
+//        return applicationUserRepository.allUsers();
+//    }
+//
+//    private boolean hasNoDelegateAuthenticationRealm() {
+//        val realm = securityRealmService.getCurrentRealm();
+//        return realm == null || !realm.getCharacteristics().contains(SecurityRealmCharacteristic.DELEGATING);
+//    }
 
 
 
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUserManager_newDelegateUser.java b/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/user/ApplicationUserManager_newDelegateUser.java
similarity index 52%
copy from extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUserManager_newDelegateUser.java
copy to extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/user/ApplicationUserManager_newDelegateUser.java
index c8a013b..df09a02 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUserManager_newDelegateUser.java
+++ b/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/user/ApplicationUserManager_newDelegateUser.java
@@ -16,19 +16,17 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.extensions.secman.model.dom.user;
-
-import javax.inject.Inject;
+package org.apache.isis.extensions.secman.jdo.dom.user;
 
 import org.apache.isis.applib.annotation.Action;
 import org.apache.isis.applib.annotation.MemberSupport;
-import org.apache.isis.applib.services.repository.RepositoryService;
-import org.apache.isis.extensions.secman.api.role.ApplicationRole;
-import org.apache.isis.extensions.secman.api.role.ApplicationRoleRepository;
+import org.apache.isis.applib.annotation.Optionality;
+import org.apache.isis.applib.annotation.Parameter;
+import org.apache.isis.applib.annotation.ParameterLayout;
 import org.apache.isis.extensions.secman.api.user.ApplicationUser;
 import org.apache.isis.extensions.secman.api.user.ApplicationUser.NewDelegateUserDomainEvent;
-import org.apache.isis.extensions.secman.api.user.ApplicationUserRepository;
-import org.apache.isis.extensions.secman.api.user.ApplicationUserStatus;
+import org.apache.isis.extensions.secman.jdo.dom.role.ApplicationRole;
+import org.apache.isis.extensions.secman.model.dom.user.ApplicationUserManager;
 
 import lombok.RequiredArgsConstructor;
 
@@ -36,29 +34,40 @@ import lombok.RequiredArgsConstructor;
         domainEvent = NewDelegateUserDomainEvent.class, 
         associateWith = "allUsers")
 @RequiredArgsConstructor
-public class ApplicationUserManager_newDelegateUser {
+public class ApplicationUserManager_newDelegateUser
+extends org.apache.isis.extensions.secman.model.dom.user.ApplicationUserManager_newDelegateUser<ApplicationRole>{
     
-    @Inject private ApplicationRoleRepository<? extends ApplicationRole> applicationRoleRepository;
-    @Inject private ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository;
-    @Inject private RepositoryService repository;
-
     @SuppressWarnings("unused")
     private final ApplicationUserManager target;
     
     @MemberSupport
     public ApplicationUser act(
-            final String username,
-            final ApplicationRole initialRole,
-            final Boolean enabled) {
+            
+          @Parameter(maxLength = ApplicationUser.MAX_LENGTH_USERNAME)
+          @ParameterLayout(named = "Name")
+          final String username,
+            
+          @Parameter(optionality = Optionality.OPTIONAL)
+          @ParameterLayout(named = "Initial role")
+          final ApplicationRole initialRole,
+            
+          @Parameter(optionality = Optionality.OPTIONAL)
+          @ParameterLayout(named = "Enabled?")
+          final Boolean enabled
+            
+            ) {
         
-        final ApplicationUser user = applicationUserRepository
-                .newDelegateUser(username, ApplicationUserStatus.parse(enabled));
+        return super.doAct(username, initialRole, enabled);
+    }
+    
+    @MemberSupport
+    public boolean hideAct() {
+        return super.doHide();
+    }
 
-        if (initialRole != null) {
-            applicationRoleRepository.addRoleToUser(initialRole, user);
-        }
-        repository.persist(user);
-        return user;
+    @MemberSupport
+    public ApplicationRole default1Act() {
+        return super.doDefault1();
     }
 
 }
diff --git a/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/user/ApplicationUserManager_newLocalUser.java b/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/user/ApplicationUserManager_newLocalUser.java
new file mode 100644
index 0000000..63be89b
--- /dev/null
+++ b/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/user/ApplicationUserManager_newLocalUser.java
@@ -0,0 +1,90 @@
+/*
+ *  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.jdo.dom.user;
+
+import org.apache.isis.applib.annotation.Action;
+import org.apache.isis.applib.annotation.MemberSupport;
+import org.apache.isis.applib.annotation.Optionality;
+import org.apache.isis.applib.annotation.Parameter;
+import org.apache.isis.applib.annotation.ParameterLayout;
+import org.apache.isis.applib.value.Password;
+import org.apache.isis.extensions.secman.api.user.ApplicationUser;
+import org.apache.isis.extensions.secman.api.user.ApplicationUser.NewLocalUserDomainEvent;
+import org.apache.isis.extensions.secman.jdo.dom.role.ApplicationRole;
+import org.apache.isis.extensions.secman.model.dom.user.ApplicationUserManager;
+
+import lombok.RequiredArgsConstructor;
+
+@Action(
+        domainEvent = NewLocalUserDomainEvent.class, 
+        associateWith = "allUsers")
+@RequiredArgsConstructor
+public class ApplicationUserManager_newLocalUser
+extends org.apache.isis.extensions.secman.model.dom.user.ApplicationUserManager_newLocalUser<ApplicationRole> {
+    
+    @SuppressWarnings("unused")
+    private final ApplicationUserManager target;
+    
+    @MemberSupport
+    public ApplicationUser act(
+          @Parameter(maxLength = ApplicationUser.MAX_LENGTH_USERNAME)
+          @ParameterLayout(named = "Name")
+          final String username,
+          
+          @Parameter(optionality = Optionality.OPTIONAL)
+          @ParameterLayout(named = "Password")
+          final Password password,
+          
+          @Parameter(optionality = Optionality.OPTIONAL)
+          @ParameterLayout(named = "Repeat password")
+          final Password passwordRepeat,
+          
+          @Parameter(optionality = Optionality.OPTIONAL)
+          @ParameterLayout(named = "Initial role")
+          final ApplicationRole initialRole,
+          
+          @Parameter(optionality = Optionality.OPTIONAL)
+          @ParameterLayout(named = "Enabled?")
+          final Boolean enabled,
+          
+          @Parameter(optionality = Optionality.OPTIONAL)
+          @ParameterLayout(named = "Email Address")
+          final String emailAddress) {
+        return super.doAct(username, password, passwordRepeat, initialRole, enabled, emailAddress);
+    }
+    
+    @MemberSupport
+    public String validateAct(
+            final String username,
+            final Password newPassword,
+            final Password newPasswordRepeat,
+            final ApplicationRole initialRole,
+            final Boolean enabled,
+            final String emailAddress) {
+        
+        return super.doValidate(username, newPassword, newPasswordRepeat, initialRole, enabled, emailAddress);
+    }
+    
+    @MemberSupport
+    public ApplicationRole default3Act() {
+        return super.doDefault3();
+    }
+  
+
+}
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUserManager_newDelegateUser.java b/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/dom/user/ApplicationUserManager_newDelegateUser.java
similarity index 52%
copy from extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUserManager_newDelegateUser.java
copy to extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/dom/user/ApplicationUserManager_newDelegateUser.java
index c8a013b..eb12063 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/ApplicationUserManager_newDelegateUser.java
+++ b/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/dom/user/ApplicationUserManager_newDelegateUser.java
@@ -16,19 +16,17 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.extensions.secman.model.dom.user;
-
-import javax.inject.Inject;
+package org.apache.isis.extensions.secman.jpa.dom.user;
 
 import org.apache.isis.applib.annotation.Action;
 import org.apache.isis.applib.annotation.MemberSupport;
-import org.apache.isis.applib.services.repository.RepositoryService;
-import org.apache.isis.extensions.secman.api.role.ApplicationRole;
-import org.apache.isis.extensions.secman.api.role.ApplicationRoleRepository;
+import org.apache.isis.applib.annotation.Optionality;
+import org.apache.isis.applib.annotation.Parameter;
+import org.apache.isis.applib.annotation.ParameterLayout;
 import org.apache.isis.extensions.secman.api.user.ApplicationUser;
 import org.apache.isis.extensions.secman.api.user.ApplicationUser.NewDelegateUserDomainEvent;
-import org.apache.isis.extensions.secman.api.user.ApplicationUserRepository;
-import org.apache.isis.extensions.secman.api.user.ApplicationUserStatus;
+import org.apache.isis.extensions.secman.jpa.dom.role.ApplicationRole;
+import org.apache.isis.extensions.secman.model.dom.user.ApplicationUserManager;
 
 import lombok.RequiredArgsConstructor;
 
@@ -36,29 +34,40 @@ import lombok.RequiredArgsConstructor;
         domainEvent = NewDelegateUserDomainEvent.class, 
         associateWith = "allUsers")
 @RequiredArgsConstructor
-public class ApplicationUserManager_newDelegateUser {
+public class ApplicationUserManager_newDelegateUser
+extends org.apache.isis.extensions.secman.model.dom.user.ApplicationUserManager_newDelegateUser<ApplicationRole>{
     
-    @Inject private ApplicationRoleRepository<? extends ApplicationRole> applicationRoleRepository;
-    @Inject private ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository;
-    @Inject private RepositoryService repository;
-
     @SuppressWarnings("unused")
     private final ApplicationUserManager target;
     
     @MemberSupport
     public ApplicationUser act(
-            final String username,
-            final ApplicationRole initialRole,
-            final Boolean enabled) {
+            
+          @Parameter(maxLength = ApplicationUser.MAX_LENGTH_USERNAME)
+          @ParameterLayout(named = "Name")
+          final String username,
+            
+          @Parameter(optionality = Optionality.OPTIONAL)
+          @ParameterLayout(named = "Initial role")
+          final ApplicationRole initialRole,
+            
+          @Parameter(optionality = Optionality.OPTIONAL)
+          @ParameterLayout(named = "Enabled?")
+          final Boolean enabled
+            
+            ) {
         
-        final ApplicationUser user = applicationUserRepository
-                .newDelegateUser(username, ApplicationUserStatus.parse(enabled));
+        return super.doAct(username, initialRole, enabled);
+    }
+    
+    @MemberSupport
+    public boolean hideAct() {
+        return super.doHide();
+    }
 
-        if (initialRole != null) {
-            applicationRoleRepository.addRoleToUser(initialRole, user);
-        }
-        repository.persist(user);
-        return user;
+    @MemberSupport
+    public ApplicationRole default1Act() {
+        return super.doDefault1();
     }
 
 }
diff --git a/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/dom/user/ApplicationUserManager_newLocalUser.java b/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/dom/user/ApplicationUserManager_newLocalUser.java
new file mode 100644
index 0000000..ac0173b
--- /dev/null
+++ b/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/dom/user/ApplicationUserManager_newLocalUser.java
@@ -0,0 +1,89 @@
+/*
+ *  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.jpa.dom.user;
+
+import org.apache.isis.applib.annotation.Action;
+import org.apache.isis.applib.annotation.MemberSupport;
+import org.apache.isis.applib.annotation.Optionality;
+import org.apache.isis.applib.annotation.Parameter;
+import org.apache.isis.applib.annotation.ParameterLayout;
+import org.apache.isis.applib.value.Password;
+import org.apache.isis.extensions.secman.api.user.ApplicationUser;
+import org.apache.isis.extensions.secman.api.user.ApplicationUser.NewLocalUserDomainEvent;
+import org.apache.isis.extensions.secman.jpa.dom.role.ApplicationRole;
+import org.apache.isis.extensions.secman.model.dom.user.ApplicationUserManager;
+
+import lombok.RequiredArgsConstructor;
+
+@Action(
+        domainEvent = NewLocalUserDomainEvent.class, 
+        associateWith = "allUsers")
+@RequiredArgsConstructor
+public class ApplicationUserManager_newLocalUser 
+extends org.apache.isis.extensions.secman.model.dom.user.ApplicationUserManager_newLocalUser<ApplicationRole> {
+    
+    @SuppressWarnings("unused")
+    private final ApplicationUserManager target;
+    
+    @MemberSupport
+    public ApplicationUser act(
+          @Parameter(maxLength = ApplicationUser.MAX_LENGTH_USERNAME)
+          @ParameterLayout(named = "Name")
+          final String username,
+          
+          @Parameter(optionality = Optionality.OPTIONAL)
+          @ParameterLayout(named = "Password")
+          final Password password,
+          
+          @Parameter(optionality = Optionality.OPTIONAL)
+          @ParameterLayout(named = "Repeat password")
+          final Password passwordRepeat,
+          
+          @Parameter(optionality = Optionality.OPTIONAL)
+          @ParameterLayout(named = "Initial role")
+          final ApplicationRole initialRole,
+          
+          @Parameter(optionality = Optionality.OPTIONAL)
+          @ParameterLayout(named = "Enabled?")
+          final Boolean enabled,
+          
+          @Parameter(optionality = Optionality.OPTIONAL)
+          @ParameterLayout(named = "Email Address")
+          final String emailAddress) {
+        return super.doAct(username, password, passwordRepeat, initialRole, enabled, emailAddress);
+    }
+    
+    @MemberSupport
+    public String validateAct(
+            final String username,
+            final Password newPassword,
+            final Password newPasswordRepeat,
+            final ApplicationRole initialRole,
+            final Boolean enabled,
+            final String emailAddress) {
+        
+        return super.doValidate(username, newPassword, newPasswordRepeat, initialRole, enabled, emailAddress);
+    }
+    
+    @MemberSupport
+    public ApplicationRole default3Act() {
+        return super.doDefault3();
+    }
+
+}