diff --git a/backend/src/lib.rs b/backend/src/lib.rs index 0302ce6..c7d94be 100644 --- a/backend/src/lib.rs +++ b/backend/src/lib.rs @@ -27,7 +27,10 @@ use std::{ use actix::prelude::*; pub use boringtun::*; use chrono::{TimeDelta, Utc}; -use db_connector::{models::{allowed_users::AllowedUser, chargers::Charger, verification::Verification}, Pool}; +use db_connector::{ + models::{allowed_users::AllowedUser, chargers::Charger, verification::Verification}, + Pool, +}; use diesel::{prelude::*, r2d2::PooledConnection, result::Error::NotFound}; use ipnetwork::IpNetwork; use lettre::SmtpTransport; @@ -40,11 +43,11 @@ use ws_udp_bridge::Message; pub mod error; pub mod middleware; pub mod models; +pub mod rate_limit; pub mod routes; pub mod udp_server; pub mod utils; pub mod ws_udp_bridge; -pub mod rate_limit; #[derive(Hash, PartialEq, Eq, Clone, Debug)] pub struct DiscoveryCharger { @@ -69,7 +72,8 @@ pub struct BridgeState { pub web_client_map: Mutex>>, pub undiscovered_clients: Mutex>>, pub charger_management_map: Arc>>>>, - pub charger_management_map_with_id: Arc>>>>, + pub charger_management_map_with_id: + Arc>>>>, pub port_discovery: Arc>>, pub charger_remote_conn_map: Mutex>, pub undiscovered_chargers: Arc>>>, @@ -84,7 +88,9 @@ pub struct AppState { pub frontend_url: String, } -pub fn clean_recovery_tokens(conn: &mut PooledConnection>) { +pub fn clean_recovery_tokens( + conn: &mut PooledConnection>, +) { use db_connector::schema::recovery_tokens::dsl::*; if let Some(time) = Utc::now().checked_sub_signed(TimeDelta::hours(1)) { @@ -94,7 +100,9 @@ pub fn clean_recovery_tokens(conn: &mut PooledConnection>) { +pub fn clean_refresh_tokens( + conn: &mut PooledConnection>, +) { use db_connector::schema::refresh_tokens::dsl::*; diesel::delete(refresh_tokens.filter(expiration.lt(Utc::now().timestamp()))) @@ -102,7 +110,9 @@ pub fn clean_refresh_tokens(conn: &mut PooledConnection>) { +pub fn clean_verification_tokens( + conn: &mut PooledConnection>, +) { let awaiting_verification: Vec = { use db_connector::schema::verification::dsl::*; @@ -110,10 +120,7 @@ pub fn clean_verification_tokens(conn: &mut PooledConnection v.into_iter().map(|v| v.user).collect(), Err(NotFound) => Vec::new(), Err(err) => { @@ -125,29 +132,30 @@ pub fn clean_verification_tokens(conn: &mut PooledConnection(0) - }); + let _ = diesel::delete( + users + .filter(id.ne_all(awaiting_verification)) + .filter(email_verified.eq(false)), + ) + .execute(conn) + .or_else(|e| { + log::error!("Failed to delete unverified users: {}", e); + Ok::(0) + }); } } // Remove chargers that dont have allowed users pub fn clean_chargers(conn: &mut PooledConnection>) { - // Get all chargers in database let chargers: Vec = { use db_connector::schema::chargers::dsl::*; - match chargers.select(Charger::as_select()) - .load(conn) - { + match chargers.select(Charger::as_select()).load(conn) { Ok(c) => c, Err(err) => { log::error!("Failed to get chargers for cleanup: {}", err); - return + return; } } }; @@ -169,7 +177,7 @@ pub fn clean_chargers(conn: &mut PooledConnection(0) }); } - }, + } Err(err) => { log::error!("Failed to get allowed user for charger cleanup: {}", err); } @@ -188,10 +196,13 @@ pub(crate) mod tests { test, web::{self, ServiceConfig}, }; + use chrono::Utc; + use db_connector::{ + models::{recovery_tokens::RecoveryToken, refresh_tokens::RefreshToken, users::User}, + test_connection_pool, + }; use ipnetwork::Ipv4Network; use lettre::transport::smtp::authentication::Credentials; - use chrono::Utc; - use db_connector::{models::{recovery_tokens::RecoveryToken, refresh_tokens::RefreshToken, users::User}, test_connection_pool}; use lru::LruCache; use rand::RngCore; use rand_core::OsRng; @@ -262,7 +273,8 @@ pub(crate) mod tests { socket: UdpSocket::bind(("0", 0)).unwrap(), }; - let cache: web::Data>>> = web::Data::new(Mutex::new(LruCache::new(NonZeroUsize::new(10000).unwrap()))); + let cache: web::Data>>> = + web::Data::new(Mutex::new(LruCache::new(NonZeroUsize::new(10000).unwrap()))); let state = web::Data::new(state); let bridge_state = web::Data::new(bridge_state); @@ -287,25 +299,39 @@ pub(crate) mod tests { let token1 = RecoveryToken { id: token1_id, user_id: uid, - created: Utc::now().checked_sub_signed(TimeDelta::hours(1)).unwrap().timestamp() + 1, + created: Utc::now() + .checked_sub_signed(TimeDelta::hours(1)) + .unwrap() + .timestamp() + + 1, }; let token2 = RecoveryToken { id: uuid::Uuid::new_v4(), user_id: uid, - created: Utc::now().checked_sub_signed(TimeDelta::hours(1)).unwrap().timestamp() - 1, + created: Utc::now() + .checked_sub_signed(TimeDelta::hours(1)) + .unwrap() + .timestamp() + - 1, }; let token3 = RecoveryToken { id: uuid::Uuid::new_v4(), user_id: uid, - created: Utc::now().checked_sub_signed(TimeDelta::hours(2)).unwrap().timestamp(), + created: Utc::now() + .checked_sub_signed(TimeDelta::hours(2)) + .unwrap() + .timestamp(), }; - diesel::insert_into(recovery_tokens).values(vec![&token1, &token2, &token3]) - .execute(&mut conn).unwrap(); + diesel::insert_into(recovery_tokens) + .values(vec![&token1, &token2, &token3]) + .execute(&mut conn) + .unwrap(); clean_recovery_tokens(&mut conn); - let tokens: Vec = recovery_tokens.filter(user_id.eq(uid)) + let tokens: Vec = recovery_tokens + .filter(user_id.eq(uid)) .select(RecoveryToken::as_select()) .load(&mut conn) .unwrap(); @@ -313,7 +339,9 @@ pub(crate) mod tests { assert_eq!(tokens.len(), 1); assert_eq!(tokens[0].id, token1_id); - diesel::delete(recovery_tokens.filter(user_id.eq(uid))).execute(&mut conn).unwrap(); + diesel::delete(recovery_tokens.filter(user_id.eq(uid))) + .execute(&mut conn) + .unwrap(); } #[actix_web::test] @@ -338,12 +366,15 @@ pub(crate) mod tests { expiration: Utc::now().timestamp() - 1, }; - diesel::insert_into(refresh_tokens).values(vec![&token1, &token2]) - .execute(&mut conn).unwrap(); + diesel::insert_into(refresh_tokens) + .values(vec![&token1, &token2]) + .execute(&mut conn) + .unwrap(); clean_refresh_tokens(&mut conn); - let tokens: Vec = refresh_tokens.filter(user_id.eq(uid)) + let tokens: Vec = refresh_tokens + .filter(user_id.eq(uid)) .select(RefreshToken::as_select()) .load(&mut conn) .unwrap(); @@ -351,7 +382,9 @@ pub(crate) mod tests { assert_eq!(tokens.len(), 1); assert_eq!(tokens[0].id, token1_id); - diesel::delete(refresh_tokens.filter(user_id.eq(uid))).execute(&mut conn).unwrap(); + diesel::delete(refresh_tokens.filter(user_id.eq(uid))) + .execute(&mut conn) + .unwrap(); } #[actix_web::test] @@ -399,14 +432,20 @@ pub(crate) mod tests { let verify = Verification { id: verify_id, user: user_id, - expiration: Utc::now().checked_sub_signed(TimeDelta::seconds(1)).unwrap().naive_utc(), + expiration: Utc::now() + .checked_sub_signed(TimeDelta::seconds(1)) + .unwrap() + .naive_utc(), }; let verify2_id = uuid::Uuid::new_v4(); let verify2 = Verification { id: verify2_id, user: user2_id, - expiration: Utc::now().checked_add_signed(TimeDelta::seconds(1)).unwrap().naive_local(), + expiration: Utc::now() + .checked_add_signed(TimeDelta::seconds(1)) + .unwrap() + .naive_local(), }; let pool = test_connection_pool(); @@ -414,14 +453,16 @@ pub(crate) mod tests { { use db_connector::schema::users::dsl::*; - diesel::insert_into(users).values(vec![&user, &user2, &user3]) + diesel::insert_into(users) + .values(vec![&user, &user2, &user3]) .execute(&mut conn) .unwrap(); } { use db_connector::schema::verification::dsl::*; - diesel::insert_into(verification).values(vec![&verify, &verify2]) + diesel::insert_into(verification) + .values(vec![&verify, &verify2]) .execute(&mut conn) .unwrap(); } @@ -482,11 +523,15 @@ pub(crate) mod tests { name: None, management_private: String::new(), charger_pub: String::new(), - wg_charger_ip: IpNetwork::V4(Ipv4Network::new(Ipv4Addr::new(123, 123, 123, 123), 24).unwrap()), + wg_charger_ip: IpNetwork::V4( + Ipv4Network::new(Ipv4Addr::new(123, 123, 123, 123), 24).unwrap(), + ), psk: String::new(), - wg_server_ip: IpNetwork::V4(Ipv4Network::new(Ipv4Addr::new(123, 123, 123, 123), 24).unwrap()), + wg_server_ip: IpNetwork::V4( + Ipv4Network::new(Ipv4Addr::new(123, 123, 123, 123), 24).unwrap(), + ), webinterface_port: 80, - firmware_version: "2.6.6".to_string() + firmware_version: "2.6.6".to_string(), }; let pool = test_connection_pool(); @@ -506,7 +551,8 @@ pub(crate) mod tests { let chargers: Vec = { use db_connector::schema::chargers::dsl::*; - chargers.filter(id.eq_any(vec![&charger_id, &charger2.id])) + chargers + .filter(id.eq_any(vec![&charger_id, &charger2.id])) .select(Charger::as_select()) .load(&mut conn) .unwrap() diff --git a/backend/src/main.rs b/backend/src/main.rs index 1baf414..1dc59ca 100644 --- a/backend/src/main.rs +++ b/backend/src/main.rs @@ -20,7 +20,11 @@ mod monitoring; use std::{ - collections::HashMap, net::UdpSocket, num::NonZeroUsize, sync::{Arc, Mutex}, time::Duration + collections::HashMap, + net::UdpSocket, + num::NonZeroUsize, + sync::{Arc, Mutex}, + time::Duration, }; use backend::utils::get_connection; @@ -29,9 +33,9 @@ pub use backend::*; use actix_web::{middleware::Logger, web, App, HttpServer}; use db_connector::{get_connection_pool, run_migrations, Pool}; use diesel::prelude::*; -use rate_limit::LoginRateLimiter; use lettre::{transport::smtp::authentication::Credentials, SmtpTransport}; use lru::LruCache; +use rate_limit::LoginRateLimiter; use simplelog::{ColorChoice, CombinedLogger, Config, LevelFilter, TermLogger, TerminalMode}; use udp_server::packet::{ ManagementCommand, ManagementCommandId, ManagementCommandPacket, ManagementPacket, @@ -167,7 +171,8 @@ async fn main() -> std::io::Result<()> { udp_server::start_server(bridge_state.clone()).unwrap(); // Cache for random salts of non existing users - let cache: web::Data>>> = web::Data::new(Mutex::new(LruCache::new(NonZeroUsize::new(10000).unwrap()))); + let cache: web::Data>>> = + web::Data::new(Mutex::new(LruCache::new(NonZeroUsize::new(10000).unwrap()))); let login_ratelimiter = web::Data::new(LoginRateLimiter::new()); diff --git a/backend/src/models/lang.rs b/backend/src/models/lang.rs index 38db460..b75d03a 100644 --- a/backend/src/models/lang.rs +++ b/backend/src/models/lang.rs @@ -19,8 +19,8 @@ use std::future::{ready, Ready}; - #[derive(Clone, Debug)] - pub struct Lang(String); +#[derive(Clone, Debug)] +pub struct Lang(String); impl From for String { fn from(value: Lang) -> Self { @@ -36,7 +36,7 @@ impl actix_web::FromRequest for Lang { for (name, value) in req.headers().iter() { if name == "X-Lang" { if let Ok(value) = value.to_str() { - return ready(Ok(Lang(value.to_string()))) + return ready(Ok(Lang(value.to_string()))); } break; } diff --git a/backend/src/models/mod.rs b/backend/src/models/mod.rs index c272fda..8f6194b 100644 --- a/backend/src/models/mod.rs +++ b/backend/src/models/mod.rs @@ -1,4 +1,4 @@ pub mod filtered_user; +pub mod lang; pub mod token_claims; pub mod uuid; -pub mod lang; diff --git a/backend/src/monitoring.rs b/backend/src/monitoring.rs index 96fe899..f8fd5e2 100644 --- a/backend/src/monitoring.rs +++ b/backend/src/monitoring.rs @@ -1,11 +1,14 @@ use std::time::Duration; -use askama::Template; -use diesel::prelude::*; use actix_web::web; use anyhow::Error; +use askama::Template; use backend::{utils::get_connection, AppState}; -use diesel::{r2d2::{ConnectionManager, PooledConnection}, PgConnection, QueryDsl}; +use diesel::prelude::*; +use diesel::{ + r2d2::{ConnectionManager, PooledConnection}, + PgConnection, QueryDsl, +}; use lettre::{message::header::ContentType, Message, Transport}; #[derive(Template)] @@ -16,9 +19,11 @@ struct MonitoringMail<'a> { server_name: &'a str, } -fn get_numbers(mut conn: PooledConnection>) -> Result<(i64, i64), Error> { - use db_connector::schema::users::dsl::*; +fn get_numbers( + mut conn: PooledConnection>, +) -> Result<(i64, i64), Error> { use db_connector::schema::chargers::dsl::*; + use db_connector::schema::users::dsl::*; let num_users: i64 = users.count().get_result(&mut conn)?; let num_chargers: i64 = chargers.count().get_result(&mut conn)?; @@ -55,22 +60,20 @@ pub fn start_monitoring(state: web::Data) { return; } - std::thread::spawn(move || { - loop { - if let Ok(conn) = get_connection(&state) { - let (num_users, num_chargers) = match get_numbers(conn) { - Ok(v) => v, - Err(_err) => { - continue; - } - }; - match send_mail(&state, num_users, num_chargers) { - Ok(()) => (), - Err(err) => log::error!("Failed to send monitoring mail: {}", err) + std::thread::spawn(move || loop { + if let Ok(conn) = get_connection(&state) { + let (num_users, num_chargers) = match get_numbers(conn) { + Ok(v) => v, + Err(_err) => { + continue; } + }; + match send_mail(&state, num_users, num_chargers) { + Ok(()) => (), + Err(err) => log::error!("Failed to send monitoring mail: {}", err), } - - std::thread::sleep(Duration::from_secs(60 * 60 * 24)); } + + std::thread::sleep(Duration::from_secs(60 * 60 * 24)); }); } diff --git a/backend/src/rate_limit.rs b/backend/src/rate_limit.rs index 23ebcc1..dbaa16d 100644 --- a/backend/src/rate_limit.rs +++ b/backend/src/rate_limit.rs @@ -21,8 +21,11 @@ use std::num::NonZeroU32; use actix_governor::{KeyExtractor, SimpleKeyExtractionError}; use actix_web::{http::StatusCode, HttpRequest, HttpResponse, ResponseError}; -use governor::{clock::{Clock, QuantaClock, QuantaInstant}, state::InMemoryState, NotUntil, Quota, RateLimiter}; - +use governor::{ + clock::{Clock, QuantaClock, QuantaInstant}, + state::InMemoryState, + NotUntil, Quota, RateLimiter, +}; /** * The struct used to extract ip for ratelimiting @@ -34,7 +37,10 @@ impl KeyExtractor for IPExtractor { type Key = String; type KeyExtractionError = SimpleKeyExtractionError<&'static str>; - fn extract(&self, req: &actix_web::dev::ServiceRequest) -> Result { + fn extract( + &self, + req: &actix_web::dev::ServiceRequest, + ) -> Result { let info = req.connection_info(); if let Some(ip) = info.realip_remote_addr() { Ok(ip.to_string()) @@ -74,13 +80,21 @@ const REQUESTS_BURST: u32 = 25; // RateLimiter for the login route pub struct LoginRateLimiter { - rate_limiter: RateLimiter, QuantaClock, governor::middleware::NoOpMiddleware>, + rate_limiter: RateLimiter< + LoginRateLimitKey, + dashmap::DashMap, + QuantaClock, + governor::middleware::NoOpMiddleware, + >, } impl LoginRateLimiter { pub fn new() -> Self { Self { - rate_limiter: RateLimiter::keyed(Quota::per_second(NonZeroU32::new(REQUESTS_PER_SECOND).unwrap()).allow_burst(NonZeroU32::new(REQUESTS_BURST).unwrap())), + rate_limiter: RateLimiter::keyed( + Quota::per_second(NonZeroU32::new(REQUESTS_PER_SECOND).unwrap()) + .allow_burst(NonZeroU32::new(REQUESTS_BURST).unwrap()), + ), } } @@ -88,13 +102,10 @@ impl LoginRateLimiter { let ip = if let Some(ip) = req.connection_info().realip_remote_addr() { ip.to_string() } else { - return Err(crate::error::Error::InternalError.into()) + return Err(crate::error::Error::InternalError.into()); }; - let key = LoginRateLimitKey { - user: email, - ip - }; + let key = LoginRateLimitKey { user: email, ip }; if let Err(err) = self.rate_limiter.check_key(&key) { log::warn!("RateLimiter triggered for {:?}", key); let now = self.rate_limiter.clock().now(); @@ -106,7 +117,6 @@ impl LoginRateLimiter { } } - #[derive(Debug)] struct RateLimitError { wait_time: NotUntil, diff --git a/backend/src/routes/auth/get_login_salt.rs b/backend/src/routes/auth/get_login_salt.rs index a9421ec..ab0618c 100644 --- a/backend/src/routes/auth/get_login_salt.rs +++ b/backend/src/routes/auth/get_login_salt.rs @@ -8,7 +8,10 @@ use serde::Deserialize; use utoipa::IntoParams; use crate::{ - error::Error, rate_limit::LoginRateLimiter, utils::{generate_random_bytes, get_connection, web_block_unpacked}, AppState + error::Error, + rate_limit::LoginRateLimiter, + utils::{generate_random_bytes, get_connection, web_block_unpacked}, + AppState, }; #[derive(Deserialize, IntoParams)] @@ -48,7 +51,11 @@ pub async fn get_login_salt( .get_result(&mut conn) { Ok(user) => Ok(user.login_salt), - Err(NotFound) => Ok(cache.lock().unwrap().get_or_insert(mail, || generate_random_bytes()).to_vec()), + Err(NotFound) => Ok(cache + .lock() + .unwrap() + .get_or_insert(mail, || generate_random_bytes()) + .to_vec()), Err(_err) => Err(Error::InternalError), } }) @@ -145,5 +152,4 @@ pub mod tests { let second_salt: Vec = test::read_body_json(resp).await; assert_ne!(second_salt, first_salt); } - } diff --git a/backend/src/routes/auth/jwt_refresh.rs b/backend/src/routes/auth/jwt_refresh.rs index d0cf3ec..e33cc33 100644 --- a/backend/src/routes/auth/jwt_refresh.rs +++ b/backend/src/routes/auth/jwt_refresh.rs @@ -139,10 +139,12 @@ pub async fn jwt_refresh( let now = Utc::now(); let iat = now.timestamp() as usize; - let exp = if let Some(exp) = now.checked_add_signed(TimeDelta::minutes(super::login::MAX_TOKEN_AGE_MINUTES)) { + let exp = if let Some(exp) = + now.checked_add_signed(TimeDelta::minutes(super::login::MAX_TOKEN_AGE_MINUTES)) + { exp.timestamp() as usize } else { - return Err(Error::InternalError.into()) + return Err(Error::InternalError.into()); }; let claims = TokenClaims { iat, diff --git a/backend/src/routes/auth/login.rs b/backend/src/routes/auth/login.rs index 9ba7f83..3318f46 100644 --- a/backend/src/routes/auth/login.rs +++ b/backend/src/routes/auth/login.rs @@ -32,7 +32,11 @@ use utoipa::ToSchema; use validator::Validate; use crate::{ - error::Error, models::token_claims::TokenClaims, rate_limit::LoginRateLimiter, utils::{get_connection, web_block_unpacked}, AppState + error::Error, + models::token_claims::TokenClaims, + rate_limit::LoginRateLimiter, + utils::{get_connection, web_block_unpacked}, + AppState, }; pub const MAX_TOKEN_AGE_MINUTES: i64 = 6; @@ -123,10 +127,12 @@ pub async fn login( let now = Utc::now(); let iat = now.timestamp() as usize; - let exp = if let Some(exp) = now.checked_add_signed(TimeDelta::minutes(super::login::MAX_TOKEN_AGE_MINUTES)) { + let exp = if let Some(exp) = + now.checked_add_signed(TimeDelta::minutes(super::login::MAX_TOKEN_AGE_MINUTES)) + { exp.timestamp() as usize } else { - return Err(Error::InternalError.into()) + return Err(Error::InternalError.into()); }; let claims = TokenClaims { iat, @@ -171,10 +177,11 @@ pub async fn create_refresh_token( let now = Utc::now(); let iat = now.timestamp() as usize; - let exp = if let Some(exp) = now.checked_add_days(Days::new(MAX_REFRESH_TOKEN_AGE_DAYS as u64)) { + let exp = if let Some(exp) = now.checked_add_days(Days::new(MAX_REFRESH_TOKEN_AGE_DAYS as u64)) + { exp.timestamp() as usize } else { - return Err(Error::InternalError.into()) + return Err(Error::InternalError.into()); }; let claims = TokenClaims { iat, diff --git a/backend/src/routes/auth/register.rs b/backend/src/routes/auth/register.rs index 2c9dd97..32da857 100644 --- a/backend/src/routes/auth/register.rs +++ b/backend/src/routes/auth/register.rs @@ -33,7 +33,10 @@ use utoipa::ToSchema; use validator::Validate; use crate::{ - error::Error, routes::auth::VERIFICATION_EXPIRATION_DAYS, utils::{get_connection, web_block_unpacked}, AppState + error::Error, + routes::auth::VERIFICATION_EXPIRATION_DAYS, + utils::{get_connection, web_block_unpacked}, + AppState, }; #[derive(Template)] @@ -141,8 +144,7 @@ fn send_verification_mail( pub async fn register( state: web::Data, data: Json, - #[cfg(not(test))] - lang: crate::models::lang::Lang, + #[cfg(not(test))] lang: crate::models::lang::Lang, ) -> Result { let mut conn = get_connection(&state)?; @@ -185,15 +187,17 @@ pub async fn register( let mut conn = get_connection(&state)?; - let exp = if let Some(expiration) = chrono::Utc::now().checked_add_days(Days::new(VERIFICATION_EXPIRATION_DAYS)) { + let exp = if let Some(expiration) = + chrono::Utc::now().checked_add_days(Days::new(VERIFICATION_EXPIRATION_DAYS)) + { expiration.naive_utc() } else { - return Err(Error::InternalError.into()) + return Err(Error::InternalError.into()); }; let insert_result = match web::block(move || { - use db_connector::schema::verification::dsl::*; use db_connector::schema::users::dsl::*; + use db_connector::schema::verification::dsl::*; let verify = Verification { id: uuid::Uuid::new_v4(), @@ -284,11 +288,11 @@ pub(crate) mod tests { } pub fn delete_user(mail: &str) { + use db_connector::schema::allowed_users::dsl as allowed_users; use db_connector::schema::refresh_tokens::dsl::*; use db_connector::schema::users::dsl::*; use db_connector::schema::verification::dsl::*; use db_connector::schema::wg_keys::dsl as wg_keys; - use db_connector::schema::allowed_users::dsl as allowed_users; use diesel::prelude::*; let pool = db_connector::test_connection_pool(); diff --git a/backend/src/routes/auth/start_recovery.rs b/backend/src/routes/auth/start_recovery.rs index 2713c14..9f7594c 100644 --- a/backend/src/routes/auth/start_recovery.rs +++ b/backend/src/routes/auth/start_recovery.rs @@ -103,8 +103,7 @@ fn send_email( pub async fn start_recovery( query: web::Query, state: web::Data, - #[cfg(not(test))] - lang: crate::models::lang::Lang, + #[cfg(not(test))] lang: crate::models::lang::Lang, ) -> actix_web::Result { let user_id = get_user_id( &state, diff --git a/backend/src/routes/charger/add.rs b/backend/src/routes/charger/add.rs index 93a4346..24b08a5 100644 --- a/backend/src/routes/charger/add.rs +++ b/backend/src/routes/charger/add.rs @@ -150,27 +150,28 @@ pub async fn add( let charger_uid = i32::from_le_bytes(charger_id); let charger_id; - let (pub_key, password) = if let Some(cid) = get_charger_uuid(&state, charger_uid, user_id.clone().into()).await? { - charger_id = cid; - update_charger( - charger_schema.charger.clone(), - charger_id, - charger_uid, - user_id.clone().into(), - &state, - ) - .await? - } else { - charger_id = uuid::Uuid::new_v4(); - add_charger( - charger_schema.0.clone(), - charger_id, - charger_uid, - user_id.clone().into(), - &state, - ) - .await? - }; + let (pub_key, password) = + if let Some(cid) = get_charger_uuid(&state, charger_uid, user_id.clone().into()).await? { + charger_id = cid; + update_charger( + charger_schema.charger.clone(), + charger_id, + charger_uid, + user_id.clone().into(), + &state, + ) + .await? + } else { + charger_id = uuid::Uuid::new_v4(); + add_charger( + charger_schema.0.clone(), + charger_id, + charger_uid, + user_id.clone().into(), + &state, + ) + .await? + }; for keys in charger_schema.keys.iter() { add_wg_key(charger_id, user_id.clone().into(), keys.to_owned(), &state).await?; @@ -437,9 +438,11 @@ pub(crate) mod tests { use crate::{ middleware::jwt::JwtMiddleware, routes::{ - charger::{allow_user::UserAuth, remove::tests::{ - remove_allowed_test_users, remove_test_charger, remove_test_keys, - }, tests::TestCharger}, + charger::{ + allow_user::UserAuth, + remove::tests::{remove_allowed_test_users, remove_test_charger, remove_test_keys}, + tests::TestCharger, + }, user::tests::TestUser, }, tests::configure, @@ -632,7 +635,13 @@ pub(crate) mod tests { let (mut user2, _) = TestUser::random().await; user2.login().await; let charger = user2.add_random_charger().await; - user2.allow_user(&email, UserAuth::LoginKey(BASE64_STANDARD.encode(user.get_login_key().await)), &charger).await; + user2 + .allow_user( + &email, + UserAuth::LoginKey(BASE64_STANDARD.encode(user.get_login_key().await)), + &charger, + ) + .await; let app = App::new() .configure(configure) diff --git a/backend/src/routes/charger/allow_user.rs b/backend/src/routes/charger/allow_user.rs index 5222198..c900fe2 100644 --- a/backend/src/routes/charger/allow_user.rs +++ b/backend/src/routes/charger/allow_user.rs @@ -26,7 +26,11 @@ use utoipa::ToSchema; use crate::{ error::Error, - routes::{auth::login::{validate_password, FindBy}, charger::add::get_charger_from_db, user::get_user_id}, + routes::{ + auth::login::{validate_password, FindBy}, + charger::add::get_charger_from_db, + user::get_user_id, + }, utils::{get_connection, parse_uuid, web_block_unpacked}, AppState, }; @@ -35,7 +39,7 @@ use super::add::{password_matches, Keys}; #[derive(Debug, Deserialize, Serialize, Clone, ToSchema)] pub enum UserAuth { - LoginKey(String) + LoginKey(String), } #[derive(Debug, Deserialize, Serialize, ToSchema, Clone)] @@ -50,13 +54,19 @@ pub struct AllowUserSchema { note: String, } -async fn add_keys(state: &web::Data, keys: [super::add::Keys; 5], uid: uuid::Uuid, cid: uuid::Uuid) -> actix_web::Result<()> { +async fn add_keys( + state: &web::Data, + keys: [super::add::Keys; 5], + uid: uuid::Uuid, + cid: uuid::Uuid, +) -> actix_web::Result<()> { let mut conn = get_connection(&state)?; web_block_unpacked(move || { use db_connector::schema::wg_keys::dsl::*; - let insert_keys: Vec = keys.into_iter().map(|key| { - WgKey { + let insert_keys: Vec = keys + .into_iter() + .map(|key| WgKey { id: uuid::Uuid::new_v4(), user_id: uid, charger_id: cid, @@ -66,28 +76,34 @@ async fn add_keys(state: &web::Data, keys: [super::add::Keys; 5], uid: psk: key.psk, web_address: key.web_address, charger_address: key.charger_address, - connection_no: key.connection_no as i32 - } - }).collect(); + connection_no: key.connection_no as i32, + }) + .collect(); - match diesel::insert_into(wg_keys).values(&insert_keys).execute(&mut conn) { + match diesel::insert_into(wg_keys) + .values(&insert_keys) + .execute(&mut conn) + { Ok(_) => Ok(()), - Err(_err) => Err(Error::InternalError) + Err(_err) => Err(Error::InternalError), } - }).await?; + }) + .await?; Ok(()) } -async fn authenticate_user(uid: uuid::Uuid, auth: &UserAuth, state: &web::Data) -> actix_web::Result<()> { +async fn authenticate_user( + uid: uuid::Uuid, + auth: &UserAuth, + state: &web::Data, +) -> actix_web::Result<()> { match auth { UserAuth::LoginKey(key) => { let conn = get_connection(state)?; let key = match base64::engine::general_purpose::STANDARD.decode(key) { Ok(v) => v, - Err(_) => { - return Err(ErrorBadRequest("login_key is wrong base64")) - } + Err(_) => return Err(ErrorBadRequest("login_key is wrong base64")), }; let _ = validate_password(&key, FindBy::Uuid(uid), conn).await?; } @@ -114,7 +130,7 @@ pub async fn allow_user( let charger = get_charger_from_db(cid, &state).await?; if !password_matches(&allow_user.charger_password, &charger.password)? { - return Err(Error::Unauthorized.into()) + return Err(Error::Unauthorized.into()); } let allowed_uuid = get_user_id(&state, FindBy::Email(allow_user.email.clone())).await?; @@ -126,14 +142,18 @@ pub async fn allow_user( web_block_unpacked(move || { use db_connector::schema::allowed_users::dsl::*; - match diesel::delete(allowed_users.filter(user_id.eq(allowed_uuid)) - .filter(charger_id.eq(cid))) - .execute(&mut conn) + match diesel::delete( + allowed_users + .filter(user_id.eq(allowed_uuid)) + .filter(charger_id.eq(cid)), + ) + .execute(&mut conn) { Ok(_) => Ok(()), - Err(_) => Err(Error::InternalError) + Err(_) => Err(Error::InternalError), } - }).await?; + }) + .await?; // add new allowed_user let mut conn = get_connection(&state)?; @@ -148,7 +168,7 @@ pub async fn allow_user( charger_uid: charger.uid, valid: true, name: Some(allow_user.charger_name), - note: Some(allow_user.note) + note: Some(allow_user.note), }; match diesel::insert_into(allowed_users) @@ -163,9 +183,7 @@ pub async fn allow_user( match add_keys(&state, allow_user.wg_keys, allowed_uuid, cid).await { Ok(_) => (), - Err(_err) => { - - } + Err(_err) => {} } Ok(HttpResponse::Ok()) @@ -179,16 +197,22 @@ pub mod tests { use actix_web::{test, App}; use base64::prelude::BASE64_STANDARD; use db_connector::test_connection_pool; - use rand::{distributions::{Alphanumeric, DistString}, RngCore}; + use rand::{ + distributions::{Alphanumeric, DistString}, + RngCore, + }; use rand_core::OsRng; - use crate::{routes::{charger::{add::tests::generate_random_keys, tests::TestCharger}, user::tests::{get_test_uuid, TestUser}}, tests::configure}; + use crate::{ + routes::{ + charger::{add::tests::generate_random_keys, tests::TestCharger}, + user::tests::{get_test_uuid, TestUser}, + }, + tests::configure, + }; pub async fn add_allowed_test_user(email: &str, user_auth: UserAuth, charger: &TestCharger) { - - let app = App::new() - .configure(configure) - .service(allow_user); + let app = App::new().configure(configure).service(allow_user); let app = test::init_service(app).await; let body = AllowUserSchema { @@ -219,9 +243,7 @@ pub mod tests { user1.login().await.to_string(); let charger = user1.add_charger(charger).await; - let app = App::new() - .configure(configure) - .service(allow_user); + let app = App::new().configure(configure).service(allow_user); let app = test::init_service(app).await; let allow = AllowUserSchema { @@ -251,9 +273,7 @@ pub mod tests { user1.login().await.to_string(); let charger = user1.add_charger(charger).await; - let app = App::new() - .configure(configure) - .service(allow_user); + let app = App::new().configure(configure).service(allow_user); let app = test::init_service(app).await; let allow = AllowUserSchema { @@ -282,9 +302,7 @@ pub mod tests { user.login().await.to_string(); let charger = user.add_charger(charger).await; - let app = App::new() - .configure(configure) - .service(allow_user); + let app = App::new().configure(configure).service(allow_user); let app = test::init_service(app).await; let allow = AllowUserSchema { @@ -312,9 +330,7 @@ pub mod tests { user.login().await; let charger = user.add_random_charger().await; - let app = App::new() - .configure(configure) - .service(allow_user); + let app = App::new().configure(configure).service(allow_user); let app = test::init_service(app).await; let allow = AllowUserSchema { @@ -355,7 +371,8 @@ pub mod tests { { use db_connector::schema::allowed_users::dsl::*; - let users: Vec = allowed_users.filter(user_id.eq(get_test_uuid(&user2.mail).unwrap())) + let users: Vec = allowed_users + .filter(user_id.eq(get_test_uuid(&user2.mail).unwrap())) .filter(charger_id.eq(uuid::Uuid::from_str(&charger.uuid).unwrap())) .select(AllowedUser::as_select()) .load(&mut conn) diff --git a/backend/src/routes/charger/get_chargers.rs b/backend/src/routes/charger/get_chargers.rs index 0cab27f..2e7d782 100644 --- a/backend/src/routes/charger/get_chargers.rs +++ b/backend/src/routes/charger/get_chargers.rs @@ -142,7 +142,11 @@ mod tests { use rand_core::OsRng; use super::*; - use crate::{middleware::jwt::JwtMiddleware, routes::{charger::allow_user::UserAuth, user::tests::TestUser}, tests::configure}; + use crate::{ + middleware::jwt::JwtMiddleware, + routes::{charger::allow_user::UserAuth, user::tests::TestUser}, + tests::configure, + }; /// Test if only the chargers the user has access to will be returned. #[actix_web::test] @@ -154,7 +158,13 @@ mod tests { for _ in 0..5 { let _ = user1.add_random_charger().await; let charger = user2.add_random_charger().await; - user2.allow_user(&user1.mail, UserAuth::LoginKey(BASE64_STANDARD.encode(user1.get_login_key().await)), &charger).await; + user2 + .allow_user( + &user1.mail, + UserAuth::LoginKey(BASE64_STANDARD.encode(user1.get_login_key().await)), + &charger, + ) + .await; } for _ in 0..5 { let uuid = OsRng.next_u32() as i32; diff --git a/backend/src/routes/charger/get_key.rs b/backend/src/routes/charger/get_key.rs index 6294871..f4ac0d3 100644 --- a/backend/src/routes/charger/get_key.rs +++ b/backend/src/routes/charger/get_key.rs @@ -78,21 +78,23 @@ pub async fn get_key( let mut conn = get_connection(&state)?; web_block_unpacked(move || { - let conns_in_use: Vec = match wg_keys.filter(charger_id.eq(&cid)) + let conns_in_use: Vec = match wg_keys + .filter(charger_id.eq(&cid)) .filter(in_use.eq(true)) .select(WgKey::as_select()) .load(&mut conn) - { - Ok(used) => used, - Err(NotFound) => return Ok(()), - Err(_err) => return Err(Error::InternalError) - }; + { + Ok(used) => used, + Err(NotFound) => return Ok(()), + Err(_err) => return Err(Error::InternalError), + }; if conns_in_use.len() >= 5 { Err(Error::AllKeysInUse) } else { Ok(()) } - }).await?; + }) + .await?; let mut conn = get_connection(&state)?; let key: Option = web_block_unpacked(move || { diff --git a/backend/src/routes/charger/mod.rs b/backend/src/routes/charger/mod.rs index d20d55d..5c9df9f 100644 --- a/backend/src/routes/charger/mod.rs +++ b/backend/src/routes/charger/mod.rs @@ -47,7 +47,11 @@ pub fn configure(cfg: &mut web::ServiceConfig) { cfg.service(allow_user::allow_user); } -pub async fn get_charger_uuid(state: &web::Data, charger_uid: i32, user_id: uuid::Uuid) -> actix_web::Result> { +pub async fn get_charger_uuid( + state: &web::Data, + charger_uid: i32, + user_id: uuid::Uuid, +) -> actix_web::Result> { let mut conn = get_connection(state)?; web_block_unpacked(move || { use db_connector::schema::allowed_users::dsl as allowed_users; @@ -56,13 +60,15 @@ pub async fn get_charger_uuid(state: &web::Data, charger_uid: i32, use .filter(allowed_users::charger_uid.eq(charger_uid)) .filter(allowed_users::user_id.eq(user_id)) .select(AllowedUser::as_select()) - .get_result(&mut conn) { - Ok(u) => u, - Err(NotFound) => return Ok(None), - Err(_err) => return Err(Error::InternalError), - }; + .get_result(&mut conn) + { + Ok(u) => u, + Err(NotFound) => return Ok(None), + Err(_err) => return Err(Error::InternalError), + }; Ok(Some(allowed_user.charger_id)) - }).await + }) + .await } pub async fn user_is_allowed( diff --git a/backend/src/routes/charger/remove.rs b/backend/src/routes/charger/remove.rs index 1312b48..7af9f0e 100644 --- a/backend/src/routes/charger/remove.rs +++ b/backend/src/routes/charger/remove.rs @@ -34,7 +34,10 @@ pub struct DeleteChargerSchema { charger: String, } -pub async fn delete_all_keys(cid: uuid::Uuid, state: &web::Data) -> Result<(), actix_web::Error> { +pub async fn delete_all_keys( + cid: uuid::Uuid, + state: &web::Data, +) -> Result<(), actix_web::Error> { use db_connector::schema::wg_keys::dsl::*; let mut conn = get_connection(state)?; @@ -67,7 +70,10 @@ pub async fn delete_all_allowed_users( Ok(()) } -pub async fn delete_charger(charger: uuid::Uuid, state: &web::Data) -> actix_web::Result<()> { +pub async fn delete_charger( + charger: uuid::Uuid, + state: &web::Data, +) -> actix_web::Result<()> { use db_connector::schema::chargers::dsl::*; let mut conn = get_connection(&state)?; web_block_unpacked(move || { @@ -100,37 +106,60 @@ async fn is_last_user(cid: uuid::Uuid, state: &web::Data) -> actix_web let count: i64 = web_block_unpacked(move || { use db_connector::schema::allowed_users::dsl::*; - match allowed_users.filter(charger_id.eq(cid)).count().get_result(&mut conn) { + match allowed_users + .filter(charger_id.eq(cid)) + .count() + .get_result(&mut conn) + { Ok(c) => Ok(c), - Err(_err) => Err(Error::InternalError) + Err(_err) => Err(Error::InternalError), } - }).await?; + }) + .await?; Ok(count == 1) } -async fn delete_keys_for_user(cid: uuid::Uuid, uid: uuid::Uuid, state: &web::Data) -> actix_web::Result<()> { +async fn delete_keys_for_user( + cid: uuid::Uuid, + uid: uuid::Uuid, + state: &web::Data, +) -> actix_web::Result<()> { let mut conn = get_connection(state)?; web_block_unpacked(move || { use db_connector::schema::wg_keys::dsl::*; - match diesel::delete(wg_keys.filter(user_id.eq(uid)).filter(charger_id.eq(cid))).execute(&mut conn) { + match diesel::delete(wg_keys.filter(user_id.eq(uid)).filter(charger_id.eq(cid))) + .execute(&mut conn) + { Ok(_) => Ok(()), - Err(_err) => Err(Error::InternalError) + Err(_err) => Err(Error::InternalError), } - }).await?; + }) + .await?; Ok(()) } -async fn delete_allowed_user(cid: uuid::Uuid, uid: uuid::Uuid, state: &web::Data) -> actix_web::Result<()> { +async fn delete_allowed_user( + cid: uuid::Uuid, + uid: uuid::Uuid, + state: &web::Data, +) -> actix_web::Result<()> { let mut conn = get_connection(state)?; web_block_unpacked(move || { use db_connector::schema::allowed_users::dsl::*; - match diesel::delete(allowed_users.filter(user_id.eq(uid)).filter(charger_id.eq(cid))).execute(&mut conn) { + match diesel::delete( + allowed_users + .filter(user_id.eq(uid)) + .filter(charger_id.eq(cid)), + ) + .execute(&mut conn) + { Ok(_) => Ok(()), - Err(_err) => Err(Error::InternalError) + Err(_err) => Err(Error::InternalError), } - }).await?; + }) + .await?; Ok(()) } @@ -153,7 +182,6 @@ pub async fn remove( data: web::Json, bridge_state: web::Data, ) -> Result { - let charger_id = parse_uuid(&data.charger)?; if !user_is_allowed(&state, user_id.clone().into(), charger_id).await? { return Err(Error::Unauthorized.into()); @@ -166,7 +194,9 @@ pub async fn remove( let mut conn = get_connection(&state)?; web_block_unpacked(move || { use db_connector::schema::chargers::dsl as chargers; - match diesel::delete(chargers::chargers.filter(chargers::id.eq(charger_id))).execute(&mut conn) { + match diesel::delete(chargers::chargers.filter(chargers::id.eq(charger_id))) + .execute(&mut conn) + { Ok(_) => Ok(()), Err(_err) => Err(Error::InternalError), } @@ -197,7 +227,10 @@ pub(crate) mod tests { use crate::{ middleware::jwt::JwtMiddleware, - routes::{charger::allow_user::UserAuth, user::tests::{get_test_uuid, TestUser}}, + routes::{ + charger::allow_user::UserAuth, + user::tests::{get_test_uuid, TestUser}, + }, tests::configure, }; @@ -208,8 +241,7 @@ pub(crate) mod tests { let pool = test_connection_pool(); let mut conn = pool.get().unwrap(); - diesel::delete(wg_keys.filter(user_id.eq(uid))) - .execute(&mut conn)?; + diesel::delete(wg_keys.filter(user_id.eq(uid))).execute(&mut conn)?; Ok(()) } @@ -240,9 +272,11 @@ pub(crate) mod tests { { use db_connector::schema::allowed_users::dsl as allowed_users; - diesel::delete(allowed_users::allowed_users.filter(allowed_users::charger_id.eq(charger_id))) - .execute(&mut conn) - .unwrap(); + diesel::delete( + allowed_users::allowed_users.filter(allowed_users::charger_id.eq(charger_id)), + ) + .execute(&mut conn) + .unwrap(); } { use db_connector::schema::chargers::dsl as chargers; @@ -252,18 +286,32 @@ pub(crate) mod tests { } } - fn get_allowed_users_count(charger_id: uuid::Uuid, conn: &mut PooledConnection>) -> i64 { + fn get_allowed_users_count( + charger_id: uuid::Uuid, + conn: &mut PooledConnection>, + ) -> i64 { use db_connector::schema::allowed_users::dsl as allowed_users; - let count: i64 = allowed_users::allowed_users.filter(allowed_users::charger_id.eq(charger_id)).count().get_result(conn).unwrap(); + let count: i64 = allowed_users::allowed_users + .filter(allowed_users::charger_id.eq(charger_id)) + .count() + .get_result(conn) + .unwrap(); count } - fn get_wg_key_count(charger_id: uuid::Uuid, conn: &mut PooledConnection>) -> i64 { + fn get_wg_key_count( + charger_id: uuid::Uuid, + conn: &mut PooledConnection>, + ) -> i64 { use db_connector::schema::wg_keys::dsl as wg_keys; - let count: i64 = wg_keys::wg_keys.filter(wg_keys::charger_id.eq(charger_id)).count().get_result(conn).unwrap(); + let count: i64 = wg_keys::wg_keys + .filter(wg_keys::charger_id.eq(charger_id)) + .count() + .get_result(conn) + .unwrap(); count } @@ -319,10 +367,18 @@ pub(crate) mod tests { let (mut user2, _) = TestUser::random().await; let token = user2.login().await.to_owned(); let charger = user2.add_random_charger().await; - user2.allow_user(&user1.mail, UserAuth::LoginKey(BASE64_STANDARD.encode(user1.get_login_key().await)), &charger).await; + user2 + .allow_user( + &user1.mail, + UserAuth::LoginKey(BASE64_STANDARD.encode(user1.get_login_key().await)), + &charger, + ) + .await; let charger_id = uuid::Uuid::from_str(&charger.uuid).unwrap(); - let body = DeleteChargerSchema { charger: charger.uuid }; + let body = DeleteChargerSchema { + charger: charger.uuid, + }; let req = test::TestRequest::delete() .uri("/remove") .cookie(Cookie::new("access_token", token)) @@ -351,10 +407,18 @@ pub(crate) mod tests { let charger_uid = OsRng.next_u32() as i32; user2.login().await; let charger = user2.add_charger(charger_uid).await; - user2.allow_user(&email, UserAuth::LoginKey(BASE64_STANDARD.encode(user1.get_login_key().await)), &charger).await; + user2 + .allow_user( + &email, + UserAuth::LoginKey(BASE64_STANDARD.encode(user1.get_login_key().await)), + &charger, + ) + .await; let token = user1.login().await; - let body = DeleteChargerSchema { charger: charger.uuid.clone() }; + let body = DeleteChargerSchema { + charger: charger.uuid.clone(), + }; let req = test::TestRequest::delete() .uri("/remove") .set_json(body) @@ -387,7 +451,9 @@ pub(crate) mod tests { let charger = user2.add_charger(charger_uid).await; let token = user1.login().await; - let body = DeleteChargerSchema { charger: charger.uuid }; + let body = DeleteChargerSchema { + charger: charger.uuid, + }; let req = test::TestRequest::delete() .uri("/remove") .set_json(body) diff --git a/backend/src/routes/charger/update_note.rs b/backend/src/routes/charger/update_note.rs index c4aa62a..68ffde4 100644 --- a/backend/src/routes/charger/update_note.rs +++ b/backend/src/routes/charger/update_note.rs @@ -22,13 +22,16 @@ use diesel::{prelude::*, result::Error::NotFound, ExpressionMethods}; use serde::{Deserialize, Serialize}; use utoipa::ToSchema; -use crate::{error::Error, utils::{get_connection, parse_uuid, web_block_unpacked}, AppState}; +use crate::{ + error::Error, + utils::{get_connection, parse_uuid, web_block_unpacked}, + AppState, +}; - - #[derive(ToSchema, Deserialize, Serialize)] +#[derive(ToSchema, Deserialize, Serialize)] pub struct UpdateNoteSchema { pub charger_id: String, - pub note: String + pub note: String, } #[utoipa::path( @@ -47,8 +50,7 @@ pub async fn update_note( schema: web::Json, state: web::Data, uid: crate::models::uuid::Uuid, -) -> actix_web::Result -{ +) -> actix_web::Result { let cid = parse_uuid(&schema.charger_id)?; let mut conn = get_connection(&state)?; @@ -63,9 +65,10 @@ pub async fn update_note( { Ok(_) => Ok(()), Err(NotFound) => Err(Error::ChargerDoesNotExist), - Err(_err) => Err(Error::InternalError) + Err(_err) => Err(Error::InternalError), } - }).await?; + }) + .await?; Ok(HttpResponse::Ok()) } @@ -77,12 +80,15 @@ mod tests { use actix_web::{cookie::Cookie, test, App}; use db_connector::{models::allowed_users::AllowedUser, test_connection_pool}; + use crate::{ + middleware::jwt::JwtMiddleware, + routes::user::tests::{get_test_uuid, TestUser}, + tests::configure, + }; use diesel::prelude::*; - use crate::{middleware::jwt::JwtMiddleware, routes::user::tests::{get_test_uuid, TestUser}, tests::configure}; use super::{update_note, UpdateNoteSchema}; - #[actix_web::test] async fn test_update_note() { let (mut user, _) = TestUser::random().await; @@ -102,7 +108,10 @@ mod tests { let req = test::TestRequest::post() .uri("/update_note") - .cookie(Cookie::new("access_token", user.access_token.as_ref().unwrap())) + .cookie(Cookie::new( + "access_token", + user.access_token.as_ref().unwrap(), + )) .set_json(schema) .to_request(); let resp = test::call_service(&app, req).await; @@ -144,7 +153,10 @@ mod tests { let req = test::TestRequest::post() .uri("/update_note") - .cookie(Cookie::new("access_token", user.access_token.as_ref().unwrap())) + .cookie(Cookie::new( + "access_token", + user.access_token.as_ref().unwrap(), + )) .set_json(schema) .to_request(); let resp = test::call_service(&app, req).await; diff --git a/backend/src/routes/management.rs b/backend/src/routes/management.rs index c4f6697..87ff98e 100644 --- a/backend/src/routes/management.rs +++ b/backend/src/routes/management.rs @@ -30,7 +30,10 @@ use serde::{Deserialize, Serialize}; use utoipa::ToSchema; use crate::{ - error::Error, routes::{auth::login::FindBy, charger::add::get_charger_from_db, user::get_user_id}, utils::{get_charger_by_uid, get_connection, parse_uuid, web_block_unpacked}, AppState, BridgeState + error::Error, + routes::{auth::login::FindBy, charger::add::get_charger_from_db, user::get_user_id}, + utils::{get_charger_by_uid, get_connection, parse_uuid, web_block_unpacked}, + AppState, BridgeState, }; use super::charger::add::password_matches; @@ -75,13 +78,13 @@ pub struct ManagementDataVersion1 { pub struct ManagementResponseSchema { pub time: u64, pub configured_users: Vec, - pub uuid: Option + pub uuid: Option, } async fn update_configured_users( state: &web::Data, charger_id: uuid::Uuid, - data: &ManagementDataVersion + data: &ManagementDataVersion, ) -> actix_web::Result> { let configured_users = if let ManagementDataVersion::V2(data) = data { // Get uuids of configured users on wallbox @@ -94,9 +97,13 @@ async fn update_configured_users( if let Some(name) = &user.name { // Update name of charger for each user let mut conn = get_connection(&state)?; - match diesel::update(allowed_users::allowed_users.filter(allowed_users::user_id.eq(u)).filter(allowed_users::charger_id.eq(charger_id))) - .set(allowed_users::name.eq(name)) - .execute(&mut conn) + match diesel::update( + allowed_users::allowed_users + .filter(allowed_users::user_id.eq(u)) + .filter(allowed_users::charger_id.eq(charger_id)), + ) + .set(allowed_users::name.eq(name)) + .execute(&mut conn) { Ok(_) => (), Err(NotFound) => (), @@ -104,10 +111,9 @@ async fn update_configured_users( } } - configured_users.push(u); - }, - Err(_err) => continue + } + Err(_err) => continue, } } @@ -128,32 +134,37 @@ async fn update_configured_users( Err(_err) => return Err(Error::InternalError), }; - match diesel::delete(allowed_users::allowed_users - .filter(allowed_users::charger_id.eq(&charger_id)) - .filter(allowed_users::user_id.ne_all(configured_users_cpy)) - ) - .execute(&mut conn) + match diesel::delete( + allowed_users::allowed_users + .filter(allowed_users::charger_id.eq(&charger_id)) + .filter(allowed_users::user_id.ne_all(configured_users_cpy)), + ) + .execute(&mut conn) { Ok(_) => Ok(users_to_delete), Err(NotFound) => Ok(users_to_delete), Err(_err) => Err(Error::InternalError), } - }).await?; + }) + .await?; if deleted_users.len() > 0 { let mut conn = get_connection(&state)?; web_block_unpacked(move || { use db_connector::schema::wg_keys::dsl as wg_keys; - match diesel::delete(wg_keys::wg_keys - .filter(wg_keys::charger_id.eq(&charger_id)) - .filter(wg_keys::user_id.eq_any(deleted_users))) - .execute(&mut conn) + match diesel::delete( + wg_keys::wg_keys + .filter(wg_keys::charger_id.eq(&charger_id)) + .filter(wg_keys::user_id.eq_any(deleted_users)), + ) + .execute(&mut conn) { Ok(_) => Ok(()), Err(_err) => Err(Error::InternalError), } - }).await?; + }) + .await?; } // Get uuid of configured users on the server @@ -168,9 +179,10 @@ async fn update_configured_users( { Ok(u) => Ok(u.into_iter().map(|u: AllowedUser| u.user_id).collect()), Err(NotFound) => Ok(Vec::new()), - Err(_err) => Err(Error::InternalError) + Err(_err) => Err(Error::InternalError), } - }).await?; + }) + .await?; // Resolve the E-Mail for each user let mut conn = get_connection(state)?; @@ -186,7 +198,8 @@ async fn update_configured_users( Err(NotFound) => Ok(Vec::new()), Err(_err) => Err(Error::InternalError), } - }).await?; + }) + .await?; let mut configured_users = Vec::new(); for u in data.configured_users.iter() { @@ -246,7 +259,7 @@ pub async fn management( charger_id = parse_uuid(&data.id)?; let charger = get_charger_from_db(charger_id, &state).await?; if !password_matches(&data.password, &charger.password)? { - return Err(Error::ChargerCredentialsWrong.into()) + return Err(Error::ChargerCredentialsWrong.into()); } charger } @@ -360,11 +373,17 @@ mod tests { use super::*; use actix_web::{cookie::Cookie, test, App}; use base64::{prelude::BASE64_STANDARD, Engine}; - use db_connector::{models::{allowed_users::AllowedUser, wg_keys::WgKey}, test_connection_pool}; + use db_connector::{ + models::{allowed_users::AllowedUser, wg_keys::WgKey}, + test_connection_pool, + }; use rand::distributions::{Alphanumeric, DistString}; use crate::{ - routes::{charger::allow_user::UserAuth, user::tests::{get_test_uuid, TestUser}}, + routes::{ + charger::allow_user::UserAuth, + user::tests::{get_test_uuid, TestUser}, + }, tests::configure, }; @@ -382,7 +401,10 @@ mod tests { password: charger.password, port: 0, firmware_version: "2.3.1".to_string(), - configured_users: vec![ConfiguredUser {email: mail, name: Some(String::new())}], + configured_users: vec![ConfiguredUser { + email: mail, + name: Some(String::new()), + }], }); let body = ManagementSchema { @@ -483,7 +505,10 @@ mod tests { password: Alphanumeric.sample_string(&mut rand::thread_rng(), 32), port: 0, firmware_version: "2.3.1".to_string(), - configured_users: vec![ConfiguredUser {email: mail, name: Some(String::new())}], + configured_users: vec![ConfiguredUser { + email: mail, + name: Some(String::new()), + }], }); let body = ManagementSchema { id: None, @@ -542,7 +567,12 @@ mod tests { let charger = user.add_random_charger().await; let (mut user2, mail2) = TestUser::random().await; user2.login().await; - user.allow_user(&mail2, UserAuth::LoginKey(BASE64_STANDARD.encode(&user2.get_login_key().await)), &charger).await; + user.allow_user( + &mail2, + UserAuth::LoginKey(BASE64_STANDARD.encode(&user2.get_login_key().await)), + &charger, + ) + .await; let app = App::new().configure(configure).service(management); let app = test::init_service(app).await; @@ -552,7 +582,10 @@ mod tests { password: charger.password, port: 0, firmware_version: "2.3.1".to_string(), - configured_users: vec![ConfiguredUser {email: mail, name: Some(String::new())}], + configured_users: vec![ConfiguredUser { + email: mail, + name: Some(String::new()), + }], }); let body = ManagementSchema { @@ -605,7 +638,12 @@ mod tests { let charger = user.add_random_charger().await; let (mut user2, mail2) = TestUser::random().await; user2.login().await; - user.allow_user(&mail2, UserAuth::LoginKey(BASE64_STANDARD.encode(&user2.get_login_key().await)), &charger).await; + user.allow_user( + &mail2, + UserAuth::LoginKey(BASE64_STANDARD.encode(&user2.get_login_key().await)), + &charger, + ) + .await; { use db_connector::schema::allowed_users::dsl::*; @@ -613,7 +651,9 @@ mod tests { let pool = test_connection_pool(); let mut conn = pool.get().unwrap(); let uuid = get_test_uuid(&mail2).unwrap(); - diesel::delete(allowed_users.filter(user_id.eq(&uuid))).execute(&mut conn).unwrap(); + diesel::delete(allowed_users.filter(user_id.eq(&uuid))) + .execute(&mut conn) + .unwrap(); } let app = App::new().configure(configure).service(management); @@ -624,7 +664,16 @@ mod tests { password: charger.password, port: 0, firmware_version: "2.3.1".to_string(), - configured_users: vec![ConfiguredUser {email: mail, name: Some(String::new())}, ConfiguredUser {email: mail2.clone(), name: Some(String::new())}], + configured_users: vec![ + ConfiguredUser { + email: mail, + name: Some(String::new()), + }, + ConfiguredUser { + email: mail2.clone(), + name: Some(String::new()), + }, + ], }); let body = ManagementSchema { @@ -669,7 +718,12 @@ mod tests { let mail2 = { let (mut user2, mail2) = TestUser::random().await; user2.login().await; - user.allow_user(&mail2, UserAuth::LoginKey(BASE64_STANDARD.encode(&user2.get_login_key().await)), &charger).await; + user.allow_user( + &mail2, + UserAuth::LoginKey(BASE64_STANDARD.encode(&user2.get_login_key().await)), + &charger, + ) + .await; mail2 }; @@ -682,7 +736,16 @@ mod tests { password: charger.password, port: 0, firmware_version: "2.3.1".to_string(), - configured_users: vec![ConfiguredUser {email: mail, name: Some(String::new())}, ConfiguredUser {email: mail2.clone(), name: Some(String::new())}], + configured_users: vec![ + ConfiguredUser { + email: mail, + name: Some(String::new()), + }, + ConfiguredUser { + email: mail2.clone(), + name: Some(String::new()), + }, + ], }); let body = ManagementSchema { diff --git a/backend/src/routes/selfdestruct.rs b/backend/src/routes/selfdestruct.rs index 288ff18..f2c8e7a 100644 --- a/backend/src/routes/selfdestruct.rs +++ b/backend/src/routes/selfdestruct.rs @@ -18,18 +18,21 @@ pub struct SelfdestructSchema { pub password: String, } -async fn get_charger(schema: SelfdestructSchema, state: &web::Data) -> actix_web::Result { +async fn get_charger( + schema: SelfdestructSchema, + state: &web::Data, +) -> actix_web::Result { if let Some(uuid) = schema.uuid { let charger_id = parse_uuid(&uuid)?; let charger = get_charger_from_db(charger_id, state).await?; if !password_matches(&schema.password, &charger.password)? { - return Err(Error::ChargerCredentialsWrong.into()) + return Err(Error::ChargerCredentialsWrong.into()); } Ok(charger) } else if let Some(uid) = schema.id { Ok(get_charger_by_uid(uid, Some(schema.password), state).await?) } else { - return Err(Error::ChargerCredentialsWrong.into()) + return Err(Error::ChargerCredentialsWrong.into()); } } diff --git a/backend/src/routes/state.rs b/backend/src/routes/state.rs index 33c02d8..f4d0263 100644 --- a/backend/src/routes/state.rs +++ b/backend/src/routes/state.rs @@ -82,7 +82,14 @@ pub async fn state(brige_state: web::Data) -> actix_web::Result)> = { let map = brige_state.lost_connections.lock().unwrap(); - map.iter().map(|(id, conns)| (id.to_string(), conns.into_iter().map(|(conn_no, _)| *conn_no).collect())).collect() + map.iter() + .map(|(id, conns)| { + ( + id.to_string(), + conns.into_iter().map(|(conn_no, _)| *conn_no).collect(), + ) + }) + .collect() }; let state = ServerState { diff --git a/backend/src/routes/user/delete.rs b/backend/src/routes/user/delete.rs index 19e0757..c75e8f3 100644 --- a/backend/src/routes/user/delete.rs +++ b/backend/src/routes/user/delete.rs @@ -4,37 +4,61 @@ use diesel::{prelude::*, result::Error::NotFound}; use serde::{Deserialize, Serialize}; use utoipa::ToSchema; -use crate::{error::Error, routes::{auth::login::{validate_password, FindBy}, charger::remove::{delete_all_allowed_users, delete_all_keys, delete_charger, remove_charger_from_state}, user::logout::delete_all_refresh_tokens}, utils::{get_connection, web_block_unpacked}, AppState, BridgeState}; +use crate::{ + error::Error, + routes::{ + auth::login::{validate_password, FindBy}, + charger::remove::{ + delete_all_allowed_users, delete_all_keys, delete_charger, remove_charger_from_state, + }, + user::logout::delete_all_refresh_tokens, + }, + utils::{get_connection, web_block_unpacked}, + AppState, BridgeState, +}; #[derive(ToSchema, Serialize, Deserialize)] pub struct DeleteUserSchema { #[schema(value_type = Vec)] - pub login_key: Vec + pub login_key: Vec, } -async fn get_all_chargers_for_user(user_id: uuid::Uuid, state: &web::Data) -> actix_web::Result> { +async fn get_all_chargers_for_user( + user_id: uuid::Uuid, + state: &web::Data, +) -> actix_web::Result> { let mut conn = get_connection(state)?; let allowed_users: Vec = web_block_unpacked(move || { use db_connector::schema::allowed_users::dsl as allowed_users; - match allowed_users::allowed_users.filter(allowed_users::user_id.eq(user_id)).select(AllowedUser::as_select()).load(&mut conn) { + match allowed_users::allowed_users + .filter(allowed_users::user_id.eq(user_id)) + .select(AllowedUser::as_select()) + .load(&mut conn) + { Ok(v) => Ok(v), Err(NotFound) => Ok(Vec::new()), Err(_err) => Err(Error::InternalError), } - }).await?; + }) + .await?; let charger_ids: Vec = allowed_users.into_iter().map(|u| u.charger_id).collect(); let mut conn = get_connection(state)?; web_block_unpacked(move || { use db_connector::schema::chargers::dsl::*; - match chargers.filter(id.eq_any(charger_ids)).select(Charger::as_select()).load(&mut conn) { + match chargers + .filter(id.eq_any(charger_ids)) + .select(Charger::as_select()) + .load(&mut conn) + { Ok(v) => Ok(v), Err(NotFound) => Ok(Vec::new()), Err(_err) => Err(Error::InternalError), } - }).await + }) + .await } #[utoipa::path( @@ -47,7 +71,12 @@ async fn get_all_chargers_for_user(user_id: uuid::Uuid, state: &web::Data, bridge_state: web::Data, user_id: crate::models::uuid::Uuid, payload: web::Json) -> actix_web::Result { +pub async fn delete_user( + state: web::Data, + bridge_state: web::Data, + user_id: crate::models::uuid::Uuid, + payload: web::Json, +) -> actix_web::Result { let user_id = user_id.into(); let conn = get_connection(&state)?; @@ -72,9 +101,10 @@ pub async fn delete_user(state: web::Data, bridge_state: web::Data { println!("err: {:?}", _err); Err(Error::InternalError) - }, + } } - }).await?; + }) + .await?; Ok(HttpResponse::Ok()) } @@ -84,14 +114,24 @@ mod tests { use std::str::FromStr; use actix_web::{cookie::Cookie, test, App}; - use db_connector::{models::{allowed_users::AllowedUser, chargers::Charger, users::User, wg_keys::WgKey}, test_connection_pool}; + use db_connector::{ + models::{allowed_users::AllowedUser, chargers::Charger, users::User, wg_keys::WgKey}, + test_connection_pool, + }; use diesel::{prelude::*, result::Error::NotFound}; - use crate::{middleware::jwt::JwtMiddleware, routes::{auth::get_login_salt::tests::get_test_login_salt, user::tests::{get_test_uuid, hash_test_key, TestUser}}, tests::configure, utils::generate_random_bytes}; + use crate::{ + middleware::jwt::JwtMiddleware, + routes::{ + auth::get_login_salt::tests::get_test_login_salt, + user::tests::{get_test_uuid, hash_test_key, TestUser}, + }, + tests::configure, + utils::generate_random_bytes, + }; use super::{delete_user, DeleteUserSchema}; - //TODO: add test for shared charger once it is merged #[actix_web::test] async fn test_delete() { @@ -112,9 +152,7 @@ mod tests { let login_salt = get_test_login_salt(&user1_mail).await; let login_key = hash_test_key(&user1.password, &login_salt, None); - let schema = DeleteUserSchema { - login_key - }; + let schema = DeleteUserSchema { login_key }; let req = test::TestRequest::delete() .uri("/delete") .cookie(Cookie::new("access_token", token)) @@ -130,10 +168,16 @@ mod tests { { use db_connector::schema::allowed_users::dsl::*; - let res = allowed_users.filter(user_id.eq(uid1)).select(AllowedUser::as_select()).get_result(&mut conn); + let res = allowed_users + .filter(user_id.eq(uid1)) + .select(AllowedUser::as_select()) + .get_result(&mut conn); assert_eq!(res, Err(NotFound)); - let res = allowed_users.filter(user_id.eq(uid2)).select(AllowedUser::as_select()).get_result(&mut conn); + let res = allowed_users + .filter(user_id.eq(uid2)) + .select(AllowedUser::as_select()) + .get_result(&mut conn); assert!(res.is_ok()); } let uuid = uuid::Uuid::from_str(&charger.uuid).unwrap(); @@ -141,29 +185,47 @@ mod tests { { use db_connector::schema::chargers::dsl::*; - let res = chargers.filter(id.eq(uuid)).select(Charger::as_select()).get_result(&mut conn); + let res = chargers + .filter(id.eq(uuid)) + .select(Charger::as_select()) + .get_result(&mut conn); assert_eq!(res, Err(NotFound)); - let res = chargers.filter(id.eq(uuid2)).select(Charger::as_select()).get_result(&mut conn); + let res = chargers + .filter(id.eq(uuid2)) + .select(Charger::as_select()) + .get_result(&mut conn); assert!(res.is_ok()); } { use db_connector::schema::wg_keys::dsl::*; let uuid = uuid::Uuid::from_str(&charger.uuid).unwrap(); - let res = wg_keys.filter(charger_id.eq(uuid)).select(WgKey::as_select()).get_result(&mut conn); + let res = wg_keys + .filter(charger_id.eq(uuid)) + .select(WgKey::as_select()) + .get_result(&mut conn); assert_eq!(res, Err(NotFound)); - let res = wg_keys.filter(charger_id.eq(uuid2)).select(WgKey::as_select()).get_result(&mut conn); + let res = wg_keys + .filter(charger_id.eq(uuid2)) + .select(WgKey::as_select()) + .get_result(&mut conn); assert!(res.is_ok()); } { use db_connector::schema::users::dsl::*; - let res = users.find(uid1).select(User::as_select()).get_result(&mut conn); + let res = users + .find(uid1) + .select(User::as_select()) + .get_result(&mut conn); assert_eq!(res, Err(NotFound)); - let res = users.find(uid2).select(User::as_select()).get_result(&mut conn); + let res = users + .find(uid2) + .select(User::as_select()) + .get_result(&mut conn); assert!(res.is_ok()); } } @@ -186,7 +248,7 @@ mod tests { let app = test::init_service(app).await; let schema = DeleteUserSchema { - login_key: generate_random_bytes() + login_key: generate_random_bytes(), }; let req = test::TestRequest::delete() .uri("/delete") @@ -203,10 +265,16 @@ mod tests { { use db_connector::schema::allowed_users::dsl::*; - let res = allowed_users.filter(user_id.eq(uid1)).select(AllowedUser::as_select()).get_result(&mut conn); + let res = allowed_users + .filter(user_id.eq(uid1)) + .select(AllowedUser::as_select()) + .get_result(&mut conn); assert!(res.is_ok()); - let res = allowed_users.filter(user_id.eq(uid2)).select(AllowedUser::as_select()).get_result(&mut conn); + let res = allowed_users + .filter(user_id.eq(uid2)) + .select(AllowedUser::as_select()) + .get_result(&mut conn); assert!(res.is_ok()); } let uuid = uuid::Uuid::from_str(&charger.uuid).unwrap(); @@ -214,28 +282,46 @@ mod tests { { use db_connector::schema::chargers::dsl::*; - let res = chargers.filter(id.eq(uuid)).select(Charger::as_select()).get_result(&mut conn); + let res = chargers + .filter(id.eq(uuid)) + .select(Charger::as_select()) + .get_result(&mut conn); assert!(res.is_ok()); - let res = chargers.filter(id.eq(uuid2)).select(Charger::as_select()).get_result(&mut conn); + let res = chargers + .filter(id.eq(uuid2)) + .select(Charger::as_select()) + .get_result(&mut conn); assert!(res.is_ok()); } { use db_connector::schema::wg_keys::dsl::*; - let res = wg_keys.filter(charger_id.eq(uuid)).select(WgKey::as_select()).get_result(&mut conn); + let res = wg_keys + .filter(charger_id.eq(uuid)) + .select(WgKey::as_select()) + .get_result(&mut conn); assert!(res.is_ok()); - let res = wg_keys.filter(charger_id.eq(uuid2)).select(WgKey::as_select()).get_result(&mut conn); + let res = wg_keys + .filter(charger_id.eq(uuid2)) + .select(WgKey::as_select()) + .get_result(&mut conn); assert!(res.is_ok()); } { use db_connector::schema::users::dsl::*; - let res = users.find(uid1).select(User::as_select()).get_result(&mut conn); + let res = users + .find(uid1) + .select(User::as_select()) + .get_result(&mut conn); assert!(res.is_ok()); - let res = users.find(uid2).select(User::as_select()).get_result(&mut conn); + let res = users + .find(uid2) + .select(User::as_select()) + .get_result(&mut conn); assert!(res.is_ok()); } } diff --git a/backend/src/routes/user/mod.rs b/backend/src/routes/user/mod.rs index dcb1b73..a61bfc9 100644 --- a/backend/src/routes/user/mod.rs +++ b/backend/src/routes/user/mod.rs @@ -17,12 +17,12 @@ * Boston, MA 02111-1307, USA. */ +pub mod delete; pub mod get_secret; pub mod logout; pub mod me; pub mod update_password; pub mod update_user; -pub mod delete; use crate::{ error::Error, @@ -150,7 +150,8 @@ pub mod tests { charger::{ add::tests::add_test_charger, allow_user::{tests::add_allowed_test_user, UserAuth}, - remove::tests::{remove_allowed_test_users, remove_test_charger, remove_test_keys}, tests::TestCharger, + remove::tests::{remove_allowed_test_users, remove_test_charger, remove_test_keys}, + tests::TestCharger, }, }, tests::configure, @@ -320,7 +321,12 @@ pub mod tests { charger } - pub async fn allow_user(&mut self, email: &str, user_auth: UserAuth, charger: &TestCharger) { + pub async fn allow_user( + &mut self, + email: &str, + user_auth: UserAuth, + charger: &TestCharger, + ) { add_allowed_test_user(email, user_auth, charger).await; } diff --git a/backend/src/udp_server/management.rs b/backend/src/udp_server/management.rs index 39dc91d..4d68b79 100644 --- a/backend/src/udp_server/management.rs +++ b/backend/src/udp_server/management.rs @@ -35,39 +35,44 @@ pub struct RemoteConnMeta { impl Serialize for RemoteConnMeta { fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer { - let mut s =serializer.serialize_struct("RemoteConnMeta", 2)?; + where + S: serde::Serializer, + { + let mut s = serializer.serialize_struct("RemoteConnMeta", 2)?; s.serialize_field("charger_id", &self.charger_id.to_string())?; s.serialize_field("conn_no", &self.conn_no)?; s.end() } } -fn process_old_packet(state: &web::Data, data: &[u8]) -> anyhow::Result { - let packet: OldManagementResponse = unsafe { - std::ptr::read(data.as_ptr() as *const _) - }; +fn process_old_packet( + state: &web::Data, + data: &[u8], +) -> anyhow::Result { + let packet: OldManagementResponse = unsafe { std::ptr::read(data.as_ptr() as *const _) }; let map = state.port_discovery.lock().unwrap(); for (meta, _) in map.iter() { - if meta.connection_no == packet.connection_no && meta.connection_uuid == packet.connection_uuid { - return Ok(meta.clone()) + if meta.connection_no == packet.connection_no + && meta.connection_uuid == packet.connection_uuid + { + return Ok(meta.clone()); } } Err(Error::msg("Unknown connection")) } -fn unpack_packet(state: &web::Data, data: &[u8]) -> anyhow::Result { +fn unpack_packet( + state: &web::Data, + data: &[u8], +) -> anyhow::Result { if data.len() == ::core::mem::size_of::() { process_old_packet(state, data) } else if data.len() == ::core::mem::size_of::() { - let packet: ManagementResponsePacket = unsafe { - std::ptr::read(data.as_ptr() as *const _) - }; + let packet: ManagementResponsePacket = unsafe { std::ptr::read(data.as_ptr() as *const _) }; if packet.header.magic != 0x1234 || packet.header.version != 1 { - return Err(Error::msg("Not a valid ManagementResponse packet")) + return Err(Error::msg("Not a valid ManagementResponse packet")); } Ok(packet.data) @@ -76,7 +81,11 @@ fn unpack_packet(state: &web::Data, data: &[u8]) -> anyhow::Result< } } -pub fn try_port_discovery(state: &web::Data, data: &[u8], addr: SocketAddr) -> anyhow::Result<()> { +pub fn try_port_discovery( + state: &web::Data, + data: &[u8], + addr: SocketAddr, +) -> anyhow::Result<()> { let response = unpack_packet(state, data)?; { diff --git a/backend/src/udp_server/multiplex.rs b/backend/src/udp_server/multiplex.rs index 9cd3f4b..6807622 100644 --- a/backend/src/udp_server/multiplex.rs +++ b/backend/src/udp_server/multiplex.rs @@ -233,16 +233,23 @@ pub fn run_server(state: web::Data, thread_pool: ThreadPool) { v.insert(tunn_data.clone()); let tunn = tunn_data.clone(); let mut lost_map = state.lost_connections.lock().unwrap(); - let mut undiscovered_clients = state.undiscovered_clients.lock().unwrap(); + let mut undiscovered_clients = + state.undiscovered_clients.lock().unwrap(); if let Some(conns) = lost_map.remove(&id) { for (conn_no, recipient) in conns.into_iter() { let meta = RemoteConnMeta { charger_id: id, - conn_no + conn_no, }; undiscovered_clients.insert(meta, recipient); - open_connection(conn_no, id, tunn.clone(), state.port_discovery.clone()).ok(); + open_connection( + conn_no, + id, + tunn.clone(), + state.port_discovery.clone(), + ) + .ok(); } } log::debug!("Adding management connection from {}", addr); diff --git a/backend/src/utils.rs b/backend/src/utils.rs index c5e1a6e..822c474 100644 --- a/backend/src/utils.rs +++ b/backend/src/utils.rs @@ -21,11 +21,13 @@ use std::str::FromStr; use actix_web::web; use db_connector::models::chargers::Charger; +use diesel::prelude::*; use diesel::{ - r2d2::{ConnectionManager, PooledConnection}, result::Error::NotFound, PgConnection + r2d2::{ConnectionManager, PooledConnection}, + result::Error::NotFound, + PgConnection, }; use rand::Rng; -use diesel::prelude::*; use crate::{error::Error, routes::charger::add::password_matches, AppState}; @@ -70,30 +72,40 @@ pub fn parse_uuid(uuid: &str) -> actix_web::Result { } } -pub async fn get_charger_by_uid(uid: i32, password: Option, state: &web::Data) -> actix_web::Result { +pub async fn get_charger_by_uid( + uid: i32, + password: Option, + state: &web::Data, +) -> actix_web::Result { let password = if let Some(password) = password { password } else { - return Err(actix_web::error::ErrorBadRequest("Password is missing")) + return Err(actix_web::error::ErrorBadRequest("Password is missing")); }; let mut conn = get_connection(state)?; let chargers: Vec = web_block_unpacked(move || { use db_connector::schema::chargers::dsl as chargers; - match chargers::chargers.filter(chargers::uid.eq(uid)).select(Charger::as_select()).load(&mut conn) { + match chargers::chargers + .filter(chargers::uid.eq(uid)) + .select(Charger::as_select()) + .load(&mut conn) + { Ok(c) => Ok(c), Err(NotFound) => { println!("C"); - Err(Error::ChargerCredentialsWrong)}, + Err(Error::ChargerCredentialsWrong) + } Err(_err) => Err(Error::InternalError), } - }).await?; + }) + .await?; for c in chargers.into_iter() { println!("D"); if password_matches(&password, &c.password)? { - return Ok(c) + return Ok(c); } } diff --git a/backend/src/ws_udp_bridge.rs b/backend/src/ws_udp_bridge.rs index 7202873..e9d1255 100644 --- a/backend/src/ws_udp_bridge.rs +++ b/backend/src/ws_udp_bridge.rs @@ -341,7 +341,8 @@ async fn start_ws( return Err(Error::InternalError); } Ok(()) - }).await?; + }) + .await?; } resp