Register works, login almost
This commit is contained in:
parent
12b865bf17
commit
c85bb0ef72
6 changed files with 79 additions and 41 deletions
|
@ -1 +1,49 @@
|
||||||
pub fn login() {}
|
use crate::{
|
||||||
|
db_connection::DbPool,
|
||||||
|
errors::CustomError,
|
||||||
|
handlers::pool_handler,
|
||||||
|
models::user::{AuthUser, RegisterUser, User},
|
||||||
|
utils::jwt::*,
|
||||||
|
};
|
||||||
|
|
||||||
|
use actix_identity::Identity;
|
||||||
|
use actix_web::{post, web, HttpResponse, Responder};
|
||||||
|
|
||||||
|
#[post("/auth/register")]
|
||||||
|
pub async fn register(
|
||||||
|
new_user: web::Json<RegisterUser>,
|
||||||
|
pool: web::Data<DbPool>,
|
||||||
|
) -> impl Responder {
|
||||||
|
let connection = pool_handler(pool)?;
|
||||||
|
let register_user = new_user
|
||||||
|
.into_inner()
|
||||||
|
.validation()
|
||||||
|
.map_err(|e| HttpResponse::InternalServerError().json(e.to_string()))?;
|
||||||
|
|
||||||
|
User::create(register_user, &connection)
|
||||||
|
.map(|user| HttpResponse::Ok().json(user))
|
||||||
|
.map_err(|e| HttpResponse::InternalServerError().json(e.to_string()))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[post("auth/login")]
|
||||||
|
pub async fn login(
|
||||||
|
id: Identity,
|
||||||
|
auth_user: web::Json<AuthUser>,
|
||||||
|
pool: web::Data<DbPool>,
|
||||||
|
) -> impl Responder {
|
||||||
|
let connection = pool_handler(pool)?;
|
||||||
|
|
||||||
|
let user = auth_user.login(&connection).map_err(|e| match e {
|
||||||
|
CustomError::DBError(diesel::result::Error::NotFound) => {
|
||||||
|
HttpResponse::NotFound().json(e.to_string())
|
||||||
|
}
|
||||||
|
_ => HttpResponse::InternalServerError().json(e.to_string()),
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let token = new_token(user.id, &user.username, &user.admin).map_err(|e| match e {
|
||||||
|
_ => HttpResponse::InternalServerError().finish(),
|
||||||
|
})?;
|
||||||
|
|
||||||
|
id.remember(token);
|
||||||
|
Ok(HttpResponse::Ok().json(token))
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
pub mod authentication;
|
pub mod authentication;
|
||||||
pub mod register;
|
|
||||||
|
|
||||||
use crate::db_connection::{DbPool, MyPooledConnection};
|
use crate::db_connection::{DbPool, MyPooledConnection};
|
||||||
use actix_web::{web, HttpResponse};
|
use actix_web::{web, HttpResponse};
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
use crate::db_connection::DbPool;
|
|
||||||
use crate::handlers::pool_handler;
|
|
||||||
use crate::models::user::{RegisterUser, User};
|
|
||||||
use actix_web::{web, HttpResponse};
|
|
||||||
|
|
||||||
pub fn register(
|
|
||||||
new_user: web::Json<RegisterUser>,
|
|
||||||
pool: web::Data<DbPool>,
|
|
||||||
) -> Result<HttpResponse, HttpResponse> {
|
|
||||||
let my_pool = pool_handler(pool)?;
|
|
||||||
let register_user = new_user
|
|
||||||
.into_inner()
|
|
||||||
.validation()
|
|
||||||
.map_err(|e| HttpResponse::InternalServerError().json(e.to_string()))?;
|
|
||||||
|
|
||||||
User::create(register_user, &my_pool)
|
|
||||||
.map(|user| HttpResponse::Ok().json(user))
|
|
||||||
.map_err(|e| HttpResponse::InternalServerError().json(e.to_string()))
|
|
||||||
}
|
|
|
@ -1,26 +1,28 @@
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate diesel;
|
extern crate diesel;
|
||||||
extern crate csrf;
|
|
||||||
extern crate dotenv;
|
extern crate dotenv;
|
||||||
#[macro_use]
|
|
||||||
extern crate dotenv_codegen;
|
|
||||||
|
|
||||||
pub mod db_connection;
|
pub mod db_connection;
|
||||||
pub mod errors;
|
pub mod errors;
|
||||||
pub mod handlers;
|
pub mod handlers;
|
||||||
pub mod models;
|
pub mod models;
|
||||||
pub mod schema;
|
pub mod schema;
|
||||||
|
pub mod utils;
|
||||||
|
|
||||||
use actix_cors::Cors;
|
use actix_cors::Cors;
|
||||||
use actix_identity::{CookieIdentityPolicy, IdentityService};
|
use actix_identity::{CookieIdentityPolicy, IdentityService};
|
||||||
use actix_web::{http::header, middleware::Logger, web, App, HttpServer};
|
use actix_web::{http::header, middleware::Logger, App, HttpServer};
|
||||||
use chrono::Duration;
|
use chrono::Duration;
|
||||||
use db_connection::get_pool;
|
use db_connection::get_pool;
|
||||||
|
use dotenv::dotenv;
|
||||||
|
use handlers::authentication;
|
||||||
|
use std::env;
|
||||||
|
|
||||||
#[actix_rt::main]
|
#[actix_rt::main]
|
||||||
async fn main() -> std::io::Result<()> {
|
async fn main() -> std::io::Result<()> {
|
||||||
std::env::set_var("RUST_LOG", "actix_web=debug,diesel=debug");
|
std::env::set_var("RUST_LOG", "actix_web=debug,diesel=debug");
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
|
dotenv().ok();
|
||||||
|
|
||||||
let bind = "localhost:8080";
|
let bind = "localhost:8080";
|
||||||
println!("Starting server at: http://{}", &bind);
|
println!("Starting server at: http://{}", &bind);
|
||||||
|
@ -30,7 +32,7 @@ async fn main() -> std::io::Result<()> {
|
||||||
.wrap(Logger::default())
|
.wrap(Logger::default())
|
||||||
.wrap(
|
.wrap(
|
||||||
Cors::new()
|
Cors::new()
|
||||||
.allowed_origin(dotenv!("ALLOWED_ORIGIN"))
|
.allowed_origin(env::var("ALLOWED_ORIGIN").expect("ALLOWED_ORIGIN").as_str())
|
||||||
.allowed_methods(vec!["GET", "POST", "PUT", "DELETE"])
|
.allowed_methods(vec!["GET", "POST", "PUT", "DELETE"])
|
||||||
.allowed_headers(vec![
|
.allowed_headers(vec![
|
||||||
header::AUTHORIZATION,
|
header::AUTHORIZATION,
|
||||||
|
@ -41,15 +43,16 @@ async fn main() -> std::io::Result<()> {
|
||||||
.finish(),
|
.finish(),
|
||||||
)
|
)
|
||||||
.wrap(IdentityService::new(
|
.wrap(IdentityService::new(
|
||||||
CookieIdentityPolicy::new(dotenv!("SECRET").as_bytes())
|
CookieIdentityPolicy::new(env::var("SECRET").expect("SECRET").as_bytes())
|
||||||
.domain(dotenv!("DOMAIN"))
|
.domain(env::var("DOMAIN").expect("DOMAIN"))
|
||||||
.name("thesis")
|
.name("thesis")
|
||||||
.path("/")
|
.path("/")
|
||||||
.max_age(Duration::days(1).num_seconds())
|
.max_age(Duration::days(1).num_seconds())
|
||||||
.secure(dotenv!("COOKIE_SECURE").parse().unwrap()),
|
.secure(false),
|
||||||
))
|
))
|
||||||
.data(get_pool())
|
.data(get_pool())
|
||||||
.service(web::resource("/register").route(web::post().to(handlers::register::register)))
|
.service(authentication::register)
|
||||||
|
.service(authentication::login)
|
||||||
})
|
})
|
||||||
.bind(&bind)?
|
.bind(&bind)?
|
||||||
.run()
|
.run()
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use crate::errors::CustomError;
|
use crate::{errors::CustomError, schema::users};
|
||||||
use crate::schema::users;
|
|
||||||
use bcrypt::{hash, verify, DEFAULT_COST};
|
use bcrypt::{hash, verify, DEFAULT_COST};
|
||||||
use chrono::{Local, NaiveDateTime};
|
use chrono::{Local, NaiveDateTime};
|
||||||
use diesel::prelude::*;
|
use diesel::prelude::*;
|
||||||
|
|
|
@ -1,17 +1,21 @@
|
||||||
extern crate bcrypt;
|
extern crate bcrypt;
|
||||||
|
extern crate jsonwebtoken;
|
||||||
|
|
||||||
use actix_web::HttpResponse;
|
use actix_web::HttpResponse;
|
||||||
use chrono::{Duration, Local};
|
use chrono::{Duration, Local};
|
||||||
use jwt::{decode, encode, DecodingKey, EncodingKey, Header, Validation};
|
use jsonwebtoken::{decode, encode, Header, Validation};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
struct Claims {
|
struct Claims {
|
||||||
sub: String,
|
sub: i32,
|
||||||
|
name: String,
|
||||||
admin: bool,
|
admin: bool,
|
||||||
exp: usize,
|
exp: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct UserWithToken {
|
pub struct UserWithToken {
|
||||||
|
pub id: i32,
|
||||||
pub username: String,
|
pub username: String,
|
||||||
pub admin: bool,
|
pub admin: bool,
|
||||||
}
|
}
|
||||||
|
@ -19,27 +23,31 @@ pub struct UserWithToken {
|
||||||
impl From<Claims> for UserWithToken {
|
impl From<Claims> for UserWithToken {
|
||||||
fn from(claims: Claims) -> Self {
|
fn from(claims: Claims) -> Self {
|
||||||
UserWithToken {
|
UserWithToken {
|
||||||
username: claims.sub,
|
id: claims.sub,
|
||||||
|
username: claims.name,
|
||||||
admin: claims.admin,
|
admin: claims.admin,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Claims {
|
impl Claims {
|
||||||
fn with_username(username: &str, admin: &bool) -> Self {
|
fn with_username(id: i32, username: &str, admin: bool) -> Self {
|
||||||
Claims {
|
Claims {
|
||||||
sub: email.into(),
|
sub: id,
|
||||||
admin: admin.into(),
|
name: username.into(),
|
||||||
|
admin,
|
||||||
exp: (Local::now() + Duration::hours(24)).timestamp() as usize,
|
exp: (Local::now() + Duration::hours(24)).timestamp() as usize,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_token(username: &str) -> Result<String, HttpResponse> {
|
fn get_secret() -> [u8] {
|
||||||
let secret = dotenv!("JWT_SECRET").as_bytes();
|
std::env::var("JWT_SECRET").expect("JWT_SECRET").as_bytes()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_token(id: i32, username: &str, admin: &bool) -> Result<String, HttpResponse> {
|
||||||
let claims = Claims::with_username(username, admin);
|
let claims = Claims::with_username(username, admin);
|
||||||
encode(&Header::default(), &claims, secret)
|
encode(&Header::default(), &claims, get_secret())
|
||||||
.map_err(|e| HttpResponse::InternalServerError().json(e.to_string()))
|
.map_err(|e| HttpResponse::InternalServerError().json(e.to_string()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue