From 35dfe31a391fa11c8920c2e1a2e3289f2e61cc9c Mon Sep 17 00:00:00 2001 From: Dessalines Date: Sun, 13 Oct 2019 12:06:18 -0700 Subject: [PATCH] Externalizing rate limits. Upgrading to Rust 1.38 - Fixes #290 --- docker/dev/.env | 6 ++++++ docker/dev/Dockerfile | 2 +- docker/dev/docker-compose.yml | 6 ++++++ docker/prod/.env | 6 ++++++ docker/prod/docker-compose.yml | 6 ++++++ server/src/api/site.rs | 4 ++-- server/src/lib.rs | 34 ++++++++++++++++++++++++++++++++-- server/src/websocket/server.rs | 26 ++++++++++++++++---------- 8 files changed, 75 insertions(+), 15 deletions(-) diff --git a/docker/dev/.env b/docker/dev/.env index f82502d7f..cca4deae7 100644 --- a/docker/dev/.env +++ b/docker/dev/.env @@ -2,3 +2,9 @@ DOMAIN=my_domain DATABASE_PASSWORD=password DATABASE_URL=postgres://lemmy:password@lemmy_db:5432/lemmy JWT_SECRET=changeme +RATE_LIMIT_MESSAGE=30 +RATE_LIMIT_MESSAGE_PER_SECOND=60 +RATE_LIMIT_POST=3 +RATE_LIMIT_POST_PER_SECOND=600 +RATE_LIMIT_REGISTER=1 +RATE_LIMIT_REGISTER_PER_SECOND=3600 diff --git a/docker/dev/Dockerfile b/docker/dev/Dockerfile index 69ef3aae0..5d25e48bd 100644 --- a/docker/dev/Dockerfile +++ b/docker/dev/Dockerfile @@ -10,7 +10,7 @@ RUN yarn install --pure-lockfile COPY ui /app/ui RUN yarn build -FROM rust:1.37 as rust +FROM rust:1.38 as rust # Install musl RUN apt-get update diff --git a/docker/dev/docker-compose.yml b/docker/dev/docker-compose.yml index 2fb039650..68bb9282f 100644 --- a/docker/dev/docker-compose.yml +++ b/docker/dev/docker-compose.yml @@ -20,6 +20,12 @@ services: - DATABASE_URL=${DATABASE_URL} - JWT_SECRET=${JWT_SECRET} - HOSTNAME=${DOMAIN} + - RATE_LIMIT_MESSAGE=${RATE_LIMIT_MESSAGE} + - RATE_LIMIT_MESSAGE_PER_SECOND=${RATE_LIMIT_MESSAGE_PER_SECOND} + - RATE_LIMIT_POST=${RATE_LIMIT_POST} + - RATE_LIMIT_POST_PER_SECOND=${RATE_LIMIT_POST_PER_SECOND} + - RATE_LIMIT_REGISTER=${RATE_LIMIT_REGISTER} + - RATE_LIMIT_REGISTER_PER_SECOND=${RATE_LIMIT_REGISTER_PER_SECOND} restart: always depends_on: - lemmy_db diff --git a/docker/prod/.env b/docker/prod/.env index f82502d7f..cca4deae7 100644 --- a/docker/prod/.env +++ b/docker/prod/.env @@ -2,3 +2,9 @@ DOMAIN=my_domain DATABASE_PASSWORD=password DATABASE_URL=postgres://lemmy:password@lemmy_db:5432/lemmy JWT_SECRET=changeme +RATE_LIMIT_MESSAGE=30 +RATE_LIMIT_MESSAGE_PER_SECOND=60 +RATE_LIMIT_POST=3 +RATE_LIMIT_POST_PER_SECOND=600 +RATE_LIMIT_REGISTER=1 +RATE_LIMIT_REGISTER_PER_SECOND=3600 diff --git a/docker/prod/docker-compose.yml b/docker/prod/docker-compose.yml index bb8245e62..aeaded11f 100644 --- a/docker/prod/docker-compose.yml +++ b/docker/prod/docker-compose.yml @@ -18,6 +18,12 @@ services: - DATABASE_URL=${DATABASE_URL} - JWT_SECRET=${JWT_SECRET} - HOSTNAME=${DOMAIN} + - RATE_LIMIT_MESSAGE=${RATE_LIMIT_MESSAGE} + - RATE_LIMIT_MESSAGE_PER_SECOND=${RATE_LIMIT_MESSAGE_PER_SECOND} + - RATE_LIMIT_POST=${RATE_LIMIT_POST} + - RATE_LIMIT_POST_PER_SECOND=${RATE_LIMIT_POST_PER_SECOND} + - RATE_LIMIT_REGISTER=${RATE_LIMIT_REGISTER} + - RATE_LIMIT_REGISTER_PER_SECOND=${RATE_LIMIT_REGISTER_PER_SECOND} restart: always depends_on: - lemmy_db diff --git a/server/src/api/site.rs b/server/src/api/site.rs index 912378ab3..40b1592dd 100644 --- a/server/src/api/site.rs +++ b/server/src/api/site.rs @@ -297,7 +297,7 @@ impl Perform for Oper { site: site_view, admins: admins, banned: banned, - online: 0 + online: 0, }) } } @@ -488,7 +488,7 @@ impl Perform for Oper { site: Some(site_view), admins: admins, banned: banned, - online: 0 + online: 0, }) } } diff --git a/server/src/lib.rs b/server/src/lib.rs index 0ff34d4ce..d75a0d18e 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -34,6 +34,12 @@ pub struct Settings { db_url: String, hostname: String, jwt_secret: String, + rate_limit_message: i32, + rate_limit_message_per_second: i32, + rate_limit_post: i32, + rate_limit_post_per_second: i32, + rate_limit_register: i32, + rate_limit_register_per_second: i32, } impl Settings { @@ -43,6 +49,30 @@ impl Settings { db_url: env::var("DATABASE_URL").expect("DATABASE_URL must be set"), hostname: env::var("HOSTNAME").unwrap_or("rrr".to_string()), jwt_secret: env::var("JWT_SECRET").unwrap_or("changeme".to_string()), + rate_limit_message: env::var("RATE_LIMIT_MESSAGE") + .unwrap_or("30".to_string()) + .parse() + .unwrap(), + rate_limit_message_per_second: env::var("RATE_LIMIT_MESSAGE_PER_SECOND") + .unwrap_or("60".to_string()) + .parse() + .unwrap(), + rate_limit_post: env::var("RATE_LIMIT_POST") + .unwrap_or("3".to_string()) + .parse() + .unwrap(), + rate_limit_post_per_second: env::var("RATE_LIMIT_POST_PER_SECOND") + .unwrap_or("600".to_string()) + .parse() + .unwrap(), + rate_limit_register: env::var("RATE_LIMIT_REGISTER") + .unwrap_or("1".to_string()) + .parse() + .unwrap(), + rate_limit_register_per_second: env::var("RATE_LIMIT_REGISTER_PER_SECOND") + .unwrap_or("3600".to_string()) + .parse() + .unwrap(), } } fn api_endpoint(&self) -> String { @@ -90,7 +120,8 @@ mod tests { #[test] fn test_slur_filter() { - let test = "coons test dindu ladyboy tranny retardeds. This is a bunch of other safe text.".to_string(); + let test = + "coons test dindu ladyboy tranny retardeds. This is a bunch of other safe text.".to_string(); let slur_free = "No slurs here"; assert_eq!( remove_slurs(&test), @@ -100,7 +131,6 @@ mod tests { assert!(has_slurs(&test)); assert!(!has_slurs(slur_free)); } - } lazy_static! { diff --git a/server/src/websocket/server.rs b/server/src/websocket/server.rs index 41bb10581..85de7eeab 100644 --- a/server/src/websocket/server.rs +++ b/server/src/websocket/server.rs @@ -17,13 +17,7 @@ use crate::api::post::*; use crate::api::site::*; use crate::api::user::*; use crate::api::*; - -const RATE_LIMIT_MESSAGE: i32 = 30; -const RATE_LIMIT_MESSAGES_PER_SECOND: i32 = 60; -const RATE_LIMIT_POST: i32 = 3; -const RATE_LIMIT_POSTS_PER_SECOND: i32 = 60 * 10; -const RATE_LIMIT_REGISTER: i32 = 1; -const RATE_LIMIT_REGISTER_PER_SECOND: i32 = 60 * 60; +use crate::Settings; /// Chat server sends this messages to session #[derive(Message)] @@ -163,15 +157,27 @@ impl ChatServer { } fn check_rate_limit_register(&mut self, id: usize) -> Result<(), Error> { - self.check_rate_limit_full(id, RATE_LIMIT_REGISTER, RATE_LIMIT_REGISTER_PER_SECOND) + self.check_rate_limit_full( + id, + Settings::get().rate_limit_register, + Settings::get().rate_limit_register_per_second, + ) } fn check_rate_limit_post(&mut self, id: usize) -> Result<(), Error> { - self.check_rate_limit_full(id, RATE_LIMIT_POST, RATE_LIMIT_POSTS_PER_SECOND) + self.check_rate_limit_full( + id, + Settings::get().rate_limit_post, + Settings::get().rate_limit_post_per_second, + ) } fn check_rate_limit_message(&mut self, id: usize) -> Result<(), Error> { - self.check_rate_limit_full(id, RATE_LIMIT_MESSAGE, RATE_LIMIT_MESSAGES_PER_SECOND) + self.check_rate_limit_full( + id, + Settings::get().rate_limit_message, + Settings::get().rate_limit_message_per_second, + ) } fn check_rate_limit_full(&mut self, id: usize, rate: i32, per: i32) -> Result<(), Error> {