Automatically clean failed login attempts
This commit is contained in:
		@@ -1,7 +1,9 @@
 | 
			
		||||
use std::collections::HashMap;
 | 
			
		||||
use std::net::IpAddr;
 | 
			
		||||
 | 
			
		||||
use crate::constants::KEEP_FAILED_LOGIN_ATTEMPTS_FOR;
 | 
			
		||||
use actix::{Actor, AsyncContext, Context};
 | 
			
		||||
 | 
			
		||||
use crate::constants::{FAIL_LOGIN_ATTEMPT_CLEANUP_INTERVAL, KEEP_FAILED_LOGIN_ATTEMPTS_FOR};
 | 
			
		||||
use crate::utils::time::time;
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Default)]
 | 
			
		||||
@@ -41,6 +43,18 @@ impl BruteForceActor {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Actor for BruteForceActor {
 | 
			
		||||
    type Context = Context<Self>;
 | 
			
		||||
 | 
			
		||||
    fn started(&mut self, ctx: &mut Self::Context) {
 | 
			
		||||
        // Clean up at a regular interval failed attempts
 | 
			
		||||
        ctx.run_interval(FAIL_LOGIN_ATTEMPT_CLEANUP_INTERVAL, |act, _ctx| {
 | 
			
		||||
            log::trace!("Cleaning up failed login attempts");
 | 
			
		||||
            act.clean_attempts();
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[cfg(test)]
 | 
			
		||||
mod test {
 | 
			
		||||
    use std::net::{IpAddr, Ipv4Addr};
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,5 @@
 | 
			
		||||
use std::time::Duration;
 | 
			
		||||
 | 
			
		||||
/// File in storage containing users list
 | 
			
		||||
pub const USERS_LIST_FILE: &str = "users.json";
 | 
			
		||||
 | 
			
		||||
@@ -32,3 +34,4 @@ pub const LOGIN_ROUTE: &str = "/login";
 | 
			
		||||
/// Bruteforce protection
 | 
			
		||||
pub const KEEP_FAILED_LOGIN_ATTEMPTS_FOR: u64 = 3600;
 | 
			
		||||
pub const MAX_FAILED_LOGIN_ATTEMPTS: u64 = 15;
 | 
			
		||||
pub const FAIL_LOGIN_ATTEMPT_CLEANUP_INTERVAL: Duration = Duration::from_secs(60);
 | 
			
		||||
@@ -1,11 +1,12 @@
 | 
			
		||||
use actix::Actor;
 | 
			
		||||
use actix_identity::{CookieIdentityPolicy, IdentityService};
 | 
			
		||||
use actix_web::cookie::time::Duration;
 | 
			
		||||
use actix_web::{App, get, HttpServer, web};
 | 
			
		||||
use actix_web::cookie::SameSite;
 | 
			
		||||
use actix_web::cookie::time::Duration;
 | 
			
		||||
use actix_web::middleware::Logger;
 | 
			
		||||
use actix_web::{get, web, App, HttpServer};
 | 
			
		||||
use clap::Parser;
 | 
			
		||||
 | 
			
		||||
use basic_oidc::actors::bruteforce_actor::BruteForceActor;
 | 
			
		||||
use basic_oidc::actors::users_actor::UsersActor;
 | 
			
		||||
use basic_oidc::constants::{
 | 
			
		||||
    DEFAULT_ADMIN_PASSWORD, DEFAULT_ADMIN_USERNAME, MAX_INACTIVITY_DURATION, MAX_SESSION_DURATION,
 | 
			
		||||
@@ -63,6 +64,7 @@ async fn main() -> std::io::Result<()> {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let users_actor = UsersActor::new(users).start();
 | 
			
		||||
    let bruteforce_actor = BruteForceActor::default().start();
 | 
			
		||||
 | 
			
		||||
    log::info!("Server will listen on {}", config.listen_address);
 | 
			
		||||
    let listen_address = config.listen_address.to_string();
 | 
			
		||||
@@ -77,6 +79,7 @@ async fn main() -> std::io::Result<()> {
 | 
			
		||||
 | 
			
		||||
        App::new()
 | 
			
		||||
            .app_data(web::Data::new(users_actor.clone()))
 | 
			
		||||
            .app_data(web::Data::new(bruteforce_actor.clone()))
 | 
			
		||||
            .app_data(web::Data::new(config.clone()))
 | 
			
		||||
            .wrap(Logger::default())
 | 
			
		||||
            .wrap(AuthMiddleware {})
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user