Skip to content

Commit

Permalink
Added the whitelist for rate limiting
Browse files Browse the repository at this point in the history
  • Loading branch information
Camelia-Orcid committed Nov 5, 2024
1 parent 4f76902 commit 10b2f24
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
import java.io.IOException;
import java.io.PrintWriter;
import java.time.LocalDate;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

Expand All @@ -14,6 +16,7 @@
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.LocaleUtils;
import org.apache.commons.lang3.StringUtils;
import org.orcid.core.manager.ClientDetailsEntityCacheManager;
import org.orcid.core.manager.OrcidSecurityManager;
import org.orcid.core.manager.TemplateManager;
Expand Down Expand Up @@ -88,6 +91,18 @@ public class ApiRateLimitFilter extends OncePerRequestFilter {

@Value("${org.orcid.persistence.panoply.papiExceededRate.production:false}")
private boolean enablePanoplyPapiExceededRateInProduction;

@Value("${org.orcid.papi.rate.limit.ip.whiteSpaceSeparatedWhiteList:127.0.0.1}")
private static String papiWhiteSpaceSeparatedWhiteList;

private static List<String> papiIpWhiteList;

static {

if(StringUtils.isNotBlank(papiWhiteSpaceSeparatedWhiteList)) {
papiIpWhiteList = Arrays.asList(papiWhiteSpaceSeparatedWhiteList.split("\\s"));
}
}

private static final String TOO_MANY_REQUESTS_MSG = "Too Many Requests - You have exceeded the daily allowance of API calls.\\n"
+ "You can increase your daily quota by registering for and using Public API client credentials "
Expand All @@ -105,7 +120,7 @@ protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServl
if (httpServletRequest.getHeader("Authorization") != null) {
tokenValue = httpServletRequest.getHeader("Authorization").replaceAll("Bearer|bearer", "").trim();
}
String ipAddress = httpServletRequest.getRemoteAddr();
String ipAddress = getClientIpAddress(httpServletRequest);

String clientId = null;
if (tokenValue != null) {
Expand All @@ -118,9 +133,11 @@ protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServl
boolean isAnonymous = (clientId == null);
LocalDate today = LocalDate.now();

if (isAnonymous) {
LOG.info("ApiRateLimitFilter anonymous request");
this.rateLimitAnonymousRequest(ipAddress, today, httpServletResponse);
if (isAnonymous ) {
if(!isWhiteListed(ipAddress)) {
LOG.info("ApiRateLimitFilter anonymous request");
this.rateLimitAnonymousRequest(ipAddress, today, httpServletResponse);
}

} else {
LOG.info("ApiRateLimitFilter client request with clientId: " + clientId);
Expand Down Expand Up @@ -250,5 +267,28 @@ private void setPapiRateExceededItemInPanoply(PanoplyPapiDailyRateExceededItem i

});
}

//gets actual client IP address, using the headers that the proxy server ads
private String getClientIpAddress(HttpServletRequest request) {
String ipAddress = request.getHeader("X-FORWARDED-FOR");
if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getHeader("X-REAL-IP");
}
if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getRemoteAddr();
}
if (ipAddress != null && ipAddress.contains(",")) {
ipAddress = ipAddress.split(",")[0].trim();
}
return ipAddress;
}

private boolean isWhiteListed(String ipAddress) {
if(papiIpWhiteList != null) {
return papiIpWhiteList.contains(ipAddress);

}
return false;
}

}
40 changes: 22 additions & 18 deletions properties/development.properties
Original file line number Diff line number Diff line change
@@ -1,56 +1,56 @@
################
# DATABASE #
# DATABASE #
################

# Main database
# Main database
org.orcid.persistence.db.class=org.postgresql.Driver
org.orcid.persistence.db.dataSource=pooledDataSource
org.orcid.persistence.db.dialect=org.hibernate.dialect.PostgreSQLDialect
org.orcid.persistence.db.generateDdl=false
org.orcid.persistence.db.hibernateStatistics=true
org.orcid.persistence.db.idleConnectionTestPeriod=3600
org.orcid.persistence.db.initialPoolSize=5
org.orcid.persistence.db.idleConnectionTestPeriod=60
org.orcid.persistence.db.initialPoolSize=1
org.orcid.persistence.db.maxPoolSize=20
org.orcid.persistence.db.maxStatements=50
org.orcid.persistence.db.maxStatements=0
org.orcid.persistence.db.minPoolSize=5
org.orcid.persistence.db.numHelperThreads=10
org.orcid.persistence.db.password=orcid
org.orcid.persistence.db.password=pheinu0uija4eechohna
org.orcid.persistence.db.preferredTestQuery=select 1
org.orcid.persistence.db.showSql=false
org.orcid.persistence.db.testConnectionOnCheckin=true
org.orcid.persistence.db.url=jdbc:postgresql://localhost:5432/orcid?stringtype=unspecified
org.orcid.persistence.db.url=jdbc:postgresql://reg-qa-pg-use2-a1:5432/orcid
org.orcid.persistence.db.username=orcid

