Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ ext['tomcat.version'] = '10.1.43'

dependencies {

implementation 'uk.gov.hmcts:opal-common-lib:0.2.6'
implementation 'uk.gov.hmcts:opal-common-lib:0.3.1'

implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,5 @@
package uk.gov.hmcts.reform.opal.controllers;

import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.hasSize;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.springframework.test.context.jdbc.Sql.ExecutionPhase.BEFORE_TEST_CLASS;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static uk.gov.hmcts.opal.common.dto.ToJsonString.toPrettyJson;

import java.time.Instant;
import java.util.Map;
import java.util.Optional;

import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.params.ParameterizedTest;
Expand All @@ -35,6 +17,26 @@
import uk.gov.hmcts.opal.common.logging.EventLoggingService;
import uk.gov.hmcts.reform.opal.AbstractIntegrationTest;

import java.time.Instant;
import java.util.Map;
import java.util.Optional;

import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.hasSize;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions;
import static org.springframework.test.context.jdbc.Sql.ExecutionPhase.BEFORE_TEST_CLASS;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static uk.gov.hmcts.opal.common.dto.ToJsonString.toPrettyJson;

@ActiveProfiles({"integration"})
@Slf4j(topic = "opal.UserPermissionsControllerIntegrationTest")
@Sql(scripts = "classpath:db.reset/clean_test_data.sql", executionPhase = BEFORE_TEST_CLASS)
Expand Down Expand Up @@ -370,6 +372,100 @@ void getUserState_returnsMultiplePermissions(Boolean newLogin) throws Exception
verify(eventLoggingService, mode).logEvent(any(), any(), any(), any(), any(), any());
}

@ParameterizedTest
@ValueSource(booleans = {false, true})
@DisplayName("V2 Should return 200 and full V2 user state for a user with permissions")
void getV2UserState_returnsFullState(boolean newLogin) throws Exception {
long userIdWithPermissions = 500000000L;

MockHttpServletRequestBuilder builder = get("/v2" + URL_BASE + "/" + userIdWithPermissions + "/state")
.principal(createJwtPrincipal());
addLoginHeader(newLogin, builder);
ResultActions actions = mockMvc.perform(builder);

String body = actions.andReturn().getResponse().getContentAsString();
log.info(":getUserState_whenUserHasPermissions_returns200AndCorrectPayload: Response body:\n{}",
toPrettyJson(body));

actions.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON));

assertThat(body).isEqualTo(objectMapper.readTree("""
{
"user_id": 500000000,
"username": "opal-test@HMCTS.NET",
"name": null,
"status": "ACTIVE",
"version": 0,
"cache_name": null,
"domains": {
"fines": {
"business_unit_users": [
{
"business_unit_user_id": "L065JG",
"business_unit_id": 70,
"permissions": [
{
"permission_id": 1,
"permission_name": "Create and Manage Draft Accounts"
},
{
"permission_id": 3,
"permission_name": "Account Enquiry"
},
{
"permission_id": 4,
"permission_name": "Collection Order"
},
{
"permission_id": 5,
"permission_name": "Check and Validate Draft Accounts"
},
{
"permission_id": 6,
"permission_name": "Search and View Accounts"
}
]
},
{
"business_unit_user_id": "L065JG",
"business_unit_id": 70,
"permissions": [
{
"permission_id": 1,
"permission_name": "Create and Manage Draft Accounts"
},
{
"permission_id": 3,
"permission_name": "Account Enquiry"
},
{
"permission_id": 4,
"permission_name": "Collection Order"
},
{
"permission_id": 5,
"permission_name": "Check and Validate Draft Accounts"
},
{
"permission_id": 6,
"permission_name": "Search and View Accounts"
}
]
}
]
}
}
}
""").toString());
if (newLogin) {
verify(eventLoggingService).logEvent(any(), any(), any(), any(), any(), any());
} else {
verifyNoInteractions(eventLoggingService);
}

}

