From 84b1ce0823aab0fcce942bab9c5e9f47be33aa27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Berthaud-M=C3=BCller?= Date: Fri, 26 Mar 2021 18:30:38 -0400 Subject: [PATCH 01/11] bootstrap database --- .gitignore | 1 + Cargo.lock | 154 ++++++++++++++++++ Cargo.toml | 5 +- Rocket.toml | 2 + diesel.toml | 5 + migrations/.gitkeep | 0 .../2021-03-26-164945_create_users/down.sql | 3 + .../2021-03-26-164945_create_users/up.sql | 12 ++ src/auth/mod.rs | 2 + src/auth/providers.rs | 12 ++ src/auth/routes.rs | 44 +++++ src/main.rs | 16 +- src/models/mod.rs | 1 + src/models/users.rs | 48 ++++++ src/schema.rs | 21 +++ 15 files changed, 324 insertions(+), 2 deletions(-) create mode 100644 Rocket.toml create mode 100644 diesel.toml create mode 100644 migrations/.gitkeep create mode 100644 migrations/2021-03-26-164945_create_users/down.sql create mode 100644 migrations/2021-03-26-164945_create_users/up.sql create mode 100644 src/auth/mod.rs create mode 100644 src/auth/providers.rs create mode 100644 src/auth/routes.rs create mode 100644 src/models/users.rs create mode 100644 src/schema.rs diff --git a/.gitignore b/.gitignore index 7f1788b..a631336 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /target config.toml +db.sqlite diff --git a/Cargo.lock b/Cargo.lock index 8348136..b6b47f1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -244,6 +244,41 @@ dependencies = [ "syn 0.15.44", ] +[[package]] +name = "diesel" +version = "1.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "047bfc4d5c3bd2ef6ca6f981941046113524b9a9f9a7cbdfdd7ff40f58e6f542" +dependencies = [ + "byteorder", + "diesel_derives", + "libsqlite3-sys", + "r2d2", +] + +[[package]] +name = "diesel-derive-enum" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "703e71c268ea2d8da9c0ab0b40d8b217179ee622209c170875d24443193a0dfb" +dependencies = [ + "heck", + "proc-macro2 1.0.24", + "quote 1.0.9", + "syn 1.0.64", +] + +[[package]] +name = "diesel_derives" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45f5098f628d02a7a0f68ddba586fb61e80edec3bdc1be3b921f4ceec60858d3" +dependencies = [ + "proc-macro2 1.0.24", + "quote 1.0.9", + "syn 1.0.64", +] + [[package]] name = "digest" version = "0.9.0" @@ -526,6 +561,15 @@ dependencies = [ "libc", ] +[[package]] +name = "instant" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec" +dependencies = [ + "cfg-if 1.0.0", +] + [[package]] name = "iovec" version = "0.1.4" @@ -581,6 +625,25 @@ version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba4aede83fc3617411dc6993bc8c70919750c1c257c6ca6a502aed6e0e2394ae" +[[package]] +name = "libsqlite3-sys" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64d31059f22935e6c31830db5249ba2b7ecd54fd73a9909286f0a67aa55c2fbd" +dependencies = [ + "pkg-config", + "vcpkg", +] + +[[package]] +name = "lock_api" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd96ffd135b2fd7b973ac026d28085defbe8983df057ced3eb4f2130b0831312" +dependencies = [ + "scopeguard", +] + [[package]] name = "log" version = "0.3.9" @@ -711,6 +774,8 @@ name = "nomilo" version = "0.1.0-dev" dependencies = [ "base64 0.13.0", + "diesel", + "diesel-derive-enum", "rocket", "rocket_contrib", "serde", @@ -718,6 +783,7 @@ dependencies = [ "toml 0.5.8", "trust-dns-client", "trust-dns-proto", + "uuid", ] [[package]] @@ -782,6 +848,31 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +[[package]] +name = "parking_lot" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb" +dependencies = [ + "instant", + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa7a782938e745763fe6907fc6ba86946d72f49fe7e21de074e08128a99fb018" +dependencies = [ + "cfg-if 1.0.0", + "instant", + "libc", + "redox_syscall", + "smallvec", + "winapi 0.3.9", +] + [[package]] name = "pear" version = "0.1.4" @@ -828,6 +919,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkg-config" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" + [[package]] name = "polyval" version = "0.4.5" @@ -881,6 +978,17 @@ dependencies = [ "proc-macro2 1.0.24", ] +[[package]] +name = "r2d2" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "545c5bc2b880973c9c10e4067418407a0ccaa3091781d1671d46eb35107cb26f" +dependencies = [ + "log 0.4.14", + "parking_lot", + "scheduled-thread-pool", +] + [[package]] name = "radix_trie" version = "0.2.1" @@ -982,13 +1090,28 @@ version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7954a707f9ca18aa74ca8c1f5d1f900f52a4dceb68e96e3112143f759cfd20e" dependencies = [ + "diesel", "log 0.4.14", "notify", + "r2d2", "rocket", + "rocket_contrib_codegen", "serde", "serde_json", ] +[[package]] +name = "rocket_contrib_codegen" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30deb6dec53b91fac3538a2a3935cf13e0f462745f9f33bf27bedffbe7265b5d" +dependencies = [ + "devise", + "quote 0.6.13", + "version_check 0.9.3", + "yansi", +] + [[package]] name = "rocket_http" version = "0.4.7" @@ -1027,6 +1150,21 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "scheduled-thread-pool" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc6f74fd1204073fa02d5d5d68bec8021be4c38690b61264b2fdb48083d0e7d7" +dependencies = [ + "parking_lot", +] + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + [[package]] name = "serde" version = "1.0.124" @@ -1345,6 +1483,22 @@ dependencies = [ "percent-encoding 2.1.0", ] +[[package]] +name = "uuid" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" +dependencies = [ + "getrandom", + "serde", +] + +[[package]] +name = "vcpkg" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b00bca6106a5e23f3eee943593759b7fcddb00554332e856d990c893966879fb" + [[package]] name = "version_check" version = "0.1.5" diff --git a/Cargo.toml b/Cargo.toml index b4276fa..50c1fa9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,9 @@ trust-dns-proto = "0.20.1" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" rocket = "0.4.7" -rocket_contrib = { version = "0.4", default-features = false, features = ["json"]} +rocket_contrib = { version = "0.4", default-features = false, features = ["json", "diesel_sqlite_pool"]} toml = "0.5" base64 = "0.13.0" +uuid = { version = "0.8.2", features = ["v4", "serde"] } +diesel = { version = "1.4", features = ["sqlite"] } +diesel-derive-enum = { version = "1", features = ["sqlite"] } diff --git a/Rocket.toml b/Rocket.toml new file mode 100644 index 0000000..4e9292a --- /dev/null +++ b/Rocket.toml @@ -0,0 +1,2 @@ +[global.databases] +db = { url = "db.sqlite" } diff --git a/diesel.toml b/diesel.toml new file mode 100644 index 0000000..92267c8 --- /dev/null +++ b/diesel.toml @@ -0,0 +1,5 @@ +# For documentation on how to configure this file, +# see diesel.rs/guides/configuring-diesel-cli + +[print_schema] +file = "src/schema.rs" diff --git a/migrations/.gitkeep b/migrations/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/migrations/2021-03-26-164945_create_users/down.sql b/migrations/2021-03-26-164945_create_users/down.sql new file mode 100644 index 0000000..973d984 --- /dev/null +++ b/migrations/2021-03-26-164945_create_users/down.sql @@ -0,0 +1,3 @@ +-- This file should undo anything in `up.sql` +DROP TABLE localuser; +DROP TABLE user; diff --git a/migrations/2021-03-26-164945_create_users/up.sql b/migrations/2021-03-26-164945_create_users/up.sql new file mode 100644 index 0000000..0dbdbdc --- /dev/null +++ b/migrations/2021-03-26-164945_create_users/up.sql @@ -0,0 +1,12 @@ +-- Your SQL goes here +CREATE TABLE localuser ( + user_id VARCHAR NOT NULL PRIMARY KEY, + username VARCHAR NOT NULL, + password VARCHAR NOT NULL, + FOREIGN KEY(user_id) REFERENCES user(id) +); + +CREATE TABLE user ( + id VARCHAR NOT NULL PRIMARY KEY, + role VARCHAR NOT NULL +); diff --git a/src/auth/mod.rs b/src/auth/mod.rs new file mode 100644 index 0000000..0a2a180 --- /dev/null +++ b/src/auth/mod.rs @@ -0,0 +1,2 @@ +pub mod providers; +pub mod routes; diff --git a/src/auth/providers.rs b/src/auth/providers.rs new file mode 100644 index 0000000..65c3ad2 --- /dev/null +++ b/src/auth/providers.rs @@ -0,0 +1,12 @@ +// enum Providers { +// Ldap(LdapProvider), +// Local(LocalProvider), +// } + +// struct LdapProvider { +// user_filter: String, +// group_filter: String, +// // ... +// } + +// struct LocalProvider; diff --git a/src/auth/routes.rs b/src/auth/routes.rs new file mode 100644 index 0000000..d8b1fe5 --- /dev/null +++ b/src/auth/routes.rs @@ -0,0 +1,44 @@ +use serde::{Serialize, Deserialize}; +use rocket_contrib::json::Json; +use diesel::prelude::*; +use crate::DbConn; +use crate::models::users::{UserInfo, LocalUser, User}; + +#[derive(Debug, Serialize, Deserialize)] +struct AuthClaims { + jti: String, + sub: String, + exp: usize, + iat: usize, +} + +#[derive(Debug, Serialize)] +pub struct AuthTokenResponse { + token: String +} + +#[derive(Debug, Deserialize)] +pub struct AuthTokenRequest { + user: String, + password: String, +} + +#[post("/users/me/token", data = "")] +pub fn create_auth_token(conn: DbConn, auth_request: Json) -> Json { + use crate::schema::localuser::dsl::*; + use crate::schema::user::dsl::*; + + let client_user: Result<(User, LocalUser), _> = user.inner_join(localuser).filter(username.eq(&auth_request.user)).get_result(&*conn); + println!("{:?}", client_user); + Json(AuthTokenResponse { token: "".into() }) +} + +/* +GET /users -> list all users +POST /users +{ + provider: local + ... +} +/users// +*/ diff --git a/src/main.rs b/src/main.rs index 8ab80f1..bfb8332 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,9 +1,16 @@ #![feature(proc_macro_hygiene, decl_macro)] #[macro_use] extern crate rocket; +#[macro_use] extern crate rocket_contrib; +#[macro_use] extern crate diesel; + use rocket::State; use rocket::http::Status; + use rocket_contrib::json::Json; +use rocket_contrib::databases::diesel as rocket_diesel; + +use diesel::prelude::*; use trust_dns_client::client::{Client, SyncClient}; use trust_dns_client::tcp::TcpClientConnection; @@ -12,10 +19,16 @@ use trust_dns_client::rr::{DNSClass, Name, RecordType}; mod models; mod config; +mod auth; +mod schema; use models::errors::ErrorResponse; +use auth::routes::*; +#[database("db")] +pub struct DbConn(diesel::SqliteConnection); + #[get("/zones//records")] fn get_zone_records(client: State>, zone: String) -> Result>, ErrorResponse<()>> { // TODO: Implement FromParam for Name @@ -52,5 +65,6 @@ fn main() { rocket::ignite() .manage(client) - .mount("/api/v1", routes![get_zone_records]).launch(); + .attach(DbConn::fairing()) + .mount("/api/v1", routes![get_zone_records, create_auth_token]).launch(); } diff --git a/src/models/mod.rs b/src/models/mod.rs index dbf31e3..dd71b7c 100644 --- a/src/models/mod.rs +++ b/src/models/mod.rs @@ -1,5 +1,6 @@ pub mod dns; pub mod errors; +pub mod users; pub mod trust_dns_types { pub use trust_dns_client::rr::rdata::{ diff --git a/src/models/users.rs b/src/models/users.rs new file mode 100644 index 0000000..6d113a6 --- /dev/null +++ b/src/models/users.rs @@ -0,0 +1,48 @@ +use uuid::Uuid; +use diesel::prelude::*; +use diesel::associations::HasTable; +use rocket::request::{FromRequest, Request, Outcome}; +use diesel_derive_enum::DbEnum; + +use crate::schema::*; + +#[derive(Debug, DbEnum)] +pub enum Role { + Admin, + ZoneAdmin, +} + +#[derive(Debug, Queryable, Identifiable)] +#[table_name = "user"] +pub struct User { + pub id: String, + pub role: String, +} + +#[derive(Debug, Queryable, Identifiable)] +#[table_name = "localuser"] +#[primary_key(user_id)] +pub struct LocalUser { + pub user_id: String, + pub username: String, + pub password: String, +} + +// pub struct LdapUserAssociation { +// user_id: Uuid, +// ldap_id: String +// } + +pub struct UserInfo { + id: Uuid, + role: Role, + username: String, +} + +impl<'a, 'r> FromRequest<'a, 'r> for UserInfo { + type Error = (); + + fn from_request(request: &'a Request<'r>) -> Outcome { + Outcome::Forward(()) + } +} diff --git a/src/schema.rs b/src/schema.rs new file mode 100644 index 0000000..21093d7 --- /dev/null +++ b/src/schema.rs @@ -0,0 +1,21 @@ +table! { + localuser (user_id) { + user_id -> Text, + username -> Text, + password -> Text, + } +} + +table! { + user (id) { + id -> Text, + role -> Text, + } +} + +joinable!(localuser -> user (user_id)); + +allow_tables_to_appear_in_same_query!( + localuser, + user, +); -- 2.45.0 From 2b8df138e080a572978bc966cc5350de51f5e668 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Berthaud-M=C3=BCller?= Date: Sat, 27 Mar 2021 01:45:59 -0400 Subject: [PATCH 02/11] basic token generation --- Cargo.lock | 263 ++++++++++++++++++ Cargo.toml | 5 +- .../2021-03-26-164945_create_users/up.sql | 2 +- src/auth/routes.rs | 58 ++-- src/main.rs | 5 +- src/models/errors.rs | 18 +- src/models/users.rs | 128 ++++++++- 7 files changed, 446 insertions(+), 33 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b6b47f1..46fdcd0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,7 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 3 + [[package]] name = "aead" version = "0.3.2" @@ -54,6 +56,27 @@ dependencies = [ "opaque-debug", ] +[[package]] +name = "aho-corasick" +version = "0.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5" +dependencies = [ + "memchr", +] + +[[package]] +name = "arrayref" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" + +[[package]] +name = "arrayvec" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" + [[package]] name = "async-trait" version = "0.1.48" @@ -110,6 +133,17 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +[[package]] +name = "blake2b_simd" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587" +dependencies = [ + "arrayref", + "arrayvec", + "constant_time_eq", +] + [[package]] name = "block-buffer" version = "0.9.0" @@ -119,12 +153,24 @@ dependencies = [ "generic-array", ] +[[package]] +name = "bumpalo" +version = "3.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63396b8a4b9de3f4fdfb320ab6080762242f66a8ef174c49d8e19b674db4cdbe" + [[package]] name = "byteorder" version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +[[package]] +name = "cc" +version = "1.0.67" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd" + [[package]] name = "cfg-if" version = "0.1.10" @@ -146,6 +192,7 @@ dependencies = [ "libc", "num-integer", "num-traits", + "serde", "time", "winapi 0.3.9", ] @@ -159,6 +206,12 @@ dependencies = [ "generic-array", ] +[[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + [[package]] name = "cookie" version = "0.11.4" @@ -187,6 +240,17 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dcb25d077389e53838a8158c8e99174c5a9d902dee4904320db714f3c653ffba" +[[package]] +name = "crossbeam-utils" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7e9d99fa91428effe99c5c6d4634cdeba32b8cf784fc428a2a687f61a952c49" +dependencies = [ + "autocfg", + "cfg-if 1.0.0", + "lazy_static", +] + [[package]] name = "crypto-mac" version = "0.10.0" @@ -288,6 +352,20 @@ dependencies = [ "generic-array", ] +[[package]] +name = "djangohashers" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b101df5b2cab337a012f1a43d4a48810a81c10ea3b6bc73b456f5707c7b4325" +dependencies = [ + "base64 0.13.0", + "constant_time_eq", + "lazy_static", + "rand", + "regex", + "rust-argon2", +] + [[package]] name = "endian-type" version = "0.1.2" @@ -591,6 +669,29 @@ version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" +[[package]] +name = "js-sys" +version = "0.3.49" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc15e39392125075f60c95ba416f5381ff6c3a948ff02ab12464715adf56c821" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "jsonwebtoken" +version = "7.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afabcc15e437a6484fc4f12d0fd63068fe457bf93f1c148d3d9649c60b103f32" +dependencies = [ + "base64 0.12.3", + "pem", + "ring", + "serde", + "serde_json", + "simple_asn1", +] + [[package]] name = "kernel32-sys" version = "0.2.2" @@ -774,8 +875,11 @@ name = "nomilo" version = "0.1.0-dev" dependencies = [ "base64 0.13.0", + "chrono", "diesel", "diesel-derive-enum", + "djangohashers", + "jsonwebtoken", "rocket", "rocket_contrib", "serde", @@ -813,6 +917,17 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "num-bigint" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + [[package]] name = "num-integer" version = "0.1.44" @@ -842,6 +957,12 @@ dependencies = [ "libc", ] +[[package]] +name = "once_cell" +version = "1.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3" + [[package]] name = "opaque-debug" version = "0.3.0" @@ -895,6 +1016,17 @@ dependencies = [ "yansi", ] +[[package]] +name = "pem" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd56cbd21fea48d0c440b41cd69c589faacade08c992d9a54e471b79d0fd13eb" +dependencies = [ + "base64 0.13.0", + "once_cell", + "regex", +] + [[package]] name = "percent-encoding" version = "1.0.1" @@ -1048,6 +1180,38 @@ dependencies = [ "bitflags", ] +[[package]] +name = "regex" +version = "1.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "957056ecddbeba1b26965114e191d2e8589ce74db242b6ea25fc4062427a5c19" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5f089152e60f62d28b835fbff2cd2e8dc0baf1ac13343bef92ab7eed84548" + +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin", + "untrusted", + "web-sys", + "winapi 0.3.9", +] + [[package]] name = "rocket" version = "0.4.7" @@ -1129,6 +1293,18 @@ dependencies = [ "unicode-xid 0.1.0", ] +[[package]] +name = "rust-argon2" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b18820d944b33caa75a71378964ac46f58517c92b6ae5f762636247c09e78fb" +dependencies = [ + "base64 0.13.0", + "blake2b_simd", + "constant_time_eq", + "crossbeam-utils", +] + [[package]] name = "ryu" version = "1.0.5" @@ -1209,6 +1385,17 @@ dependencies = [ "opaque-debug", ] +[[package]] +name = "simple_asn1" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "692ca13de57ce0613a363c8c2f1de925adebc81b04c923ac60c5488bb44abe4b" +dependencies = [ + "chrono", + "num-bigint", + "num-traits", +] + [[package]] name = "slab" version = "0.4.2" @@ -1232,6 +1419,12 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + [[package]] name = "state" version = "0.4.2" @@ -1460,6 +1653,12 @@ dependencies = [ "subtle", ] +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + [[package]] name = "url" version = "1.7.2" @@ -1528,6 +1727,70 @@ version = "0.10.2+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" +[[package]] +name = "wasm-bindgen" +version = "0.2.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fe8f61dba8e5d645a4d8132dc7a0a66861ed5e1045d2c0ed940fab33bac0fbe" +dependencies = [ + "cfg-if 1.0.0", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "046ceba58ff062da072c7cb4ba5b22a37f00a302483f7e2a6cdc18fedbdc1fd3" +dependencies = [ + "bumpalo", + "lazy_static", + "log 0.4.14", + "proc-macro2 1.0.24", + "quote 1.0.9", + "syn 1.0.64", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ef9aa01d36cda046f797c57959ff5f3c615c9cc63997a8d545831ec7976819b" +dependencies = [ + "quote 1.0.9", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96eb45c1b2ee33545a813a92dbb53856418bf7eb54ab34f7f7ff1448a5b3735d" +dependencies = [ + "proc-macro2 1.0.24", + "quote 1.0.9", + "syn 1.0.64", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7148f4696fb4960a346eaa60bbfb42a1ac4ebba21f750f75fc1375b098d5ffa" + +[[package]] +name = "web-sys" +version = "0.3.49" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59fe19d70f5dacc03f6e46777213facae5ac3801575d56ca6cbd4c93dcd12310" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "winapi" version = "0.2.8" diff --git a/Cargo.toml b/Cargo.toml index 50c1fa9..124b8a6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,10 +11,13 @@ trust-dns-client = "0.20.1" trust-dns-proto = "0.20.1" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -rocket = "0.4.7" +rocket = "0.4" rocket_contrib = { version = "0.4", default-features = false, features = ["json", "diesel_sqlite_pool"]} toml = "0.5" base64 = "0.13.0" uuid = { version = "0.8.2", features = ["v4", "serde"] } diesel = { version = "1.4", features = ["sqlite"] } diesel-derive-enum = { version = "1", features = ["sqlite"] } +djangohashers = { version = "1.4.0", features = ["with_argon2"], default-features = false } +jsonwebtoken = "7.2.0" +chrono = { version = "0.4", features = ["serde"] } diff --git a/migrations/2021-03-26-164945_create_users/up.sql b/migrations/2021-03-26-164945_create_users/up.sql index 0dbdbdc..c9753af 100644 --- a/migrations/2021-03-26-164945_create_users/up.sql +++ b/migrations/2021-03-26-164945_create_users/up.sql @@ -1,7 +1,7 @@ -- Your SQL goes here CREATE TABLE localuser ( user_id VARCHAR NOT NULL PRIMARY KEY, - username VARCHAR NOT NULL, + username VARCHAR NOT NULL UNIQUE, password VARCHAR NOT NULL, FOREIGN KEY(user_id) REFERENCES user(id) ); diff --git a/src/auth/routes.rs b/src/auth/routes.rs index d8b1fe5..247157b 100644 --- a/src/auth/routes.rs +++ b/src/auth/routes.rs @@ -1,15 +1,26 @@ use serde::{Serialize, Deserialize}; + use rocket_contrib::json::Json; -use diesel::prelude::*; +use rocket::Response; +use rocket::http::Status; +use uuid::Uuid; +use jsonwebtoken::{encode, Header, EncodingKey}; +use chrono::prelude::{DateTime, Utc}; +use chrono::Duration; +use chrono::serde::ts_seconds; + use crate::DbConn; -use crate::models::users::{UserInfo, LocalUser, User}; +use crate::models::errors::ErrorResponse; +use crate::models::users::{LocalUser, CreateUserRequest}; #[derive(Debug, Serialize, Deserialize)] struct AuthClaims { jti: String, sub: String, - exp: usize, - iat: usize, + #[serde(with = "ts_seconds")] + exp: DateTime, + #[serde(with = "ts_seconds")] + iat: DateTime, } #[derive(Debug, Serialize)] @@ -19,26 +30,35 @@ pub struct AuthTokenResponse { #[derive(Debug, Deserialize)] pub struct AuthTokenRequest { - user: String, + username: String, password: String, } #[post("/users/me/token", data = "")] -pub fn create_auth_token(conn: DbConn, auth_request: Json) -> Json { - use crate::schema::localuser::dsl::*; - use crate::schema::user::dsl::*; +pub fn create_auth_token(conn: DbConn, auth_request: Json) -> Result, ErrorResponse<()>> { + let user_info = LocalUser::get_user_by_creds(&conn, &auth_request.username, &auth_request.password)?; + let jti = Uuid::new_v4().to_simple().to_string(); + let iat = Utc::now(); + let exp = iat + Duration::minutes(1); - let client_user: Result<(User, LocalUser), _> = user.inner_join(localuser).filter(username.eq(&auth_request.user)).get_result(&*conn); - println!("{:?}", client_user); - Json(AuthTokenResponse { token: "".into() }) + let claims = AuthClaims { + jti: jti, + sub: user_info.id, + exp: exp, + iat: iat, + }; + + // TODO: catch error + let token = encode(&Header::default(), &claims, &EncodingKey::from_secret("changeme".as_ref())).unwrap(); + + Ok(Json(AuthTokenResponse { token })) } -/* -GET /users -> list all users -POST /users -{ - provider: local - ... +#[post("/users", data = "")] +pub fn create_user<'r>(conn: DbConn, user_request: Json) -> Result, ErrorResponse<()>>{ + // TODO: Check current user if any to check if user has permission to create users (with or without role) + let _user_info = LocalUser::create_user(&conn, user_request.into_inner())?; + Response::build() + .status(Status::Created) + .ok() } -/users// -*/ diff --git a/src/main.rs b/src/main.rs index bfb8332..d563a3f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,9 +8,6 @@ use rocket::State; use rocket::http::Status; use rocket_contrib::json::Json; -use rocket_contrib::databases::diesel as rocket_diesel; - -use diesel::prelude::*; use trust_dns_client::client::{Client, SyncClient}; use trust_dns_client::tcp::TcpClientConnection; @@ -66,5 +63,5 @@ fn main() { rocket::ignite() .manage(client) .attach(DbConn::fairing()) - .mount("/api/v1", routes![get_zone_records, create_auth_token]).launch(); + .mount("/api/v1", routes![get_zone_records, create_auth_token, create_user]).launch(); } diff --git a/src/models/errors.rs b/src/models/errors.rs index d08b697..856b28e 100644 --- a/src/models/errors.rs +++ b/src/models/errors.rs @@ -3,7 +3,7 @@ use rocket::http::Status; use rocket::request::Request; use rocket::response::{self, Response, Responder}; use rocket_contrib::json::Json; - +use crate::models::users::UserError; #[derive(Serialize, Debug)] pub struct ErrorResponse { @@ -53,3 +53,19 @@ impl<'r, T: Serialize> Responder<'r> for ErrorResponse { Response::build_from(Json(self).respond_to(req)?).status(status).ok() } } + +impl From for ErrorResponse<()> { + fn from(e: UserError) -> Self { + match e { + UserError::NotFound => ErrorResponse::new(Status::Unauthorized, "Incorrect password or username.".into()), + UserError::UserExists => ErrorResponse::new(Status::Conflict, "User already exists.".into()), + UserError::DbError(e) => make_500(e), + UserError::PasswordError(e) => make_500(e) + } + } +} + +fn make_500(e: E) -> ErrorResponse<()> { + println!("{:?}", e); + ErrorResponse::new(Status::InternalServerError, "An unexpected error occured.".into()) +} diff --git a/src/models/users.rs b/src/models/users.rs index 6d113a6..7772d51 100644 --- a/src/models/users.rs +++ b/src/models/users.rs @@ -1,25 +1,32 @@ use uuid::Uuid; use diesel::prelude::*; -use diesel::associations::HasTable; +use diesel::result::Error as DieselError; use rocket::request::{FromRequest, Request, Outcome}; use diesel_derive_enum::DbEnum; +use serde::Deserialize; +// TODO: Maybe just use argon2 crate directly +use djangohashers::{make_password_with_algorithm, check_password, HasherError, Algorithm}; use crate::schema::*; +use crate::DbConn; -#[derive(Debug, DbEnum)] +#[derive(Debug, DbEnum, Deserialize)] +#[serde(rename_all = "snake_case")] pub enum Role { Admin, ZoneAdmin, } -#[derive(Debug, Queryable, Identifiable)] +// TODO: Store Uuid instead of string?? +// TODO: Store role as Role and not String. +#[derive(Debug, Queryable, Identifiable, Insertable)] #[table_name = "user"] pub struct User { pub id: String, pub role: String, } -#[derive(Debug, Queryable, Identifiable)] +#[derive(Debug, Queryable, Identifiable, Insertable)] #[table_name = "localuser"] #[primary_key(user_id)] pub struct LocalUser { @@ -28,21 +35,128 @@ pub struct LocalUser { pub password: String, } +#[derive(Debug, Deserialize)] +pub struct CreateUserRequest { + pub username: String, + pub password: String, + pub email: String, + pub role: Option +} + // pub struct LdapUserAssociation { // user_id: Uuid, // ldap_id: String // } +#[derive(Debug)] pub struct UserInfo { - id: Uuid, - role: Role, - username: String, + pub id: String, + pub role: String, + pub username: String, } impl<'a, 'r> FromRequest<'a, 'r> for UserInfo { type Error = (); fn from_request(request: &'a Request<'r>) -> Outcome { + // LocalUser::get_user_by_uuid() Outcome::Forward(()) } } + +#[derive(Debug)] +pub enum UserError { + NotFound, + UserExists, + DbError(DieselError), + PasswordError(HasherError), +} + +impl From for UserError { + fn from(e: DieselError) -> Self { + match e { + DieselError::NotFound => UserError::NotFound, + DieselError::DatabaseError(diesel::result::DatabaseErrorKind::UniqueViolation, _) => UserError::UserExists, + other => UserError::DbError(other) + } + } +} + +impl From for UserError { + fn from(e: HasherError) -> Self { + match e { + other => UserError::PasswordError(other) + } + } +} + + +impl LocalUser { + pub fn create_user(conn: &DbConn, user_request: CreateUserRequest) -> Result { + use crate::schema::localuser::dsl::*; + use crate::schema::user::dsl::*; + + let new_user_id = Uuid::new_v4().to_simple().to_string(); + + let new_user = User { + id: new_user_id.clone(), + // TODO: Use role from request + role: "zoneadmin".into(), + }; + + let new_localuser = LocalUser { + user_id: new_user_id.clone(), + username: user_request.username.clone(), + password: make_password_with_algorithm(&user_request.password, Algorithm::Argon2), + }; + + let res = UserInfo { + id: new_user.id.clone(), + role: new_user.role.clone(), + username: new_localuser.username.clone(), + }; + + conn.immediate_transaction(|| -> diesel::QueryResult<()> { + diesel::insert_into(user) + .values(new_user) + .execute(&**conn)?; + + diesel::insert_into(localuser) + .values(new_localuser) + .execute(&**conn)?; + + Ok(()) + })?; + + Ok(res) + } + + pub fn get_user_by_creds( + conn: &DbConn, + request_username: &str, + request_password: &str + ) -> Result { + + use crate::schema::localuser::dsl::*; + use crate::schema::user::dsl::*; + + let (client_user, client_localuser): (User, LocalUser) = user.inner_join(localuser) + .filter(username.eq(request_username)) + .get_result(&**conn)?; + + if !check_password(&request_password, &client_localuser.password)? { + return Err(UserError::NotFound); + } + + Ok(UserInfo { + id: client_user.id, + role: client_user.role, + username: client_localuser.username, + }) + } + + pub fn get_user_by_uuid(user_id: Uuid) -> Result { + unimplemented!() + } + +} -- 2.45.0 From 759bf0cb4d294215dacc78a81cbcab6ac3c83fbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Berthaud-M=C3=BCller?= Date: Sat, 27 Mar 2021 13:23:19 -0400 Subject: [PATCH 03/11] add config for tokens --- Cargo.lock | 7 ++++++ Cargo.toml | 1 + config.example.toml | 9 +++++-- src/auth/routes.rs | 57 ++++++++++---------------------------------- src/config.rs | 42 ++++++++++++++++++++++++++------ src/main.rs | 4 +++- src/models/errors.rs | 5 +--- src/models/users.rs | 50 +++++++++++++++++++++++++++++++++++--- 8 files changed, 114 insertions(+), 61 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 46fdcd0..3fd27dc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -568,6 +568,12 @@ version = "1.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "615caabe2c3160b313d52ccc905335f4ed5f10881dd63dc5699d47e90be85691" +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + [[package]] name = "hyper" version = "0.10.16" @@ -879,6 +885,7 @@ dependencies = [ "diesel", "diesel-derive-enum", "djangohashers", + "humantime", "jsonwebtoken", "rocket", "rocket_contrib", diff --git a/Cargo.toml b/Cargo.toml index 124b8a6..2712a07 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,3 +21,4 @@ diesel-derive-enum = { version = "1", features = ["sqlite"] } djangohashers = { version = "1.4.0", features = ["with_argon2"], default-features = false } jsonwebtoken = "7.2.0" chrono = { version = "0.4", features = ["serde"] } +humantime = "2.1.0" diff --git a/config.example.toml b/config.example.toml index fc23052..ade3716 100644 --- a/config.example.toml +++ b/config.example.toml @@ -1,2 +1,7 @@ -[dns_server] -address = "127.0.0.1:53" +[web_app] +# base64 secret, change it (openssl rand -base64 32) +secret = "Y2hhbmdlbWUK" +token_duration = "1d" + +[dns] +server = "127.0.0.1:53" diff --git a/src/auth/routes.rs b/src/auth/routes.rs index 247157b..d48c3cf 100644 --- a/src/auth/routes.rs +++ b/src/auth/routes.rs @@ -1,55 +1,24 @@ -use serde::{Serialize, Deserialize}; - use rocket_contrib::json::Json; -use rocket::Response; +use rocket::{Response, State}; use rocket::http::Status; -use uuid::Uuid; -use jsonwebtoken::{encode, Header, EncodingKey}; -use chrono::prelude::{DateTime, Utc}; -use chrono::Duration; -use chrono::serde::ts_seconds; +use crate::config::Config; use crate::DbConn; -use crate::models::errors::ErrorResponse; -use crate::models::users::{LocalUser, CreateUserRequest}; +use crate::models::errors::{ErrorResponse, make_500}; +use crate::models::users::{LocalUser, CreateUserRequest, AuthClaims, AuthTokenRequest, AuthTokenResponse}; -#[derive(Debug, Serialize, Deserialize)] -struct AuthClaims { - jti: String, - sub: String, - #[serde(with = "ts_seconds")] - exp: DateTime, - #[serde(with = "ts_seconds")] - iat: DateTime, -} - -#[derive(Debug, Serialize)] -pub struct AuthTokenResponse { - token: String -} - -#[derive(Debug, Deserialize)] -pub struct AuthTokenRequest { - username: String, - password: String, -} #[post("/users/me/token", data = "")] -pub fn create_auth_token(conn: DbConn, auth_request: Json) -> Result, ErrorResponse<()>> { +pub fn create_auth_token( + conn: DbConn, + config: State, + auth_request: Json +) -> Result, ErrorResponse<()>> { + let user_info = LocalUser::get_user_by_creds(&conn, &auth_request.username, &auth_request.password)?; - let jti = Uuid::new_v4().to_simple().to_string(); - let iat = Utc::now(); - let exp = iat + Duration::minutes(1); - - let claims = AuthClaims { - jti: jti, - sub: user_info.id, - exp: exp, - iat: iat, - }; - - // TODO: catch error - let token = encode(&Header::default(), &claims, &EncodingKey::from_secret("changeme".as_ref())).unwrap(); + let token = AuthClaims::new(&user_info, config.web_app.token_duration) + .encode(&config.web_app.secret) + .map_err(|e| make_500(e))?; Ok(Json(AuthTokenResponse { token })) } diff --git a/src/config.rs b/src/config.rs index 8a1901d..f0e0428 100644 --- a/src/config.rs +++ b/src/config.rs @@ -2,20 +2,48 @@ use std::net::SocketAddr; use std::path::PathBuf; use std::fs; -use serde::{Deserialize}; +use serde::{Deserialize, Deserializer}; +use chrono::Duration; use toml; -#[derive(Deserialize)] +#[derive(Debug, Deserialize)] pub struct Config { - pub dns_server: DnsServerConfig + pub dns: DnsConfig, + pub web_app: WebAppConfig, } -#[derive(Deserialize)] -pub struct DnsServerConfig { - pub address: SocketAddr +#[derive(Debug, Deserialize)] +pub struct DnsConfig { + pub server: SocketAddr +} + +#[derive(Debug, Deserialize)] +pub struct WebAppConfig { + #[serde(deserialize_with = "from_base64")] + pub secret: Vec, + #[serde(deserialize_with = "from_duration")] + pub token_duration: Duration, +} + +fn from_base64<'de, D>(deserializer: D) -> Result, D::Error> + where D: Deserializer<'de> +{ + use serde::de::Error; + String::deserialize(deserializer) + .and_then(|string| base64::decode(&string).map_err(|err| Error::custom(err.to_string()))) +} + +fn from_duration<'de, D>(deserializer: D) -> Result + where D: Deserializer<'de> +{ + use serde::de::Error; + String::deserialize(deserializer) + .and_then(|string| humantime::parse_duration(&string).map_err(|err| Error::custom(err.to_string()))) + .and_then(|duration| Duration::from_std(duration).map_err(|err| Error::custom(err.to_string()))) } pub fn load(file_name: PathBuf) -> Config { - toml::from_str(&fs::read_to_string(file_name).expect("could not read config file")).expect("could not parse config file") + let file_content = fs::read_to_string(file_name).expect("could not read config file"); + toml::from_str(&file_content).expect("could not parse config file") } diff --git a/src/main.rs b/src/main.rs index d563a3f..6550319 100644 --- a/src/main.rs +++ b/src/main.rs @@ -56,12 +56,14 @@ fn get_zone_records(client: State>, zone: String fn main() { let app_config = config::load("config.toml".into()); + println!("{:#?}", app_config); - let conn = TcpClientConnection::new(app_config.dns_server.address).unwrap(); + let conn = TcpClientConnection::new(app_config.dns.server).unwrap(); let client = SyncClient::new(conn); rocket::ignite() .manage(client) + .manage(app_config) .attach(DbConn::fairing()) .mount("/api/v1", routes![get_zone_records, create_auth_token, create_user]).launch(); } diff --git a/src/models/errors.rs b/src/models/errors.rs index 856b28e..c8892f7 100644 --- a/src/models/errors.rs +++ b/src/models/errors.rs @@ -15,7 +15,6 @@ pub struct ErrorResponse { pub details: Option } - #[derive(Serialize)] #[serde(remote = "Status")] struct StatusDef { @@ -24,7 +23,6 @@ struct StatusDef { reason: &'static str, } - impl ErrorResponse { pub fn new(status: Status, message: String) -> ErrorResponse { ErrorResponse { @@ -46,7 +44,6 @@ impl ErrorResponse { } } - impl<'r, T: Serialize> Responder<'r> for ErrorResponse { fn respond_to(self, req: &Request) -> response::Result<'r> { let status = self.status; @@ -65,7 +62,7 @@ impl From for ErrorResponse<()> { } } -fn make_500(e: E) -> ErrorResponse<()> { +pub fn make_500(e: E) -> ErrorResponse<()> { println!("{:?}", e); ErrorResponse::new(Status::InternalServerError, "An unexpected error occured.".into()) } diff --git a/src/models/users.rs b/src/models/users.rs index 7772d51..cd0989b 100644 --- a/src/models/users.rs +++ b/src/models/users.rs @@ -1,15 +1,20 @@ use uuid::Uuid; use diesel::prelude::*; use diesel::result::Error as DieselError; -use rocket::request::{FromRequest, Request, Outcome}; use diesel_derive_enum::DbEnum; -use serde::Deserialize; +use rocket::request::{FromRequest, Request, Outcome}; +use serde::{Serialize, Deserialize}; +use chrono::serde::ts_seconds; +use chrono::prelude::{DateTime, Utc}; +use chrono::Duration; // TODO: Maybe just use argon2 crate directly use djangohashers::{make_password_with_algorithm, check_password, HasherError, Algorithm}; +use jsonwebtoken::{encode, Header, EncodingKey, errors::Result as JwtResult}; use crate::schema::*; use crate::DbConn; + #[derive(Debug, DbEnum, Deserialize)] #[serde(rename_all = "snake_case")] pub enum Role { @@ -48,6 +53,27 @@ pub struct CreateUserRequest { // ldap_id: String // } +#[derive(Debug, Serialize, Deserialize)] +pub struct AuthClaims { + pub jti: String, + pub sub: String, + #[serde(with = "ts_seconds")] + pub exp: DateTime, + #[serde(with = "ts_seconds")] + pub iat: DateTime, +} + +#[derive(Debug, Serialize)] +pub struct AuthTokenResponse { + pub token: String +} + +#[derive(Debug, Deserialize)] +pub struct AuthTokenRequest { + pub username: String, + pub password: String, +} + #[derive(Debug)] pub struct UserInfo { pub id: String, @@ -90,7 +116,6 @@ impl From for UserError { } } - impl LocalUser { pub fn create_user(conn: &DbConn, user_request: CreateUserRequest) -> Result { use crate::schema::localuser::dsl::*; @@ -160,3 +185,22 @@ impl LocalUser { } } + +impl AuthClaims { + pub fn new(user_info: &UserInfo, token_duration: Duration) -> AuthClaims { + let jti = Uuid::new_v4().to_simple().to_string(); + let iat = Utc::now(); + let exp = iat + token_duration; + + AuthClaims { + jti: jti, + sub: user_info.id.clone(), + exp: exp, + iat: iat, + } + } + + pub fn encode(self, secret: &[u8]) -> JwtResult { + encode(&Header::default(), &self, &EncodingKey::from_secret(&secret)) + } +} -- 2.45.0 From 853b760968cb6295ea1e1fc56eca6747f4724520 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Berthaud-M=C3=BCller?= Date: Sat, 27 Mar 2021 13:31:14 -0400 Subject: [PATCH 04/11] secret as string and not bytes --- src/config.rs | 11 +---------- src/models/users.rs | 4 ++-- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/src/config.rs b/src/config.rs index f0e0428..e664e51 100644 --- a/src/config.rs +++ b/src/config.rs @@ -20,20 +20,11 @@ pub struct DnsConfig { #[derive(Debug, Deserialize)] pub struct WebAppConfig { - #[serde(deserialize_with = "from_base64")] - pub secret: Vec, + pub secret: String, #[serde(deserialize_with = "from_duration")] pub token_duration: Duration, } -fn from_base64<'de, D>(deserializer: D) -> Result, D::Error> - where D: Deserializer<'de> -{ - use serde::de::Error; - String::deserialize(deserializer) - .and_then(|string| base64::decode(&string).map_err(|err| Error::custom(err.to_string()))) -} - fn from_duration<'de, D>(deserializer: D) -> Result where D: Deserializer<'de> { diff --git a/src/models/users.rs b/src/models/users.rs index cd0989b..be1a6b7 100644 --- a/src/models/users.rs +++ b/src/models/users.rs @@ -200,7 +200,7 @@ impl AuthClaims { } } - pub fn encode(self, secret: &[u8]) -> JwtResult { - encode(&Header::default(), &self, &EncodingKey::from_secret(&secret)) + pub fn encode(self, secret: &str) -> JwtResult { + encode(&Header::default(), &self, &EncodingKey::from_secret(secret.as_bytes())) } } -- 2.45.0 From 5e08f2c2c85ca4ffcf2e9b22bb711277f3d38eea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Berthaud-M=C3=BCller?= Date: Sat, 27 Mar 2021 15:36:57 -0400 Subject: [PATCH 05/11] basic authentification check --- src/main.rs | 8 ++++- src/models/errors.rs | 8 +++-- src/models/users.rs | 86 +++++++++++++++++++++++++++++++++++++++----- 3 files changed, 90 insertions(+), 12 deletions(-) diff --git a/src/main.rs b/src/main.rs index 6550319..f78f5fd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -20,6 +20,7 @@ mod auth; mod schema; use models::errors::ErrorResponse; +use models::users::UserInfo; use auth::routes::*; @@ -27,7 +28,12 @@ use auth::routes::*; pub struct DbConn(diesel::SqliteConnection); #[get("/zones//records")] -fn get_zone_records(client: State>, zone: String) -> Result>, ErrorResponse<()>> { +fn get_zone_records( + client: State>, + _user_info: UserInfo, + zone: String +) -> Result>, ErrorResponse<()>> { + // TODO: Implement FromParam for Name let name = Name::from_utf8(&zone).unwrap(); diff --git a/src/models/errors.rs b/src/models/errors.rs index c8892f7..9a7d56b 100644 --- a/src/models/errors.rs +++ b/src/models/errors.rs @@ -54,8 +54,12 @@ impl<'r, T: Serialize> Responder<'r> for ErrorResponse { impl From for ErrorResponse<()> { fn from(e: UserError) -> Self { match e { - UserError::NotFound => ErrorResponse::new(Status::Unauthorized, "Incorrect password or username.".into()), - UserError::UserExists => ErrorResponse::new(Status::Conflict, "User already exists.".into()), + UserError::NotFound => ErrorResponse::new(Status::Unauthorized, "Provided credentials or token do not match any existing user".into()), + UserError::UserExists => ErrorResponse::new(Status::Conflict, "User already exists".into()), + UserError::BadToken => ErrorResponse::new(Status::BadRequest, "Malformed token".into()), + UserError::ExpiredToken => ErrorResponse::new(Status::Unauthorized, "The provided token has expired".into()), + UserError::MalformedHeader => ErrorResponse::new(Status::BadRequest, "Malformed authorization header".into()), + UserError::PermissionDenied => ErrorResponse::new(Status::Forbidden, "Bearer is not authorized to access the resource".into()), UserError::DbError(e) => make_500(e), UserError::PasswordError(e) => make_500(e) } diff --git a/src/models/users.rs b/src/models/users.rs index be1a6b7..49432d0 100644 --- a/src/models/users.rs +++ b/src/models/users.rs @@ -2,17 +2,29 @@ use uuid::Uuid; use diesel::prelude::*; use diesel::result::Error as DieselError; use diesel_derive_enum::DbEnum; -use rocket::request::{FromRequest, Request, Outcome}; +use rocket::request::{FromRequest, Request, Outcome, State}; use serde::{Serialize, Deserialize}; +use rocket::http::Status; use chrono::serde::ts_seconds; use chrono::prelude::{DateTime, Utc}; use chrono::Duration; // TODO: Maybe just use argon2 crate directly use djangohashers::{make_password_with_algorithm, check_password, HasherError, Algorithm}; -use jsonwebtoken::{encode, Header, EncodingKey, errors::Result as JwtResult}; +use jsonwebtoken::{ + encode, decode, + Header, Validation, + Algorithm as JwtAlgorithm, EncodingKey, DecodingKey, + errors::Result as JwtResult, + errors::ErrorKind as JwtErrorKind +}; use crate::schema::*; use crate::DbConn; +use crate::config::Config; + + +const BEARER: &'static str = "Bearer "; +const AUTH_HEADER: &'static str = "Authentication"; #[derive(Debug, DbEnum, Deserialize)] @@ -82,11 +94,44 @@ pub struct UserInfo { } impl<'a, 'r> FromRequest<'a, 'r> for UserInfo { - type Error = (); + type Error = UserError; - fn from_request(request: &'a Request<'r>) -> Outcome { - // LocalUser::get_user_by_uuid() - Outcome::Forward(()) + fn from_request(request: &'a Request<'r>) -> Outcome { + let auth_header = match request.headers().get_one(AUTH_HEADER) { + None => return Outcome::Forward(()), + Some(auth_header) => auth_header, + }; + + let token = if auth_header.starts_with(BEARER) { + auth_header.trim_start_matches(BEARER) + } else { + return Outcome::Failure((Status::BadRequest, UserError::MalformedHeader)) + }; + + // TODO: Better error handling + let config = request.guard::>().unwrap(); + let conn = request.guard::().unwrap(); + + let token_data = AuthClaims::decode( + token, &config.web_app.secret + ).map_err(|e| match e.into_kind() { + JwtErrorKind::ExpiredSignature => (Status::Unauthorized, UserError::ExpiredToken), + _ => (Status::BadRequest, UserError::BadToken), + }); + + let token_data = match token_data { + Err(e) => return Outcome::Failure(e), + Ok(data) => data + }; + + let user_id = token_data.sub; + let user_info = match LocalUser::get_user_by_uuid(&conn, user_id) { + Err(UserError::NotFound) => return Outcome::Failure((Status::NotFound, UserError::NotFound)), + Err(e) => return Outcome::Failure((Status::InternalServerError, e)), + Ok(d) => d, + }; + + return Outcome::Success(user_info) } } @@ -94,6 +139,10 @@ impl<'a, 'r> FromRequest<'a, 'r> for UserInfo { pub enum UserError { NotFound, UserExists, + BadToken, + ExpiredToken, + MalformedHeader, + PermissionDenied, DbError(DieselError), PasswordError(HasherError), } @@ -180,8 +229,19 @@ impl LocalUser { }) } - pub fn get_user_by_uuid(user_id: Uuid) -> Result { - unimplemented!() + pub fn get_user_by_uuid(conn: &DbConn, request_user_id: String) -> Result { + use crate::schema::localuser::dsl::*; + use crate::schema::user::dsl::*; + + let (client_user, client_localuser): (User, LocalUser) = user.inner_join(localuser) + .filter(id.eq(request_user_id)) + .get_result(&**conn)?; + + Ok(UserInfo { + id: client_user.id, + role: client_user.role, + username: client_localuser.username, + }) } } @@ -200,7 +260,15 @@ impl AuthClaims { } } + pub fn decode(token: &str, secret: &str) -> JwtResult { + decode::( + token, + &DecodingKey::from_secret(secret.as_ref()), + &Validation::new(JwtAlgorithm::HS256) + ).and_then(|data| Ok(data.claims)) + } + pub fn encode(self, secret: &str) -> JwtResult { - encode(&Header::default(), &self, &EncodingKey::from_secret(secret.as_bytes())) + encode(&Header::default(), &self, &EncodingKey::from_secret(secret.as_ref())) } } -- 2.45.0 From 13a163423cad9ce21197901e84422d18b162d826 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Berthaud-M=C3=BCller?= Date: Fri, 2 Apr 2021 13:33:59 -0400 Subject: [PATCH 06/11] update rocket to 0.5-dev --- Cargo.lock | 1288 ++++++++++++++++++++++-------------------- Cargo.toml | 4 +- src/auth/routes.rs | 16 +- src/main.rs | 6 +- src/models/errors.rs | 4 +- src/models/users.rs | 38 +- 6 files changed, 718 insertions(+), 638 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3fd27dc..c6e4aaf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,60 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "aead" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fc95d1bdb8e6666b2b217308eeeb09f2d6728d104be3e31916cc74d15420331" -dependencies = [ - "generic-array", -] - -[[package]] -name = "aes" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "884391ef1066acaa41e766ba8f596341b96e93ce34f9a43e7d24bf0a0eaf0561" -dependencies = [ - "aes-soft", - "aesni", - "cipher", -] - -[[package]] -name = "aes-gcm" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5278b5fabbb9bd46e24aa69b2fdea62c99088e0a950a9be40e3e0101298f88da" -dependencies = [ - "aead", - "aes", - "cipher", - "ctr", - "ghash", - "subtle", -] - -[[package]] -name = "aes-soft" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be14c7498ea50828a38d0e24a765ed2effe92a705885b57d029cd67d45744072" -dependencies = [ - "cipher", - "opaque-debug", -] - -[[package]] -name = "aesni" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea2e11f5e94c2f7d386164cc2aa1f97823fed6f259e486940a71c174dd01b0ce" -dependencies = [ - "cipher", - "opaque-debug", -] - [[package]] name = "aho-corasick" version = "0.7.15" @@ -83,9 +29,18 @@ version = "0.1.48" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "36ea56748e10732c49404c153638a15ec3d6211ec5ff35d9bb20e13b93576adf" dependencies = [ - "proc-macro2 1.0.24", - "quote 1.0.9", - "syn 1.0.64", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "atomic" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3410529e8288c463bedb5930f82833bc0c90e5d2fe639a56582a4d09220b281" +dependencies = [ + "autocfg", ] [[package]] @@ -96,7 +51,7 @@ checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ "hermit-abi", "libc", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -106,14 +61,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" [[package]] -name = "base64" -version = "0.9.3" +name = "base-x" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643" -dependencies = [ - "byteorder", - "safemem", -] +checksum = "a4521f3e3d031370679b3b140beb36dfe4801b09ac77e30c61941f97df3ef28b" [[package]] name = "base64" @@ -127,6 +78,12 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" +[[package]] +name = "binascii" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "383d29d513d8764dcdc42ea295d979eb99c3c9f00607b3692cf68a431f7dca72" + [[package]] name = "bitflags" version = "1.2.1" @@ -144,15 +101,6 @@ dependencies = [ "constant_time_eq", ] -[[package]] -name = "block-buffer" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" -dependencies = [ - "generic-array", -] - [[package]] name = "bumpalo" version = "3.6.1" @@ -165,6 +113,12 @@ version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +[[package]] +name = "bytes" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040" + [[package]] name = "cc" version = "1.0.67" @@ -193,18 +147,15 @@ dependencies = [ "num-integer", "num-traits", "serde", - "time", - "winapi 0.3.9", + "time 0.1.43", + "winapi", ] [[package]] -name = "cipher" -version = "0.2.5" +name = "const_fn" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12f8e7987cbd042a63249497f41aed09f8e65add917ea6566effbc56578d6801" -dependencies = [ - "generic-array", -] +checksum = "076a6803b0dacd6a88cfe64deba628b01533ff5ef265687e6938280c1afd0a28" [[package]] name = "constant_time_eq" @@ -212,34 +163,23 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + [[package]] name = "cookie" -version = "0.11.4" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80f6044740a4a516b8aac14c140cdf35c1a640b1bd6b98b6224e49143b2f1566" +checksum = "ffdf8865bac3d9a3bde5bde9088ca431b11f5d37c7a578b8086af77248b76627" dependencies = [ - "aes-gcm", - "base64 0.13.0", - "hkdf", - "hmac", - "percent-encoding 2.1.0", - "rand", - "sha2", - "time", + "percent-encoding", + "time 0.2.26", + "version_check", ] -[[package]] -name = "cpuid-bool" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634" - -[[package]] -name = "cpuid-bool" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcb25d077389e53838a8158c8e99174c5a9d902dee4904320db714f3c653ffba" - [[package]] name = "crossbeam-utils" version = "0.8.3" @@ -251,25 +191,6 @@ dependencies = [ "lazy_static", ] -[[package]] -name = "crypto-mac" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4857fd85a0c34b3c3297875b747c1e02e06b6a0ea32dd892d8192b9ce0813ea6" -dependencies = [ - "generic-array", - "subtle", -] - -[[package]] -name = "ctr" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb4a30d54f7443bf3d6191dcd486aca19e67cb3c49fa7a06a319966346707e7f" -dependencies = [ - "cipher", -] - [[package]] name = "data-encoding" version = "2.3.2" @@ -277,10 +198,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ee2393c4a91429dffb4bedf19f4d6abf27d8a732c8ce4980305d782e5426d57" [[package]] -name = "devise" -version = "0.2.0" +name = "derive_more" +version = "0.99.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74e04ba2d03c5fa0d954c061fc8c9c288badadffc272ebb87679a89846de3ed3" +checksum = "f82b1b72f1263f214c0f823371768776c4f5841b942c9883aa8e5ec584fd0ba6" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "devise" +version = "0.3.0" +source = "git+https://github.com/SergioBenitez/Devise.git?rev=3ebe83#3ebe83823241c7979e6d2ccd18f889968a01985f" dependencies = [ "devise_codegen", "devise_core", @@ -288,24 +220,23 @@ dependencies = [ [[package]] name = "devise_codegen" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "066ceb7928ca93a9bedc6d0e612a8a0424048b0ab1f75971b203d01420c055d7" +version = "0.3.0" +source = "git+https://github.com/SergioBenitez/Devise.git?rev=3ebe83#3ebe83823241c7979e6d2ccd18f889968a01985f" dependencies = [ "devise_core", - "quote 0.6.13", + "quote", ] [[package]] name = "devise_core" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf41c59b22b5e3ec0ea55c7847e5f358d340f3a8d6d53a5cf4f1564967f96487" +version = "0.3.0" +source = "git+https://github.com/SergioBenitez/Devise.git?rev=3ebe83#3ebe83823241c7979e6d2ccd18f889968a01985f" dependencies = [ "bitflags", - "proc-macro2 0.4.30", - "quote 0.6.13", - "syn 0.15.44", + "proc-macro2", + "proc-macro2-diagnostics", + "quote", + "syn", ] [[package]] @@ -327,9 +258,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "703e71c268ea2d8da9c0ab0b40d8b217179ee622209c170875d24443193a0dfb" dependencies = [ "heck", - "proc-macro2 1.0.24", - "quote 1.0.9", - "syn 1.0.64", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -338,19 +269,16 @@ version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "45f5098f628d02a7a0f68ddba586fb61e80edec3bdc1be3b921f4ceec60858d3" dependencies = [ - "proc-macro2 1.0.24", - "quote 1.0.9", - "syn 1.0.64", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "digest" -version = "0.9.0" +name = "discard" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" -dependencies = [ - "generic-array", -] +checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" [[package]] name = "djangohashers" @@ -366,6 +294,21 @@ dependencies = [ "rust-argon2", ] +[[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" + +[[package]] +name = "encoding_rs" +version = "0.8.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80df024fbc5ac80f87dfef0d9f5209a252f2a497f7f42944cff24d8253cac065" +dependencies = [ + "cfg-if 1.0.0", +] + [[package]] name = "endian-type" version = "0.1.2" @@ -379,23 +322,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c5f0096a91d210159eceb2ff5e1c4da18388a170e1e3ce948aac9c8fdbbf595" dependencies = [ "heck", - "proc-macro2 1.0.24", - "quote 1.0.9", - "syn 1.0.64", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "filetime" -version = "0.2.14" +name = "figment" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d34cfa13a63ae058bfa601fe9e313bbdb3746427c1459185464ce0fcf62e1e8" +checksum = "708a94ecb9ca72e347442fef4563e459035b950c78091a355ed8a40180b33367" dependencies = [ - "cfg-if 1.0.0", - "libc", - "redox_syscall", - "winapi 0.3.9", + "atomic", + "pear", + "serde", + "toml", + "uncased", + "version_check", ] +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + [[package]] name = "form_urlencoded" version = "1.0.1" @@ -403,44 +354,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" dependencies = [ "matches", - "percent-encoding 2.1.0", + "percent-encoding", ] [[package]] -name = "fsevent" -version = "0.4.0" +name = "futures" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ab7d1bd1bd33cc98b0889831b72da23c0aa4df9cec7e0702f46ecea04b35db6" +checksum = "7f55667319111d593ba876406af7c409c0ebb44dc4be6132a783ccf163ea14c1" dependencies = [ - "bitflags", - "fsevent-sys", + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", ] -[[package]] -name = "fsevent-sys" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f41b048a94555da0f42f1d632e2e19510084fb8e303b0daa2816e733fb3644a0" -dependencies = [ - "libc", -] - -[[package]] -name = "fuchsia-zircon" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" -dependencies = [ - "bitflags", - "fuchsia-zircon-sys", -] - -[[package]] -name = "fuchsia-zircon-sys" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" - [[package]] name = "futures-channel" version = "0.3.13" @@ -448,6 +379,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c2dd2df839b57db9ab69c2c9d8f3e8c81984781937fe2807dc6dcf3b2ad2939" dependencies = [ "futures-core", + "futures-sink", ] [[package]] @@ -456,12 +388,41 @@ version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "15496a72fabf0e62bdc3df11a59a3787429221dd0710ba8ef163d6f7a9112c94" +[[package]] +name = "futures-executor" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "891a4b7b96d84d5940084b2a37632dd65deeae662c114ceaa2c879629c9c0ad1" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + [[package]] name = "futures-io" version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d71c2c65c57704c32f5241c1223167c2c3294fd34ac020c807ddbe6db287ba59" +[[package]] +name = "futures-macro" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea405816a5139fb39af82c2beb921d52143f556038378d6db21183a5c37fbfb7" +dependencies = [ + "proc-macro-hack", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85754d98985841b7d4f5e8e6fbfa4a4ac847916893ec511a2917ccd8525b8bb3" + [[package]] name = "futures-task" version = "0.3.13" @@ -474,21 +435,31 @@ version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1812c7ab8aedf8d6f2701a43e1243acdbcc2b36ab26e2ad421eb99ac963d96d1" dependencies = [ + "futures-channel", "futures-core", + "futures-io", + "futures-macro", + "futures-sink", "futures-task", + "memchr", "pin-project-lite", "pin-utils", + "proc-macro-hack", + "proc-macro-nested", "slab", ] [[package]] -name = "generic-array" -version = "0.14.4" +name = "generator" +version = "0.6.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" +checksum = "061d3be1afec479d56fa3bd182bf966c7999ec175fcfdb87ac14d417241366c6" dependencies = [ - "typenum", - "version_check 0.9.3", + "cc", + "libc", + "log", + "rustversion", + "winapi", ] [[package]] @@ -502,22 +473,31 @@ dependencies = [ "wasi", ] -[[package]] -name = "ghash" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97304e4cd182c3846f7575ced3890c53012ce534ad9114046b0a9e00bb30a375" -dependencies = [ - "opaque-debug", - "polyval", -] - [[package]] name = "glob" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" +[[package]] +name = "h2" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc018e188373e2777d0ef2467ebff62a08e66c3f5857b23c8fbec3018210dc00" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "hashbrown" version = "0.9.1" @@ -543,23 +523,25 @@ dependencies = [ ] [[package]] -name = "hkdf" -version = "0.10.0" +name = "http" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51ab2f639c231793c5f6114bdb9bbe50a7dbbfcd7c7c6bd8475dec2d991e964f" +checksum = "7245cd7449cc792608c3c8a9eaf69bd4eabbabf802713748fd739c98b82f0747" dependencies = [ - "digest", - "hmac", + "bytes", + "fnv", + "itoa", ] [[package]] -name = "hmac" -version = "0.10.1" +name = "http-body" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1441c6b1e930e2817404b5046f1f989899143a12bf92de603b69f4e0aee1e15" +checksum = "5dfb77c123b4e2f72a2069aeae0b4b4949cc7e966df277813fc16347e7549737" dependencies = [ - "crypto-mac", - "digest", + "bytes", + "http", + "pin-project-lite", ] [[package]] @@ -568,6 +550,12 @@ version = "1.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "615caabe2c3160b313d52ccc905335f4ed5f10881dd63dc5699d47e90be85691" +[[package]] +name = "httpdate" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "494b4d60369511e7dea41cf646832512a94e542f68bb9c49e54518e0f468eb47" + [[package]] name = "humantime" version = "2.1.0" @@ -576,32 +564,26 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.10.16" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a0652d9a2609a968c14be1a9ea00bf4b1d64e2e1f53a1b51b6fff3a6e829273" +checksum = "8bf09f61b52cfcf4c00de50df88ae423d6c02354e385a86341133b5338630ad1" dependencies = [ - "base64 0.9.3", + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", "httparse", - "language-tags", - "log 0.3.9", - "mime", - "num_cpus", - "time", - "traitobject", - "typeable", - "unicase", - "url 1.7.2", -] - -[[package]] -name = "idna" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" -dependencies = [ - "matches", - "unicode-bidi", - "unicode-normalization", + "httpdate", + "itoa", + "pin-project", + "socket2 0.4.0", + "tokio", + "tower-service", + "tracing", + "want", ] [[package]] @@ -623,27 +605,14 @@ checksum = "824845a0bf897a9042383849b02c1bc219c2383772efcd5c6f9766fa4b81aef3" dependencies = [ "autocfg", "hashbrown", + "serde", ] [[package]] -name = "inotify" -version = "0.7.1" +name = "inlinable_string" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4816c66d2c8ae673df83366c18341538f234a26d65a9ecea5c348b453ac1d02f" -dependencies = [ - "bitflags", - "inotify-sys", - "libc", -] - -[[package]] -name = "inotify-sys" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb" -dependencies = [ - "libc", -] +checksum = "3094308123a0e9fd59659ce45e22de9f53fc1d2ac6e1feb9fef988e4f76cad77" [[package]] name = "instant" @@ -654,15 +623,6 @@ dependencies = [ "cfg-if 1.0.0", ] -[[package]] -name = "iovec" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" -dependencies = [ - "libc", -] - [[package]] name = "ipnet" version = "2.3.0" @@ -698,34 +658,12 @@ dependencies = [ "simple_asn1", ] -[[package]] -name = "kernel32-sys" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" -dependencies = [ - "winapi 0.2.8", - "winapi-build", -] - -[[package]] -name = "language-tags" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" - [[package]] name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" -[[package]] -name = "lazycell" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" - [[package]] name = "libc" version = "0.2.90" @@ -751,15 +689,6 @@ dependencies = [ "scopeguard", ] -[[package]] -name = "log" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" -dependencies = [ - "log 0.4.14", -] - [[package]] name = "log" version = "0.4.14" @@ -769,6 +698,19 @@ dependencies = [ "cfg-if 1.0.0", ] +[[package]] +name = "loom" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0e8460f2f2121162705187214720353c517b97bdfb3494c0b1e33d83ebe4bed" +dependencies = [ + "cfg-if 0.1.10", + "generator", + "scoped-tls", + "serde", + "serde_json", +] + [[package]] name = "matches" version = "0.1.8" @@ -783,31 +725,9 @@ checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" [[package]] name = "mime" -version = "0.2.6" +version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba626b8a6de5da682e1caa06bdb42a335aee5a84db8e5046a3e8ab17ba0a3ae0" -dependencies = [ - "log 0.3.9", -] - -[[package]] -name = "mio" -version = "0.6.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4afd66f5b91bf2a3bc13fad0e21caedac168ca4c707504e75585648ae80e4cc4" -dependencies = [ - "cfg-if 0.1.10", - "fuchsia-zircon", - "fuchsia-zircon-sys", - "iovec", - "kernel32-sys", - "libc", - "log 0.4.14", - "miow 0.2.2", - "net2", - "slab", - "winapi 0.2.8", -] +checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" [[package]] name = "mio" @@ -816,34 +736,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2182a122f3b7f3f5329cb1972cee089ba2459a0a80a56935e6e674f096f8d839" dependencies = [ "libc", - "log 0.4.14", - "miow 0.3.6", + "log", + "miow", "ntapi", - "winapi 0.3.9", -] - -[[package]] -name = "mio-extras" -version = "2.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19" -dependencies = [ - "lazycell", - "log 0.4.14", - "mio 0.6.23", - "slab", -] - -[[package]] -name = "miow" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebd808424166322d4a38da87083bfddd3ac4c131334ed55856112eb06d46944d" -dependencies = [ - "kernel32-sys", - "net2", - "winapi 0.2.8", - "ws2_32-sys", + "winapi", ] [[package]] @@ -852,19 +748,27 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a33c1b55807fbed163481b5ba66db4b2fa6cde694a5027be10fb724206c5897" dependencies = [ - "socket2", - "winapi 0.3.9", + "socket2 0.3.19", + "winapi", ] [[package]] -name = "net2" -version = "0.2.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "391630d12b68002ae1e25e8f974306474966550ad82dac6886fb8910c19568ae" +name = "multer" +version = "1.2.2" +source = "git+https://github.com/rousan/multer-rs.git?rev=7e4f0c5f#7e4f0c5fe14e4c531f503922bfe04f68b32ddf17" dependencies = [ - "cfg-if 0.1.10", - "libc", - "winapi 0.3.9", + "bytes", + "derive_more", + "encoding_rs", + "futures-util", + "http", + "httparse", + "log", + "mime", + "tokio", + "tokio-util", + "twoway", + "version_check", ] [[package]] @@ -891,37 +795,19 @@ dependencies = [ "rocket_contrib", "serde", "serde_json", - "toml 0.5.8", + "toml", "trust-dns-client", "trust-dns-proto", "uuid", ] -[[package]] -name = "notify" -version = "4.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80ae4a7688d1fab81c5bf19c64fc8db920be8d519ce6336ed4e7efe024724dbd" -dependencies = [ - "bitflags", - "filetime", - "fsevent", - "fsevent-sys", - "inotify", - "libc", - "mio 0.6.23", - "mio-extras", - "walkdir", - "winapi 0.3.9", -] - [[package]] name = "ntapi" version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44" dependencies = [ - "winapi 0.3.9", + "winapi", ] [[package]] @@ -970,12 +856,6 @@ version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3" -[[package]] -name = "opaque-debug" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" - [[package]] name = "parking_lot" version = "0.11.1" @@ -998,29 +878,30 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "winapi 0.3.9", + "winapi", ] [[package]] name = "pear" -version = "0.1.4" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5320f212db967792b67cfe12bd469d08afd6318a249bd917d5c19bc92200ab8a" +checksum = "86ab3a2b792945ed67eadbbdcbd2898f8dd2319392b2a45ac21adea5245cb113" dependencies = [ + "inlinable_string", "pear_codegen", + "yansi", ] [[package]] name = "pear_codegen" -version = "0.1.4" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfc1c836fdc3d1ef87c348b237b5b5c4dff922156fb2d968f57734f9669768ca" +checksum = "620c9c4776ba41b59ab101360c9b1419c0c8c81cd2e6e39fae7109e7425994cb" dependencies = [ - "proc-macro2 0.4.30", - "quote 0.6.13", - "syn 0.15.44", - "version_check 0.9.3", - "yansi", + "proc-macro2", + "proc-macro2-diagnostics", + "quote", + "syn", ] [[package]] @@ -1034,18 +915,32 @@ dependencies = [ "regex", ] -[[package]] -name = "percent-encoding" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" - [[package]] name = "percent-encoding" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" +[[package]] +name = "pin-project" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc174859768806e91ae575187ada95c91a29e96a98dc5d2cd9a1fed039501ba6" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a490329918e856ed1b083f244e3bfe2d8c4f336407e4ea9e1a9f479ff09049e5" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "pin-project-lite" version = "0.2.6" @@ -1064,17 +959,6 @@ version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" -[[package]] -name = "polyval" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eebcc4aa140b9abd2bc40d9c3f7ccec842679cd79045ac3a7ac698c1a064b7cd" -dependencies = [ - "cpuid-bool 0.2.0", - "opaque-debug", - "universal-hash", -] - [[package]] name = "ppv-lite86" version = "0.2.10" @@ -1082,13 +966,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" [[package]] -name = "proc-macro2" -version = "0.4.30" +name = "proc-macro-hack" +version = "0.5.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" -dependencies = [ - "unicode-xid 0.1.0", -] +checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" + +[[package]] +name = "proc-macro-nested" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086" [[package]] name = "proc-macro2" @@ -1096,16 +983,20 @@ version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" dependencies = [ - "unicode-xid 0.2.1", + "unicode-xid", ] [[package]] -name = "quote" -version = "0.6.13" +name = "proc-macro2-diagnostics" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" +checksum = "4bf29726d67464d49fa6224a1d07936a8c08bb3fba727c7493f6cf1616fdaada" dependencies = [ - "proc-macro2 0.4.30", + "proc-macro2", + "quote", + "syn", + "version_check", + "yansi", ] [[package]] @@ -1114,7 +1005,7 @@ version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" dependencies = [ - "proc-macro2 1.0.24", + "proc-macro2", ] [[package]] @@ -1123,7 +1014,7 @@ version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "545c5bc2b880973c9c10e4067418407a0ccaa3091781d1671d46eb35107cb26f" dependencies = [ - "log 0.4.14", + "log", "parking_lot", "scheduled-thread-pool", ] @@ -1187,6 +1078,26 @@ dependencies = [ "bitflags", ] +[[package]] +name = "ref-cast" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "300f2a835d808734ee295d45007adacb9ebb29dd3ae2424acfa17930cae541da" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c38e3aecd2b21cb3959637b883bb3714bc7e43f0268b9a29d3743ee3e55cdd2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "regex" version = "1.4.5" @@ -1204,6 +1115,15 @@ version = "0.6.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5f089152e60f62d28b835fbff2cd2e8dc0baf1ac13343bef92ab7eed84548" +[[package]] +name = "remove_dir_all" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +dependencies = [ + "winapi", +] + [[package]] name = "ring" version = "0.16.20" @@ -1216,88 +1136,104 @@ dependencies = [ "spin", "untrusted", "web-sys", - "winapi 0.3.9", + "winapi", ] [[package]] name = "rocket" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7febfdfd4d43facfc7daba20349ebe2c310c6735bd6a2a9255ea8bc425b4cb13" +version = "0.5.0-dev" +source = "git+https://github.com/SergioBenitez/Rocket?rev=0654890#0654890e3d03a91537ee1d06b34ea3d2143f009e" dependencies = [ + "async-trait", + "atomic", "atty", - "base64 0.12.3", - "log 0.4.14", + "binascii", + "either", + "figment", + "futures", + "indexmap", + "log", "memchr", + "multer", "num_cpus", - "pear", + "parking_lot", + "pin-project-lite", + "rand", + "ref-cast", "rocket_codegen", "rocket_http", + "serde", "state", - "time", - "toml 0.4.10", - "version_check 0.9.3", + "tempfile", + "time 0.2.26", + "tokio", + "ubyte", + "version_check", "yansi", ] [[package]] name = "rocket_codegen" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ceac2c55b2c8b1cdc53add64332defa5fc227f64263b86b4114d1386286d42a3" +version = "0.5.0-dev" +source = "git+https://github.com/SergioBenitez/Rocket?rev=0654890#0654890e3d03a91537ee1d06b34ea3d2143f009e" dependencies = [ "devise", "glob", "indexmap", - "quote 0.6.13", + "quote", "rocket_http", - "version_check 0.9.3", - "yansi", + "unicode-xid", ] [[package]] name = "rocket_contrib" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7954a707f9ca18aa74ca8c1f5d1f900f52a4dceb68e96e3112143f759cfd20e" +version = "0.5.0-dev" +source = "git+https://github.com/SergioBenitez/Rocket?rev=0654890#0654890e3d03a91537ee1d06b34ea3d2143f009e" dependencies = [ "diesel", - "log 0.4.14", - "notify", + "log", "r2d2", "rocket", "rocket_contrib_codegen", "serde", "serde_json", + "tokio", ] [[package]] name = "rocket_contrib_codegen" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30deb6dec53b91fac3538a2a3935cf13e0f462745f9f33bf27bedffbe7265b5d" +version = "0.5.0-dev" +source = "git+https://github.com/SergioBenitez/Rocket?rev=0654890#0654890e3d03a91537ee1d06b34ea3d2143f009e" dependencies = [ "devise", - "quote 0.6.13", - "version_check 0.9.3", - "yansi", + "quote", ] [[package]] name = "rocket_http" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce364100ed7a1bf39257b69ebd014c1d5b4979b0d365d8c9ab0aa9c79645493d" +version = "0.5.0-dev" +source = "git+https://github.com/SergioBenitez/Rocket?rev=0654890#0654890e3d03a91537ee1d06b34ea3d2143f009e" dependencies = [ "cookie", + "either", + "http", "hyper", "indexmap", + "log", + "memchr", + "mime", + "parking_lot", "pear", - "percent-encoding 1.0.1", + "percent-encoding", + "pin-project-lite", + "ref-cast", + "serde", "smallvec", + "stable-pattern", "state", - "time", - "unicode-xid 0.1.0", + "time 0.2.26", + "tokio", + "uncased", ] [[package]] @@ -1312,27 +1248,27 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver", +] + +[[package]] +name = "rustversion" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb5d2a036dc6d2d8fd16fde3498b04306e29bd193bf306a57427019b823d5acd" + [[package]] name = "ryu" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" -[[package]] -name = "safemem" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072" - -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - [[package]] name = "scheduled-thread-pool" version = "0.2.5" @@ -1342,12 +1278,33 @@ dependencies = [ "parking_lot", ] +[[package]] +name = "scoped-tls" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2" + [[package]] name = "scopeguard" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + [[package]] name = "serde" version = "1.0.124" @@ -1363,9 +1320,9 @@ version = "1.0.124" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1800f7693e94e186f5e25a28291ae1570da908aff7d97a095dec1e56ff99069b" dependencies = [ - "proc-macro2 1.0.24", - "quote 1.0.9", - "syn 1.0.64", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -1380,16 +1337,18 @@ dependencies = [ ] [[package]] -name = "sha2" -version = "0.9.3" +name = "sha1" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa827a14b29ab7f44778d14a88d3cb76e949c45083f7dbfa507d0cb699dc12de" +checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" + +[[package]] +name = "signal-hook-registry" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16f1d0fef1604ba8f7a073c7e701f213e056707210e9020af4528e0101ce11a6" dependencies = [ - "block-buffer", - "cfg-if 1.0.0", - "cpuid-bool 0.1.2", - "digest", - "opaque-debug", + "libc", ] [[package]] @@ -1423,7 +1382,17 @@ checksum = "122e570113d28d773067fab24266b66753f6ea915758651696b6e35e49f88d6e" dependencies = [ "cfg-if 1.0.0", "libc", - "winapi 0.3.9", + "winapi", +] + +[[package]] +name = "socket2" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e3dfc207c526015c632472a77be09cf1b6e46866581aecae5cc38fb4235dea2" +dependencies = [ + "libc", + "winapi", ] [[package]] @@ -1432,38 +1401,104 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" +[[package]] +name = "stable-pattern" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4564168c00635f88eaed410d5efa8131afa8d8699a612c80c455a0ba05c21045" +dependencies = [ + "memchr", +] + +[[package]] +name = "standback" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e113fb6f3de07a243d434a56ec6f186dfd51cb08448239fe7bcae73f87ff28ff" +dependencies = [ + "version_check", +] + [[package]] name = "state" version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3015a7d0a5fd5105c91c3710d42f9ccf0abfb287d62206484dcc67f9569a6483" - -[[package]] -name = "subtle" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e81da0851ada1f3e9d4312c704aa4f8806f0f9d69faaf8df2f3464b4a9437c2" - -[[package]] -name = "syn" -version = "0.15.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" +source = "git+https://github.com/SergioBenitez/state.git?rev=504ef71a#504ef71ae39310107a5ebad5f23c6e4c8c9b3ae9" dependencies = [ - "proc-macro2 0.4.30", - "quote 0.6.13", - "unicode-xid 0.1.0", + "loom", ] +[[package]] +name = "stdweb" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d022496b16281348b52d0e30ae99e01a73d737b2f45d38fed4edf79f9325a1d5" +dependencies = [ + "discard", + "rustc_version", + "stdweb-derive", + "stdweb-internal-macros", + "stdweb-internal-runtime", + "wasm-bindgen", +] + +[[package]] +name = "stdweb-derive" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef" +dependencies = [ + "proc-macro2", + "quote", + "serde", + "serde_derive", + "syn", +] + +[[package]] +name = "stdweb-internal-macros" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58fa5ff6ad0d98d1ffa8cb115892b6e69d67799f6763e162a1c9db421dc22e11" +dependencies = [ + "base-x", + "proc-macro2", + "quote", + "serde", + "serde_derive", + "serde_json", + "sha1", + "syn", +] + +[[package]] +name = "stdweb-internal-runtime" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0" + [[package]] name = "syn" version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fd9d1e9976102a03c542daa2eff1b43f9d72306342f3f8b3ed5fb8908195d6f" dependencies = [ - "proc-macro2 1.0.24", - "quote 1.0.9", - "unicode-xid 0.2.1", + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "tempfile" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "rand", + "redox_syscall", + "remove_dir_all", + "winapi", ] [[package]] @@ -1481,9 +1516,9 @@ version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7765189610d8241a44529806d6fd1f2e0a08734313a35d5b3a556f92b381f3c0" dependencies = [ - "proc-macro2 1.0.24", - "quote 1.0.9", - "syn 1.0.64", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -1493,7 +1528,45 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" dependencies = [ "libc", - "winapi 0.3.9", + "winapi", +] + +[[package]] +name = "time" +version = "0.2.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08a8cbfbf47955132d0202d1662f49b2423ae35862aee471f3ba4b133358f372" +dependencies = [ + "const_fn", + "libc", + "standback", + "stdweb", + "time-macros", + "version_check", + "winapi", +] + +[[package]] +name = "time-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "957e9c6e26f12cb6d0dd7fc776bb67a706312e7299aed74c8dd5b17ebb27e2f1" +dependencies = [ + "proc-macro-hack", + "time-macros-impl", +] + +[[package]] +name = "time-macros-impl" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5c3be1edfad6027c69f5491cf4cb310d1a71ecd6af742788c6ff8bced86b8fa" +dependencies = [ + "proc-macro-hack", + "proc-macro2", + "quote", + "standback", + "syn", ] [[package]] @@ -1518,19 +1591,41 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d56477f6ed99e10225f38f9f75f872f29b8b8bd8c0b946f63345bb144e9eeda" dependencies = [ "autocfg", + "bytes", "libc", - "mio 0.7.10", + "memchr", + "mio", "num_cpus", + "once_cell", "pin-project-lite", + "signal-hook-registry", + "tokio-macros", + "winapi", ] [[package]] -name = "toml" -version = "0.4.10" +name = "tokio-macros" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f" +checksum = "caf7b11a536f46a809a8a9f0bb4237020f70ecbf115b842360afb127ea2fda57" dependencies = [ - "serde", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tokio-util" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5143d049e85af7fbc36f5454d990e62c2df705b3589f123b71f441b6b59f443f" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "log", + "pin-project-lite", + "tokio", ] [[package]] @@ -1543,10 +1638,30 @@ dependencies = [ ] [[package]] -name = "traitobject" -version = "0.1.0" +name = "tower-service" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079" +checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" + +[[package]] +name = "tracing" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01ebdc2bb4498ab1ab5f5b73c5803825e60199229ccba0698170e3be0e7f959f" +dependencies = [ + "cfg-if 1.0.0", + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f50de3927f93d202783f4513cda820ab47ef17f624b03c096e86ef00c67e6b5f" +dependencies = [ + "lazy_static", +] [[package]] name = "trust-dns-client" @@ -1560,7 +1675,7 @@ dependencies = [ "futures-channel", "futures-util", "lazy_static", - "log 0.4.14", + "log", "radix_trie", "rand", "thiserror", @@ -1581,39 +1696,59 @@ dependencies = [ "futures-channel", "futures-io", "futures-util", - "idna 0.2.2", + "idna", "ipnet", "lazy_static", - "log 0.4.14", + "log", "rand", "smallvec", "thiserror", "tinyvec", "tokio", - "url 2.2.1", + "url", ] [[package]] -name = "typeable" -version = "0.1.2" +name = "try-lock" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887" +checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" [[package]] -name = "typenum" -version = "1.13.0" +name = "twoway" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" - -[[package]] -name = "unicase" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33" +checksum = "6b40075910de3a912adbd80b5d8bad6ad10a23eeb1f5bf9d4006839e899ba5bc" dependencies = [ - "version_check 0.1.5", + "memchr", + "unchecked-index", ] +[[package]] +name = "ubyte" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42756bb9e708855de2f8a98195643dff31a97f0485d90d8467b39dc24be9e8fe" +dependencies = [ + "serde", +] + +[[package]] +name = "uncased" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "300932469d646d39929ffe84ad5c1837beecf602519ef5695e485b472de4082b" +dependencies = [ + "serde", + "version_check", +] + +[[package]] +name = "unchecked-index" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eeba86d422ce181a719445e51872fa30f1f7413b62becb52e95ec91aa262d85c" + [[package]] name = "unicode-bidi" version = "0.3.4" @@ -1638,45 +1773,18 @@ version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb0d2e7be6ae3a5fa87eed5fb451aff96f2573d2694942e40543ae0bbe19c796" -[[package]] -name = "unicode-xid" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" - [[package]] name = "unicode-xid" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" -[[package]] -name = "universal-hash" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8326b2c654932e3e4f9196e69d08fdf7cfd718e1dc6f66b347e6024a0c961402" -dependencies = [ - "generic-array", - "subtle", -] - [[package]] name = "untrusted" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" -[[package]] -name = "url" -version = "1.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" -dependencies = [ - "idna 0.1.5", - "matches", - "percent-encoding 1.0.1", -] - [[package]] name = "url" version = "2.2.1" @@ -1684,9 +1792,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ccd964113622c8e9322cfac19eb1004a07e636c545f325da085d5cdde6f1f8b" dependencies = [ "form_urlencoded", - "idna 0.2.2", + "idna", "matches", - "percent-encoding 2.1.0", + "percent-encoding", ] [[package]] @@ -1705,12 +1813,6 @@ version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b00bca6106a5e23f3eee943593759b7fcddb00554332e856d990c893966879fb" -[[package]] -name = "version_check" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" - [[package]] name = "version_check" version = "0.9.3" @@ -1718,14 +1820,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" [[package]] -name = "walkdir" -version = "2.3.1" +name = "want" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d" +checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" dependencies = [ - "same-file", - "winapi 0.3.9", - "winapi-util", + "log", + "try-lock", ] [[package]] @@ -1752,10 +1853,10 @@ checksum = "046ceba58ff062da072c7cb4ba5b22a37f00a302483f7e2a6cdc18fedbdc1fd3" dependencies = [ "bumpalo", "lazy_static", - "log 0.4.14", - "proc-macro2 1.0.24", - "quote 1.0.9", - "syn 1.0.64", + "log", + "proc-macro2", + "quote", + "syn", "wasm-bindgen-shared", ] @@ -1765,7 +1866,7 @@ version = "0.2.72" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ef9aa01d36cda046f797c57959ff5f3c615c9cc63997a8d545831ec7976819b" dependencies = [ - "quote 1.0.9", + "quote", "wasm-bindgen-macro-support", ] @@ -1775,9 +1876,9 @@ version = "0.2.72" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96eb45c1b2ee33545a813a92dbb53856418bf7eb54ab34f7f7ff1448a5b3735d" dependencies = [ - "proc-macro2 1.0.24", - "quote 1.0.9", - "syn 1.0.64", + "proc-macro2", + "quote", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -1798,12 +1899,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "winapi" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" - [[package]] name = "winapi" version = "0.3.9" @@ -1814,43 +1909,18 @@ dependencies = [ "winapi-x86_64-pc-windows-gnu", ] -[[package]] -name = "winapi-build" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" - [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -[[package]] -name = "winapi-util" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" -dependencies = [ - "winapi 0.3.9", -] - [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "ws2_32-sys" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" -dependencies = [ - "winapi 0.2.8", - "winapi-build", -] - [[package]] name = "yansi" version = "0.5.0" diff --git a/Cargo.toml b/Cargo.toml index 2712a07..2a86380 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,8 +11,8 @@ trust-dns-client = "0.20.1" trust-dns-proto = "0.20.1" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -rocket = "0.4" -rocket_contrib = { version = "0.4", default-features = false, features = ["json", "diesel_sqlite_pool"]} +rocket = { git = "https://github.com/SergioBenitez/Rocket", rev = "0654890", version = "0.5.0-dev" } +rocket_contrib = { git = "https://github.com/SergioBenitez/Rocket", rev = "0654890", default-features = false, features = ["json", "diesel_sqlite_pool"], version = "0.5.0-dev"} toml = "0.5" base64 = "0.13.0" uuid = { version = "0.8.2", features = ["v4", "serde"] } diff --git a/src/auth/routes.rs b/src/auth/routes.rs index d48c3cf..17fefa2 100644 --- a/src/auth/routes.rs +++ b/src/auth/routes.rs @@ -9,13 +9,16 @@ use crate::models::users::{LocalUser, CreateUserRequest, AuthClaims, AuthTokenRe #[post("/users/me/token", data = "")] -pub fn create_auth_token( +pub async fn create_auth_token( conn: DbConn, - config: State, + config: State<'_, Config>, auth_request: Json ) -> Result, ErrorResponse<()>> { - let user_info = LocalUser::get_user_by_creds(&conn, &auth_request.username, &auth_request.password)?; + let user_info = conn.run(move |c| { + LocalUser::get_user_by_creds(c, &auth_request.username, &auth_request.password) + }).await?; + let token = AuthClaims::new(&user_info, config.web_app.token_duration) .encode(&config.web_app.secret) .map_err(|e| make_500(e))?; @@ -24,9 +27,12 @@ pub fn create_auth_token( } #[post("/users", data = "")] -pub fn create_user<'r>(conn: DbConn, user_request: Json) -> Result, ErrorResponse<()>>{ +pub async fn create_user<'r>(conn: DbConn, user_request: Json) -> Result, ErrorResponse<()>>{ // TODO: Check current user if any to check if user has permission to create users (with or without role) - let _user_info = LocalUser::create_user(&conn, user_request.into_inner())?; + let _user_info = conn.run(|c| { + LocalUser::create_user(&c, user_request.into_inner()) + }).await?; + Response::build() .status(Status::Created) .ok() diff --git a/src/main.rs b/src/main.rs index f78f5fd..31133b2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -27,6 +27,7 @@ use auth::routes::*; #[database("db")] pub struct DbConn(diesel::SqliteConnection); + #[get("/zones//records")] fn get_zone_records( client: State>, @@ -60,7 +61,8 @@ fn get_zone_records( Ok(Json(records)) } -fn main() { +#[launch] +fn rocket() -> rocket::Rocket { let app_config = config::load("config.toml".into()); println!("{:#?}", app_config); @@ -71,5 +73,5 @@ fn main() { .manage(client) .manage(app_config) .attach(DbConn::fairing()) - .mount("/api/v1", routes![get_zone_records, create_auth_token, create_user]).launch(); + .mount("/api/v1", routes![get_zone_records, create_auth_token, create_user]) } diff --git a/src/models/errors.rs b/src/models/errors.rs index 9a7d56b..ddc47c3 100644 --- a/src/models/errors.rs +++ b/src/models/errors.rs @@ -44,8 +44,8 @@ impl ErrorResponse { } } -impl<'r, T: Serialize> Responder<'r> for ErrorResponse { - fn respond_to(self, req: &Request) -> response::Result<'r> { +impl<'r, T: Serialize> Responder<'r, 'static> for ErrorResponse { + fn respond_to(self, req: &'r Request<'_>) -> response::Result<'static> { let status = self.status; Response::build_from(Json(self).respond_to(req)?).status(status).ok() } diff --git a/src/models/users.rs b/src/models/users.rs index 49432d0..c9b5fe0 100644 --- a/src/models/users.rs +++ b/src/models/users.rs @@ -2,7 +2,7 @@ use uuid::Uuid; use diesel::prelude::*; use diesel::result::Error as DieselError; use diesel_derive_enum::DbEnum; -use rocket::request::{FromRequest, Request, Outcome, State}; +use rocket::{State, request::{FromRequest, Request, Outcome}}; use serde::{Serialize, Deserialize}; use rocket::http::Status; use chrono::serde::ts_seconds; @@ -93,10 +93,11 @@ pub struct UserInfo { pub username: String, } -impl<'a, 'r> FromRequest<'a, 'r> for UserInfo { +#[rocket::async_trait] +impl<'r> FromRequest<'r> for UserInfo { type Error = UserError; - fn from_request(request: &'a Request<'r>) -> Outcome { + async fn from_request(request: &'r Request<'_>) -> Outcome { let auth_header = match request.headers().get_one(AUTH_HEADER) { None => return Outcome::Forward(()), Some(auth_header) => auth_header, @@ -109,8 +110,8 @@ impl<'a, 'r> FromRequest<'a, 'r> for UserInfo { }; // TODO: Better error handling - let config = request.guard::>().unwrap(); - let conn = request.guard::().unwrap(); + let config = request.guard::>().await.unwrap(); + let conn = request.guard::().await.unwrap(); let token_data = AuthClaims::decode( token, &config.web_app.secret @@ -125,13 +126,14 @@ impl<'a, 'r> FromRequest<'a, 'r> for UserInfo { }; let user_id = token_data.sub; - let user_info = match LocalUser::get_user_by_uuid(&conn, user_id) { - Err(UserError::NotFound) => return Outcome::Failure((Status::NotFound, UserError::NotFound)), - Err(e) => return Outcome::Failure((Status::InternalServerError, e)), - Ok(d) => d, - }; - return Outcome::Success(user_info) + conn.run(|c| { + match LocalUser::get_user_by_uuid(c, user_id) { + Err(UserError::NotFound) => Outcome::Failure((Status::NotFound, UserError::NotFound)), + Err(e) => Outcome::Failure((Status::InternalServerError, e)), + Ok(d) => Outcome::Success(d), + } + }).await } } @@ -166,7 +168,7 @@ impl From for UserError { } impl LocalUser { - pub fn create_user(conn: &DbConn, user_request: CreateUserRequest) -> Result { + pub fn create_user(conn: &diesel::SqliteConnection, user_request: CreateUserRequest) -> Result { use crate::schema::localuser::dsl::*; use crate::schema::user::dsl::*; @@ -193,11 +195,11 @@ impl LocalUser { conn.immediate_transaction(|| -> diesel::QueryResult<()> { diesel::insert_into(user) .values(new_user) - .execute(&**conn)?; + .execute(conn)?; diesel::insert_into(localuser) .values(new_localuser) - .execute(&**conn)?; + .execute(conn)?; Ok(()) })?; @@ -206,7 +208,7 @@ impl LocalUser { } pub fn get_user_by_creds( - conn: &DbConn, + conn: &diesel::SqliteConnection, request_username: &str, request_password: &str ) -> Result { @@ -216,7 +218,7 @@ impl LocalUser { let (client_user, client_localuser): (User, LocalUser) = user.inner_join(localuser) .filter(username.eq(request_username)) - .get_result(&**conn)?; + .get_result(conn)?; if !check_password(&request_password, &client_localuser.password)? { return Err(UserError::NotFound); @@ -229,13 +231,13 @@ impl LocalUser { }) } - pub fn get_user_by_uuid(conn: &DbConn, request_user_id: String) -> Result { + pub fn get_user_by_uuid(conn: &diesel::SqliteConnection, request_user_id: String) -> Result { use crate::schema::localuser::dsl::*; use crate::schema::user::dsl::*; let (client_user, client_localuser): (User, LocalUser) = user.inner_join(localuser) .filter(id.eq(request_user_id)) - .get_result(&**conn)?; + .get_result(conn)?; Ok(UserInfo { id: client_user.id, -- 2.45.0 From b758c87521af06404977d95c9ee411c5ee63efbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Berthaud-M=C3=BCller?= Date: Fri, 2 Apr 2021 16:09:51 -0400 Subject: [PATCH 07/11] change architecture --- src/auth/mod.rs | 2 - src/auth/providers.rs | 12 ------ src/main.rs | 49 +++---------------------- src/routes/mod.rs | 2 + src/{auth/routes.rs => routes/users.rs} | 0 src/routes/zones.rs | 47 ++++++++++++++++++++++++ 6 files changed, 54 insertions(+), 58 deletions(-) delete mode 100644 src/auth/mod.rs delete mode 100644 src/auth/providers.rs create mode 100644 src/routes/mod.rs rename src/{auth/routes.rs => routes/users.rs} (100%) create mode 100644 src/routes/zones.rs diff --git a/src/auth/mod.rs b/src/auth/mod.rs deleted file mode 100644 index 0a2a180..0000000 --- a/src/auth/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod providers; -pub mod routes; diff --git a/src/auth/providers.rs b/src/auth/providers.rs deleted file mode 100644 index 65c3ad2..0000000 --- a/src/auth/providers.rs +++ /dev/null @@ -1,12 +0,0 @@ -// enum Providers { -// Ldap(LdapProvider), -// Local(LocalProvider), -// } - -// struct LdapProvider { -// user_filter: String, -// group_filter: String, -// // ... -// } - -// struct LocalProvider; diff --git a/src/main.rs b/src/main.rs index 31133b2..b0baa7f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,62 +4,23 @@ #[macro_use] extern crate rocket_contrib; #[macro_use] extern crate diesel; -use rocket::State; -use rocket::http::Status; - -use rocket_contrib::json::Json; - -use trust_dns_client::client::{Client, SyncClient}; +use trust_dns_client::client::SyncClient; use trust_dns_client::tcp::TcpClientConnection; -use trust_dns_client::op::{DnsResponse, ResponseCode}; -use trust_dns_client::rr::{DNSClass, Name, RecordType}; mod models; mod config; -mod auth; mod schema; +mod routes; -use models::errors::ErrorResponse; -use models::users::UserInfo; -use auth::routes::*; +use routes::users::*; +use routes::zones::*; #[database("db")] pub struct DbConn(diesel::SqliteConnection); +type DnsClient = SyncClient; -#[get("/zones//records")] -fn get_zone_records( - client: State>, - _user_info: UserInfo, - zone: String -) -> Result>, ErrorResponse<()>> { - - // TODO: Implement FromParam for Name - let name = Name::from_utf8(&zone).unwrap(); - - let response: DnsResponse = client.query(&name, DNSClass::IN, RecordType::AXFR).unwrap(); - - if response.response_code() != ResponseCode::NoError { - return ErrorResponse::new( - Status::NotFound, - format!("zone {} could not be found", name.to_utf8()) - ).err() - } - - let answers = response.answers(); - let mut records: Vec<_> = answers.to_vec().into_iter() - .map(|record| models::dns::Record::from(record)) - .filter(|record| match record.rdata { - models::dns::RData::NULL { .. } | models::dns::RData::DNSSEC(_) => false, - _ => true, - }).collect(); - - // AXFR response ends with SOA, we remove it so it is not doubled in the response. - records.pop(); - - Ok(Json(records)) -} #[launch] fn rocket() -> rocket::Rocket { diff --git a/src/routes/mod.rs b/src/routes/mod.rs new file mode 100644 index 0000000..7100db1 --- /dev/null +++ b/src/routes/mod.rs @@ -0,0 +1,2 @@ +pub mod users; +pub mod zones; diff --git a/src/auth/routes.rs b/src/routes/users.rs similarity index 100% rename from src/auth/routes.rs rename to src/routes/users.rs diff --git a/src/routes/zones.rs b/src/routes/zones.rs new file mode 100644 index 0000000..1ccbe73 --- /dev/null +++ b/src/routes/zones.rs @@ -0,0 +1,47 @@ +use rocket::State; +use rocket::http::Status; + +use rocket_contrib::json::Json; + +use trust_dns_client::client::{Client}; +use trust_dns_client::op::{DnsResponse, ResponseCode}; +use trust_dns_client::rr::{DNSClass, Name, RecordType}; + +use crate::models::dns; +use crate::models::errors::ErrorResponse; +use crate::models::users::UserInfo; +use crate::DnsClient; + + +#[get("/zones//records")] +pub fn get_zone_records( + client: State, + _user_info: UserInfo, + zone: String +) -> Result>, ErrorResponse<()>> { + + // TODO: Implement FromParam for Name + let name = Name::from_utf8(&zone).unwrap(); + + let response: DnsResponse = client.query(&name, DNSClass::IN, RecordType::AXFR).unwrap(); + + if response.response_code() != ResponseCode::NoError { + return ErrorResponse::new( + Status::NotFound, + format!("zone {} could not be found", name.to_utf8()) + ).err() + } + + let answers = response.answers(); + let mut records: Vec<_> = answers.to_vec().into_iter() + .map(|record| dns::Record::from(record)) + .filter(|record| match record.rdata { + dns::RData::NULL { .. } | dns::RData::DNSSEC(_) => false, + _ => true, + }).collect(); + + // AXFR response ends with SOA, we remove it so it is not doubled in the response. + records.pop(); + + Ok(Json(records)) +} -- 2.45.0 From 7df4792ec50303351da7b942021292259e9547b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Berthaud-M=C3=BCller?= Date: Fri, 2 Apr 2021 17:12:29 -0400 Subject: [PATCH 08/11] improve error type --- src/models/errors.rs | 32 +++++++++++++++++++++----------- src/models/users.rs | 16 ++++++++-------- src/routes/users.rs | 4 ++-- src/routes/zones.rs | 5 +++-- 4 files changed, 34 insertions(+), 23 deletions(-) diff --git a/src/models/errors.rs b/src/models/errors.rs index ddc47c3..c7973a3 100644 --- a/src/models/errors.rs +++ b/src/models/errors.rs @@ -1,18 +1,20 @@ use serde::Serialize; use rocket::http::Status; -use rocket::request::Request; +use rocket::request::{Request, Outcome}; use rocket::response::{self, Response, Responder}; use rocket_contrib::json::Json; use crate::models::users::UserError; +use serde_json::Value; + #[derive(Serialize, Debug)] -pub struct ErrorResponse { +pub struct ErrorResponse { #[serde(with = "StatusDef")] #[serde(flatten)] pub status: Status, pub message: String, #[serde(skip_serializing_if = "Option::is_none")] - pub details: Option + pub details: Option } #[derive(Serialize)] @@ -23,8 +25,8 @@ struct StatusDef { reason: &'static str, } -impl ErrorResponse { - pub fn new(status: Status, message: String) -> ErrorResponse { +impl ErrorResponse { + pub fn new(status: Status, message: String) -> ErrorResponse { ErrorResponse { status, message, @@ -32,26 +34,26 @@ impl ErrorResponse { } } - pub fn with_details(self, details: T) -> ErrorResponse { + pub fn with_details (self, details: T) -> ErrorResponse { ErrorResponse { - details: Some(details), + details: serde_json::to_value(details).ok(), ..self } } - pub fn err(self) -> Result> { + pub fn err(self) -> Result { Err(self) } } -impl<'r, T: Serialize> Responder<'r, 'static> for ErrorResponse { +impl<'r> Responder<'r, 'static> for ErrorResponse { fn respond_to(self, req: &'r Request<'_>) -> response::Result<'static> { let status = self.status; Response::build_from(Json(self).respond_to(req)?).status(status).ok() } } -impl From for ErrorResponse<()> { +impl From for ErrorResponse { fn from(e: UserError) -> Self { match e { UserError::NotFound => ErrorResponse::new(Status::Unauthorized, "Provided credentials or token do not match any existing user".into()), @@ -66,7 +68,15 @@ impl From for ErrorResponse<()> { } } -pub fn make_500(e: E) -> ErrorResponse<()> { + +impl Into> for ErrorResponse { + fn into(self) -> Outcome { + Outcome::Failure((self.status.clone(), self)) + } +} + + +pub fn make_500(e: E) -> ErrorResponse { println!("{:?}", e); ErrorResponse::new(Status::InternalServerError, "An unexpected error occured.".into()) } diff --git a/src/models/users.rs b/src/models/users.rs index c9b5fe0..59b3645 100644 --- a/src/models/users.rs +++ b/src/models/users.rs @@ -4,7 +4,6 @@ use diesel::result::Error as DieselError; use diesel_derive_enum::DbEnum; use rocket::{State, request::{FromRequest, Request, Outcome}}; use serde::{Serialize, Deserialize}; -use rocket::http::Status; use chrono::serde::ts_seconds; use chrono::prelude::{DateTime, Utc}; use chrono::Duration; @@ -21,6 +20,7 @@ use jsonwebtoken::{ use crate::schema::*; use crate::DbConn; use crate::config::Config; +use crate::models::errors::ErrorResponse; const BEARER: &'static str = "Bearer "; @@ -95,7 +95,7 @@ pub struct UserInfo { #[rocket::async_trait] impl<'r> FromRequest<'r> for UserInfo { - type Error = UserError; + type Error = ErrorResponse; async fn from_request(request: &'r Request<'_>) -> Outcome { let auth_header = match request.headers().get_one(AUTH_HEADER) { @@ -106,7 +106,7 @@ impl<'r> FromRequest<'r> for UserInfo { let token = if auth_header.starts_with(BEARER) { auth_header.trim_start_matches(BEARER) } else { - return Outcome::Failure((Status::BadRequest, UserError::MalformedHeader)) + return ErrorResponse::from(UserError::MalformedHeader).into() }; // TODO: Better error handling @@ -116,12 +116,12 @@ impl<'r> FromRequest<'r> for UserInfo { let token_data = AuthClaims::decode( token, &config.web_app.secret ).map_err(|e| match e.into_kind() { - JwtErrorKind::ExpiredSignature => (Status::Unauthorized, UserError::ExpiredToken), - _ => (Status::BadRequest, UserError::BadToken), + JwtErrorKind::ExpiredSignature => UserError::ExpiredToken, + _ => UserError::BadToken, }); let token_data = match token_data { - Err(e) => return Outcome::Failure(e), + Err(e) => return ErrorResponse::from(e).into(), Ok(data) => data }; @@ -129,8 +129,8 @@ impl<'r> FromRequest<'r> for UserInfo { conn.run(|c| { match LocalUser::get_user_by_uuid(c, user_id) { - Err(UserError::NotFound) => Outcome::Failure((Status::NotFound, UserError::NotFound)), - Err(e) => Outcome::Failure((Status::InternalServerError, e)), + Err(UserError::NotFound) => ErrorResponse::from(UserError::NotFound).into(), + Err(e) => ErrorResponse::from(e).into(), Ok(d) => Outcome::Success(d), } }).await diff --git a/src/routes/users.rs b/src/routes/users.rs index 17fefa2..0937901 100644 --- a/src/routes/users.rs +++ b/src/routes/users.rs @@ -13,7 +13,7 @@ pub async fn create_auth_token( conn: DbConn, config: State<'_, Config>, auth_request: Json -) -> Result, ErrorResponse<()>> { +) -> Result, ErrorResponse> { let user_info = conn.run(move |c| { LocalUser::get_user_by_creds(c, &auth_request.username, &auth_request.password) @@ -27,7 +27,7 @@ pub async fn create_auth_token( } #[post("/users", data = "")] -pub async fn create_user<'r>(conn: DbConn, user_request: Json) -> Result, ErrorResponse<()>>{ +pub async fn create_user<'r>(conn: DbConn, user_request: Json) -> Result, ErrorResponse>{ // TODO: Check current user if any to check if user has permission to create users (with or without role) let _user_info = conn.run(|c| { LocalUser::create_user(&c, user_request.into_inner()) diff --git a/src/routes/zones.rs b/src/routes/zones.rs index 1ccbe73..bc72497 100644 --- a/src/routes/zones.rs +++ b/src/routes/zones.rs @@ -16,9 +16,10 @@ use crate::DnsClient; #[get("/zones//records")] pub fn get_zone_records( client: State, - _user_info: UserInfo, + user_info: Result, zone: String -) -> Result>, ErrorResponse<()>> { +) -> Result>, ErrorResponse> { + user_info?; // TODO: Implement FromParam for Name let name = Name::from_utf8(&zone).unwrap(); -- 2.45.0 From 67e12239b3b5de7c62b70b424d7015ea377d142c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Berthaud-M=C3=BCller?= Date: Fri, 2 Apr 2021 17:35:25 -0400 Subject: [PATCH 09/11] better error handling --- src/models/errors.rs | 13 +++++++++++-- src/models/users.rs | 7 +++---- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/models/errors.rs b/src/models/errors.rs index c7973a3..7ae5b4f 100644 --- a/src/models/errors.rs +++ b/src/models/errors.rs @@ -71,12 +71,21 @@ impl From for ErrorResponse { impl Into> for ErrorResponse { fn into(self) -> Outcome { - Outcome::Failure((self.status.clone(), self)) + Outcome::Failure(self.into()) } } +impl Into<(Status, ErrorResponse)> for ErrorResponse { + fn into(self) -> (Status, ErrorResponse) { + (self.status.clone(), self) + } +} pub fn make_500(e: E) -> ErrorResponse { - println!("{:?}", e); + println!("Making 500 for Error: {:?}", e); ErrorResponse::new(Status::InternalServerError, "An unexpected error occured.".into()) } + +pub fn make_500_tuple(e: E) -> (Status, ErrorResponse) { + make_500(e).into() +} diff --git a/src/models/users.rs b/src/models/users.rs index 59b3645..67e5df5 100644 --- a/src/models/users.rs +++ b/src/models/users.rs @@ -20,7 +20,7 @@ use jsonwebtoken::{ use crate::schema::*; use crate::DbConn; use crate::config::Config; -use crate::models::errors::ErrorResponse; +use crate::models::errors::{ErrorResponse, make_500_tuple}; const BEARER: &'static str = "Bearer "; @@ -109,9 +109,8 @@ impl<'r> FromRequest<'r> for UserInfo { return ErrorResponse::from(UserError::MalformedHeader).into() }; - // TODO: Better error handling - let config = request.guard::>().await.unwrap(); - let conn = request.guard::().await.unwrap(); + let config = try_outcome!(request.guard::>().await.map_failure(make_500_tuple)); + let conn = try_outcome!(request.guard::().await.map_failure(make_500_tuple)); let token_data = AuthClaims::decode( token, &config.web_app.secret -- 2.45.0 From ebe1552032a1bc245142a19769176fc2c5718e36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Berthaud-M=C3=BCller?= Date: Sat, 3 Apr 2021 02:16:54 -0400 Subject: [PATCH 10/11] use enum for role and fix dns client for async --- Cargo.lock | 1 + Cargo.toml | 1 + diesel.toml | 1 + .../2021-03-26-164945_create_users/up.sql | 2 +- src/main.rs | 24 +++++++++++++------ src/models/users.rs | 11 +++++---- src/routes/zones.rs | 15 +++++++----- src/schema.rs | 7 +++++- 8 files changed, 42 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c6e4aaf..d8a74cb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -795,6 +795,7 @@ dependencies = [ "rocket_contrib", "serde", "serde_json", + "tokio", "toml", "trust-dns-client", "trust-dns-proto", diff --git a/Cargo.toml b/Cargo.toml index 2a86380..c6da57c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,3 +22,4 @@ djangohashers = { version = "1.4.0", features = ["with_argon2"], default-feature jsonwebtoken = "7.2.0" chrono = { version = "0.4", features = ["serde"] } humantime = "2.1.0" +tokio = "1" diff --git a/diesel.toml b/diesel.toml index 92267c8..764d6e0 100644 --- a/diesel.toml +++ b/diesel.toml @@ -3,3 +3,4 @@ [print_schema] file = "src/schema.rs" +import_types = ["diesel::sql_types::*", "crate::models::users::*"] diff --git a/migrations/2021-03-26-164945_create_users/up.sql b/migrations/2021-03-26-164945_create_users/up.sql index c9753af..0198256 100644 --- a/migrations/2021-03-26-164945_create_users/up.sql +++ b/migrations/2021-03-26-164945_create_users/up.sql @@ -8,5 +8,5 @@ CREATE TABLE localuser ( CREATE TABLE user ( id VARCHAR NOT NULL PRIMARY KEY, - role VARCHAR NOT NULL + role TEXT CHECK(role IN ('admin', 'zoneadmin')) NOT NULL -- note: migrate to postgres so enum are actually a thing ); diff --git a/src/main.rs b/src/main.rs index b0baa7f..b24f9b6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,8 +4,15 @@ #[macro_use] extern crate rocket_contrib; #[macro_use] extern crate diesel; -use trust_dns_client::client::SyncClient; -use trust_dns_client::tcp::TcpClientConnection; +use trust_dns_client::client::AsyncClient; +use trust_dns_client::tcp::TcpClientStream; +use trust_dns_proto::xfer::dns_multiplexer::DnsMultiplexer; +use trust_dns_proto::iocompat::AsyncIoTokioAsStd; +use trust_dns_client::rr::dnssec::Signer; +use tokio::net::TcpStream as TokioTcpStream; +use tokio::task; + +use std::sync::{Arc, Mutex}; mod models; mod config; @@ -19,19 +26,22 @@ use routes::zones::*; #[database("db")] pub struct DbConn(diesel::SqliteConnection); -type DnsClient = SyncClient; +type DnsClient = Arc>; #[launch] -fn rocket() -> rocket::Rocket { +async fn rocket() -> rocket::Rocket { let app_config = config::load("config.toml".into()); println!("{:#?}", app_config); - let conn = TcpClientConnection::new(app_config.dns.server).unwrap(); - let client = SyncClient::new(conn); + let (stream, handle) = TcpClientStream::>::new(app_config.dns.server); + let multiplexer = DnsMultiplexer::<_, Signer>::new(stream, handle, None); + let client = AsyncClient::connect(multiplexer); + let (client, bg) = client.await.expect("connection failed"); + task::spawn(bg); rocket::ignite() - .manage(client) + .manage(Arc::new(Mutex::new(client))) .manage(app_config) .attach(DbConn::fairing()) .mount("/api/v1", routes![get_zone_records, create_auth_token, create_user]) diff --git a/src/models/users.rs b/src/models/users.rs index 67e5df5..a770b66 100644 --- a/src/models/users.rs +++ b/src/models/users.rs @@ -27,10 +27,11 @@ const BEARER: &'static str = "Bearer "; const AUTH_HEADER: &'static str = "Authentication"; -#[derive(Debug, DbEnum, Deserialize)] -#[serde(rename_all = "snake_case")] +#[derive(Debug, DbEnum, Deserialize, Clone)] +#[serde(rename_all = "kebab-case")] pub enum Role { Admin, + #[db_rename = "zoneadmin"] ZoneAdmin, } @@ -40,7 +41,7 @@ pub enum Role { #[table_name = "user"] pub struct User { pub id: String, - pub role: String, + pub role: Role, } #[derive(Debug, Queryable, Identifiable, Insertable)] @@ -89,7 +90,7 @@ pub struct AuthTokenRequest { #[derive(Debug)] pub struct UserInfo { pub id: String, - pub role: String, + pub role: Role, pub username: String, } @@ -176,7 +177,7 @@ impl LocalUser { let new_user = User { id: new_user_id.clone(), // TODO: Use role from request - role: "zoneadmin".into(), + role: Role::ZoneAdmin, }; let new_localuser = LocalUser { diff --git a/src/routes/zones.rs b/src/routes/zones.rs index bc72497..0d1ec2d 100644 --- a/src/routes/zones.rs +++ b/src/routes/zones.rs @@ -3,28 +3,31 @@ use rocket::http::Status; use rocket_contrib::json::Json; -use trust_dns_client::client::{Client}; +use trust_dns_client::client::ClientHandle; use trust_dns_client::op::{DnsResponse, ResponseCode}; use trust_dns_client::rr::{DNSClass, Name, RecordType}; use crate::models::dns; -use crate::models::errors::ErrorResponse; +use crate::models::errors::{ErrorResponse, make_500}; use crate::models::users::UserInfo; use crate::DnsClient; #[get("/zones//records")] -pub fn get_zone_records( - client: State, +pub async fn get_zone_records( + client: State<'_, DnsClient>, user_info: Result, zone: String ) -> Result>, ErrorResponse> { - user_info?; + println!("{:#?}", user_info?); // TODO: Implement FromParam for Name let name = Name::from_utf8(&zone).unwrap(); - let response: DnsResponse = client.query(&name, DNSClass::IN, RecordType::AXFR).unwrap(); + let response: DnsResponse = { + let query = client.lock().unwrap().query(name.clone(), DNSClass::IN, RecordType::AXFR); + query.await.map_err(make_500)? + }; if response.response_code() != ResponseCode::NoError { return ErrorResponse::new( diff --git a/src/schema.rs b/src/schema.rs index 21093d7..c1bd1aa 100644 --- a/src/schema.rs +++ b/src/schema.rs @@ -1,4 +1,6 @@ table! { + use diesel::sql_types::*; + localuser (user_id) { user_id -> Text, username -> Text, @@ -7,9 +9,12 @@ table! { } table! { + use diesel::sql_types::*; + use crate::models::users::*; + user (id) { id -> Text, - role -> Text, + role -> RoleMapping, } } -- 2.45.0 From 950e9ded4457414c16d201a83ad4370e1e812790 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Berthaud-M=C3=BCller?= Date: Sat, 3 Apr 2021 02:19:58 -0400 Subject: [PATCH 11/11] fix role renaming --- src/models/users.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/models/users.rs b/src/models/users.rs index a770b66..85195ef 100644 --- a/src/models/users.rs +++ b/src/models/users.rs @@ -28,8 +28,9 @@ const AUTH_HEADER: &'static str = "Authentication"; #[derive(Debug, DbEnum, Deserialize, Clone)] -#[serde(rename_all = "kebab-case")] +#[serde(rename_all = "lowercase")] pub enum Role { + #[db_rename = "admin"] Admin, #[db_rename = "zoneadmin"] ZoneAdmin, -- 2.45.0