tangled
alpha
login
or
join now
hotsocket.fyi
/
microcosm-rs
forked from
microcosm.blue/microcosm-rs
0
fork
atom
Constellation, Spacedust, Slingshot, UFOs: atproto crates and services for microcosm
0
fork
atom
overview
issues
pulls
pipelines
com.atproto.identity.resolveHandle
bad-example.com
7 months ago
2afb053e
1d646ef2
+97
1 changed file
expand all
collapse all
unified
split
slingshot
src
server.rs
+97
slingshot/src/server.rs
···
91
91
}))
92
92
}
93
93
94
94
+
fn bad_request_handler_resolve_handle(err: poem::Error) -> JustDidResponse {
95
95
+
JustDidResponse::BadRequest(Json(XrpcErrorResponseObject {
96
96
+
error: "InvalidRequest".to_string(),
97
97
+
message: format!("Bad request, here's some info that maybe should not be exposed: {err}"),
98
98
+
}))
99
99
+
}
100
100
+
94
101
#[derive(Object)]
95
102
#[oai(example = true)]
96
103
struct FoundRecordResponseObject {
···
182
189
BadRequest(XrpcError),
183
190
}
184
191
192
192
+
#[derive(Object)]
193
193
+
#[oai(example = true)]
194
194
+
struct FoundDidResponseObject {
195
195
+
/// the DID, bi-directionally verified if using Slingshot
196
196
+
did: String,
197
197
+
}
198
198
+
impl Example for FoundDidResponseObject {
199
199
+
fn example() -> Self {
200
200
+
Self { did: example_did() }
201
201
+
}
202
202
+
}
203
203
+
204
204
+
#[derive(ApiResponse)]
205
205
+
#[oai(bad_request_handler = "bad_request_handler_resolve_handle")]
206
206
+
enum JustDidResponse {
207
207
+
/// Resolution succeeded
208
208
+
#[oai(status = 200)]
209
209
+
Ok(Json<FoundDidResponseObject>),
210
210
+
/// Bad request, failed to resolve, or failed to verify
211
211
+
///
212
212
+
/// `error` will be one of `InvalidRequest`, `HandleNotFound`.
213
213
+
#[oai(status = 400)]
214
214
+
BadRequest(XrpcError),
215
215
+
/// Something went wrong trying to complete the request
216
216
+
#[oai(status = 500)]
217
217
+
ServerError(XrpcError),
218
218
+
}
219
219
+
185
220
struct Xrpc {
186
221
cache: HybridCache<String, CachedRecord>,
187
222
identity: Identity,
···
312
347
cid,
313
348
)
314
349
.await
350
350
+
}
351
351
+
352
352
+
/// com.atproto.identity.resolveHandle
353
353
+
///
354
354
+
/// Resolves an atproto [`handle`](https://atproto.com/guides/glossary#handle)
355
355
+
/// (hostname) to a [`DID`](https://atproto.com/guides/glossary#did-decentralized-id).
356
356
+
///
357
357
+
/// Compatibility note: **Slingshot will _always_ bi-directionally verify
358
358
+
/// against the DID document**, which is optional by the authoritative
359
359
+
/// lexicon. You can trust the `DID` returned from this endpoint without
360
360
+
/// further checks, but this may not hold if you switch from Slingshot to a
361
361
+
/// different service offering this query.
362
362
+
///
363
363
+
/// See also the [canonical `com.atproto` XRPC documentation](https://docs.bsky.app/docs/api/com-atproto-identity-resolve-handle)
364
364
+
/// that this endpoint aims to be compatible with.
365
365
+
#[oai(
366
366
+
path = "/com.atproto.identity.resolveHandle",
367
367
+
method = "get",
368
368
+
tag = "ApiTags::ComAtproto"
369
369
+
)]
370
370
+
async fn resolve_handle(
371
371
+
&self,
372
372
+
/// The handle to resolve.
373
373
+
#[oai(example = "example_handle")]
374
374
+
Query(handle): Query<String>,
375
375
+
) -> JustDidResponse {
376
376
+
let Ok(handle) = Handle::new(handle) else {
377
377
+
return JustDidResponse::BadRequest(xrpc_error("InvalidRequest", "not a valid handle"));
378
378
+
};
379
379
+
380
380
+
let Ok(alleged_did) = self.identity.handle_to_did(handle.clone()).await else {
381
381
+
return JustDidResponse::ServerError(xrpc_error("Failed", "Could not resolve handle"));
382
382
+
};
383
383
+
384
384
+
let Some(alleged_did) = alleged_did else {
385
385
+
return JustDidResponse::BadRequest(xrpc_error(
386
386
+
"HandleNotFound",
387
387
+
"Could not resolve handle to a DID",
388
388
+
));
389
389
+
};
390
390
+
391
391
+
let Ok(partial_doc) = self.identity.did_to_partial_mini_doc(&alleged_did).await else {
392
392
+
return JustDidResponse::ServerError(xrpc_error("Failed", "Could not fetch DID doc"));
393
393
+
};
394
394
+
395
395
+
let Some(partial_doc) = partial_doc else {
396
396
+
return JustDidResponse::BadRequest(xrpc_error(
397
397
+
"HandleNotFound",
398
398
+
"Resolved handle but could not find DID doc for the DID",
399
399
+
));
400
400
+
};
401
401
+
402
402
+
if partial_doc.unverified_handle != handle {
403
403
+
return JustDidResponse::BadRequest(xrpc_error(
404
404
+
"HandleNotFound",
405
405
+
"Resolved handle failed bi-directional validation",
406
406
+
));
407
407
+
}
408
408
+
409
409
+
JustDidResponse::Ok(Json(FoundDidResponseObject {
410
410
+
did: alleged_did.to_string(),
411
411
+
}))
315
412
}
316
413
317
414
/// com.bad-example.identity.resolveMiniDoc