resolve did:web users
parent
c9e4db5f91
commit
28ecfd6851
78
src/user.rs
78
src/user.rs
|
@ -22,6 +22,28 @@ pub struct User {
|
||||||
pub handle: Option<String>,
|
pub handle: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn create_user_from_did_doc(did_doc: DidDocument) -> Result<User> {
|
||||||
|
let pds_endpoint = did_doc.get_pds_endpoint();
|
||||||
|
let pds_uri: Option<Uri> = pds_endpoint.as_deref().unwrap_or_default().parse().ok();
|
||||||
|
let pds = pds_uri
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|u| u.authority())
|
||||||
|
.map(|a| a.host())
|
||||||
|
.map(|s| s.to_string());
|
||||||
|
|
||||||
|
let handle = did_doc
|
||||||
|
.also_known_as
|
||||||
|
.and_then(|v| v.into_iter().next())
|
||||||
|
.and_then(|s| s.strip_prefix("at://").map(str::to_string));
|
||||||
|
let did = did_doc.id;
|
||||||
|
|
||||||
|
// TODO: check if handle resolves to did and fill none otherwise
|
||||||
|
|
||||||
|
let user = User { pds, did, handle };
|
||||||
|
|
||||||
|
Ok(user)
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn fetch_user(server: &RelayServer, did: &str) -> Result<User> {
|
pub async fn fetch_user(server: &RelayServer, did: &str) -> Result<User> {
|
||||||
tracing::debug!(%did, "fetching user");
|
tracing::debug!(%did, "fetching user");
|
||||||
if did.starts_with("did:plc:") {
|
if did.starts_with("did:plc:") {
|
||||||
|
@ -58,29 +80,45 @@ pub async fn fetch_user(server: &RelayServer, did: &str) -> Result<User> {
|
||||||
let did_doc = serde_json::from_reader::<_, DidDocument>(body.reader())
|
let did_doc = serde_json::from_reader::<_, DidDocument>(body.reader())
|
||||||
.context("Failed to parse plc DID doc as JSON")?;
|
.context("Failed to parse plc DID doc as JSON")?;
|
||||||
|
|
||||||
let pds_endpoint = did_doc.get_pds_endpoint();
|
let user = create_user_from_did_doc(did_doc)?;
|
||||||
let pds_uri: Option<Uri> = pds_endpoint.as_deref().unwrap_or_default().parse().ok();
|
store_user(server, &user)?;
|
||||||
let pds = pds_uri
|
|
||||||
.as_ref()
|
Ok(user)
|
||||||
.and_then(|u| u.authority())
|
} else if let Some(domain) = did.strip_prefix("did:web:") {
|
||||||
.map(|a| a.host())
|
let tcp_stream = TcpStream::connect((domain, 443)).await?;
|
||||||
.map(|s| s.to_string());
|
let domain_tls: ServerName<'_> = ServerName::try_from(domain.to_string())?;
|
||||||
|
let tls_stream = open_tls_stream(tcp_stream, domain_tls).await?;
|
||||||
let handle = did_doc
|
let io = TokioIo::new(tls_stream);
|
||||||
.also_known_as
|
|
||||||
.and_then(|v| v.into_iter().next())
|
let req = Request::builder()
|
||||||
.and_then(|s| s.strip_prefix("at://").map(str::to_string));
|
.method("GET")
|
||||||
let did = did_doc.id;
|
.uri(format!("https://{domain}/.well-known/did.json"))
|
||||||
|
.header("Host", domain.to_string())
|
||||||
// TODO: check if handle resolves to did and fill none otherwise
|
.body(body_empty())?;
|
||||||
|
|
||||||
let user = User { pds, did, handle };
|
let (mut sender, conn) = http1::handshake::<_, HttpBody>(io).await?;
|
||||||
|
tokio::task::spawn(async move {
|
||||||
|
if let Err(err) = conn.await {
|
||||||
|
println!("Connection failed: {:?}", err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let res = sender
|
||||||
|
.send_request(req)
|
||||||
|
.await
|
||||||
|
.context("Failed to send plc request")?;
|
||||||
|
if res.status() != StatusCode::OK {
|
||||||
|
bail!("server returned non-200 status for did:web document");
|
||||||
|
}
|
||||||
|
|
||||||
|
let body = res.collect().await?.aggregate();
|
||||||
|
let did_doc = serde_json::from_reader::<_, DidDocument>(body.reader())
|
||||||
|
.context("Failed to parse did:web document as JSON")?;
|
||||||
|
|
||||||
|
let user = create_user_from_did_doc(did_doc)?;
|
||||||
store_user(server, &user)?;
|
store_user(server, &user)?;
|
||||||
|
|
||||||
Ok(user)
|
Ok(user)
|
||||||
} else if did.starts_with("did:web:") {
|
|
||||||
todo!("resolve did web")
|
|
||||||
} else {
|
} else {
|
||||||
bail!("unknown did type {did}");
|
bail!("unknown did type {did}");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue