8 use crate::apub::signatures::PublicKeyExtension;
10 use activitystreams::actor::{properties::ApActorProperties, Group, Person};
11 use activitystreams::ext::Ext;
12 use actix_web::body::Body;
13 use actix_web::HttpResponse;
14 use openssl::{pkey::PKey, rsa::Rsa};
17 type GroupExt = Ext<Ext<Group, ApActorProperties>, PublicKeyExtension>;
18 type PersonExt = Ext<Ext<Person, ApActorProperties>, PublicKeyExtension>;
20 static APUB_JSON_CONTENT_TYPE: &str = "application/activity+json";
22 pub enum EndpointType {
33 fn create_apub_response<T>(json: &T) -> HttpResponse<Body>
35 T: serde::ser::Serialize,
38 .content_type(APUB_JSON_CONTENT_TYPE)
42 // TODO: we will probably need to change apub endpoint urls so that html and activity+json content
43 // types are handled at the same endpoint, so that you can copy the url into mastodon search
44 // and have it fetch the object.
45 pub fn make_apub_endpoint(endpoint_type: EndpointType, name: &str) -> Url {
46 let point = match endpoint_type {
47 EndpointType::Community => "c",
48 EndpointType::User => "u",
49 EndpointType::Post => "p",
50 // TODO I have to change this else my update advanced_migrations crashes the
51 // server if a comment exists.
52 EndpointType::Comment => "comment",
56 "{}://{}/federation/{}/{}",
57 get_apub_protocol_string(),
58 Settings::get().hostname,
65 pub fn get_apub_protocol_string() -> &'static str {
66 if Settings::get().federation.tls_enabled {
73 pub fn gen_keypair() -> (Vec<u8>, Vec<u8>) {
74 let rsa = Rsa::generate(2048).expect("sign::gen_keypair: key generation error");
75 let pkey = PKey::from_rsa(rsa).expect("sign::gen_keypair: parsing error");
79 .expect("sign::gen_keypair: public key encoding error"),
81 .private_key_to_pem_pkcs8()
82 .expect("sign::gen_keypair: private key encoding error"),
86 pub fn gen_keypair_str() -> (String, String) {
87 let (public_key, private_key) = gen_keypair();
88 (vec_bytes_to_str(public_key), vec_bytes_to_str(private_key))
91 fn vec_bytes_to_str(bytes: Vec<u8>) -> String {
92 String::from_utf8_lossy(&bytes).into_owned()
95 /// If community is on local instance, don't include the @instance part. This is only for displaying
96 /// to the user and should never be used otherwise.
97 pub fn format_community_name(name: &str, instance: &str) -> String {
98 if instance == Settings::get().hostname {
101 format!("!{}@{}", name, instance)
105 pub fn get_following_instances() -> Vec<Instance> {
111 domain: i.to_string(),