ocm-types 0.2.1

Types required to implement the OpenCloudMesh filesharing protocol
Documentation
// SPDX-FileCopyrightText: 2026 Matthias Kraus <info@opengeomesh.org>
//
// SPDX-License-Identifier: LGPL-3.0-or-later

mod protocols;

pub use protocols::*;

use serde::{Deserialize, Serialize};

use crate::common::{OcmAddress, ShareType};

#[derive(Debug, PartialEq, Eq, Default, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct NewShare {
    /// Consumer specific identifier of the user, group or federation the provider
    /// wants to share the resource with. This is known in advance.
    /// Please note that the consumer service endpoint is known in advance
    /// as well, so this is no part of the request body.
    /// example: 51dc30ddc473d43a6011e9ebba6ca770@geant.org
    pub share_with: OcmAddress,
    /// Name of the resource (file or folder).
    /// example: resource.txt
    pub name: String,
    /// Optional description of the resource (file or folder).
    #[serde(skip_serializing_if = "Option::is_none", default)]
    pub description: Option<String>,
    /// Identifier to identify the shared resource at the provider side.
    /// This is unique per provider such that if the same resource is shared twice,
    /// this providerId will not be repeated.
    ///
    /// example: 7c084226-d9a1-11e6-bf26-cec0c932ce01
    pub provider_id: String,
    /// Provider specific identifier of the user who owns the resource.
    ///
    /// example: 6358b71804dfa8ab069cf05ed1b0ed2a@apiwise.nl
    pub owner: OcmAddress,
    /// Provider specific identifier of the user that wants to share the
    /// resource. Please note that the requesting provider is being
    /// identified on a higher level, so the former `remote` property
    /// is not part of the request body.
    ///
    /// example: 527bd5b5d689e2c32ae974c6229ff785@apiwise.nl
    pub sender: OcmAddress,
    /// Display name of the owner of the resource
    /// example: Dimitri
    #[serde(skip_serializing_if = "Option::is_none", default)]
    pub owner_display_name: Option<String>,
    /// Display name of the user that wants to share the resource
    /// example: John Doe
    #[serde(skip_serializing_if = "Option::is_none", default)]
    pub sender_display_name: Option<String>,
    /// Recipient share type
    pub share_type: ShareType,
    /// Resource type (file, calendar, contact, ...)
    /// example: file
    pub resource_type: String,
    /// The expiration time for the share, in seconds of UTC time since
    /// Unix epoch. If omitted, it is assumed that the share does not expire.
    #[serde(skip_serializing_if = "Option::is_none", default)]
    pub expiration: Option<i64>,
    pub protocol: Protocol,
}

/// The Sending Server
/// * holds the Resource ("file server" or "Entreprise File Sync and Share (EFSS) server" role), provides access to it (by exposing at least one "API"),
/// * takes the decision to create the Share based on user interface gestures from the Sending Party (the "Authorization Server" role in OAuth)
/// * takes the decision about authorizing attempts to access the Resource (the "Resource Server" role in OAuth)
/// * sends out Share Creation Notifications when appropriate
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct SendingServer(String);

impl NewShare {
    /// Get the Sending Server from the sender of the share.
    pub fn sending_server(&self) -> SendingServer {
        SendingServer(self.owner.get_server_url().into())
    }
}

impl<T: Into<String>> From<T> for SendingServer {
    fn from(value: T) -> Self {
        // FIXME make sure this is a fqdn
        Self(value.into())
    }
}
impl AsRef<str> for SendingServer {
    fn as_ref(&self) -> &str {
        &self.0
    }
}

/// Consumer successfully received the share. The response might contain
/// the display name of the recipient of the share for general user
/// experience improvement.
#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ShareCreationResponse {
    /// display name of the recipient
    /// example: John Doe
    pub recipient_display_name: Option<String>,
    /// The public key(s) of the recipient. This value MUST be provided
    /// in case the Share Creation Notification includes the `ssh` protocol.
    #[serde(skip_serializing_if = "Vec::is_empty", default)]
    pub recipient_public_keys: Vec<String>
}