feat(server): v2 RPC handler dispatch for all 33 methods
Add v2_handlers module with ServerState, build_registry(), require_auth() helper, and 33 protobuf handlers across 10 files: - auth: 4 OPAQUE handlers (register start/finish, login start/finish) - delivery: 6 handlers (enqueue, fetch, fetch_wait, peek, ack, batch) - keys: 5 handlers (upload/fetch key package, upload/fetch hybrid key/keys) - channel: create_channel - user: resolve_user, resolve_identity - blob: upload_blob, download_blob - device: register, list, revoke - p2p: publish_endpoint, resolve_endpoint, health - federation: 6 stubs (Unimplemented) - account: delete_account All handlers decode protobuf, call domain services, encode response. Auth handlers use full OPAQUE flow with session creation. Delivery handlers include rate limiting and long-poll (fetch_wait).
This commit is contained in:
89
crates/quicproquo-server/src/v2_handlers/user.rs
Normal file
89
crates/quicproquo-server/src/v2_handlers/user.rs
Normal file
@@ -0,0 +1,89 @@
|
||||
//! User resolution handlers — username <-> identity key lookups.
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use bytes::Bytes;
|
||||
use prost::Message;
|
||||
use quicproquo_proto::qpq::v1;
|
||||
use quicproquo_rpc::method::{HandlerResult, RequestContext};
|
||||
|
||||
use crate::domain::types::{ResolveIdentityReq, ResolveUserReq};
|
||||
use crate::domain::users::UserService;
|
||||
|
||||
use super::{domain_err, require_auth, ServerState};
|
||||
|
||||
pub async fn handle_resolve_user(state: Arc<ServerState>, ctx: RequestContext) -> HandlerResult {
|
||||
let _identity_key = match require_auth(&state, &ctx) {
|
||||
Ok(ik) => ik,
|
||||
Err(e) => return e,
|
||||
};
|
||||
|
||||
let req = match v1::ResolveUserRequest::decode(ctx.payload) {
|
||||
Ok(r) => r,
|
||||
Err(e) => {
|
||||
return HandlerResult::err(
|
||||
quicproquo_rpc::error::RpcStatus::BadRequest,
|
||||
&format!("decode: {e}"),
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
let svc = UserService {
|
||||
store: Arc::clone(&state.store),
|
||||
kt_log: Arc::clone(&state.kt_log),
|
||||
};
|
||||
|
||||
let domain_req = ResolveUserReq {
|
||||
username: req.username,
|
||||
};
|
||||
|
||||
match svc.resolve_user(domain_req) {
|
||||
Ok(resp) => {
|
||||
let proto = v1::ResolveUserResponse {
|
||||
identity_key: resp.identity_key,
|
||||
inclusion_proof: resp.inclusion_proof,
|
||||
};
|
||||
HandlerResult::ok(Bytes::from(proto.encode_to_vec()))
|
||||
}
|
||||
Err(e) => domain_err(e),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn handle_resolve_identity(
|
||||
state: Arc<ServerState>,
|
||||
ctx: RequestContext,
|
||||
) -> HandlerResult {
|
||||
let _identity_key = match require_auth(&state, &ctx) {
|
||||
Ok(ik) => ik,
|
||||
Err(e) => return e,
|
||||
};
|
||||
|
||||
let req = match v1::ResolveIdentityRequest::decode(ctx.payload) {
|
||||
Ok(r) => r,
|
||||
Err(e) => {
|
||||
return HandlerResult::err(
|
||||
quicproquo_rpc::error::RpcStatus::BadRequest,
|
||||
&format!("decode: {e}"),
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
let svc = UserService {
|
||||
store: Arc::clone(&state.store),
|
||||
kt_log: Arc::clone(&state.kt_log),
|
||||
};
|
||||
|
||||
let domain_req = ResolveIdentityReq {
|
||||
identity_key: req.identity_key,
|
||||
};
|
||||
|
||||
match svc.resolve_identity(domain_req) {
|
||||
Ok(resp) => {
|
||||
let proto = v1::ResolveIdentityResponse {
|
||||
username: resp.username,
|
||||
};
|
||||
HandlerResult::ok(Bytes::from(proto.encode_to_vec()))
|
||||
}
|
||||
Err(e) => domain_err(e),
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user