Skip to main content

ocm_types/share/protocols/
mod.rs

1// SPDX-FileCopyrightText: 2026 Matthias Kraus <info@opengeomesh.org>
2//
3// SPDX-License-Identifier: LGPL-3.0-or-later
4
5//! Protocol Properties for access protocols specified within OpenCloudMesh
6//! The Protocol Properties are used in [crate::shares::NewShare] to inform the Receiving Server
7//! about how to access a shared Resource.
8
9mod ssh;
10mod webapp;
11mod webdav;
12pub use ssh::*;
13pub use webapp::*;
14pub use webdav::*;
15
16use std::collections::HashMap;
17
18use serde::{Deserialize, Serialize};
19use serde_json::{Map, Value};
20
21/// JSON object with specific options for each protocol.
22///
23/// The supported protocols are:
24/// - `webdav`, to access the data
25/// - `webapp`, to access remote web applications
26/// - `ssh`, to access the data via SFTP/SCP
27///
28/// Other custom protocols might be added in the future.
29///
30/// # Single Protocol Legacy
31/// ```
32/// use ocm_types::share::Protocol;
33/// use serde_json::Map;
34/// use serde_json::Value;
35/// use serde_json::json;
36///
37/// #[allow(deprecated)]
38/// let single_protocol_legacy = Protocol{
39///     name: "webdav".to_string(),
40///     options: Some(Map::from_iter(vec![
41///         ("sharedSecret".to_string(), Value::String("hfiuhworzwnur98d3wjiwhr".to_string())),
42///         ("permissions".to_string(), Value::String("some permissions scheme".to_string())),
43///     ].into_iter())),
44///     ..Default::default()
45/// };
46/// let json: Value = serde_json::from_str(r#"{
47///     "name": "webdav",
48///     "options": {
49///         "sharedSecret": "hfiuhworzwnur98d3wjiwhr",
50///         "permissions": "some permissions scheme"
51///     }
52/// }"#).unwrap();
53/// assert_eq!(json!(single_protocol_legacy), json);
54/// ```
55///
56/// # Single Protocol New
57/// ```
58/// use ocm_types::share::Protocol;
59/// use ocm_types::share::WebDavProperties;
60/// use ocm_types::share::WebDavPermissions;
61/// use ocm_types::share::AccessType;
62/// use std::collections::HashMap;
63/// use serde_json::Value;
64/// use serde_json::json;
65/// use serde::de::Deserialize;
66///
67/// let single_protocol_new = Protocol{
68///     name: "multi".to_string(),
69///     webdav: Some(WebDavProperties{
70///         access_types: vec![AccessType::Remote],
71///         uri: "7c084226-d9a1-11e6-bf26-cec0c932ce01".to_string(),
72///         shared_secret: Some("hfiuhworzwnur98d3wjiwhr".to_string()),
73///         refresh_token: None,
74///         permissions: vec![
75///             WebDavPermissions::Read,
76///             WebDavPermissions::Write,
77///         ],
78///         requirements: vec![]
79///     }),
80///     ..Default::default()
81/// };
82/// let json: Value = serde_json::from_str(r#"{
83///     "name": "multi",
84///     "webdav": {
85///         "accessTypes": ["remote"],
86///         "uri": "7c084226-d9a1-11e6-bf26-cec0c932ce01",
87///         "sharedSecret": "hfiuhworzwnur98d3wjiwhr",
88///         "permissions": ["read", "write"]
89///     }
90/// }"#).unwrap();
91/// assert_eq!(json!(single_protocol_new), json);
92/// ```
93///
94/// # Multi Protocol
95/// ```
96/// use ocm_types::share::Protocol;
97/// use ocm_types::share::WebDavProperties;
98/// use ocm_types::share::WebDavPermissions;
99/// use ocm_types::share::WebDavRequirements;
100/// use ocm_types::share::WebAppProperties;
101/// use ocm_types::share::WebAppViewMode;
102/// use ocm_types::share::SshProperties;
103/// use ocm_types::share::AccessType;
104/// use std::collections::HashMap;
105/// use serde_json::Value;
106/// use serde_json::json;
107///
108/// let single_protocol_new = Protocol{
109///     name: "multi".to_string(),
110///     webdav: Some(WebDavProperties{
111///         access_types: vec![AccessType::Remote],
112///         uri: "7c084226-d9a1-11e6-bf26-cec0c932ce01".to_string(),
113///         shared_secret: Some("hfiuhworzwnur98d3wjiwhr".to_string()),
114///         refresh_token: None,
115///         permissions: vec![
116///             WebDavPermissions::Read,
117///             WebDavPermissions::Write
118///         ],
119///         requirements: vec![
120///             WebDavRequirements::MustUseMfa
121///         ]
122///     }),
123///     webapp: Some(WebAppProperties{
124///         uri: "7c084226-d9a1-11e6-bf26-cec0c932ce01".to_string(),
125///         shared_secret: Some("hfiuhworzwnur98d3wjiwhr".to_string()),
126///         view_mode: WebAppViewMode::Read
127///     }),
128///     ssh: Some(SshProperties{
129///         access_types: vec![AccessType::DataTx],
130///         uri: "extuser@cloud.example.org:/7c084226-d9a1-11e6-bf26-cec0c932ce01".to_string()
131///     }),
132///     additional_protocols: HashMap::from_iter(vec![
133///         (
134///             "datatx".to_string(), 
135///             json!({
136///                 "srcUri": "7c084226-d9a1-11e6-bf26-cec0c932ce01",
137///                 "sharedSecret": "hfiuhworzwnur98d3wjiwhr",
138///                 "size": 100000
139///             })
140///         )
141///     ].into_iter()),
142///     ..Default::default()
143/// };
144/// let json: Value = serde_json::from_str(r#"{
145///     "name": "multi",
146///     "webdav": {
147///         "accessTypes": ["remote"],
148///         "uri": "7c084226-d9a1-11e6-bf26-cec0c932ce01",
149///         "sharedSecret": "hfiuhworzwnur98d3wjiwhr",
150///         "permissions": ["read", "write"],
151///         "requirements": ["must-use-mfa"]
152///     },
153///     "webapp": {
154///       "uri": "7c084226-d9a1-11e6-bf26-cec0c932ce01",
155///       "sharedSecret": "hfiuhworzwnur98d3wjiwhr",
156///       "viewMode": "read"
157///     },
158///     "datatx": {
159///      "srcUri": "7c084226-d9a1-11e6-bf26-cec0c932ce01",
160///      "sharedSecret": "hfiuhworzwnur98d3wjiwhr",
161///      "size": 100000
162///     },
163///     "ssh": {
164///         "accessTypes": ["datatx"],
165///         "uri": "extuser@cloud.example.org:/7c084226-d9a1-11e6-bf26-cec0c932ce01"
166///     }
167/// }"#).unwrap();
168/// assert_eq!(json!(single_protocol_new), json);
169/// ```
170///
171/// # WebDAV with refreshToken
172/// ```
173/// # use ocm_types::share::Protocol;
174/// # use ocm_types::share::AccessType;
175/// # use ocm_types::share::WebDavProperties;
176/// # use ocm_types::share::WebDavPermissions;
177/// # use ocm_types::share::WebDavRequirements;
178/// # use ocm_types::share::WebAppProperties;
179/// # use ocm_types::share::WebAppViewMode;
180/// # use std::collections::HashMap;
181/// # use serde_json::Value;
182/// # use serde_json::json;
183///
184/// let webdav_refresh_token = Protocol{
185///     name: "multi".to_string(),
186///     webdav: Some(WebDavProperties{
187///         access_types: vec![AccessType::Remote],
188///         uri: "7c084226-d9a1-11e6-bf26-cec0c932ce01".to_string(),
189///         shared_secret: None,
190///         refresh_token: Some("hfiuhworzwnur98d3wjiwhr".to_string()),
191///         permissions: vec![
192///             WebDavPermissions::Read,
193///             WebDavPermissions::Write
194///         ],
195///         requirements: vec![
196///             WebDavRequirements::MustUseMfa,
197///             WebDavRequirements::MustExchangeToken
198///         ]
199///     }),
200///     webapp: Some(WebAppProperties{
201///         uri: "7c084226-d9a1-11e6-bf26-cec0c932ce01".to_string(),
202///         shared_secret: Some("hfiuhworzwnur98d3wjiwhr".to_string()),
203///         view_mode: WebAppViewMode::Read
204///     }),
205///     additional_protocols: HashMap::from_iter(vec![
206///         (
207///             "datatx".to_string(), 
208///             json!({
209///                 "srcUri": "7c084226-d9a1-11e6-bf26-cec0c932ce01",
210///                 "sharedSecret": "hfiuhworzwnur98d3wjiwhr",
211///                 "size": 100000
212///             })
213///         )
214///     ].into_iter()),
215///     ..Default::default()
216/// };
217/// let json: Value = serde_json::from_str(r#"{
218///     "name": "multi",
219///     "webdav": {
220///         "accessTypes": ["remote"],
221///         "uri": "7c084226-d9a1-11e6-bf26-cec0c932ce01",
222///         "refreshToken": "hfiuhworzwnur98d3wjiwhr",
223///         "permissions": ["read", "write"],
224///         "requirements": ["must-use-mfa", "must-exchange-token"]
225///     },
226///     "webapp": {
227///       "uri": "7c084226-d9a1-11e6-bf26-cec0c932ce01",
228///       "sharedSecret": "hfiuhworzwnur98d3wjiwhr",
229///       "viewMode": "read"
230///     },
231///     "datatx": {
232///      "srcUri": "7c084226-d9a1-11e6-bf26-cec0c932ce01",
233///      "sharedSecret": "hfiuhworzwnur98d3wjiwhr",
234///      "size": 100000
235///     }
236/// }"#).unwrap();
237/// assert_eq!(json!(webdav_refresh_token), json);
238/// ```
239// example:
240//   multipleProtocols:
241//     name: multi
242//     webapp:
243//       uri: 7c084226-d9a1-11e6-bf26-cec0c932ce01
244//       sharedSecret: hfiuhworzwnur98d3wjiwhr
245//       viewMode: read
246//     datatx:
247//       srcUri: 7c084226-d9a1-11e6-bf26-cec0c932ce01
248//       sharedSecret: hfiuhworzwnur98d3wjiwhr
249//       size: 100000
250#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize)]
251#[serde(rename_all = "camelCase")]
252pub struct Protocol {
253    /// The name of the protocol. Default: `multi`.
254    /// If `multi` is given, one or more protocol endpoints are expected
255    /// to be defined according to the optional properties specified below.
256    /// Otherwise, at least `webdav` is expected to be supported, and
257    /// its options MAY be given in the opaque `options` payload for
258    /// compatibility with v1.0 implementations (see examples). Note
259    /// though that this format is deprecated.
260    /// Warning: client implementers should be aware that v1.1 servers
261    /// MAY support both `webdav` and `multi`, but v1.0 servers MAY
262    /// only support `webdav`.
263    /// This field may be removed in a future major version of the spec.
264    pub name: String,
265    /// This property is now deprecated. Implementations are
266    /// encouraged to transition to the new optional properties
267    /// defined below, such that this field may be removed in a future major
268    /// version of the spec.
269    #[deprecated]
270    #[serde(skip_serializing_if = "Option::is_none", default)]
271    pub options: Option<Map<String, Value>>,
272    #[serde(skip_serializing_if = "Option::is_none", default)]
273    pub webdav: Option<WebDavProperties>,
274    #[serde(skip_serializing_if = "Option::is_none", default)]
275    pub webapp: Option<WebAppProperties>,
276    #[serde(skip_serializing_if = "Option::is_none", default)]
277    pub ssh: Option<SshProperties>,
278    /// Any optional additional protocols supported for this resource
279    /// MAY
280    /// be provided here, along with their custom payload. Appropriate
281    /// capabilities MUST be advertised in order for a sender to ensure
282    /// the recipient can parse such customized payloads.
283    #[serde(skip_serializing_if = "HashMap::is_empty", default)]
284    #[serde(flatten)]
285    pub additional_protocols: HashMap<String, Value>,
286}
287
288#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
289#[serde(rename_all = "lowercase")]
290pub enum AccessType {
291    /// signals the recipient that the resource is available
292    /// for remote access and interactive browsing.
293    Remote,
294    /// signals the recipient to transfer the resource
295    /// from the given URI. The recipient MAY delegate a third-party
296    /// service to execute the data transfer on their behalf.
297    DataTx,
298}
299
300fn default_access_types() -> Vec<AccessType> {
301    vec![AccessType::Remote]
302}