From 7e691a4f5367a49fc3f5f73b023275638580c90a Mon Sep 17 00:00:00 2001 From: Albert Louis Rossi Date: Tue, 5 Sep 2023 07:18:14 -0500 Subject: [PATCH] dcache-frontend,dcache-webdav: use RolePrincipal instead of LoginAttributes roles Motivation: modification of the QoS of files; but this mechanism offers a simpler solution for defining roles in the frontend as well. Modification: Replace the definition of the `admin` privileges based on the assertion of the `RolesPlugin` `DesiredRole` with one which inspects the user's Subject for the `RolePrincipal`. Result: No need to assert a desired role; roles are assigned automatically on the basis of user mappings in the `Multimap` plugin. This greatly facilitates the use of administrative-restrictive functions in `dCacheView` and `Swagger` (see the next patch, Target: master Patch: https://rb.dcache.org/r/14083/ Requires-notes: yes (eventually pointing to the deprecation of the use of the RolesPlugin). Acked-by: Tigran --- .../java/org/dcache/restful/ApiConfig.java | 7 +---- .../resources/identity/UserResource.java | 27 ++++++++++--------- .../restful/util/HttpServletRequests.java | 7 +++-- .../dcache/webdav/DcacheResourceFactory.java | 8 +++--- 4 files changed, 25 insertions(+), 24 deletions(-) diff --git a/modules/dcache-frontend/src/main/java/org/dcache/restful/ApiConfig.java b/modules/dcache-frontend/src/main/java/org/dcache/restful/ApiConfig.java index d158f9f532f..abe93be6fba 100644 --- a/modules/dcache-frontend/src/main/java/org/dcache/restful/ApiConfig.java +++ b/modules/dcache-frontend/src/main/java/org/dcache/restful/ApiConfig.java @@ -51,12 +51,7 @@ securityDefinition = @SecurityDefinition( basicAuthDefinitions = { @BasicAuthDefinition(key = "basicAuth", - description = "Username and password authentication " - + "with optional role assertion. To assert " - + "roles, append '#' to the username followed " - + "by a comma-separated list of roles; e.g., " - + "a username of \"paul#admin\" is user " - + "\"paul\" asserting the \"admin\" role.") + description = "Username and password authentication.") } ), consumes = {"application/json"}, diff --git a/modules/dcache-frontend/src/main/java/org/dcache/restful/resources/identity/UserResource.java b/modules/dcache-frontend/src/main/java/org/dcache/restful/resources/identity/UserResource.java index 4429b502b68..eba9d5190e3 100644 --- a/modules/dcache-frontend/src/main/java/org/dcache/restful/resources/identity/UserResource.java +++ b/modules/dcache-frontend/src/main/java/org/dcache/restful/resources/identity/UserResource.java @@ -23,9 +23,10 @@ import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.Authorization; -import java.util.ArrayList; +import java.security.Principal; import java.util.Arrays; import java.util.List; +import java.util.Optional; import java.util.stream.Collectors; import javax.security.auth.Subject; import javax.servlet.http.HttpServletRequest; @@ -34,12 +35,12 @@ import javax.ws.rs.Produces; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; +import org.dcache.auth.RolePrincipal; +import org.dcache.auth.RolePrincipal.Role; import org.dcache.auth.Subjects; import org.dcache.auth.attributes.HomeDirectory; import org.dcache.auth.attributes.LoginAttribute; -import org.dcache.auth.attributes.Role; import org.dcache.auth.attributes.RootDirectory; -import org.dcache.auth.attributes.UnassertedRole; import org.dcache.restful.providers.UserAttributes; import org.dcache.restful.util.RequestUser; import org.springframework.stereotype.Component; @@ -82,18 +83,18 @@ public UserAttributes getUserAttributes(@Context HttpServletRequest request) { user.setHomeDirectory(((HomeDirectory) attribute).getHome()); } else if (attribute instanceof RootDirectory) { user.setRootDirectory(((RootDirectory) attribute).getRoot()); - } else if (attribute instanceof Role) { - if (user.getRoles() == null) { - user.setRoles(new ArrayList<>()); - } - user.getRoles().add(((Role) attribute).getRole()); - } else if (attribute instanceof UnassertedRole) { - if (user.getUnassertedRoles() == null) { - user.setUnassertedRoles(new ArrayList<>()); - } - user.getUnassertedRoles().add(((UnassertedRole) attribute).getRole()); } } + + Optional principal + = subject.getPrincipals().stream().filter(p->p instanceof RolePrincipal) + .findFirst(); + + if (principal.isPresent()) { + RolePrincipal rolePrincipal = (RolePrincipal) principal.get(); + user.setRoles(rolePrincipal.getRoles().stream().map(Role::getTag) + .collect(Collectors.toList())); + } } return user; diff --git a/modules/dcache-frontend/src/main/java/org/dcache/restful/util/HttpServletRequests.java b/modules/dcache-frontend/src/main/java/org/dcache/restful/util/HttpServletRequests.java index 0ce8838ca15..e3433958905 100644 --- a/modules/dcache-frontend/src/main/java/org/dcache/restful/util/HttpServletRequests.java +++ b/modules/dcache-frontend/src/main/java/org/dcache/restful/util/HttpServletRequests.java @@ -27,9 +27,10 @@ import javax.security.auth.Subject; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.BadRequestException; +import org.dcache.auth.RolePrincipal; +import org.dcache.auth.RolePrincipal.Role; import org.dcache.auth.Subjects; import org.dcache.auth.attributes.LoginAttribute; -import org.dcache.auth.attributes.LoginAttributes; import org.dcache.auth.attributes.Restriction; import org.dcache.auth.attributes.Restrictions; import org.dcache.auth.attributes.RootDirectory; @@ -55,7 +56,9 @@ public static Set getLoginAttributes(HttpServletRequest request) } public static boolean isAdmin(HttpServletRequest request) { - return LoginAttributes.hasAdminRole(getLoginAttributes(request)); + return RequestUser.getSubject().getPrincipals().stream() + .filter(p -> p instanceof RolePrincipal) + .anyMatch(p -> ((RolePrincipal) p).hasRole(Role.ADMIN)); } public static Subject roleAwareSubject(HttpServletRequest request) { diff --git a/modules/dcache-webdav/src/main/java/org/dcache/webdav/DcacheResourceFactory.java b/modules/dcache-webdav/src/main/java/org/dcache/webdav/DcacheResourceFactory.java index 323366a032b..72488e32f27 100644 --- a/modules/dcache-webdav/src/main/java/org/dcache/webdav/DcacheResourceFactory.java +++ b/modules/dcache-webdav/src/main/java/org/dcache/webdav/DcacheResourceFactory.java @@ -113,6 +113,8 @@ import javax.security.auth.Subject; import javax.servlet.http.HttpServletRequest; import org.dcache.auth.Origin; +import org.dcache.auth.RolePrincipal; +import org.dcache.auth.RolePrincipal.Role; import org.dcache.auth.SubjectWrapper; import org.dcache.auth.Subjects; import org.dcache.auth.attributes.LoginAttribute; @@ -1304,9 +1306,9 @@ private void checkUploadSize(Long length) { } private boolean isAdmin() { - Set attributes = AuthenticationHandler.getLoginAttributes( - ServletRequest.getRequest()); - return LoginAttributes.hasAdminRole(attributes); + return getSubject().getPrincipals().stream() + .filter(p->p instanceof RolePrincipal) + .anyMatch(p->((RolePrincipal) p).hasRole(Role.ADMIN)); } private PnfsHandler roleAwarePnfsHandler() {