1
0
mirror of https://github.com/matrix-org/matrix-authentication-service.git synced 2025-07-29 22:01:14 +03:00

iana: manually implement JsonSchema/Display/FromStr/Serialize/Deserialize

This removes the dependency on serde_with and parse-display, and makes
the serde & schemars dependencies optional
This commit is contained in:
Quentin Gliech
2023-02-01 14:20:45 +01:00
parent 792d3c793b
commit 311cad47c2
8 changed files with 2424 additions and 610 deletions

3
Cargo.lock generated
View File

@ -2975,9 +2975,8 @@ dependencies = [
name = "mas-iana" name = "mas-iana"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"parse-display",
"schemars", "schemars",
"serde_with", "serde",
] ]
[[package]] [[package]]

View File

@ -0,0 +1,261 @@
// Copyright 2023 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use crate::traits::{EnumMember, Section};
pub fn struct_def(
f: &mut std::fmt::Formatter<'_>,
section: &Section,
list: &[EnumMember],
is_exhaustive: bool,
) -> std::fmt::Result {
write!(
f,
r#"/// {}
///
/// Source: <{}>
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]"#,
section.doc,
section.url.unwrap(),
)?;
if !is_exhaustive {
write!(
f,
r#"
#[non_exhaustive]"#
)?;
}
write!(
f,
r#"
pub enum {} {{"#,
section.key,
)?;
for member in list {
writeln!(f)?;
if let Some(description) = &member.description {
writeln!(f, " /// {description}")?;
} else {
writeln!(f, " /// `{}`", member.value)?;
}
writeln!(f, " {},", member.enum_name)?;
}
if !is_exhaustive {
// Add a variant for custom enums
writeln!(f)?;
writeln!(f, " /// An unknown value.")?;
writeln!(f, " Unknown(String),")?;
}
writeln!(f, "}}")
}
pub fn display_impl(
f: &mut std::fmt::Formatter<'_>,
section: &Section,
list: &[EnumMember],
is_exhaustive: bool,
) -> std::fmt::Result {
write!(
f,
r#"impl core::fmt::Display for {} {{
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {{
match self {{"#,
section.key,
)?;
for member in list {
write!(
f,
r#"
Self::{} => write!(f, "{}"),"#,
member.enum_name, member.value
)?;
}
if !is_exhaustive {
write!(
f,
r#"
Self::Unknown(value) => write!(f, "{{value}}"),"#
)?;
}
writeln!(
f,
r#"
}}
}}
}}"#,
)
}
pub fn from_str_impl(
f: &mut std::fmt::Formatter<'_>,
section: &Section,
list: &[EnumMember],
is_exhaustive: bool,
) -> std::fmt::Result {
let err_ty = if is_exhaustive {
"crate::ParseError"
} else {
"core::convert::Infallible"
};
write!(
f,
r#"impl core::str::FromStr for {} {{
type Err = {err_ty};
fn from_str(s: &str) -> Result<Self, Self::Err> {{
match s {{"#,
section.key,
)?;
for member in list {
write!(
f,
r#"
"{}" => Ok(Self::{}),"#,
member.value, member.enum_name
)?;
}
if is_exhaustive {
write!(
f,
r#"
_ => Err(crate::ParseError::new()),"#
)?;
} else {
write!(
f,
r#"
value => Ok(Self::Unknown(value.to_owned())),"#,
)?;
}
writeln!(
f,
r#"
}}
}}
}}"#,
)
}
pub fn json_schema_impl(
f: &mut std::fmt::Formatter<'_>,
section: &Section,
list: &[EnumMember],
) -> std::fmt::Result {
write!(
f,
r#"#[cfg(feature = "schemars")]
impl schemars::JsonSchema for {} {{
fn schema_name() -> String {{
"{}".to_owned()
}}
#[allow(clippy::too_many_lines)]
fn json_schema(_gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {{
let enums = vec!["#,
section.key, section.key,
)?;
for member in list {
write!(
f,
r#"
// ---
schemars::schema::SchemaObject {{"#,
)?;
if let Some(description) = &member.description {
write!(
f,
r##"
metadata: Some(Box::new(schemars::schema::Metadata {{
description: Some(
// ---
r#"{description}"#.to_owned(),
),
..Default::default()
}})),"##,
)?;
}
write!(
f,
r#"
const_value: Some("{}".into()),
..Default::default()
}}
.into(),"#,
member.value
)?;
}
writeln!(
f,
r##"
];
let description = r#"{}"#;
schemars::schema::SchemaObject {{
metadata: Some(Box::new(schemars::schema::Metadata {{
description: Some(description.to_owned()),
..Default::default()
}})),
subschemas: Some(Box::new(schemars::schema::SubschemaValidation {{
any_of: Some(enums),
..Default::default()
}})),
..Default::default()
}}
.into()
}}
}}"##,
section.doc,
)
}
pub fn serde_impl(f: &mut std::fmt::Formatter<'_>, section: &Section) -> std::fmt::Result {
writeln!(
f,
r#"#[cfg(feature = "serde")]
impl<'de> serde::Deserialize<'de> for {} {{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::de::Deserializer<'de>,
{{
let s = String::deserialize(deserializer)?;
core::str::FromStr::from_str(&s).map_err(serde::de::Error::custom)
}}
}}
#[cfg(feature = "serde")]
impl serde::Serialize for {} {{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::ser::Serializer,
{{
serializer.serialize_str(&self.to_string())
}}
}}"#,
section.key, section.key,
)
}

View File

@ -1,4 +1,4 @@
// Copyright 2022 The Matrix.org Foundation C.I.C. // Copyright 2022, 2023 The Matrix.org Foundation C.I.C.
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
@ -23,6 +23,7 @@ use reqwest::Client;
use tokio::io::AsyncWriteExt; use tokio::io::AsyncWriteExt;
use tracing::Level; use tracing::Level;
mod gen;
pub mod jose; pub mod jose;
pub mod oauth; pub mod oauth;
pub mod traits; pub mod traits;
@ -82,10 +83,11 @@ impl File {
} }
impl Display for File { impl Display for File {
#[allow(clippy::too_many_lines)]
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
writeln!( writeln!(
f, f,
r#"// Copyright 2022 The Matrix.org Foundation C.I.C. r#"// Copyright 2023 The Matrix.org Foundation C.I.C.
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
@ -102,11 +104,7 @@ impl Display for File {
//! Enums from the {:?} IANA registry //! Enums from the {:?} IANA registry
//! See <{}> //! See <{}>
// Do not edit this file manually // Do not edit this file manually"#,
use parse_display::{{Display, FromStr}};
use schemars::JsonSchema;
use serde_with::{{DeserializeFromStr, SerializeDisplay}};"#,
self.registry_name, self.registry_url, self.registry_name, self.registry_url,
)?; )?;
@ -116,61 +114,25 @@ use serde_with::{{DeserializeFromStr, SerializeDisplay}};"#,
}; };
let is_exhaustive = section.key == "OAuthAuthorizationEndpointResponseType"; let is_exhaustive = section.key == "OAuthAuthorizationEndpointResponseType";
writeln!(f)?;
let non_exhaustive_attr = if is_exhaustive { self::gen::struct_def(f, section, list, is_exhaustive)?;
"" writeln!(f)?;
} else {
"\n#[non_exhaustive]"
};
write!( // Write the Display impl
f, self::gen::display_impl(f, section, list, is_exhaustive)?;
r#" writeln!(f)?;
/// {}
///
/// Source: <{}>
#[derive(
Debug,
Clone,
PartialEq,
Eq,
PartialOrd,
Ord,
Hash,
Display,
FromStr,
SerializeDisplay,
DeserializeFromStr,
JsonSchema,
)]{}
pub enum {} {{"#,
section.doc,
section.url.unwrap(),
non_exhaustive_attr,
section.key,
)?;
for member in list {
writeln!(f)?;
if let Some(description) = &member.description {
writeln!(f, " /// {description}")?;
} else {
writeln!(f, " /// `{}`", member.value)?;
}
writeln!(f, " #[schemars(rename = \"{}\")]", member.value)?;
writeln!(f, " #[display(\"{}\")]", member.value)?;
writeln!(f, " {},", member.enum_name)?;
}
if !is_exhaustive { // Write the FromStr impl
// Add a variant for custom enums self::gen::from_str_impl(f, section, list, is_exhaustive)?;
writeln!(f)?; writeln!(f)?;
writeln!(f, " /// An unknown value.")?;
writeln!(f, " #[display(\"{{0}}\")]")?;
writeln!(f, " #[schemars(skip)]")?;
writeln!(f, " Unknown(String),")?;
}
writeln!(f, "}}")?; // Write the Serialize and Deserialize impls
self::gen::serde_impl(f, section)?;
writeln!(f)?;
// Write the JsonSchema impl
self::gen::json_schema_impl(f, section, list)?;
} }
Ok(()) Ok(())

