From cf9efc9866c971bfb2a63a4b1fd1ff924c433805388133fb1b8036a470b1bef1 Mon Sep 17 00:00:00 2001 From: RavenX8 <7156279+RavenX8@users.noreply.github.com> Date: Sun, 16 Mar 2025 01:35:44 -0400 Subject: [PATCH] - update: auth system to work with the website auth --- auth-service/src/database_client.rs | 26 +----- auth-service/src/grpc.rs | 93 +++++-------------- .../src/mocks/database_client_mock.rs | 3 +- auth-service/src/users.rs | 15 +-- database-service/src/characters.rs | 20 ++-- database-service/src/grpc/user_service.rs | 34 ++----- database-service/src/users.rs | 82 ++++++---------- docker-compose.yml | 2 +- proto/character_db_api.proto | 4 +- proto/user_db_api.proto | 32 ++----- session-service/src/session_service.rs | 1 + 11 files changed, 93 insertions(+), 219 deletions(-) diff --git a/auth-service/src/database_client.rs b/auth-service/src/database_client.rs index 393532d..3b7feb8 100644 --- a/auth-service/src/database_client.rs +++ b/auth-service/src/database_client.rs @@ -1,6 +1,5 @@ use crate::database::{ - user_service_client::UserServiceClient, CreateUserRequest, CreateUserResponse, - GetUserByEmailRequest, GetUserByUsernameRequest, GetUserRequest, GetUserResponse, + user_service_client::UserServiceClient, GetUserByEmailRequest, GetUserByUsernameRequest, GetUserRequest, GetUserResponse, }; use async_trait::async_trait; use chrono::{DateTime, Utc}; @@ -22,12 +21,6 @@ pub trait DatabaseClientTrait: Sized { &mut self, email: &str, ) -> Result>; - async fn create_user( - &mut self, - username: &str, - email: &str, - password: &str, - ) -> Result>; async fn store_password_reset( &mut self, email: &str, @@ -94,22 +87,7 @@ impl DatabaseClientTrait for DatabaseClient { let response = self.client.get_user_by_email(request).await?; Ok(response.into_inner()) } - - async fn create_user( - &mut self, - username: &str, - email: &str, - password: &str, - ) -> Result> { - let request = tonic::Request::new(CreateUserRequest { - username: username.to_string(), - email: email.to_string(), - hashed_password: password.to_string(), - }); - let response = self.client.create_user(request).await?; - Ok(response.into_inner()) - } - + async fn store_password_reset( &mut self, _email: &str, diff --git a/auth-service/src/grpc.rs b/auth-service/src/grpc.rs index eeb1f2c..c123bdd 100644 --- a/auth-service/src/grpc.rs +++ b/auth-service/src/grpc.rs @@ -27,51 +27,7 @@ impl AuthService for MyAuthService { &self, request: Request, ) -> Result, Status> { - let req = request.into_inner(); - - info!("Login attempt for username: {}", req.username); - - if let Some(user) = verify_user( - self.db_client.as_ref().clone(), - &req.username, - &req.password, - ) - .await - { - let user_id = user.user_id.to_string(); - let session_id = uuid::Uuid::new_v4().to_string(); - let response = self - .session_client - .as_ref() - .clone() - .create_session(CreateSessionRequest { - session_id: session_id.clone(), - user_id: user.user_id, - username: req.username.to_string(), - character_id: 0, - ip_address: req.ip_address.to_string(), - }) - .await; - - let session = match response { - Ok(session) => session, - Err(_) => return Err(Status::internal("Session creation failed")), - }; - let session_id = session.into_inner().session_id; - - let token = generate_token(&user_id, &&session_id.clone(), user.roles) - .map_err(|_| Status::internal("Token generation failed"))?; - - info!("Login successful for username: {}", req.username); - Ok(Response::new(LoginResponse { - token, - user_id, - session_id, - })) - } else { - warn!("Invalid login attempt for username: {}", req.username); - Err(Status::unauthenticated("Invalid credentials")) - } + Err(Status::unimplemented("login not implemented due to changes")) } async fn logout(&self, request: Request) -> Result, Status> { @@ -188,29 +144,30 @@ impl AuthService for MyAuthService { &self, request: Request, ) -> Result, Status> { - let req = request.into_inner(); - - // Hash the password - let hashed_password = hash_password(&req.password); - - // Create user in the database - let result = self - .db_client - .as_ref() - .clone() - .create_user(&req.username, &req.email, &hashed_password) - .await; - - match result { - Ok(user) => Ok(Response::new(RegisterResponse { - user_id: user.user_id, - message: "User registered successfully".into(), - })), - Err(e) => { - error!("Failed to register user: {:?}", e); - Err(Status::internal("Failed to register user")) - } - } + // let req = request.into_inner(); + // + // // Hash the password + // let hashed_password = hash_password(&req.password); + // + // // Create user in the database + // let result = self + // .db_client + // .as_ref() + // .clone() + // .create_user(&req.username, &req.email, &hashed_password) + // .await; + // + // match result { + // Ok(user) => Ok(Response::new(RegisterResponse { + // user_id: user.user_id, + // message: "User registered successfully".into(), + // })), + // Err(e) => { + // error!("Failed to register user: {:?}", e); + // Err(Status::internal("Failed to register user")) + // } + // } + Err(Status::unimplemented("register not implemented")) } async fn request_password_reset( diff --git a/auth-service/src/mocks/database_client_mock.rs b/auth-service/src/mocks/database_client_mock.rs index 466a199..efb0d18 100644 --- a/auth-service/src/mocks/database_client_mock.rs +++ b/auth-service/src/mocks/database_client_mock.rs @@ -1,4 +1,4 @@ -use crate::database::{CreateUserResponse, GetUserResponse}; +use crate::database::GetUserResponse; use crate::database_client::{DatabaseClientTrait, PasswordReset}; use async_trait::async_trait; use chrono::{DateTime, Utc}; @@ -15,7 +15,6 @@ mock! { async fn get_user_by_userid(&mut self, user_id: i32) -> Result>; async fn get_user_by_username(&mut self, user_id: &str) -> Result>; async fn get_user_by_email(&mut self, email: &str) -> Result>; - async fn create_user(&mut self, username: &str, email: &str, password: &str) -> Result>; async fn store_password_reset(&mut self, email: &str, reset_token: &str, expires_at: DateTime) -> Result<(), Box>; async fn get_password_reset(&self, reset_token: &str) -> Result, Box>; async fn delete_password_reset(&self, reset_token: &str) -> Result<(), Box>; diff --git a/auth-service/src/users.rs b/auth-service/src/users.rs index 2efde31..d29f788 100644 --- a/auth-service/src/users.rs +++ b/auth-service/src/users.rs @@ -27,11 +27,12 @@ pub async fn verify_user( username: &str, password: &str, ) -> Option { - let user = db_client.get_user_by_username(username).await.ok()?; - - if verify_password(password, &user.hashed_password) { - Some(user) - } else { - None - } + // let user = db_client.get_user_by_username(username).await.ok()?; + // + // if verify_password(password, &user.hashed_password) { + // Some(user) + // } else { + // None + // } + None } diff --git a/database-service/src/characters.rs b/database-service/src/characters.rs index 02934b9..c476840 100644 --- a/database-service/src/characters.rs +++ b/database-service/src/characters.rs @@ -8,7 +8,7 @@ use utils::redis_cache::{Cache, RedisCache}; #[derive(Debug, FromRow, Serialize, Deserialize)] pub struct Character { pub id: i32, - pub user_id: i32, + pub user_id: String, pub name: String, pub money: i64, pub inventory: serde_json::Value, @@ -49,9 +49,9 @@ impl CharacterRepository { // Fetch from database let character = sqlx::query_as::<_, Character>( - "SELECT id, user_id, name, money, inventory, stats, skills, looks, position, \ - created_at, updated_at, extract(epoch from (deleted_at - now()))::BIGINT as deleted_at, is_active \ - FROM characters WHERE id = $1 AND is_active = true", + "SELECT id, userId as user_id, name, money, inventory, stats, skills, looks, position, \ + createdAt as created_at, updatedAt as updated_at, extract(epoch from (deletedAt - now()))::BIGINT as deleted_at, isActive as is_active \ + FROM character WHERE id = $1 AND isActive = true", ) .bind(character_id) .fetch_one(&self.pool) @@ -69,7 +69,7 @@ impl CharacterRepository { pub async fn create_character( &self, - user_id: i32, + user_id: String, name: &str, inventory: serde_json::Value, skills: serde_json::Value, @@ -78,10 +78,10 @@ impl CharacterRepository { position: serde_json::Value, ) -> Result { let result = sqlx::query( - "INSERT INTO characters (user_id, name, inventory, stats, skills, looks, position, created_at, updated_at, is_active) \ + "INSERT INTO character (userId, name, inventory, stats, skills, looks, position, createdAt, updatedAt, isActive) \ VALUES ($1, $2, $3, $4, $5, $6, $7, NOW(), NOW(), true) RETURNING id", ) - .bind(user_id) + .bind(&user_id) .bind(name) .bind(inventory) .bind(stats) @@ -107,9 +107,9 @@ impl CharacterRepository { character_id: i32, delete_type: i32, ) -> Result { - let mut query = "UPDATE characters SET updated_at = NOW(), deleted_at = NOW() + '24 hours' WHERE id = $1 RETURNING user_id, extract(epoch from (deleted_at - now()))::BIGINT as deleted_at"; + let mut query = "UPDATE character SET updatedAt = NOW(), deletedAt = NOW() + '24 hours' WHERE id = $1 RETURNING userId, extract(epoch from (deletedAt - now()))::BIGINT as deletedAt"; if 0 == delete_type { - query = "UPDATE characters SET updated_at = NOW(), deleted_at = null WHERE id = $1 RETURNING user_id, 0::BIGINT as deleted_at"; + query = "UPDATE character SET updatedAt = NOW(), deletedAt = null WHERE id = $1 RETURNING userId, 0::BIGINT as deletedAt"; } let result = sqlx::query(query) .bind(character_id) @@ -154,7 +154,7 @@ impl CharacterRepository { // Fetch from database let characters = sqlx::query_as::<_, Character>( - "SELECT id, user_id, name, money, inventory, stats, skills, looks, position, created_at, updated_at, extract(epoch from (deleted_at - now()))::BIGINT as deleted_at, is_active FROM characters WHERE user_id = $1 AND is_active = true", + "SELECT id, userId as user_id, name, money, inventory, stats, skills, looks, position, createdAt as created_at, updatedAt as updated_at, extract(epoch from (deletedAt - now()))::BIGINT as deleted_at, isActive as is_active FROM character WHERE userId = $1 AND isActive = true", ) .bind(user_id) .fetch_all(&self.pool) diff --git a/database-service/src/grpc/user_service.rs b/database-service/src/grpc/user_service.rs index 28c522f..898cc66 100644 --- a/database-service/src/grpc/user_service.rs +++ b/database-service/src/grpc/user_service.rs @@ -1,7 +1,7 @@ use crate::grpc::database_service::MyDatabaseService; use crate::grpc::user_service_server::UserService; use crate::grpc::{ - CreateUserRequest, CreateUserResponse, GetUserByEmailRequest, GetUserByUsernameRequest, + GetUserByEmailRequest, GetUserByUsernameRequest, GetUserRequest, GetUserResponse, }; use tonic::{Request, Response, Status}; @@ -23,30 +23,12 @@ impl UserService for MyDatabaseService { Ok(Response::new(GetUserResponse { user_id: user.id, - username: user.username, + username: user.name, email: user.email, - hashed_password: user.hashed_password, - roles: user.roles.unwrap_or_else(Vec::new), + role: user.role, })) } - async fn create_user( - &self, - request: Request, - ) -> Result, Status> { - let req = request.into_inner(); - - let user_id = self - .db - .user_repo - .create_user(&req.username, &req.email, &req.hashed_password) - .await - .map_err(|_| Status::internal("Failed to create user"))?; - - // Return the newly created user ID - Ok(Response::new(CreateUserResponse { user_id })) - } - async fn get_user_by_username( &self, request: Request, @@ -62,10 +44,9 @@ impl UserService for MyDatabaseService { Ok(Response::new(GetUserResponse { user_id: user.id, - username: user.username, + username: user.name, email: user.email, - hashed_password: user.hashed_password, - roles: user.roles.unwrap_or_else(Vec::new), + role: user.role, })) } @@ -84,10 +65,9 @@ impl UserService for MyDatabaseService { Ok(Response::new(GetUserResponse { user_id: user.id, - username: user.username, + username: user.name, email: user.email, - hashed_password: user.hashed_password, - roles: user.roles.unwrap_or_else(Vec::new), + role: user.role, })) } } diff --git a/database-service/src/users.rs b/database-service/src/users.rs index 4fa12bb..e538173 100644 --- a/database-service/src/users.rs +++ b/database-service/src/users.rs @@ -2,15 +2,14 @@ use serde::{Deserialize, Serialize}; use sqlx::{FromRow, Row}; use std::sync::Arc; use tokio::sync::Mutex; -use utils::redis_cache::{Cache, RedisCache}; // Import RedisCache and Cache Trait +use utils::redis_cache::{Cache, RedisCache}; #[derive(Debug, FromRow, Serialize, Deserialize)] pub struct User { pub id: i32, - pub username: String, + pub name: String, pub email: String, - pub hashed_password: String, - pub roles: Option>, + pub role: String, pub created_at: chrono::NaiveDateTime, pub updated_at: chrono::NaiveDateTime, } @@ -40,7 +39,7 @@ impl UserRepository { } let user = sqlx::query_as::<_, User>( - "SELECT id, username, email, hashed_password, roles, created_at, updated_at FROM users WHERE id = $1", + "SELECT id, name, email, role, createdAt, updatedAt FROM user WHERE id = $1", ) .bind(user_id) .fetch_one(&self.pool) @@ -70,7 +69,7 @@ impl UserRepository { } let user = sqlx::query_as::<_, User>( - "SELECT id, username, email, hashed_password, roles, created_at, updated_at FROM users WHERE username = $1", + "SELECT id, name, email, role, createdAt, updatedAt FROM user WHERE name = $1", ) .bind(username) .fetch_one(&self.pool) @@ -100,7 +99,7 @@ impl UserRepository { } let user = sqlx::query_as::<_, User>( - "SELECT id, username, email, hashed_password, roles, created_at, updated_at FROM users WHERE email = $1", + "SELECT id, name, email, role, createdAt, updatedAt FROM user WHERE email = $1", ) .bind(email) .fetch_one(&self.pool) @@ -115,62 +114,33 @@ impl UserRepository { Ok(user) } - pub async fn create_user( - &self, - username: &str, - email: &str, - hashed_password: &str, - ) -> Result { - let row = sqlx::query( - r#" - INSERT INTO users (username, email, hashed_password) - VALUES ($1, $2, $3) - RETURNING id - "#, + pub async fn get_user_by_session(&self, session: &str) -> Result { + let cache_key = format!("user:session:{}", session); + + if let Some(user) = self + .cache + .lock() + .await + .get::(&cache_key) + .await + .map_err(|_| sqlx::Error::RowNotFound)? + { + return Ok(user); + } + + let user = sqlx::query_as::<_, User>( + "SELECT id, name, email, role, createdAt, updatedAt FROM user WHERE email = $1", ) - .bind(username) - .bind(email) - .bind(hashed_password) - .fetch_one(&self.pool) - .await?; - - Ok(row.get(0)) - } - - pub async fn update_user_email( - &self, - user_id: i32, - new_email: &str, - ) -> Result<(), sqlx::Error> { - sqlx::query("UPDATE users SET email = $1, updated_at = NOW() WHERE id = $2") - .bind(new_email) - .bind(user_id) - .execute(&self.pool) + .bind(session) + .fetch_one(&self.pool) .await?; - let cache_key = format!("user:{}", user_id); self.cache .lock() .await - .delete(&cache_key) + .set(&cache_key, &user, 300) .await .map_err(|_| sqlx::Error::RowNotFound)?; - Ok(()) - } - - pub async fn delete_user(&self, user_id: i32) -> Result<(), sqlx::Error> { - sqlx::query("DELETE FROM users WHERE id = $1") - .bind(user_id) - .execute(&self.pool) - .await?; - - let cache_key = format!("user:{}", user_id); - self.cache - .lock() - .await - .delete(&cache_key) - .await - .map_err(|_| sqlx::Error::RowNotFound)?; - Ok(()) + Ok(user) } } diff --git a/docker-compose.yml b/docker-compose.yml index 2b395b4..c87c493 100755 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -172,7 +172,7 @@ - "5432:5432" volumes: - db_data:/var/lib/postgresql/data - - ./sql/schema.sql:/docker-entrypoint-initdb.d/schema.sql:ro + # - ./sql/schema.sql:/docker-entrypoint-initdb.d/schema.sql:ro consul: image: hashicorp/consul:latest diff --git a/proto/character_db_api.proto b/proto/character_db_api.proto index c2f85f6..6e5f82b 100644 --- a/proto/character_db_api.proto +++ b/proto/character_db_api.proto @@ -23,7 +23,7 @@ message CharacterListResponse { } message CreateCharacterRequest { - int32 user_id = 1; + string user_id = 1; string name = 2; string inventory = 3; // JSON serialized string skills = 4; // JSON serialized @@ -50,7 +50,7 @@ message DeleteCharacterResponse { message Character { int32 id = 1; - int32 user_id = 2; + string user_id = 2; string name = 3; int64 money = 4; string inventory = 6; diff --git a/proto/user_db_api.proto b/proto/user_db_api.proto index ff2ec36..4209643 100644 --- a/proto/user_db_api.proto +++ b/proto/user_db_api.proto @@ -3,38 +3,26 @@ syntax = "proto3"; package user_db_api; service UserService { - rpc GetUser(GetUserRequest) returns (GetUserResponse); - rpc CreateUser(CreateUserRequest) returns (CreateUserResponse); - rpc GetUserByUsername(GetUserByUsernameRequest) returns (GetUserResponse); - rpc GetUserByEmail(GetUserByEmailRequest) returns (GetUserResponse); + rpc GetUser(GetUserRequest) returns (GetUserResponse); + rpc GetUserByUsername(GetUserByUsernameRequest) returns (GetUserResponse); + rpc GetUserByEmail(GetUserByEmailRequest) returns (GetUserResponse); } message GetUserRequest { - int32 user_id = 1; + int32 user_id = 1; } message GetUserByUsernameRequest { - string username = 1; + string username = 1; } message GetUserByEmailRequest { - string email = 1; + string email = 1; } message GetUserResponse { - int32 user_id = 1; - string username = 2; - string email = 3; - string hashed_password = 4; - repeated string roles = 5; -} - -message CreateUserRequest { - string username = 1; - string email = 2; - string hashed_password = 3; -} - -message CreateUserResponse { - int32 user_id = 1; + int32 user_id = 1; + string username = 2; + string email = 3; + string role = 4; } diff --git a/session-service/src/session_service.rs b/session-service/src/session_service.rs index 9e8d0ea..c16c6f5 100644 --- a/session-service/src/session_service.rs +++ b/session-service/src/session_service.rs @@ -84,6 +84,7 @@ impl SessionService for SessionServiceImpl { Ok(Response::new(response)) } else { + debug!("Session not found in redis: {}", req.session_id); Err(Status::not_found("Session not found")) } }