mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-14 20:40:17 -05:00
Merge pull request #21327 from overleaf/msm-optional-subnet-rate-limiter
[web] Add option to disable subnet rate limiting (+CE/SP Hotfix `5.2.1`) GitOrigin-RevId: 78d60c9638cede729dd93c3c2421f55b34c0dbfe
This commit is contained in:
parent
25f4e6cf67
commit
27c2e8b938
6 changed files with 81 additions and 1 deletions
|
@ -212,6 +212,11 @@ const settings = {
|
||||||
enabled: process.env.OVERLEAF_CSP_ENABLED !== 'false',
|
enabled: process.env.OVERLEAF_CSP_ENABLED !== 'false',
|
||||||
},
|
},
|
||||||
|
|
||||||
|
rateLimit: {
|
||||||
|
subnetRateLimiterDisabled:
|
||||||
|
process.env.SUBNET_RATE_LIMITER_DISABLED !== 'false',
|
||||||
|
},
|
||||||
|
|
||||||
// These credentials are used for authenticating api requests
|
// These credentials are used for authenticating api requests
|
||||||
// between services that may need to go over public channels
|
// between services that may need to go over public channels
|
||||||
httpAuthUsers,
|
httpAuthUsers,
|
||||||
|
|
5
server-ce/hotfix/5.2.1/Dockerfile
Normal file
5
server-ce/hotfix/5.2.1/Dockerfile
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
FROM sharelatex/sharelatex:5.2.0
|
||||||
|
|
||||||
|
# Subnet rate limiter fix
|
||||||
|
COPY pr_21327.patch /
|
||||||
|
RUN cd / && patch -p0 < pr_21327.patch && rm pr_21327.patch
|
36
server-ce/hotfix/5.2.1/pr_21327.patch
Normal file
36
server-ce/hotfix/5.2.1/pr_21327.patch
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
--- overleaf/services/web/app/src/infrastructure/RateLimiter.js
|
||||||
|
+++ overleaf/services/web/app/src/infrastructure/RateLimiter.js
|
||||||
|
@@ -39,7 +39,7 @@ class RateLimiter {
|
||||||
|
keyPrefix: `rate-limit:${name}`,
|
||||||
|
storeClient: rclient,
|
||||||
|
})
|
||||||
|
- if (opts.subnetPoints) {
|
||||||
|
+ if (opts.subnetPoints && !Settings.rateLimit?.subnetRateLimiterDisabled) {
|
||||||
|
this._subnetRateLimiter = new RateLimiterFlexible.RateLimiterRedis({
|
||||||
|
...opts,
|
||||||
|
points: opts.subnetPoints,
|
||||||
|
--- overleaf/services/web/config/settings.defaults.js
|
||||||
|
+++ overleaf/services/web/config/settings.defaults.js
|
||||||
|
@@ -777,6 +777,8 @@ module.exports = {
|
||||||
|
reloadModuleViewsOnEachRequest: process.env.NODE_ENV === 'development',
|
||||||
|
|
||||||
|
rateLimit: {
|
||||||
|
+ subnetRateLimiterDisabled:
|
||||||
|
+ process.env.SUBNET_RATE_LIMITER_DISABLED === 'true',
|
||||||
|
autoCompile: {
|
||||||
|
everyone: process.env.RATE_LIMIT_AUTO_COMPILE_EVERYONE || 100,
|
||||||
|
standard: process.env.RATE_LIMIT_AUTO_COMPILE_STANDARD || 25,
|
||||||
|
--- etc/overleaf/settings.js
|
||||||
|
+++ etc/overleaf/settings.js
|
||||||
|
@@ -212,6 +212,11 @@ const settings = {
|
||||||
|
enabled: process.env.OVERLEAF_CSP_ENABLED !== 'false',
|
||||||
|
},
|
||||||
|
|
||||||
|
+ rateLimit: {
|
||||||
|
+ subnetRateLimiterDisabled:
|
||||||
|
+ process.env.SUBNET_RATE_LIMITER_DISABLED !== 'false',
|
||||||
|
+ },
|
||||||
|
+
|
||||||
|
// These credentials are used for authenticating api requests
|
||||||
|
// between services that may need to go over public channels
|
||||||
|
httpAuthUsers,
|
|
@ -39,7 +39,7 @@ class RateLimiter {
|
||||||
keyPrefix: `rate-limit:${name}`,
|
keyPrefix: `rate-limit:${name}`,
|
||||||
storeClient: rclient,
|
storeClient: rclient,
|
||||||
})
|
})
|
||||||
if (opts.subnetPoints) {
|
if (opts.subnetPoints && !Settings.rateLimit?.subnetRateLimiterDisabled) {
|
||||||
this._subnetRateLimiter = new RateLimiterFlexible.RateLimiterRedis({
|
this._subnetRateLimiter = new RateLimiterFlexible.RateLimiterRedis({
|
||||||
...opts,
|
...opts,
|
||||||
points: opts.subnetPoints,
|
points: opts.subnetPoints,
|
||||||
|
|
|
@ -777,6 +777,8 @@ module.exports = {
|
||||||
reloadModuleViewsOnEachRequest: process.env.NODE_ENV === 'development',
|
reloadModuleViewsOnEachRequest: process.env.NODE_ENV === 'development',
|
||||||
|
|
||||||
rateLimit: {
|
rateLimit: {
|
||||||
|
subnetRateLimiterDisabled:
|
||||||
|
process.env.SUBNET_RATE_LIMITER_DISABLED === 'true',
|
||||||
autoCompile: {
|
autoCompile: {
|
||||||
everyone: process.env.RATE_LIMIT_AUTO_COMPILE_EVERYONE || 100,
|
everyone: process.env.RATE_LIMIT_AUTO_COMPILE_EVERYONE || 100,
|
||||||
standard: process.env.RATE_LIMIT_AUTO_COMPILE_STANDARD || 25,
|
standard: process.env.RATE_LIMIT_AUTO_COMPILE_STANDARD || 25,
|
||||||
|
|
|
@ -19,11 +19,13 @@ describe('RateLimiter', function () {
|
||||||
this.RateLimiterFlexible = {
|
this.RateLimiterFlexible = {
|
||||||
RateLimiterRedis: sinon.stub(),
|
RateLimiterRedis: sinon.stub(),
|
||||||
}
|
}
|
||||||
|
this.Settings = {}
|
||||||
|
|
||||||
this.RateLimiter = SandboxedModule.require(modulePath, {
|
this.RateLimiter = SandboxedModule.require(modulePath, {
|
||||||
requires: {
|
requires: {
|
||||||
'./RedisWrapper': this.RedisWrapper,
|
'./RedisWrapper': this.RedisWrapper,
|
||||||
'rate-limiter-flexible': this.RateLimiterFlexible,
|
'rate-limiter-flexible': this.RateLimiterFlexible,
|
||||||
|
'@overleaf/settings': this.Settings,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -60,4 +62,34 @@ describe('RateLimiter', function () {
|
||||||
).to.throw()
|
).to.throw()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('_subnetRateLimiter', function () {
|
||||||
|
it('should be defined by default', function () {
|
||||||
|
const rateLimiter = new this.RateLimiter.RateLimiter('some-limit', {
|
||||||
|
points: 20,
|
||||||
|
subnetPoints: 200,
|
||||||
|
duration: 60,
|
||||||
|
})
|
||||||
|
expect(rateLimiter._subnetRateLimiter).not.to.be.undefined
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should be undefined when subnet rate limiting is disabled', function () {
|
||||||
|
this.Settings.rateLimit = { subnetRateLimiterDisabled: true }
|
||||||
|
|
||||||
|
const rateLimiter = new this.RateLimiter.RateLimiter('some-limit', {
|
||||||
|
points: 20,
|
||||||
|
subnetPoints: 200,
|
||||||
|
duration: 60,
|
||||||
|
})
|
||||||
|
expect(rateLimiter._subnetRateLimiter).to.be.undefined
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should be undefined when subnetPoints are not passed as an option', function () {
|
||||||
|
const rateLimiter = new this.RateLimiter.RateLimiter('some-limit', {
|
||||||
|
points: 20,
|
||||||
|
duration: 60,
|
||||||
|
})
|
||||||
|
expect(rateLimiter._subnetRateLimiter).to.be.undefined
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in a new issue