diff --git a/orcid-core/src/main/resources/i18n/papi_rate_limit_email_en.properties b/orcid-core/src/main/resources/i18n/papi_rate_limit_email_en.properties new file mode 100644 index 0000000000..6328202a32 --- /dev/null +++ b/orcid-core/src/main/resources/i18n/papi_rate_limit_email_en.properties @@ -0,0 +1,13 @@ +papi.rate.limit.subject=[ORCID-API] WARNING! You have exceeded the daily Public API Usage Limit - ({0}) +papi.rate.limit.important.msg=This is an important message to let you know that you have exceeded your +papi.rate.limit.daily.usage.limit=daily Public API usage limit +papi.rate.limit.your.integration=with your integration: +papi.rate.limit.client.name=Client Name: +papi.rate.limit.client.id=Client ID: +papi.rate.limit.please.remember=Please remember that the ORCID Public API is free for non-commercial use by individuals as stated in the +papi.rate.limit.public.api.terms=Public APIs Terms of Service +papi.rate.limit.by.non.commercial=By "non-commercial" we mean that you may not charge any re-use fees for the Public API, and you may not make use of the Public API in connection with any revenue-generating product or service. +papi.rate.limit.based.on.your=Based on your API usage, we highly recommend you consider becoming an ORCID member for access to our +papi.rate.limit.member.api=Member API +papi.rate.limit.not.only=Not only will it allow you to access a higher Rate Limits and an unrestricted Usage Quota, but you will be able to access Trusted Party data in ORCID records and contribute data to ORCID records from your institutional systems +papi.rate.limit.to.minimize=To minimize any disruption to your ORCID integration in the future, we would recommend that you reach out to our Engagement Team by replying to this email to discuss our ORCID membership options. \ No newline at end of file diff --git a/orcid-core/src/main/resources/i18n/papi_rate_limit_email_lr.properties b/orcid-core/src/main/resources/i18n/papi_rate_limit_email_lr.properties new file mode 100644 index 0000000000..47c2ea1dde --- /dev/null +++ b/orcid-core/src/main/resources/i18n/papi_rate_limit_email_lr.properties @@ -0,0 +1,13 @@ +papi.rate.limit.subject=LR +papi.rate.limit.important.msg=LR +papi.rate.limit.daily.usage.limit=LR +papi.rate.limit.your.integration=LR +papi.rate.limit.client.name=LR +papi.rate.limit.client.id=LR +papi.rate.limit.please.remember=LR +papi.rate.limit.public.api.terms=LR +papi.rate.limit.by.non.commercial=LR +papi.rate.limit.based.on.your=LR +papi.rate.limit.member.api=LR +papi.rate.limit.not.only=LR +papi.rate.limit.to.minimize=LR \ No newline at end of file diff --git a/orcid-core/src/main/resources/i18n/papi_rate_limit_email_rl.properties b/orcid-core/src/main/resources/i18n/papi_rate_limit_email_rl.properties new file mode 100644 index 0000000000..0692e965ee --- /dev/null +++ b/orcid-core/src/main/resources/i18n/papi_rate_limit_email_rl.properties @@ -0,0 +1,13 @@ +papi.rate.limit.subject=RL +papi.rate.limit.important.msg=RL +papi.rate.limit.daily.usage.limit=RL +papi.rate.limit.your.integration=RL +papi.rate.limit.client.name=RL +papi.rate.limit.client.id=RL +papi.rate.limit.please.remember=RL +papi.rate.limit.public.api.terms=RL +papi.rate.limit.by.non.commercial=RL +papi.rate.limit.based.on.your=RL +papi.rate.limit.member.api=RL +papi.rate.limit.not.only=RL +papi.rate.limit.to.minimize=RL \ No newline at end of file diff --git a/orcid-core/src/main/resources/i18n/papi_rate_limit_email_xx.properties b/orcid-core/src/main/resources/i18n/papi_rate_limit_email_xx.properties new file mode 100644 index 0000000000..3bb4fafe44 --- /dev/null +++ b/orcid-core/src/main/resources/i18n/papi_rate_limit_email_xx.properties @@ -0,0 +1,13 @@ +papi.rate.limit.subject=XX +papi.rate.limit.important.msg=XX +papi.rate.limit.daily.usage.limit=XX +papi.rate.limit.your.integration=XX +papi.rate.limit.client.name=XX +papi.rate.limit.client.id=XX +papi.rate.limit.please.remember=XX +papi.rate.limit.public.api.terms=XX +papi.rate.limit.by.non.commercial=XX +papi.rate.limit.based.on.your=XX +papi.rate.limit.member.api=XX +papi.rate.limit.not.only=XX +papi.rate.limit.to.minimize=XX \ No newline at end of file diff --git a/orcid-core/src/main/resources/orcid-core-context.xml b/orcid-core/src/main/resources/orcid-core-context.xml index 1b1725537b..7dc4840c32 100644 --- a/orcid-core/src/main/resources/orcid-core-context.xml +++ b/orcid-core/src/main/resources/orcid-core-context.xml @@ -786,14 +786,14 @@ - + - + diff --git a/orcid-core/src/main/resources/org/orcid/core/template/papi_rate_limit_email.ftl b/orcid-core/src/main/resources/org/orcid/core/template/papi_rate_limit_email.ftl index bbae0db18c..0406dd89bb 100644 --- a/orcid-core/src/main/resources/org/orcid/core/template/papi_rate_limit_email.ftl +++ b/orcid-core/src/main/resources/org/orcid/core/template/papi_rate_limit_email.ftl @@ -1,15 +1,15 @@ <#import "email_macros.ftl" as emailMacros /> -Dear ${emailName}, +<@emailMacros.msg "email.common.dear" /><@emailMacros.space />${emailName}, -This is an important message to let you know that you have exceeded your daily Public API usage limit with your integration (https://info.orcid.org/ufaqs/what-are-the-api-limits/): +<@emailMacros.msg "papi.rate.limit.important.msg" /><@emailMacros.space /><@emailMacros.msg "papi.rate.limit.daily.usage.limit" /><@emailMacros.space /><@emailMacros.msg "papi.rate.limit.your.integration" /><@emailMacros.space />(https://info.orcid.org/ufaqs/what-are-the-api-limits/): -Client Name: ${clientName} -Client ID: ${clientId} +<@emailMacros.msg "papi.rate.limit.client.name" /><@emailMacros.space />${clientName} +<@emailMacros.msg "papi.rate.limit.client.id" /><@emailMacros.space />${clientId} -Please remember that the ORCID Public API is free for non-commercial use by individuals as stated in the Public APIs Terms of Service (https://info.orcid.org/public-client-terms-of-service). By "non-commercial" we mean that you may not charge any re-use fees for the Public API, and you may not make use of the Public API in connection with any revenue-generating product or service. +<@emailMacros.msg "papi.rate.limit.please.remember" /><@emailMacros.space /><@emailMacros.msg "papi.rate.limit.public.api.terms" /><@emailMacros.space />(https://info.orcid.org/public-client-terms-of-service).<@emailMacros.space /><@emailMacros.msg "papi.rate.limit.by.non.commercial" /> -Based on your API usage, we highly recommend you consider becoming an ORCID member for access to our Member API (https://info.orcid.org/what-is-orcid/services/member-api/). Not only will it allow you to access a higher Rate Limits and an unrestricted Usage Quota, but you will be able to access Trusted Party data in ORCID records and contribute data to ORCID records from your institutional systems. +<@emailMacros.msg "papi.rate.limit.based.on.your" /><@emailMacros.space /><@emailMacros.msg "papi.rate.limit.member.api" /><@emailMacros.space />(https://info.orcid.org/what-is-orcid/services/member-api/).<@emailMacros.space /><@emailMacros.msg "papi.rate.limit.not.only" /> -To minimize any disruption to your ORCID integration in the future, we would recommend that you reach out to our Engagement Team by replying to this email to discuss our ORCID membership options. +<@emailMacros.msg "papi.rate.limit.to.minimize" /> <#include "email_footer.ftl"/> diff --git a/orcid-core/src/main/resources/org/orcid/core/template/papi_rate_limit_email_html.ftl b/orcid-core/src/main/resources/org/orcid/core/template/papi_rate_limit_email_html.ftl index a43872bb53..cd6f3d04c8 100644 --- a/orcid-core/src/main/resources/org/orcid/core/template/papi_rate_limit_email_html.ftl +++ b/orcid-core/src/main/resources/org/orcid/core/template/papi_rate_limit_email_html.ftl @@ -9,14 +9,14 @@
ORCID.org
- Dear ${emailName}, -

