From 2a6bf14baaf667cfc0bb6a9b9955af47aab6da1d Mon Sep 17 00:00:00 2001 From: Dmitriy Kopylenko Date: Tue, 11 Dec 2018 17:26:48 -0500 Subject: [PATCH] SHIBUI-1031: 1034 --- .../security/controller/UsersController.java | 30 +++++++++++++++++++ .../admin/ui/security/model/Role.java | 3 ++ .../admin/ui/security/model/User.java | 4 ++- .../UsersControllerIntegrationTests.groovy | 30 +++++++++++++++++++ 4 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/controller/UsersController.java create mode 100644 backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/security/controller/UsersControllerIntegrationTests.groovy diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/controller/UsersController.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/controller/UsersController.java new file mode 100644 index 000000000..ab0127ce5 --- /dev/null +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/controller/UsersController.java @@ -0,0 +1,30 @@ +package edu.internet2.tier.shibboleth.admin.ui.security.controller; + +import edu.internet2.tier.shibboleth.admin.ui.security.model.User; +import edu.internet2.tier.shibboleth.admin.ui.security.repository.UserRepository; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +/** + * Implementation of the REST resource endpoints exposing system users. + * + * @author Dmitriy Kopylenko + */ +@RestController +@RequestMapping("/api/security/users") +public class UsersController { + + private UserRepository userRepository; + + public UsersController(UserRepository userRepository) { + this.userRepository = userRepository; + } + + @GetMapping + List getAll() { + return userRepository.findAll(); + } + } diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/model/Role.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/model/Role.java index 20564093d..fcb893c20 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/model/Role.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/model/Role.java @@ -1,5 +1,6 @@ package edu.internet2.tier.shibboleth.admin.ui.security.model; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import edu.internet2.tier.shibboleth.admin.ui.domain.AbstractAuditable; import lombok.EqualsAndHashCode; import lombok.Getter; @@ -31,6 +32,8 @@ public class Role extends AbstractAuditable { @Column(unique = true) private String name; + //Ignore properties annotation here is to prevent stack overflow recursive error during JSON serialization + @JsonIgnoreProperties("roles") @ManyToMany(cascade = CascadeType.ALL, mappedBy = "roles", fetch = FetchType.EAGER) private Set users = new HashSet<>(); diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/model/User.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/model/User.java index 9b24cf946..fa403aa86 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/model/User.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/model/User.java @@ -1,5 +1,6 @@ package edu.internet2.tier.shibboleth.admin.ui.security.model; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import edu.internet2.tier.shibboleth.admin.ui.domain.AbstractAuditable; import lombok.*; @@ -37,7 +38,8 @@ public class User extends AbstractAuditable { private String lastName; - @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) + //Ignore properties annotation here is to prevent stack overflow recursive error during JSON serialization + @JsonIgnoreProperties("users") @ManyToMany(cascade = CascadeType.ALL) @JoinTable(name = "user_role", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "role_id")) private Set roles = new HashSet<>(); diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/security/controller/UsersControllerIntegrationTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/security/controller/UsersControllerIntegrationTests.groovy new file mode 100644 index 000000000..6b2c5f2cc --- /dev/null +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/security/controller/UsersControllerIntegrationTests.groovy @@ -0,0 +1,30 @@ +package edu.internet2.tier.shibboleth.admin.ui.security.controller + +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.test.context.SpringBootTest +import org.springframework.boot.test.web.client.TestRestTemplate +import org.springframework.test.context.ActiveProfiles +import spock.lang.Specification + +/** + * @author Dmitriy Kopylenko + */ +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@ActiveProfiles(["no-auth", "dev"]) +class UsersControllerIntegrationTests extends Specification { + + @Autowired + private TestRestTemplate restTemplate + + static RESOURCE_URI = '/api/security/users' + + def "GET users"() { + when: 'GET request is made for ALL users in the system' + def result = this.restTemplate.getForEntity(RESOURCE_URI, Object) + + then: "Request completed successfully" + result.statusCodeValue == 200 + result.body[0].username == 'admin' + result.body[0].roles[0].name == 'ROLE_ADMIN' + } +} \ No newline at end of file