Use permissions instead of roles

This commit is contained in:
René Pfeuffer
2018-06-06 13:46:06 +02:00
parent 2c5823e961
commit ea93b2d123
2 changed files with 24 additions and 14 deletions

View File

@@ -1,11 +1,10 @@
package sonia.scm.api.v2.resources; package sonia.scm.api.v2.resources;
import de.otto.edison.hal.Links; import de.otto.edison.hal.Links;
import org.apache.shiro.SecurityUtils;
import org.mapstruct.*; import org.mapstruct.*;
import sonia.scm.api.rest.resources.UserResource; import sonia.scm.api.rest.resources.UserResource;
import sonia.scm.security.Role;
import sonia.scm.user.User; import sonia.scm.user.User;
import sonia.scm.user.UserPermissions;
import javax.ws.rs.core.UriInfo; import javax.ws.rs.core.UriInfo;
import java.time.Instant; import java.time.Instant;
@@ -25,17 +24,18 @@ public abstract class User2UserDtoMapper {
} }
@AfterMapping @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 userLinkBuilder = new LinkBuilder(uriInfo, UserV2Resource.class, UserSubResource.class);
LinkBuilder collectionLinkBuilder = new LinkBuilder(uriInfo, UserV2Resource.class, UserCollectionResource.class);
Links.Builder linksBuilder = linkingTo() Links.Builder linksBuilder = linkingTo()
.self(userLinkBuilder.method("getUserSubResource").parameters(target.getName()).method("get").parameters().href()); .self(userLinkBuilder.method("getUserSubResource").parameters(target.getName()).method("get").parameters().href());
if (SecurityUtils.getSubject().hasRole(Role.ADMIN)) { if (UserPermissions.delete(user).isPermitted()) {
linksBuilder linksBuilder
.single(link("delete", userLinkBuilder.method("getUserSubResource").parameters(target.getName()).method("delete").parameters().href())) .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())); if (UserPermissions.modify(user).isPermitted()) {
linksBuilder
.single(link("update", userLinkBuilder.method("getUserSubResource").parameters(target.getName()).method("update").parameters().href()));
} }
target.add( target.add(
linksBuilder.build()); linksBuilder.build());

View File

@@ -2,6 +2,7 @@ package sonia.scm.api.v2.resources;
import org.apache.shiro.subject.Subject; import org.apache.shiro.subject.Subject;
import org.apache.shiro.subject.support.SubjectThreadState; import org.apache.shiro.subject.support.SubjectThreadState;
import org.apache.shiro.util.ThreadContext;
import org.apache.shiro.util.ThreadState; import org.apache.shiro.util.ThreadState;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@@ -24,7 +25,7 @@ public class User2UserDtoMapperTest {
private final User2UserDtoMapper mapper = Mappers.getMapper(User2UserDtoMapper.class); private final User2UserDtoMapper mapper = Mappers.getMapper(User2UserDtoMapper.class);
private final UriInfo uriInfo = mock(UriInfo.class); private final UriInfo uriInfo = mock(UriInfo.class);
private final Subject subject = mock(Subject.class); private final Subject subject = mock(Subject.class);
private ThreadState subjectThreadState = new SubjectThreadState(subject); private final ThreadState subjectThreadState = new SubjectThreadState(subject);
private URI expectedBaseUri; private URI expectedBaseUri;
@@ -34,19 +35,29 @@ public class User2UserDtoMapperTest {
expectedBaseUri = baseUri.resolve(UserV2Resource.USERS_PATH_V2 + "/"); expectedBaseUri = baseUri.resolve(UserV2Resource.USERS_PATH_V2 + "/");
when(uriInfo.getBaseUri()).thenReturn(baseUri); when(uriInfo.getBaseUri()).thenReturn(baseUri);
subjectThreadState.bind(); subjectThreadState.bind();
ThreadContext.bind(subject);
} }
@Test @Test
public void shouldMapLinks_forAdmin() { public void shouldMapLinks_forUpdate() {
User user = createDefaultUser(); 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); UserDto userDto = mapper.userToUserDto(user, uriInfo);
assertEquals("expected self link", expectedBaseUri.resolve("abc").toString(), userDto.getLinks().getLinkBy("self").get().getHref()); 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 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() { private User createDefaultUser() {
@@ -66,7 +77,6 @@ public class User2UserDtoMapperTest {
assertEquals("expected self link", expectedBaseUri.resolve("abc").toString(), userDto.getLinks().getLinkBy("self").get().getHref()); 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 delete link", userDto.getLinks().getLinkBy("delete").isPresent());
assertFalse("expected no update link", userDto.getLinks().getLinkBy("update").isPresent()); assertFalse("expected no update link", userDto.getLinks().getLinkBy("update").isPresent());
assertFalse("expected no create link", userDto.getLinks().getLinkBy("create").isPresent());
} }
@Test @Test