Skip to main content

forge_ir/
security.rs

1//! Security schemes and requirements.
2
3use serde::{Deserialize, Serialize};
4
5use crate::value::ValueRef;
6
7#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
8pub struct SecurityScheme {
9    pub id: String,
10    pub kind: SecuritySchemeKind,
11    /// OAS §4.27 `description` (CommonMark).
12    #[serde(default, skip_serializing_if = "Option::is_none")]
13    pub description: Option<String>,
14    /// OAS 3.2 §4.27 `deprecated` flag. Generators should surface this
15    /// as a deprecation hint so consumers migrate off the scheme.
16    #[serde(default, skip_serializing_if = "crate::is_false")]
17    pub deprecated: bool,
18    /// `x-*` extensions declared on the security scheme object. Compound
19    /// extensions drop with `parser/W-EXTENSION-DROPPED`.
20    #[serde(default, skip_serializing_if = "Vec::is_empty")]
21    pub extensions: Vec<(String, ValueRef)>,
22}
23
24#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
25#[serde(tag = "type", rename_all = "kebab-case")]
26pub enum SecuritySchemeKind {
27    ApiKey(ApiKeyScheme),
28    HttpBasic,
29    HttpBearer {
30        #[serde(default, skip_serializing_if = "Option::is_none")]
31        bearer_format: Option<String>,
32    },
33    /// OAS 3.0+ `mutualTLS` — client-cert auth (mTLS). The IR carries
34    /// the declaration; certificate provisioning is out of scope and
35    /// left to the consumer's transport configuration.
36    MutualTls,
37    Oauth2(OAuth2Scheme),
38    OpenIdConnect {
39        url: String,
40    },
41}
42
43#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
44pub struct ApiKeyScheme {
45    pub name: String,
46    pub location: ApiKeyLocation,
47}
48
49#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
50#[serde(rename_all = "kebab-case")]
51pub enum ApiKeyLocation {
52    Header,
53    Query,
54    Cookie,
55}
56
57#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
58pub struct OAuth2Scheme {
59    pub flows: Vec<OAuth2Flow>,
60}
61
62#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
63pub struct OAuth2Flow {
64    pub kind: OAuth2FlowKind,
65    #[serde(default, skip_serializing_if = "Option::is_none")]
66    pub authorization_url: Option<String>,
67    #[serde(default, skip_serializing_if = "Option::is_none")]
68    pub token_url: Option<String>,
69    #[serde(default, skip_serializing_if = "Option::is_none")]
70    pub refresh_url: Option<String>,
71    #[serde(default, skip_serializing_if = "Vec::is_empty")]
72    pub scopes: Vec<(String, String)>,
73    /// `x-*` extensions declared on the OAuth2 flow object. Compound
74    /// extensions drop with `parser/W-EXTENSION-DROPPED`.
75    #[serde(default, skip_serializing_if = "Vec::is_empty")]
76    pub extensions: Vec<(String, ValueRef)>,
77}
78
79#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
80#[serde(rename_all = "kebab-case")]
81pub enum OAuth2FlowKind {
82    Implicit,
83    Password,
84    ClientCredentials,
85    AuthorizationCode,
86}
87
88#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
89pub struct SecurityRequirement {
90    pub scheme_id: String,
91    #[serde(default, skip_serializing_if = "Vec::is_empty")]
92    pub scopes: Vec<String>,
93}