From e8419c3a14979f67e9251b77d7cf6070a782d063 Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Mon, 19 Jul 2021 14:26:51 +0200 Subject: [PATCH] oops --- README.md | 2 +- .../2021-07-16-091329_add_users/down.sql | 4 +- migrations/2021-07-16-091329_add_users/up.sql | 18 +- src/actions.rs | 78 ++++---- src/auth.rs | 172 +++++++++--------- src/errors.rs | 82 ++++----- src/models.rs | 54 +++--- 7 files changed, 205 insertions(+), 205 deletions(-) diff --git a/README.md b/README.md index 7aab4bd..42711db 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,2 @@ -# nein +# nein zu windows \ No newline at end of file diff --git a/migrations/2021-07-16-091329_add_users/down.sql b/migrations/2021-07-16-091329_add_users/down.sql index 97b7752..c26cbfd 100644 --- a/migrations/2021-07-16-091329_add_users/down.sql +++ b/migrations/2021-07-16-091329_add_users/down.sql @@ -1,3 +1,3 @@ --- This file should undo anything in `up.sql` - +-- This file should undo anything in `up.sql` + DROP TABLE users; \ No newline at end of file diff --git a/migrations/2021-07-16-091329_add_users/up.sql b/migrations/2021-07-16-091329_add_users/up.sql index 3a0f17e..1a947b9 100644 --- a/migrations/2021-07-16-091329_add_users/up.sql +++ b/migrations/2021-07-16-091329_add_users/up.sql @@ -1,10 +1,10 @@ --- Your SQL goes here - -CREATE TABLE users -( - id SERIAL NOT NULL PRIMARY KEY, - first_name TEXT NOT NULL, - last_name TEXT NOT NULL, - email TEXT NOT NULL, - created_at TIMESTAMP NOT NULL +-- Your SQL goes here + +CREATE TABLE users +( + id SERIAL NOT NULL PRIMARY KEY, + first_name TEXT NOT NULL, + last_name TEXT NOT NULL, + email TEXT NOT NULL, + created_at TIMESTAMP NOT NULL ); \ No newline at end of file diff --git a/src/actions.rs b/src/actions.rs index 8d53019..78d50a8 100644 --- a/src/actions.rs +++ b/src/actions.rs @@ -1,39 +1,39 @@ -use super::models::{NewUser, User}; -use crate::diesel::QueryDsl; -use crate::diesel::RunQueryDsl; - -use crate::handlers::InputUser; -use crate::Pool; -use diesel::{delete, insert_into}; - -type DbResult = Result; - -pub fn get_all_users(db: &Pool) -> DbResult> { - use super::schema::users::dsl::*; - let conn = db.get().unwrap(); - users.load::(&conn) -} - -pub fn get_user_by_id(db: &Pool, user_id: i32) -> DbResult { - use super::schema::users::dsl::*; - let conn = db.get().unwrap(); - users.find(user_id).get_result::(&conn) -} - -pub fn add_user(db: &Pool, user: InputUser) -> DbResult { - use super::schema::users::dsl::*; - let conn = db.get().unwrap(); - let new_user = NewUser { - first_name: &user.first_name, - last_name: &user.last_name, - email: &user.email, - created_at: chrono::Local::now().naive_local(), - }; - insert_into(users).values(&new_user).get_result(&conn) -} - -pub fn delete_user(db: &Pool, user_id: i32) -> DbResult { - use super::schema::users::dsl::*; - let conn = db.get().unwrap(); - delete(users.find(user_id)).execute(&conn) -} +use super::models::{NewUser, User}; +use crate::diesel::QueryDsl; +use crate::diesel::RunQueryDsl; + +use crate::handlers::InputUser; +use crate::Pool; +use diesel::{delete, insert_into}; + +type DbResult = Result; + +pub fn get_all_users(db: &Pool) -> DbResult> { + use super::schema::users::dsl::*; + let conn = db.get().unwrap(); + users.load::(&conn) +} + +pub fn get_user_by_id(db: &Pool, user_id: i32) -> DbResult { + use super::schema::users::dsl::*; + let conn = db.get().unwrap(); + users.find(user_id).get_result::(&conn) +} + +pub fn add_user(db: &Pool, user: InputUser) -> DbResult { + use super::schema::users::dsl::*; + let conn = db.get().unwrap(); + let new_user = NewUser { + first_name: &user.first_name, + last_name: &user.last_name, + email: &user.email, + created_at: chrono::Local::now().naive_local(), + }; + insert_into(users).values(&new_user).get_result(&conn) +} + +pub fn delete_user(db: &Pool, user_id: i32) -> DbResult { + use super::schema::users::dsl::*; + let conn = db.get().unwrap(); + delete(users.find(user_id)).execute(&conn) +} diff --git a/src/auth.rs b/src/auth.rs index 42d47be..bb0bae0 100644 --- a/src/auth.rs +++ b/src/auth.rs @@ -1,86 +1,86 @@ -use crate::errors::ServiceError; -use crate::models::User; -use actix_web::dev::{Payload, ServiceRequest}; -use actix_web::error::ErrorUnauthorized; -use actix_web::http::header::Header; -use actix_web::{FromRequest, HttpMessage, HttpRequest}; -use actix_web_httpauth::extractors::bearer::BearerAuth; -use actix_web_httpauth::headers::authorization; -use actix_web_httpauth::headers::authorization::Bearer; -use chrono::Utc; -use jsonwebtoken::{Algorithm, DecodingKey, EncodingKey, Validation}; -use serde::{Deserialize, Serialize}; -use std::future; - -#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] -pub enum Role { - None = 0, - ReadAll = 1, - WriteAll = 2, - Admin = 3, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct Claims { - pub exp: usize, - pub uid: i32, - pub role: Role, -} - -impl FromRequest for Claims { - type Error = actix_web::Error; - type Future = std::future::Ready>; - type Config = (); - - fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future { - future::ready(match authorization::Authorization::::parse(req) { - Ok(auth) => validate_token(auth.into_scheme().token()), - Err(_) => Err(ErrorUnauthorized("No Bearer token present")), - }) - } -} - -fn validate_token(token: &str) -> Result { - let secret = std::env::var("JWT_SECRET").expect("JWT_SECRET env var"); - - let decoded = jsonwebtoken::decode::( - &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.into()) - } else { - Ok(decoded) - } -} - -pub fn create_jwt(user: &User) -> Result { - create_jwt_role(user, Role::ReadAll) -} - -pub fn create_jwt_role(user: &User, role: Role) -> Result { - 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, - }; - - let secret = std::env::var("JWT_SECRET").expect("JWT_SECRET env var"); - - let header = jsonwebtoken::Header::new(Algorithm::HS512); - jsonwebtoken::encode( - &header, - &claims, - &EncodingKey::from_secret(secret.as_bytes()), - ) - .map_err(|_| ServiceError::JWTCreationError) -} +use crate::errors::ServiceError; +use crate::models::User; +use actix_web::dev::{Payload, ServiceRequest}; +use actix_web::error::ErrorUnauthorized; +use actix_web::http::header::Header; +use actix_web::{FromRequest, HttpMessage, HttpRequest}; +use actix_web_httpauth::extractors::bearer::BearerAuth; +use actix_web_httpauth::headers::authorization; +use actix_web_httpauth::headers::authorization::Bearer; +use chrono::Utc; +use jsonwebtoken::{Algorithm, DecodingKey, EncodingKey, Validation}; +use serde::{Deserialize, Serialize}; +use std::future; + +#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] +pub enum Role { + None = 0, + ReadAll = 1, + WriteAll = 2, + Admin = 3, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct Claims { + pub exp: usize, + pub uid: i32, + pub role: Role, +} + +impl FromRequest for Claims { + type Error = actix_web::Error; + type Future = std::future::Ready>; + type Config = (); + + fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future { + future::ready(match authorization::Authorization::::parse(req) { + Ok(auth) => validate_token(auth.into_scheme().token()), + Err(_) => Err(ErrorUnauthorized("No Bearer token present")), + }) + } +} + +fn validate_token(token: &str) -> Result { + let secret = std::env::var("JWT_SECRET").expect("JWT_SECRET env var"); + + let decoded = jsonwebtoken::decode::( + &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.into()) + } else { + Ok(decoded) + } +} + +pub fn create_jwt(user: &User) -> Result { + create_jwt_role(user, Role::ReadAll) +} + +pub fn create_jwt_role(user: &User, role: Role) -> Result { + 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, + }; + + let secret = std::env::var("JWT_SECRET").expect("JWT_SECRET env var"); + + let header = jsonwebtoken::Header::new(Algorithm::HS512); + jsonwebtoken::encode( + &header, + &claims, + &EncodingKey::from_secret(secret.as_bytes()), + ) + .map_err(|_| ServiceError::JWTCreationError) +} diff --git a/src/errors.rs b/src/errors.rs index 2e940ec..613f0e6 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -1,41 +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"), - } - } -} +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"), + } + } +} diff --git a/src/models.rs b/src/models.rs index b8d9bcf..dee6f5a 100644 --- a/src/models.rs +++ b/src/models.rs @@ -1,27 +1,27 @@ -use crate::schema::*; -use actix_web::HttpResponse; -use serde::{Deserialize, Serialize}; - -#[derive(Debug, Clone, Serialize, Deserialize, Queryable)] -pub struct User { - pub id: i32, - pub first_name: String, - pub last_name: String, - pub email: String, - pub created_at: chrono::NaiveDateTime, -} - -#[derive(Insertable, Debug)] -#[table_name = "users"] -pub struct NewUser<'a> { - pub first_name: &'a str, - pub last_name: &'a str, - pub email: &'a str, - pub created_at: chrono::NaiveDateTime, -} - -impl From for HttpResponse { - fn from(user: User) -> Self { - HttpResponse::Ok().json(user) - } -} +use crate::schema::*; +use actix_web::HttpResponse; +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Serialize, Deserialize, Queryable)] +pub struct User { + pub id: i32, + pub first_name: String, + pub last_name: String, + pub email: String, + pub created_at: chrono::NaiveDateTime, +} + +#[derive(Insertable, Debug)] +#[table_name = "users"] +pub struct NewUser<'a> { + pub first_name: &'a str, + pub last_name: &'a str, + pub email: &'a str, + pub created_at: chrono::NaiveDateTime, +} + +impl From for HttpResponse { + fn from(user: User) -> Self { + HttpResponse::Ok().json(user) + } +}