private JwtAuthenticationToken createJwtPrincipal() {
return createJwtPrincipal("jjqwGAERGW43","test-user@HMCTS.NET", "Pablo");
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package uk.gov.hmcts.reform.opal.repository;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.jdbc.Sql;
import uk.gov.hmcts.opal.common.user.authorisation.client.dto.UserStateV2Dto;
import uk.gov.hmcts.reform.opal.BaseIntegrationTest;
import uk.gov.hmcts.reform.opal.entity.UserEntity;
import uk.gov.hmcts.reform.opal.mappers.UserStateMapper;

import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.test.context.jdbc.Sql.ExecutionPhase.BEFORE_TEST_CLASS;

@ActiveProfiles({"integration"})
@Sql(scripts = "classpath:db.reset/clean_test_data.sql", executionPhase = BEFORE_TEST_CLASS)
@Sql(scripts = "classpath:db.insertData/insert_user_state_data.sql", executionPhase = BEFORE_TEST_CLASS)
@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_CLASS)
@DisplayName("UserRepository database integration tests")
class UserRepositoryDatabaseIntegrationTest extends BaseIntegrationTest {

@Autowired
private UserRepository userRepository;

@Autowired
private UserStateMapper mapper;

@Autowired
ObjectMapper objectMapper;

@Test
@DisplayName("Test UserStateV2Dto production in isolation")
void testUserStateV2DtoProductionInIsolation() throws JsonProcessingException {
UserEntity user = userRepository.findIdWithPermissions(500000000L).orElseThrow();
UserStateV2Dto dto = mapper.toUserStateV2Dto(user);
assertThat(objectMapper.readTree(objectMapper.writeValueAsString(dto)))
.isEqualTo(objectMapper.readTree("""
{
"user_id": 500000000,
"username": "opal-test@HMCTS.NET",
"name": null,
"status": "ACTIVE",
"version": 0,
"cache_name": null,
"domains": {
"fines": {
"business_unit_users": [
{
"business_unit_user_id": "L065JG",
"business_unit_id": 70,
"permissions": [
{
"permission_id": 1,
"permission_name": "Create and Manage Draft Accounts"
},
{
"permission_id": 3,
"permission_name": "Account Enquiry"
},
{
"permission_id": 4,
"permission_name": "Collection Order"
},
{
"permission_id": 5,
"permission_name": "Check and Validate Draft Accounts"
},
{
"permission_id": 6,
"permission_name": "Search and View Accounts"
}
]
},
{
"business_unit_user_id": "L065JG",
"business_unit_id": 70,
"permissions": [
{
"permission_id": 1,
"permission_name": "Create and Manage Draft Accounts"
},
{
"permission_id": 3,
"permission_name": "Account Enquiry"
},
{
"permission_id": 4,
"permission_name": "Collection Order"
},
{
"permission_id": 5,
"permission_name": "Check and Validate Draft Accounts"
},
{
"permission_id": 6,
"permission_name": "Search and View Accounts"
}
]
}
]
}
}
}
"""));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,16 @@ VALUES (112687, 'L065JG', 41), -- BU 70 gets 'Account Enquiry - Account Notes'
(112683, 'L065JG', 54), -- BU 70 gets 'Account Enquiry'
(112921, 'L066JG', 41), -- BU 68 gets 'Account Enquiry - Account Notes'
(500001, 'L080JG', 500); -- BU 61 gets 'Collection Order'

INSERT INTO roles (role_id, version_number, opal_domain_id, role_name, is_active, application_function_list)
VALUES (1,1, 1, 'Fines_Role_1', true, ARRAY['CREATE_MANAGE_DRAFT_ACCOUNTS', 'ACCOUNT_ENQUIRY_NOTES']),
(1,2, 1, 'Fines_Role_1', true, ARRAY['CREATE_MANAGE_DRAFT_ACCOUNTS', 'ACCOUNT_ENQUIRY']),
(2,1, 1, 'Fines_Role_2', true, ARRAY['COLLECTION_ORDER']),
(2,2, 1, 'Fines_Role_2', true, ARRAY['CHECK_VALIDATE_DRAFT_ACCOUNTS', 'SEARCH_AND_VIEW_ACCOUNTS']),
(2,3, 1, 'Fines_Role_2', true, ARRAY['COLLECTION_ORDER', 'CHECK_VALIDATE_DRAFT_ACCOUNTS', 'SEARCH_AND_VIEW_ACCOUNTS']),
(3,1, 2, 'Confiscation_Role_3', true, ARRAY['CREATE_MANAGE_DRAFT_ACCOUNTS']),
(3,2, 2, 'Confiscation_Role_3', true, ARRAY['CREATE_MANAGE_DRAFT_ACCOUNTS', 'COLLECTION_ORDER']);

INSERT INTO business_unit_user_roles(business_unit_user_role_id, business_unit_user_id, role_id)
VALUES (1,'L065JG', 1),
(2,'L065JG', 2);
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package uk.gov.hmcts.reform.opal.controllers;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import uk.gov.hmcts.opal.common.user.authorisation.client.dto.UserStateV2Dto;
import uk.gov.hmcts.reform.opal.service.UserPermissionsService;

import static uk.gov.hmcts.reform.opal.util.HttpUtil.buildResponse;

// Spring Boot 4 handles versioned endpoints better, so won't need separate controller then

@RestController
@RequestMapping("/v2/users")
@RequiredArgsConstructor
@Slf4j(topic = "opal.UserPermissionsV2Controller")
public class UserPermissionsV2Controller {

private static final String X_NEW_LOGIN = "X-New-Login";
private final UserPermissionsService userPermissionsService;

@GetMapping("/{userId}/state")
public ResponseEntity<UserStateV2Dto> getUserStateV2(
@PathVariable Long userId, Authentication authentication,
@RequestHeader(value = X_NEW_LOGIN, required = false) Boolean newLogin) {

log.debug(":GET:getUserState: userId: {}, new login: {}", userId, newLogin);
return buildResponse(userPermissionsService
.getUserStateV2(userId, authentication, userPermissionsService, newLogin));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,9 @@ public class BusinessUnitEntity {
@JoinColumn(name = "parent_business_unit_id")
private BusinessUnitEntity parentBusinessUnit;

@Column(name = "opal_domain_id")
private Short opalDomainId;
@ManyToOne
@JoinColumn(name = "opal_domain_id")
private DomainEntity domain;

@Column(name = "welsh_language")
private Boolean welshLanguage;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import jakarta.xml.bind.annotation.XmlAccessType;
import jakarta.xml.bind.annotation.XmlAccessorType;
Expand All @@ -19,13 +20,17 @@
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;

import java.util.HashSet;
import java.util.Set;


@Entity
@Table(name = "business_unit_users")
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "businessUnitUserId")
@XmlRootElement
Expand All @@ -34,20 +39,22 @@ public class BusinessUnitUserEntity {

@Id
@Column(name = "business_unit_user_id", length = 6)
@EqualsAndHashCode.Include
private String businessUnitUserId;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "business_unit_id", nullable = false)
@EqualsAndHashCode.Exclude
private BusinessUnitEntity businessUnit;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id", nullable = false)
@EqualsAndHashCode.Exclude
private UserEntity user;

@OneToMany(mappedBy = "businessUnitUser")
@Builder.Default
private Set<BusinessUnitUserRoleEntity> businessUnitUserRoleList = new HashSet<>();

public Short getBusinessUnitId() {
return businessUnit.getBusinessUnitId();
}

}
Loading