1use indexmap::IndexMap;
2use serde::{Deserialize, Serialize};
3
4#[allow(clippy::large_enum_variant)]
9#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
10#[serde(tag = "type")]
11pub enum SecurityScheme {
12 #[serde(rename = "apiKey")]
13 APIKey {
14 #[serde(rename = "in")]
17 location: APIKeyLocation,
18 name: String,
20 #[serde(skip_serializing_if = "Option::is_none")]
23 description: Option<String>,
24
25 #[serde(flatten, deserialize_with = "crate::util::deserialize_extensions")]
27 extensions: IndexMap<String, serde_json::Value>,
28 },
29 #[serde(rename = "http")]
30 HTTP {
31 scheme: String,
35 #[serde(rename = "bearerFormat", skip_serializing_if = "Option::is_none")]
36 bearer_format: Option<String>,
37 #[serde(skip_serializing_if = "Option::is_none")]
40 description: Option<String>,
41
42 #[serde(flatten, deserialize_with = "crate::util::deserialize_extensions")]
44 extensions: IndexMap<String, serde_json::Value>,
45 },
46 #[serde(rename = "oauth2")]
47 OAuth2 {
48 flows: OAuth2Flows,
51 #[serde(skip_serializing_if = "Option::is_none")]
54 description: Option<String>,
55
56 #[serde(flatten, deserialize_with = "crate::util::deserialize_extensions")]
58 extensions: IndexMap<String, serde_json::Value>,
59 },
60 #[serde(rename = "openIdConnect")]
61 OpenIDConnect {
62 #[serde(rename = "openIdConnectUrl")]
65 open_id_connect_url: String,
66 #[serde(skip_serializing_if = "Option::is_none")]
69 description: Option<String>,
70
71 #[serde(flatten, deserialize_with = "crate::util::deserialize_extensions")]
73 extensions: IndexMap<String, serde_json::Value>,
74 },
75}
76
77#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
78#[serde(rename_all = "camelCase")]
79pub enum APIKeyLocation {
80 Query,
81 Header,
82 Cookie,
83}
84
85#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
86#[serde(rename_all = "camelCase")]
87pub struct OAuth2Flows {
88 #[serde(default, skip_serializing_if = "Option::is_none")]
90 pub implicit: Option<ImplicitOAuth2Flow>,
91 #[serde(default, skip_serializing_if = "Option::is_none")]
93 pub password: Option<PasswordOAuth2Flow>,
94 #[serde(default, skip_serializing_if = "Option::is_none")]
96 pub client_credentials: Option<ClientCredentialsOAuth2Flow>,
97 #[serde(default, skip_serializing_if = "Option::is_none")]
99 pub authorization_code: Option<AuthorizationCodeOAuth2Flow>,
100
101 #[serde(flatten, deserialize_with = "crate::util::deserialize_extensions")]
103 pub extensions: IndexMap<String, serde_json::Value>,
104}
105#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
106#[serde(rename_all = "camelCase")]
107pub struct ImplicitOAuth2Flow {
108 authorization_url: String,
111 #[serde(skip_serializing_if = "Option::is_none")]
114 refresh_url: Option<String>,
115 scopes: IndexMap<String, String>,
118
119 #[serde(flatten, deserialize_with = "crate::util::deserialize_extensions")]
121 pub extensions: IndexMap<String, serde_json::Value>,
122}
123
124#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
125#[serde(rename_all = "camelCase")]
126pub struct PasswordOAuth2Flow {
127 #[serde(skip_serializing_if = "Option::is_none")]
130 refresh_url: Option<String>,
131 token_url: String,
134 scopes: IndexMap<String, String>,
137
138 #[serde(flatten, deserialize_with = "crate::util::deserialize_extensions")]
140 pub extensions: IndexMap<String, serde_json::Value>,
141}
142#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
143#[serde(rename_all = "camelCase")]
144pub struct ClientCredentialsOAuth2Flow {
145 #[serde(skip_serializing_if = "Option::is_none")]
148 refresh_url: Option<String>,
149 token_url: String,
152 scopes: IndexMap<String, String>,
155
156 #[serde(flatten, deserialize_with = "crate::util::deserialize_extensions")]
158 pub extensions: IndexMap<String, serde_json::Value>,
159}
160
161#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
162#[serde(rename_all = "camelCase")]
163pub struct AuthorizationCodeOAuth2Flow {
164 authorization_url: String,
167 token_url: String,
170 #[serde(skip_serializing_if = "Option::is_none")]
173 refresh_url: Option<String>,
174 scopes: IndexMap<String, String>,
177
178 #[serde(flatten, deserialize_with = "crate::util::deserialize_extensions")]
180 pub extensions: IndexMap<String, serde_json::Value>,
181}
182
183#[cfg(test)]
184mod tests {
185 use crate::{OpenAPI, ReferenceOr, SecurityScheme};
186
187 #[test]
188 fn test_slack_auth() {
189 let openapi: OpenAPI =
190 serde_json::from_reader(std::fs::File::open("fixtures/slack.json").unwrap()).unwrap();
191
192 assert!(matches!(
193 openapi
194 .components
195 .as_ref()
196 .unwrap()
197 .security_schemes
198 .get("slackAuth")
199 .unwrap(),
200 ReferenceOr::Item(SecurityScheme::OAuth2 { .. })
201 ));
202 }
203}