Skip to content
Clone
eeff292
87 lines 2.7 KB Rust
//! 内部 RPC 的 auth 域:协议转换只在这一层,业务逻辑在 `AuthService`。
use internal::Gate;
use internal::server::InternalRouter;
use proto::internal::v1::identity_service_server::{
IdentityService as IdentityServiceTrait, IdentityServiceServer,
};
use proto::internal::v1::{
AttestIdentityRequest, AttestIdentityResponse, CredentialKind, ResolveIdentityRequest,
ResolveIdentityResponse,
};
use tonic::{Request, Response, Status};
use crate::errors::AuthError;
use crate::services::AuthService;
mod access_key;
mod ssh_key;
pub fn register(router: InternalRouter, service: &AuthService, gate: Gate) -> InternalRouter {
let router = access_key::register(router, service, gate.clone());
let router = ssh_key::register(router, service, gate.clone());
router.add_service(IdentityServiceServer::with_interceptor(
IdentityRpc {
service: service.clone(),
},
gate,
))
}
#[derive(Clone)]
struct IdentityRpc {
service: AuthService,
}
#[tonic::async_trait]
impl IdentityServiceTrait for IdentityRpc {
async fn resolve(
&self,
request: Request<ResolveIdentityRequest>,
) -> Result<Response<ResolveIdentityResponse>, Status> {
let meta = internal::interceptor::meta(&request)?;
let request = request.into_inner();
if request.kind() != CredentialKind::Session {
return Err(Status::invalid_argument("unsupported credential kind"));
}
let principal = self
.service
.resolve_internal_session(&request.credential, meta.request_id.as_str())
.await
.map_err(status_of)?;
Ok(Response::new(ResolveIdentityResponse {
principal: Some(principal),
}))
}
async fn attest(
&self,
request: Request<AttestIdentityRequest>,
) -> Result<Response<AttestIdentityResponse>, Status> {
let meta = internal::interceptor::meta(&request)?;
let request = request.into_inner();
let principal = self
.service
.attest_internal_identity(
request.user_id,
request.security_version,
meta.request_id.as_str(),
)
.await
.map_err(status_of)?;
Ok(Response::new(AttestIdentityResponse {
active: true,
principal: Some(principal),
}))
}
}
fn status_of(error: AuthError) -> Status {
match error {
AuthError::Unauthenticated => Status::unauthenticated("identity was rejected"),
other => {
tracing::warn!(%other, "internal identity rpc failed");
Status::internal("identity lookup failed")
}
}
}