mirror of
https://github.com/HeyPuter/puter
synced 2024-11-14 22:06:00 +00:00
feat: rate-limit for excessive groups
This commit is contained in:
parent
0855f2b36e
commit
4af279a72f
@ -295,6 +295,9 @@ const install = async ({ services, app, useapi }) => {
|
||||
|
||||
const { MountpointService } = require('./services/MountpointService');
|
||||
services.registerService('mountpoint', MountpointService);
|
||||
|
||||
const { AnomalyService } = require('./services/AnomalyService');
|
||||
services.registerService('anomaly', AnomalyService);
|
||||
}
|
||||
|
||||
const install_legacy = async ({ services }) => {
|
||||
|
35
packages/backend/src/services/AnomalyService.js
Normal file
35
packages/backend/src/services/AnomalyService.js
Normal file
@ -0,0 +1,35 @@
|
||||
const BaseService = require("./BaseService");
|
||||
|
||||
const DENY_SERVICE_INSTRUCTION = Symbol('DENY_SERVICE_INSTRUCTION');
|
||||
|
||||
class AnomalyService extends BaseService {
|
||||
_construct () {
|
||||
this.types = {};
|
||||
}
|
||||
register (type, config) {
|
||||
const type_instance = {
|
||||
config,
|
||||
}
|
||||
if ( config.handler ) {
|
||||
type_instance.handler = config.handler;
|
||||
} else if ( config.high ) {
|
||||
type_instance.handler = data => {
|
||||
if ( data.value > config.high ) {
|
||||
return new Set([DENY_SERVICE_INSTRUCTION]);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.types[type] = type_instance;
|
||||
}
|
||||
async note (id, data) {
|
||||
const type = this.types[id];
|
||||
if ( ! type ) return;
|
||||
|
||||
return type.handler(data);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
AnomalyService,
|
||||
DENY_SERVICE_INSTRUCTION,
|
||||
};
|
@ -1,4 +1,6 @@
|
||||
const APIError = require("../../api/APIError");
|
||||
const Group = require("../../entities/Group");
|
||||
const { DENY_SERVICE_INSTRUCTION } = require("../AnomalyService");
|
||||
const BaseService = require("../BaseService");
|
||||
const { DB_WRITE } = require("../database/consts");
|
||||
|
||||
@ -9,6 +11,11 @@ class GroupService extends BaseService {
|
||||
|
||||
_init () {
|
||||
this.db = this.services.get('database').get(DB_WRITE, 'permissions');
|
||||
|
||||
const svc_anomaly = this.services.get('anomaly');
|
||||
svc_anomaly.register('groups-user-hour', {
|
||||
high: 20,
|
||||
});
|
||||
}
|
||||
|
||||
async get({ uid }) {
|
||||
@ -31,7 +38,24 @@ class GroupService extends BaseService {
|
||||
metadata = metadata ?? {};
|
||||
|
||||
const uid = this.modules.uuidv4();
|
||||
|
||||
|
||||
const [{ n_groups }] = await this.db.read(
|
||||
"SELECT COUNT(*) AS n_groups FROM `group` WHERE " +
|
||||
"owner_user_id=? AND " +
|
||||
"created_at >= datetime('now', '-1 hour')",
|
||||
[owner_user_id]
|
||||
);
|
||||
|
||||
const svc_anomaly = this.services.get('anomaly');
|
||||
const anomaly = await svc_anomaly.note('groups-user-hour', {
|
||||
value: n_groups,
|
||||
user_id: owner_user_id,
|
||||
});
|
||||
|
||||
if ( anomaly && anomaly.has(DENY_SERVICE_INSTRUCTION) ) {
|
||||
throw APIError.create('too_many_requests');
|
||||
}
|
||||
|
||||
await this.db.write(
|
||||
'INSERT INTO `group` ' +
|
||||
'(`uid`, `owner_user_id`, `extra`, `metadata`) ' +
|
||||
|
Loading…
Reference in New Issue
Block a user