From b77e7895b7195e038ecd23e7e8a97fcf156aefc6 Mon Sep 17 00:00:00 2001 From: Pierre HUBERT Date: Fri, 28 Mar 2025 14:40:35 +0100 Subject: [PATCH] Rust Edition 2024 --- Cargo.lock | 2 +- Cargo.toml | 4 +- src/actors/bruteforce_actor.rs | 2 +- src/actors/providers_states_actor.rs | 2 +- src/controllers/admin_api.rs | 2 +- src/controllers/admin_controller.rs | 2 +- src/controllers/assets_controller.rs | 4 +- src/controllers/login_api.rs | 2 +- src/controllers/login_controller.rs | 9 ++- src/controllers/openid_controller.rs | 6 +- src/controllers/providers_controller.rs | 2 +- src/controllers/settings_controller.rs | 2 +- src/controllers/two_factor_api.rs | 2 +- src/controllers/two_factors_controller.rs | 2 +- src/data/action_logger.rs | 80 ++++++++++++++++------- src/data/code_challenge.rs | 2 +- src/data/critical_route.rs | 2 +- src/data/current_user.rs | 2 +- src/data/entity_manager.rs | 5 +- src/data/force_2fa_auth.rs | 2 +- src/data/jwt_signer.rs | 4 +- src/data/provider_configuration.rs | 4 +- src/data/totp_key.rs | 4 +- src/data/users_file_entity.rs | 2 +- src/main.rs | 6 +- src/middlewares/auth_middleware.rs | 6 +- 26 files changed, 102 insertions(+), 60 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5c25d45..92f0fe6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -585,7 +585,7 @@ dependencies = [ [[package]] name = "basic-oidc" -version = "0.1.4" +version = "0.1.5" dependencies = [ "actix", "actix-identity", diff --git a/Cargo.toml b/Cargo.toml index d65e316..a9868e0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "basic-oidc" -version = "0.1.4" -edition = "2021" +version = "0.1.5" +edition = "2024" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/src/actors/bruteforce_actor.rs b/src/actors/bruteforce_actor.rs index 451467a..914922b 100644 --- a/src/actors/bruteforce_actor.rs +++ b/src/actors/bruteforce_actor.rs @@ -1,5 +1,5 @@ -use std::collections::hash_map::Entry; use std::collections::HashMap; +use std::collections::hash_map::Entry; use std::net::IpAddr; use actix::{Actor, AsyncContext, Context, Handler, Message}; diff --git a/src/actors/providers_states_actor.rs b/src/actors/providers_states_actor.rs index 41cd642..fd3e644 100644 --- a/src/actors/providers_states_actor.rs +++ b/src/actors/providers_states_actor.rs @@ -8,8 +8,8 @@ use crate::constants::{ OIDC_STATES_CLEANUP_INTERVAL, }; use actix::{Actor, AsyncContext, Context, Handler, Message}; -use std::collections::hash_map::Entry; use std::collections::HashMap; +use std::collections::hash_map::Entry; use std::net::IpAddr; use crate::data::login_redirect::LoginRedirect; diff --git a/src/controllers/admin_api.rs b/src/controllers/admin_api.rs index 0f6d9ea..319af7d 100644 --- a/src/controllers/admin_api.rs +++ b/src/controllers/admin_api.rs @@ -1,6 +1,6 @@ use crate::actors::users_actor; use actix::Addr; -use actix_web::{web, HttpResponse, Responder}; +use actix_web::{HttpResponse, Responder, web}; use crate::actors::users_actor::{DeleteUserRequest, FindUserByUsername, UsersActor}; use crate::data::action_logger::{Action, ActionLogger}; diff --git a/src/controllers/admin_controller.rs b/src/controllers/admin_controller.rs index 57904bf..d59fbcf 100644 --- a/src/controllers/admin_controller.rs +++ b/src/controllers/admin_controller.rs @@ -2,7 +2,7 @@ use std::ops::Deref; use std::sync::Arc; use actix::Addr; -use actix_web::{web, HttpResponse, Responder}; +use actix_web::{HttpResponse, Responder, web}; use askama::Template; use crate::actors::users_actor; diff --git a/src/controllers/assets_controller.rs b/src/controllers/assets_controller.rs index b300b2b..b07da33 100644 --- a/src/controllers/assets_controller.rs +++ b/src/controllers/assets_controller.rs @@ -1,7 +1,7 @@ use std::path::Path; -use actix_web::{web, HttpResponse}; -use include_dir::{include_dir, Dir}; +use actix_web::{HttpResponse, web}; +use include_dir::{Dir, include_dir}; /// Assets directory static ASSETS_DIR: Dir = include_dir!("$CARGO_MANIFEST_DIR/assets"); diff --git a/src/controllers/login_api.rs b/src/controllers/login_api.rs index bc016d2..e178813 100644 --- a/src/controllers/login_api.rs +++ b/src/controllers/login_api.rs @@ -4,7 +4,7 @@ use crate::data::action_logger::{Action, ActionLogger}; use actix::Addr; use actix_identity::Identity; use actix_remote_ip::RemoteIP; -use actix_web::{web, HttpRequest, HttpResponse, Responder}; +use actix_web::{HttpRequest, HttpResponse, Responder, web}; use webauthn_rs::prelude::PublicKeyCredential; use crate::data::session_identity::{SessionIdentity, SessionStatus}; diff --git a/src/controllers/login_controller.rs b/src/controllers/login_controller.rs index 06e7496..3a35eb2 100644 --- a/src/controllers/login_controller.rs +++ b/src/controllers/login_controller.rs @@ -1,7 +1,7 @@ use actix::Addr; use actix_identity::Identity; use actix_remote_ip::RemoteIP; -use actix_web::{web, HttpRequest, HttpResponse, Responder}; +use actix_web::{HttpRequest, HttpResponse, Responder, web}; use askama::Template; use std::sync::Arc; @@ -14,7 +14,7 @@ use crate::controllers::base_controller::{ }; use crate::data::action_logger::{Action, ActionLogger}; use crate::data::force_2fa_auth::Force2FAAuth; -use crate::data::login_redirect::{get_2fa_url, LoginRedirect}; +use crate::data::login_redirect::{LoginRedirect, get_2fa_url}; use crate::data::provider::{Provider, ProvidersManager}; use crate::data::session_identity::{SessionIdentity, SessionStatus}; use crate::data::user::User; @@ -177,7 +177,10 @@ pub async fn login_route( } LoginResult::LocalAuthForbidden => { - log::warn!("Failed login for username {} : attempted to use local auth, but it is forbidden", &login); + log::warn!( + "Failed login for username {} : attempted to use local auth, but it is forbidden", + &login + ); logger.log(Action::TryLocalLoginFromUnauthorizedAccount(&login)); danger = Some("You cannot login from local auth with your account!".to_string()); } diff --git a/src/controllers/openid_controller.rs b/src/controllers/openid_controller.rs index ebcf2e0..fd4a954 100644 --- a/src/controllers/openid_controller.rs +++ b/src/controllers/openid_controller.rs @@ -4,9 +4,9 @@ use std::sync::Arc; use actix::Addr; use actix_identity::Identity; use actix_web::error::ErrorUnauthorized; -use actix_web::{web, HttpRequest, HttpResponse, Responder}; -use base64::engine::general_purpose::STANDARD as BASE64_STANDARD; +use actix_web::{HttpRequest, HttpResponse, Responder, web}; use base64::Engine as _; +use base64::engine::general_purpose::STANDARD as BASE64_STANDARD; use light_openid::primitives::{OpenIDConfig, OpenIDTokenResponse, OpenIDUserInfo}; use crate::actors::openid_sessions_actor::{OpenIDSessionsActor, Session, SessionID}; @@ -21,7 +21,7 @@ use crate::data::code_challenge::CodeChallenge; use crate::data::current_user::CurrentUser; use crate::data::id_token::IdToken; use crate::data::jwt_signer::{JWTSigner, JsonWebKey}; -use crate::data::login_redirect::{get_2fa_url, LoginRedirect}; +use crate::data::login_redirect::{LoginRedirect, get_2fa_url}; use crate::data::session_identity::SessionIdentity; use crate::data::user::User; diff --git a/src/controllers/providers_controller.rs b/src/controllers/providers_controller.rs index b607969..c27f07f 100644 --- a/src/controllers/providers_controller.rs +++ b/src/controllers/providers_controller.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use actix::Addr; use actix_identity::Identity; use actix_remote_ip::RemoteIP; -use actix_web::{web, HttpRequest, HttpResponse, Responder}; +use actix_web::{HttpRequest, HttpResponse, Responder, web}; use askama::Template; use crate::actors::bruteforce_actor::BruteForceActor; diff --git a/src/controllers/settings_controller.rs b/src/controllers/settings_controller.rs index 897a582..3efbab6 100644 --- a/src/controllers/settings_controller.rs +++ b/src/controllers/settings_controller.rs @@ -1,6 +1,6 @@ use actix::Addr; use actix_remote_ip::RemoteIP; -use actix_web::{web, HttpResponse, Responder}; +use actix_web::{HttpResponse, Responder, web}; use askama::Template; use crate::actors::bruteforce_actor::BruteForceActor; diff --git a/src/controllers/two_factor_api.rs b/src/controllers/two_factor_api.rs index ce46e05..56b4994 100644 --- a/src/controllers/two_factor_api.rs +++ b/src/controllers/two_factor_api.rs @@ -1,5 +1,5 @@ use actix::Addr; -use actix_web::{web, HttpResponse, Responder}; +use actix_web::{HttpResponse, Responder, web}; use uuid::Uuid; use webauthn_rs::prelude::RegisterPublicKeyCredential; diff --git a/src/controllers/two_factors_controller.rs b/src/controllers/two_factors_controller.rs index cd72c9e..5a1231e 100644 --- a/src/controllers/two_factors_controller.rs +++ b/src/controllers/two_factors_controller.rs @@ -2,8 +2,8 @@ use std::ops::Deref; use actix_web::{HttpResponse, Responder}; use askama::Template; -use base64::engine::general_purpose::STANDARD as BASE64_STANDARD; use base64::Engine as _; +use base64::engine::general_purpose::STANDARD as BASE64_STANDARD; use qrcode_generator::QrCodeEcc; use crate::constants::MAX_SECOND_FACTOR_NAME_LEN; diff --git a/src/data/action_logger.rs b/src/data/action_logger.rs index cce5585..59c5110 100644 --- a/src/data/action_logger.rs +++ b/src/data/action_logger.rs @@ -6,7 +6,7 @@ use actix::Addr; use actix_identity::Identity; use actix_remote_ip::RemoteIP; use actix_web::dev::Payload; -use actix_web::{web, Error, FromRequest, HttpRequest}; +use actix_web::{Error, FromRequest, HttpRequest, web}; use crate::actors::providers_states_actor::ProviderLoginState; use crate::actors::users_actor; @@ -142,27 +142,56 @@ impl Action<'_> { false => format!("performed FAILED webauthn attempt for user {user_id:?}"), }, Action::StartLoginAttemptWithOpenIDProvider { provider_id, state } => format!( - "started new authentication attempt through an OpenID provider (prov={} / state={state})", provider_id.0 + "started new authentication attempt through an OpenID provider (prov={} / state={state})", + provider_id.0 + ), + Action::ProviderError { message } => { + format!("failed provider authentication with message '{message}'") + } + Action::ProviderCBInvalidState { state } => { + format!("provided invalid callback state after provider authentication: '{state}'") + } + Action::ProviderRateLimited => { + "could not complete OpenID login because it has reached failed attempts rate limit!" + .to_string() + } + Action::ProviderFailedGetToken { state, code } => format!( + "could not complete login from provider because the id_token could not be retrieved! (state={:?} code = {code})", + state + ), + Action::ProviderFailedGetUserInfo { provider } => format!( + "could not get user information from userinfo endpoint of provider {}!", + provider.id.0 + ), + Action::ProviderEmailNotValidated { provider } => format!( + "could not login using provider {} because its email was marked as not validated!", + provider.id.0 + ), + Action::ProviderMissingEmailInResponse { provider } => format!( + "could not login using provider {} because the email was not provided by userinfo endpoint!", + provider.id.0 + ), + Action::ProviderAccountNotFound { provider, email } => format!( + "could not login using provider {} because the email {email} could not be associated to any account!", + &provider.id.0 + ), + Action::ProviderAccountDisabled { provider, email } => format!( + "could not login using provider {} because the account associated to the email {email} is disabled!", + &provider.id.0 + ), + Action::ProviderAccountNotAllowedToLoginWithProvider { provider, email } => format!( + "could not login using provider {} because the account associated to the email {email} is not allowed to authenticate using this provider!", + &provider.id.0 + ), + Action::ProviderLoginFailed { provider, email } => format!( + "could not login using provider {} with the email {email} for an unknown reason!", + &provider.id.0 + ), + Action::ProviderLoginSuccessful { provider, user } => format!( + "successfully authenticated using provider {} as {}", + provider.id.0, + user.quick_identity() ), - Action::ProviderError { message } => - format!("failed provider authentication with message '{message}'"), - Action::ProviderCBInvalidState { state } => - format!("provided invalid callback state after provider authentication: '{state}'"), - Action::ProviderRateLimited => "could not complete OpenID login because it has reached failed attempts rate limit!".to_string(), - Action::ProviderFailedGetToken {state, code} => format!("could not complete login from provider because the id_token could not be retrieved! (state={:?} code = {code})",state), - Action::ProviderFailedGetUserInfo {provider} => format!("could not get user information from userinfo endpoint of provider {}!", provider.id.0), - Action::ProviderEmailNotValidated {provider}=>format!("could not login using provider {} because its email was marked as not validated!", provider.id.0), - Action::ProviderMissingEmailInResponse {provider}=>format!("could not login using provider {} because the email was not provided by userinfo endpoint!", provider.id.0), - Action::ProviderAccountNotFound { provider, email } => - format!("could not login using provider {} because the email {email} could not be associated to any account!", &provider.id.0), - Action::ProviderAccountDisabled { provider, email } => - format!("could not login using provider {} because the account associated to the email {email} is disabled!", &provider.id.0), - Action::ProviderAccountNotAllowedToLoginWithProvider { provider, email } => - format!("could not login using provider {} because the account associated to the email {email} is not allowed to authenticate using this provider!", &provider.id.0), - Action::ProviderLoginFailed { provider, email } => - format!("could not login using provider {} with the email {email} for an unknown reason!", &provider.id.0), - Action::ProviderLoginSuccessful {provider, user} => - format!("successfully authenticated using provider {} as {}", provider.id.0, user.quick_identity()), Action::Signout => "signed out".to_string(), Action::UserNeed2FAOnLogin(user) => { format!( @@ -181,7 +210,9 @@ impl Action<'_> { format!("successfully authenticated as {login}, but this is a DISABLED ACCOUNT") } Action::TryLocalLoginFromUnauthorizedAccount(login) => { - format!("successfully locally authenticated as {login}, but this is a FORBIDDEN for this account!") + format!( + "successfully locally authenticated as {login}, but this is a FORBIDDEN for this account!" + ) } Action::FailedLoginWithBadCredentials(login) => { format!("attempted to authenticate as {login} but with a WRONG PASSWORD") @@ -202,7 +233,10 @@ impl Action<'_> { Action::NewOpenIDSession { client } => { format!("opened a new OpenID session with {:?}", client.id) } - Action::NewOpenIDSuccessfulImplicitAuth { client } => format!("finished an implicit flow connection for client {:?}", client.id), + Action::NewOpenIDSuccessfulImplicitAuth { client } => format!( + "finished an implicit flow connection for client {:?}", + client.id + ), Action::ChangedHisPassword => "changed his password".to_string(), Action::ClearedHisLoginHistory => "cleared his login history".to_string(), Action::AddNewFactor(factor) => format!( diff --git a/src/data/code_challenge.rs b/src/data/code_challenge.rs index 3f06ff6..f9df32f 100644 --- a/src/data/code_challenge.rs +++ b/src/data/code_challenge.rs @@ -1,5 +1,5 @@ -use base64::engine::general_purpose::URL_SAFE_NO_PAD as BASE64_URL_SAFE_NO_PAD; use base64::Engine as _; +use base64::engine::general_purpose::URL_SAFE_NO_PAD as BASE64_URL_SAFE_NO_PAD; use crate::utils::crypt_utils::sha256; diff --git a/src/data/critical_route.rs b/src/data/critical_route.rs index f8a2a85..814ef32 100644 --- a/src/data/critical_route.rs +++ b/src/data/critical_route.rs @@ -1,6 +1,6 @@ use crate::data::current_user::CurrentUser; use crate::data::from_request_redirect::FromRequestRedirect; -use crate::data::login_redirect::{get_2fa_url, LoginRedirect}; +use crate::data::login_redirect::{LoginRedirect, get_2fa_url}; use actix_web::dev::Payload; use actix_web::{FromRequest, HttpRequest}; use std::future::Future; diff --git a/src/data/current_user.rs b/src/data/current_user.rs index d1532ab..8d08912 100644 --- a/src/data/current_user.rs +++ b/src/data/current_user.rs @@ -6,7 +6,7 @@ use actix::Addr; use actix_identity::Identity; use actix_web::dev::Payload; use actix_web::error::ErrorInternalServerError; -use actix_web::{web, Error, FromRequest, HttpRequest}; +use actix_web::{Error, FromRequest, HttpRequest, web}; use crate::actors::users_actor; use crate::actors::users_actor::UsersActor; diff --git a/src/data/entity_manager.rs b/src/data/entity_manager.rs index f5ac8a6..a5bcfdf 100644 --- a/src/data/entity_manager.rs +++ b/src/data/entity_manager.rs @@ -20,7 +20,10 @@ where /// Open entity pub fn open_or_create>(path: A) -> Res { if !path.as_ref().is_file() { - log::warn!("Entities at {:?} does not point to a file, creating a new empty entity container...", path.as_ref()); + log::warn!( + "Entities at {:?} does not point to a file, creating a new empty entity container...", + path.as_ref() + ); return Ok(Self { file_path: path.as_ref().to_path_buf(), list: vec![], diff --git a/src/data/force_2fa_auth.rs b/src/data/force_2fa_auth.rs index f5a0531..c567f9d 100644 --- a/src/data/force_2fa_auth.rs +++ b/src/data/force_2fa_auth.rs @@ -2,7 +2,7 @@ use crate::data::current_user::CurrentUser; use crate::data::session_identity::SessionIdentity; use actix_identity::Identity; use actix_web::dev::Payload; -use actix_web::{web, Error, FromRequest, HttpRequest}; +use actix_web::{Error, FromRequest, HttpRequest, web}; use std::future::Future; use std::pin::Pin; diff --git a/src/data/jwt_signer.rs b/src/data/jwt_signer.rs index c3f009f..45b9baa 100644 --- a/src/data/jwt_signer.rs +++ b/src/data/jwt_signer.rs @@ -1,12 +1,12 @@ use jwt_simple::algorithms::RSAKeyPairLike; use jwt_simple::claims::JWTClaims; use jwt_simple::prelude::RS256KeyPair; -use serde::de::DeserializeOwned; use serde::Serialize; +use serde::de::DeserializeOwned; +use base64::Engine as _; use base64::engine::general_purpose::URL_SAFE as BASE64_URL_URL_SAFE; use base64::engine::general_purpose::URL_SAFE_NO_PAD as BASE64_URL_SAFE_NO_PAD; -use base64::Engine as _; use crate::utils::err::Res; use crate::utils::string_utils::rand_str; diff --git a/src/data/provider_configuration.rs b/src/data/provider_configuration.rs index 36b17b4..85e1f0e 100644 --- a/src/data/provider_configuration.rs +++ b/src/data/provider_configuration.rs @@ -26,7 +26,9 @@ impl ProviderConfiguration { let state = urlencoding::encode(&state.state_id).to_string(); let callback_url = AppConfig::get().oidc_provider_redirect_url(); - format!("{authorization_url}?response_type=code&scope=openid%20profile%20email&client_id={client_id}&state={state}&redirect_uri={callback_url}") + format!( + "{authorization_url}?response_type=code&scope=openid%20profile%20email&client_id={client_id}&state={state}&redirect_uri={callback_url}" + ) } /// Retrieve the authorization token after a successful authentication, using an authorization code diff --git a/src/data/totp_key.rs b/src/data/totp_key.rs index 5ae67b1..b6430d1 100644 --- a/src/data/totp_key.rs +++ b/src/data/totp_key.rs @@ -80,7 +80,7 @@ impl TotpKey { /// Get the code at a specific time fn get_code_at u64>(&self, get_time: F) -> Res { - let gen = TotpGenerator::new() + let generator = TotpGenerator::new() .set_digit(NUM_DIGITS) .unwrap() .set_step(PERIOD) @@ -98,7 +98,7 @@ impl TotpKey { Some(k) => k, }; - Ok(gen.get_code_with(&key, get_time)) + Ok(generator.get_code_with(&key, get_time)) } /// Check a code's validity diff --git a/src/data/users_file_entity.rs b/src/data/users_file_entity.rs index 176664a..21a1a43 100644 --- a/src/data/users_file_entity.rs +++ b/src/data/users_file_entity.rs @@ -3,7 +3,7 @@ use std::net::IpAddr; use crate::actors::users_actor::{AuthorizedAuthenticationSources, UsersSyncBackend}; use crate::data::entity_manager::EntityManager; use crate::data::user::{FactorID, GeneralSettings, GrantedClients, TwoFactor, User, UserID}; -use crate::utils::err::{new_error, Res}; +use crate::utils::err::{Res, new_error}; use crate::utils::time::time; impl EntityManager { diff --git a/src/main.rs b/src/main.rs index 5c34e79..ba53c2e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,14 +2,14 @@ use core::time::Duration; use std::sync::Arc; use actix::Actor; -use actix_identity::config::LogoutBehaviour; use actix_identity::IdentityMiddleware; +use actix_identity::config::LogoutBehaviour; use actix_remote_ip::RemoteIPConfig; -use actix_session::storage::CookieSessionStore; use actix_session::SessionMiddleware; +use actix_session::storage::CookieSessionStore; use actix_web::cookie::{Key, SameSite}; use actix_web::middleware::Logger; -use actix_web::{get, middleware, web, App, HttpResponse, HttpServer}; +use actix_web::{App, HttpResponse, HttpServer, get, middleware, web}; use basic_oidc::actors::bruteforce_actor::BruteForceActor; use basic_oidc::actors::openid_sessions_actor::OpenIDSessionsActor; diff --git a/src/middlewares/auth_middleware.rs b/src/middlewares/auth_middleware.rs index 546bb4b..54646e7 100644 --- a/src/middlewares/auth_middleware.rs +++ b/src/middlewares/auth_middleware.rs @@ -1,15 +1,15 @@ //! # Authentication middleware -use std::future::{ready, Future, Ready}; +use std::future::{Future, Ready, ready}; use std::pin::Pin; use std::rc::Rc; use actix_identity::IdentityExt; use actix_web::body::EitherBody; -use actix_web::http::{header, Method}; +use actix_web::http::{Method, header}; use actix_web::{ - dev::{forward_ready, Service, ServiceRequest, ServiceResponse, Transform}, Error, HttpResponse, + dev::{Service, ServiceRequest, ServiceResponse, Transform, forward_ready}, }; use crate::constants::{