From ea93b2d123c9b4df93d6aca835bf3f7398d7b023 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Wed, 6 Jun 2018 13:46:06 +0200 Subject: [PATCH] Use permissions instead of roles --- .../api/v2/resources/User2UserDtoMapper.java | 16 +++++++------- .../v2/resources/User2UserDtoMapperTest.java | 22 ++++++++++++++----- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/User2UserDtoMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/User2UserDtoMapper.java index 72fa0db382..489fc588f4 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/User2UserDtoMapper.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/User2UserDtoMapper.java @@ -1,11 +1,10 @@ package sonia.scm.api.v2.resources; import de.otto.edison.hal.Links; -import org.apache.shiro.SecurityUtils; import org.mapstruct.*; import sonia.scm.api.rest.resources.UserResource; -import sonia.scm.security.Role; import sonia.scm.user.User; +import sonia.scm.user.UserPermissions; import javax.ws.rs.core.UriInfo; import java.time.Instant; @@ -25,17 +24,18 @@ public abstract class User2UserDtoMapper { } @AfterMapping - void appendLinks(@MappingTarget UserDto target, @Context UriInfo uriInfo) { + void appendLinks(User user, @MappingTarget UserDto target, @Context UriInfo uriInfo) { LinkBuilder userLinkBuilder = new LinkBuilder(uriInfo, UserV2Resource.class, UserSubResource.class); - LinkBuilder collectionLinkBuilder = new LinkBuilder(uriInfo, UserV2Resource.class, UserCollectionResource.class); Links.Builder linksBuilder = linkingTo() .self(userLinkBuilder.method("getUserSubResource").parameters(target.getName()).method("get").parameters().href()); - if (SecurityUtils.getSubject().hasRole(Role.ADMIN)) { + if (UserPermissions.delete(user).isPermitted()) { linksBuilder - .single(link("delete", userLinkBuilder.method("getUserSubResource").parameters(target.getName()).method("delete").parameters().href())) - .single(link("update", userLinkBuilder.method("getUserSubResource").parameters(target.getName()).method("update").parameters().href())) - .single(link("create", collectionLinkBuilder. method("getUserCollectionResource").parameters().method("create").parameters().href())); + .single(link("delete", userLinkBuilder.method("getUserSubResource").parameters(target.getName()).method("delete").parameters().href())); + } + if (UserPermissions.modify(user).isPermitted()) { + linksBuilder + .single(link("update", userLinkBuilder.method("getUserSubResource").parameters(target.getName()).method("update").parameters().href())); } target.add( linksBuilder.build()); diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/User2UserDtoMapperTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/User2UserDtoMapperTest.java index a770c4d4a8..34f5b96ec3 100644 --- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/User2UserDtoMapperTest.java +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/User2UserDtoMapperTest.java @@ -2,6 +2,7 @@ package sonia.scm.api.v2.resources; import org.apache.shiro.subject.Subject; import org.apache.shiro.subject.support.SubjectThreadState; +import org.apache.shiro.util.ThreadContext; import org.apache.shiro.util.ThreadState; import org.junit.Before; import org.junit.Test; @@ -24,7 +25,7 @@ public class User2UserDtoMapperTest { private final User2UserDtoMapper mapper = Mappers.getMapper(User2UserDtoMapper.class); private final UriInfo uriInfo = mock(UriInfo.class); private final Subject subject = mock(Subject.class); - private ThreadState subjectThreadState = new SubjectThreadState(subject); + private final ThreadState subjectThreadState = new SubjectThreadState(subject); private URI expectedBaseUri; @@ -34,19 +35,29 @@ public class User2UserDtoMapperTest { expectedBaseUri = baseUri.resolve(UserV2Resource.USERS_PATH_V2 + "/"); when(uriInfo.getBaseUri()).thenReturn(baseUri); subjectThreadState.bind(); + ThreadContext.bind(subject); } @Test - public void shouldMapLinks_forAdmin() { + public void shouldMapLinks_forUpdate() { User user = createDefaultUser(); - when(subject.hasRole("admin")).thenReturn(true); + when(subject.isPermitted("user:modify:abc")).thenReturn(true); + + UserDto userDto = mapper.userToUserDto(user, uriInfo); + + assertEquals("expected self link", expectedBaseUri.resolve("abc").toString(), userDto.getLinks().getLinkBy("self").get().getHref()); + assertEquals("expected update link", expectedBaseUri.resolve("abc").toString(), userDto.getLinks().getLinkBy("update").get().getHref()); + } + + @Test + public void shouldMapLinks_forDelete() { + User user = createDefaultUser(); + when(subject.isPermitted("user:delete:abc")).thenReturn(true); UserDto userDto = mapper.userToUserDto(user, uriInfo); assertEquals("expected self link", expectedBaseUri.resolve("abc").toString(), userDto.getLinks().getLinkBy("self").get().getHref()); assertEquals("expected delete link", expectedBaseUri.resolve("abc").toString(), userDto.getLinks().getLinkBy("delete").get().getHref()); - assertEquals("expected update link", expectedBaseUri.resolve("abc").toString(), userDto.getLinks().getLinkBy("update").get().getHref()); - assertEquals("expected create link", expectedBaseUri.toString(), userDto.getLinks().getLinkBy("create").get().getHref()); } private User createDefaultUser() { @@ -66,7 +77,6 @@ public class User2UserDtoMapperTest { assertEquals("expected self link", expectedBaseUri.resolve("abc").toString(), userDto.getLinks().getLinkBy("self").get().getHref()); assertFalse("expected no delete link", userDto.getLinks().getLinkBy("delete").isPresent()); assertFalse("expected no update link", userDto.getLinks().getLinkBy("update").isPresent()); - assertFalse("expected no create link", userDto.getLinks().getLinkBy("create").isPresent()); } @Test