user-auth orm and meili changes

This commit is contained in:
2022-12-29 22:22:04 +05:30
parent 0e357b0d4e
commit ec907e4b5f
20 changed files with 702 additions and 175 deletions

View File

@@ -9,7 +9,7 @@ booksman-orm = { path = "../orm" }
booksman-search = { path = "../search" }
migration = { path = "../migration" }
entity = { path = "../entity" }
axum = "^0.5"
axum = "^0.6"
axum-extra = { version = "^0.3", features = ["spa"] }
clap = { version = "^3", features = ["derive"] }
dotenvy = "0.15.0"
@@ -27,9 +27,15 @@ tracing = "^0.1"
tracing-subscriber = "^0.3"
itertools = "0.10"
chrono = "0.4"
axum-login = "0.4"
#features = ["sqlite"]
[dependencies.rand]
version = "0.8.5"
features = ["min_const_gen"]
[dependencies.sea-orm]
version = "^0.9.2" # sea-orm version
version = "^0.10.6" # sea-orm version
features = [
"debug-print",
"runtime-tokio-native-tls",

View File

@@ -31,6 +31,31 @@ use ::entity::entities::{book,book_author,book_person,book_place,book_subject,bo
use std::env;
use migration::{Migrator, MigratorTrait};
use chrono::Local;
use axum_login::{
axum_sessions::{async_session::MemoryStore as SessionMemoryStore, SessionLayer},
memory_store::MemoryStore as AuthMemoryStore,
secrecy::SecretVec,
AuthLayer, AuthUser, RequireAuthorizationLayer,
};
use rand::Rng;
use std::{collections::HashMap, sync::Arc};
#[derive(Debug, Default, Clone)]
struct User {
id: i64,
password_hash: String,
name: String,
}
impl AuthUser for User {
fn get_id(&self) -> String {
format!("{}", self.id)
}
fn get_password_hash(&self) -> SecretVec<u8> {
SecretVec::new(self.password_hash.clone().into())
}
}
#[derive(Deserialize, Serialize, Debug, Clone)]
struct BookUI {
@@ -206,6 +231,8 @@ struct Opt {
static_dir: String,
}
type AuthContext = axum_login::extractors::AuthContext<User, AuthMemoryStore<User>>;
#[tokio::main]
pub async fn main() {
let opt = Opt::parse();
@@ -225,6 +252,10 @@ pub async fn main() {
let meili_url = env::var("MEILI_URL").expect("MEILI_URL is not set in .env file");
let meili_key = env::var("MEILI_KEY").expect("MEILI_KEY is not set in .env file");
let secret = rand::thread_rng().gen::<[u8; 64]>();
let session_store = MemoryStore::new();
let session_layer = SessionLayer::new(session_store, &secret).with_secure(false);
let conn = Database::connect(db_url)
.await
@@ -232,8 +263,37 @@ pub async fn main() {
// Apply all pending migrations
Migrator::up(&conn, None).await.unwrap();
let store = Arc::new(RwLock::new(HashMap::default()));
let users : Vec<User> = get_users_seaorm(conn);
//let user = User::get_rusty_user();
for user in users.iter() {
store.write().await.insert(user.get_id(), user);
}
let user_store = AuthMemoryStore::new(&store);
let auth_layer = AuthLayer::new(user_store, &secret);
let meili_client = Client::new(meili_url, meili_key);
async fn login_handler(mut auth: AuthContext, Json(user_sent): Json<User>) {
auth.login(&user_sent).await.unwrap();
}
async fn register_handler(mut auth: AuthContext, Json(user_sent): Json<User>) {
// add to db
store.write().await.insert(user_sent.get_id(), user_sent);
auth.login(&user_sent).await.unwrap();
}
async fn logout_handler(mut auth: AuthContext) {
dbg!("Logging out user: {}", &auth.current_user);
auth.logout().await;
}
let app = Router::new()
.route("/api/search_openlibrary", get(search_openlibrary))
.route("/api/create_by_isbn", get(create_by_isbn))
@@ -242,8 +302,13 @@ pub async fn main() {
.route("/api/list_search", get(list_search_book))
.route("/api/create", post(create_book))
.route("/api/update", post(update_book))
.route("/api/login", post(login_handler))
.route("/api/register", post(register_handler))
.route("/api/logout", post(logout_handler))
.nest("/images", get_service(ServeDir::new(images_dir)).handle_error(handle_error))
.merge(SpaRouter::new("/assets", opt.static_dir))
.layer(auth_layer)
.layer(session_layer)
.layer(ServiceBuilder::new().layer(TraceLayer::new_for_http()))
.layer(Extension(conn))
.layer(Extension(meili_client))