//! 内部 RPC 的 chat 域:只做协议转换,权限判定在 `ChatService`。 use internal::Gate; use internal::server::InternalRouter; use proto::internal::v1::chat_authorization_service_server::{ ChatAuthorizationService as ChatAuthorizationTrait, ChatAuthorizationServiceServer, }; use proto::internal::v1::{AuthorizationDecision, AuthorizeRoomRequest}; use tonic::{Request, Response, Status}; use crate::errors::ChatError; use crate::services::service::ChatService; pub fn register(router: InternalRouter, service: &ChatService, gate: Gate) -> InternalRouter { router.add_service(ChatAuthorizationServiceServer::with_interceptor( ChatRpc { service: service.clone(), }, gate, )) } #[derive(Clone)] struct ChatRpc { service: ChatService, } #[tonic::async_trait] impl ChatAuthorizationTrait for ChatRpc { async fn authorize_room( &self, request: Request, ) -> Result, Status> { let _meta = internal::interceptor::meta(&request)?; let request = request.into_inner(); let room_id = request .room_id .parse() .map_err(|_| Status::invalid_argument("room_id must be a UUID"))?; let allowed = self .service .authorize_internal_room(request.user_id, room_id, &request.action) .await .map_err(status_of)?; Ok(Response::new(AuthorizationDecision { allowed, reason: String::new(), resource_id: request.room_id, })) } } fn status_of(error: ChatError) -> Status { match error { ChatError::Unauthorized => Status::unauthenticated("chat authorization rejected"), ChatError::Forbidden | ChatError::NotFound => Status::permission_denied("not allowed"), ChatError::BadRequest(message) => Status::invalid_argument(message), ChatError::RateLimited(message) => Status::resource_exhausted(message), other => { tracing::warn!(%other, "internal chat authorization failed"); Status::internal("chat authorization failed") } } }