Skip to main content
Glama
jwk.rs4.96 kB
use std::collections::HashSet; use indexmap::IndexSet; use itertools::Itertools as _; use serde::{ Deserialize, Serialize, }; use super::KeyUsage; use crate::convert_v8::{ DOMException, DOMExceptionName, }; #[derive(Deserialize, Serialize, Default)] pub(super) struct JsonWebKey { #[serde(skip_serializing_if = "Option::is_none")] pub kty: Option<String>, #[serde(skip_serializing_if = "Option::is_none")] pub r#use: Option<String>, #[serde(skip_serializing_if = "Option::is_none")] pub key_ops: Option<Vec<String>>, #[serde(skip_serializing_if = "Option::is_none")] pub alg: Option<String>, #[serde(skip_serializing_if = "Option::is_none")] pub ext: Option<bool>, #[serde(skip_serializing_if = "Option::is_none")] pub crv: Option<String>, #[serde(skip_serializing_if = "Option::is_none")] pub x: Option<String>, #[serde(skip_serializing_if = "Option::is_none")] pub y: Option<String>, #[serde(skip_serializing_if = "Option::is_none")] pub d: Option<String>, #[serde(skip_serializing_if = "Option::is_none")] pub n: Option<String>, #[serde(skip_serializing_if = "Option::is_none")] pub e: Option<String>, #[serde(skip_serializing_if = "Option::is_none")] pub p: Option<String>, #[serde(skip_serializing_if = "Option::is_none")] pub q: Option<String>, #[serde(skip_serializing_if = "Option::is_none")] pub dp: Option<String>, #[serde(skip_serializing_if = "Option::is_none")] pub dq: Option<String>, #[serde(skip_serializing_if = "Option::is_none")] pub qi: Option<String>, #[serde(skip_serializing_if = "Option::is_none")] pub oth: Option<Vec<RsaOtherPrimesInfo>>, #[serde(skip_serializing_if = "Option::is_none")] pub k: Option<String>, } #[derive(Deserialize, Serialize)] pub(super) struct RsaOtherPrimesInfo { // The following fields are defined in Section 6.3.2.7 of JSON Web Algorithms #[serde(skip_serializing_if = "Option::is_none")] pub r: Option<String>, #[serde(skip_serializing_if = "Option::is_none")] pub d: Option<String>, #[serde(skip_serializing_if = "Option::is_none")] pub t: Option<String>, } impl JsonWebKey { pub(super) fn check_kty(&self, kty: &str) -> anyhow::Result<()> { anyhow::ensure!( self.kty.as_deref() == Some(kty), DOMException::new( format!("JWK \"kty\" must be {kty:?}"), DOMExceptionName::DataError ), ); Ok(()) } pub(super) fn check_crv(&self, crv: &str) -> anyhow::Result<()> { anyhow::ensure!( self.crv.as_deref() == Some(crv), DOMException::new( format!("JWK \"crv\" must be {crv:?}"), DOMExceptionName::DataError ), ); Ok(()) } pub(super) fn check_ext(&self, extractable: bool) -> anyhow::Result<()> { if let Some(false) = self.ext && extractable { anyhow::bail!(DOMException::new( "JWK \"ext\" must be true", DOMExceptionName::DataError )); } Ok(()) } pub(super) fn check_key_ops_and_use( &self, key_usages: &IndexSet<KeyUsage>, expected_use: &str, ) -> anyhow::Result<()> { if !key_usages.is_empty() && let Some(r#use) = &self.r#use { anyhow::ensure!( r#use == expected_use, DOMException::new( format!("JWK \"use\" must be {expected_use:?}"), DOMExceptionName::DataError ), ); } if let Some(key_ops) = &self.key_ops { let allowed_usages: HashSet<_> = key_ops .iter() .filter_map(|s| s.parse::<KeyUsage>().ok()) .collect(); for usage in key_usages { anyhow::ensure!( allowed_usages.contains(usage), DOMException::new( format!("JWK \"key_ops\" does not contain {usage:?}"), DOMExceptionName::DataError ), ); } } Ok(()) } pub(super) fn check_alg_oneof(&self, expected: &[&str]) -> anyhow::Result<()> { if let Some(alg) = &self.alg { anyhow::ensure!( expected.contains(&alg.as_str()), DOMException::new( format!( "JWK \"alg\" must be {}", expected.iter().map(|e| format!("{e:?}")).join(" or ") ), DOMExceptionName::DataError ), ); } Ok(()) } pub(super) fn check_alg(&self, expected: &str) -> anyhow::Result<()> { self.check_alg_oneof(&[expected]) } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/get-convex/convex-backend'

If you have feedback or need assistance with the MCP directory API, please join our Discord server