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 f96ddd329b ISIS-3283: fixes unreachable code in keycloak integration
f96ddd329b is described below

commit f96ddd329ba8ab54fa94031f38f0425235ef8ed1
Author: andi-huber <ahu...@apache.org>
AuthorDate: Sat Nov 19 08:51:35 2022 +0100

    ISIS-3283: fixes unreachable code in keycloak integration
---
 security/keycloak/src/main/java/module-info.java   |   1 +
 .../services/KeycloakOauth2UserService.java        | 112 ++++++++++-----------
 2 files changed, 56 insertions(+), 57 deletions(-)

diff --git a/security/keycloak/src/main/java/module-info.java 
b/security/keycloak/src/main/java/module-info.java
index ba9fcba7d5..b964fd68d4 100644
--- a/security/keycloak/src/main/java/module-info.java
+++ b/security/keycloak/src/main/java/module-info.java
@@ -39,4 +39,5 @@ module org.apache.causeway.security.keycloak {
     requires spring.security.oauth2.jose;
     requires spring.security.web;
     requires spring.web;
+    requires org.apache.causeway.commons;
 }
\ No newline at end of file
diff --git 
a/security/keycloak/src/main/java/org/apache/causeway/security/keycloak/services/KeycloakOauth2UserService.java
 
b/security/keycloak/src/main/java/org/apache/causeway/security/keycloak/services/KeycloakOauth2UserService.java
index 88e561b459..8fd40dc317 100644
--- 
a/security/keycloak/src/main/java/org/apache/causeway/security/keycloak/services/KeycloakOauth2UserService.java
+++ 
b/security/keycloak/src/main/java/org/apache/causeway/security/keycloak/services/KeycloakOauth2UserService.java
@@ -26,7 +26,10 @@ import java.util.Map;
 import java.util.Objects;
 import java.util.Optional;
 import java.util.Set;
+import java.util.function.Consumer;
+import java.util.function.Predicate;
 
+import org.springframework.lang.Nullable;
 import org.springframework.security.core.GrantedAuthority;
 import org.springframework.security.core.authority.AuthorityUtils;
 import 
org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
@@ -42,8 +45,11 @@ import org.springframework.security.oauth2.jwt.JwtDecoder;
 import org.springframework.security.oauth2.jwt.JwtException;
 import org.springframework.util.CollectionUtils;
 
+import org.apache.causeway.commons.internal.base._Casts;
+import org.apache.causeway.commons.internal.base._NullSafe;
 import org.apache.causeway.core.config.CausewayConfiguration;
 
+import lombok.NonNull;
 import lombok.RequiredArgsConstructor;
 import lombok.val;
 