View File

@ -6,6 +6,10 @@ edition = "2021"
license = "Apache-2.0" license = "Apache-2.0"
[dependencies] [dependencies]
serde_with = "2.2.0" serde = { version = "1.0.130", optional = true }
schemars = "0.8.11" schemars = { version = "0.8.11", default-features = false, optional = true }
parse-display = "0.8.0"
[features]
default = ["serde", "schemars"]
serde = ["dep:serde"]
schemars = ["dep:schemars"]

File diff suppressed because it is too large Load Diff

View File

@ -27,4 +27,27 @@
pub mod jose; pub mod jose;
pub mod oauth; pub mod oauth;
pub use parse_display::ParseError; /// An error that occurred while parsing a value from a string.
pub struct ParseError {
_private: (),
}
impl ParseError {
fn new() -> Self {
Self { _private: () }
}
}
impl core::fmt::Debug for ParseError {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str("ParseError")
}
}
impl core::fmt::Display for ParseError {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str("Parse error")
}
}
impl std::error::Error for ParseError {}

View File

@ -1,4 +1,4 @@
// Copyright 2022 The Matrix.org Foundation C.I.C. // Copyright 2023 The Matrix.org Foundation C.I.C.
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
@ -17,240 +17,630 @@
// Do not edit this file manually // Do not edit this file manually
use parse_display::{Display, FromStr};
use schemars::JsonSchema;
use serde_with::{DeserializeFromStr, SerializeDisplay};
/// OAuth Access Token Type /// OAuth Access Token Type
/// ///
/// Source: <https://www.iana.org/assignments/oauth-parameters/token-types.csv> /// Source: <https://www.iana.org/assignments/oauth-parameters/token-types.csv>
#[derive( #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
Debug,
Clone,
PartialEq,
Eq,
PartialOrd,
Ord,
Hash,
Display,
FromStr,
SerializeDisplay,
DeserializeFromStr,
JsonSchema,
)]
#[non_exhaustive] #[non_exhaustive]
pub enum OAuthAccessTokenType { pub enum OAuthAccessTokenType {
/// `Bearer` /// `Bearer`
#[schemars(rename = "Bearer")]
#[display("Bearer")]
Bearer, Bearer,
/// `N_A` /// `N_A`
#[schemars(rename = "N_A")]
#[display("N_A")]
Na, Na,
/// `PoP` /// `PoP`
#[schemars(rename = "PoP")]
#[display("PoP")]
PoP, PoP,
/// An unknown value. /// An unknown value.
#[display("{0}")]
#[schemars(skip)]
Unknown(String), Unknown(String),
} }
impl core::fmt::Display for OAuthAccessTokenType {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Self::Bearer => write!(f, "Bearer"),
Self::Na => write!(f, "N_A"),
Self::PoP => write!(f, "PoP"),
Self::Unknown(value) => write!(f, "{value}"),
}
}
}
impl core::str::FromStr for OAuthAccessTokenType {
type Err = core::convert::Infallible;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"Bearer" => Ok(Self::Bearer),
"N_A" => Ok(Self::Na),
"PoP" => Ok(Self::PoP),
value => Ok(Self::Unknown(value.to_owned())),
}
}
}
#[cfg(feature = "serde")]
impl<'de> serde::Deserialize<'de> for OAuthAccessTokenType {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::de::Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
core::str::FromStr::from_str(&s).map_err(serde::de::Error::custom)
}
}
#[cfg(feature = "serde")]
impl serde::Serialize for OAuthAccessTokenType {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::ser::Serializer,
{
serializer.serialize_str(&self.to_string())
}
}
#[cfg(feature = "schemars")]
impl schemars::JsonSchema for OAuthAccessTokenType {
fn schema_name() -> String {
"OAuthAccessTokenType".to_owned()
}
#[allow(clippy::too_many_lines)]
fn json_schema(_gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
let enums = vec![
// ---
schemars::schema::SchemaObject {
const_value: Some("Bearer".into()),
..Default::default()
}
.into(),
// ---
schemars::schema::SchemaObject {
const_value: Some("N_A".into()),
..Default::default()
}
.into(),
// ---
schemars::schema::SchemaObject {
const_value: Some("PoP".into()),
..Default::default()
}
.into(),
];
let description = r#"OAuth Access Token Type"#;
schemars::schema::SchemaObject {
metadata: Some(Box::new(schemars::schema::Metadata {
description: Some(description.to_owned()),
..Default::default()
})),
subschemas: Some(Box::new(schemars::schema::SubschemaValidation {
any_of: Some(enums),
..Default::default()
})),
..Default::default()
}
.into()
}
}
/// OAuth Authorization Endpoint Response Type /// OAuth Authorization Endpoint Response Type
/// ///
/// Source: <https://www.iana.org/assignments/oauth-parameters/endpoint.csv> /// Source: <https://www.iana.org/assignments/oauth-parameters/endpoint.csv>
#[derive( #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
Debug,
Clone,
PartialEq,
Eq,
PartialOrd,
Ord,
Hash,
Display,
FromStr,
SerializeDisplay,
DeserializeFromStr,
JsonSchema,
)]
pub enum OAuthAuthorizationEndpointResponseType { pub enum OAuthAuthorizationEndpointResponseType {
/// `code` /// `code`
#[schemars(rename = "code")]
#[display("code")]
Code, Code,
/// `code id_token` /// `code id_token`
#[schemars(rename = "code id_token")]
#[display("code id_token")]
CodeIdToken, CodeIdToken,
/// `code id_token token` /// `code id_token token`
#[schemars(rename = "code id_token token")]
#[display("code id_token token")]
CodeIdTokenToken, CodeIdTokenToken,
/// `code token` /// `code token`
#[schemars(rename = "code token")]
#[display("code token")]
CodeToken, CodeToken,
/// `id_token` /// `id_token`
#[schemars(rename = "id_token")]
#[display("id_token")]
IdToken, IdToken,
/// `id_token token` /// `id_token token`
#[schemars(rename = "id_token token")]
#[display("id_token token")]
IdTokenToken, IdTokenToken,
/// `none` /// `none`
#[schemars(rename = "none")]
#[display("none")]
None, None,
/// `token` /// `token`
#[schemars(rename = "token")]
#[display("token")]
Token, Token,
} }
impl core::fmt::Display for OAuthAuthorizationEndpointResponseType {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Self::Code => write!(f, "code"),
Self::CodeIdToken => write!(f, "code id_token"),
Self::CodeIdTokenToken => write!(f, "code id_token token"),
Self::CodeToken => write!(f, "code token"),
Self::IdToken => write!(f, "id_token"),
Self::IdTokenToken => write!(f, "id_token token"),
Self::None => write!(f, "none"),
Self::Token => write!(f, "token"),
}
}
}
impl core::str::FromStr for OAuthAuthorizationEndpointResponseType {
type Err = crate::ParseError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"code" => Ok(Self::Code),
"code id_token" => Ok(Self::CodeIdToken),
"code id_token token" => Ok(Self::CodeIdTokenToken),
"code token" => Ok(Self::CodeToken),
"id_token" => Ok(Self::IdToken),
"id_token token" => Ok(Self::IdTokenToken),
"none" => Ok(Self::None),
"token" => Ok(Self::Token),
_ => Err(crate::ParseError::new()),
}
}
}
#[cfg(feature = "serde")]
impl<'de> serde::Deserialize<'de> for OAuthAuthorizationEndpointResponseType {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::de::Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
core::str::FromStr::from_str(&s).map_err(serde::de::Error::custom)
}
}
#[cfg(feature = "serde")]
impl serde::Serialize for OAuthAuthorizationEndpointResponseType {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::ser::Serializer,
{
serializer.serialize_str(&self.to_string())
}
}
#[cfg(feature = "schemars")]
impl schemars::JsonSchema for OAuthAuthorizationEndpointResponseType {
fn schema_name() -> String {
"OAuthAuthorizationEndpointResponseType".to_owned()
}
#[allow(clippy::too_many_lines)]
fn json_schema(_gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
let enums = vec![
// ---
schemars::schema::SchemaObject {
const_value: Some("code".into()),
..Default::default()
}
.into(),
// ---
schemars::schema::SchemaObject {
const_value: Some("code id_token".into()),
..Default::default()
}
.into(),
// ---
schemars::schema::SchemaObject {
const_value: Some("code id_token token".into()),
..Default::default()
}
.into(),
// ---
schemars::schema::SchemaObject {
const_value: Some("code token".into()),
..Default::default()
}
.into(),
// ---
schemars::schema::SchemaObject {
const_value: Some("id_token".into()),
..Default::default()
}
.into(),
// ---
schemars::schema::SchemaObject {
const_value: Some("id_token token".into()),
..Default::default()
}
.into(),
// ---
schemars::schema::SchemaObject {
const_value: Some("none".into()),
..Default::default()
}
.into(),
// ---
schemars::schema::SchemaObject {
const_value: Some("token".into()),
..Default::default()
}
.into(),
];
let description = r#"OAuth Authorization Endpoint Response Type"#;
schemars::schema::SchemaObject {
metadata: Some(Box::new(schemars::schema::Metadata {
description: Some(description.to_owned()),
..Default::default()
})),
subschemas: Some(Box::new(schemars::schema::SubschemaValidation {
any_of: Some(enums),
..Default::default()
})),
..Default::default()
}
.into()
}
}
/// OAuth Token Type Hint /// OAuth Token Type Hint
/// ///
/// Source: <https://www.iana.org/assignments/oauth-parameters/token-type-hint.csv> /// Source: <https://www.iana.org/assignments/oauth-parameters/token-type-hint.csv>
#[derive( #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
Debug,
Clone,
PartialEq,
Eq,
PartialOrd,
Ord,
Hash,
Display,
FromStr,
SerializeDisplay,
DeserializeFromStr,
JsonSchema,
)]
#[non_exhaustive] #[non_exhaustive]
pub enum OAuthTokenTypeHint { pub enum OAuthTokenTypeHint {
/// `access_token` /// `access_token`
#[schemars(rename = "access_token")]
#[display("access_token")]
AccessToken, AccessToken,
/// `refresh_token` /// `refresh_token`
#[schemars(rename = "refresh_token")]
#[display("refresh_token")]
RefreshToken, RefreshToken,
/// `pct` /// `pct`
#[schemars(rename = "pct")]
#[display("pct")]
Pct, Pct,
/// An unknown value. /// An unknown value.
#[display("{0}")]
#[schemars(skip)]
Unknown(String), Unknown(String),
} }
impl core::fmt::Display for OAuthTokenTypeHint {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Self::AccessToken => write!(f, "access_token"),
Self::RefreshToken => write!(f, "refresh_token"),
Self::Pct => write!(f, "pct"),
Self::Unknown(value) => write!(f, "{value}"),
}
}
}
impl core::str::FromStr for OAuthTokenTypeHint {
type Err = core::convert::Infallible;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"access_token" => Ok(Self::AccessToken),
"refresh_token" => Ok(Self::RefreshToken),
"pct" => Ok(Self::Pct),
value => Ok(Self::Unknown(value.to_owned())),
}
}
}
#[cfg(feature = "serde")]
impl<'de> serde::Deserialize<'de> for OAuthTokenTypeHint {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::de::Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
core::str::FromStr::from_str(&s).map_err(serde::de::Error::custom)
}
}
#[cfg(feature = "serde")]
impl serde::Serialize for OAuthTokenTypeHint {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::ser::Serializer,
{
serializer.serialize_str(&self.to_string())
}
}
#[cfg(feature = "schemars")]
impl schemars::JsonSchema for OAuthTokenTypeHint {
fn schema_name() -> String {
"OAuthTokenTypeHint".to_owned()
}
#[allow(clippy::too_many_lines)]
fn json_schema(_gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
let enums = vec![
// ---
schemars::schema::SchemaObject {
const_value: Some("access_token".into()),
..Default::default()
}
.into(),
// ---
schemars::schema::SchemaObject {
const_value: Some("refresh_token".into()),
..Default::default()
}
.into(),
// ---
schemars::schema::SchemaObject {
const_value: Some("pct".into()),
..Default::default()
}
.into(),
];
let description = r#"OAuth Token Type Hint"#;
schemars::schema::SchemaObject {
metadata: Some(Box::new(schemars::schema::Metadata {
description: Some(description.to_owned()),
..Default::default()
})),
subschemas: Some(Box::new(schemars::schema::SubschemaValidation {
any_of: Some(enums),
..Default::default()
})),
..Default::default()
}
.into()
}
}
/// OAuth Token Endpoint Authentication Method /// OAuth Token Endpoint Authentication Method
/// ///
/// Source: <https://www.iana.org/assignments/oauth-parameters/token-endpoint-auth-method.csv> /// Source: <https://www.iana.org/assignments/oauth-parameters/token-endpoint-auth-method.csv>
#[derive( #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
Debug,
Clone,
PartialEq,
Eq,
PartialOrd,
Ord,
Hash,
Display,
FromStr,
SerializeDisplay,
DeserializeFromStr,
JsonSchema,
)]
#[non_exhaustive] #[non_exhaustive]
pub enum OAuthClientAuthenticationMethod { pub enum OAuthClientAuthenticationMethod {
/// `none` /// `none`
#[schemars(rename = "none")]
#[display("none")]
None, None,
/// `client_secret_post` /// `client_secret_post`
#[schemars(rename = "client_secret_post")]
#[display("client_secret_post")]
ClientSecretPost, ClientSecretPost,
/// `client_secret_basic` /// `client_secret_basic`
#[schemars(rename = "client_secret_basic")]
#[display("client_secret_basic")]
ClientSecretBasic, ClientSecretBasic,
/// `client_secret_jwt` /// `client_secret_jwt`
#[schemars(rename = "client_secret_jwt")]
#[display("client_secret_jwt")]
ClientSecretJwt, ClientSecretJwt,
/// `private_key_jwt` /// `private_key_jwt`
#[schemars(rename = "private_key_jwt")]
#[display("private_key_jwt")]
PrivateKeyJwt, PrivateKeyJwt,
/// `tls_client_auth` /// `tls_client_auth`
#[schemars(rename = "tls_client_auth")]
#[display("tls_client_auth")]
TlsClientAuth, TlsClientAuth,
/// `self_signed_tls_client_auth` /// `self_signed_tls_client_auth`
#[schemars(rename = "self_signed_tls_client_auth")]
#[display("self_signed_tls_client_auth")]
SelfSignedTlsClientAuth, SelfSignedTlsClientAuth,
/// An unknown value. /// An unknown value.
#[display("{0}")]
#[schemars(skip)]
Unknown(String), Unknown(String),
} }
impl core::fmt::Display for OAuthClientAuthenticationMethod {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Self::None => write!(f, "none"),
Self::ClientSecretPost => write!(f, "client_secret_post"),
Self::ClientSecretBasic => write!(f, "client_secret_basic"),
Self::ClientSecretJwt => write!(f, "client_secret_jwt"),
Self::PrivateKeyJwt => write!(f, "private_key_jwt"),
Self::TlsClientAuth => write!(f, "tls_client_auth"),
Self::SelfSignedTlsClientAuth => write!(f, "self_signed_tls_client_auth"),
Self::Unknown(value) => write!(f, "{value}"),
}
}
}
impl core::str::FromStr for OAuthClientAuthenticationMethod {
type Err = core::convert::Infallible;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"none" => Ok(Self::None),
"client_secret_post" => Ok(Self::ClientSecretPost),
"client_secret_basic" => Ok(Self::ClientSecretBasic),
"client_secret_jwt" => Ok(Self::ClientSecretJwt),
"private_key_jwt" => Ok(Self::PrivateKeyJwt),
"tls_client_auth" => Ok(Self::TlsClientAuth),
"self_signed_tls_client_auth" => Ok(Self::SelfSignedTlsClientAuth),
value => Ok(Self::Unknown(value.to_owned())),
}
}
}
#[cfg(feature = "serde")]
impl<'de> serde::Deserialize<'de> for OAuthClientAuthenticationMethod {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::de::Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
core::str::FromStr::from_str(&s).map_err(serde::de::Error::custom)
}
}
#[cfg(feature = "serde")]
impl serde::Serialize for OAuthClientAuthenticationMethod {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::ser::Serializer,
{
serializer.serialize_str(&self.to_string())
}
}
#[cfg(feature = "schemars")]
impl schemars::JsonSchema for OAuthClientAuthenticationMethod {
fn schema_name() -> String {
"OAuthClientAuthenticationMethod".to_owned()
}
#[allow(clippy::too_many_lines)]
fn json_schema(_gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
let enums = vec![
// ---
schemars::schema::SchemaObject {
const_value: Some("none".into()),
..Default::default()
}
.into(),
// ---
schemars::schema::SchemaObject {
const_value: Some("client_secret_post".into()),
..Default::default()
}
.into(),
// ---
schemars::schema::SchemaObject {
const_value: Some("client_secret_basic".into()),
..Default::default()
}
.into(),
// ---
schemars::schema::SchemaObject {
const_value: Some("client_secret_jwt".into()),
..Default::default()
}
.into(),
// ---
schemars::schema::SchemaObject {
const_value: Some("private_key_jwt".into()),
..Default::default()
}
.into(),
// ---
schemars::schema::SchemaObject {
const_value: Some("tls_client_auth".into()),
..Default::default()
}
.into(),
// ---
schemars::schema::SchemaObject {
const_value: Some("self_signed_tls_client_auth".into()),
..Default::default()
}
.into(),
];
let description = r#"OAuth Token Endpoint Authentication Method"#;
schemars::schema::SchemaObject {
metadata: Some(Box::new(schemars::schema::Metadata {
description: Some(description.to_owned()),
..Default::default()
})),
subschemas: Some(Box::new(schemars::schema::SubschemaValidation {
any_of: Some(enums),
..Default::default()
})),
..Default::default()
}
.into()
}
}
/// PKCE Code Challenge Method /// PKCE Code Challenge Method
/// ///
/// Source: <https://www.iana.org/assignments/oauth-parameters/pkce-code-challenge-method.csv> /// Source: <https://www.iana.org/assignments/oauth-parameters/pkce-code-challenge-method.csv>
#[derive( #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
Debug,
Clone,
PartialEq,
Eq,
PartialOrd,
Ord,
Hash,
Display,
FromStr,
SerializeDisplay,
DeserializeFromStr,
JsonSchema,
)]
#[non_exhaustive] #[non_exhaustive]
pub enum PkceCodeChallengeMethod { pub enum PkceCodeChallengeMethod {
/// `plain` /// `plain`
#[schemars(rename = "plain")]
#[display("plain")]
Plain, Plain,
/// `S256` /// `S256`
#[schemars(rename = "S256")]
#[display("S256")]
S256, S256,
/// An unknown value. /// An unknown value.
#[display("{0}")]
#[schemars(skip)]
Unknown(String), Unknown(String),
} }
impl core::fmt::Display for PkceCodeChallengeMethod {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Self::Plain => write!(f, "plain"),
Self::S256 => write!(f, "S256"),
Self::Unknown(value) => write!(f, "{value}"),
}
}
}
impl core::str::FromStr for PkceCodeChallengeMethod {
type Err = core::convert::Infallible;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"plain" => Ok(Self::Plain),
"S256" => Ok(Self::S256),
value => Ok(Self::Unknown(value.to_owned())),
}
}
}
#[cfg(feature = "serde")]
impl<'de> serde::Deserialize<'de> for PkceCodeChallengeMethod {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::de::Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
core::str::FromStr::from_str(&s).map_err(serde::de::Error::custom)
}
}
#[cfg(feature = "serde")]
impl serde::Serialize for PkceCodeChallengeMethod {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::ser::Serializer,
{
serializer.serialize_str(&self.to_string())
}
}
#[cfg(feature = "schemars")]
impl schemars::JsonSchema for PkceCodeChallengeMethod {
fn schema_name() -> String {
"PkceCodeChallengeMethod".to_owned()
}
#[allow(clippy::too_many_lines)]
fn json_schema(_gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
let enums = vec![
// ---
schemars::schema::SchemaObject {
const_value: Some("plain".into()),
..Default::default()
}
.into(),
// ---
schemars::schema::SchemaObject {
const_value: Some("S256".into()),
..Default::default()
}
.into(),
];
let description = r#"PKCE Code Challenge Method"#;
schemars::schema::SchemaObject {
metadata: Some(Box::new(schemars::schema::Metadata {
description: Some(description.to_owned()),
..Default::default()
})),
subschemas: Some(Box::new(schemars::schema::SubschemaValidation {
any_of: Some(enums),
..Default::default()
})),
..Default::default()
}
.into()
}
}

