134 lines
3.4 KiB
Rust
134 lines
3.4 KiB
Rust
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<AuditLogger>,
|
|
}
|
|
|
|
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<GetUsersRequest>,
|
|
) -> Result<Response<UserListResponse>, 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<GetUserRequest>,
|
|
) -> Result<Response<UserResponse>, 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<CreateUserRequest>,
|
|
) -> Result<Response<UserResponse>, 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<dyn std::error::Error>> {
|
|
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(())
|
|
}
|
|
|
|
|