mirror of
https://github.com/Noratrieb/karlauth.git
synced 2026-01-14 14:25:02 +01:00
may not actually really kind of works
This commit is contained in:
parent
1a8f223d39
commit
c2973477d1
8 changed files with 335 additions and 37 deletions
1
.env
1
.env
|
|
@ -1 +1,2 @@
|
||||||
DATABASE_URL=postgres://postgres:hugo123@localhost/karldbauth
|
DATABASE_URL=postgres://postgres:hugo123@localhost/karldbauth
|
||||||
|
JWT_SECRET=halloichbineinsecretundsosehrsicherlmao34567
|
||||||
180
Cargo.lock
generated
180
Cargo.lock
generated
|
|
@ -333,19 +333,6 @@ dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "alcoholic_jwt"
|
|
||||||
version = "1.0.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d27226e01414833a0443a67862f5aaf1cf3536b39b11f8b7d30d0e31b29d38db"
|
|
||||||
dependencies = [
|
|
||||||
"base64 0.10.1",
|
|
||||||
"openssl",
|
|
||||||
"serde",
|
|
||||||
"serde_derive",
|
|
||||||
"serde_json",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-trait"
|
name = "async-trait"
|
||||||
version = "0.1.50"
|
version = "0.1.50"
|
||||||
|
|
@ -422,6 +409,18 @@ version = "0.11.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7"
|
checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "base64"
|
||||||
|
version = "0.12.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "base64"
|
||||||
|
version = "0.13.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "1.2.1"
|
version = "1.2.1"
|
||||||
|
|
@ -448,6 +447,12 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bumpalo"
|
||||||
|
version = "3.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9c59e7af012c713f529e7a3ee57ce9b31ddd858d4b512923602f74608b009631"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "byteorder"
|
name = "byteorder"
|
||||||
version = "1.4.3"
|
version = "1.4.3"
|
||||||
|
|
@ -1176,6 +1181,29 @@ version = "0.4.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
|
checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "js-sys"
|
||||||
|
version = "0.3.51"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "83bdfbace3a0e81a4253f73b49e960b053e396a11012cbd49b9b74d6a2b67062"
|
||||||
|
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]]
|
[[package]]
|
||||||
name = "karlauth"
|
name = "karlauth"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
|
@ -1184,12 +1212,12 @@ dependencies = [
|
||||||
"actix-service",
|
"actix-service",
|
||||||
"actix-web",
|
"actix-web",
|
||||||
"actix-web-httpauth",
|
"actix-web-httpauth",
|
||||||
"alcoholic_jwt",
|
|
||||||
"chrono",
|
"chrono",
|
||||||
"derive_more",
|
"derive_more",
|
||||||
"diesel",
|
"diesel",
|
||||||
"dotenv",
|
"dotenv",
|
||||||
"futures 0.3.15",
|
"futures 0.3.15",
|
||||||
|
"jsonwebtoken",
|
||||||
"r2d2",
|
"r2d2",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"serde",
|
"serde",
|
||||||
|
|
@ -1397,6 +1425,17 @@ dependencies = [
|
||||||
"winapi 0.3.9",
|
"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 1.0.1",
|
||||||
|
"num-integer",
|
||||||
|
"num-traits",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-integer"
|
name = "num-integer"
|
||||||
version = "0.1.44"
|
version = "0.1.44"
|
||||||
|
|
@ -1525,6 +1564,17 @@ dependencies = [
|
||||||
"winapi 0.3.9",
|
"winapi 0.3.9",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[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]]
|
[[package]]
|
||||||
name = "percent-encoding"
|
name = "percent-encoding"
|
||||||
version = "1.0.1"
|
version = "1.0.1"
|
||||||
|
|
@ -1963,6 +2013,21 @@ dependencies = [
|
||||||
"quick-error",
|
"quick-error",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[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]]
|
[[package]]
|
||||||
name = "rustc-demangle"
|
name = "rustc-demangle"
|
||||||
version = "0.1.20"
|
version = "0.1.20"
|
||||||
|
|
@ -2144,6 +2209,17 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[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]]
|
[[package]]
|
||||||
name = "slab"
|
name = "slab"
|
||||||
version = "0.4.3"
|
version = "0.4.3"
|
||||||
|
|
@ -2176,6 +2252,12 @@ dependencies = [
|
||||||
"winapi 0.3.9",
|
"winapi 0.3.9",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "spin"
|
||||||
|
version = "0.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "string"
|
name = "string"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
|
|
@ -2568,6 +2650,12 @@ version = "0.2.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "untrusted"
|
||||||
|
version = "0.7.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "url"
|
name = "url"
|
||||||
version = "1.7.2"
|
version = "1.7.2"
|
||||||
|
|
@ -2641,6 +2729,70 @@ version = "0.10.0+wasi-snapshot-preview1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
|
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen"
|
||||||
|
version = "0.2.74"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d54ee1d4ed486f78874278e63e4069fc1ab9f6a18ca492076ffb90c5eb2997fd"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if 1.0.0",
|
||||||
|
"wasm-bindgen-macro",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-backend"
|
||||||
|
version = "0.2.74"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3b33f6a0694ccfea53d94db8b2ed1c3a8a4c86dd936b13b9f0a15ec4a451b900"
|
||||||
|
dependencies = [
|
||||||
|
"bumpalo",
|
||||||
|
"lazy_static",
|
||||||
|
"log",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"wasm-bindgen-shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-macro"
|
||||||
|
version = "0.2.74"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "088169ca61430fe1e58b8096c24975251700e7b1f6fd91cc9d59b04fb9b18bd4"
|
||||||
|
dependencies = [
|
||||||
|
"quote",
|
||||||
|
"wasm-bindgen-macro-support",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-macro-support"
|
||||||
|
version = "0.2.74"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "be2241542ff3d9f241f5e2cb6dd09b37efe786df8851c54957683a49f0987a97"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"wasm-bindgen-backend",
|
||||||
|
"wasm-bindgen-shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-shared"
|
||||||
|
version = "0.2.74"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d7cff876b8f18eed75a66cf49b65e7f967cb354a7aa16003fb55dbfd25b44b4f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "web-sys"
|
||||||
|
version = "0.3.51"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e828417b379f3df7111d3a2a9e5753706cae29c41f7c4029ee9fd77f3e09e582"
|
||||||
|
dependencies = [
|
||||||
|
"js-sys",
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "widestring"
|
name = "widestring"
|
||||||
version = "0.4.3"
|
version = "0.4.3"
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,6 @@ serde = "1.0"
|
||||||
serde_derive = "1.0"
|
serde_derive = "1.0"
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
actix-service = "1.0.1"
|
actix-service = "1.0.1"
|
||||||
alcoholic_jwt = "1.0.0"
|
jsonwebtoken = "7.2.0"
|
||||||
reqwest = "0.9.22"
|
reqwest = "0.9.22"
|
||||||
actix-rt = "1.0.0"
|
actix-rt = "1.0.0"
|
||||||
|
|
@ -8,17 +8,16 @@ use diesel::{delete, insert_into};
|
||||||
|
|
||||||
type DbResult<T> = Result<T, diesel::result::Error>;
|
type DbResult<T> = Result<T, diesel::result::Error>;
|
||||||
|
|
||||||
pub fn get_all_users(db: &Pool) -> DbResult<User> {
|
pub fn get_all_users(db: &Pool) -> DbResult<Vec<User>> {
|
||||||
use super::schema::users::dsl::*;
|
use super::schema::users::dsl::*;
|
||||||
let conn = db.get().unwrap();
|
let conn = db.get().unwrap();
|
||||||
let items = users.load::<User>(&conn)?;
|
users.load::<User>(&conn)
|
||||||
Ok(items)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_user_by_id(db: &Pool, id: i32) -> DbResult<User> {
|
pub fn get_user_by_id(db: &Pool, user_id: i32) -> DbResult<User> {
|
||||||
use super::schema::users::dsl::*;
|
use super::schema::users::dsl::*;
|
||||||
let conn = db.get().unwrap();
|
let conn = db.get().unwrap();
|
||||||
users.find(id).get_result::<User>(&conn)
|
users.find(user_id).get_result::<User>(&conn)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_user(db: &Pool, user: InputUser) -> DbResult<User> {
|
pub fn add_user(db: &Pool, user: InputUser) -> DbResult<User> {
|
||||||
|
|
@ -33,8 +32,8 @@ pub fn add_user(db: &Pool, user: InputUser) -> DbResult<User> {
|
||||||
insert_into(users).values(&new_user).get_result(&conn)
|
insert_into(users).values(&new_user).get_result(&conn)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn delete_user(db: &Pool, id: i32) -> DbResult<usize> {
|
pub fn delete_user(db: &Pool, user_id: i32) -> DbResult<usize> {
|
||||||
use super::schema::users::dsl::*;
|
use super::schema::users::dsl::*;
|
||||||
let conn = db.get().unwrap();
|
let conn = db.get().unwrap();
|
||||||
delete(users.find(id)).execute(&conn)
|
delete(users.find(user_id)).execute(&conn)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
82
src/auth.rs
Normal file
82
src/auth.rs
Normal file
|
|
@ -0,0 +1,82 @@
|
||||||
|
use crate::errors::ServiceError;
|
||||||
|
use crate::models::User;
|
||||||
|
use actix_web::dev::{Payload, ServiceRequest};
|
||||||
|
use actix_web_httpauth::extractors::bearer::{BearerAuth, Config};
|
||||||
|
use actix_web_httpauth::extractors::AuthenticationError;
|
||||||
|
use chrono::Utc;
|
||||||
|
use jsonwebtoken::{Algorithm, DecodingKey, EncodingKey, Header, Validation};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||||
|
pub enum Role {
|
||||||
|
None,
|
||||||
|
ReadAll,
|
||||||
|
WriteAll,
|
||||||
|
Admin,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
struct Claims {
|
||||||
|
exp: usize,
|
||||||
|
uid: i32,
|
||||||
|
role: Role,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn validator(
|
||||||
|
req: ServiceRequest,
|
||||||
|
credentials: BearerAuth,
|
||||||
|
) -> Result<ServiceRequest, actix_web::Error> {
|
||||||
|
let config = req
|
||||||
|
.app_data::<Config>()
|
||||||
|
.map(|data| data.get_ref().clone())
|
||||||
|
.unwrap_or(Default::default());
|
||||||
|
|
||||||
|
match validate_token(credentials.token()) {
|
||||||
|
Ok(claims) => {
|
||||||
|
//req.extensions_mut().insert(claims);
|
||||||
|
Ok(req)
|
||||||
|
}
|
||||||
|
Err(err) => Err(AuthenticationError::from(config).into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn validate_token(token: &str) -> Result<Claims, ServiceError> {
|
||||||
|
let secret = std::env::var("JWT_SECRET").expect("JWT_SECRET env var");
|
||||||
|
|
||||||
|
let decoded = jsonwebtoken::decode::<Claims>(
|
||||||
|
&token,
|
||||||
|
&DecodingKey::from_secret(secret.as_bytes()),
|
||||||
|
&Validation::new(Algorithm::HS512),
|
||||||
|
)
|
||||||
|
.map_err(|_| ServiceError::JWTokenError)?
|
||||||
|
.claims;
|
||||||
|
|
||||||
|
if decoded.exp > Utc::now().timestamp() as usize {
|
||||||
|
Err(ServiceError::TokenExpiredError)
|
||||||
|
} else {
|
||||||
|
Ok(decoded)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn create_jwt(user: &User) -> Result<String, ServiceError> {
|
||||||
|
let expiration = Utc::now()
|
||||||
|
.checked_add_signed(chrono::Duration::weeks(10))
|
||||||
|
.expect("valid timestamp")
|
||||||
|
.timestamp();
|
||||||
|
|
||||||
|
let claims = Claims {
|
||||||
|
exp: expiration as usize,
|
||||||
|
uid: user.id,
|
||||||
|
role: Role::ReadAll,
|
||||||
|
};
|
||||||
|
|
||||||
|
let secret = std::env::var("JWT_SECRET").expect("JWT_SECRET env var");
|
||||||
|
|
||||||
|
let header = Header::new(Algorithm::HS512);
|
||||||
|
jsonwebtoken::encode(
|
||||||
|
&header,
|
||||||
|
&claims,
|
||||||
|
&EncodingKey::from_secret(secret.as_bytes()),
|
||||||
|
)
|
||||||
|
.map_err(|_| ServiceError::JWTCreationError)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
use actix_web::{error::ResponseError, HttpResponse};
|
||||||
|
use derive_more::Display;
|
||||||
|
|
||||||
|
#[derive(Debug, Display)]
|
||||||
|
pub enum ServiceError {
|
||||||
|
#[display(fmt = "Internal Server Error")]
|
||||||
|
InternalServerError,
|
||||||
|
|
||||||
|
#[display(fmt = "BadRequest: {}", _0)]
|
||||||
|
BadRequest(String),
|
||||||
|
|
||||||
|
#[display(fmt = "JWT Creation Error")]
|
||||||
|
JWTCreationError,
|
||||||
|
|
||||||
|
#[display(fmt = "JWT Error")]
|
||||||
|
JWTokenError,
|
||||||
|
|
||||||
|
#[display(fmt = "No Permission Error")]
|
||||||
|
NoPermissionError,
|
||||||
|
|
||||||
|
#[display(fmt = "Token Expired Error")]
|
||||||
|
TokenExpiredError,
|
||||||
|
}
|
||||||
|
|
||||||
|
// impl ResponseError trait allows to convert our errors into http responses with appropriate data
|
||||||
|
impl ResponseError for ServiceError {
|
||||||
|
fn error_response(&self) -> HttpResponse {
|
||||||
|
match self {
|
||||||
|
ServiceError::InternalServerError => {
|
||||||
|
HttpResponse::InternalServerError().json("Internal Server Error, Please try later")
|
||||||
|
}
|
||||||
|
ServiceError::BadRequest(ref message) => HttpResponse::BadRequest().json(message),
|
||||||
|
ServiceError::JWTCreationError => {
|
||||||
|
HttpResponse::InternalServerError().json("Could not fetch JWKS")
|
||||||
|
}
|
||||||
|
ServiceError::JWTokenError => HttpResponse::BadRequest().json("Invalid JWT"),
|
||||||
|
ServiceError::NoPermissionError => HttpResponse::Unauthorized().json("No permissions"),
|
||||||
|
ServiceError::TokenExpiredError => HttpResponse::Unauthorized().json("Token expired"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,10 +1,9 @@
|
||||||
use super::actions;
|
use super::actions;
|
||||||
use super::models::{NewUser, User};
|
|
||||||
use super::Pool;
|
use super::Pool;
|
||||||
use actix_web::{web, HttpResponse, Responder};
|
use crate::auth::create_jwt;
|
||||||
use diesel::dsl::{delete, insert_into};
|
use crate::models::User;
|
||||||
|
use actix_web::{web, HttpResponse};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::vec::Vec;
|
|
||||||
|
|
||||||
type HttpResult = Result<HttpResponse, actix_web::Error>;
|
type HttpResult = Result<HttpResponse, actix_web::Error>;
|
||||||
|
|
||||||
|
|
@ -15,13 +14,21 @@ pub struct InputUser {
|
||||||
pub email: String,
|
pub email: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
struct UserWithToken {
|
||||||
|
pub user: User,
|
||||||
|
pub token: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// handler for `GET /users`
|
||||||
pub async fn get_users(db: web::Data<Pool>) -> HttpResult {
|
pub async fn get_users(db: web::Data<Pool>) -> HttpResult {
|
||||||
Ok(web::block(move || actions::get_all_users(&db))
|
Ok(web::block(move || actions::get_all_users(&db))
|
||||||
.await
|
.await
|
||||||
.map(|user| user.into())
|
.map(|users| HttpResponse::Ok().json(users))
|
||||||
.map_err(|_| HttpResponse::InternalServerError())?)
|
.map_err(|_| HttpResponse::InternalServerError())?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// handler for `GET /users/{id}`
|
||||||
pub async fn get_user_by_id(db: web::Data<Pool>, user_id: web::Path<i32>) -> HttpResult {
|
pub async fn get_user_by_id(db: web::Data<Pool>, user_id: web::Path<i32>) -> HttpResult {
|
||||||
Ok(web::block(move || actions::get_user_by_id(&db, *user_id))
|
Ok(web::block(move || actions::get_user_by_id(&db, *user_id))
|
||||||
.await
|
.await
|
||||||
|
|
@ -29,15 +36,23 @@ pub async fn get_user_by_id(db: web::Data<Pool>, user_id: web::Path<i32>) -> Htt
|
||||||
.map_err(|_| HttpResponse::InternalServerError())?)
|
.map_err(|_| HttpResponse::InternalServerError())?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// handler for `POST /users`
|
||||||
pub async fn add_user(db: web::Data<Pool>, item: web::Json<InputUser>) -> HttpResult {
|
pub async fn add_user(db: web::Data<Pool>, item: web::Json<InputUser>) -> HttpResult {
|
||||||
Ok(web::block(move || actions::add_user(&db, *item))
|
Ok(
|
||||||
|
web::block(move || actions::add_user(&db, item.into_inner()))
|
||||||
.await
|
.await
|
||||||
.map(|user| user.into())
|
.map_err(|_| HttpResponse::InternalServerError())
|
||||||
.map_err(|_| HttpResponse::InternalServerError())?)
|
.map(|user| {
|
||||||
|
HttpResponse::Ok().json(UserWithToken {
|
||||||
|
token: create_jwt(&user).expect("Could not create JWT"),
|
||||||
|
user,
|
||||||
|
})
|
||||||
|
})?,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// handler for `DELETE /users/{id}`
|
/// handler for `DELETE /users/{id}`
|
||||||
pub async fn delete_user(db: web::Data<Pool>, user_id: web::Path<i32>) -> impl Responder {
|
pub async fn delete_user(db: web::Data<Pool>, user_id: web::Path<i32>) -> HttpResult {
|
||||||
Ok(web::block(move || actions::delete_user(&db, *user_id))
|
Ok(web::block(move || actions::delete_user(&db, *user_id))
|
||||||
.await
|
.await
|
||||||
.map(|count| HttpResponse::Ok().body(format!("Deleted {} user.", count)))
|
.map(|count| HttpResponse::Ok().body(format!("Deleted {} user.", count)))
|
||||||
|
|
|
||||||
16
src/main.rs
16
src/main.rs
|
|
@ -1,11 +1,14 @@
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate diesel;
|
extern crate diesel;
|
||||||
|
|
||||||
use actix_web::{dev::ServiceRequest, web, App, Error, HttpServer};
|
use crate::auth::validator;
|
||||||
|
use actix_web::{web, App, Error, HttpServer};
|
||||||
|
use actix_web_httpauth::middleware::HttpAuthentication;
|
||||||
use diesel::prelude::*;
|
use diesel::prelude::*;
|
||||||
use diesel::r2d2::{self, ConnectionManager};
|
use diesel::r2d2::{self, ConnectionManager};
|
||||||
|
|
||||||
mod actions;
|
mod actions;
|
||||||
|
mod auth;
|
||||||
mod errors;
|
mod errors;
|
||||||
mod handlers;
|
mod handlers;
|
||||||
mod models;
|
mod models;
|
||||||
|
|
@ -25,12 +28,17 @@ async fn main() -> std::io::Result<()> {
|
||||||
.expect("Failed to create pool.");
|
.expect("Failed to create pool.");
|
||||||
|
|
||||||
HttpServer::new(move || {
|
HttpServer::new(move || {
|
||||||
|
let auth_middleware = HttpAuthentication::bearer(validator);
|
||||||
App::new()
|
App::new()
|
||||||
.data(pool.clone())
|
.data(pool.clone())
|
||||||
.route("/users", web::get().to(handlers::get_users))
|
|
||||||
.route("/users/{id}", web::get().to(handlers::get_user_by_id))
|
|
||||||
.route("/users", web::post().to(handlers::add_user))
|
.route("/users", web::post().to(handlers::add_user))
|
||||||
.route("/users/{id}", web::delete().to(handlers::delete_user))
|
.service(
|
||||||
|
web::scope("/users")
|
||||||
|
.wrap(auth_middleware)
|
||||||
|
.route("", web::get().to(handlers::get_users))
|
||||||
|
.route("/{id}", web::get().to(handlers::get_user_by_id))
|
||||||
|
.route("/{id}", web::delete().to(handlers::delete_user)),
|
||||||
|
)
|
||||||
})
|
})
|
||||||
.bind("127.0.0.1:8080")?
|
.bind("127.0.0.1:8080")?
|
||||||
.run()
|
.run()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue