gantry-protocol 0.0.7

Protocol message primitives for the Gantry protocol
Documentation
//! # Gantry catalog protocol
//!
//! This module contains data types and traits for use with Gantry's catalog
//! functionality. Gantry supports the following catalog operations:
//! * `put` - Adds a token to the catalog
//! * `query` - Queries the catalog
//! * `delete` - Takes an entity out of service from the catalog. This will mark the entity as removed/unavailable but will not erase the entry.
//! * `get` - Obtain details on a given entity

use std::fmt::Display;

pub static SUBJECT_CATALOG_PUT_TOKEN: &str = "gantry.catalog.tokens.put";
pub static SUBJECT_CATALOG_DELETE_TOKEN: &str = "gantry.catalog.tokens.delete";
pub static SUBJECT_CATALOG_QUERY: &str = "gantry.catalog.tokens.query";
pub static SUBJECT_CATALOG_GET: &str = "gantry.catalog.tokens.get";

/// A token contains the raw string for a JWT signed with the ed25519 signature
/// format. Actors, Accounts, Operators are all identified by tokens
#[derive(Debug, PartialEq, Deserialize, Serialize)]
pub struct Token {
    pub raw_token: String,
    pub decoded_token_json: String,
    pub validation_result: Option<TokenValidation>,
}

/// A protocol-specific message version of the validation result that the wascap
/// library provides
#[derive(Debug, PartialEq, Deserialize, Serialize)]
pub struct TokenValidation {
    pub expired: bool,
    pub expires_human: String,
    pub not_before_human: String,
    pub cannot_use_yet: bool,
    pub signature_valid: bool,
}

#[derive(Debug, PartialEq, Deserialize, Serialize)]
pub struct CatalogQuery {
    pub query_type: QueryType,
    pub issuer: Option<String>,
}

#[derive(Debug, PartialEq, Deserialize, Serialize)]
pub struct CatalogQueryResults {
    pub results: Vec<CatalogQueryResult>,
}

#[derive(Debug, PartialEq, Deserialize, Serialize)]
pub struct CatalogQueryResult {
    pub subject: String,
    pub issuer: String,
    pub issuer_name: String,
    pub name: String,
}

#[derive(Debug, PartialEq, Deserialize, Serialize)]
pub enum QueryType {
    Actor,
    Account,
    Operator,
}

#[derive(Debug, PartialEq, Deserialize, Serialize)]
pub enum PutTokenResponse {
    Success {
        subject: String,
        issuer_name: String,
        issuer_id: String,
    },
    Failure(String),
}

#[derive(Debug, PartialEq, Deserialize, Serialize)]
pub enum TokenDetail {
    Account {
        name: String,
        jwt: String,
        issuer_id: String,
        issuer_name: String,
        signing_keys: Vec<String>,
    },
    Operator {
        name: String,
        jwt: String,
        signing_keys: Vec<String>,
    },
    Actor {
        issuer_id: String,
        issuer_name: String,
        name: String,
        jwt: String,
        revisions: Vec<ActorRevision>,
    },
}

impl TokenDetail {
    fn render_account(
        f: &mut std::fmt::Formatter<'_>,
        name: &str,
        _jwt: &str,
        issuer_id: &str,
        issuer_name: &str,
        signing_keys: &Vec<String>,
    ) -> std::fmt::Result {
        write!(
            f,
            "Account: {}\nIssuer: {} ({})\nSigning Keys: {}",
            name,
            issuer_id,
            issuer_name,
            signing_keys.join(",")
        )
    }

    fn render_operator(
        f: &mut std::fmt::Formatter<'_>,
        name: &str,
        _jwt: &str,
        signing_keys: &Vec<String>,
    ) -> std::fmt::Result {
        write!(
            f,
            "Operator: {}\nSigning Keys: {}",
            name,
            signing_keys.join(",")
        )
    }

    fn render_actor(
        f: &mut std::fmt::Formatter<'_>,
        issuer_id: &str,
        issuer_name: &str,
        name: &str,
        _jwt: &str,
        revisions: &Vec<ActorRevision>,
    ) -> std::fmt::Result {
        write!(
            f,
            "Actor: {}\nIssuer: {} ({})\nRevisions: {}",
            name,
            issuer_id,
            issuer_name,
            revisions
                .iter()
                .map(|r| format!("{} ({})", r.version, r.revision))
                .collect::<Vec<_>>()
                .join("\n")
        )
    }
}

impl Display for TokenDetail {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            TokenDetail::Account {
                name,
                jwt,
                issuer_id,
                issuer_name,
                signing_keys,
            } => Self::render_account(f, name, jwt, issuer_id, issuer_name, signing_keys),
            TokenDetail::Operator {
                name,
                jwt,
                signing_keys,
            } => Self::render_operator(f, name, jwt, signing_keys),
            TokenDetail::Actor {
                issuer_id,
                issuer_name,
                name,
                jwt,
                revisions,
            } => Self::render_actor(f, issuer_id, issuer_name, name, jwt, revisions),
        }
    }
}

#[derive(Debug, PartialEq, Deserialize, Serialize)]
pub struct ActorRevision {
    pub revision: u32,
    pub version: String,
}