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")] 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", format = "application/xml")] fn host_meta() -> String { format!(r#" "#, url = ap_url(format!("{domain}/.well-known/webfinger?resource={{uri}}", domain = BASE_URL.as_str()))) } #[derive(FromForm)] struct WebfingerQuery { resource: String } struct WebfingerResolver; impl Resolver for WebfingerResolver { fn instance_domain<'a>() -> &'a str { BASE_URL.as_str() } fn find(acct: String, conn: DbConn) -> Result { match User::find_local(&*conn, acct.clone()) { Some(usr) => Ok(usr.webfinger(&*conn)), None => match Blog::find_local(&*conn, acct) { Some(blog) => Ok(blog.webfinger(&*conn)), None => Err(ResolverError::NotFound) } } } } #[get("/.well-known/webfinger?")] fn webfinger(query: WebfingerQuery, conn: DbConn) -> Content { match WebfingerResolver::endpoint(query.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" })) } }