diff --git a/src/api/admin.rs b/src/api/admin.rs index a897be1..4bd3f28 100644 --- a/src/api/admin.rs +++ b/src/api/admin.rs @@ -1,22 +1,26 @@ use once_cell::sync::Lazy; -use serde_json::Value; use serde::de::DeserializeOwned; +use serde_json::Value; use std::process::Command; -use rocket::http::{Cookie, Cookies, SameSite}; -use rocket::request::{self, FlashMessage, Form, FromRequest, Request}; -use rocket::response::{content::Html, Flash, Redirect}; -use rocket::{Outcome, Route}; +use rocket::{ + http::{Cookie, Cookies, SameSite}, + request::{self, FlashMessage, Form, FromRequest, Request}, + response::{content::Html, Flash, Redirect}, + Outcome, Route, +}; use rocket_contrib::json::Json; -use crate::api::{ApiResult, EmptyResult, JsonResult}; -use crate::auth::{decode_admin, encode_jwt, generate_admin_claims, ClientIp}; -use crate::config::ConfigBuilder; -use crate::db::{backup_database, models::*, DbConn}; -use crate::error::Error; -use crate::mail; -use crate::util::get_display_size; -use crate::CONFIG; +use crate::{ + api::{ApiResult, EmptyResult, JsonResult}, + auth::{decode_admin, encode_jwt, generate_admin_claims, ClientIp}, + config::ConfigBuilder, + db::{backup_database, models::*, DbConn}, + error::{Error, MapResult}, + mail, + util::get_display_size, + CONFIG, +}; pub fn routes() -> Vec { if !CONFIG.disable_admin_token() && !CONFIG.is_admin_token_set() { @@ -270,21 +274,13 @@ fn users_overview(_token: AdminToken, conn: DbConn) -> ApiResult> { #[post("/users//delete")] fn delete_user(uuid: String, _token: AdminToken, conn: DbConn) -> EmptyResult { - let user = match User::find_by_uuid(&uuid, &conn) { - Some(user) => user, - None => err!("User doesn't exist"), - }; - + let user = User::find_by_uuid(&uuid, &conn).map_res("User doesn't exist")?; user.delete(&conn) } #[post("/users//deauth")] fn deauth_user(uuid: String, _token: AdminToken, conn: DbConn) -> EmptyResult { - let mut user = match User::find_by_uuid(&uuid, &conn) { - Some(user) => user, - None => err!("User doesn't exist"), - }; - + let mut user = User::find_by_uuid(&uuid, &conn).map_res("User doesn't exist")?; Device::delete_all_by_user(&user.uuid, &conn)?; user.reset_security_stamp(); @@ -293,11 +289,7 @@ fn deauth_user(uuid: String, _token: AdminToken, conn: DbConn) -> EmptyResult { #[post("/users//remove-2fa")] fn remove_2fa(uuid: String, _token: AdminToken, conn: DbConn) -> EmptyResult { - let mut user = match User::find_by_uuid(&uuid, &conn) { - Some(user) => user, - None => err!("User doesn't exist"), - }; - + let mut user = User::find_by_uuid(&uuid, &conn).map_res("User doesn't exist")?; TwoFactor::delete_all_by_user(&user.uuid, &conn)?; user.totp_recover = None; user.save(&conn) @@ -340,7 +332,7 @@ struct GitCommit { } fn get_github_api(url: &str) -> Result { - use reqwest::{header::USER_AGENT, blocking::Client}; + use reqwest::{blocking::Client, header::USER_AGENT}; use std::time::Duration; let github_api = Client::builder().build()?; diff --git a/src/api/core/accounts.rs b/src/api/core/accounts.rs index 31bcded..3f76900 100644 --- a/src/api/core/accounts.rs +++ b/src/api/core/accounts.rs @@ -1,19 +1,15 @@ use chrono::Utc; use rocket_contrib::json::Json; -use crate::db::models::*; -use crate::db::DbConn; +use crate::{ + api::{EmptyResult, JsonResult, JsonUpcase, Notify, NumberOrString, PasswordData, UpdateType}, + auth::{decode_delete, decode_invite, decode_verify_email, Headers}, + crypto, + db::{models::*, DbConn}, + mail, CONFIG, +}; -use crate::api::{EmptyResult, JsonResult, JsonUpcase, Notify, NumberOrString, PasswordData, UpdateType}; -use crate::auth::{decode_delete, decode_invite, decode_verify_email, Headers}; -use crate::crypto; -use crate::mail; - -use crate::CONFIG; - -use rocket::Route; - -pub fn routes() -> Vec { +pub fn routes() -> Vec { routes![ register, profile, diff --git a/src/api/core/ciphers.rs b/src/api/core/ciphers.rs index 3eac10b..0180266 100644 --- a/src/api/core/ciphers.rs +++ b/src/api/core/ciphers.rs @@ -1,26 +1,20 @@ use std::collections::{HashMap, HashSet}; use std::path::Path; -use rocket::http::ContentType; -use rocket::{request::Form, Data, Route}; - +use rocket::{http::ContentType, request::Form, Data, Route}; use rocket_contrib::json::Json; use serde_json::Value; -use multipart::server::save::SavedData; -use multipart::server::{Multipart, SaveResult}; - use data_encoding::HEXLOWER; +use multipart::server::{save::SavedData, Multipart, SaveResult}; -use crate::db::models::*; -use crate::db::DbConn; - -use crate::crypto; - -use crate::api::{self, EmptyResult, JsonResult, JsonUpcase, Notify, PasswordData, UpdateType}; -use crate::auth::Headers; - -use crate::CONFIG; +use crate::{ + api::{self, EmptyResult, JsonResult, JsonUpcase, Notify, PasswordData, UpdateType}, + auth::Headers, + crypto, + db::{models::*, DbConn}, + CONFIG, +}; pub fn routes() -> Vec { routes![ @@ -617,9 +611,8 @@ fn share_cipher_by_uuid( match data.Cipher.OrganizationId.clone() { // If we don't get an organization ID, we don't do anything // No error because this is used when using the Clone functionality - None => {}, + None => {} Some(organization_uuid) => { - for uuid in &data.CollectionIds { match Collection::find_by_uuid_and_org(uuid, &organization_uuid, &conn) { None => err!("Invalid collection ID provided"), diff --git a/src/api/core/folders.rs b/src/api/core/folders.rs index a3a682d..63bf40e 100644 --- a/src/api/core/folders.rs +++ b/src/api/core/folders.rs @@ -1,15 +1,13 @@ use rocket_contrib::json::Json; use serde_json::Value; -use crate::db::models::*; -use crate::db::DbConn; +use crate::{ + api::{EmptyResult, JsonResult, JsonUpcase, Notify, UpdateType}, + auth::Headers, + db::{models::*, DbConn}, +}; -use crate::api::{EmptyResult, JsonResult, JsonUpcase, Notify, UpdateType}; -use crate::auth::Headers; - -use rocket::Route; - -pub fn routes() -> Vec { +pub fn routes() -> Vec { routes![ get_folders, get_folder, diff --git a/src/api/core/mod.rs b/src/api/core/mod.rs index 9b0b5f4..a925468 100644 --- a/src/api/core/mod.rs +++ b/src/api/core/mod.rs @@ -29,14 +29,15 @@ pub fn routes() -> Vec { // Move this somewhere else // use rocket::Route; - use rocket_contrib::json::Json; use serde_json::Value; -use crate::api::{EmptyResult, JsonResult, JsonUpcase}; -use crate::auth::Headers; -use crate::db::DbConn; -use crate::error::Error; +use crate::{ + api::{EmptyResult, JsonResult, JsonUpcase}, + auth::Headers, + db::DbConn, + error::Error, +}; #[put("/devices/identifier//clear-token")] fn clear_device_token(uuid: String) -> EmptyResult { @@ -146,7 +147,7 @@ fn hibp_breach(username: String) -> JsonResult { username ); - use reqwest::{header::USER_AGENT, blocking::Client}; + use reqwest::{blocking::Client, header::USER_AGENT}; if let Some(api_key) = crate::CONFIG.hibp_api_key() { let hibp_client = Client::builder().build()?; diff --git a/src/api/core/organizations.rs b/src/api/core/organizations.rs index 8adacda..b4ec4d8 100644 --- a/src/api/core/organizations.rs +++ b/src/api/core/organizations.rs @@ -1,17 +1,14 @@ -use rocket::request::Form; -use rocket::Route; +use num_traits::FromPrimitive; +use rocket::{request::Form, Route}; use rocket_contrib::json::Json; use serde_json::Value; -use num_traits::FromPrimitive; -use crate::api::{ - EmptyResult, JsonResult, JsonUpcase, JsonUpcaseVec, Notify, NumberOrString, PasswordData, UpdateType, +use crate::{ + api::{EmptyResult, JsonResult, JsonUpcase, JsonUpcaseVec, Notify, NumberOrString, PasswordData, UpdateType}, + auth::{decode_invite, AdminHeaders, Headers, OwnerHeaders}, + db::{models::*, DbConn}, + mail, CONFIG, }; -use crate::auth::{decode_invite, AdminHeaders, Headers, OwnerHeaders}; -use crate::db::models::*; -use crate::db::DbConn; -use crate::mail; -use crate::CONFIG; pub fn routes() -> Vec { routes![ @@ -935,7 +932,7 @@ fn list_policies_token(org_id: String, token: String, conn: DbConn) -> JsonResul if invite_org_id != org_id { err!("Token doesn't match request organization"); } - + // TODO: We receive the invite token as ?token=<>, validate it contains the org id let policies = OrgPolicy::find_by_org(&org_id, &conn); let policies_json: Vec = policies.iter().map(OrgPolicy::to_json).collect(); diff --git a/src/api/core/two_factor/authenticator.rs b/src/api/core/two_factor/authenticator.rs index 6b65137..f4bd5df 100644 --- a/src/api/core/two_factor/authenticator.rs +++ b/src/api/core/two_factor/authenticator.rs @@ -2,13 +2,16 @@ use data_encoding::BASE32; use rocket::Route; use rocket_contrib::json::Json; -use crate::api::core::two_factor::_generate_recover_code; -use crate::api::{EmptyResult, JsonResult, JsonUpcase, NumberOrString, PasswordData}; -use crate::auth::{ClientIp, Headers}; -use crate::crypto; -use crate::db::{ - models::{TwoFactor, TwoFactorType}, - DbConn, +use crate::{ + api::{ + core::two_factor::_generate_recover_code, EmptyResult, JsonResult, JsonUpcase, NumberOrString, PasswordData, + }, + auth::{ClientIp, Headers}, + crypto, + db::{ + models::{TwoFactor, TwoFactorType}, + DbConn, + }, }; pub use crate::config::CONFIG; diff --git a/src/api/core/two_factor/duo.rs b/src/api/core/two_factor/duo.rs index 9e52110..18eda4b 100644 --- a/src/api/core/two_factor/duo.rs +++ b/src/api/core/two_factor/duo.rs @@ -3,16 +3,17 @@ use data_encoding::BASE64; use rocket::Route; use rocket_contrib::json::Json; -use crate::api::core::two_factor::_generate_recover_code; -use crate::api::{ApiResult, EmptyResult, JsonResult, JsonUpcase, PasswordData}; -use crate::auth::Headers; -use crate::crypto; -use crate::db::{ - models::{TwoFactor, TwoFactorType, User}, - DbConn, +use crate::{ + api::{core::two_factor::_generate_recover_code, ApiResult, EmptyResult, JsonResult, JsonUpcase, PasswordData}, + auth::Headers, + crypto, + db::{ + models::{TwoFactor, TwoFactorType, User}, + DbConn, + }, + error::MapResult, + CONFIG, }; -use crate::error::MapResult; -use crate::CONFIG; pub fn routes() -> Vec { routes![get_duo, activate_duo, activate_duo_put,] @@ -186,7 +187,7 @@ fn activate_duo_put(data: JsonUpcase, headers: Headers, conn: DbC fn duo_api_request(method: &str, path: &str, params: &str, data: &DuoData) -> EmptyResult { const AGENT: &str = "bitwarden_rs:Duo/1.0 (Rust)"; - use reqwest::{header::*, Method, blocking::Client}; + use reqwest::{blocking::Client, header::*, Method}; use std::str::FromStr; // https://duo.com/docs/authapi#api-details diff --git a/src/api/core/two_factor/email.rs b/src/api/core/two_factor/email.rs index 4d2b840..6aa6e01 100644 --- a/src/api/core/two_factor/email.rs +++ b/src/api/core/two_factor/email.rs @@ -1,20 +1,18 @@ +use chrono::{Duration, NaiveDateTime, Utc}; use rocket::Route; use rocket_contrib::json::Json; -use crate::api::core::two_factor::_generate_recover_code; -use crate::api::{EmptyResult, JsonResult, JsonUpcase, PasswordData}; -use crate::auth::Headers; -use crate::crypto; -use crate::db::{ - models::{TwoFactor, TwoFactorType}, - DbConn, +use crate::{ + api::{core::two_factor::_generate_recover_code, EmptyResult, JsonResult, JsonUpcase, PasswordData}, + auth::Headers, + crypto, + db::{ + models::{TwoFactor, TwoFactorType}, + DbConn, + }, + error::{Error, MapResult}, + mail, CONFIG, }; -use crate::error::Error; -use crate::mail; -use crate::CONFIG; - -use chrono::{Duration, NaiveDateTime, Utc}; -use std::ops::Add; pub fn routes() -> Vec { routes![get_email, send_email_login, send_email, email,] @@ -58,7 +56,7 @@ fn send_email_login(data: JsonUpcase, conn: DbConn) -> Empty /// Generate the token, save the data for later verification and send email to user pub fn send_token(user_uuid: &str, conn: &DbConn) -> EmptyResult { let type_ = TwoFactorType::Email as i32; - let mut twofactor = TwoFactor::find_by_user_and_type(user_uuid, type_, &conn)?; + let mut twofactor = TwoFactor::find_by_user_and_type(user_uuid, type_, &conn).map_res("Two factor not found")?; let generated_token = crypto::generate_token(CONFIG.email_token_size())?; @@ -67,7 +65,7 @@ pub fn send_token(user_uuid: &str, conn: &DbConn) -> EmptyResult { twofactor.data = twofactor_data.to_json(); twofactor.save(&conn)?; - mail::send_token(&twofactor_data.email, &twofactor_data.last_token?)?; + mail::send_token(&twofactor_data.email, &twofactor_data.last_token.map_res("Token is empty")?)?; Ok(()) } @@ -134,7 +132,7 @@ fn send_email(data: JsonUpcase, headers: Headers, conn: DbConn) - ); twofactor.save(&conn)?; - mail::send_token(&twofactor_data.email, &twofactor_data.last_token?)?; + mail::send_token(&twofactor_data.email, &twofactor_data.last_token.map_res("Token is empty")?)?; Ok(()) } @@ -158,7 +156,7 @@ fn email(data: JsonUpcase, headers: Headers, conn: DbConn) -> JsonRes } let type_ = TwoFactorType::EmailVerificationChallenge as i32; - let mut twofactor = TwoFactor::find_by_user_and_type(&user.uuid, type_, &conn)?; + let mut twofactor = TwoFactor::find_by_user_and_type(&user.uuid, type_, &conn).map_res("Two factor not found")?; let mut email_data = EmailTokenData::from_json(&twofactor.data)?; @@ -188,7 +186,7 @@ fn email(data: JsonUpcase, headers: Headers, conn: DbConn) -> JsonRes /// Validate the email code when used as TwoFactor token mechanism pub fn validate_email_code_str(user_uuid: &str, token: &str, data: &str, conn: &DbConn) -> EmptyResult { let mut email_data = EmailTokenData::from_json(&data)?; - let mut twofactor = TwoFactor::find_by_user_and_type(&user_uuid, TwoFactorType::Email as i32, &conn)?; + let mut twofactor = TwoFactor::find_by_user_and_type(&user_uuid, TwoFactorType::Email as i32, &conn).map_res("Two factor not found")?; let issued_token = match &email_data.last_token { Some(t) => t, _ => err!("No token available"), @@ -211,7 +209,7 @@ pub fn validate_email_code_str(user_uuid: &str, token: &str, data: &str, conn: & let date = NaiveDateTime::from_timestamp(email_data.token_sent, 0); let max_time = CONFIG.email_expiration_time() as i64; - if date.add(Duration::seconds(max_time)) < Utc::now().naive_utc() { + if date + Duration::seconds(max_time) < Utc::now().naive_utc() { err!("Token has expired") } diff --git a/src/api/core/two_factor/mod.rs b/src/api/core/two_factor/mod.rs index 4f07511..77e2cf2 100644 --- a/src/api/core/two_factor/mod.rs +++ b/src/api/core/two_factor/mod.rs @@ -3,12 +3,14 @@ use rocket::Route; use rocket_contrib::json::Json; use serde_json::Value; -use crate::api::{JsonResult, JsonUpcase, NumberOrString, PasswordData}; -use crate::auth::Headers; -use crate::crypto; -use crate::db::{ - models::{TwoFactor, User}, - DbConn, +use crate::{ + api::{JsonResult, JsonUpcase, NumberOrString, PasswordData}, + auth::Headers, + crypto, + db::{ + models::{TwoFactor, User}, + DbConn, + }, }; pub mod authenticator; diff --git a/src/api/core/two_factor/u2f.rs b/src/api/core/two_factor/u2f.rs index 47c7d17..7934ab6 100644 --- a/src/api/core/two_factor/u2f.rs +++ b/src/api/core/two_factor/u2f.rs @@ -2,19 +2,25 @@ use once_cell::sync::Lazy; use rocket::Route; use rocket_contrib::json::Json; use serde_json::Value; -use u2f::messages::{RegisterResponse, SignResponse, U2fSignRequest}; -use u2f::protocol::{Challenge, U2f}; -use u2f::register::Registration; - -use crate::api::core::two_factor::_generate_recover_code; -use crate::api::{ApiResult, EmptyResult, JsonResult, JsonUpcase, NumberOrString, PasswordData}; -use crate::auth::Headers; -use crate::db::{ - models::{TwoFactor, TwoFactorType}, - DbConn, +use u2f::{ + messages::{RegisterResponse, SignResponse, U2fSignRequest}, + protocol::{Challenge, U2f}, + register::Registration, +}; + +use crate::{ + api::{ + core::two_factor::_generate_recover_code, ApiResult, EmptyResult, JsonResult, JsonUpcase, NumberOrString, + PasswordData, + }, + auth::Headers, + db::{ + models::{TwoFactor, TwoFactorType}, + DbConn, + }, + error::Error, + CONFIG, }; -use crate::error::Error; -use crate::CONFIG; const U2F_VERSION: &str = "U2F_V2"; diff --git a/src/api/core/two_factor/yubikey.rs b/src/api/core/two_factor/yubikey.rs index 2b2cdca..c088324 100644 --- a/src/api/core/two_factor/yubikey.rs +++ b/src/api/core/two_factor/yubikey.rs @@ -1,18 +1,18 @@ use rocket::Route; use rocket_contrib::json::Json; use serde_json::Value; -use yubico::config::Config; -use yubico::verify; +use yubico::{config::Config, verify}; -use crate::api::core::two_factor::_generate_recover_code; -use crate::api::{EmptyResult, JsonResult, JsonUpcase, PasswordData}; -use crate::auth::Headers; -use crate::db::{ - models::{TwoFactor, TwoFactorType}, - DbConn, +use crate::{ + api::{core::two_factor::_generate_recover_code, EmptyResult, JsonResult, JsonUpcase, PasswordData}, + auth::Headers, + db::{ + models::{TwoFactor, TwoFactorType}, + DbConn, + }, + error::{Error, MapResult}, + CONFIG, }; -use crate::error::{Error, MapResult}; -use crate::CONFIG; pub fn routes() -> Vec { routes![generate_yubikey, activate_yubikey, activate_yubikey_put,] diff --git a/src/api/icons.rs b/src/api/icons.rs index 98ebca6..fdf99ed 100644 --- a/src/api/icons.rs +++ b/src/api/icons.rs @@ -1,23 +1,17 @@ +use std::{ + fs::{create_dir_all, remove_file, symlink_metadata, File}, + io::prelude::*, + net::ToSocketAddrs, + time::{Duration, SystemTime}, +}; + use once_cell::sync::Lazy; -use std::fs::{create_dir_all, remove_file, symlink_metadata, File}; -use std::io::prelude::*; -use std::net::ToSocketAddrs; -use std::time::{Duration, SystemTime}; - -use rocket::http::ContentType; -use rocket::response::Content; -use rocket::Route; - -use reqwest::{Url, header::HeaderMap, blocking::Client, blocking::Response}; - -use rocket::http::Cookie; - use regex::Regex; +use reqwest::{blocking::Client, blocking::Response, header::HeaderMap, Url}; +use rocket::{http::ContentType, http::Cookie, response::Content, Route}; use soup::prelude::*; -use crate::error::Error; -use crate::CONFIG; -use crate::util::Cached; +use crate::{error::Error, util::Cached, CONFIG}; pub fn routes() -> Vec { routes![icon] diff --git a/src/api/identity.rs b/src/api/identity.rs index a0cb8cd..f2b553e 100644 --- a/src/api/identity.rs +++ b/src/api/identity.rs @@ -1,19 +1,22 @@ use chrono::Local; use num_traits::FromPrimitive; -use rocket::request::{Form, FormItems, FromForm}; -use rocket::Route; +use rocket::{ + request::{Form, FormItems, FromForm}, + Route, +}; use rocket_contrib::json::Json; use serde_json::Value; -use crate::api::core::two_factor::email::EmailTokenData; -use crate::api::core::two_factor::{duo, email, yubikey}; -use crate::api::{ApiResult, EmptyResult, JsonResult}; -use crate::auth::ClientIp; -use crate::db::models::*; -use crate::db::DbConn; -use crate::mail; -use crate::util; -use crate::CONFIG; +use crate::{ + api::{ + core::two_factor::{duo, email, email::EmailTokenData, yubikey}, + ApiResult, EmptyResult, JsonResult, + }, + auth::ClientIp, + db::{models::*, DbConn}, + error::MapResult, + mail, util, CONFIG, +}; pub fn routes() -> Vec { routes![login] @@ -49,10 +52,7 @@ fn _refresh_login(data: ConnectData, conn: DbConn) -> JsonResult { let token = data.refresh_token.unwrap(); // Get device by refresh token - let mut device = match Device::find_by_refresh_token(&token, &conn) { - Some(device) => device, - None => err!("Invalid refresh token"), - }; + let mut device = Device::find_by_refresh_token(&token, &conn).map_res("Invalid refresh token")?; // COMMON let user = User::find_by_uuid(&device.user_uuid, &conn).unwrap(); @@ -254,10 +254,7 @@ fn twofactor_auth( } fn _selected_data(tf: Option) -> ApiResult { - match tf { - Some(tf) => Ok(tf.data), - None => err!("Two factor doesn't exist"), - } + tf.map(|t| t.data).map_res("Two factor doesn't exist") } fn _json_err_twofactor(providers: &[i32], user_uuid: &str, conn: &DbConn) -> ApiResult { diff --git a/src/api/mod.rs b/src/api/mod.rs index 4f0b6b1..6962e38 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -5,23 +5,25 @@ mod identity; mod notifications; mod web; -pub use self::admin::routes as admin_routes; -pub use self::core::routes as core_routes; -pub use self::icons::routes as icons_routes; -pub use self::identity::routes as identity_routes; -pub use self::notifications::routes as notifications_routes; -pub use self::notifications::{start_notification_server, Notify, UpdateType}; -pub use self::web::routes as web_routes; - use rocket_contrib::json::Json; use serde_json::Value; +pub use crate::api::{ + admin::routes as admin_routes, + core::routes as core_routes, + icons::routes as icons_routes, + identity::routes as identity_routes, + notifications::routes as notifications_routes, + notifications::{start_notification_server, Notify, UpdateType}, + web::routes as web_routes, +}; +use crate::util; + // Type aliases for API methods results type ApiResult = Result; pub type JsonResult = ApiResult>; pub type EmptyResult = ApiResult<()>; -use crate::util; type JsonUpcase = Json>; type JsonUpcaseVec = Json>>; diff --git a/src/api/notifications.rs b/src/api/notifications.rs index acd2111..1bd551c 100644 --- a/src/api/notifications.rs +++ b/src/api/notifications.rs @@ -4,11 +4,12 @@ use rocket::Route; use rocket_contrib::json::Json; use serde_json::Value as JsonValue; -use crate::api::{EmptyResult, JsonResult}; -use crate::auth::Headers; -use crate::db::DbConn; - -use crate::{Error, CONFIG}; +use crate::{ + api::{EmptyResult, JsonResult}, + auth::Headers, + db::DbConn, + Error, CONFIG, +}; pub fn routes() -> Vec { routes![negotiate, websockets_err] @@ -163,7 +164,7 @@ impl Handler for WSHandler { let mut id = None; let mut access_token = None; - + for val in params_iter { if val.starts_with(ID_KEY) { id = Some(&val[ID_KEY.len()..]); diff --git a/src/api/web.rs b/src/api/web.rs index a97a1c9..306b58c 100644 --- a/src/api/web.rs +++ b/src/api/web.rs @@ -1,15 +1,10 @@ use std::path::{Path, PathBuf}; -use rocket::http::ContentType; -use rocket::response::content::Content; -use rocket::response::NamedFile; -use rocket::Route; +use rocket::{http::ContentType, response::content::Content, response::NamedFile, Route}; use rocket_contrib::json::Json; use serde_json::Value; -use crate::error::Error; -use crate::util::Cached; -use crate::CONFIG; +use crate::{error::Error, util::Cached, CONFIG}; pub fn routes() -> Vec { // If addding more routes here, consider also adding them to diff --git a/src/auth.rs b/src/auth.rs index 3842530..2a775eb 100644 --- a/src/auth.rs +++ b/src/auth.rs @@ -1,17 +1,19 @@ // // JWT Handling // -use crate::util::read_file; use chrono::{Duration, Utc}; -use once_cell::sync::Lazy; use num_traits::FromPrimitive; +use once_cell::sync::Lazy; -use jsonwebtoken::{self, Algorithm, Header, EncodingKey, DecodingKey}; +use jsonwebtoken::{self, Algorithm, DecodingKey, EncodingKey, Header}; use serde::de::DeserializeOwned; use serde::ser::Serialize; -use crate::error::{Error, MapResult}; -use crate::CONFIG; +use crate::{ + error::{Error, MapResult}, + util::read_file, + CONFIG, +}; const JWT_ALGORITHM: Algorithm = Algorithm::RS256; @@ -213,11 +215,15 @@ pub fn generate_admin_claims() -> AdminJWTClaims { // // Bearer token authentication // -use rocket::request::{self, FromRequest, Request}; -use rocket::Outcome; +use rocket::{ + request::{self, FromRequest, Request}, + Outcome, +}; -use crate::db::models::{Device, User, UserOrgStatus, UserOrgType, UserOrganization}; -use crate::db::DbConn; +use crate::db::{ + models::{Device, User, UserOrgStatus, UserOrgType, UserOrganization}, + DbConn, +}; pub struct Headers { pub host: String, @@ -366,7 +372,7 @@ impl<'a, 'r> FromRequest<'a, 'r> for OrgHeaders { } }, }) - }, + } _ => err_handler!("Error getting the organization id"), } } @@ -404,14 +410,14 @@ impl<'a, 'r> FromRequest<'a, 'r> for AdminHeaders { } } -impl Into for AdminHeaders { - fn into(self) -> Headers { +impl Into for AdminHeaders { + fn into(self) -> Headers { Headers { host: self.host, device: self.device, - user: self.user + user: self.user, } - } + } } pub struct OwnerHeaders { diff --git a/src/config.rs b/src/config.rs index ec6bf2e..8c6126f 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,11 +1,13 @@ -use once_cell::sync::Lazy; use std::process::exit; use std::sync::RwLock; +use once_cell::sync::Lazy; use reqwest::Url; -use crate::error::Error; -use crate::util::{get_env, get_env_bool}; +use crate::{ + error::Error, + util::{get_env, get_env_bool}, +}; static CONFIG_FILE: Lazy = Lazy::new(|| { let data_folder = get_env("DATA_FOLDER").unwrap_or_else(|| String::from("data")); diff --git a/src/crypto.rs b/src/crypto.rs index 68f4534..c2da8fb 100644 --- a/src/crypto.rs +++ b/src/crypto.rs @@ -1,10 +1,11 @@ // // PBKDF2 derivation // +use std::num::NonZeroU32; + +use ring::{digest, hmac, pbkdf2}; use crate::error::Error; -use ring::{digest, hmac, pbkdf2}; -use std::num::NonZeroU32; static DIGEST_ALG: pbkdf2::Algorithm = pbkdf2::PBKDF2_HMAC_SHA256; const OUTPUT_LEN: usize = digest::SHA256_OUTPUT_LEN; diff --git a/src/db/mod.rs b/src/db/mod.rs index 2034cd2..1fba3e4 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -1,18 +1,14 @@ -use std::ops::Deref; - -use diesel::r2d2; -use diesel::r2d2::ConnectionManager; -use diesel::{Connection as DieselConnection, ConnectionError}; - -use rocket::http::Status; -use rocket::request::{self, FromRequest}; -use rocket::{Outcome, Request, State}; - -use crate::error::Error; -use chrono::prelude::*; use std::process::Command; -use crate::CONFIG; +use chrono::prelude::*; +use diesel::{r2d2, r2d2::ConnectionManager, Connection as DieselConnection, ConnectionError}; +use rocket::{ + http::Status, + request::{self, FromRequest}, + Outcome, Request, State, +}; + +use crate::{error::Error, CONFIG}; /// An alias to the database connection used #[cfg(feature = "sqlite")] @@ -86,7 +82,7 @@ impl<'a, 'r> FromRequest<'a, 'r> for DbConn { } // For the convenience of using an &DbConn as a &Database. -impl Deref for DbConn { +impl std::ops::Deref for DbConn { type Target = Connection; fn deref(&self) -> &Self::Target { &self.0 diff --git a/src/error.rs b/src/error.rs index 5488d6f..577f899 100644 --- a/src/error.rs +++ b/src/error.rs @@ -41,7 +41,6 @@ use reqwest::Error as ReqErr; use serde_json::{Error as SerdeErr, Value}; use std::io::Error as IOErr; -use std::option::NoneError as NoneErr; use std::time::SystemTimeError as TimeErr; use u2f::u2ferror::U2fError as U2fErr; use yubico::yubicoerror::YubicoError as YubiErr; @@ -84,13 +83,6 @@ make_error! { FromStrError(FromStrErr): _has_source, _api_error, } -// This is implemented by hand because NoneError doesn't implement neither Display nor Error -impl From for Error { - fn from(_: NoneErr) -> Self { - Error::from(("NoneError", String::new())) - } -} - impl std::fmt::Debug for Error { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { match self.source() { diff --git a/src/mail.rs b/src/mail.rs index 8a6257f..a80b7ca 100644 --- a/src/mail.rs +++ b/src/mail.rs @@ -1,21 +1,23 @@ -use std::env; -use std::str::FromStr; - -use lettre::message::{header, Mailbox, Message, MultiPart, SinglePart}; -use lettre::transport::smtp::authentication::{Credentials, Mechanism as SmtpAuthMechanism}; -use lettre::transport::smtp::extension::ClientId; -use lettre::{Address, SmtpTransport, Tls, TlsParameters, Transport}; - -use native_tls::{Protocol, TlsConnector}; -use percent_encoding::{percent_encode, NON_ALPHANUMERIC}; - -use crate::api::EmptyResult; -use crate::auth::{encode_jwt, generate_delete_claims, generate_invite_claims, generate_verify_email_claims}; -use crate::error::Error; -use crate::CONFIG; +use std::{env, str::FromStr}; use chrono::{DateTime, Local}; use chrono_tz::Tz; +use native_tls::{Protocol, TlsConnector}; +use percent_encoding::{percent_encode, NON_ALPHANUMERIC}; + +use lettre::{ + message::{header, Mailbox, Message, MultiPart, SinglePart}, + transport::smtp::authentication::{Credentials, Mechanism as SmtpAuthMechanism}, + transport::smtp::extension::ClientId, + Address, SmtpTransport, Tls, TlsParameters, Transport, +}; + +use crate::{ + api::EmptyResult, + auth::{encode_jwt, generate_delete_claims, generate_invite_claims, generate_verify_email_claims}, + error::Error, + CONFIG, +}; fn mailer() -> SmtpTransport { let host = CONFIG.smtp_host().unwrap(); diff --git a/src/main.rs b/src/main.rs index bba1868..eeca0ff 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,5 @@ #![forbid(unsafe_code)] -#![feature(proc_macro_hygiene, try_trait, ip)] +#![feature(proc_macro_hygiene, ip)] #![recursion_limit = "256"] extern crate openssl; diff --git a/src/util.rs b/src/util.rs index ace247b..a8215b5 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,12 +1,15 @@ // // Web Headers and caching // -use rocket::fairing::{Fairing, Info, Kind}; -use rocket::http::{ContentType, Header, HeaderMap, Method, Status}; -use rocket::response::{self, Responder}; -use rocket::{Data, Request, Response, Rocket}; use std::io::Cursor; +use rocket::{ + fairing::{Fairing, Info, Kind}, + http::{ContentType, Header, HeaderMap, Method, Status}, + response::{self, Responder}, + Data, Request, Response, Rocket, +}; + use crate::CONFIG; pub struct AppHeaders(); @@ -189,9 +192,11 @@ impl Fairing for BetterLogging { // // File handling // -use std::fs::{self, File}; -use std::io::{Read, Result as IOResult}; -use std::path::Path; +use std::{ + fs::{self, File}, + io::{Read, Result as IOResult}, + path::Path, +}; pub fn file_exists(path: &str) -> bool { Path::new(path).exists() @@ -253,7 +258,6 @@ pub fn get_uuid() -> String { // String util methods // -use std::ops::Try; use std::str::FromStr; pub fn upcase_first(s: &str) -> String { @@ -264,12 +268,12 @@ pub fn upcase_first(s: &str) -> String { } } -pub fn try_parse_string(string: impl Try) -> Option +pub fn try_parse_string(string: Option) -> Option where S: AsRef, T: FromStr, { - if let Ok(Ok(value)) = string.into_result().map(|s| s.as_ref().parse::()) { + if let Some(Ok(value)) = string.map(|s| s.as_ref().parse::()) { Some(value) } else { None @@ -286,7 +290,7 @@ pub fn get_env(key: &str) -> Option where V: FromStr, { - try_parse_string(env::var(key)) + try_parse_string(env::var(key).ok()) } const TRUE_VALUES: &[&str] = &["true", "t", "yes", "y", "1"];