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 2022/08/23 17:05:26 UTC
[isis] 01/02: ISIS-3169: also adds auto-created users to a set of initial roles.
This is an automated email from the ASF dual-hosted git repository.
danhaywood pushed a commit to branch ISIS-3169
in repository https://gitbox.apache.org/repos/asf/isis.git
commit 849917841242f7e98dcda709583ddbb19e53efa3
Author: Dan Haywood <da...@haywood-associates.co.uk>
AuthorDate: Tue Aug 23 16:29:50 2022 +0100
ISIS-3169: also adds auto-created users to a set of initial roles.
---
.../apache/isis/core/config/IsisConfiguration.java | 17 +++++++-
.../dom/ApplicationUserAutoCreationService.java | 47 ++++++++++++++++++++--
2 files changed, 60 insertions(+), 4 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 2be200a9fe..c6bb6c980b 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
@@ -3105,7 +3105,6 @@ public class IsisConfiguration {
public enum AutoCreatePolicy {
AUTO_CREATE_AS_LOCKED,
AUTO_CREATE_AS_UNLOCKED,
- // NO_AUTO_CREATE
}
/**
@@ -3115,10 +3114,26 @@ public class IsisConfiguration {
* 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>
+ *
+ * <p>
+ * NOTE also that this configuration policy is ignored if running secman with Spring OAuth2
+ * or Keycloak as the authenticator; users are always auto-created.
+ * </p>
*/
@Getter @Setter
private AutoCreatePolicy autoCreatePolicy = AutoCreatePolicy.AUTO_CREATE_AS_LOCKED;
+ /**
+ * The set of roles that users that have been automatically created are granted automatically.
+ *
+ * <p>
+ * Typically the regular user role (as per <code>isis.secman.seed.regular-user.role-name</code>
+ * will be one of the roles listed here; that will provide the ability for the end-user to logout,
+ * among other things (!).
+ * </p>
+ */
+ private List<String> initialRoleNames = new ArrayList<>();
+
}
public enum PermissionsEvaluationPolicy {
diff --git a/extensions/security/secman/delegated-springoauth2/src/main/java/org/apache/isis/extensions/secman/delegated/springoauth2/dom/ApplicationUserAutoCreationService.java b/extensions/security/secman/delegated-springoauth2/src/main/java/org/apache/isis/extensions/secman/delegated/springoauth2/dom/ApplicationUserAutoCreationService.java
index f485a6825e..85289c6e31 100644
--- a/extensions/security/secman/delegated-springoauth2/src/main/java/org/apache/isis/extensions/secman/delegated/springoauth2/dom/ApplicationUserAutoCreationService.java
+++ b/extensions/security/secman/delegated-springoauth2/src/main/java/org/apache/isis/extensions/secman/delegated/springoauth2/dom/ApplicationUserAutoCreationService.java
@@ -20,16 +20,27 @@
package org.apache.isis.extensions.secman.delegated.springoauth2.dom;
+import java.util.Collection;
+import java.util.List;
+import java.util.Optional;
+
import javax.inject.Inject;
import org.springframework.context.ApplicationListener;
+import org.springframework.lang.Nullable;
import org.springframework.security.authentication.event.InteractiveAuthenticationSuccessEvent;
import org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser;
import org.springframework.stereotype.Service;
+import org.apache.isis.applib.services.factory.FactoryService;
import org.apache.isis.applib.services.iactnlayer.InteractionService;
+import org.apache.isis.core.config.IsisConfiguration;
+import org.apache.isis.extensions.secman.applib.role.dom.ApplicationRoleRepository;
+import org.apache.isis.extensions.secman.applib.user.dom.ApplicationUser;
import org.apache.isis.extensions.secman.applib.user.dom.ApplicationUserRepository;
import org.apache.isis.extensions.secman.applib.user.dom.ApplicationUserStatus;
+import org.apache.isis.extensions.secman.applib.user.dom.mixins.ApplicationUser_addRole;
+import org.apache.isis.extensions.secman.applib.user.dom.mixins.ApplicationUser_updateEmailAddress;
import lombok.RequiredArgsConstructor;
import lombok.val;
@@ -40,7 +51,10 @@ public class ApplicationUserAutoCreationService
implements ApplicationListener<InteractiveAuthenticationSuccessEvent> {
private final ApplicationUserRepository applicationUserRepository;
+ private final ApplicationRoleRepository applicationRoleRepository;
private final InteractionService interactionService;
+ private final IsisConfiguration isisConfiguration;
+ private final FactoryService factoryService;
@Override
public void onApplicationEvent(final InteractiveAuthenticationSuccessEvent event) {
@@ -53,8 +67,35 @@ public class ApplicationUserAutoCreationService
val oidcUser = (DefaultOidcUser) principal;
val username = oidcUser.getIdToken().getPreferredUsername();
val email = oidcUser.getIdToken().getEmail();
- val applicationUser = interactionService.callAnonymous(() -> applicationUserRepository.findOrCreateUserByUsername(username));
- applicationUser.setEmailAddress(email);
- applicationUser.setStatus(ApplicationUserStatus.UNLOCKED); // locking not supported for keycloak
+ interactionService.runAnonymous(() -> {
+ Optional<ApplicationUser> userIfAny = applicationUserRepository.findByUsername(username);
+ if (userIfAny.isEmpty()) {
+ val status = ApplicationUserStatus.UNLOCKED; // locking not supported for spring delegated accounts
+ val applicationUser = applicationUserRepository.newDelegateUser(username, status);
+ factoryService.mixin(ApplicationUser_updateEmailAddress.class, applicationUser).act(email);
+
+ val initialRoleNames = isisConfiguration.getExtensions().getSecman().getDelegatedUsers().getInitialRoleNames();
+ if (notEmpty(initialRoleNames)) {
+ for (String initialRoleName : initialRoleNames) {
+ addRoleIfExists(applicationUser, initialRoleName);
+ }
+ }
+ }
+ });
}
+
+ private void addRoleIfExists(ApplicationUser applicationUser, String initialRoleName) {
+ applicationRoleRepository.findByName(initialRoleName).ifPresent(role -> {
+ factoryService.mixin(ApplicationUser_addRole.class, applicationUser).act(role);
+ });
+ }
+
+ private static boolean notEmpty(List<String> initialRoleNames) {
+ return !isEmpty(initialRoleNames);
+ }
+
+ private static boolean isEmpty(@Nullable Collection<?> collection) {
+ return collection == null || collection.isEmpty();
+ }
+
}