diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 93ef3ec8..1cb774d7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,4 +1,4 @@ -on: [push, pull_request] +on: [ push, pull_request ] name: CI @@ -29,7 +29,7 @@ jobs: strategy: fail-fast: false matrix: - rust_version: [stable, 1.70.0] + rust_version: [ stable, 1.70.0 ] os: - ubuntu-latest - windows-latest @@ -58,13 +58,13 @@ jobs: token: ${{ github.token }} # Transitive dependency of wasm-bindgen; works around https://github.com/rustwasm/wasm-bindgen/issues/3918 - run: cargo update -p bumpalo --precise 3.14.0 - - run: cargo build --workspace --exclude webauthn-authenticator-rs + - run: cargo build --workspace --exclude webauthn-authenticator-rs --exclude actix_web --exclude web_authn --exclude tide-server # Don't run clippy on Windows, we only need to run it on Linux - if: runner.os != 'windows' - run: cargo clippy --no-deps --workspace --exclude webauthn-authenticator-rs --all-targets + run: cargo clippy --no-deps --workspace --exclude webauthn-authenticator-rs --exclude actix_web --exclude web_authn --exclude tide-server --all-targets - - run: cargo test --workspace --exclude webauthn-authenticator-rs + - run: cargo test --workspace --exclude webauthn-authenticator-rs --exclude actix_web --exclude web_authn --exclude tide-server # Some clap errors manifest as panics at runtime. Running tools with # --help should be enough to find an issue. @@ -85,7 +85,7 @@ jobs: strategy: fail-fast: false matrix: - rust_version: [stable, 1.70.0] + rust_version: [ stable, 1.70.0 ] features: - bluetooth - cable @@ -186,7 +186,7 @@ jobs: strategy: fail-fast: false matrix: - rust_version: [stable, nightly] + rust_version: [ stable, nightly ] runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 @@ -233,3 +233,32 @@ jobs: if-no-files-found: error retention-days: 14 - run: ./.github/check_built_docs.sh + + tutorial: + name: Tutorial builds + strategy: + fail-fast: false + matrix: + rust_version: [ stable ] + os: + - ubuntu-latest + - windows-latest + + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v3 + - uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ matrix.rust_version }} + components: clippy + - uses: mozilla-actions/sccache-action@v0.0.3 + with: + version: v0.4.2 + - if: runner.os == 'windows' + uses: johnwason/vcpkg-action@v4 + with: + pkgs: openssl + triplet: x64-windows-static-md + token: ${{ github.token }} + + - run: cargo build -p actix_web -p web_authn -p tide-server diff --git a/Cargo.toml b/Cargo.toml index a324415d..d47a7b33 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ members = [ # Tutorial / Example sites. "tutorial/server/tide", "tutorial/server/axum", - # "tutorial/server/actix_web", + "tutorial/server/actix_web", "tutorial/wasm", # Attestatation struct format "attestation-ca", diff --git a/tutorial/server/actix_web/Cargo.toml b/tutorial/server/actix_web/Cargo.toml index 64662bac..449a4b59 100644 --- a/tutorial/server/actix_web/Cargo.toml +++ b/tutorial/server/actix_web/Cargo.toml @@ -2,25 +2,27 @@ name = "actix_web" version = "0.1.0" edition = "2021" -rust-version = "1.70.0" authors = ["Niklas Pfister "] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] # Webframework -actix-web = { version = "~4.5.1" } +actix-web = { version = ">=4.5.1" } # Session framework for actix-web -actix-session = { version = "~0.7", features = ["cookie-session"] } +actix-session = { version = "~0.9", features = ["cookie-session"] } # Async trait, anyhow, chrono, once_cell and rand are required for the implementation of a # server-side memory-backed session store. # Normally, you want to use a database / redis backend as session store, but for the simplicity of this # tutorial, we implement our own. async-trait = { version = "~0.1" } -anyhow = { version = "~1.0" } +anyhow = { version = "~1" } chrono = { version = "~0.4" } -once_cell = { version = "~1.18" } -rand.workspace = true +once_cell = { version = ">=1.18" } +rand = { workspace = true } + +# Nicer error management +thiserror = { version = "~1" } # Serve static file. Used to serve wasm actix-files = { version = "~0.6" } diff --git a/tutorial/server/actix_web/src/handler/mod.rs b/tutorial/server/actix_web/src/handler/mod.rs index 31849e17..9d118601 100644 --- a/tutorial/server/actix_web/src/handler/mod.rs +++ b/tutorial/server/actix_web/src/handler/mod.rs @@ -1,7 +1,7 @@ use actix_session::{SessionGetError, SessionInsertError}; -use std::fmt::{Display, Formatter}; use actix_web::http::StatusCode; +use thiserror::Error; use webauthn_rs::prelude::WebauthnError; pub(crate) mod auth; @@ -16,42 +16,24 @@ type WebResult = Result; /** Unified errors for simpler Responses */ -#[derive(Debug)] +#[derive(Debug, Error)] pub(crate) enum Error { + #[error("Unknown webauthn error")] Unknown(WebauthnError), - SessionGet(SessionGetError), - SessionInsert(SessionInsertError), + #[error("Corrupt session")] + SessionGet(#[from] SessionGetError), + #[error("Corrupt session")] + SessionInsert(#[from] SessionInsertError), + #[error("Corrupt session")] CorruptSession, - BadRequest(WebauthnError), + #[error("Bad request")] + BadRequest(#[from] WebauthnError), + #[error("User not found")] UserNotFound, + #[error("User has no credentials")] UserHasNoCredentials, } -impl From for Error { - fn from(value: SessionGetError) -> Self { - Self::SessionGet(value) - } -} - -impl From for Error { - fn from(value: SessionInsertError) -> Self { - Self::SessionInsert(value) - } -} - -impl Display for Error { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - match self { - Error::Unknown(_) => write!(f, "Unknown webauthn error"), - Error::SessionGet(_) | Error::SessionInsert(_) => write!(f, "Corrupt session"), - Error::BadRequest(_) => write!(f, "Bad request"), - Error::UserNotFound => write!(f, "User not found"), - Error::UserHasNoCredentials => write!(f, "User has no credentials"), - Error::CorruptSession => write!(f, "Corrupt session"), - } - } -} - impl actix_web::ResponseError for Error { fn status_code(&self) -> StatusCode { StatusCode::INTERNAL_SERVER_ERROR diff --git a/tutorial/server/actix_web/src/handler/serve_wasm.rs b/tutorial/server/actix_web/src/handler/serve_wasm.rs index eb2ebacc..9fcc3d4c 100644 --- a/tutorial/server/actix_web/src/handler/serve_wasm.rs +++ b/tutorial/server/actix_web/src/handler/serve_wasm.rs @@ -1,4 +1,4 @@ -use std::path::PathBuf; +use std::path::Path; use actix_files::NamedFile; use actix_web::HttpRequest; @@ -6,7 +6,7 @@ use actix_web::HttpRequest; pub const WASM_DIR: &str = "../../wasm/pkg"; pub(crate) async fn serve_wasm(req: HttpRequest) -> actix_web::Result { - let fp: PathBuf = req.match_info().query("filename").parse().unwrap(); - let path = PathBuf::new().join(WASM_DIR).join(fp); + let fp = req.match_info().query("filename"); + let path = Path::new(WASM_DIR).join(fp); Ok(NamedFile::open(path)?) } diff --git a/tutorial/server/actix_web/src/main.rs b/tutorial/server/actix_web/src/main.rs index c7412a61..ea58330a 100644 --- a/tutorial/server/actix_web/src/main.rs +++ b/tutorial/server/actix_web/src/main.rs @@ -1,5 +1,4 @@ -use core::panic; -use std::path::PathBuf; +use std::path::Path; use actix_session::SessionMiddleware; use actix_web::cookie::Key; @@ -23,7 +22,7 @@ mod startup; #[tokio::main] async fn main() { - if std::env::var("RUST_LOG").is_err() { + if std::env::var_os("RUST_LOG").is_none() { std::env::set_var("RUST_LOG", "info"); } @@ -36,7 +35,7 @@ async fn main() { let (webauthn, webauthn_users) = startup(); - if !PathBuf::from(WASM_DIR).exists() { + if !Path::new(WASM_DIR).exists() { panic!("{} does not exist, can't serve WASM files.", WASM_DIR); } else { info!("Found WASM files OK"); diff --git a/tutorial/server/actix_web/src/session.rs b/tutorial/server/actix_web/src/session.rs index 74875f89..71a4a96b 100644 --- a/tutorial/server/actix_web/src/session.rs +++ b/tutorial/server/actix_web/src/session.rs @@ -5,7 +5,6 @@ use std::sync::Mutex; use actix_session::storage::{LoadError, SaveError, SessionKey, SessionStore, UpdateError}; use actix_web::cookie::time::Duration; use anyhow::anyhow; -use async_trait::async_trait; use chrono::Utc; use once_cell::sync::Lazy; use rand::distributions::{Alphanumeric, DistString}; @@ -27,7 +26,6 @@ Implementation of the [SessionStore] trait of [actix_session]. #[derive(Default)] pub(crate) struct MemorySession; -#[async_trait(?Send)] impl SessionStore for MemorySession { async fn load( &self, @@ -74,8 +72,8 @@ impl SessionStore for MemorySession { }, ); - Ok(SessionKey::try_from(session_key) - .map_err(|_| SaveError::Serialization(anyhow!("Invalid Session Key Error")))?) + SessionKey::try_from(session_key) + .map_err(|_| SaveError::Serialization(anyhow!("Invalid Session Key Error"))) } async fn update( diff --git a/tutorial/server/axum/Cargo.toml b/tutorial/server/axum/Cargo.toml index 3a029b2e..30fdd457 100644 --- a/tutorial/server/axum/Cargo.toml +++ b/tutorial/server/axum/Cargo.toml @@ -2,7 +2,6 @@ name = "web_authn" version = "0.1.0" edition = "2021" -rust-version = "1.70.0" authors = ["William Brown , Ben Wishovich "] license = "MPL-2.0" @@ -13,13 +12,13 @@ tracing.workspace = true tracing-subscriber.workspace = true serde.workspace = true webauthn-rs = { workspace = true, features = ["danger-allow-state-serialisation"] } -axum = {version = "0.6.1", features = ["http2"]} +axum = { version = "0.6.1", features = ["http2"] } tokio = { workspace = true, features = ["full"] } -uuid = { workspace = true, features=["v4"] } +uuid = { workspace = true, features = ["v4"] } url.workspace = true thiserror.workspace = true tower = "0.4.13" -tower-http = {version="0.4.4", features=["fs"]} +tower-http = { version = "0.4.4", features = ["fs"] } tower-sessions = "0.6" [features] diff --git a/tutorial/server/tide/Cargo.toml b/tutorial/server/tide/Cargo.toml index 8f0abf39..bf1d6c82 100644 --- a/tutorial/server/tide/Cargo.toml +++ b/tutorial/server/tide/Cargo.toml @@ -2,7 +2,6 @@ name = "tide-server" version = "0.1.0" edition = "2021" -rust-version = "1.70.0" authors = ["William Brown "] license = "MPL-2.0"