Tighten user linking
This commit is contained in:
@@ -52,6 +52,8 @@ public class CustomerService {
|
|||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
public CustomerResponse createCustomer(CustomerRequest request) {
|
public CustomerResponse createCustomer(CustomerRequest request) {
|
||||||
|
ensureEmailAvailable(request.getEmail(), null);
|
||||||
|
|
||||||
Customer customer = new Customer();
|
Customer customer = new Customer();
|
||||||
customer.setFirstName(request.getFirstName());
|
customer.setFirstName(request.getFirstName());
|
||||||
customer.setLastName(request.getLastName());
|
customer.setLastName(request.getLastName());
|
||||||
@@ -78,6 +80,8 @@ public class CustomerService {
|
|||||||
Customer customer = customerRepository.findById(id)
|
Customer customer = customerRepository.findById(id)
|
||||||
.orElseThrow(() -> new ResourceNotFoundException("Customer not found with id: " + id));
|
.orElseThrow(() -> new ResourceNotFoundException("Customer not found with id: " + id));
|
||||||
|
|
||||||
|
ensureEmailAvailable(request.getEmail(), customer.getUserId());
|
||||||
|
|
||||||
customer.setFirstName(request.getFirstName());
|
customer.setFirstName(request.getFirstName());
|
||||||
customer.setLastName(request.getLastName());
|
customer.setLastName(request.getLastName());
|
||||||
customer.setEmail(request.getEmail());
|
customer.setEmail(request.getEmail());
|
||||||
@@ -142,4 +146,16 @@ public class CustomerService {
|
|||||||
private String generatePhone(Customer customer) {
|
private String generatePhone(Customer customer) {
|
||||||
return String.format("200-000-%04d", customer.getCustomerId());
|
return String.format("200-000-%04d", customer.getCustomerId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ensureEmailAvailable(String email, Long currentUserId) {
|
||||||
|
if (email == null || email.isBlank()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
userRepository.findByEmail(email).ifPresent(existing -> {
|
||||||
|
if (currentUserId == null || !existing.getId().equals(currentUserId)) {
|
||||||
|
throw new ResponseStatusException(CONFLICT, "Email already exists");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,10 @@ INSERT INTO users (username, password, email, fullName, phone, role, active, tok
|
|||||||
SELECT
|
SELECT
|
||||||
CONCAT('customer_', c.customerId) AS username,
|
CONCAT('customer_', c.customerId) AS username,
|
||||||
'$2a$10$mE0D/HrnCuqFeEqMy0NJwuy2jkoRYjQ7GrKcc/7QQ0r2AqnZTvyGq' AS password,
|
'$2a$10$mE0D/HrnCuqFeEqMy0NJwuy2jkoRYjQ7GrKcc/7QQ0r2AqnZTvyGq' AS password,
|
||||||
c.email,
|
CASE
|
||||||
|
WHEN EXISTS (SELECT 1 FROM users u WHERE u.email = c.email) THEN CONCAT('customer_', c.customerId, '@petshop.local')
|
||||||
|
ELSE c.email
|
||||||
|
END AS email,
|
||||||
CONCAT(c.firstName, ' ', c.lastName) AS fullName,
|
CONCAT(c.firstName, ' ', c.lastName) AS fullName,
|
||||||
CONCAT('200-000-', LPAD(c.customerId, 4, '0')) AS phone,
|
CONCAT('200-000-', LPAD(c.customerId, 4, '0')) AS phone,
|
||||||
'CUSTOMER' AS role,
|
'CUSTOMER' AS role,
|
||||||
@@ -14,14 +17,16 @@ WHERE c.user_id IS NULL
|
|||||||
SELECT 1
|
SELECT 1
|
||||||
FROM users u
|
FROM users u
|
||||||
WHERE u.username = CONCAT('customer_', c.customerId)
|
WHERE u.username = CONCAT('customer_', c.customerId)
|
||||||
OR u.email = c.email
|
|
||||||
);
|
);
|
||||||
|
|
||||||
INSERT INTO users (username, password, email, fullName, phone, role, active, tokenVersion)
|
INSERT INTO users (username, password, email, fullName, phone, role, active, tokenVersion)
|
||||||
SELECT
|
SELECT
|
||||||
CONCAT('employee_', e.employeeId) AS username,
|
CONCAT('employee_', e.employeeId) AS username,
|
||||||
'$2a$10$mE0D/HrnCuqFeEqMy0NJwuy2jkoRYjQ7GrKcc/7QQ0r2AqnZTvyGq' AS password,
|
'$2a$10$mE0D/HrnCuqFeEqMy0NJwuy2jkoRYjQ7GrKcc/7QQ0r2AqnZTvyGq' AS password,
|
||||||
e.email,
|
CASE
|
||||||
|
WHEN EXISTS (SELECT 1 FROM users u WHERE u.email = e.email) THEN CONCAT('employee_', e.employeeId, '@petshop.local')
|
||||||
|
ELSE e.email
|
||||||
|
END AS email,
|
||||||
CONCAT(e.firstName, ' ', e.lastName) AS fullName,
|
CONCAT(e.firstName, ' ', e.lastName) AS fullName,
|
||||||
CONCAT('300-000-', LPAD(e.employeeId, 4, '0')) AS phone,
|
CONCAT('300-000-', LPAD(e.employeeId, 4, '0')) AS phone,
|
||||||
CASE
|
CASE
|
||||||
@@ -36,7 +41,6 @@ WHERE e.user_id IS NULL
|
|||||||
SELECT 1
|
SELECT 1
|
||||||
FROM users u
|
FROM users u
|
||||||
WHERE u.username = CONCAT('employee_', e.employeeId)
|
WHERE u.username = CONCAT('employee_', e.employeeId)
|
||||||
OR u.email = e.email
|
|
||||||
);
|
);
|
||||||
|
|
||||||
UPDATE customer c
|
UPDATE customer c
|
||||||
|
|||||||
@@ -98,9 +98,52 @@ class CustomerServiceTest {
|
|||||||
existing.setEmail("pat@example.com");
|
existing.setEmail("pat@example.com");
|
||||||
existing.setRole(User.Role.STAFF);
|
existing.setRole(User.Role.STAFF);
|
||||||
|
|
||||||
when(customerRepository.save(any(Customer.class))).thenAnswer(invocation -> invocation.getArgument(0));
|
|
||||||
when(userRepository.findByEmail("pat@example.com")).thenReturn(Optional.of(existing));
|
when(userRepository.findByEmail("pat@example.com")).thenReturn(Optional.of(existing));
|
||||||
|
|
||||||
assertThrows(ResponseStatusException.class, () -> customerService.createCustomer(request));
|
assertThrows(ResponseStatusException.class, () -> customerService.createCustomer(request));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void createCustomerRejectsExistingCustomerEmail() {
|
||||||
|
CustomerRequest request = new CustomerRequest();
|
||||||
|
request.setFirstName("Pat");
|
||||||
|
request.setLastName("Owner");
|
||||||
|
request.setEmail("pat@example.com");
|
||||||
|
|
||||||
|
User existing = new User();
|
||||||
|
existing.setId(22L);
|
||||||
|
existing.setUsername("customer1");
|
||||||
|
existing.setEmail("pat@example.com");
|
||||||
|
existing.setRole(User.Role.CUSTOMER);
|
||||||
|
|
||||||
|
when(userRepository.findByEmail("pat@example.com")).thenReturn(Optional.of(existing));
|
||||||
|
|
||||||
|
assertThrows(ResponseStatusException.class, () -> customerService.createCustomer(request));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void updateCustomerRejectsExistingEmailFromOtherUser() {
|
||||||
|
Customer customer = new Customer();
|
||||||
|
customer.setCustomerId(7L);
|
||||||
|
customer.setUserId(11L);
|
||||||
|
customer.setFirstName("Pat");
|
||||||
|
customer.setLastName("Owner");
|
||||||
|
customer.setEmail("old@example.com");
|
||||||
|
|
||||||
|
CustomerRequest request = new CustomerRequest();
|
||||||
|
request.setFirstName("Pat");
|
||||||
|
request.setLastName("Owner");
|
||||||
|
request.setEmail("pat@example.com");
|
||||||
|
|
||||||
|
User existing = new User();
|
||||||
|
existing.setId(22L);
|
||||||
|
existing.setUsername("customer2");
|
||||||
|
existing.setEmail("pat@example.com");
|
||||||
|
existing.setRole(User.Role.CUSTOMER);
|
||||||
|
|
||||||
|
when(customerRepository.findById(7L)).thenReturn(Optional.of(customer));
|
||||||
|
when(userRepository.findByEmail("pat@example.com")).thenReturn(Optional.of(existing));
|
||||||
|
|
||||||
|
assertThrows(ResponseStatusException.class, () -> customerService.updateCustomer(7L, request));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user