You've already forked authentication-service
mirror of
https://github.com/matrix-org/matrix-authentication-service.git
synced 2025-07-31 09:24:31 +03:00
Multiple IANA codegen enhancement
- JWS/JWE algorithms are properly splitted - Enums now have a proper description - They implement FromStr and Display - mas-jose does not reexport mas-iana anymore
This commit is contained in:
@ -14,7 +14,10 @@
|
||||
|
||||
use serde::Deserialize;
|
||||
|
||||
use crate::EnumEntry;
|
||||
use crate::{
|
||||
traits::{s, Section},
|
||||
EnumEntry,
|
||||
};
|
||||
|
||||
#[derive(Debug, Deserialize, PartialEq, Eq)]
|
||||
enum Usage {
|
||||
@ -60,13 +63,41 @@ pub struct WebEncryptionSignatureAlgorithm {
|
||||
impl EnumEntry for WebEncryptionSignatureAlgorithm {
|
||||
const URL: &'static str =
|
||||
"https://www.iana.org/assignments/jose/web-signature-encryption-algorithms.csv";
|
||||
const SECTIONS: &'static [&'static str] =
|
||||
&["JsonWebSignatureAlgorithm", "JsonWebEncryptionAlgorithm"];
|
||||
const SECTIONS: &'static [Section] = &[
|
||||
s(
|
||||
"JsonWebSignatureAlg",
|
||||
r#"JSON Web Signature "alg" parameter"#,
|
||||
),
|
||||
s(
|
||||
"JsonWebEncryptionAlg",
|
||||
r#"JSON Web Encryption "alg" parameter"#,
|
||||
),
|
||||
s(
|
||||
"JsonWebEncryptionEnc",
|
||||
r#"JSON Web Encryption "enc" parameter"#,
|
||||
),
|
||||
];
|
||||
|
||||
fn key(&self) -> Option<&'static str> {
|
||||
match self.usage {
|
||||
Usage::Alg => Some("JsonWebSignatureAlgorithm"),
|
||||
Usage::Enc => Some("JsonWebEncryptionAlgorithm"),
|
||||
Usage::Alg => {
|
||||
// RFC7518 has one for signature algs and one for encryption algs. The other two
|
||||
// RFCs are additional Elliptic curve signature algs
|
||||
if self.reference.contains("RFC7518, Section 3")
|
||||
|| self.reference.contains("RFC8037")
|
||||
|| self.reference.contains("RFC8812")
|
||||
{
|
||||
Some("JsonWebSignatureAlg")
|
||||
} else if self.reference.contains("RFC7518, Section 4")
|
||||
|| self.reference.contains("WebCryptoAPI")
|
||||
{
|
||||
Some("JsonWebEncryptionAlg")
|
||||
} else {
|
||||
tracing::warn!("Unknown reference {} for JWA", self.reference);
|
||||
None
|
||||
}
|
||||
}
|
||||
Usage::Enc => Some("JsonWebEncryptionEnc"),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@ -96,7 +127,10 @@ pub struct WebEncryptionCompressionAlgorithm {
|
||||
impl EnumEntry for WebEncryptionCompressionAlgorithm {
|
||||
const URL: &'static str =
|
||||
"https://www.iana.org/assignments/jose/web-encryption-compression-algorithms.csv";
|
||||
const SECTIONS: &'static [&'static str] = &["JsonWebEncryptionCompressionAlgorithm"];
|
||||
const SECTIONS: &'static [Section] = &[s(
|
||||
"JsonWebEncryptionCompressionAlgorithm",
|
||||
"JSON Web Encryption Compression Algorithm",
|
||||
)];
|
||||
|
||||
fn key(&self) -> Option<&'static str> {
|
||||
Some("JsonWebEncryptionCompressionAlgorithm")
|
||||
@ -128,7 +162,7 @@ pub struct WebKeyType {
|
||||
|
||||
impl EnumEntry for WebKeyType {
|
||||
const URL: &'static str = "https://www.iana.org/assignments/jose/web-key-types.csv";
|
||||
const SECTIONS: &'static [&'static str] = &["JsonWebKeyType"];
|
||||
const SECTIONS: &'static [Section] = &[s("JsonWebKeyType", "JSON Web Key Type")];
|
||||
|
||||
fn key(&self) -> Option<&'static str> {
|
||||
Some("JsonWebKeyType")
|
||||
@ -160,8 +194,16 @@ pub struct WebKeyEllipticCurve {
|
||||
|
||||
impl EnumEntry for WebKeyEllipticCurve {
|
||||
const URL: &'static str = "https://www.iana.org/assignments/jose/web-key-elliptic-curve.csv";
|
||||
const SECTIONS: &'static [&'static str] =
|
||||
&["JsonWebKeyEcEllipticCurve", "JsonWebKeyOkpEllipticCurve"];
|
||||
const SECTIONS: &'static [Section] = &[
|
||||
s(
|
||||
"JsonWebKeyEcEllipticCurve",
|
||||
"JSON Web Key EC Elliptic Curve",
|
||||
),
|
||||
s(
|
||||
"JsonWebKeyOkpEllipticCurve",
|
||||
"JSON Web Key OKP Elliptic Curve",
|
||||
),
|
||||
];
|
||||
|
||||
fn key(&self) -> Option<&'static str> {
|
||||
if self.name.starts_with("P-") || self.name == "secp256k1" {
|
||||
@ -195,7 +237,7 @@ pub struct WebKeyUse {
|
||||
|
||||
impl EnumEntry for WebKeyUse {
|
||||
const URL: &'static str = "https://www.iana.org/assignments/jose/web-key-use.csv";
|
||||
const SECTIONS: &'static [&'static str] = &["JsonWebKeyUse"];
|
||||
const SECTIONS: &'static [Section] = &[s("JsonWebKeyUse", "JSON Web Key Use")];
|
||||
|
||||
fn key(&self) -> Option<&'static str> {
|
||||
Some("JsonWebKeyUse")
|
||||
@ -225,7 +267,7 @@ pub struct WebKeyOperation {
|
||||
|
||||
impl EnumEntry for WebKeyOperation {
|
||||
const URL: &'static str = "https://www.iana.org/assignments/jose/web-key-operations.csv";
|
||||
const SECTIONS: &'static [&'static str] = &["JsonWebKeyOperation"];
|
||||
const SECTIONS: &'static [Section] = &[s("JsonWebKeyOperation", "JSON Web Key Operation")];
|
||||
|
||||
fn key(&self) -> Option<&'static str> {
|
||||
Some("JsonWebKeyOperation")
|
||||
|
@ -27,8 +27,7 @@ struct File {
|
||||
client: Arc<Client>,
|
||||
registry_name: &'static str,
|
||||
registry_url: &'static str,
|
||||
sections: Vec<&'static str>,
|
||||
sources: Vec<&'static str>,
|
||||
sections: Vec<Section>,
|
||||
items: HashMap<&'static str, Vec<EnumMember>>,
|
||||
}
|
||||
|
||||
@ -46,7 +45,6 @@ impl File {
|
||||
client,
|
||||
registry_name,
|
||||
registry_url,
|
||||
sources: Vec::new(),
|
||||
sections: Vec::new(),
|
||||
items: HashMap::new(),
|
||||
}
|
||||
@ -55,8 +53,7 @@ impl File {
|
||||
#[tracing::instrument(skip_all, fields(url))]
|
||||
async fn load<T: EnumEntry>(mut self) -> anyhow::Result<Self> {
|
||||
tracing::Span::current().record("url", &T::URL);
|
||||
self.sections.extend_from_slice(T::SECTIONS);
|
||||
self.sources.push(T::URL);
|
||||
self.sections.extend(T::sections());
|
||||
for (key, value) in T::fetch(&self.client).await? {
|
||||
self.items.entry(key).or_default().push(value);
|
||||
}
|
||||
@ -99,43 +96,43 @@ impl Display for File {
|
||||
|
||||
//! Enums from the {:?} IANA registry
|
||||
//! See <{}>
|
||||
//!
|
||||
//! Generated from:"#,
|
||||
|
||||
// Do not edit this file manually
|
||||
|
||||
use parse_display::{{Display, FromStr}};
|
||||
use schemars::JsonSchema;
|
||||
use serde::{{Deserialize, Serialize}};"#,
|
||||
self.registry_name, self.registry_url,
|
||||
)?;
|
||||
|
||||
for source in &self.sources {
|
||||
writeln!(f, "//! - <{}>", source)?;
|
||||
}
|
||||
|
||||
writeln!(
|
||||
f,
|
||||
r#"
|
||||
// Do not edit this file manually
|
||||
|
||||
use schemars::JsonSchema;
|
||||
use serde::{{Deserialize, Serialize}};"#
|
||||
)?;
|
||||
|
||||
for key in &self.sections {
|
||||
let list = if let Some(list) = self.items.get(key) {
|
||||
for section in &self.sections {
|
||||
let list = if let Some(list) = self.items.get(section.key) {
|
||||
list
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
|
||||
writeln!(f)?;
|
||||
writeln!(
|
||||
write!(
|
||||
f,
|
||||
"#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]"
|
||||
r#"
|
||||
/// {}
|
||||
///
|
||||
/// Source: <{}>
|
||||
#[derive(
|
||||
Debug, Clone, Copy, PartialEq, Eq, Hash, Display, FromStr, Serialize, Deserialize, JsonSchema,
|
||||
)]
|
||||
pub enum {} {{"#,
|
||||
section.doc,
|
||||
section.url.unwrap(),
|
||||
section.key,
|
||||
)?;
|
||||
write!(f, "pub enum {} {{", key)?;
|
||||
for member in list {
|
||||
writeln!(f)?;
|
||||
if let Some(description) = &member.description {
|
||||
writeln!(f, " /// {}", description)?;
|
||||
}
|
||||
writeln!(f, " #[serde(rename = \"{}\")]", member.value)?;
|
||||
writeln!(f, " #[display(\"{}\")]", member.value)?;
|
||||
writeln!(f, " {},", member.enum_name)?;
|
||||
}
|
||||
writeln!(f, "}}")?;
|
||||
|
@ -14,7 +14,10 @@
|
||||
|
||||
use serde::Deserialize;
|
||||
|
||||
use crate::EnumEntry;
|
||||
use crate::{
|
||||
traits::{s, Section},
|
||||
EnumEntry,
|
||||
};
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug, Deserialize)]
|
||||
@ -30,7 +33,7 @@ pub struct TokenTypeHint {
|
||||
impl EnumEntry for TokenTypeHint {
|
||||
const URL: &'static str =
|
||||
"https://www.iana.org/assignments/oauth-parameters/token-type-hint.csv";
|
||||
const SECTIONS: &'static [&'static str] = &["OAuthTokenTypeHint"];
|
||||
const SECTIONS: &'static [Section] = &[s("OAuthTokenTypeHint", "OAuth Token Type Hint")];
|
||||
|
||||
fn key(&self) -> Option<&'static str> {
|
||||
Some("OAuthTokenTypeHint")
|
||||
@ -54,7 +57,10 @@ pub struct AuthorizationEndpointResponseType {
|
||||
|
||||
impl EnumEntry for AuthorizationEndpointResponseType {
|
||||
const URL: &'static str = "https://www.iana.org/assignments/oauth-parameters/endpoint.csv";
|
||||
const SECTIONS: &'static [&'static str] = &["OAuthAuthorizationEndpointResponseType"];
|
||||
const SECTIONS: &'static [Section] = &[s(
|
||||
"OAuthAuthorizationEndpointResponseType",
|
||||
"OAuth Authorization Endpoint Response Type",
|
||||
)];
|
||||
|
||||
fn key(&self) -> Option<&'static str> {
|
||||
Some("OAuthAuthorizationEndpointResponseType")
|
||||
@ -79,7 +85,10 @@ pub struct TokenEndpointAuthenticationMethod {
|
||||
impl EnumEntry for TokenEndpointAuthenticationMethod {
|
||||
const URL: &'static str =
|
||||
"https://www.iana.org/assignments/oauth-parameters/token-endpoint-auth-method.csv";
|
||||
const SECTIONS: &'static [&'static str] = &["OAuthTokenEndpointAuthenticationMethod"];
|
||||
const SECTIONS: &'static [Section] = &[s(
|
||||
"OAuthTokenEndpointAuthenticationMethod",
|
||||
"OAuth Token Endpoint Authentication Method",
|
||||
)];
|
||||
|
||||
fn key(&self) -> Option<&'static str> {
|
||||
Some("OAuthTokenEndpointAuthenticationMethod")
|
||||
@ -104,7 +113,8 @@ pub struct PkceCodeChallengeMethod {
|
||||
impl EnumEntry for PkceCodeChallengeMethod {
|
||||
const URL: &'static str =
|
||||
"https://www.iana.org/assignments/oauth-parameters/pkce-code-challenge-method.csv";
|
||||
const SECTIONS: &'static [&'static str] = &["PkceCodeChallengeMethod"];
|
||||
const SECTIONS: &'static [Section] =
|
||||
&[s("PkceCodeChallengeMethod", "PKCE Code Challenge Method")];
|
||||
|
||||
fn key(&self) -> Option<&'static str> {
|
||||
Some("PkceCodeChallengeMethod")
|
||||
|
@ -18,6 +18,21 @@ use convert_case::{Case, Casing};
|
||||
use reqwest::Client;
|
||||
use serde::de::DeserializeOwned;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Section {
|
||||
pub key: &'static str,
|
||||
pub doc: &'static str,
|
||||
pub url: Option<&'static str>,
|
||||
}
|
||||
|
||||
pub const fn s(key: &'static str, doc: &'static str) -> Section {
|
||||
Section {
|
||||
key,
|
||||
doc,
|
||||
url: None,
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct EnumMember {
|
||||
pub value: String,
|
||||
@ -28,7 +43,17 @@ pub struct EnumMember {
|
||||
#[async_trait]
|
||||
pub trait EnumEntry: DeserializeOwned + Send + Sync {
|
||||
const URL: &'static str;
|
||||
const SECTIONS: &'static [&'static str];
|
||||
const SECTIONS: &'static [Section];
|
||||
|
||||
fn sections() -> Vec<Section> {
|
||||
Self::SECTIONS
|
||||
.iter()
|
||||
.map(|s| Section {
|
||||
url: Some(Self::URL),
|
||||
..*s
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn key(&self) -> Option<&'static str>;
|
||||
fn name(&self) -> &str;
|
||||
|
Reference in New Issue
Block a user