Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adding rate limiting for command engine #10211

Merged
merged 85 commits into from
Mar 20, 2024
Merged
Show file tree
Hide file tree
Changes from 84 commits
Commits
Show all changes
85 commits
Select commit Hold shift + click to select a range
598912f
adding rate limiting for commmand engine
stevenwinship Jan 5, 2024
c657eb0
fixing tests
stevenwinship Jan 5, 2024
f5e0070
fixing tests
stevenwinship Jan 5, 2024
1b0a554
fixing tests
stevenwinship Jan 5, 2024
a534627
Update doc/release-notes/9356-rate-limiting.md
stevenwinship Jan 9, 2024
c80f74a
fixing review comments
stevenwinship Jan 9, 2024
12c15b5
review comment fixes
stevenwinship Jan 9, 2024
a178929
review comment fixes
stevenwinship Jan 9, 2024
4684384
review comment fixes
stevenwinship Jan 9, 2024
1e44206
fixes to get DatasetsIT to pass
stevenwinship Jan 11, 2024
77074cc
fix mock for redis tests
stevenwinship Jan 18, 2024
4cdba95
fix mock for redis tests
stevenwinship Jan 18, 2024
1b4f613
Update doc/sphinx-guides/source/installation/config.rst
stevenwinship Jan 24, 2024
2b603a6
fixes from comments
stevenwinship Jan 24, 2024
13e3011
Update doc/release-notes/9356-rate-limiting.md
stevenwinship Jan 24, 2024
0467f4c
Update doc/release-notes/9356-rate-limiting.md
stevenwinship Jan 24, 2024
5253de8
Update doc/release-notes/9356-rate-limiting.md
stevenwinship Jan 24, 2024
13fdd88
Update doc/release-notes/9356-rate-limiting.md
stevenwinship Jan 24, 2024
dd30c7b
Update doc/release-notes/9356-rate-limiting.md
stevenwinship Jan 24, 2024
23606a0
Update doc/release-notes/9356-rate-limiting.md
stevenwinship Jan 24, 2024
1bd2556
Update doc/release-notes/9356-rate-limiting.md
stevenwinship Jan 24, 2024
c04db0a
Update doc/release-notes/9356-rate-limiting.md
stevenwinship Jan 24, 2024
3dfc2a0
adding changes per pr comments
stevenwinship Jan 24, 2024
727cccf
remove redis and replace with jcache hazelcast
stevenwinship Jan 26, 2024
58ea032
adding cache tests
stevenwinship Jan 26, 2024
f7f9664
fixing unit tests
stevenwinship Jan 29, 2024
dbb774b
fixing unit tests
stevenwinship Jan 29, 2024
b489ec8
fixing unit tests
stevenwinship Jan 29, 2024
700e799
fixing unit tests
stevenwinship Jan 29, 2024
5a7d300
fixing unit tests
stevenwinship Jan 29, 2024
e2b5fe8
fixing unit tests
stevenwinship Jan 29, 2024
7fb8c88
fixing unit tests
stevenwinship Jan 29, 2024
0674105
fixing unit tests
stevenwinship Jan 29, 2024
a55ed93
fixing unit tests
stevenwinship Jan 29, 2024
c7b5969
fixing unit tests
stevenwinship Jan 29, 2024
a27c785
fixing unit tests
stevenwinship Jan 30, 2024
ecca881
fixing unit tests
stevenwinship Jan 30, 2024
11a37e3
fixing unit tests
stevenwinship Jan 30, 2024
c84ae14
fixing unit tests
stevenwinship Jan 30, 2024
4f8a39c
fixing unit tests
stevenwinship Jan 30, 2024
3d0e438
fix test hazelcast config
stevenwinship Jan 31, 2024
176adbc
fix test hazelcast config
stevenwinship Jan 31, 2024
403dc08
fix test hazelcast config
stevenwinship Jan 31, 2024
9e43b25
fix test hazelcast config
stevenwinship Jan 31, 2024
0771fae
fixing more review comments
stevenwinship Feb 1, 2024
252337a
fix db rate limit tier column
stevenwinship Feb 1, 2024
cc70ba7
fix db rate limit tier column
stevenwinship Feb 1, 2024
794f024
fix db rate limit tier column
stevenwinship Feb 1, 2024
605097c
getting tests to pass on Jenkins
stevenwinship Feb 2, 2024
879bc5c
testing in jenkins
stevenwinship Feb 2, 2024
27cce94
use payara instance of hazelcast
stevenwinship Feb 2, 2024
9784416
fixes for Jenkins
stevenwinship Feb 2, 2024
21b0951
fixes for Jenkins
stevenwinship Feb 2, 2024
465c5d5
fixes for Jenkins
stevenwinship Feb 2, 2024
e5fe18f
fixes for Jenkins
stevenwinship Feb 2, 2024
15ef82e
Update pom.xml
stevenwinship Feb 5, 2024
77cede2
Update src/test/java/edu/harvard/iq/dataverse/cache/CacheFactoryBeanT…
stevenwinship Feb 5, 2024
02cd0d0
Update pom.xml
stevenwinship Feb 5, 2024
9b95e4d
Update src/main/java/edu/harvard/iq/dataverse/cache/CacheFactoryBean.…
stevenwinship Feb 5, 2024
52e714b
review comments re: JCache
stevenwinship Feb 6, 2024
669d273
review comments re: JCache
stevenwinship Feb 6, 2024
9800fc1
doc change
stevenwinship Feb 6, 2024
ae0ec5a
fix bad merge
stevenwinship Feb 7, 2024
5e507a0
moving cache to util/cache
stevenwinship Feb 7, 2024
0774223
review comments fixed
stevenwinship Feb 7, 2024
d5b1fb5
rename db script
stevenwinship Feb 9, 2024
54f1077
review comments
stevenwinship Feb 20, 2024
d2d3b4a
fixing config.rst
stevenwinship Feb 20, 2024
3102b05
fixing config.rst
stevenwinship Feb 20, 2024
736c633
more review comments
stevenwinship Feb 20, 2024
ecea90c
fixing tests
stevenwinship Feb 21, 2024
9d575ed
fixing tests
stevenwinship Feb 21, 2024
692c650
more review comments
stevenwinship Feb 22, 2024
13674df
more review comments
stevenwinship Feb 22, 2024
1e4d351
review comments
stevenwinship Feb 27, 2024
8edbc04
review comments
stevenwinship Feb 27, 2024
4a0e0af
rename sql to unique
stevenwinship Feb 29, 2024
5233bf2
review comments
stevenwinship Feb 29, 2024
b66e000
Update doc/sphinx-guides/source/installation/config.rst
stevenwinship Feb 29, 2024
0b3c5e3
Cosmetics for 9356 - Rate Limiting PR (#10349)
poikilotherm Mar 1, 2024
2266225
rename sql file
stevenwinship Mar 6, 2024
a1ab6f9
change sql script name
stevenwinship Mar 18, 2024
e1f2e66
One extra phrase added to the guide
landreev Mar 19, 2024
91bb468
adding two specific commands CheckRateLimitForDatasetPage and CheckRa…
stevenwinship Mar 20, 2024
a9b2514
add check for existing cache before creating a new one
stevenwinship Mar 20, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions doc/release-notes/9356-rate-limiting.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
## Rate Limiting using JCache (with Hazelcast as provided by Payara)
The option to rate limit has been added to prevent users from over taxing the system either deliberately or by runaway automated processes.
Rate limiting can be configured on a tier level with tier 0 being reserved for guest users and tiers 1-any for authenticated users.
Superuser accounts are exempt from rate limiting.
Rate limits can be imposed on command APIs by configuring the tier, the command, and the hourly limit in the database.
Two database settings configure the rate limiting.
stevenwinship marked this conversation as resolved.
Show resolved Hide resolved
Note: If either of these settings exist in the database rate limiting will be enabled.
If neither setting exists rate limiting is disabled.

`:RateLimitingDefaultCapacityTiers` is a comma separated list of default values for each tier.
In the following example, the default for tier `0` (guest users) is set to 10,000 calls per command per hour and tier `1` (authenticated users) is set to 20,000 calls per command per hour.
Tiers not specified in this setting will default to `-1` (No Limit). I.e., -d "10000" is equivalent to -d "10000,-1,-1,..."
`curl http://localhost:8080/api/admin/settings/:RateLimitingDefaultCapacityTiers -X PUT -d '10000,20000'`

`:RateLimitingCapacityByTierAndAction` is a JSON object specifying the rate by tier and a list of actions (commands).
This allows for more control over the rate limit of individual API command calls.
In the following example, calls made by a guest user (tier 0) for API `GetLatestPublishedDatasetVersionCommand` is further limited to only 10 calls per hour, while an authenticated user (tier 1) will be able to make 30 calls per hour to the same API.
`curl http://localhost:8080/api/admin/settings/:RateLimitingCapacityByTierAndAction -X PUT -d '[{"tier": 0, "limitPerHour": 10, "actions": ["GetLatestPublishedDatasetVersionCommand", "GetPrivateUrlCommand", "GetDatasetCommand", "GetLatestAccessibleDatasetVersionCommand"]}, {"tier": 0, "limitPerHour": 1, "actions": ["CreateGuestbookResponseCommand", "UpdateDatasetVersionCommand", "DestroyDatasetCommand", "DeleteDataFileCommand", "FinalizeDatasetPublicationCommand", "PublishDatasetCommand"]}, {"tier": 1, "limitPerHour": 30, "actions": ["CreateGuestbookResponseCommand", "GetLatestPublishedDatasetVersionCommand", "GetPrivateUrlCommand", "GetDatasetCommand", "GetLatestAccessibleDatasetVersionCommand", "UpdateDatasetVersionCommand", "DestroyDatasetCommand", "DeleteDataFileCommand", "FinalizeDatasetPublicationCommand", "PublishDatasetCommand"]}]'`

Hazelcast is configured in Payara and should not need any changes for this feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
[
{
"tier": 0,
"limitPerHour": 10,
"actions": [
"GetLatestPublishedDatasetVersionCommand",
"GetPrivateUrlCommand",
"GetDatasetCommand",
"GetLatestAccessibleDatasetVersionCommand"
]
},
{
"tier": 0,
"limitPerHour": 1,
"actions": [
"CreateGuestbookResponseCommand",
"UpdateDatasetVersionCommand",
"DestroyDatasetCommand",
"DeleteDataFileCommand",
"FinalizeDatasetPublicationCommand",
"PublishDatasetCommand"
]
},
{
"tier": 1,
"limitPerHour": 30,
"actions": [
"CreateGuestbookResponseCommand",
"GetLatestPublishedDatasetVersionCommand",
"GetPrivateUrlCommand",
"GetDatasetCommand",
"GetLatestAccessibleDatasetVersionCommand",
"UpdateDatasetVersionCommand",
"DestroyDatasetCommand",
"DeleteDataFileCommand",
"FinalizeDatasetPublicationCommand",
"PublishDatasetCommand"
]
}
]
41 changes: 41 additions & 0 deletions doc/sphinx-guides/source/installation/config.rst
stevenwinship marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -1373,6 +1373,33 @@ Before being moved there,
on your machine, large file uploads via API will cause RAM and/or swap usage bursts. You might want to point this to
a different location, restrict maximum size of it, and monitor for stale uploads.

.. _cache-rate-limiting:

Configure Your Dataverse Installation to Use JCache (with Hazelcast as Provided by Payara) for Rate Limiting
------------------------------------------------------------------------------------------------------------

Rate limiting has been added to prevent users from over taxing the system either deliberately or by runaway automated processes.
Rate limiting can be configured on a tier level with tier 0 being reserved for guest users and tiers 1-any for authenticated users.
Superuser accounts are exempt from rate limiting.
Rate limits can be imposed on command APIs by configuring the tier, the command, and the hourly limit in the database.
Two database settings configure the rate limiting.
Note: If either of these settings exist in the database rate limiting will be enabled (note that a Payara restart is required for the setting to take effect). If neither setting exists rate limiting is disabled.

- :RateLimitingDefaultCapacityTiers is the number of calls allowed per hour if the specific command is not configured. The values represent the number of calls per hour per user for tiers 0,1,...
A value of -1 can be used to signify no rate limit. Tiers not specified in this setting will default to `-1` (No Limit). I.e., -d "10000" is equivalent to -d "10000,-1,-1,..."

.. code-block:: bash

curl http://localhost:8080/api/admin/settings/:RateLimitingDefaultCapacityTiers -X PUT -d '10000,20000'
poikilotherm marked this conversation as resolved.
Show resolved Hide resolved

- :RateLimitingCapacityByTierAndAction is a JSON object specifying the rate by tier and a list of actions (commands). This allows for more control over the rate limit of individual API command calls.
In the following example, calls made by a guest user (tier 0) for API GetLatestPublishedDatasetVersionCommand is further limited to only 10 calls per hour, while an authenticated user (tier 1) will be able to make 30 calls per hour to the same API.

:download:`rate-limit-actions.json </_static/installation/files/examples/rate-limit-actions-setting.json>` Example json for RateLimitingCapacityByTierAndAction

.. code-block:: bash

curl http://localhost:8080/api/admin/settings/:RateLimitingCapacityByTierAndAction -X PUT -d '[{"tier": 0, "limitPerHour": 10, "actions": ["GetLatestPublishedDatasetVersionCommand", "GetPrivateUrlCommand", "GetDatasetCommand", "GetLatestAccessibleDatasetVersionCommand"]}, {"tier": 0, "limitPerHour": 1, "actions": ["CreateGuestbookResponseCommand", "UpdateDatasetVersionCommand", "DestroyDatasetCommand", "DeleteDataFileCommand", "FinalizeDatasetPublicationCommand", "PublishDatasetCommand"]}, {"tier": 1, "limitPerHour": 30, "actions": ["CreateGuestbookResponseCommand", "GetLatestPublishedDatasetVersionCommand", "GetPrivateUrlCommand", "GetDatasetCommand", "GetLatestAccessibleDatasetVersionCommand", "UpdateDatasetVersionCommand", "DestroyDatasetCommand", "DeleteDataFileCommand", "FinalizeDatasetPublicationCommand", "PublishDatasetCommand"]}]'

.. _Branding Your Installation:

Expand Down Expand Up @@ -4496,3 +4523,17 @@ tab. files saved with these headers on S3 - since they no longer have
to be generated and added to the streamed file on the fly.

The setting is ``false`` by default, preserving the legacy behavior.

:RateLimitingDefaultCapacityTiers
+++++++++++++++++++++++++++++++++
Number of calls allowed per hour if the specific command is not configured. The values represent the number of calls per hour per user for tiers 0,1,...
A value of -1 can be used to signify no rate limit. Also, by default, a tier not defined would receive a default of no limit.

:RateLimitingCapacityByTierAndAction
++++++++++++++++++++++++++++++++++++
JSON object specifying the rate by tier and a list of actions (commands). This allows for more control over the rate limit of individual API command calls.
In the following example, calls made by a guest user (tier 0) for API GetLatestPublishedDatasetVersionCommand is further limited to only 10 calls per hour, while an authenticated user (tier 1) will be able to make 30 calls per hour to the same API.
{"rateLimits":[
{"tier": 0, "limitPerHour": 10, "actions": ["GetLatestPublishedDatasetVersionCommand", "GetPrivateUrlCommand", "GetDatasetCommand", "GetLatestAccessibleDatasetVersionCommand"]},
{"tier": 0, "limitPerHour": 1, "actions": ["CreateGuestbookResponseCommand", "UpdateDatasetVersionCommand", "DestroyDatasetCommand", "DeleteDataFileCommand", "FinalizeDatasetPublicationCommand", "PublishDatasetCommand"]},
{"tier": 1, "limitPerHour": 30, "actions": ["CreateGuestbookResponseCommand", "GetLatestPublishedDatasetVersionCommand", "GetPrivateUrlCommand", "GetDatasetCommand", "GetLatestAccessibleDatasetVersionCommand", "UpdateDatasetVersionCommand", "DestroyDatasetCommand", "DeleteDataFileCommand", "FinalizeDatasetPublicationCommand", "PublishDatasetCommand"]}]}
21 changes: 21 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,18 @@
<scope>provided</scope>
</dependency>

<!-- JSON-B -->
<dependency>
<groupId>jakarta.json.bind</groupId>
<artifactId>jakarta.json.bind-api</artifactId>
</dependency>
<!-- Rope in an implementation for unit tests - is provided at runtime by appserver -->
<dependency>
<groupId>org.eclipse</groupId>
<artifactId>yasson</artifactId>
<scope>test</scope>
</dependency>

<!-- Jakarta Faces & related -->
<dependency>
<groupId>org.glassfish</groupId>
Expand Down Expand Up @@ -542,6 +554,10 @@
<artifactId>dataverse-spi</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>javax.cache</groupId>
<artifactId>cache-api</artifactId>
</dependency>
<!-- TESTING DEPENDENCIES -->
<dependency>
<groupId>org.junit.jupiter</groupId>
Expand Down Expand Up @@ -653,6 +669,11 @@
<version>3.9.0</version>
<scope>test</scope>
</dependency>
stevenwinship marked this conversation as resolved.
Show resolved Hide resolved
<dependency>
<groupId>com.hazelcast</groupId>
<artifactId>hazelcast</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<testResources>
Expand Down
9 changes: 8 additions & 1 deletion src/main/java/edu/harvard/iq/dataverse/DatasetPage.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import edu.harvard.iq.dataverse.engine.command.Command;
import edu.harvard.iq.dataverse.engine.command.CommandContext;
import edu.harvard.iq.dataverse.engine.command.exception.CommandException;
import edu.harvard.iq.dataverse.engine.command.impl.CheckRateLimitForDatasetPage;
import edu.harvard.iq.dataverse.engine.command.impl.CreatePrivateUrlCommand;
import edu.harvard.iq.dataverse.engine.command.impl.CuratePublishedDatasetVersionCommand;
import edu.harvard.iq.dataverse.engine.command.impl.DeaccessionDatasetVersionCommand;
Expand All @@ -36,6 +37,7 @@
import edu.harvard.iq.dataverse.engine.command.impl.PublishDataverseCommand;
import edu.harvard.iq.dataverse.engine.command.impl.UpdateDatasetVersionCommand;
import edu.harvard.iq.dataverse.export.ExportService;
import edu.harvard.iq.dataverse.util.cache.CacheFactoryBean;
import io.gdcc.spi.export.ExportException;
import io.gdcc.spi.export.Exporter;
import edu.harvard.iq.dataverse.ingest.IngestRequest;
Expand Down Expand Up @@ -242,6 +244,8 @@ public enum DisplayMode {
SolrClientService solrClientService;
@EJB
DvObjectServiceBean dvObjectService;
@EJB
CacheFactoryBean cacheFactory;
@Inject
DataverseRequestServiceBean dvRequestService;
@Inject
Expand Down Expand Up @@ -1930,7 +1934,10 @@ private void setIdByPersistentId() {
}

private String init(boolean initFull) {

// Check for rate limit exceeded. Must be done before anything else to prevent unnecessary processing.
if (!cacheFactory.checkRate(session.getUser(), new CheckRateLimitForDatasetPage(null,null))) {
return BundleUtil.getStringFromBundle("command.exception.user.ratelimited", Arrays.asList(CheckRateLimitForDatasetPage.class.getSimpleName()));
}
//System.out.println("_YE_OLDE_QUERY_COUNTER_"); // for debug purposes
setDataverseSiteUrl(systemConfig.getDataverseSiteUrl());

Expand Down
10 changes: 9 additions & 1 deletion src/main/java/edu/harvard/iq/dataverse/DataversePage.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import edu.harvard.iq.dataverse.dataverse.DataverseUtil;
import edu.harvard.iq.dataverse.engine.command.Command;
import edu.harvard.iq.dataverse.engine.command.exception.CommandException;
import edu.harvard.iq.dataverse.engine.command.impl.CheckRateLimitForCollectionPage;
import edu.harvard.iq.dataverse.engine.command.impl.CreateDataverseCommand;
import edu.harvard.iq.dataverse.engine.command.impl.CreateSavedSearchCommand;
import edu.harvard.iq.dataverse.engine.command.impl.DeleteDataverseCommand;
Expand All @@ -31,6 +32,8 @@
import static edu.harvard.iq.dataverse.util.JsfHelper.JH;
import edu.harvard.iq.dataverse.util.SystemConfig;
import java.util.List;

import edu.harvard.iq.dataverse.util.cache.CacheFactoryBean;
import jakarta.ejb.EJB;
import jakarta.faces.application.FacesMessage;
import jakarta.faces.context.FacesContext;
Expand Down Expand Up @@ -118,6 +121,8 @@ public enum LinkMode {
@Inject DataverseHeaderFragment dataverseHeaderFragment;
@EJB
PidProviderFactoryBean pidProviderFactoryBean;
@EJB
CacheFactoryBean cacheFactory;

private Dataverse dataverse = new Dataverse();

Expand Down Expand Up @@ -318,7 +323,10 @@ public void updateOwnerDataverse() {

public String init() {
//System.out.println("_YE_OLDE_QUERY_COUNTER_"); // for debug purposes

// Check for rate limit exceeded. Must be done before anything else to prevent unnecessary processing.
if (!cacheFactory.checkRate(session.getUser(), new CheckRateLimitForCollectionPage(null,null))) {
return BundleUtil.getStringFromBundle("command.exception.user.ratelimited", Arrays.asList(CheckRateLimitForCollectionPage.class.getSimpleName()));
}
if (this.getAlias() != null || this.getId() != null || this.getOwnerId() == null) {// view mode for a dataverse
if (this.getAlias() != null) {
dataverse = dataverseService.findByAlias(this.getAlias());
Expand Down
12 changes: 10 additions & 2 deletions src/main/java/edu/harvard/iq/dataverse/EjbDataverseEngine.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import edu.harvard.iq.dataverse.actionlogging.ActionLogServiceBean;
import edu.harvard.iq.dataverse.authorization.AuthenticationServiceBean;
import edu.harvard.iq.dataverse.authorization.providers.builtin.BuiltinUserServiceBean;
import edu.harvard.iq.dataverse.util.cache.CacheFactoryBean;
import edu.harvard.iq.dataverse.engine.DataverseEngine;
import edu.harvard.iq.dataverse.authorization.Permission;
import edu.harvard.iq.dataverse.authorization.groups.GroupServiceBean;
Expand All @@ -16,6 +17,7 @@
import edu.harvard.iq.dataverse.engine.command.DataverseRequest;
import edu.harvard.iq.dataverse.engine.command.exception.CommandException;
import edu.harvard.iq.dataverse.engine.command.exception.PermissionException;
import edu.harvard.iq.dataverse.engine.command.exception.RateLimitCommandException;
import edu.harvard.iq.dataverse.ingest.IngestServiceBean;
import edu.harvard.iq.dataverse.pidproviders.PidProviderFactoryBean;
import edu.harvard.iq.dataverse.privateurl.PrivateUrlServiceBean;
Expand Down Expand Up @@ -176,7 +178,9 @@ public class EjbDataverseEngine {

@EJB
EjbDataverseEngineInner innerEngine;


@EJB
CacheFactoryBean cacheFactory;

@Resource
EJBContext ejbCtxt;
Expand All @@ -202,7 +206,11 @@ public <R> R submit(Command<R> aCommand) throws CommandException {

try {
logRec.setUserIdentifier( aCommand.getRequest().getUser().getIdentifier() );

// Check for rate limit exceeded. Must be done before anything else to prevent unnecessary processing.
if (!cacheFactory.checkRate(aCommand.getRequest().getUser(), aCommand)) {
throw new RateLimitCommandException(BundleUtil.getStringFromBundle("command.exception.user.ratelimited", Arrays.asList(aCommand.getClass().getSimpleName())), aCommand);
stevenwinship marked this conversation as resolved.
Show resolved Hide resolved
}

// Check permissions - or throw an exception
Map<String, ? extends Set<Permission>> requiredMap = aCommand.getRequiredPermissions();
if (requiredMap == null) {
Expand Down
4 changes: 3 additions & 1 deletion src/main/java/edu/harvard/iq/dataverse/UserServiceBean.java
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,8 @@ private AuthenticatedUser createAuthenticatedUserForView (Object[] dbRowValues,
user.setMutedEmails(Type.tokenizeToSet((String) dbRowValues[15]));
user.setMutedNotifications(Type.tokenizeToSet((String) dbRowValues[15]));

user.setRateLimitTier((int)dbRowValues[17]);

user.setRoles(roles);
return user;
}
Expand Down Expand Up @@ -419,7 +421,7 @@ private List<Object[]> getUserListCore(String searchTerm,
qstr += " u.createdtime, u.lastlogintime, u.lastapiusetime, ";
qstr += " prov.id, prov.factoryalias, ";
qstr += " u.deactivated, u.deactivatedtime, ";
qstr += " u.mutedEmails, u.mutedNotifications ";
qstr += " u.mutedEmails, u.mutedNotifications, u.rateLimitTier ";
qstr += " FROM authenticateduser u,";
qstr += " authenticateduserlookup prov_lookup,";
qstr += " authenticationproviderrow prov";
Expand Down
13 changes: 10 additions & 3 deletions src/main/java/edu/harvard/iq/dataverse/api/AbstractApiBean.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import edu.harvard.iq.dataverse.engine.command.impl.GetLatestAccessibleDatasetVersionCommand;
import edu.harvard.iq.dataverse.engine.command.impl.GetLatestPublishedDatasetVersionCommand;
import edu.harvard.iq.dataverse.engine.command.impl.GetSpecificPublishedDatasetVersionCommand;
import edu.harvard.iq.dataverse.engine.command.exception.RateLimitCommandException;
import edu.harvard.iq.dataverse.externaltools.ExternalToolServiceBean;
import edu.harvard.iq.dataverse.license.LicenseServiceBean;
import edu.harvard.iq.dataverse.locality.StorageSiteServiceBean;
Expand Down Expand Up @@ -421,7 +422,7 @@ public Command<DatasetVersion> handleLatestPublished() {
}));
return dsv;
}

protected DataFile findDataFileOrDie(String id) throws WrappedResponse {
DataFile datafile;
if (id.equals(PERSISTENT_ID_KEY)) {
Expand Down Expand Up @@ -575,6 +576,8 @@ protected <T> T execCommand( Command<T> cmd ) throws WrappedResponse {
try {
return engineSvc.submit(cmd);

} catch (RateLimitCommandException ex) {
throw new WrappedResponse(rateLimited(ex.getMessage()));
} catch (IllegalCommandException ex) {
//for 8859 for api calls that try to update datasets with TOA out of compliance
if (ex.getMessage().toLowerCase().contains("terms of use")){
Expand Down Expand Up @@ -776,11 +779,15 @@ protected Response notFound( String msg ) {
protected Response badRequest( String msg ) {
return error( Status.BAD_REQUEST, msg );
}

protected Response forbidden( String msg ) {
return error( Status.FORBIDDEN, msg );
}


protected Response rateLimited( String msg ) {
return error( Status.TOO_MANY_REQUESTS, msg );
}

protected Response conflict( String msg ) {
return error( Status.CONFLICT, msg );
}
Expand Down
Loading
Loading