Skip to content

Commit

Permalink
Merge pull request #106 from usnistgov/feature/email-country-blacklis…
Browse files Browse the repository at this point in the history
…ts-v2

Add Email and Country Blacklisting (server-side handling)
  • Loading branch information
RayPlante authored Mar 12, 2024
2 parents e125b00 + 60f6c41 commit e707e18
Show file tree
Hide file tree
Showing 6 changed files with 248 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
Expand Down Expand Up @@ -69,6 +72,7 @@ public class HttpURLConnectionRPARequestHandlerService implements RPARequestHand
private final static String RECORD_PENDING_STATUS = "pending";
private final static String RECORD_APPROVED_STATUS = "approved";
private final static String RECORD_DECLINED_STATUS = "declined";
private final static String RECORD_REJECTED_STATUS = "rejected";

/**
* The RPA configuration.
Expand Down Expand Up @@ -273,6 +277,37 @@ public RecordWrapper getRecord(String recordId) throws RecordNotFoundException,
public RecordWrapper createRecord(UserInfoWrapper userInfoWrapper) throws InvalidRequestException,
RequestProcessingException {
int responseCode;

// Validate the email and country against the blacklists before proceeding
String email = userInfoWrapper.getUserInfo().getEmail();
String country = userInfoWrapper.getUserInfo().getCountry();
String rejectionReason = "";

// Log user info
LOGGER.debug("User's email: " + email);
LOGGER.debug("User's country: " + country);

// Check for blacklisted email and country
if (isEmailBlacklisted(email)) {
rejectionReason = "Email " + email + " is blacklisted.";
LOGGER.warn("Email {} is blacklisted. Request to create record will be automatically rejected.", email);
} else if (isCountryBlacklisted(country)) {
rejectionReason = "Country " + country + " is blacklisted.";
LOGGER.warn("Country {} is blacklisted. Request to create record will be automatically rejected.", country);
}

// Set the pending status of the record in this service, and not based on the user's input
userInfoWrapper.getUserInfo().setApprovalStatus(RECORD_PENDING_STATUS);

if (!rejectionReason.isEmpty()) {
// Append the rejection reason to the existing description
String currentDescription = userInfoWrapper.getUserInfo().getDescription();
String updatedDescription = currentDescription + "\nThis record was automatically rejected. Reason: " + rejectionReason;
userInfoWrapper.getUserInfo().setDescription(updatedDescription);
// Set approval status to rejected
userInfoWrapper.getUserInfo().setApprovalStatus(RECORD_REJECTED_STATUS);
}

// Initialize return value
RecordWrapper newRecordWrapper;

Expand All @@ -294,9 +329,6 @@ public RecordWrapper createRecord(UserInfoWrapper userInfoWrapper) throws Invali
}
LOGGER.debug("CREATE_RECORD_URL=" + url);

// Set the pending status of the record in this service, and not based on the user's input
userInfoWrapper.getUserInfo().setApprovalStatus(RECORD_PENDING_STATUS);

String postPayload;
try {
postPayload = prepareRequestPayload(userInfoWrapper);
Expand Down Expand Up @@ -360,16 +392,42 @@ public RecordWrapper createRecord(UserInfoWrapper userInfoWrapper) throws Invali

// Check if success and handle accordingly
if (newRecordWrapper != null) {
this.recordResponseHandler.onRecordCreationSuccess(newRecordWrapper.getRecord());
// Check if the record is marked as rejected before proceeding
if (!RECORD_REJECTED_STATUS.equals(newRecordWrapper.getRecord().getUserInfo().getApprovalStatus())) {
// If the record is not marked as rejected, proceed with the normal success handling,
// including sending emails for SME approval and to the requester.
this.recordResponseHandler.onRecordCreationSuccess(newRecordWrapper.getRecord());
} else {
// Since the record is automatically rejected, we skip sending approval and notification emails.
LOGGER.info("Record automatically rejected due to blacklist. Skipping email notifications.");
}
} else {
// we expect a record to be created every time we call createRecord
// if newRecordWrapped is null, it means creation failed
// if newRecordWrapper is null, it means creation failed
this.recordResponseHandler.onRecordCreationFailure(responseCode);
}


return newRecordWrapper;
}

private boolean isEmailBlacklisted(String email) {
List<String> disallowedEmailStrings = rpaConfiguration.getDisallowedEmails();
for (String patternString : disallowedEmailStrings) {
Pattern pattern = Pattern.compile(patternString);
Matcher matcher = pattern.matcher(email);
if (matcher.find()) {
return true;
}
}
return false;
}

private boolean isCountryBlacklisted(String country) {
List<String> disallowedCountries = rpaConfiguration.getDisallowedCountries();
return disallowedCountries.contains(country);
}

private String prepareRequestPayload(UserInfoWrapper userInfoWrapper) throws JsonProcessingException {
// Set reCAPTCHA field to null, so it doesn't get serialized. SF service doesn't expect this field
userInfoWrapper.setRecaptcha(null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@
import gov.nist.oar.distrib.service.DefaultPreservationBagService;
import gov.nist.oar.distrib.service.FileDownloadService;
import gov.nist.oar.distrib.service.PreservationBagService;
import gov.nist.oar.distrib.service.RPACachingService;
import gov.nist.oar.distrib.service.rpa.JKSKeyRetriever;
import gov.nist.oar.distrib.service.rpa.KeyRetriever;
import gov.nist.oar.distrib.storage.AWSS3LongTermStorage;
import gov.nist.oar.distrib.storage.FilesystemLongTermStorage;
import io.swagger.v3.oas.models.Components;
Expand Down
21 changes: 21 additions & 0 deletions src/main/java/gov/nist/oar/distrib/web/RPAConfiguration.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package gov.nist.oar.distrib.web;

import com.fasterxml.jackson.annotation.JsonAlias;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonProcessingException;
Expand Down Expand Up @@ -53,6 +54,10 @@ public class RPAConfiguration {
String bagStore = null;
@JsonProperty("bagstore-mode")
String mode = null;
@JsonProperty("disallowedEmails")
private List<String> disallowedEmails = new ArrayList<>();
@JsonProperty("disallowedCountries")
private List<String> disallowedCountries = new ArrayList<>();
@JsonProperty("expiresAfterMillis")
long expiresAfterMillis = 0L;

Expand Down Expand Up @@ -198,6 +203,22 @@ public void setJwtSecretKey(String jwtSecretKey) {
this.jwtSecretKey = jwtSecretKey;
}

public List<String> getDisallowedEmails() {
return disallowedEmails;
}

public void setDisallowedEmailStrings(List<String> disallowedEmails) {
this.disallowedEmails = disallowedEmails;
}

public List<String> getDisallowedCountries() {
return disallowedCountries;
}

public void setDisallowedCountries(List<String> disallowedCountries) {
this.disallowedCountries = disallowedCountries;
}

@NoArgsConstructor
public static class SalesforceJwt {
@JsonProperty("clientId")
Expand Down
Loading

0 comments on commit e707e18

Please sign in to comment.