use rocket::http::ContentType; use rocket::response::Content; use serde_json; use webfinger::*; use plume_models::{BASE_URL, ap_url, db_conn::DbConn, blogs::Blog, users::User}; #[get("/.well-known/nodeinfo")] pub fn nodeinfo() -> Content { Content(ContentType::new("application", "jrd+json"), json!({ "links": [ { "rel": "http://nodeinfo.diaspora.software/ns/schema/2.0", "href": ap_url(&format!("{domain}/nodeinfo", domain = BASE_URL.as_str())) } ] }).to_string()) } #[get("/.well-known/host-meta")] pub fn host_meta() -> String { format!(r#" "#, url = ap_url(&format!("{domain}/.well-known/webfinger?resource={{uri}}", domain = BASE_URL.as_str()))) } struct WebfingerResolver; impl Resolver for WebfingerResolver { fn instance_domain<'a>() -> &'a str { BASE_URL.as_str() } fn find(acct: String, conn: DbConn) -> Result { User::find_local(&*conn, &acct) .and_then(|usr| usr.webfinger(&*conn)) .or_else(|_| Blog::find_local(&*conn, &acct) .and_then(|blog| blog.webfinger(&*conn)) .or(Err(ResolverError::NotFound))) } } #[get("/.well-known/webfinger?")] pub fn webfinger(resource: String, conn: DbConn) -> Content { match WebfingerResolver::endpoint(resource, conn).and_then(|wf| serde_json::to_string(&wf).map_err(|_| ResolverError::NotFound)) { Ok(wf) => Content(ContentType::new("application", "jrd+json"), wf), Err(err) => Content(ContentType::new("text", "plain"), String::from(match err { ResolverError::InvalidResource => "Invalid resource. Make sure to request an acct: URI", ResolverError::NotFound => "Requested resource was not found", ResolverError::WrongInstance => "This is not the instance of the requested resource" })) } }