for customer findAll()->findCustomerByOptionalPrefix(...)
This commit is contained in:
parent
8fb92f9978
commit
57cf316c00
@ -22,13 +22,14 @@ public class CustomerController {
|
|||||||
@Transactional
|
@Transactional
|
||||||
public List<CustomerEntity> listCustomers(
|
public List<CustomerEntity> listCustomers(
|
||||||
@RequestHeader(value = "current-user") String userName,
|
@RequestHeader(value = "current-user") String userName,
|
||||||
@RequestHeader(value = "assumed-roles", required = false) String assumedRoles
|
@RequestHeader(value = "assumed-roles", required = false) String assumedRoles,
|
||||||
|
@RequestParam(required = false) String prefix
|
||||||
) {
|
) {
|
||||||
context.setCurrentUser(userName);
|
context.setCurrentUser(userName);
|
||||||
if (assumedRoles != null && !assumedRoles.isBlank()) {
|
if (assumedRoles != null && !assumedRoles.isBlank()) {
|
||||||
context.assumeRoles(assumedRoles);
|
context.assumeRoles(assumedRoles);
|
||||||
}
|
}
|
||||||
return customerRepository.findAll();
|
return customerRepository.findCustomerByOptionalPrefix(prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping(value = "/api/customers")
|
@PostMapping(value = "/api/customers")
|
||||||
@ -48,5 +49,4 @@ public class CustomerController {
|
|||||||
}
|
}
|
||||||
return customerRepository.save(customer);
|
return customerRepository.save(customer);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,21 @@
|
|||||||
package net.hostsharing.hsadminng.hs.hscustomer;
|
package net.hostsharing.hsadminng.hs.hscustomer;
|
||||||
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.data.jpa.repository.Query;
|
||||||
|
import org.springframework.data.repository.Repository;
|
||||||
|
import org.springframework.data.repository.query.Param;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public interface CustomerRepository extends JpaRepository<CustomerEntity, UUID> {
|
public interface CustomerRepository extends Repository<CustomerEntity, UUID> {
|
||||||
|
|
||||||
|
|
||||||
|
Optional<CustomerEntity> findByUuid(UUID id);
|
||||||
|
|
||||||
|
@Query("SELECT c FROM CustomerEntity c WHERE :prefix is null or c.prefix like concat(:prefix, '%')")
|
||||||
|
List<CustomerEntity> findCustomerByOptionalPrefix(@Param("prefix") String prefix);
|
||||||
|
|
||||||
|
CustomerEntity save(final CustomerEntity entity);
|
||||||
|
|
||||||
List<CustomerEntity> findByPrefixLike(final String prefix);
|
|
||||||
}
|
}
|
||||||
|
@ -111,11 +111,18 @@ declare
|
|||||||
objectUuid uuid;
|
objectUuid uuid;
|
||||||
begin
|
begin
|
||||||
if TG_OP = 'INSERT' then
|
if TG_OP = 'INSERT' then
|
||||||
|
if NEW.uuid is null then
|
||||||
insert
|
insert
|
||||||
into RbacObject (objectTable)
|
into RbacObject (objectTable)
|
||||||
values (TG_TABLE_NAME)
|
values (TG_TABLE_NAME)
|
||||||
returning uuid into objectUuid;
|
returning uuid into objectUuid;
|
||||||
NEW.uuid = objectUuid;
|
NEW.uuid = objectUuid;
|
||||||
|
else
|
||||||
|
insert
|
||||||
|
into RbacObject (uuid, objectTable)
|
||||||
|
values (NEW.uuid, TG_TABLE_NAME)
|
||||||
|
returning uuid into objectUuid;
|
||||||
|
end if;
|
||||||
return NEW;
|
return NEW;
|
||||||
else
|
else
|
||||||
raise exception 'invalid usage of TRIGGER AFTER INSERT';
|
raise exception 'invalid usage of TRIGGER AFTER INSERT';
|
||||||
@ -138,7 +145,8 @@ create table RbacRole
|
|||||||
(
|
(
|
||||||
uuid uuid primary key references RbacReference (uuid) on delete cascade,
|
uuid uuid primary key references RbacReference (uuid) on delete cascade,
|
||||||
objectUuid uuid references RbacObject (uuid) not null,
|
objectUuid uuid references RbacObject (uuid) not null,
|
||||||
roleType RbacRoleType not null
|
roleType RbacRoleType not null,
|
||||||
|
unique (objectUuid, roleType)
|
||||||
);
|
);
|
||||||
|
|
||||||
create type RbacRoleDescriptor as
|
create type RbacRoleDescriptor as
|
||||||
@ -753,7 +761,7 @@ grant all privileges on all tables in schema public to restricted;
|
|||||||
*/
|
*/
|
||||||
drop view if exists rbacrole_rv;
|
drop view if exists rbacrole_rv;
|
||||||
create or replace view rbacrole_rv as
|
create or replace view rbacrole_rv as
|
||||||
select r.*, o.objectTable,
|
select DISTINCT r.*, o.objectTable,
|
||||||
findIdNameByObjectUuid(o.objectTable, o.uuid) as objectIdName
|
findIdNameByObjectUuid(o.objectTable, o.uuid) as objectIdName
|
||||||
from rbacrole as r
|
from rbacrole as r
|
||||||
join rbacobject as o on o.uuid=r.objectuuid
|
join rbacobject as o on o.uuid=r.objectuuid
|
||||||
|
@ -12,7 +12,7 @@ import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
|||||||
import static java.util.Arrays.asList;
|
import static java.util.Arrays.asList;
|
||||||
import static org.hamcrest.Matchers.hasSize;
|
import static org.hamcrest.Matchers.hasSize;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
import static org.mockito.Mockito.*;
|
import static org.mockito.Mockito.when;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
@ -27,13 +27,13 @@ class CustomerControllerRestTest {
|
|||||||
CustomerRepository customerRepositoryMock;
|
CustomerRepository customerRepositoryMock;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void apiCustomersWillReturnCustomersFromRepository() throws Exception {
|
void apiCustomersWillReturnAllCustomersFromRepositoryIfNoCriteriaGiven() throws Exception {
|
||||||
|
|
||||||
// given
|
// given
|
||||||
when(customerRepositoryMock.findAll()).thenReturn(asList(TestCustomer.xxx, TestCustomer.yyy));
|
when(customerRepositoryMock.findCustomerByOptionalPrefix(null)).thenReturn(asList(TestCustomer.xxx, TestCustomer.yyy));
|
||||||
|
|
||||||
// when
|
// when
|
||||||
final var pacs = mockMvc.perform(MockMvcRequestBuilders
|
mockMvc.perform(MockMvcRequestBuilders
|
||||||
.get("/api/customers")
|
.get("/api/customers")
|
||||||
.header("current-user", "mike@hostsharing.net")
|
.header("current-user", "mike@hostsharing.net")
|
||||||
.accept(MediaType.APPLICATION_JSON))
|
.accept(MediaType.APPLICATION_JSON))
|
||||||
@ -44,4 +44,23 @@ class CustomerControllerRestTest {
|
|||||||
.andExpect(jsonPath("$[0].prefix", is(TestCustomer.xxx.getPrefix())))
|
.andExpect(jsonPath("$[0].prefix", is(TestCustomer.xxx.getPrefix())))
|
||||||
.andExpect(jsonPath("$[1].reference", is(TestCustomer.yyy.getReference())));
|
.andExpect(jsonPath("$[1].reference", is(TestCustomer.yyy.getReference())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void apiCustomersWillReturnMatchingCustomersFromRepositoryIfCriteriaGiven() throws Exception {
|
||||||
|
|
||||||
|
// given
|
||||||
|
when(customerRepositoryMock.findCustomerByOptionalPrefix("x")).thenReturn(asList(TestCustomer.xxx));
|
||||||
|
|
||||||
|
// when
|
||||||
|
mockMvc.perform(MockMvcRequestBuilders
|
||||||
|
.get("/api/customers")
|
||||||
|
.header("current-user", "mike@hostsharing.net")
|
||||||
|
.param("prefix", "x")
|
||||||
|
.accept(MediaType.APPLICATION_JSON))
|
||||||
|
|
||||||
|
// then
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$", hasSize(1)))
|
||||||
|
.andExpect(jsonPath("$[0].prefix", is(TestCustomer.xxx.getPrefix())));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,10 +27,10 @@ class CustomerControllerUnitTest {
|
|||||||
void apiCustomersWillReturnCustomersFromRepository() throws Exception {
|
void apiCustomersWillReturnCustomersFromRepository() throws Exception {
|
||||||
|
|
||||||
// given
|
// given
|
||||||
when(customerRepositoryMock.findAll()).thenReturn(asList(TestCustomer.xxx, TestCustomer.yyy));
|
when(customerRepositoryMock.findCustomerByOptionalPrefix(null)).thenReturn(asList(TestCustomer.xxx, TestCustomer.yyy));
|
||||||
|
|
||||||
// when
|
// when
|
||||||
final var pacs = customerController.listCustomers("mike@hostsharing.net", null);
|
final var pacs = customerController.listCustomers("mike@hostsharing.net", null, null);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assertThat(pacs).hasSize(2);
|
assertThat(pacs).hasSize(2);
|
||||||
@ -42,10 +42,10 @@ class CustomerControllerUnitTest {
|
|||||||
void findAllWithAssumedCustomerAdminRole() throws Exception {
|
void findAllWithAssumedCustomerAdminRole() throws Exception {
|
||||||
|
|
||||||
// given
|
// given
|
||||||
when(customerRepositoryMock.findAll()).thenReturn(singletonList(TestCustomer.yyy));
|
when(customerRepositoryMock.findCustomerByOptionalPrefix(null)).thenReturn(singletonList(TestCustomer.yyy));
|
||||||
|
|
||||||
// when
|
// when
|
||||||
final var pacs = customerController.listCustomers("mike@hostsharing.net", "customer#yyy.admin");
|
final var pacs = customerController.listCustomers("mike@hostsharing.net", "customer#yyy.admin", null);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assertThat(pacs).hasSize(1);
|
assertThat(pacs).hasSize(1);
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
package net.hostsharing.hsadminng.hs.hscustomer;
|
package net.hostsharing.hsadminng.hs.hscustomer;
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.context.Context;
|
||||||
import net.hostsharing.hsadminng.hs.hscustomer.CustomerEntity;
|
|
||||||
import net.hostsharing.hsadminng.hs.hscustomer.CustomerRepository;
|
|
||||||
import org.junit.jupiter.api.Nested;
|
import org.junit.jupiter.api.Nested;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@ -40,13 +38,17 @@ class CustomerRepositoryIntegrationTest {
|
|||||||
currentUser("mike@hostsharing.net");
|
currentUser("mike@hostsharing.net");
|
||||||
|
|
||||||
// when
|
// when
|
||||||
|
|
||||||
|
final var attempt = attempt(em, () -> {
|
||||||
final var newCustomer = new CustomerEntity(
|
final var newCustomer = new CustomerEntity(
|
||||||
UUID.randomUUID(), "xxx", 90001, "admin@xxx.example.com");
|
UUID.randomUUID(), "xxx", 90001, "admin@xxx.example.com");
|
||||||
final var result = customerRepository.save(newCustomer);
|
return customerRepository.save(newCustomer);
|
||||||
|
});
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assertThat(result).isNotNull().extracting(CustomerEntity::getUuid).isNotNull();
|
assertThat(attempt.wasSuccessful()).isTrue();
|
||||||
assertThatCustomerIsPersisted(result);
|
assertThat(attempt.returnedResult()).isNotNull().extracting(CustomerEntity::getUuid).isNotNull();
|
||||||
|
assertThatCustomerIsPersisted(attempt.returnedResult());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -88,8 +90,8 @@ class CustomerRepositoryIntegrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void assertThatCustomerIsPersisted(final CustomerEntity saved) {
|
private void assertThatCustomerIsPersisted(final CustomerEntity saved) {
|
||||||
final var found = customerRepository.findById(saved.getUuid());
|
final var found = customerRepository.findByUuid(saved.getUuid());
|
||||||
assertThat(found).hasValue(saved);
|
assertThat(found).isNotEmpty().get().usingRecursiveComparison().isEqualTo(saved);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,7 +104,7 @@ class CustomerRepositoryIntegrationTest {
|
|||||||
currentUser("mike@hostsharing.net");
|
currentUser("mike@hostsharing.net");
|
||||||
|
|
||||||
// when
|
// when
|
||||||
final var result = customerRepository.findAll();
|
final var result = customerRepository.findCustomerByOptionalPrefix(null);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
exactlyTheseCustomersAreReturned(result, "aaa", "aab", "aac");
|
exactlyTheseCustomersAreReturned(result, "aaa", "aab", "aac");
|
||||||
@ -115,7 +117,7 @@ class CustomerRepositoryIntegrationTest {
|
|||||||
assumedRoles("global#hostsharing.admin");
|
assumedRoles("global#hostsharing.admin");
|
||||||
|
|
||||||
// when
|
// when
|
||||||
final var result = customerRepository.findAll();
|
final var result = customerRepository.findCustomerByOptionalPrefix(null);
|
||||||
|
|
||||||
then:
|
then:
|
||||||
exactlyTheseCustomersAreReturned(result, "aaa", "aab", "aac");
|
exactlyTheseCustomersAreReturned(result, "aaa", "aab", "aac");
|
||||||
@ -127,7 +129,7 @@ class CustomerRepositoryIntegrationTest {
|
|||||||
currentUser("admin@aaa.example.com");
|
currentUser("admin@aaa.example.com");
|
||||||
|
|
||||||
// when:
|
// when:
|
||||||
final var result = customerRepository.findAll();
|
final var result = customerRepository.findCustomerByOptionalPrefix(null);
|
||||||
|
|
||||||
// then:
|
// then:
|
||||||
exactlyTheseCustomersAreReturned(result, "aaa");
|
exactlyTheseCustomersAreReturned(result, "aaa");
|
||||||
@ -138,7 +140,7 @@ class CustomerRepositoryIntegrationTest {
|
|||||||
currentUser("admin@aaa.example.com");
|
currentUser("admin@aaa.example.com");
|
||||||
assumedRoles("package#aaa00.admin");
|
assumedRoles("package#aaa00.admin");
|
||||||
|
|
||||||
final var result = customerRepository.findAll();
|
final var result = customerRepository.findCustomerByOptionalPrefix(null);
|
||||||
|
|
||||||
exactlyTheseCustomersAreReturned(result, "aaa");
|
exactlyTheseCustomersAreReturned(result, "aaa");
|
||||||
}
|
}
|
||||||
@ -152,7 +154,7 @@ class CustomerRepositoryIntegrationTest {
|
|||||||
// when
|
// when
|
||||||
final var attempt = attempt(
|
final var attempt = attempt(
|
||||||
em,
|
em,
|
||||||
() -> customerRepository.findAll());
|
() -> customerRepository.findCustomerByOptionalPrefix(null));
|
||||||
|
|
||||||
// then
|
// then
|
||||||
attempt.assertExceptionWithRootCauseMessage(
|
attempt.assertExceptionWithRootCauseMessage(
|
||||||
@ -166,7 +168,7 @@ class CustomerRepositoryIntegrationTest {
|
|||||||
|
|
||||||
final var attempt = attempt(
|
final var attempt = attempt(
|
||||||
em,
|
em,
|
||||||
() -> customerRepository.findAll());
|
() -> customerRepository.findCustomerByOptionalPrefix(null));
|
||||||
|
|
||||||
attempt.assertExceptionWithRootCauseMessage(
|
attempt.assertExceptionWithRootCauseMessage(
|
||||||
JpaSystemException.class,
|
JpaSystemException.class,
|
||||||
@ -181,7 +183,7 @@ class CustomerRepositoryIntegrationTest {
|
|||||||
|
|
||||||
final var attempt = attempt(
|
final var attempt = attempt(
|
||||||
em,
|
em,
|
||||||
() -> customerRepository.findAll());
|
() -> customerRepository.findCustomerByOptionalPrefix(null));
|
||||||
|
|
||||||
attempt.assertExceptionWithRootCauseMessage(
|
attempt.assertExceptionWithRootCauseMessage(
|
||||||
JpaSystemException.class,
|
JpaSystemException.class,
|
||||||
@ -190,6 +192,34 @@ class CustomerRepositoryIntegrationTest {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
class FindByPrefixLike {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void hostsharingAdmin_withoutAssumedRole_canViewAllCustomers() {
|
||||||
|
// given
|
||||||
|
currentUser("mike@hostsharing.net");
|
||||||
|
|
||||||
|
// when
|
||||||
|
final var result = customerRepository.findCustomerByOptionalPrefix("aab");
|
||||||
|
|
||||||
|
// then
|
||||||
|
exactlyTheseCustomersAreReturned(result, "aab");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void customerAdmin_withoutAssumedRole_canViewOnlyItsOwnCustomer() {
|
||||||
|
// given:
|
||||||
|
currentUser("admin@aaa.example.com");
|
||||||
|
|
||||||
|
// when:
|
||||||
|
final var result = customerRepository.findCustomerByOptionalPrefix("aab");
|
||||||
|
|
||||||
|
// then:
|
||||||
|
exactlyTheseCustomersAreReturned(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void currentUser(final String currentUser) {
|
void currentUser(final String currentUser) {
|
||||||
context.setCurrentUser(currentUser);
|
context.setCurrentUser(currentUser);
|
||||||
assertThat(context.getCurrentUser()).as("precondition").isEqualTo(currentUser);
|
assertThat(context.getCurrentUser()).as("precondition").isEqualTo(currentUser);
|
||||||
|
Loading…
Reference in New Issue
Block a user