Skip to main content

kynos_openapi/model/security/
requirement.rs

1//! The Security Requirement Object.
2
3use serde::{Deserialize, Serialize};
4
5use crate::Map;
6
7/// The security schemes that must be satisfied to invoke an operation.
8///
9/// Each key names a scheme in
10/// [`Components::security_schemes`](crate::Components::security_schemes); the
11/// value lists the required scopes, which is meaningful only for `oauth2` and
12/// `openIdConnect`. All entries in one requirement must be satisfied together;
13/// a list of requirements is satisfied when any one of them is.
14///
15/// An empty requirement means anonymous access is permitted.
16///
17/// This object carries no extensions: the specification does not permit them.
18#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
19#[serde(transparent)]
20pub struct SecurityRequirement(pub Map<Vec<String>>);
21
22impl SecurityRequirement {
23    /// Creates a requirement permitting anonymous access.
24    #[must_use]
25    pub fn anonymous() -> Self {
26        Self(Map::new())
27    }
28
29    /// Requires a scheme that takes no scopes.
30    pub fn scheme(name: impl Into<String>) -> Self {
31        let mut map = Map::new();
32        map.insert(name.into(), Vec::new());
33        Self(map)
34    }
35
36    /// Requires a scheme together with a set of scopes.
37    pub fn scoped(
38        name: impl Into<String>,
39        scopes: impl IntoIterator<Item = impl Into<String>>,
40    ) -> Self {
41        let mut map = Map::new();
42        map.insert(name.into(), scopes.into_iter().map(Into::into).collect());
43        Self(map)
44    }
45
46    /// Adds another scheme that must be satisfied alongside the existing ones.
47    #[must_use]
48    pub fn and(
49        mut self,
50        name: impl Into<String>,
51        scopes: impl IntoIterator<Item = impl Into<String>>,
52    ) -> Self {
53        self.0
54            .insert(name.into(), scopes.into_iter().map(Into::into).collect());
55        self
56    }
57
58    /// Returns `true` when this requirement permits anonymous access.
59    #[must_use]
60    pub fn is_anonymous(&self) -> bool {
61        self.0.is_empty()
62    }
63}