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:
2026-03-04 12:10:33 +01:00
parent 6273ab668d
commit d118fdbddf
13 changed files with 1695 additions and 0 deletions

View 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),
}
}