use tonic::{Request, Response, Status, transport::Server}; use std::sync::Arc; use shared_proto::user::{ user_service_server::{UserService, UserServiceServer}, GetUsersRequest, UserListResponse, User, GetUserRequest, CreateUserRequest, UserResponse, }; use tracing_subscriber; use audit_logger::{ActionType, AuditLogger, InMemoryAuditStore}; pub struct UserServiceImpl { audit_logger: Arc, } fn create_audit_logger() -> AuditLogger { let store = Arc::new(InMemoryAuditStore::new()); AuditLogger::new(store, "user_service") } #[tonic::async_trait] impl UserService for UserServiceImpl { async fn get_users( &self, _request: Request, ) -> Result, Status> { let _ = self .audit_logger .log_action( None, ActionType::Read, "users".to_string(), "/GetUsers".to_string(), ) .await; tracing::info!("GetUsers called"); let users = vec![ User { id: 1, name: "Alice".to_string(), email: "alice@example.com".to_string(), }, User { id: 2, name: "Bob".to_string(), email: "bob@example.com".to_string(), }, ]; Ok(Response::new(UserListResponse { users })) } async fn get_user( &self, request: Request, ) -> Result, Status> { let user_id = request.into_inner().id; let _ = self .audit_logger .log_detailed( None, ActionType::Read, "users".to_string(), "/GetUser".to_string(), None, None, Some(format!("Getting user {}", user_id)), ) .await; tracing::info!("GetUser called with id: {}", user_id); Ok(Response::new(UserResponse { id: user_id, name: "User".to_string(), email: format!("user{}@example.com", user_id), })) } async fn create_user( &self, request: Request, ) -> Result, Status> { let req = request.into_inner(); let _ = self .audit_logger .log_detailed( None, ActionType::Create, "users".to_string(), "/CreateUser".to_string(), None, None, Some(format!("Creating user: {}", req.name)), ) .await; tracing::info!("CreateUser called with name: {}", req.name); Ok(Response::new(UserResponse { id: 3, name: req.name, email: req.email, })) } } #[tokio::main] async fn main() -> Result<(), Box> { tracing_subscriber::fmt::init(); let audit_logger = Arc::new(create_audit_logger()); let addr = "127.0.0.1:13001".parse()?; let user_service = UserServiceImpl { audit_logger: audit_logger.clone(), }; tracing::info!("User Service gRPC server listening on {}", addr); tracing::info!("Audit logging enabled!"); Server::builder() .add_service(UserServiceServer::new(user_service)) .serve(addr) .await?; Ok(()) }