feat: add auth things
This commit is contained in:
parent
42a75ba800
commit
88c4045d33
7 changed files with 182 additions and 20 deletions
97
Cargo.lock
generated
97
Cargo.lock
generated
|
|
@ -17,6 +17,15 @@ version = "1.0.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ea5d730647d4fadd988536d06fecce94b7b4f2a7efdae548f1cf4b63205518ab"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.71"
|
||||
|
|
@ -42,9 +51,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
|||
|
||||
[[package]]
|
||||
name = "axum"
|
||||
version = "0.6.18"
|
||||
version = "0.6.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8175979259124331c1d7bf6586ee7e0da434155e4b2d48ec2c8386281d8df39"
|
||||
checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"axum-core",
|
||||
|
|
@ -412,9 +421,9 @@ checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904"
|
|||
|
||||
[[package]]
|
||||
name = "httpc-test"
|
||||
version = "0.1.4"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7e7d56c0f391b27f6b4186e9ad7dad17c2f80329a8a409312a6e7622a25379f3"
|
||||
checksum = "81a425cb8352fb5080b3622e8a4265c63e75bedd68a4c19a83f7d4c88f9c9667"
|
||||
dependencies = [
|
||||
"cookie 0.16.2",
|
||||
"http",
|
||||
|
|
@ -449,7 +458,7 @@ dependencies = [
|
|||
"httpdate",
|
||||
"itoa",
|
||||
"pin-project-lite",
|
||||
"socket2",
|
||||
"socket2 0.4.9",
|
||||
"tokio",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
|
|
@ -551,6 +560,29 @@ dependencies = [
|
|||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy-regex"
|
||||
version = "3.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e723bd417b2df60a0f6a2b6825f297ea04b245d4ba52b5a22cb679bdf58b05fa"
|
||||
dependencies = [
|
||||
"lazy-regex-proc_macros",
|
||||
"once_cell",
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy-regex-proc_macros"
|
||||
version = "3.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0f0a1d9139f0ee2e862e08a9c5d0ba0470f2aa21cd1e1aa1b1562f83116c725f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"regex",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
|
|
@ -564,6 +596,7 @@ dependencies = [
|
|||
"anyhow",
|
||||
"axum",
|
||||
"httpc-test",
|
||||
"lazy-regex",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tokio",
|
||||
|
|
@ -791,9 +824,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.9"
|
||||
version = "0.2.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
|
||||
checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58"
|
||||
|
||||
[[package]]
|
||||
name = "pin-utils"
|
||||
|
|
@ -850,6 +883,35 @@ dependencies = [
|
|||
"bitflags 1.3.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12de2eff854e5fa4b1295edd650e227e9d8fb0c9e90b12e7f36d6a6811791a29"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-automata",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49530408a136e16e5b486e883fbb6ba058e8e4e8ae6621a77b048b314336e629"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da"
|
||||
|
||||
[[package]]
|
||||
name = "reqwest"
|
||||
version = "0.11.18"
|
||||
|
|
@ -1058,6 +1120,16 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
version = "0.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.22"
|
||||
|
|
@ -1153,11 +1225,10 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
|||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.29.1"
|
||||
version = "1.32.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "532826ff75199d5833b9d2c5fe410f29235e25704ee5f0ef599fb51c21f4a4da"
|
||||
checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"backtrace",
|
||||
"bytes",
|
||||
"libc",
|
||||
|
|
@ -1166,7 +1237,7 @@ dependencies = [
|
|||
"parking_lot",
|
||||
"pin-project-lite",
|
||||
"signal-hook-registry",
|
||||
"socket2",
|
||||
"socket2 0.5.4",
|
||||
"tokio-macros",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
|
@ -1241,9 +1312,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tower-http"
|
||||
version = "0.4.1"
|
||||
version = "0.4.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8bd22a874a2d0b70452d5597b12c537331d49060824a95f49f108994f94aa4c"
|
||||
checksum = "61c5bb1d698276a2443e5ecfabc1008bf15a36c12e6a7176e7bf089ea9131140"
|
||||
dependencies = [
|
||||
"bitflags 2.3.3",
|
||||
"bytes",
|
||||
|
|
|
|||
12
Cargo.toml
12
Cargo.toml
|
|
@ -6,13 +6,17 @@ edition = "2021"
|
|||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
tokio = { version = "1.29.1", features = ["full"] }
|
||||
axum = "0.6.18"
|
||||
tokio = { version = "1.32.0", features = ["full"] }
|
||||
# Serde / json
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
tower-http = { version = "0.4.1", features = ["fs"] }
|
||||
# Axum
|
||||
axum = { version = "0.6.20" }
|
||||
tower-http = { version = "0.4.4", features = ["fs"] }
|
||||
tower-cookies = "0.9"
|
||||
# Others
|
||||
lazy-regex = "3"
|
||||
|
||||
[dev-dependencies]
|
||||
anyhow = "1"
|
||||
httpc-test = "0.1.1"
|
||||
httpc-test = "0.1.5"
|
||||
|
|
|
|||
|
|
@ -6,6 +6,12 @@ pub type Result<T> = core::result::Result<T, Error>;
|
|||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
LoginFail,
|
||||
|
||||
// -- Auth errors.
|
||||
AuthFailNoAuthTokenCookie,
|
||||
AuthFailTokenWrongFormat,
|
||||
|
||||
// -- Model errors.
|
||||
PropertyDeleteFailIdNotFound { id: u64 },
|
||||
}
|
||||
|
||||
|
|
|
|||
11
src/main.rs
11
src/main.rs
|
|
@ -1,5 +1,7 @@
|
|||
#![allow(unused)]
|
||||
|
||||
use crate::model::ModelController;
|
||||
|
||||
pub use self::error::{Error, Result};
|
||||
|
||||
use std::net::SocketAddr;
|
||||
|
|
@ -25,10 +27,15 @@ struct HelloParams {
|
|||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
async fn main() -> Result<()>{
|
||||
let mc = ModelController::new().await?;
|
||||
|
||||
let routes_apis = web::routes_properties::routes(mc.clone()).route_layer(middleware::from_fn(web::mw_auth::mw_require_auth));
|
||||
|
||||
let routes_all = Router::new()
|
||||
.merge(routes_hello())
|
||||
.merge(web::routes_login::routes())
|
||||
.nest("/api", routes_apis)
|
||||
.layer(middleware::map_response(main_response_mapper))
|
||||
.layer(CookieManagerLayer::new()) // must be above? the auth routes
|
||||
// TODO: continue video at 22:15
|
||||
|
|
@ -40,6 +47,8 @@ async fn main() {
|
|||
.serve(routes_all.into_make_service())
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
pub mod mw_auth;
|
||||
pub mod routes_login;
|
||||
pub mod routes_properties;
|
||||
|
||||
|
|
|
|||
42
src/web/mw_auth.rs
Normal file
42
src/web/mw_auth.rs
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
use axum::http::Request;
|
||||
use axum::middleware::Next;
|
||||
use axum::response::Response;
|
||||
use lazy_regex::regex_captures;
|
||||
use tower_cookies::Cookies;
|
||||
|
||||
use crate::web::AUTH_TOKEN;
|
||||
use crate::{Error, Result};
|
||||
|
||||
pub async fn mw_require_auth<B>(
|
||||
cookies: Cookies,
|
||||
req: Request<B>,
|
||||
next: Next<B>
|
||||
) -> Result<Response> {
|
||||
println!("->> {:<12} - mw_require_auth", "MIDDLEWARE");
|
||||
let auth_token = cookies.get(AUTH_TOKEN).map(|c| c.value().to_string());
|
||||
|
||||
// Parse token.
|
||||
let (user_id, exp, sign) = auth_token
|
||||
.ok_or(Error::AuthFailNoAuthTokenCookie)
|
||||
.and_then(parse_token)?;
|
||||
|
||||
// TODO: Token components validation.
|
||||
|
||||
Ok(next.run(req).await)
|
||||
}
|
||||
|
||||
/// Parse a token of format `user-[user-id].[expiration].[signature]`
|
||||
/// Returns (user-id, expiration, signature)
|
||||
fn parse_token(token: String) -> Result<(u64, String, String)> {
|
||||
let (_whole, user_id, exp, sign) = regex_captures!(
|
||||
r#"^user-(\d+)\.(.+)\.(.+)"#, // a literal regex
|
||||
&token)
|
||||
.ok_or(Error::AuthFailTokenWrongFormat)?;
|
||||
|
||||
let user_id: u64 = user_id
|
||||
.parse()
|
||||
.map_err(|_| Error::AuthFailTokenWrongFormat)?;
|
||||
|
||||
Ok((user_id, exp.to_string(), sign.to_string()))
|
||||
|
||||
}
|
||||
|
|
@ -21,7 +21,7 @@ async fn test_quick_dev() -> Result<()> {
|
|||
json!(
|
||||
{
|
||||
"username": "demo1",
|
||||
"password": "demo1"
|
||||
"password": "demowrong"
|
||||
}
|
||||
)
|
||||
);
|
||||
|
|
@ -31,7 +31,7 @@ async fn test_quick_dev() -> Result<()> {
|
|||
json!(
|
||||
{
|
||||
"username": "demo1",
|
||||
"password": "demowrong"
|
||||
"password": "demo1"
|
||||
}
|
||||
)
|
||||
);
|
||||
|
|
@ -39,5 +39,34 @@ async fn test_quick_dev() -> Result<()> {
|
|||
|
||||
hc.do_get("/hello2/mike").await?.print().await?;
|
||||
|
||||
let req_create_property = hc.do_post(
|
||||
"/api/properties",
|
||||
json!(
|
||||
{
|
||||
"address": "Lolilat Street 1",
|
||||
"contact": "01234 567890"
|
||||
}
|
||||
)
|
||||
);
|
||||
req_create_property.await?.print().await?;
|
||||
let req_create_property = hc.do_post(
|
||||
"/api/properties",
|
||||
json!(
|
||||
{
|
||||
"address": "Lolilat Street 2",
|
||||
"contact": "01243 217890"
|
||||
}
|
||||
)
|
||||
);
|
||||
req_create_property.await?.print().await?;
|
||||
let req_get_properties = hc.do_get("/api/properties").await?;
|
||||
req_get_properties.print().await?;
|
||||
let req_delete_property = hc.do_delete("/api/properties/1").await?;
|
||||
req_delete_property.print().await?;
|
||||
let req_get_properties = hc.do_get("/api/properties").await?;
|
||||
req_get_properties.print().await?;
|
||||
let req_delete_property = hc.do_delete("/api/properties/0").await?;
|
||||
req_delete_property.print().await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue