align create methods and improve and align acceptance tests
This commit is contained in:
parent
9a7b683e7d
commit
2531b9071f
@ -28,26 +28,26 @@ public class CustomerController implements CustomersApi {
|
|||||||
@Override
|
@Override
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
public ResponseEntity<List<CustomerResource>> listCustomers(
|
public ResponseEntity<List<CustomerResource>> listCustomers(
|
||||||
String userName,
|
String userName,
|
||||||
String assumedRoles,
|
String assumedRoles,
|
||||||
String prefix
|
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 ResponseEntity.ok(
|
|
||||||
mapList(
|
final var result = customerRepository.findCustomerByOptionalPrefixLike(prefix);
|
||||||
customerRepository.findCustomerByOptionalPrefixLike(prefix),
|
|
||||||
CustomerResource.class));
|
return ResponseEntity.ok(mapList(result, CustomerResource.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public ResponseEntity<CustomerResource> addCustomer(
|
public ResponseEntity<CustomerResource> addCustomer(
|
||||||
final String currentUser,
|
final String currentUser,
|
||||||
final String assumedRoles,
|
final String assumedRoles,
|
||||||
final CustomerResource customer) {
|
final CustomerResource customer) {
|
||||||
|
|
||||||
context.setCurrentTask("create new customer: #" + customer.getReference() + " / " + customer.getPrefix());
|
context.setCurrentTask("create new customer: #" + customer.getReference() + " / " + customer.getPrefix());
|
||||||
context.setCurrentUser(currentUser);
|
context.setCurrentUser(currentUser);
|
||||||
@ -61,10 +61,10 @@ public class CustomerController implements CustomersApi {
|
|||||||
final var saved = customerRepository.save(map(customer, CustomerEntity.class));
|
final var saved = customerRepository.save(map(customer, CustomerEntity.class));
|
||||||
|
|
||||||
final var uri =
|
final var uri =
|
||||||
MvcUriComponentsBuilder.fromController(getClass())
|
MvcUriComponentsBuilder.fromController(getClass())
|
||||||
.path("/api/rbac-users/{id}")
|
.path("/api/rbac-users/{id}")
|
||||||
.buildAndExpand(customer.getUuid())
|
.buildAndExpand(customer.getUuid())
|
||||||
.toUri();
|
.toUri();
|
||||||
return ResponseEntity.created(uri).body(map(saved, CustomerResource.class));
|
return ResponseEntity.created(uri).body(map(saved, CustomerResource.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ import org.springframework.transaction.annotation.Transactional;
|
|||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder;
|
import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder;
|
||||||
|
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@ -25,6 +26,9 @@ public class RbacGrantController implements RbacgrantsApi {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private RbacGrantRepository rbacGrantRepository;
|
private RbacGrantRepository rbacGrantRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private EntityManager em;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
public ResponseEntity<RbacGrantResource> getGrantById(
|
public ResponseEntity<RbacGrantResource> getGrantById(
|
||||||
@ -61,7 +65,7 @@ public class RbacGrantController implements RbacgrantsApi {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public ResponseEntity<Void> grantRoleToUser(
|
public ResponseEntity<RbacGrantResource> grantRoleToUser(
|
||||||
final String currentUser,
|
final String currentUser,
|
||||||
final String assumedRoles,
|
final String assumedRoles,
|
||||||
final RbacGrantResource body) {
|
final RbacGrantResource body) {
|
||||||
@ -72,14 +76,16 @@ public class RbacGrantController implements RbacgrantsApi {
|
|||||||
context.assumeRoles(assumedRoles);
|
context.assumeRoles(assumedRoles);
|
||||||
}
|
}
|
||||||
|
|
||||||
rbacGrantRepository.save(map(body, RbacGrantEntity.class));
|
final var granted = rbacGrantRepository.save(map(body, RbacGrantEntity.class));
|
||||||
|
em.flush();
|
||||||
|
em.refresh(granted);
|
||||||
|
|
||||||
final var uri =
|
final var uri =
|
||||||
MvcUriComponentsBuilder.fromController(getClass())
|
MvcUriComponentsBuilder.fromController(getClass())
|
||||||
.path("/api/rbac-grants/{roleUuid}")
|
.path("/api/rbac-grants/{roleUuid}")
|
||||||
.buildAndExpand(body.getGrantedRoleUuid())
|
.buildAndExpand(body.getGrantedRoleUuid())
|
||||||
.toUri();
|
.toUri();
|
||||||
return ResponseEntity.created(uri).build();
|
return ResponseEntity.created(uri).body(map(granted, RbacGrantResource.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -100,5 +106,4 @@ public class RbacGrantController implements RbacgrantsApi {
|
|||||||
|
|
||||||
return ResponseEntity.noContent().build();
|
return ResponseEntity.noContent().build();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ public interface RbacGrantRepository extends Repository<RbacGrantEntity, RbacGra
|
|||||||
|
|
||||||
List<RbacGrantEntity> findAll();
|
List<RbacGrantEntity> findAll();
|
||||||
|
|
||||||
void save(final RbacGrantEntity grant);
|
RbacGrantEntity save(final RbacGrantEntity grant);
|
||||||
|
|
||||||
@Modifying
|
@Modifying
|
||||||
@Query(value = """
|
@Query(value = """
|
||||||
|
@ -32,6 +32,9 @@ post:
|
|||||||
"201":
|
"201":
|
||||||
description: OK
|
description: OK
|
||||||
content:
|
content:
|
||||||
|
'application/json':
|
||||||
|
schema:
|
||||||
|
$ref: './api-definition/rbac-grant-schemas.yaml#/components/schemas/RbacGrant'
|
||||||
"401":
|
"401":
|
||||||
$ref: './api-definition/error-responses.yaml#/components/responses/Unauthorized'
|
$ref: './api-definition/error-responses.yaml#/components/responses/Unauthorized'
|
||||||
"403":
|
"403":
|
||||||
|
@ -0,0 +1,173 @@
|
|||||||
|
package net.hostsharing.hsadminng.hs.hscustomer;
|
||||||
|
|
||||||
|
import io.restassured.RestAssured;
|
||||||
|
import io.restassured.http.ContentType;
|
||||||
|
import net.hostsharing.hsadminng.HsadminNgApplication;
|
||||||
|
import net.hostsharing.hsadminng.context.Context;
|
||||||
|
import org.junit.jupiter.api.Nested;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.boot.test.web.server.LocalServerPort;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.hamcrest.CoreMatchers.containsString;
|
||||||
|
import static org.hamcrest.Matchers.*;
|
||||||
|
|
||||||
|
@SpringBootTest(
|
||||||
|
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||||
|
classes = HsadminNgApplication.class
|
||||||
|
)
|
||||||
|
@Transactional
|
||||||
|
class CustomerControllerAcceptanceTest {
|
||||||
|
|
||||||
|
@LocalServerPort
|
||||||
|
private Integer port;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
Context context;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
Context contextMock;
|
||||||
|
@Autowired
|
||||||
|
CustomerRepository customerRepository;
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
class ListCustomers {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void hostsharingAdmin_withoutAssumedRoles_canViewAllCustomers_ifNoCriteriaGiven() {
|
||||||
|
RestAssured // @formatter:off
|
||||||
|
.given()
|
||||||
|
.header("current-user", "mike@hostsharing.net")
|
||||||
|
.port(port)
|
||||||
|
.when()
|
||||||
|
.get("http://localhost/api/customers")
|
||||||
|
.then().assertThat()
|
||||||
|
.statusCode(200)
|
||||||
|
.contentType("application/json")
|
||||||
|
.body("[0].prefix", is("xxx"))
|
||||||
|
.body("[1].prefix", is("yyy"))
|
||||||
|
.body("[2].prefix", is("zzz"))
|
||||||
|
.body("size()", greaterThanOrEqualTo(3));
|
||||||
|
// @formatter:on
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void hostsharingAdmin_withoutAssumedRoles_canViewMatchingCustomers_ifCriteriaGiven() throws Exception {
|
||||||
|
RestAssured // @formatter:off
|
||||||
|
.given()
|
||||||
|
.header("current-user", "mike@hostsharing.net")
|
||||||
|
.port(port)
|
||||||
|
.when()
|
||||||
|
.get("http://localhost/api/customers?prefix=y")
|
||||||
|
.then().assertThat()
|
||||||
|
.statusCode(200)
|
||||||
|
.contentType("application/json")
|
||||||
|
.body("[0].prefix", is("yyy"))
|
||||||
|
.body("size()", is(1));
|
||||||
|
// @formatter:on
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void hostsharingAdmin_withoutAssumedCustomerAdminRole_canOnlyViewOwnCustomer() throws Exception {
|
||||||
|
RestAssured // @formatter:off
|
||||||
|
.given()
|
||||||
|
.header("current-user", "mike@hostsharing.net")
|
||||||
|
.header("assumed-roles", "customer#yyy.admin")
|
||||||
|
.port(port)
|
||||||
|
.when()
|
||||||
|
.get("http://localhost/api/customers")
|
||||||
|
.then().assertThat()
|
||||||
|
.statusCode(200)
|
||||||
|
.contentType("application/json")
|
||||||
|
.body("[0].prefix", is("yyy"))
|
||||||
|
.body("size()", is(1));
|
||||||
|
// @formatter:on
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void customerAdmin_withoutAssumedRole_canOnlyViewOwnCustomer() throws Exception {
|
||||||
|
RestAssured // @formatter:off
|
||||||
|
.given()
|
||||||
|
.header("current-user", "customer-admin@yyy.example.com")
|
||||||
|
.port(port)
|
||||||
|
.when()
|
||||||
|
.get("http://localhost/api/customers")
|
||||||
|
.then().assertThat()
|
||||||
|
.statusCode(200)
|
||||||
|
.contentType("application/json")
|
||||||
|
.body("[0].prefix", is("yyy"))
|
||||||
|
.body("size()", is(1));
|
||||||
|
// @formatter:on
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
class CreateCustomer {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void hostsharingAdmin_withoutAssumedRole_canCreateCustomer() throws Exception {
|
||||||
|
|
||||||
|
final var location = RestAssured // @formatter:off
|
||||||
|
.given()
|
||||||
|
.header("current-user", "mike@hostsharing.net")
|
||||||
|
.contentType(ContentType.JSON)
|
||||||
|
.body("""
|
||||||
|
{
|
||||||
|
"reference": 90010,
|
||||||
|
"prefix": "vvv",
|
||||||
|
"adminUserName": "customer-admin@vvv.example.com"
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
.port(port)
|
||||||
|
.when()
|
||||||
|
.post("http://localhost/api/customers")
|
||||||
|
.then().assertThat()
|
||||||
|
.statusCode(201)
|
||||||
|
.contentType(ContentType.JSON)
|
||||||
|
.body("prefix", is("vvv"))
|
||||||
|
.header("Location", startsWith("http://localhost"))
|
||||||
|
.extract().header("Location"); // @formatter:on
|
||||||
|
|
||||||
|
// finally, the new customer can be viewed by its own admin
|
||||||
|
final var newUserUuid = UUID.fromString(
|
||||||
|
location.substring(location.lastIndexOf('/') + 1));
|
||||||
|
context.setCurrentUser("customer-admin@vvv.example.com");
|
||||||
|
assertThat(customerRepository.findByUuid(newUserUuid))
|
||||||
|
.hasValueSatisfying(c -> assertThat(c.getPrefix()).isEqualTo("vvv"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void customerAdmin_withoutAssumedRole_canNotCreateCustomer() throws Exception {
|
||||||
|
|
||||||
|
RestAssured // @formatter:off
|
||||||
|
.given()
|
||||||
|
.header("current-user", "customer-admin@yyy.example.com")
|
||||||
|
.contentType(ContentType.JSON)
|
||||||
|
.body("""
|
||||||
|
{
|
||||||
|
"reference": 90010,
|
||||||
|
"prefix": "uuu",
|
||||||
|
"adminUserName": "customer-admin@uuu.example.com"
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
.port(port)
|
||||||
|
.when()
|
||||||
|
.post("http://localhost/api/customers")
|
||||||
|
.then().assertThat()
|
||||||
|
.statusCode(403)
|
||||||
|
.contentType(ContentType.JSON)
|
||||||
|
.statusCode(403)
|
||||||
|
.body("message", containsString("add-customer not permitted for customer-admin@yyy.example.com"));
|
||||||
|
// @formatter:on
|
||||||
|
|
||||||
|
// finally, the new customer was not created
|
||||||
|
context.setCurrentUser("sven@hostsharing.net");
|
||||||
|
assertThat(customerRepository.findCustomerByOptionalPrefixLike("uuu")).hasSize(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,110 +0,0 @@
|
|||||||
package net.hostsharing.hsadminng.hs.hscustomer;
|
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
|
||||||
import org.junit.jupiter.api.Nested;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
|
||||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
|
||||||
import org.springframework.http.MediaType;
|
|
||||||
import org.springframework.test.web.servlet.MockMvc;
|
|
||||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.hasSize;
|
|
||||||
import static org.hamcrest.Matchers.is;
|
|
||||||
import static org.mockito.ArgumentMatchers.anyString;
|
|
||||||
import static org.mockito.Mockito.*;
|
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
|
||||||
|
|
||||||
@WebMvcTest(CustomerController.class)
|
|
||||||
class CustomerControllerRestTest {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
MockMvc mockMvc;
|
|
||||||
@MockBean
|
|
||||||
Context contextMock;
|
|
||||||
@MockBean
|
|
||||||
CustomerRepository customerRepositoryMock;
|
|
||||||
|
|
||||||
@Nested
|
|
||||||
class ListCustomers {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void listCustomersWillReturnAllCustomersFromRepositoryIfNoCriteriaGiven() throws Exception {
|
|
||||||
|
|
||||||
// given
|
|
||||||
when(customerRepositoryMock.findCustomerByOptionalPrefixLike(null)).thenReturn(List.of(
|
|
||||||
TestCustomer.xxx,
|
|
||||||
TestCustomer.yyy));
|
|
||||||
|
|
||||||
// when
|
|
||||||
mockMvc.perform(MockMvcRequestBuilders
|
|
||||||
.get("/api/customers")
|
|
||||||
.header("current-user", "mike@hostsharing.net")
|
|
||||||
.accept(MediaType.APPLICATION_JSON))
|
|
||||||
|
|
||||||
// then
|
|
||||||
.andExpect(status().isOk())
|
|
||||||
.andExpect(jsonPath("$", hasSize(2)))
|
|
||||||
.andExpect(jsonPath("$[0].prefix", is(TestCustomer.xxx.getPrefix())))
|
|
||||||
.andExpect(jsonPath("$[1].reference", is(TestCustomer.yyy.getReference()))
|
|
||||||
);
|
|
||||||
|
|
||||||
// then
|
|
||||||
verify(contextMock).setCurrentUser("mike@hostsharing.net");
|
|
||||||
verify(contextMock, never()).assumeRoles(anyString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void listCustomersWillReturnMatchingCustomersFromRepositoryIfCriteriaGiven() throws Exception {
|
|
||||||
|
|
||||||
// given
|
|
||||||
when(customerRepositoryMock.findCustomerByOptionalPrefixLike("x")).thenReturn(List.of(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()))
|
|
||||||
);
|
|
||||||
|
|
||||||
// then
|
|
||||||
verify(contextMock).setCurrentUser("mike@hostsharing.net");
|
|
||||||
verify(contextMock, never()).assumeRoles(anyString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void listCustomersWillReturnAllCustomersForGivenAssumedRoles() throws Exception {
|
|
||||||
|
|
||||||
// given
|
|
||||||
when(customerRepositoryMock.findCustomerByOptionalPrefixLike(null)).thenReturn(List.of(TestCustomer.yyy));
|
|
||||||
|
|
||||||
// when
|
|
||||||
mockMvc.perform(MockMvcRequestBuilders
|
|
||||||
.get("/api/customers")
|
|
||||||
.header("current-user", "mike@hostsharing.net")
|
|
||||||
.header("assumed-roles", "customer-admin@yyy.example.com")
|
|
||||||
.accept(MediaType.APPLICATION_JSON))
|
|
||||||
|
|
||||||
// then
|
|
||||||
.andExpect(status().isOk())
|
|
||||||
.andExpect(jsonPath("$", hasSize(1)))
|
|
||||||
.andExpect(jsonPath("$[0].prefix", is(TestCustomer.yyy.getPrefix()))
|
|
||||||
);
|
|
||||||
|
|
||||||
// then
|
|
||||||
verify(contextMock).setCurrentUser("mike@hostsharing.net");
|
|
||||||
verify(contextMock).assumeRoles("customer-admin@yyy.example.com");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -27,7 +27,8 @@ class CustomerRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
@Autowired
|
@Autowired
|
||||||
CustomerRepository customerRepository;
|
CustomerRepository customerRepository;
|
||||||
|
|
||||||
@Autowired EntityManager em;
|
@Autowired
|
||||||
|
EntityManager em;
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
class CreateCustomer {
|
class CreateCustomer {
|
||||||
@ -42,7 +43,7 @@ class CustomerRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
|
|
||||||
final var result = attempt(em, () -> {
|
final var result = attempt(em, () -> {
|
||||||
final var newCustomer = new CustomerEntity(
|
final var newCustomer = new CustomerEntity(
|
||||||
UUID.randomUUID(), "www", 90001, "customer-admin@www.example.com");
|
UUID.randomUUID(), "www", 90001, "customer-admin@www.example.com");
|
||||||
return customerRepository.save(newCustomer);
|
return customerRepository.save(newCustomer);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -61,14 +62,14 @@ class CustomerRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
// when
|
// when
|
||||||
final var result = attempt(em, () -> {
|
final var result = attempt(em, () -> {
|
||||||
final var newCustomer = new CustomerEntity(
|
final var newCustomer = new CustomerEntity(
|
||||||
UUID.randomUUID(), "www", 90001, "customer-admin@www.example.com");
|
UUID.randomUUID(), "www", 90001, "customer-admin@www.example.com");
|
||||||
return customerRepository.save(newCustomer);
|
return customerRepository.save(newCustomer);
|
||||||
});
|
});
|
||||||
|
|
||||||
// then
|
// then
|
||||||
result.assertExceptionWithRootCauseMessage(
|
result.assertExceptionWithRootCauseMessage(
|
||||||
PersistenceException.class,
|
PersistenceException.class,
|
||||||
"add-customer not permitted for customer#xxx.admin");
|
"add-customer not permitted for customer#xxx.admin");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -79,14 +80,14 @@ class CustomerRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
// when
|
// when
|
||||||
final var result = attempt(em, () -> {
|
final var result = attempt(em, () -> {
|
||||||
final var newCustomer = new CustomerEntity(
|
final var newCustomer = new CustomerEntity(
|
||||||
UUID.randomUUID(), "www", 90001, "customer-admin@www.example.com");
|
UUID.randomUUID(), "www", 90001, "customer-admin@www.example.com");
|
||||||
return customerRepository.save(newCustomer);
|
return customerRepository.save(newCustomer);
|
||||||
});
|
});
|
||||||
|
|
||||||
// then
|
// then
|
||||||
result.assertExceptionWithRootCauseMessage(
|
result.assertExceptionWithRootCauseMessage(
|
||||||
PersistenceException.class,
|
PersistenceException.class,
|
||||||
"add-customer not permitted for customer-admin@xxx.example.com");
|
"add-customer not permitted for customer-admin@xxx.example.com");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,7 +109,7 @@ class CustomerRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
final var result = customerRepository.findCustomerByOptionalPrefixLike(null);
|
final var result = customerRepository.findCustomerByOptionalPrefixLike(null);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
exactlyTheseCustomersAreReturned(result, "xxx", "yyy", "zzz");
|
allTheseCustomersAreReturned(result, "xxx", "yyy", "zzz");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -120,7 +121,7 @@ class CustomerRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
final var result = customerRepository.findCustomerByOptionalPrefixLike(null);
|
final var result = customerRepository.findCustomerByOptionalPrefixLike(null);
|
||||||
|
|
||||||
then:
|
then:
|
||||||
exactlyTheseCustomersAreReturned(result, "xxx", "yyy", "zzz");
|
allTheseCustomersAreReturned(result, "xxx", "yyy", "zzz");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -151,13 +152,13 @@ class CustomerRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
|
|
||||||
// when
|
// when
|
||||||
final var result = attempt(
|
final var result = attempt(
|
||||||
em,
|
em,
|
||||||
() -> customerRepository.findCustomerByOptionalPrefixLike(null));
|
() -> customerRepository.findCustomerByOptionalPrefixLike(null));
|
||||||
|
|
||||||
// then
|
// then
|
||||||
result.assertExceptionWithRootCauseMessage(
|
result.assertExceptionWithRootCauseMessage(
|
||||||
JpaSystemException.class,
|
JpaSystemException.class,
|
||||||
"[403] user customer-admin@xxx.example.com", "has no permission to assume role package#yyy00#admin");
|
"[403] user customer-admin@xxx.example.com", "has no permission to assume role package#yyy00#admin");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -165,12 +166,12 @@ class CustomerRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
context("unknown@example.org", null);
|
context("unknown@example.org", null);
|
||||||
|
|
||||||
final var result = attempt(
|
final var result = attempt(
|
||||||
em,
|
em,
|
||||||
() -> customerRepository.findCustomerByOptionalPrefixLike(null));
|
() -> customerRepository.findCustomerByOptionalPrefixLike(null));
|
||||||
|
|
||||||
result.assertExceptionWithRootCauseMessage(
|
result.assertExceptionWithRootCauseMessage(
|
||||||
JpaSystemException.class,
|
JpaSystemException.class,
|
||||||
"hsadminng.currentUser defined as unknown@example.org, but does not exists");
|
"hsadminng.currentUser defined as unknown@example.org, but does not exists");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -179,12 +180,12 @@ class CustomerRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
context("unknown@example.org", "customer#xxx.admin");
|
context("unknown@example.org", "customer#xxx.admin");
|
||||||
|
|
||||||
final var result = attempt(
|
final var result = attempt(
|
||||||
em,
|
em,
|
||||||
() -> customerRepository.findCustomerByOptionalPrefixLike(null));
|
() -> customerRepository.findCustomerByOptionalPrefixLike(null));
|
||||||
|
|
||||||
result.assertExceptionWithRootCauseMessage(
|
result.assertExceptionWithRootCauseMessage(
|
||||||
JpaSystemException.class,
|
JpaSystemException.class,
|
||||||
"hsadminng.currentUser defined as unknown@example.org, but does not exists");
|
"hsadminng.currentUser defined as unknown@example.org, but does not exists");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -219,9 +220,14 @@ class CustomerRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
|
|
||||||
void exactlyTheseCustomersAreReturned(final List<CustomerEntity> actualResult, final String... customerPrefixes) {
|
void exactlyTheseCustomersAreReturned(final List<CustomerEntity> actualResult, final String... customerPrefixes) {
|
||||||
assertThat(actualResult)
|
assertThat(actualResult)
|
||||||
.hasSize(customerPrefixes.length)
|
.hasSize(customerPrefixes.length)
|
||||||
.extracting(CustomerEntity::getPrefix)
|
.extracting(CustomerEntity::getPrefix)
|
||||||
.containsExactlyInAnyOrder(customerPrefixes);
|
.containsExactlyInAnyOrder(customerPrefixes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void allTheseCustomersAreReturned(final List<CustomerEntity> actualResult, final String... customerPrefixes) {
|
||||||
|
assertThat(actualResult)
|
||||||
|
.extracting(CustomerEntity::getPrefix)
|
||||||
|
.contains(customerPrefixes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -102,7 +102,9 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
|
|||||||
@Accepts({ "GRT:R(Read)" })
|
@Accepts({ "GRT:R(Read)" })
|
||||||
void packageAdmin_withAssumedUnixUserAdmin_canNotReadItsOwnGrantById() {
|
void packageAdmin_withAssumedUnixUserAdmin_canNotReadItsOwnGrantById() {
|
||||||
// given
|
// given
|
||||||
final var givenCurrentUserAsPackageAdmin = new Subject("pac-admin-xxx00@xxx.example.com", "unixuser#xxx00-xxxa.admin");
|
final var givenCurrentUserAsPackageAdmin = new Subject(
|
||||||
|
"pac-admin-xxx00@xxx.example.com",
|
||||||
|
"unixuser#xxx00-xxxa.admin");
|
||||||
final var givenGranteeUser = findRbacUserByName("pac-admin-xxx00@xxx.example.com");
|
final var givenGranteeUser = findRbacUserByName("pac-admin-xxx00@xxx.example.com");
|
||||||
final var givenGrantedRole = findRbacRoleByName("package#xxx00.admin");
|
final var givenGrantedRole = findRbacRoleByName("package#xxx00.admin");
|
||||||
|
|
||||||
@ -131,11 +133,17 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
|
|||||||
findRbacRoleByName(givenCurrentUserAsPackageAdmin.assumedRole);
|
findRbacRoleByName(givenCurrentUserAsPackageAdmin.assumedRole);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
givenCurrentUserAsPackageAdmin
|
final var response = givenCurrentUserAsPackageAdmin
|
||||||
.grantsRole(givenOwnPackageAdminRole).assumed()
|
.grantsRole(givenOwnPackageAdminRole).assumed()
|
||||||
.toUser(givenNewUser);
|
.toUser(givenNewUser);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
|
response.assertThat()
|
||||||
|
.statusCode(201)
|
||||||
|
.body("grantedByRoleIdName", is("package#xxx00.admin"))
|
||||||
|
.body("assumed", is(true))
|
||||||
|
.body("grantedRoleIdName", is("package#xxx00.admin"))
|
||||||
|
.body("granteeUserName", is(givenNewUser.getName()));
|
||||||
assertThat(findAllGrantsOf(givenCurrentUserAsPackageAdmin))
|
assertThat(findAllGrantsOf(givenCurrentUserAsPackageAdmin))
|
||||||
.extracting(RbacGrantEntity::toDisplay)
|
.extracting(RbacGrantEntity::toDisplay)
|
||||||
.contains("{ grant assumed role " + givenOwnPackageAdminRole.getRoleName() +
|
.contains("{ grant assumed role " + givenOwnPackageAdminRole.getRoleName() +
|
||||||
@ -160,9 +168,9 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
|
|||||||
|
|
||||||
// then
|
// then
|
||||||
result.assertThat()
|
result.assertThat()
|
||||||
|
.statusCode(403)
|
||||||
.body("message", containsString("Access to granted role"))
|
.body("message", containsString("Access to granted role"))
|
||||||
.body("message", containsString("forbidden for {package#xxx00.admin}"))
|
.body("message", containsString("forbidden for {package#xxx00.admin}"));
|
||||||
.statusCode(403);
|
|
||||||
assertThat(findAllGrantsOf(givenCurrentUserAsPackageAdmin))
|
assertThat(findAllGrantsOf(givenCurrentUserAsPackageAdmin))
|
||||||
.extracting(RbacGrantEntity::getGranteeUserName)
|
.extracting(RbacGrantEntity::getGranteeUserName)
|
||||||
.doesNotContain(givenNewUser.getName());
|
.doesNotContain(givenNewUser.getName());
|
||||||
@ -200,7 +208,7 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
|
|||||||
.fromUser(givenArbitraryUser);
|
.fromUser(givenArbitraryUser);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assertRevoked(revokeResponse);
|
revokeResponse.assertThat().statusCode(204);
|
||||||
assertThat(findAllGrantsOf(givenCurrentUserAsPackageAdmin))
|
assertThat(findAllGrantsOf(givenCurrentUserAsPackageAdmin))
|
||||||
.extracting(RbacGrantEntity::getGranteeUserName)
|
.extracting(RbacGrantEntity::getGranteeUserName)
|
||||||
.doesNotContain(givenArbitraryUser.getName());
|
.doesNotContain(givenArbitraryUser.getName());
|
||||||
@ -211,10 +219,6 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
|
|||||||
assumeThat(response.extract().response().statusCode()).isEqualTo(201);
|
assumeThat(response.extract().response().statusCode()).isEqualTo(201);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertRevoked(final ValidatableResponse revokeResponse) {
|
|
||||||
revokeResponse.assertThat().statusCode(204);
|
|
||||||
}
|
|
||||||
|
|
||||||
class Subject {
|
class Subject {
|
||||||
|
|
||||||
final String currentUser;
|
final String currentUser;
|
||||||
@ -278,7 +282,7 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
|
|||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.post("http://localhost/api/rbac-grants")
|
.post("http://localhost/api/rbac-grants")
|
||||||
.then(); // @formatter:on
|
.then().log().all(); // @formatter:on
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -316,7 +320,7 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
|
|||||||
.delete("http://localhost/api/rbac-grants/%s/%s".formatted(
|
.delete("http://localhost/api/rbac-grants/%s/%s".formatted(
|
||||||
grantedRole.getUuid(), granteeUser.getUuid()
|
grantedRole.getUuid(), granteeUser.getUuid()
|
||||||
))
|
))
|
||||||
.then(); // @formatter:on
|
.then().log().all(); // @formatter:on
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -344,7 +348,7 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
|
|||||||
.get("http://localhost/api/rbac-grants/%s/%s".formatted(
|
.get("http://localhost/api/rbac-grants/%s/%s".formatted(
|
||||||
grantedRole.getUuid(), granteeUser.getUuid()
|
grantedRole.getUuid(), granteeUser.getUuid()
|
||||||
))
|
))
|
||||||
.then(); // @formatter:on
|
.then().log().all(); // @formatter:on
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,8 +15,8 @@ import javax.persistence.EntityManager;
|
|||||||
import static org.hamcrest.Matchers.*;
|
import static org.hamcrest.Matchers.*;
|
||||||
|
|
||||||
@SpringBootTest(
|
@SpringBootTest(
|
||||||
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||||
classes = HsadminNgApplication.class
|
classes = HsadminNgApplication.class
|
||||||
)
|
)
|
||||||
@Accepts({ "ROL:*:S:Schema" })
|
@Accepts({ "ROL:*:S:Schema" })
|
||||||
class RbacRoleControllerAcceptanceTest {
|
class RbacRoleControllerAcceptanceTest {
|
||||||
@ -38,7 +38,7 @@ class RbacRoleControllerAcceptanceTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Accepts({ "ROL:L(List)" })
|
@Accepts({ "ROL:L(List)" })
|
||||||
void hostsharingAdmin_withoutAssumedRole_canViewPackageAdminRoles() {
|
void hostsharingAdmin_withoutAssumedRole_canViewAllRoles() {
|
||||||
|
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
RestAssured
|
RestAssured
|
||||||
@ -50,15 +50,15 @@ class RbacRoleControllerAcceptanceTest {
|
|||||||
.then().assertThat()
|
.then().assertThat()
|
||||||
.statusCode(200)
|
.statusCode(200)
|
||||||
.contentType("application/json")
|
.contentType("application/json")
|
||||||
.body("[0].roleName", is("customer#xxx.admin"))
|
.body("", hasItem(hasEntry("roleName", "customer#xxx.admin")))
|
||||||
.body("[1].roleName", is("customer#xxx.owner"))
|
.body("", hasItem(hasEntry("roleName", "customer#xxx.owner")))
|
||||||
.body("[2].roleName", is("customer#xxx.tenant"))
|
.body("", hasItem(hasEntry("roleName", "customer#xxx.tenant")))
|
||||||
// ...
|
// ...
|
||||||
.body("", hasItem(hasEntry("roleName", "global#hostsharing.admin")))
|
.body("", hasItem(hasEntry("roleName", "global#hostsharing.admin")))
|
||||||
.body("", hasItem(hasEntry("roleName", "customer#yyy.admin")))
|
.body("", hasItem(hasEntry("roleName", "customer#yyy.admin")))
|
||||||
.body("", hasItem(hasEntry("roleName", "package#yyy00.admin")))
|
.body("", hasItem(hasEntry("roleName", "package#yyy00.admin")))
|
||||||
.body("", hasItem(hasEntry("roleName", "unixuser#yyy00-aaaa.owner")))
|
.body("", hasItem(hasEntry("roleName", "unixuser#yyy00-aaaa.owner")))
|
||||||
.body( "size()", is(73)); // increases with new test data
|
.body( "size()", greaterThanOrEqualTo(73)); // increases with new test data
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,8 +18,8 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||||||
import static org.hamcrest.Matchers.*;
|
import static org.hamcrest.Matchers.*;
|
||||||
|
|
||||||
@SpringBootTest(
|
@SpringBootTest(
|
||||||
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||||
classes = HsadminNgApplication.class
|
classes = HsadminNgApplication.class
|
||||||
)
|
)
|
||||||
@Transactional
|
@Transactional
|
||||||
class RbacUserControllerAcceptanceTest {
|
class RbacUserControllerAcceptanceTest {
|
||||||
@ -52,14 +52,14 @@ class RbacUserControllerAcceptanceTest {
|
|||||||
.then().log().body().assertThat()
|
.then().log().body().assertThat()
|
||||||
.statusCode(200)
|
.statusCode(200)
|
||||||
.contentType("application/json")
|
.contentType("application/json")
|
||||||
.body("[0].name", is("customer-admin@xxx.example.com"))
|
.body("", hasItem(hasEntry("name", "customer-admin@xxx.example.com")))
|
||||||
.body("[1].name", is("customer-admin@yyy.example.com"))
|
.body("", hasItem(hasEntry("name", "customer-admin@yyy.example.com")))
|
||||||
.body("[2].name", is("customer-admin@zzz.example.com"))
|
.body("", hasItem(hasEntry("name", "customer-admin@zzz.example.com")))
|
||||||
.body("[3].name", is("mike@hostsharing.net"))
|
.body("", hasItem(hasEntry("name", "mike@hostsharing.net")))
|
||||||
// ...
|
// ...
|
||||||
.body("[11].name", is("pac-admin-zzz01@zzz.example.com"))
|
.body("", hasItem(hasEntry("name", "pac-admin-zzz01@zzz.example.com")))
|
||||||
.body("[12].name", is("pac-admin-zzz02@zzz.example.com"))
|
.body("", hasItem(hasEntry("name", "pac-admin-zzz02@zzz.example.com")))
|
||||||
.body("[13].name", is("sven@hostsharing.net"))
|
.body("", hasItem(hasEntry("name", "sven@hostsharing.net")))
|
||||||
.body("size()", greaterThanOrEqualTo(14));
|
.body("size()", greaterThanOrEqualTo(14));
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
}
|
}
|
||||||
@ -152,10 +152,10 @@ class RbacUserControllerAcceptanceTest {
|
|||||||
|
|
||||||
// finally, the user can view its own record
|
// finally, the user can view its own record
|
||||||
final var newUserUuid = UUID.fromString(
|
final var newUserUuid = UUID.fromString(
|
||||||
location.substring(location.lastIndexOf('/') + 1));
|
location.substring(location.lastIndexOf('/') + 1));
|
||||||
context.setCurrentUser("new-user@example.com");
|
context.setCurrentUser("new-user@example.com");
|
||||||
assertThat(rbacUserRepository.findByUuid(newUserUuid))
|
assertThat(rbacUserRepository.findByUuid(newUserUuid))
|
||||||
.extracting(RbacUserEntity::getName).isEqualTo("new-user@example.com");
|
.extracting(RbacUserEntity::getName).isEqualTo("new-user@example.com");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,8 @@ class RbacUserRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
@Autowired
|
@Autowired
|
||||||
JpaAttempt jpaAttempt;
|
JpaAttempt jpaAttempt;
|
||||||
|
|
||||||
@Autowired EntityManager em;
|
@Autowired
|
||||||
|
EntityManager em;
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
class CreateUser {
|
class CreateUser {
|
||||||
@ -45,7 +46,7 @@ class RbacUserRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
|
|
||||||
// when
|
// when
|
||||||
final var result = rbacUserRepository.create(
|
final var result = rbacUserRepository.create(
|
||||||
new RbacUserEntity(null, givenNewUserName));
|
new RbacUserEntity(null, givenNewUserName));
|
||||||
|
|
||||||
// then the persisted user is returned
|
// then the persisted user is returned
|
||||||
assertThat(result).isNotNull().extracting(RbacUserEntity::getName).isEqualTo(givenNewUserName);
|
assertThat(result).isNotNull().extracting(RbacUserEntity::getName).isEqualTo(givenNewUserName);
|
||||||
@ -53,7 +54,7 @@ class RbacUserRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
// and the new user entity can be fetched by the user itself
|
// and the new user entity can be fetched by the user itself
|
||||||
context(givenNewUserName);
|
context(givenNewUserName);
|
||||||
assertThat(em.find(RbacUserEntity.class, result.getUuid()))
|
assertThat(em.find(RbacUserEntity.class, result.getUuid()))
|
||||||
.isNotNull().extracting(RbacUserEntity::getName).isEqualTo(givenNewUserName);
|
.isNotNull().extracting(RbacUserEntity::getName).isEqualTo(givenNewUserName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -73,11 +74,11 @@ class RbacUserRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
// then:
|
// then:
|
||||||
assertThat(result.wasSuccessful()).isTrue();
|
assertThat(result.wasSuccessful()).isTrue();
|
||||||
assertThat(result.returnedValue()).isNotNull()
|
assertThat(result.returnedValue()).isNotNull()
|
||||||
.extracting(RbacUserEntity::getUuid).isEqualTo(givenUuid);
|
.extracting(RbacUserEntity::getUuid).isEqualTo(givenUuid);
|
||||||
jpaAttempt.transacted(() -> {
|
jpaAttempt.transacted(() -> {
|
||||||
context(newUserName);
|
context(newUserName);
|
||||||
assertThat(em.find(RbacUserEntity.class, givenUuid))
|
assertThat(em.find(RbacUserEntity.class, givenUuid))
|
||||||
.isNotNull().extracting(RbacUserEntity::getName).isEqualTo(newUserName);
|
.isNotNull().extracting(RbacUserEntity::getName).isEqualTo(newUserName);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -86,7 +87,7 @@ class RbacUserRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
class FindByOptionalNameLike {
|
class FindByOptionalNameLike {
|
||||||
|
|
||||||
private static final String[] ALL_TEST_DATA_USERS = Array.of(
|
private static final String[] ALL_TEST_DATA_USERS = Array.of(
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
"mike@hostsharing.net", "sven@hostsharing.net",
|
"mike@hostsharing.net", "sven@hostsharing.net",
|
||||||
"customer-admin@xxx.example.com",
|
"customer-admin@xxx.example.com",
|
||||||
"pac-admin-xxx00@xxx.example.com", "pac-admin-xxx01@xxx.example.com", "pac-admin-xxx02@xxx.example.com",
|
"pac-admin-xxx00@xxx.example.com", "pac-admin-xxx01@xxx.example.com", "pac-admin-xxx02@xxx.example.com",
|
||||||
@ -106,7 +107,7 @@ class RbacUserRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
final var result = rbacUserRepository.findByOptionalNameLike(null);
|
final var result = rbacUserRepository.findByOptionalNameLike(null);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
exactlyTheseRbacUsersAreReturned(result, ALL_TEST_DATA_USERS);
|
allTheseRbacUsersAreReturned(result, ALL_TEST_DATA_USERS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -118,7 +119,7 @@ class RbacUserRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
final var result = rbacUserRepository.findByOptionalNameLike(null);
|
final var result = rbacUserRepository.findByOptionalNameLike(null);
|
||||||
|
|
||||||
then:
|
then:
|
||||||
exactlyTheseRbacUsersAreReturned(result, ALL_TEST_DATA_USERS);
|
allTheseRbacUsersAreReturned(result, ALL_TEST_DATA_USERS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -131,9 +132,9 @@ class RbacUserRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
|
|
||||||
then:
|
then:
|
||||||
exactlyTheseRbacUsersAreReturned(
|
exactlyTheseRbacUsersAreReturned(
|
||||||
result,
|
result,
|
||||||
"customer-admin@xxx.example.com",
|
"customer-admin@xxx.example.com",
|
||||||
"pac-admin-xxx00@xxx.example.com", "pac-admin-xxx01@xxx.example.com", "pac-admin-xxx02@xxx.example.com"
|
"pac-admin-xxx00@xxx.example.com", "pac-admin-xxx01@xxx.example.com", "pac-admin-xxx02@xxx.example.com"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,9 +148,9 @@ class RbacUserRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
|
|
||||||
// then:
|
// then:
|
||||||
exactlyTheseRbacUsersAreReturned(
|
exactlyTheseRbacUsersAreReturned(
|
||||||
result,
|
result,
|
||||||
"customer-admin@xxx.example.com",
|
"customer-admin@xxx.example.com",
|
||||||
"pac-admin-xxx00@xxx.example.com", "pac-admin-xxx01@xxx.example.com", "pac-admin-xxx02@xxx.example.com"
|
"pac-admin-xxx00@xxx.example.com", "pac-admin-xxx01@xxx.example.com", "pac-admin-xxx02@xxx.example.com"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,7 +178,7 @@ class RbacUserRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
class ListUserPermissions {
|
class ListUserPermissions {
|
||||||
|
|
||||||
private static final String[] ALL_USER_PERMISSIONS = Array.of(
|
private static final String[] ALL_USER_PERMISSIONS = Array.of(
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
"global#hostsharing.admin -> global#hostsharing: add-customer",
|
"global#hostsharing.admin -> global#hostsharing: add-customer",
|
||||||
|
|
||||||
"customer#xxx.admin -> customer#xxx: add-package",
|
"customer#xxx.admin -> customer#xxx: add-package",
|
||||||
@ -243,13 +244,13 @@ class RbacUserRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
|
|
||||||
// when
|
// when
|
||||||
final var result = attempt(em, () ->
|
final var result = attempt(em, () ->
|
||||||
rbacUserRepository.findPermissionsOfUser("mike@hostsharing.net")
|
rbacUserRepository.findPermissionsOfUser("mike@hostsharing.net")
|
||||||
);
|
);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
result.assertExceptionWithRootCauseMessage(
|
result.assertExceptionWithRootCauseMessage(
|
||||||
JpaSystemException.class,
|
JpaSystemException.class,
|
||||||
"[400] grantedPermissions(...) does not support assumed roles");
|
"[400] grantedPermissions(...) does not support assumed roles");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -262,8 +263,8 @@ class RbacUserRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
|
|
||||||
// then
|
// then
|
||||||
allTheseRbacPermissionsAreReturned(
|
allTheseRbacPermissionsAreReturned(
|
||||||
result,
|
result,
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
"customer#xxx.admin -> customer#xxx: add-package",
|
"customer#xxx.admin -> customer#xxx: add-package",
|
||||||
"customer#xxx.admin -> customer#xxx: view",
|
"customer#xxx.admin -> customer#xxx: view",
|
||||||
"customer#xxx.tenant -> customer#xxx: view",
|
"customer#xxx.tenant -> customer#xxx: view",
|
||||||
@ -285,8 +286,8 @@ class RbacUserRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
// @formatter:on
|
// @formatter:on
|
||||||
);
|
);
|
||||||
noneOfTheseRbacPermissionsAreReturned(
|
noneOfTheseRbacPermissionsAreReturned(
|
||||||
result,
|
result,
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
"customer#yyy.admin -> customer#yyy: add-package",
|
"customer#yyy.admin -> customer#yyy: add-package",
|
||||||
"customer#yyy.admin -> customer#yyy: view",
|
"customer#yyy.admin -> customer#yyy: view",
|
||||||
"customer#yyy.tenant -> customer#yyy: view"
|
"customer#yyy.tenant -> customer#yyy: view"
|
||||||
@ -301,13 +302,13 @@ class RbacUserRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
|
|
||||||
// when
|
// when
|
||||||
final var result = attempt(em, () ->
|
final var result = attempt(em, () ->
|
||||||
rbacUserRepository.findPermissionsOfUser("mike@hostsharing.net")
|
rbacUserRepository.findPermissionsOfUser("mike@hostsharing.net")
|
||||||
);
|
);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
result.assertExceptionWithRootCauseMessage(
|
result.assertExceptionWithRootCauseMessage(
|
||||||
JpaSystemException.class,
|
JpaSystemException.class,
|
||||||
"[403] permissions of user \"mike@hostsharing.net\" are not accessible to user \"customer-admin@xxx.example.com\"");
|
"[403] permissions of user \"mike@hostsharing.net\" are not accessible to user \"customer-admin@xxx.example.com\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -320,8 +321,8 @@ class RbacUserRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
|
|
||||||
// then
|
// then
|
||||||
allTheseRbacPermissionsAreReturned(
|
allTheseRbacPermissionsAreReturned(
|
||||||
result,
|
result,
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
"customer#xxx.tenant -> customer#xxx: view",
|
"customer#xxx.tenant -> customer#xxx: view",
|
||||||
// "customer#xxx.admin -> customer#xxx: view" - Not permissions through the customer admin!
|
// "customer#xxx.admin -> customer#xxx: view" - Not permissions through the customer admin!
|
||||||
"package#xxx00.admin -> package#xxx00: add-unixuser",
|
"package#xxx00.admin -> package#xxx00: add-unixuser",
|
||||||
@ -332,8 +333,8 @@ class RbacUserRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
// @formatter:on
|
// @formatter:on
|
||||||
);
|
);
|
||||||
noneOfTheseRbacPermissionsAreReturned(
|
noneOfTheseRbacPermissionsAreReturned(
|
||||||
result,
|
result,
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
"customer#yyy.admin -> customer#yyy: add-package",
|
"customer#yyy.admin -> customer#yyy: add-package",
|
||||||
"customer#yyy.admin -> customer#yyy: view",
|
"customer#yyy.admin -> customer#yyy: view",
|
||||||
"customer#yyy.tenant -> customer#yyy: view",
|
"customer#yyy.tenant -> customer#yyy: view",
|
||||||
@ -368,8 +369,8 @@ class RbacUserRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
|
|
||||||
// then
|
// then
|
||||||
allTheseRbacPermissionsAreReturned(
|
allTheseRbacPermissionsAreReturned(
|
||||||
result,
|
result,
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
"customer#xxx.tenant -> customer#xxx: view",
|
"customer#xxx.tenant -> customer#xxx: view",
|
||||||
// "customer#xxx.admin -> customer#xxx: view" - Not permissions through the customer admin!
|
// "customer#xxx.admin -> customer#xxx: view" - Not permissions through the customer admin!
|
||||||
"package#xxx00.admin -> package#xxx00: add-unixuser",
|
"package#xxx00.admin -> package#xxx00: add-unixuser",
|
||||||
@ -378,8 +379,8 @@ class RbacUserRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
// @formatter:on
|
// @formatter:on
|
||||||
);
|
);
|
||||||
noneOfTheseRbacPermissionsAreReturned(
|
noneOfTheseRbacPermissionsAreReturned(
|
||||||
result,
|
result,
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
// no customer admin permissions
|
// no customer admin permissions
|
||||||
"customer#xxx.admin -> customer#xxx: add-package",
|
"customer#xxx.admin -> customer#xxx: add-package",
|
||||||
// no permissions on other customer's objects
|
// no permissions on other customer's objects
|
||||||
@ -398,40 +399,47 @@ class RbacUserRepositoryIntegrationTest extends ContextBasedTest {
|
|||||||
|
|
||||||
void exactlyTheseRbacUsersAreReturned(final List<RbacUserEntity> actualResult, final String... expectedUserNames) {
|
void exactlyTheseRbacUsersAreReturned(final List<RbacUserEntity> actualResult, final String... expectedUserNames) {
|
||||||
assertThat(actualResult)
|
assertThat(actualResult)
|
||||||
.filteredOn(u -> !u.getName().startsWith("test-user-"))
|
.extracting(RbacUserEntity::getName)
|
||||||
.extracting(RbacUserEntity::getName)
|
.filteredOn(n -> !n.startsWith("test-user"))
|
||||||
.containsExactlyInAnyOrder(expectedUserNames);
|
.containsExactlyInAnyOrder(expectedUserNames);
|
||||||
|
}
|
||||||
|
|
||||||
|
void allTheseRbacUsersAreReturned(final List<RbacUserEntity> actualResult, final String... expectedUserNames) {
|
||||||
|
assertThat(actualResult)
|
||||||
|
.extracting(RbacUserEntity::getName)
|
||||||
|
.filteredOn(n -> !n.startsWith("test-user"))
|
||||||
|
.contains(expectedUserNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
void noRbacPermissionsAreReturned(
|
void noRbacPermissionsAreReturned(
|
||||||
final List<RbacUserPermission> actualResult) {
|
final List<RbacUserPermission> actualResult) {
|
||||||
assertThat(actualResult)
|
assertThat(actualResult)
|
||||||
.extracting(p -> p.getRoleName() + " -> " + p.getObjectTable() + "#" + p.getObjectIdName() + ": " + p.getOp())
|
.extracting(p -> p.getRoleName() + " -> " + p.getObjectTable() + "#" + p.getObjectIdName() + ": " + p.getOp())
|
||||||
.containsExactlyInAnyOrder();
|
.containsExactlyInAnyOrder();
|
||||||
}
|
}
|
||||||
|
|
||||||
void exactlyTheseRbacPermissionsAreReturned(
|
void exactlyTheseRbacPermissionsAreReturned(
|
||||||
final List<RbacUserPermission> actualResult,
|
final List<RbacUserPermission> actualResult,
|
||||||
final String... expectedRoleNames) {
|
final String... expectedRoleNames) {
|
||||||
assertThat(actualResult)
|
assertThat(actualResult)
|
||||||
.extracting(p -> p.getRoleName() + " -> " + p.getObjectTable() + "#" + p.getObjectIdName() + ": " + p.getOp())
|
.extracting(p -> p.getRoleName() + " -> " + p.getObjectTable() + "#" + p.getObjectIdName() + ": " + p.getOp())
|
||||||
.containsExactlyInAnyOrder(expectedRoleNames);
|
.containsExactlyInAnyOrder(expectedRoleNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
void allTheseRbacPermissionsAreReturned(
|
void allTheseRbacPermissionsAreReturned(
|
||||||
final List<RbacUserPermission> actualResult,
|
final List<RbacUserPermission> actualResult,
|
||||||
final String... expectedRoleNames) {
|
final String... expectedRoleNames) {
|
||||||
assertThat(actualResult)
|
assertThat(actualResult)
|
||||||
.extracting(p -> p.getRoleName() + " -> " + p.getObjectTable() + "#" + p.getObjectIdName() + ": " + p.getOp())
|
.extracting(p -> p.getRoleName() + " -> " + p.getObjectTable() + "#" + p.getObjectIdName() + ": " + p.getOp())
|
||||||
.contains(expectedRoleNames);
|
.contains(expectedRoleNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
void noneOfTheseRbacPermissionsAreReturned(
|
void noneOfTheseRbacPermissionsAreReturned(
|
||||||
final List<RbacUserPermission> actualResult,
|
final List<RbacUserPermission> actualResult,
|
||||||
final String... unexpectedRoleNames) {
|
final String... unexpectedRoleNames) {
|
||||||
assertThat(actualResult)
|
assertThat(actualResult)
|
||||||
.extracting(p -> p.getRoleName() + " -> " + p.getObjectTable() + "#" + p.getObjectIdName() + ": " + p.getOp())
|
.extracting(p -> p.getRoleName() + " -> " + p.getObjectTable() + "#" + p.getObjectIdName() + ": " + p.getOp())
|
||||||
.doesNotContain(unexpectedRoleNames);
|
.doesNotContain(unexpectedRoleNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user