Skip to content

Commit

Permalink
#803 | Enforce valid registration address level in external subject w…
Browse files Browse the repository at this point in the history
…rite APIs
  • Loading branch information
1t5j0y committed Oct 31, 2024
1 parent ca659a0 commit 40a0848
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -160,15 +160,11 @@ public Optional<AddressLevel> findByAddressMap(Map<String, String> addressMap) {

if (addressLevels.size() != addressMap.size()) return Optional.empty();

String typeHierarchyForAddressMap = addressLevels.stream().map(al -> String.valueOf(al.getTypeId())).collect(Collectors.joining("."));
String lineageForAddressMap = addressLevels.stream().map(al -> String.valueOf(al.getId())).collect(Collectors.joining("."));

TreeSet<String> addressLevelTypeHierarchies = locationHierarchyService.fetchAndFilterHierarchies();
if (addressLevelTypeHierarchies.stream().anyMatch(hierarchy -> hierarchy.equals(typeHierarchyForAddressMap))) {
AddressLevel matchedAddressLevel = addressLevels.get(addressLevels.size() - 1);
if (matchedAddressLevel.getLineage().equals(lineageForAddressMap)) {
return Optional.of(matchedAddressLevel);
}
AddressLevel matchedAddressLevel = addressLevels.get(addressLevels.size() - 1);
if (matchedAddressLevel.getLineage().equals(lineageForAddressMap)) {
return Optional.of(matchedAddressLevel);
}
return Optional.empty();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ public class SubjectApiController {
private final AddressLevelService addressLevelService;
private final String V3_REQUIRES_ADDRESS_MAP = String.format("version 3 and above requires '%s' instead of '%s'", ADDRESS_MAP, ADDRESS);
private final String ADDRESS_MAP_NO_RESULTS = String.format("Address corresponding to '%s' not found", ADDRESS_MAP);
private final String INVALID_ADDRESS_TYPE_FOR_SUBJECT_TYPE = "Address '%s' of type '%s' is not valid for subject type '%s'";
private final SubjectTypeService subjectTypeService;


@Autowired
Expand All @@ -60,7 +62,7 @@ public SubjectApiController(ConceptService conceptService, IndividualRepository
LocationService locationService, SubjectTypeRepository subjectTypeRepository,
LocationRepository locationRepository, GenderRepository genderRepository,
SubjectMigrationService subjectMigrationService, IndividualService individualService,
S3Service s3Service, MediaObservationService mediaObservationService, AccessControlService accessControlService, AddressLevelService addressLevelService) {
S3Service s3Service, MediaObservationService mediaObservationService, AccessControlService accessControlService, AddressLevelService addressLevelService, SubjectTypeService subjectTypeService) {
this.conceptService = conceptService;
this.individualRepository = individualRepository;
this.conceptRepository = conceptRepository;
Expand All @@ -75,6 +77,7 @@ public SubjectApiController(ConceptService conceptService, IndividualRepository
this.mediaObservationService = mediaObservationService;
this.accessControlService = accessControlService;
this.addressLevelService = addressLevelService;
this.subjectTypeService = subjectTypeService;
}

@RequestMapping(value = "/api/subjects", method = RequestMethod.GET)
Expand Down Expand Up @@ -213,9 +216,17 @@ private void updateSubjectDetails(Individual subject, ApiSubjectRequest request)
throw new IllegalArgumentException(V3_REQUIRES_ADDRESS_MAP);
}
Optional<AddressLevel> addressLevel = versionGreaterThan2 ? addressLevelService.findByAddressMap(request.getAddressMap()) : locationRepository.findByTitleLineageIgnoreCase(request.getAddress());
if (!addressLevel.isPresent() && !subjectType.isAllowEmptyLocation()) {
throw new IllegalArgumentException(versionGreaterThan2 ? ADDRESS_MAP_NO_RESULTS : String.format("Address '%s' not found", request.getAddress()));
if (!addressLevel.isPresent()) {
if (!subjectType.isAllowEmptyLocation()) {
throw new IllegalArgumentException(versionGreaterThan2 ? ADDRESS_MAP_NO_RESULTS : String.format("Address '%s' not found", request.getAddress()));
}
} else {
AddressLevel address = addressLevel.get();
if (!subjectTypeService.getRegistrableLocationTypes(subjectType).contains(address.getType())) {
throw new IllegalArgumentException(String.format(INVALID_ADDRESS_TYPE_FOR_SUBJECT_TYPE, versionGreaterThan2 ? request.getAddressMap() : request.getAddress(), address.getType().getName(), subjectType.getName()));
}
}

setExternalId(subject, request.getExternalId());
subject.setFirstName(request.getFirstName());
setMiddleName(subject, subjectType, request.getMiddleName());
Expand Down Expand Up @@ -298,7 +309,8 @@ private void patchSubject(Individual subject, Map<String, Object> request) throw
if (request.containsKey(ADDRESS) || request.containsKey(ADDRESS_MAP)) {
Optional<AddressLevel> addressLevel;
AddressLevel newAddressLevel;
if (ApiRequestContextHolder.isVersionGreaterThan(2)) {
boolean versionGreaterThan2 = ApiRequestContextHolder.isVersionGreaterThan(2);
if (versionGreaterThan2) {
if (!request.containsKey(ADDRESS_MAP)) {
throw new IllegalArgumentException(String.format("version 3 and above requires '%s' instead of '%s'", ADDRESS_MAP, ADDRESS));
}
Expand All @@ -311,6 +323,10 @@ private void patchSubject(Individual subject, Map<String, Object> request) throw
newAddressLevel = addressLevel.orElseThrow(() -> new IllegalArgumentException(String.format("Address '%s' not found", locationTitleLineage)));
}

if (!subjectTypeService.getRegistrableLocationTypes(subjectType).contains(newAddressLevel.getType())) {
throw new IllegalArgumentException(String.format(INVALID_ADDRESS_TYPE_FOR_SUBJECT_TYPE, versionGreaterThan2 ? request.get(ADDRESS_MAP) : request.get(ADDRESS), newAddressLevel.getType().getName(), subjectType.getName()));
}

subject.setAddressLevel(newAddressLevel);
subjectMigrationService.markSubjectMigrationIfRequired(subject.getUuid(), null, newAddressLevel, null, subject.getObservations(), false);
}
Expand Down

0 comments on commit 40a0848

Please sign in to comment.