This is an important message to let you know that you have exceeded your daily Public API usage limit with your integration:

-

Client Name: ${clientName}

-

Client ID: ${clientId}

+ <@emailMacros.msg "email.common.dear" /> ${emailName}, +

<@emailMacros.msg "papi.rate.limit.important.msg" /><@emailMacros.space /><@emailMacros.msg "papi.rate.limit.daily.usage.limit" /><@emailMacros.space /><@emailMacros.msg "papi.rate.limit.your.integration" />

+

<@emailMacros.msg "papi.rate.limit.client.name" /><@emailMacros.space /> ${clientName}

+

<@emailMacros.msg "papi.rate.limit.client.id" /><@emailMacros.space />${clientId}


-

Please remember that the ORCID Public API is free for non-commercial use by individuals as stated in the Public APIs Terms of Service. By "non-commercial" we mean that you may not charge any re-use fees for the Public API, and you may not make use of the Public API in connection with any revenue-generating product or service.

-

Based on your API usage, we highly recommend you consider becoming an ORCID member for access to our Member API. Not only will it allow you to access a higher Rate Limits and an unrestricted Usage Quota, but you will be able to access Trusted Party data in ORCID records and contribute data to ORCID records from your institutional systems.

-

To minimize any disruption to your ORCID integration in the future, we would recommend that you reach out to our Engagement Team by replying to this email to discuss our ORCID membership options. +

