use serde::{Deserialize, Serialize};
use crate::errors::ParseEnumError;
use std::collections::HashMap;
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum SecurityScheme {
#[serde(rename = "apiKeySecurityScheme")]
ApiKey(ApiKeySecurityScheme),
#[serde(rename = "httpAuthSecurityScheme")]
HttpAuth(HttpAuthSecurityScheme),
#[serde(rename = "oauth2SecurityScheme")]
OAuth2(OAuth2SecurityScheme),
#[serde(rename = "openIdConnectSecurityScheme")]
OpenIdConnect(OpenIdConnectSecurityScheme),
#[serde(rename = "mtlsSecurityScheme")]
MutualTls(MutualTlsSecurityScheme),
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct ApiKeySecurityScheme {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
pub location: ApiKeyLocation,
pub name: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct HttpAuthSecurityScheme {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
pub scheme: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub bearer_format: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct OAuth2SecurityScheme {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
pub flows: OAuthFlows,
#[serde(
default,
rename = "oauth2MetadataUrl",
skip_serializing_if = "Option::is_none"
)]
pub oauth2_metadata_url: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct OpenIdConnectSecurityScheme {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
pub open_id_connect_url: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
#[serde(rename_all = "camelCase")]
pub struct MutualTlsSecurityScheme {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub enum ApiKeyLocation {
Query,
Header,
Cookie,
}
impl std::fmt::Display for ApiKeyLocation {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Query => write!(f, "query"),
Self::Header => write!(f, "header"),
Self::Cookie => write!(f, "cookie"),
}
}
}
impl std::str::FromStr for ApiKeyLocation {
type Err = ParseEnumError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"query" => Ok(Self::Query),
"header" => Ok(Self::Header),
"cookie" => Ok(Self::Cookie),
_ => Err(ParseEnumError::new("API key location", s)),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub enum OAuthFlows {
AuthorizationCode(AuthorizationCodeOAuthFlow),
ClientCredentials(ClientCredentialsOAuthFlow),
DeviceCode(DeviceCodeOAuthFlow),
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct AuthorizationCodeOAuthFlow {
pub authorization_url: String,
pub token_url: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub refresh_url: Option<String>,
#[serde(default)]
pub scopes: HashMap<String, String>,
#[serde(default)]
pub pkce_required: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct ClientCredentialsOAuthFlow {
pub token_url: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub refresh_url: Option<String>,
#[serde(default)]
pub scopes: HashMap<String, String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct DeviceCodeOAuthFlow {
pub device_authorization_url: String,
pub token_url: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub refresh_url: Option<String>,
#[serde(default)]
pub scopes: HashMap<String, String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
pub struct SecurityRequirement {
#[serde(default)]
pub schemes: HashMap<String, StringList>,
}
impl SecurityRequirement {
#[must_use]
pub fn scheme(name: impl Into<String>, scopes: Vec<String>) -> Self {
Self {
schemes: HashMap::from([(name.into(), StringList { list: scopes })]),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
pub struct StringList {
#[serde(default)]
pub list: Vec<String>,
}