sw4rm_rs/shared/
security_scheme.rs

1use std::collections::HashMap;
2use serde::{Deserialize, Serialize};
3use serde_json::Value;
4
5use crate::{
6    Spec,
7    reference::*,
8    openapi_v3_0::OAuthFlows,
9};
10
11/// Security Scheme Object
12///
13/// Defines a security scheme that can be used by the operations. Supported schemes are HTTP
14/// authentication, an API key (either as a header, a cookie parameter or as a query parameter),
15/// OAuth2's common flows (implicit, password, client credentials and authorization code) as
16/// defined in RFC6749, and OpenID Connect Discovery.
17#[derive(Debug, Serialize, Deserialize, Default, Clone, PartialEq)]
18#[serde(default, rename_all = "camelCase")]
19pub struct SecurityScheme {
20    // MARK: Common Fields
21    #[serde(rename = "type")]
22    pub scheme_type: SecuritySchemeType,
23    #[serde(skip_serializing_if = "Option::is_none")]
24    pub description: Option<String>,
25    pub name: String,
26    #[serde(rename = "in")]
27    pub location: String,
28
29    /// Allows extensions to the Swagger Schema. The field name MUST begin with x-, for example,
30    /// x-internal-id. The value can be null, a primitive, an array or an object. See Vendor
31    /// Extensions for further details.
32    #[serde(flatten, skip_serializing_if = "HashMap::is_empty")]
33    pub x_fields: HashMap<String, Value>,
34
35    // MARK: OpenAPI v2 Fields
36
37    #[serde(skip_serializing_if = "Option::is_none")]
38    pub flow: Option<String>,
39    #[serde(skip_serializing_if = "Option::is_none")]
40    pub authorization_url: Option<String>,
41    #[serde(skip_serializing_if = "Option::is_none")]
42    pub token_url: Option<String>,
43    #[serde(skip_serializing_if = "HashMap::is_empty")]
44    pub scopes: HashMap<String, String>,
45
46    // MARK: OpenAPI v3 Fields
47
48    #[serde(skip_serializing_if = "Option::is_none")]
49    pub scheme: Option<String>,
50    #[serde(skip_serializing_if = "Option::is_none")]
51    pub bearer_format: Option<String>,
52    #[serde(skip_serializing_if = "Option::is_none")]
53    pub flows: Option<OAuthFlows>,
54    #[serde(skip_serializing_if = "Option::is_none")]
55    pub open_id_connect_url: Option<String>,
56}
57impl Resolvable for SecurityScheme {
58    fn resolve(spec: &Spec, path: &String) -> Result<Self, ResolveError> {
59        let path = path.clone();
60        let reference: Reference = path.clone().try_into().unwrap();
61
62        match reference.kind {
63            ReferenceType::SecurityScheme => {
64                if spec.semver_check("=2") {
65                    spec.security_definitions.get(&reference.name)
66                        .ok_or_else(|| ResolveError::UnknownPathError(path))
67                        .and_then(|t| t.resolve(spec))
68                } else {
69                    spec.components
70                        .as_ref()
71                        .ok_or_else(|| ResolveError::UnknownPathError(path.clone()))
72                        .and_then(|c| c.security_schemes.get(&reference.name).ok_or_else(|| ResolveError::UnknownPathError(path)))
73                        .and_then(|p| p.resolve(spec))
74                }
75            },
76            _ => Err(ResolveError::UnknownPathError(path)),
77        }
78    }
79}
80
81#[derive(Debug, Serialize, Deserialize, Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
82#[serde(rename_all = "camelCase")]
83pub enum SecuritySchemeType {
84    ApiKey,
85    Http,
86    OAuth2,
87    OpenIdConnect,
88}
89impl Default for SecuritySchemeType {
90    fn default() -> Self { Self::ApiKey }
91}