Temp updated
This commit is contained in:
@@ -28,6 +28,7 @@ r2d2 = "0.8.10"
|
|||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
uuid = { version = "1.4.1", features = ["serde", "v4"] }
|
uuid = { version = "1.4.1", features = ["serde", "v4"] }
|
||||||
argon2 = "0.5.2"
|
argon2 = "0.5.2"
|
||||||
|
jsonwebtoken = "9.0.0"
|
||||||
|
|
||||||
[dependencies.tokio]
|
[dependencies.tokio]
|
||||||
version = "1.32.0"
|
version = "1.32.0"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use std::future::{ready, Ready};
|
use std::{future::{ready, Ready, Future}, pin::Pin};
|
||||||
use actix_identity::Identity;
|
use actix_identity::Identity;
|
||||||
use actix_web::{FromRequest, Error as ActixError, HttpRequest, dev::Payload};
|
use actix_web::{FromRequest, Error as ActixError, HttpRequest, dev::Payload, error::{ErrorUnauthorized, ErrorInternalServerError}};
|
||||||
use argon2::{password_hash::{rand_core::OsRng, PasswordHasher, PasswordVerifier, SaltString, Error as HashError}, Argon2, PasswordHash};
|
use argon2::{password_hash::{rand_core::OsRng, PasswordHasher, PasswordVerifier, SaltString, Error as HashError}, Argon2, PasswordHash};
|
||||||
use diesel::prelude::*;
|
use diesel::prelude::*;
|
||||||
use serde::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
@@ -42,25 +42,47 @@ pub struct LoggedUser {
|
|||||||
|
|
||||||
impl FromRequest for LoggedUser {
|
impl FromRequest for LoggedUser {
|
||||||
type Error = ActixError;
|
type Error = ActixError;
|
||||||
type Future = Ready<Result<LoggedUser, ActixError>>;
|
// type Future = Ready<Result<LoggedUser, ActixError>>;
|
||||||
|
// type Future = std::pin::Pin<Box<dyn std::future::Future<Output = Result<LoggedUser, ActixError>>>>;
|
||||||
|
type Future = Pin<Box<dyn Future<Output = Result<Self, Self::Error>>>>;
|
||||||
|
|
||||||
fn from_request(req: &HttpRequest, pl: &mut Payload) -> Self::Future {
|
fn from_request(req: &HttpRequest, pl: &mut Payload) -> Self::Future {
|
||||||
if let Ok(identity) = Identity::from_request(req, pl).into_inner() {
|
// if let Ok(identity) = Identity::from_request(req, pl).into_inner() {
|
||||||
if let Ok(user_json) = identity.id() {
|
// if let Ok(user_json) = identity.id() {
|
||||||
if let Ok(user) = serde_json::from_str(&user_json) {
|
// if let Ok(user) = serde_json::from_str(&user_json) {
|
||||||
return ready(Ok(user));
|
// return ready(Ok(user));
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
std::future::ready(Err(
|
// std::future::ready(Err(
|
||||||
ActixError::from(ServiceError {
|
// ActixError::from(ServiceError {
|
||||||
status: 401,
|
// status: 401,
|
||||||
message: "Unauthorized".to_string(),
|
// message: "Unauthorized".to_string(),
|
||||||
})
|
// })
|
||||||
))
|
// ))
|
||||||
|
let identity = Identity::extract(req).into_inner();
|
||||||
|
Box::pin(async move {
|
||||||
|
process_req_auth_data(identity).await
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn process_req_auth_data(identity: Result<Identity, ActixError>) -> Result<LoggedUser, ActixError> {
|
||||||
|
let id = identity
|
||||||
|
.map_err(|_| ErrorUnauthorized("You are not logged in; 1"))?
|
||||||
|
.id()
|
||||||
|
.map_err(|_| ErrorUnauthorized("You are not logged in; 3"))?;
|
||||||
|
let logged_user = match serde_json::from_str::<LoggedUser>(&id) {
|
||||||
|
Ok(user) => user,
|
||||||
|
Err(err) => return Err(ErrorInternalServerError(err))
|
||||||
|
};
|
||||||
|
|
||||||
|
let user = QueryUser::get_by_email(&logged_user.email)
|
||||||
|
.map_err(|_| ErrorUnauthorized("You are not logged in; 3"))?;
|
||||||
|
|
||||||
|
Ok(LoggedUser { email: user.email })
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Queryable, QueryableByName, Serialize, Deserialize)]
|
#[derive(Debug, Queryable, QueryableByName, Serialize, Deserialize)]
|
||||||
#[diesel(table_name = users)]
|
#[diesel(table_name = users)]
|
||||||
pub struct QueryUser {
|
pub struct QueryUser {
|
||||||
|
|||||||
@@ -30,39 +30,38 @@ async fn register(user: web::Json<RegisterUser>) -> HttpResponse {
|
|||||||
async fn login(req: HttpRequest, auth: web::Json<LoginAuth>) -> HttpResponse {
|
async fn login(req: HttpRequest, auth: web::Json<LoginAuth>) -> HttpResponse {
|
||||||
let email = auth.email.clone();
|
let email = auth.email.clone();
|
||||||
|
|
||||||
match QueryUser::get_by_email(&email) {
|
let query_user = match QueryUser::get_by_email(&email) {
|
||||||
Ok(query_user) => {
|
Ok(query_user) => query_user,
|
||||||
let hash = query_user.hash;
|
Err(err) => return ResponseError::error_response(&err)
|
||||||
let password = auth.password.as_bytes();
|
};
|
||||||
match verify(&hash, password) {
|
let hash = query_user.hash;
|
||||||
Ok(_) => {
|
let password = auth.password.as_bytes();
|
||||||
let user = LoggedUser {
|
match verify(&hash, password) {
|
||||||
email: email.clone()
|
Ok(_) => {
|
||||||
};
|
let user = LoggedUser {
|
||||||
let user_string = serde_json::to_string(&user).unwrap();
|
email: email.clone()
|
||||||
match Identity::login(&req.extensions(), user_string) {
|
};
|
||||||
Ok(_) => HttpResponse::Ok().finish(),
|
let user_string = serde_json::to_string(&user).unwrap();
|
||||||
Err(err) => return ResponseError::error_response(&err)
|
match Identity::login(&req.extensions(), user_string) {
|
||||||
}
|
Ok(_) => HttpResponse::Ok().finish(),
|
||||||
},
|
Err(err) => return ResponseError::error_response(&err)
|
||||||
Err(err) => ResponseError::error_response(&ServiceError {
|
|
||||||
status: 401,
|
|
||||||
message: err.to_string()
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Err(err) => ResponseError::error_response(&err)
|
Err(err) => ResponseError::error_response(&ServiceError {
|
||||||
|
status: 401,
|
||||||
|
message: err.to_string()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/logout")]
|
#[post("/logout")]
|
||||||
async fn logout(id: Identity) -> HttpResponse {
|
async fn logout(identity: Identity) -> HttpResponse {
|
||||||
id.logout();
|
identity.logout();
|
||||||
HttpResponse::Ok().finish()
|
HttpResponse::Ok().finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/me")]
|
#[get("/ping")]
|
||||||
async fn me(user: LoggedUser) -> HttpResponse {
|
async fn ping(user: LoggedUser) -> HttpResponse {
|
||||||
HttpResponse::Ok().json(user)
|
HttpResponse::Ok().json(user)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,5 +70,5 @@ pub fn init_routes(config: &mut web::ServiceConfig) {
|
|||||||
.service(register)
|
.service(register)
|
||||||
.service(login)
|
.service(login)
|
||||||
.service(logout)
|
.service(logout)
|
||||||
.service(me));
|
.service(ping));
|
||||||
}
|
}
|
||||||
@@ -6,8 +6,7 @@ use std::env;
|
|||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use actix_identity::IdentityMiddleware;
|
use actix_identity::IdentityMiddleware;
|
||||||
use actix_session::{SessionMiddleware, storage::{RedisActorSessionStore, CookieSessionStore}, config::{PersistentSession, BrowserSession, CookieContentSecurity}};
|
use actix_session::{SessionMiddleware, storage::{RedisActorSessionStore, CookieSessionStore}, config::BrowserSession};
|
||||||
// use db::users::validator;
|
|
||||||
use log::{error, warn, info};
|
use log::{error, warn, info};
|
||||||
use serenity::client::Cache;
|
use serenity::client::Cache;
|
||||||
use serenity::framework::StandardFramework;
|
use serenity::framework::StandardFramework;
|
||||||
@@ -16,7 +15,7 @@ use serenity::prelude::*;
|
|||||||
use songbird::{SerenityInit, Songbird};
|
use songbird::{SerenityInit, Songbird};
|
||||||
|
|
||||||
use actix_cors::Cors;
|
use actix_cors::Cors;
|
||||||
use actix_web::{HttpServer, App, web, cookie::{time::Duration, SameSite}};
|
use actix_web::{HttpServer, App, web};
|
||||||
use crate::bot::{commands::oai::GPTModel, handler::Handler};
|
use crate::bot::{commands::oai::GPTModel, handler::Handler};
|
||||||
|
|
||||||
use dotenv::dotenv;
|
use dotenv::dotenv;
|
||||||
@@ -114,7 +113,6 @@ async fn main() -> std::io::Result<()> {
|
|||||||
let port = env::var("SERVICE_PORT").unwrap_or("5000".to_string());
|
let port = env::var("SERVICE_PORT").unwrap_or("5000".to_string());
|
||||||
|
|
||||||
let server = match HttpServer::new(move || {
|
let server = match HttpServer::new(move || {
|
||||||
// let auth = HttpAuthentication::bearer(validator);
|
|
||||||
let private_key = actix_web::cookie::Key::generate();
|
let private_key = actix_web::cookie::Key::generate();
|
||||||
// let redis_host = env::var("REDIS_HOST").unwrap_or("localhost".to_string());
|
// let redis_host = env::var("REDIS_HOST").unwrap_or("localhost".to_string());
|
||||||
// let redis_port = env::var("REDIS_PORT").unwrap_or("6379".to_string());
|
// let redis_port = env::var("REDIS_PORT").unwrap_or("6379".to_string());
|
||||||
@@ -127,7 +125,6 @@ async fn main() -> std::io::Result<()> {
|
|||||||
.cookie_name("auth".to_owned())
|
.cookie_name("auth".to_owned())
|
||||||
.cookie_secure(false)
|
.cookie_secure(false)
|
||||||
.cookie_http_only(false)
|
.cookie_http_only(false)
|
||||||
// .cookie_content_security(CookieContentSecurity::Private)
|
|
||||||
.cookie_domain(Some("localhost".to_owned()))
|
.cookie_domain(Some("localhost".to_owned()))
|
||||||
.cookie_path("/".to_owned())
|
.cookie_path("/".to_owned())
|
||||||
.build();
|
.build();
|
||||||
@@ -137,9 +134,7 @@ async fn main() -> std::io::Result<()> {
|
|||||||
.allow_any_header()
|
.allow_any_header()
|
||||||
.supports_credentials()
|
.supports_credentials()
|
||||||
.max_age(3600);
|
.max_age(3600);
|
||||||
// let cors = Cors::permissive();
|
|
||||||
App::new()
|
App::new()
|
||||||
// .wrap(auth)
|
|
||||||
.wrap(IdentityMiddleware::default())
|
.wrap(IdentityMiddleware::default())
|
||||||
.wrap(session)
|
.wrap(session)
|
||||||
.wrap(cors)
|
.wrap(cors)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { postRequest } from '.';
|
import { getRequest, postRequest } from '.';
|
||||||
|
|
||||||
export async function login(email: string, password: string) {
|
export async function login(email: string, password: string) {
|
||||||
return await postRequest('users/login', { email, password }, { withCredentials: true });
|
return await postRequest('users/login', { email, password }, { withCredentials: true });
|
||||||
@@ -7,3 +7,7 @@ export async function login(email: string, password: string) {
|
|||||||
export async function logout() {
|
export async function logout() {
|
||||||
return await postRequest('users/logout', {}, { withCredentials: true });
|
return await postRequest('users/logout', {}, { withCredentials: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function ping() {
|
||||||
|
return await getRequest('users/ping', { withCredentials: true });
|
||||||
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import {
|
|||||||
import Cookies from 'js-cookie';
|
import Cookies from 'js-cookie';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { useForm } from '@mantine/form';
|
import { useForm } from '@mantine/form';
|
||||||
import { login, logout } from '@/api/users';
|
import { login, logout, ping } from '@/api/users';
|
||||||
|
|
||||||
const headerItems = [
|
const headerItems = [
|
||||||
{
|
{
|
||||||
@@ -107,6 +107,7 @@ export default function Topbar() {
|
|||||||
Logout
|
Logout
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
)}
|
)}
|
||||||
|
<Menu.Item onClick={() => ping()}>Ping</Menu.Item>
|
||||||
</Menu.Dropdown>
|
</Menu.Dropdown>
|
||||||
</Menu>
|
</Menu>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user