InventoryItemSecurityValidator.java
package com.smartsupplypro.inventory.validation;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.web.server.ResponseStatusException;
import com.smartsupplypro.inventory.dto.InventoryItemDTO;
import com.smartsupplypro.inventory.model.InventoryItem;
/**
* Security validator for role-based inventory item update restrictions.
*
* <p><strong>Access Control</strong>:
* <ul>
* <li><strong>ADMIN</strong>: Full update permissions (name, supplier, quantity, price)</li>
* <li><strong>USER</strong>: Restricted to quantity and price updates only</li>
* </ul>
*
* <p><strong>Design</strong>:
* Validates field-level permissions before service layer commits changes.
* Throws HTTP 403 for unauthorized field modifications.
*
* @see InventoryItemService
* @see <a href="file:../../../../../../docs/architecture/patterns/validation-patterns.md">Validation Patterns</a>
*/
public class InventoryItemSecurityValidator {
/**
* Validates user has permission to update specific inventory item fields.
* USER role: only quantity and price changes allowed.
* ADMIN role: full update permissions.
*
* @param existing current inventory item entity
* @param incoming updated item DTO from request
* @throws ResponseStatusException 401 if not authenticated, 403 if unauthorized field change
*/
public static void validateUpdatePermissions(InventoryItem existing, InventoryItemDTO incoming) {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth == null || !(auth.getPrincipal() instanceof OAuth2User)) {
throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, "Unauthorized access");
}
OAuth2User user = (OAuth2User) auth.getPrincipal();
String role = user.getAuthorities().stream()
.map(a -> a.getAuthority())
.filter(r -> r.equals("ROLE_ADMIN") || r.equals("ROLE_USER"))
.findFirst()
.orElse("ROLE_USER"); // Default to USER if not explicitly found
if (role.equals("ROLE_USER")) {
boolean nameChanged = !existing.getName().equals(incoming.getName());
boolean supplierChanged = !existing.getSupplierId().equals(incoming.getSupplierId());
if (nameChanged || supplierChanged) {
throw new ResponseStatusException(
HttpStatus.FORBIDDEN,
"Users are only allowed to change quantity or price."
);
}
}
}
}
// This code provides the InventoryItemSecurityValidator class, which enforces security constraints on inventory item updates based on user roles.