@@ -65,7 +71,7 @@ public class KeycloakOauth2UserService extends 
OidcUserService {
      * {@link OidcUserRequest}.
      */
     @Override
-    public OidcUser loadUser(OidcUserRequest userRequest) throws 
OAuth2AuthenticationException {
+    public OidcUser loadUser(final OidcUserRequest userRequest) throws 
OAuth2AuthenticationException {
 
         OidcUser user = super.loadUser(userRequest);
 
@@ -83,75 +89,45 @@ public class KeycloakOauth2UserService extends 
OidcUserService {
      * @param userRequest
      * @return
      */
-    private Collection<? extends GrantedAuthority> 
extractKeycloakAuthorities(OidcUserRequest userRequest) {
+    private Collection<? extends GrantedAuthority> 
extractKeycloakAuthorities(final OidcUserRequest userRequest) {
 
         Jwt token = parseJwt(userRequest.getAccessToken().getTokenValue());
 
-        List<String> combinedRoles = new ArrayList<>();
+        final List<String> combinedRoles = new ArrayList<>();
 
         
if(causewayConfiguration.getSecurity().getKeycloak().isExtractClientRoles()) {
-
             // attempt to parse out 'resource_access.${client_id}.roles'
-
-            val resourceObj = token.getClaims().get("resource_access");
-            if (resourceObj instanceof Map) {
-                @SuppressWarnings("rawtypes")
-                val resourceMap = (Map) resourceObj;
-
-                val clientId = 
userRequest.getClientRegistration().getClientId();
-                val clientResourceObj = resourceMap.get(clientId);
-                if(clientResourceObj instanceof Map) {
-                    @SuppressWarnings("rawtypes")
-                    val clientResource = (Map) clientResourceObj;
-                    if (!CollectionUtils.isEmpty(clientResource)) {
-                        val clientRolesObj = clientResource.get("roles");
-                        if (clientResourceObj instanceof List) {
-                            @SuppressWarnings("unchecked")
-                            val clientRoles = (List<Object>) clientRolesObj;
-                            if (!CollectionUtils.isEmpty(clientRoles)) {
-                                val prefix = 
Optional.ofNullable(causewayConfiguration.getSecurity().getKeycloak().getClientRolePrefix()).orElse("");
-                                clientRoles.stream()
-                                        .filter(Objects::nonNull)
-                                        .map(clientRole -> prefix + clientRole)
-                                        .forEach(combinedRoles::add);
-                            }
-                        }
-                    }
-                }
-            }
+            val rolePrefix = 
Optional.ofNullable(causewayConfiguration.getSecurity().getKeycloak().getClientRolePrefix()).orElse("");
+            asNonEmptyMap(token.getClaims().get("resource_access"))
+            .ifPresent(resourceMap->{
+                final String clientId = 
userRequest.getClientRegistration().getClientId();
+                asNonEmptyMap(resourceMap.get(clientId))
+                
.flatMap(clientResource->asNonEmptyCollection(clientResource.get("roles")))
+                .ifPresent(clientRoles->
+                    forEachNonNullIn(clientRoles, clientRole -> 
combinedRoles.add(rolePrefix + clientRole))
+                );
+            });
         }
 
         if 
(causewayConfiguration.getSecurity().getKeycloak().isExtractRealmRoles()) {
             // attempt to parse out 'realm_access.roles'
-            val realmAccessObj = token.getClaims().get("realm_access");
-            if (realmAccessObj instanceof Map) {
-                @SuppressWarnings("rawtypes")
-                val realmAccessMap = (Map)realmAccessObj;
-                Object realmRolesObj = realmAccessMap.get("roles");
-                if (realmRolesObj instanceof List) {
-                    @SuppressWarnings("unchecked")
-                    val realmRoles = (List<Object>) realmRolesObj;
-                    val prefix = 
Optional.ofNullable(causewayConfiguration.getSecurity().getKeycloak().getRealmRolePrefix()).orElse("");
-                    realmRoles.stream()
-                            .filter(Objects::nonNull)
-                            .map(realmRole -> prefix + realmRole)
-                            .forEach(combinedRoles::add);
-                }
-            }
+            val rolePrefix = 
Optional.ofNullable(causewayConfiguration.getSecurity().getKeycloak().getRealmRolePrefix()).orElse("");
+            asNonEmptyMap(token.getClaims().get("realm_access"))
+            .ifPresent(realmAccessMap->{
+                asNonEmptyCollection(realmAccessMap.get("roles"))
+                .ifPresent(realmRoles->{
+                    forEachNonNullIn(realmRoles, realmRole -> 
combinedRoles.add(rolePrefix + realmRole));
+                });
+            });
         }
 
         if 
(causewayConfiguration.getSecurity().getKeycloak().isExtractRoles()) {
             // attempt to parse out 'roles'
-            val rolesObj = token.getClaims().get("roles");
-            if (rolesObj instanceof List) {
-                @SuppressWarnings("unchecked")
-                val roles = (List<Object>) rolesObj;
-                val prefix = 
Optional.ofNullable(causewayConfiguration.getSecurity().getKeycloak().getRolePrefix()).orElse("");
-                roles.stream()
-                        .filter(Objects::nonNull)
-                        .map(role -> prefix + role)
-                        .forEach(combinedRoles::add);
-            }
+            val rolePrefix = 
Optional.ofNullable(causewayConfiguration.getSecurity().getKeycloak().getRolePrefix()).orElse("");
+            asNonEmptyCollection(token.getClaims().get("roles"))
+            .ifPresent(roles->{
+                forEachNonNullIn(roles, role -> combinedRoles.add(rolePrefix + 
role));
+            });
         }
 
         Collection<? extends GrantedAuthority> authorities = 
AuthorityUtils.createAuthorityList(combinedRoles.toArray(new String[]{}));
@@ -161,7 +137,29 @@ public class KeycloakOauth2UserService extends 
OidcUserService {
 
     }
 
-    private Jwt parseJwt(String accessTokenValue) {
+    // -- HELPER
+
+    @SuppressWarnings("rawtypes")
+    private Optional<Map> asNonEmptyMap(final @Nullable Object x){
+        return _Casts.castTo(Map.class, x)
+                .filter(Predicate.not(_NullSafe::isEmpty));
+    }
+
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    private void forEachNonNullIn(final @NonNull Collection x, final @NonNull 
Consumer<Object> _do){
+        x.stream()
+                .filter(Objects::nonNull)
+                .forEach(_do);
+    }
+
+    @SuppressWarnings("rawtypes")
+    private Optional<Collection> asNonEmptyCollection(final @Nullable Object 
x){
+        return _Casts.castTo(Collection.class, x)
+                .filter(Predicate.not(_NullSafe::isEmpty));
+    }
+
+
+    private Jwt parseJwt(final String accessTokenValue) {
         try {
             // Token is already verified by spring security infrastructure
             return jwtDecoder.decode(accessTokenValue);

Reply via email to