View File

@ -759,129 +759,81 @@
} }
}, },
"JsonWebKeyEcEllipticCurve": { "JsonWebKeyEcEllipticCurve": {
"description": "JSON Web Key EC Elliptic Curve\n\nSource: <https://www.iana.org/assignments/jose/web-key-elliptic-curve.csv>", "description": "JSON Web Key EC Elliptic Curve",
"oneOf": [ "anyOf": [
{ {
"description": "P-256 Curve", "description": "P-256 Curve",
"type": "string", "const": "P-256"
"enum": [
"P-256"
]
}, },
{ {
"description": "P-384 Curve", "description": "P-384 Curve",
"type": "string", "const": "P-384"
"enum": [
"P-384"
]
}, },
{ {
"description": "P-521 Curve", "description": "P-521 Curve",
"type": "string", "const": "P-521"
"enum": [
"P-521"
]
}, },
{ {
"description": "SECG secp256k1 curve", "description": "SECG secp256k1 curve",
"type": "string", "const": "secp256k1"
"enum": [
"secp256k1"
]
} }
] ]
}, },
"JsonWebKeyOkpEllipticCurve": { "JsonWebKeyOkpEllipticCurve": {
"description": "JSON Web Key OKP Elliptic Curve\n\nSource: <https://www.iana.org/assignments/jose/web-key-elliptic-curve.csv>", "description": "JSON Web Key OKP Elliptic Curve",
"oneOf": [ "anyOf": [
{ {
"description": "Ed25519 signature algorithm key pairs", "description": "Ed25519 signature algorithm key pairs",
"type": "string", "const": "Ed25519"
"enum": [
"Ed25519"
]
}, },
{ {
"description": "Ed448 signature algorithm key pairs", "description": "Ed448 signature algorithm key pairs",
"type": "string", "const": "Ed448"
"enum": [
"Ed448"
]
}, },
{ {
"description": "X25519 function key pairs", "description": "X25519 function key pairs",
"type": "string", "const": "X25519"
"enum": [
"X25519"
]
}, },
{ {
"description": "X448 function key pairs", "description": "X448 function key pairs",
"type": "string", "const": "X448"
"enum": [
"X448"
]
} }
] ]
}, },
"JsonWebKeyOperation": { "JsonWebKeyOperation": {
"description": "JSON Web Key Operation\n\nSource: <https://www.iana.org/assignments/jose/web-key-operations.csv>", "description": "JSON Web Key Operation",
"oneOf": [ "anyOf": [
{ {
"description": "Compute digital signature or MAC", "description": "Compute digital signature or MAC",
"type": "string", "const": "sign"
"enum": [
"sign"
]
}, },
{ {
"description": "Verify digital signature or MAC", "description": "Verify digital signature or MAC",
"type": "string", "const": "verify"
"enum": [
"verify"
]
}, },
{ {
"description": "Encrypt content", "description": "Encrypt content",
"type": "string", "const": "encrypt"
"enum": [
"encrypt"
]
}, },
{ {
"description": "Decrypt content and validate decryption, if applicable", "description": "Decrypt content and validate decryption, if applicable",
"type": "string", "const": "decrypt"
"enum": [
"decrypt"
]
}, },
{ {
"description": "Encrypt key", "description": "Encrypt key",
"type": "string", "const": "wrapKey"
"enum": [
"wrapKey"
]
}, },
{ {
"description": "Decrypt key and validate decryption, if applicable", "description": "Decrypt key and validate decryption, if applicable",
"type": "string", "const": "unwrapKey"
"enum": [
"unwrapKey"
]
}, },
{ {
"description": "Derive key", "description": "Derive key",
"type": "string", "const": "deriveKey"
"enum": [
"deriveKey"
]
}, },
{ {
"description": "Derive bits not to be used as a key", "description": "Derive bits not to be used as a key",
"type": "string", "const": "deriveBits"
"enum": [
"deriveBits"
]
} }
] ]
}, },
@ -900,21 +852,15 @@
} }
}, },
"JsonWebKeyUse": { "JsonWebKeyUse": {
"description": "JSON Web Key Use\n\nSource: <https://www.iana.org/assignments/jose/web-key-use.csv>", "description": "JSON Web Key Use",
"oneOf": [ "anyOf": [
{ {
"description": "Digital Signature or MAC", "description": "Digital Signature or MAC",
"type": "string", "const": "sig"
"enum": [
"sig"
]
}, },
{ {
"description": "Encryption", "description": "Encryption",
"type": "string", "const": "enc"
"enum": [
"enc"
]
} }
] ]
}, },
@ -1026,112 +972,67 @@
} }
}, },
"JsonWebSignatureAlg": { "JsonWebSignatureAlg": {
"description": "JSON Web Signature \"alg\" parameter\n\nSource: <https://www.iana.org/assignments/jose/web-signature-encryption-algorithms.csv>", "description": "JSON Web Signature \"alg\" parameter",
"oneOf": [ "anyOf": [
{ {
"description": "HMAC using SHA-256", "description": "HMAC using SHA-256",
"type": "string", "const": "HS256"
"enum": [
"HS256"
]
}, },
{ {
"description": "HMAC using SHA-384", "description": "HMAC using SHA-384",
"type": "string", "const": "HS384"
"enum": [
"HS384"
]
}, },
{ {
"description": "HMAC using SHA-512", "description": "HMAC using SHA-512",
"type": "string", "const": "HS512"
"enum": [
"HS512"
]
}, },
{ {
"description": "RSASSA-PKCS1-v1_5 using SHA-256", "description": "RSASSA-PKCS1-v1_5 using SHA-256",
"type": "string", "const": "RS256"
"enum": [
"RS256"
]
}, },
{ {
"description": "RSASSA-PKCS1-v1_5 using SHA-384", "description": "RSASSA-PKCS1-v1_5 using SHA-384",
"type": "string", "const": "RS384"
"enum": [
"RS384"
]
}, },
{ {
"description": "RSASSA-PKCS1-v1_5 using SHA-512", "description": "RSASSA-PKCS1-v1_5 using SHA-512",
"type": "string", "const": "RS512"
"enum": [
"RS512"
]
}, },
{ {
"description": "ECDSA using P-256 and SHA-256", "description": "ECDSA using P-256 and SHA-256",
"type": "string", "const": "ES256"
"enum": [
"ES256"
]
}, },
{ {
"description": "ECDSA using P-384 and SHA-384", "description": "ECDSA using P-384 and SHA-384",
"type": "string", "const": "ES384"
"enum": [
"ES384"
]
}, },
{ {
"description": "ECDSA using P-521 and SHA-512", "description": "ECDSA using P-521 and SHA-512",
"type": "string", "const": "ES512"
"enum": [
"ES512"
]
}, },
{ {
"description": "RSASSA-PSS using SHA-256 and MGF1 with SHA-256", "description": "RSASSA-PSS using SHA-256 and MGF1 with SHA-256",
"type": "string", "const": "PS256"
"enum": [
"PS256"
]
}, },
{ {
"description": "RSASSA-PSS using SHA-384 and MGF1 with SHA-384", "description": "RSASSA-PSS using SHA-384 and MGF1 with SHA-384",
"type": "string", "const": "PS384"
"enum": [
"PS384"
]
}, },
{ {
"description": "RSASSA-PSS using SHA-512 and MGF1 with SHA-512", "description": "RSASSA-PSS using SHA-512 and MGF1 with SHA-512",
"type": "string", "const": "PS512"
"enum": [
"PS512"
]
}, },
{ {
"description": "No digital signature or MAC performed", "description": "No digital signature or MAC performed",
"type": "string", "const": "none"
"enum": [
"none"
]
}, },
{ {
"description": "EdDSA signature algorithms", "description": "EdDSA signature algorithms",
"type": "string", "const": "EdDSA"
"enum": [
"EdDSA"
]
}, },
{ {
"description": "ECDSA using secp256k1 curve and SHA-256", "description": "ECDSA using secp256k1 curve and SHA-256",
"type": "string", "const": "ES256K"
"enum": [
"ES256K"
]
} }
] ]
}, },