<@emailMacros.msg "papi.rate.limit.please.remember" /><@emailMacros.space /><@emailMacros.msg "papi.rate.limit.public.api.terms" />.<@emailMacros.space /><@emailMacros.msg "papi.rate.limit.by.non.commercial" />

+

<@emailMacros.msg "papi.rate.limit.based.on.your" /><@emailMacros.space /><@emailMacros.msg "papi.rate.limit.member.api" />.<@emailMacros.space /><@emailMacros.msg "papi.rate.limit.not.only" />

+

<@emailMacros.msg "papi.rate.limit.to.minimize" />

<#include "email_footer_html.ftl"/>

diff --git a/orcid-pub-web/src/main/java/org/orcid/api/filters/ApiRateLimitFilter.java b/orcid-pub-web/src/main/java/org/orcid/api/filters/ApiRateLimitFilter.java index 16cf9e5ff8..6878d6c0a2 100644 --- a/orcid-pub-web/src/main/java/org/orcid/api/filters/ApiRateLimitFilter.java +++ b/orcid-pub-web/src/main/java/org/orcid/api/filters/ApiRateLimitFilter.java @@ -23,7 +23,9 @@ import org.orcid.core.manager.v3.EmailManager; import org.orcid.core.manager.v3.RecordNameManager; import org.orcid.core.oauth.service.OrcidTokenStore; +import org.orcid.persistence.dao.ProfileDao; import org.orcid.persistence.jpa.entities.ClientDetailsEntity; +import org.orcid.persistence.jpa.entities.ProfileEntity; import org.orcid.utils.email.MailGunManager; import org.orcid.utils.panoply.PanoplyPapiDailyRateExceededItem; import org.orcid.utils.panoply.PanoplyRedshiftClient; @@ -38,6 +40,7 @@ import org.springframework.web.filter.OncePerRequestFilter; import org.orcid.core.togglz.Features; +import org.orcid.jaxb.model.common.AvailableLocales; @Component public class ApiRateLimitFilter extends OncePerRequestFilter { @@ -45,6 +48,9 @@ public class ApiRateLimitFilter extends OncePerRequestFilter { @Autowired private ClientDetailsEntityCacheManager clientDetailsEntityCacheManager; + + @Autowired + private ProfileDao profileDao; @Autowired private MailGunManager mailGunManager; @@ -103,7 +109,7 @@ public class ApiRateLimitFilter extends OncePerRequestFilter { + "You can increase your daily quota by registering for and using Public API client credentials " + "(https://info.orcid.org/documentation/integration-guide/registering-a-public-api-client/)"; - private static final String SUBJECT = "[ORCID-API] WARNING! You have exceeded the daily Public API Usage Limit - ({ORCID-ID})"; + private static final String SUBJECT = "[ORCID-API] WARNING! You have exceeded the daily Public API Usage Limit - ({0})"; @Value("${org.orcid.papi.rate.limit.fromEmail:apiusage@orcid.org}") private String FROM_ADDRESS; @@ -152,6 +158,7 @@ public void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletR } else { if (!isClientIdWhiteListed(clientId)) { + //Get the locale for the clientID LOG.info("ApiRateLimitFilter client request with clientId: " + clientId); this.rateLimitClientRequest(clientId, today); } @@ -213,29 +220,33 @@ private void rateLimitClientRequest(String clientId, LocalDate today) throws JSO } - private Map createTemplateParams(String clientId, String clientName, String emailName, String orcidId) { + private Map createTemplateParams(String clientId, String clientName, String emailName, String orcidId, Locale locale) { + String subject = messageSource.getMessage("papi.rate.limit.subject", new String[] { orcidId }, locale);; Map templateParams = new HashMap(); templateParams.put("messages", messageSource); templateParams.put("messageArgs", new Object[0]); templateParams.put("clientId", clientId); templateParams.put("clientName", clientName); templateParams.put("emailName", emailName); - templateParams.put("locale", LocaleUtils.toLocale("en")); + templateParams.put("locale", locale); templateParams.put("baseUri", orcidUrlManager.getBaseUrl()); templateParams.put("baseUriHttp", orcidUrlManager.getBaseUriHttp()); - templateParams.put("subject", SUBJECT.replace("{ORCID-ID}", orcidId)); + templateParams.put("subject", subject); return templateParams; } private void sendEmail(String clientId, LocalDate requestDate) { ClientDetailsEntity clientDetailsEntity = clientDetailsEntityCacheManager.retrieve(clientId); String memberId = clientDetailsEntity.getGroupProfileId(); + ProfileEntity memberProfile = profileDao.find(memberId); String emailName = recordNameManager.deriveEmailFriendlyName(memberId); - Map templateParams = this.createTemplateParams(clientId, clientDetailsEntity.getClientName(), emailName, memberId); + Locale locale = getUserLocaleFromProfileEntity(memberProfile); + + Map templateParams = this.createTemplateParams(clientId, clientDetailsEntity.getClientName(), emailName, memberId, getUserLocaleFromProfileEntity(memberProfile)); // Generate body from template - String body = templateManager.processTemplate("papi_rate_limit_email.ftl", templateParams); + String body = templateManager.processTemplate("papi_rate_limit_email.ftl", templateParams, locale); // Generate html from template - String html = templateManager.processTemplate("papi_rate_limit_email_html.ftl", templateParams); + String html = templateManager.processTemplate("papi_rate_limit_email_html.ftl", templateParams, locale ); String email = emailManager.findPrimaryEmail(memberId).getEmail(); LOG.info("from address={}", FROM_ADDRESS); LOG.info("text email={}", body); @@ -304,4 +315,17 @@ private boolean isReferrerWhiteListed(String referrer) { else return (papiReferrerWhiteList != null) ? papiReferrerWhiteList.contains(referrer) : false; } + + private Locale getUserLocaleFromProfileEntity(ProfileEntity profile) { + String locale = profile.getLocale(); + try { + if (locale != null) { + return LocaleUtils.toLocale(AvailableLocales.valueOf(locale).value()); + } + } + catch(Exception ex) { + LOG.error("Locale is not supported in the available locales, defaulting to en", ex); + } + return LocaleUtils.toLocale("en"); + } } diff --git a/properties/development.properties b/properties/development.properties index d9fc7fb464..d6d65d0dda 100644 --- a/properties/development.properties +++ b/properties/development.properties @@ -277,8 +277,8 @@ org.orcid.core.utils.panoply.username=xxx #Slack channel for papi limits org.orcid.core.papiLimitReport.slackChannel=system-alerts-qa org.orcid.core.papiLimitReport.webhookUrl=xxx -org.orcid.papi.rate.limit.anonymous.requests=1000 -org.orcid.papi.rate.limit.known.requests=11111 +org.orcid.papi.rate.limit.anonymous.requests=4 +org.orcid.papi.rate.limit.known.requests=2 org.orcid.papi.rate.limit.enabled=true org.orcid.scheduler.papiLimitReport.process=0 18 15 * * * @@ -286,4 +286,4 @@ org.orcid.scheduler.papiLimitReport.process=0 18 15 * * * org.orcid.core.utils.cache.papi.redis.host=xxxx org.orcid.core.utils.cache.papi.redis.port=6379 org.orcid.core.utils.cache.papi.redis.password=xxxx -org.orcid.core.utils.cache.papi.redis.enabled=true \ No newline at end of file +org.orcid.core.utils.cache.papi.redis.enabled=true