[][src]Module activitystreams::ext

Defining extensibility in the ActivityStreams spec

In ActivityStreams, there are many times you may want to use an extension. For example, to interact with Mastodon, you need to at least understand the publicKey field on their actor type. If not, you won't be able to use HTTP Signatures, and will have your messages rejected.

But this library doesn't provide any of the security extensions to ActivityStreams. In order to support it, you could implment your own extensions to this library. Let's cover a basic example.

// For this example, we'll use the Extensible trait, the Extension trait, the Actor trait, and
// the Person type
use activitystreams::{
    actor::{Actor, Person},
    ext::{Extensible, Extension},
};

/// Let's define the PublicKey type. The three fields in this PublicKey struct are how Mastodon
/// represents Public Keys on actors. We'll need to derive Serialize and Deserialize for these
/// in order for them to be useful.
#[derive(Clone, Debug, Default, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct PublicKey {
    /// The ID of the key.
    ///
    /// In mastodon, this is the same as the actor's URL with a #main-key on
    /// the end.
    pub id: String,

    /// The ID of the actor who owns this key.
    pub owner: String,

    /// This is a PEM file with PKCS#8 encoded data.
    pub public_key_pem: String,
}

/// Now, we'll need more than just a PublicKey struct to make this work. We'll need to define a
/// second struct that declares the correct key to house this information inside of
///
/// The information is represented as the following json:
/// ```json
/// {
///     "publicKey": {
///         "id": "key id",
///         "owner": "actor id",
///         "publicKeyPem": "pem string"
///     }
/// }
/// ```
///
/// This means we'll need to define the 'publicKey' key
#[derive(Clone, Debug, Default, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct PublicKeyExtension {
    /// The public key's information
    pub public_key: PublicKey
}

impl PublicKey {
    /// Let's add a convenience method to turn a PublicKey into a PublicKeyExtension
    pub fn to_ext(self) -> PublicKeyExtension {
        PublicKeyExtension { public_key: self }
    }
}

// And finally, we'll implement the Extension trait for PublicKeyExtension
//
// We'll bound this extension by the Actor trait, since we don't care about non-actors having
// keys. This means that you can put a key on a `Person`, but not on a `Video`.
impl<T> Extension<T> for PublicKeyExtension where T: Actor {}

// Now that these types are defined, we can put them to use!
let person = Person::new();

// let's just create a dummy key for this example
let public_key = PublicKey {
    id: "My ID".to_owned(),
    owner: "Owner ID".to_owned(),
    public_key_pem: "My Public Key".to_owned(),
};

// We're doing it! The person is being extended with a public key
//
// Note that calling `extend` on person here is possible because the Extensible trait is in
// scope
let person_with_key = person.extend(public_key.to_ext());

Structs

Ext

Defines an extension to an activitystreams object or link

Traits

Extensible

A trait implemented (automatically) by objects and links in the ActivityStreams specification

Extension

A trait implemented by extensions to the ActivityStreams specification