# Read only database
org.orcid.persistence.db.readonly.class=org.postgresql.Driver
org.orcid.persistence.db.readonly.dataSource=pooledDataSourceReadOnly
org.orcid.persistence.db.readonly.dialect=org.hibernate.dialect.PostgreSQLDialect
org.orcid.persistence.db.readonly.generateDdl=false
org.orcid.persistence.db.readonly.idleConnectionTestPeriod=3600
org.orcid.persistence.db.readonly.initialPoolSize=5
org.orcid.persistence.db.readonly.idleConnectionTestPeriod=60
org.orcid.persistence.db.readonly.initialPoolSize=1
org.orcid.persistence.db.readonly.maxPoolSize=20
org.orcid.persistence.db.readonly.maxStatements=50
org.orcid.persistence.db.readonly.maxStatements=0
org.orcid.persistence.db.readonly.minPoolSize=5
org.orcid.persistence.db.readonly.password=orcidro
org.orcid.persistence.db.readonly.password=5dyjm5fmcpvksa9562tv
org.orcid.persistence.db.readonly.preferredTestQuery=select 1
org.orcid.persistence.db.readonly.showSql=false
org.orcid.persistence.db.readonly.testConnectionOnCheckin=true
org.orcid.persistence.db.readonly.url=jdbc:postgresql://localhost:5432/orcid?stringtype=unspecified
org.orcid.persistence.db.readonly.url=jdbc:postgresql://reg-qa-pg-use2-a1:5432/orcid
org.orcid.persistence.db.readonly.username=orcidro

# Features database
org.orcid.persistence.togglz.cache.ttl=0
org.orcid.persistence.togglz.cache.ttl=60000
org.orcid.persistence.togglz.db.class=org.postgresql.Driver
org.orcid.persistence.togglz.db.idleConnectionTestPeriod=3600
org.orcid.persistence.togglz.db.idleConnectionTestPeriod=60
org.orcid.persistence.togglz.db.initialPoolSize=1
org.orcid.persistence.togglz.db.maxPoolSize=1
org.orcid.persistence.togglz.db.maxPoolSize=5
org.orcid.persistence.togglz.db.maxStatements=0
org.orcid.persistence.togglz.db.minPoolSize=1
org.orcid.persistence.togglz.db.minPoolSize=3
org.orcid.persistence.togglz.db.numHelperThreads=5
org.orcid.persistence.togglz.db.password=orcid
org.orcid.persistence.togglz.db.password=pheinu0uija4eechohna
org.orcid.persistence.togglz.db.preferredTestQuery=select 1
org.orcid.persistence.togglz.db.testConnectionOnCheckin=true
org.orcid.persistence.togglz.db.url=jdbc:postgresql://localhost:5432/features
org.orcid.persistence.togglz.db.url=jdbc:postgresql://reg-qa-pg-use2-a1:5432/features
org.orcid.persistence.togglz.db.username=orcid

################
Expand All @@ -66,6 +66,10 @@ org.orcid.core.baseUri=https://dev.orcid.org
org.orcid.core.internalApiBaseUri=http://localhost:8080/orcid-internal-api
org.orcid.core.pubBaseUri=https://pub.dev.orcid.org

# Used to encrypt some user data before sending it to the database
org.orcid.core.passPhraseForExternalEncryption=spAbusa3ubRase7udEpr
org.orcid.core.passPhraseForInternalEncryption=XeZa8wUkuchusp8saWaW

# Mailgun
com.mailgun.alt.apiUrl=https://api.mailgun.net/v2/samples.mailgun.org/messages
com.mailgun.alt.notify.apiUrl=https://api.mailgun.net/v2/samples.mailgun.org/messages
Expand Down

0 comments on commit 10b2f24

Please sign in to comment.