diff --git a/.github/workflows/clippy-fmt.yml b/.github/workflows/clippy-fmt.yml new file mode 100644 index 00000000..76977a9e --- /dev/null +++ b/.github/workflows/clippy-fmt.yml @@ -0,0 +1,42 @@ +name: Lint + +on: + pull_request: + types: [opened, synchronize, reopened] + push: + branches: + - master + +jobs: + fmt: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - name: Install Rust + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + components: rustfmt + - name: Check with rustfmt + uses: actions-rs/cargo@v1 + with: + command: fmt + args: --all -- --check + + clippy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - name: Install Rust + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + components: clippy + override: true + - name: Check with Clippy + uses: actions-rs/clippy-check@v1 + with: + token: ${{ secrets.GITHUB_TOKEN }} + args: --workspace --tests --all-features diff --git a/src/api/v1/account/delete.rs b/src/api/v1/account/delete.rs index ae103479..9539df06 100644 --- a/src/api/v1/account/delete.rs +++ b/src/api/v1/account/delete.rs @@ -58,7 +58,7 @@ async fn delete_account( } } Err(RowNotFound) => return Err(ServiceError::UsernameNotFound), - Err(_) => return Err(ServiceError::InternalServerError)?, + Err(_) => return Err(ServiceError::InternalServerError), } } diff --git a/src/api/v1/account/email.rs b/src/api/v1/account/email.rs index 248cdf55..a179d9fb 100644 --- a/src/api/v1/account/email.rs +++ b/src/api/v1/account/email.rs @@ -74,14 +74,14 @@ async fn set_email( ) .execute(&data.db) .await; - if !res.is_ok() { + if res.is_err() { if let Err(sqlx::Error::Database(err)) = res { if err.code() == Some(Cow::from("23505")) && err.message().contains("mcaptcha_users_email_key") { - Err(ServiceError::EmailTaken)? + return Err(ServiceError::EmailTaken); } else { - Err(sqlx::Error::Database(err))? + return Err(sqlx::Error::Database(err).into()); } }; } diff --git a/src/api/v1/account/mod.rs b/src/api/v1/account/mod.rs index 90cf441a..b60012e1 100644 --- a/src/api/v1/account/mod.rs +++ b/src/api/v1/account/mod.rs @@ -32,8 +32,8 @@ pub mod routes { pub struct Account { pub delete: &'static str, pub email_exists: &'static str, - pub update_email: &'static str, pub get_secret: &'static str, + pub update_email: &'static str, pub update_secret: &'static str, pub username_exists: &'static str, } @@ -47,12 +47,13 @@ pub mod routes { let username_exists = "/api/v1/account/username/exists"; let update_email = "/api/v1/account/email/update"; Account { - get_secret, - update_secret, - username_exists, - update_email, delete, email_exists, + + get_secret, + update_email, + update_secret, + username_exists, } } } diff --git a/src/api/v1/account/secret.rs b/src/api/v1/account/secret.rs index 5d63467a..b724a34e 100644 --- a/src/api/v1/account/secret.rs +++ b/src/api/v1/account/secret.rs @@ -71,16 +71,14 @@ async fn update_user_secret( .await; if res.is_ok() { break; - } else { - if let Err(sqlx::Error::Database(err)) = res { - if err.code() == Some(Cow::from("23505")) - && err.message().contains("mcaptcha_users_secret_key") - { - continue; - } else { - Err(sqlx::Error::Database(err))?; - } - }; + } else if let Err(sqlx::Error::Database(err)) = res { + if err.code() == Some(Cow::from("23505")) + && err.message().contains("mcaptcha_users_secret_key") + { + continue; + } else { + return Err(sqlx::Error::Database(err).into()); + } } } Ok(HttpResponse::Ok()) diff --git a/src/api/v1/auth.rs b/src/api/v1/auth.rs index 3eb46b36..69f8c022 100644 --- a/src/api/v1/auth.rs +++ b/src/api/v1/auth.rs @@ -28,8 +28,8 @@ use crate::AppData; pub mod routes { pub struct Auth { - pub login: &'static str, pub logout: &'static str, + pub login: &'static str, pub register: &'static str, } @@ -39,8 +39,8 @@ pub mod routes { let logout = "/logout"; let register = "/api/v1/signup"; Auth { - login, logout, + login, register, } } @@ -48,16 +48,9 @@ pub mod routes { } pub fn services(cfg: &mut web::ServiceConfig) { - // protect_get!(cfg, V1_API_ROUTES.auth.logout, signout); - cfg.service(signup); cfg.service(signin); cfg.service(signout); - - // define_resource!(cfg, V1_API_ROUTES.auth.register, Methods::Post, signup); - // define_resource!(cfg, V1_API_ROUTES.auth.logout, Methods::ProtectGet, signout); - // define_resource!(cfg, V1_API_ROUTES.auth.login, Methods::Post, signin); - //post!(cfg, V1_API_ROUTES.auth.login, signin); } #[derive(Clone, Debug, Deserialize, Serialize)] @@ -85,10 +78,10 @@ async fn signup( data: AppData, ) -> ServiceResult { if !crate::SETTINGS.server.allow_registration { - Err(ServiceError::ClosedForRegistration)? + return Err(ServiceError::ClosedForRegistration); } - if &payload.password != &payload.confirm_password { + if payload.password != payload.confirm_password { return Err(ServiceError::PasswordsDontMatch); } let username = data.creds.username(&payload.username)?; @@ -127,22 +120,20 @@ async fn signup( } if res.is_ok() { break; - } else { - if let Err(sqlx::Error::Database(err)) = res { - if err.code() == Some(Cow::from("23505")) { - let msg = err.message(); - if msg.contains("mcaptcha_users_name_key") { - Err(ServiceError::UsernameTaken)?; - } else if msg.contains("mcaptcha_users_secret_key") { - continue; - } else { - Err(ServiceError::InternalServerError)?; - } + } else if let Err(sqlx::Error::Database(err)) = res { + if err.code() == Some(Cow::from("23505")) { + let msg = err.message(); + if msg.contains("mcaptcha_users_name_key") { + return Err(ServiceError::UsernameTaken); + } else if msg.contains("mcaptcha_users_secret_key") { + continue; } else { - Err(sqlx::Error::Database(err))?; + return Err(ServiceError::InternalServerError); } - }; - } + } else { + return Err(sqlx::Error::Database(err).into()); + } + }; } Ok(HttpResponse::Ok()) } @@ -174,14 +165,14 @@ async fn signin( Err(ServiceError::WrongPassword) } } - Err(RowNotFound) => return Err(ServiceError::UsernameNotFound), - Err(_) => return Err(ServiceError::InternalServerError)?, + Err(RowNotFound) => Err(ServiceError::UsernameNotFound), + Err(_) => Err(ServiceError::InternalServerError), } } #[my_codegen::get(path = "crate::V1_API_ROUTES.auth.logout", wrap = "crate::CheckLogin")] async fn signout(id: Identity) -> impl Responder { - if let Some(_) = id.identity() { + if id.identity().is_some() { id.forget(); } HttpResponse::Found() diff --git a/src/api/v1/mcaptcha/mcaptcha.rs b/src/api/v1/mcaptcha/captcha.rs similarity index 95% rename from src/api/v1/mcaptcha/mcaptcha.rs rename to src/api/v1/mcaptcha/captcha.rs index c2b3c5af..b64c552d 100644 --- a/src/api/v1/mcaptcha/mcaptcha.rs +++ b/src/api/v1/mcaptcha/captcha.rs @@ -94,10 +94,10 @@ pub async fn add_mcaptcha_util( { continue; } else { - Err(sqlx::Error::Database(err))?; + return Err(sqlx::Error::Database(err).into()); } } - Err(e) => Err(e)?, + Err(e) => return Err(e.into()), Ok(_) => { resp = MCaptchaDetails { @@ -128,15 +128,13 @@ async fn update_token( let res = update_token_helper(&key, &payload.key, &username, &data).await; if res.is_ok() { break; - } else { - if let Err(sqlx::Error::Database(err)) = res { - if err.code() == Some(Cow::from("23505")) { - continue; - } else { - Err(sqlx::Error::Database(err))?; - } - }; - } + } else if let Err(sqlx::Error::Database(err)) = res { + if err.code() == Some(Cow::from("23505")) { + continue; + } else { + return Err(sqlx::Error::Database(err).into()); + } + }; } let resp = MCaptchaDetails { diff --git a/src/api/v1/mcaptcha/duration.rs b/src/api/v1/mcaptcha/duration.rs index 5e857545..507562fb 100644 --- a/src/api/v1/mcaptcha/duration.rs +++ b/src/api/v1/mcaptcha/duration.rs @@ -19,7 +19,7 @@ use actix_identity::Identity; use actix_web::{web, HttpResponse, Responder}; use serde::{Deserialize, Serialize}; -use crate::api::v1::mcaptcha::mcaptcha::MCaptchaDetails; +use crate::api::v1::mcaptcha::captcha::MCaptchaDetails; use crate::errors::*; use crate::AppData; diff --git a/src/api/v1/mcaptcha/levels.rs b/src/api/v1/mcaptcha/levels.rs index a2810ba7..cdef16bc 100644 --- a/src/api/v1/mcaptcha/levels.rs +++ b/src/api/v1/mcaptcha/levels.rs @@ -20,8 +20,8 @@ use libmcaptcha::{defense::Level, DefenseBuilder}; use log::debug; use serde::{Deserialize, Serialize}; -use super::mcaptcha::add_mcaptcha_util; -use crate::api::v1::mcaptcha::mcaptcha::MCaptchaDetails; +use super::captcha::add_mcaptcha_util; +use super::captcha::MCaptchaDetails; use crate::errors::*; use crate::AppData; @@ -29,9 +29,9 @@ pub mod routes { pub struct Levels { pub add: &'static str, - pub update: &'static str, pub delete: &'static str, pub get: &'static str, + pub update: &'static str, } impl Levels { @@ -42,9 +42,9 @@ pub mod routes { let get = "/api/v1/mcaptcha/levels/get"; Levels { add, + delete, get, update, - delete, } } } @@ -76,7 +76,7 @@ async fn add_levels( let username = id.identity().unwrap(); for level in payload.levels.iter() { - defense.add_level(level.clone())?; + defense.add_level(*level)?; } defense.build()?; @@ -132,7 +132,7 @@ async fn update_levels( let mut defense = DefenseBuilder::default(); for level in payload.levels.iter() { - defense.add_level(level.clone())?; + defense.add_level(*level)?; } // I feel this is necessary as both difficulty factor _and_ visitor threshold of a diff --git a/src/api/v1/mcaptcha/mod.rs b/src/api/v1/mcaptcha/mod.rs index 28b1642b..870f668a 100644 --- a/src/api/v1/mcaptcha/mod.rs +++ b/src/api/v1/mcaptcha/mod.rs @@ -15,9 +15,9 @@ * along with this program. If not, see . */ +pub mod captcha; pub mod duration; pub mod levels; -pub mod mcaptcha; pub fn get_random(len: usize) -> String { use std::iter; @@ -36,5 +36,5 @@ pub fn get_random(len: usize) -> String { pub fn services(cfg: &mut actix_web::web::ServiceConfig) { duration::services(cfg); levels::services(cfg); - mcaptcha::services(cfg); + captcha::services(cfg); } diff --git a/src/api/v1/meta.rs b/src/api/v1/meta.rs index 640901ce..883100cc 100644 --- a/src/api/v1/meta.rs +++ b/src/api/v1/meta.rs @@ -49,7 +49,7 @@ pub mod routes { async fn build_details() -> impl Responder { let build = BuildDetails { version: VERSION, - git_commit_hash: &GIT_COMMIT_HASH, + git_commit_hash: GIT_COMMIT_HASH, }; HttpResponse::Ok().json(build) } @@ -68,7 +68,7 @@ async fn health(data: AppData) -> impl Responder { let mut resp_builder = HealthBuilder::default(); resp_builder.db(false); if let Ok(mut con) = data.db.acquire().await { - if let Ok(_) = con.ping().await { + if con.ping().await.is_ok() { resp_builder.db(true); } }; diff --git a/src/api/v1/notifications/mark_read.rs b/src/api/v1/notifications/mark_read.rs index cb1e433a..3495abf3 100644 --- a/src/api/v1/notifications/mark_read.rs +++ b/src/api/v1/notifications/mark_read.rs @@ -128,7 +128,7 @@ mod tests { assert_eq!(notification.heading, HEADING); let mark_read_payload = MarkReadReq { - id: notification.id.clone(), + id: notification.id, }; let mark_read_resp = test::call_service( &mut app, diff --git a/src/api/v1/pow/get_config.rs b/src/api/v1/pow/get_config.rs index ed1dc4e4..b6087b10 100644 --- a/src/api/v1/pow/get_config.rs +++ b/src/api/v1/pow/get_config.rs @@ -193,8 +193,8 @@ mod tests { .to_request(), ) .await; - // assert_eq!(get_config_resp.status(), StatusCode::OK); - // let config: PoWConfig = test::read_body_json(get_config_resp).await; - // assert_eq!(config.difficulty_factor, L1.difficulty_factor); + assert_eq!(get_config_resp.status(), StatusCode::OK); + let config: PoWConfig = test::read_body_json(get_config_resp).await; + assert_eq!(config.difficulty_factor, L1.difficulty_factor); } } diff --git a/src/api/v1/routes.rs b/src/api/v1/routes.rs index 560e8e41..797affc7 100644 --- a/src/api/v1/routes.rs +++ b/src/api/v1/routes.rs @@ -17,9 +17,9 @@ use super::account::routes::Account; use super::auth::routes::Auth; +use super::mcaptcha::captcha::routes::MCaptcha; use super::mcaptcha::duration::routes::Duration; use super::mcaptcha::levels::routes::Levels; -use super::mcaptcha::mcaptcha::routes::MCaptcha; use super::meta::routes::Meta; use super::notifications::routes::Notifications; use super::pow::routes::PoW; diff --git a/src/errors.rs b/src/errors.rs index 87faae8f..98a03201 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -221,12 +221,10 @@ impl ResponseError for PageError { match self.status_code() { StatusCode::INTERNAL_SERVER_ERROR => HttpResponse::Found() .header(header::LOCATION, PAGES.errors.internal_server_error) - .finish() - .into(), + .finish(), _ => HttpResponse::Found() .header(header::LOCATION, PAGES.errors.unknown_error) - .finish() - .into(), + .finish(), } } diff --git a/src/main.rs b/src/main.rs index 6fab0e28..fa874a0a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -19,8 +19,8 @@ use std::sync::Arc; use actix_identity::{CookieIdentityPolicy, IdentityService}; use actix_web::{ - client::Client, error::InternalError, http::StatusCode, - middleware as actix_middleware, web::JsonConfig, App, HttpServer, + error::InternalError, http::StatusCode, middleware as actix_middleware, + web::JsonConfig, App, HttpServer, }; use lazy_static::lazy_static; use log::info; @@ -69,7 +69,7 @@ lazy_static! { /// points to source files matching build commit pub static ref SOURCE_FILES_OF_INSTANCE: String = { let mut url = SETTINGS.source_code.clone(); - if url.chars().last() != Some('/') { + if !url.ends_with('/') { url.push('/'); } let mut base = url::Url::parse(&url).unwrap(); @@ -95,7 +95,6 @@ pub type AppData = actix_web::web::Data>; #[actix_web::main] async fn main() -> std::io::Result<()> { use api::v1; - use docs; pretty_env_logger::init(); info!( "{}: {}.\nFor more information, see: {}\nBuild info:\nVersion: {} commit: {}", @@ -105,14 +104,11 @@ async fn main() -> std::io::Result<()> { let data = Data::new().await; sqlx::migrate!("./migrations/").run(&data.db).await.unwrap(); HttpServer::new(move || { - let client = Client::default(); - App::new() .wrap(actix_middleware::Logger::default()) .wrap(get_identity_service()) .wrap(actix_middleware::Compress::default()) .data(data.clone()) - .data(client.clone()) .wrap(actix_middleware::NormalizePath::new( actix_middleware::normalize::TrailingSlash::Trim, )) diff --git a/src/pages/panel/sitekey/list.rs b/src/pages/panel/sitekey/list.rs index 55ac5b06..0a619abc 100644 --- a/src/pages/panel/sitekey/list.rs +++ b/src/pages/panel/sitekey/list.rs @@ -19,7 +19,7 @@ use actix_identity::Identity; use actix_web::{HttpResponse, Responder}; use sailfish::TemplateOnce; -use crate::api::v1::mcaptcha::mcaptcha::MCaptchaDetails; +use crate::api::v1::mcaptcha::captcha::MCaptchaDetails; use crate::errors::*; use crate::AppData; diff --git a/src/settings.rs b/src/settings.rs index 4deacc25..e6be4bf0 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -59,7 +59,7 @@ impl DatabaseBuilder { #[cfg(not(tarpaulin_include))] fn extract_database_url(url: &Url) -> Self { debug!("Databse name: {}", url.path()); - let mut path = url.path().split("/"); + let mut path = url.path().split('/'); path.next(); let name = path.next().expect("no database name").to_string(); DatabaseBuilder { @@ -143,7 +143,7 @@ impl Settings { match s.try_into() { Ok(val) => Ok(val), - Err(e) => Err(ConfigError::Message(format!("\n\nError: {}. If it says missing fields, then please refer to https://github.com/mCaptcha/mcaptcha#configuration to learn more about how mcaptcha reads configuration\n\n", e)))?, + Err(e) => Err(ConfigError::Message(format!("\n\nError: {}. If it says missing fields, then please refer to https://github.com/mCaptcha/mcaptcha#configuration to learn more about how mcaptcha reads configuration\n\n", e))), } } } diff --git a/src/static_assets/filemap.rs b/src/static_assets/filemap.rs index 1c5a338c..64e5ab54 100644 --- a/src/static_assets/filemap.rs +++ b/src/static_assets/filemap.rs @@ -21,21 +21,15 @@ pub struct FileMap { } impl FileMap { + #[allow(clippy::new_without_default)] pub fn new() -> Self { let map = include_str!("../cache_buster_data.json"); let files = Files::new(&map); Self { files } } pub fn get<'a>(&'a self, path: &'a str) -> Option<&'a str> { - // let file_path = self.files.get(path); let file_path = self.files.get_full_path(path); - - if file_path.is_some() { - let file_path = &file_path.unwrap()[1..]; - return Some(file_path); - } else { - return None; - } + file_path.map(|file_path| &file_path[1..]) } } diff --git a/src/static_assets/static_files.rs b/src/static_assets/static_files.rs index 6ef7abb7..f04ddee4 100644 --- a/src/static_assets/static_files.rs +++ b/src/static_assets/static_files.rs @@ -99,7 +99,7 @@ mod tests { let resp = test::call_service( &mut app, - test::TestRequest::get().uri(&*crate::JS).to_request(), + test::TestRequest::get().uri(*crate::JS).to_request(), ) .await; assert_eq!(resp.status(), StatusCode::OK); @@ -107,7 +107,7 @@ mod tests { let resp = test::call_service( &mut app, test::TestRequest::get() - .uri(&*crate::VERIFICATIN_WIDGET_JS) + .uri(*crate::VERIFICATIN_WIDGET_JS) .to_request(), ) .await; @@ -116,7 +116,7 @@ mod tests { let resp = test::call_service( &mut app, test::TestRequest::get() - .uri(&*crate::VERIFICATIN_WIDGET_CSS) + .uri(*crate::VERIFICATIN_WIDGET_CSS) .to_request(), ) .await; diff --git a/src/tests/mod.rs b/src/tests/mod.rs index aaa0bfd9..4049d2fb 100644 --- a/src/tests/mod.rs +++ b/src/tests/mod.rs @@ -11,8 +11,8 @@ use serde::Serialize; use super::*; use crate::api::v1::auth::{Login, Register}; +use crate::api::v1::mcaptcha::captcha::MCaptchaDetails; use crate::api::v1::mcaptcha::levels::AddLevels; -use crate::api::v1::mcaptcha::mcaptcha::MCaptchaDetails; use crate::api::v1::ROUTES; use crate::data::Data; use crate::errors::*; @@ -95,8 +95,8 @@ macro_rules! get_app { } /// register and signin utility -pub async fn register_and_signin<'a>( - name: &'a str, +pub async fn register_and_signin( + name: &str, email: &str, password: &str, ) -> (Arc, Login, ServiceResponse) { @@ -105,7 +105,7 @@ pub async fn register_and_signin<'a>( } /// register utility -pub async fn register<'a>(name: &'a str, email: &str, password: &str) { +pub async fn register(name: &str, email: &str, password: &str) { let data = Data::new().await; let mut app = get_app!(data).await; @@ -125,10 +125,7 @@ pub async fn register<'a>(name: &'a str, email: &str, password: &str) { } /// signin util -pub async fn signin<'a>( - name: &'a str, - password: &str, -) -> (Arc, Login, ServiceResponse) { +pub async fn signin(name: &str, password: &str) -> (Arc, Login, ServiceResponse) { let data = Data::new().await; let mut app = get_app!(data.clone()).await; diff --git a/templates/panel/sitekey/add/form.html b/templates/panel/sitekey/add/form.html index e7de9c22..899afeb9 100644 --- a/templates/panel/sitekey/add/form.html +++ b/templates/panel/sitekey/add/form.html @@ -10,7 +10,7 @@ name="description" id="description" required - <. if form_description.trim().len() > 0 { .> + <. if !form_description.trim().is_empty() { .> value="<.= form_description .>" <. } .> /> diff --git a/templates/panel/sitekey/view/index.html b/templates/panel/sitekey/view/index.html index 4af66a65..7c8d9d0b 100644 --- a/templates/panel/sitekey/view/index.html +++ b/templates/panel/sitekey/view/index.html @@ -26,7 +26,7 @@ name="description" id="description" required - <. if name.trim().len() > 0 { .> + <. if !name.trim().is_empty() { .> value="<.= name .>" <. } .> />