Skip to content

Commit

Permalink
dcache-frontend,dcache-webdav: use RolePrincipal instead of LoginAttr…
Browse files Browse the repository at this point in the history
…ibutes 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
  • Loading branch information
alrossi committed Sep 5, 2023
1 parent 7609229 commit 7e691a4
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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"},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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> 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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -55,7 +56,9 @@ public static Set<LoginAttribute> 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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -1304,9 +1306,9 @@ private void checkUploadSize(Long length) {
}

private boolean isAdmin() {
Set<LoginAttribute> 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() {
Expand Down

0 comments on commit 7e691a4

Please sign in to comment.