Skip to content

Commit

Permalink
SHIBUI-1848
Browse files Browse the repository at this point in the history
finished adjustments to groups controller. Added group field to user
  • Loading branch information
chasegawa committed Jun 25, 2021
1 parent 47e21b6 commit b18290c
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -99,18 +99,16 @@ public ResponseEntity<?> delete(@PathVariable String resourceId) {
.body(new ErrorResponse(String.valueOf(HttpStatus.NOT_FOUND.value()),
String.format("Unable to find group with resource id: [%s]", resourceId)));
}
try {
groupService.deleteDefinition(g);
}
catch (Exception e) {
if (!g.getUsers().isEmpty()) {
HttpHeaders headers = new HttpHeaders();
headers.setLocation(ServletUriComponentsBuilder.fromCurrentServletMapping().path("/api/admin/groups").build().toUri());

return ResponseEntity.status(HttpStatus.CONFLICT).headers(headers)
.body(new ErrorResponse(String.valueOf(HttpStatus.CONFLICT.value()), String.format(
"Unable to delete group with resource id: [%s] - remove all users from group",
"Unable to delete group with resource id: [%s] - remove all users from group first",
resourceId)));
}
groupService.deleteDefinition(g);
return ResponseEntity.noContent().build();
}
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
package edu.internet2.tier.shibboleth.admin.ui.security.model;

import java.util.Set;
import java.util.UUID;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.OneToMany;

import org.hibernate.envers.Audited;
import com.fasterxml.jackson.annotation.JsonIgnore;

import lombok.Data;
import lombok.EqualsAndHashCode;

@Entity(name = "user_groups")
@Audited
@Data
public class Group {
@Column(name = "group_description", nullable = true)
Expand All @@ -23,4 +27,9 @@ public class Group {
@Id
@Column(name = "resource_id")
String resourceId = UUID.randomUUID().toString();

@OneToMany(mappedBy = "group", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JsonIgnore
@EqualsAndHashCode.Exclude
Set<User> users;
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,15 @@
import lombok.ToString;
import org.apache.commons.lang.StringUtils;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.Transient;
import java.util.HashSet;
Expand All @@ -30,32 +33,38 @@
@NoArgsConstructor
@Getter
@Setter
@EqualsAndHashCode(callSuper = true, exclude = "roles")
@EqualsAndHashCode(callSuper = true)
@ToString(exclude = "roles")
@Table(name = "USERS")
public class User extends AbstractAuditable {

@Column(nullable = false, unique = true)
private String username;

@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
@Column(nullable = false)
private String password;
private String emailAddress;

private String firstName;

@ManyToOne
@JoinColumn(name = "resource_id")
@EqualsAndHashCode.Exclude
private Group group;

private String lastName;

private String emailAddress;
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
@Column(nullable = false)
private String password;

@Transient
private String role;

@JsonIgnore
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "user_role", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "role_id"))
@EqualsAndHashCode.Exclude
private Set<Role> roles = new HashSet<>();

@Column(nullable = false, unique = true)
private String username;

public String getRole() {
if (StringUtils.isBlank(this.role)) {
Set<Role> roles = this.getRoles();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class GroupsControllerIntegrationTests extends Specification {
private MockMvc mockMvc

static RESOURCE_URI = '/api/admin/groups'
static USERS_RESOURCE_URI = '/api/admin/users'

@Rollback
@WithMockUser(value = "admin", roles = ["ADMIN"])
Expand Down Expand Up @@ -147,33 +148,81 @@ class GroupsControllerIntegrationTests extends Specification {
nonexistentGroupRequest.andExpect(status().isNotFound())
}
// @Rollback
// @WithMockUser(value = "admin", roles = ["ADMIN"])
// def 'DELETE ONE existing group'() {
// when: 'GET request for a single specific group in a system that has groups'
// def result = mockMvc.perform(get("$RESOURCE_URI/BBB"))
//
// then: 'GET request for a single specific group completed with HTTP 200'
// result.andExpect(status().isOk())
//
// when: 'DELETE request is made'
// result = mockMvc.perform(delete("$RESOURCE_URI/BBB"))
//
// then: 'DELETE was successful'
// result.andExpect(status().isNoContent())
//
// when: 'GET request for a single specific group just deleted'
// result = mockMvc.perform(get("$RESOURCE_URI/BBB"))
//
// then: 'The group not found'
// result.andExpect(status().isNotFound())
//
// when: 'DELETE request for a single specific group that does not exist'
// result = mockMvc.perform(delete("$RESOURCE_URI/CCCC"))
//
// then: 'The group not found'
// result.andExpect(status().isNotFound())
// }
@Rollback
@WithMockUser(value = "admin", roles = ["ADMIN"])
def 'DELETE ONE existing group'() {
when: 'GET request for a single specific group in a system that has groups'
def result = mockMvc.perform(get("$RESOURCE_URI/BBB"))
def 'DELETE performs correctly when group attached to a user'() {
given:
def group = [name: 'A1',
description: 'AAA Group',
resourceId: 'AAA']
def newUser = [firstName: 'Foo',
lastName: 'Bar',
username: 'FooBar',
password: 'somepass',
emailAddress: 'foo@institution.edu',
role: 'ROLE_USER',
group: group]

then: 'GET request for a single specific group completed with HTTP 200'
when:
def result = mockMvc.perform(post(USERS_RESOURCE_URI)
.contentType(MediaType.APPLICATION_JSON)
.content(JsonOutput.toJson(newUser))
.accept(MediaType.APPLICATION_JSON))

then:
result.andExpect(status().isOk())
when: 'DELETE request is made'
result = mockMvc.perform(delete("$RESOURCE_URI/BBB"))
then: 'DELETE was successful'
result.andExpect(status().isNoContent())
when: 'GET request for a single specific group just deleted'
result = mockMvc.perform(get("$RESOURCE_URI/BBB"))
then: 'The group not found'
result.andExpect(status().isNotFound())

when:
def userresult = mockMvc.perform(get("$USERS_RESOURCE_URI/$newUser.username"))
def expectedJson = """
{
"modifiedBy" : admin,
"firstName" : "Foo",
"emailAddress" : "foo@institution.edu",
"role" : "ROLE_USER",
"username" : "FooBar",
"createdBy" : admin,
"lastName" : "Bar",
"group" : {"description":"AAA Group","name":"A1","resourceId":"AAA"}
}"""
then: 'Request completed with HTTP 200 and returned one user'
userresult.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(content().json(expectedJson, false))

when: 'DELETE request for a single specific group that does not exist'
result = mockMvc.perform(delete("$RESOURCE_URI/CCCC"))
then: 'The group not found'
result.andExpect(status().isNotFound())

//ADD conflict test when the group has users
when: 'DELETE request is made'
result = mockMvc.perform(delete("$RESOURCE_URI/$group.resourceId"))

then: 'DELETE was not successful'
result.andExpect(status().isConflict())
}
}

0 comments on commit b18290c

Please sign in to comment.