Skip to main content

moq_token/
algorithm.rs

1use crate::Error;
2use std::{fmt, str::FromStr};
3
4/// A subset of jsonwebtoken algorithms.
5///
6/// We could support all of them, but there's currently no point using public key crypto.
7/// The relay can fetch any resource it wants; it doesn't need to forge tokens.
8///
9#[derive(Clone, Copy, Debug, serde::Serialize, serde::Deserialize, PartialEq, Eq, Hash)]
10pub enum Algorithm {
11	HS256,
12	HS384,
13	HS512,
14	ES256,
15	ES384,
16	RS256,
17	RS384,
18	RS512,
19	PS256,
20	PS384,
21	PS512,
22	EdDSA,
23}
24
25impl From<Algorithm> for jsonwebtoken::Algorithm {
26	fn from(val: Algorithm) -> Self {
27		match val {
28			Algorithm::HS256 => jsonwebtoken::Algorithm::HS256,
29			Algorithm::HS384 => jsonwebtoken::Algorithm::HS384,
30			Algorithm::HS512 => jsonwebtoken::Algorithm::HS512,
31			Algorithm::ES256 => jsonwebtoken::Algorithm::ES256,
32			Algorithm::ES384 => jsonwebtoken::Algorithm::ES384,
33			Algorithm::RS256 => jsonwebtoken::Algorithm::RS256,
34			Algorithm::RS384 => jsonwebtoken::Algorithm::RS384,
35			Algorithm::RS512 => jsonwebtoken::Algorithm::RS512,
36			Algorithm::PS256 => jsonwebtoken::Algorithm::PS256,
37			Algorithm::PS384 => jsonwebtoken::Algorithm::PS384,
38			Algorithm::PS512 => jsonwebtoken::Algorithm::PS512,
39			Algorithm::EdDSA => jsonwebtoken::Algorithm::EdDSA,
40		}
41	}
42}
43
44impl FromStr for Algorithm {
45	type Err = Error;
46
47	fn from_str(s: &str) -> Result<Self, Self::Err> {
48		match s {
49			"HS256" => Ok(Algorithm::HS256),
50			"HS384" => Ok(Algorithm::HS384),
51			"HS512" => Ok(Algorithm::HS512),
52			"ES256" => Ok(Algorithm::ES256),
53			"ES384" => Ok(Algorithm::ES384),
54			"RS256" => Ok(Algorithm::RS256),
55			"RS384" => Ok(Algorithm::RS384),
56			"RS512" => Ok(Algorithm::RS512),
57			"PS256" => Ok(Algorithm::PS256),
58			"PS384" => Ok(Algorithm::PS384),
59			"PS512" => Ok(Algorithm::PS512),
60			"EdDSA" => Ok(Algorithm::EdDSA),
61			_ => Err(Error::InvalidAlgorithm(s.to_string())),
62		}
63	}
64}
65
66impl fmt::Display for Algorithm {
67	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
68		match self {
69			Algorithm::HS256 => write!(f, "HS256"),
70			Algorithm::HS384 => write!(f, "HS384"),
71			Algorithm::HS512 => write!(f, "HS512"),
72			Algorithm::ES256 => write!(f, "ES256"),
73			Algorithm::ES384 => write!(f, "ES384"),
74			Algorithm::RS256 => write!(f, "RS256"),
75			Algorithm::RS384 => write!(f, "RS384"),
76			Algorithm::RS512 => write!(f, "RS512"),
77			Algorithm::PS256 => write!(f, "PS256"),
78			Algorithm::PS384 => write!(f, "PS384"),
79			Algorithm::PS512 => write!(f, "PS512"),
80			Algorithm::EdDSA => write!(f, "EdDSA"),
81		}
82	}
83}
84
85#[cfg(test)]
86mod tests {
87	use super::*;
88
89	#[test]
90	fn test_algorithm_from_str_valid() {
91		assert_eq!(Algorithm::from_str("HS256").unwrap(), Algorithm::HS256);
92		assert_eq!(Algorithm::from_str("HS384").unwrap(), Algorithm::HS384);
93		assert_eq!(Algorithm::from_str("HS512").unwrap(), Algorithm::HS512);
94		assert_eq!(Algorithm::from_str("ES256").unwrap(), Algorithm::ES256);
95		assert_eq!(Algorithm::from_str("ES384").unwrap(), Algorithm::ES384);
96		assert_eq!(Algorithm::from_str("RS256").unwrap(), Algorithm::RS256);
97		assert_eq!(Algorithm::from_str("RS384").unwrap(), Algorithm::RS384);
98		assert_eq!(Algorithm::from_str("RS512").unwrap(), Algorithm::RS512);
99		assert_eq!(Algorithm::from_str("PS256").unwrap(), Algorithm::PS256);
100		assert_eq!(Algorithm::from_str("PS384").unwrap(), Algorithm::PS384);
101		assert_eq!(Algorithm::from_str("PS512").unwrap(), Algorithm::PS512);
102		assert_eq!(Algorithm::from_str("EdDSA").unwrap(), Algorithm::EdDSA);
103	}
104
105	#[test]
106	fn test_algorithm_from_str_invalid() {
107		assert!(Algorithm::from_str("HS128").is_err());
108		assert!(Algorithm::from_str("RS128").is_err());
109		assert!(Algorithm::from_str("ES512").is_err());
110		assert!(Algorithm::from_str("EDDSA").is_err());
111		assert!(Algorithm::from_str("invalid").is_err());
112		assert!(Algorithm::from_str("").is_err());
113	}
114
115	#[test]
116	fn test_algorithm_display() {
117		assert_eq!(Algorithm::HS256.to_string(), "HS256");
118		assert_eq!(Algorithm::HS384.to_string(), "HS384");
119		assert_eq!(Algorithm::HS512.to_string(), "HS512");
120		assert_eq!(Algorithm::ES256.to_string(), "ES256");
121		assert_eq!(Algorithm::ES384.to_string(), "ES384");
122		assert_eq!(Algorithm::RS256.to_string(), "RS256");
123		assert_eq!(Algorithm::RS384.to_string(), "RS384");
124		assert_eq!(Algorithm::RS512.to_string(), "RS512");
125		assert_eq!(Algorithm::PS256.to_string(), "PS256");
126		assert_eq!(Algorithm::PS384.to_string(), "PS384");
127		assert_eq!(Algorithm::PS512.to_string(), "PS512");
128		assert_eq!(Algorithm::EdDSA.to_string(), "EdDSA");
129	}
130
131	#[test]
132	fn test_algorithm_to_jsonwebtoken_algorithm() {
133		assert_eq!(
134			jsonwebtoken::Algorithm::from(Algorithm::HS256),
135			jsonwebtoken::Algorithm::HS256
136		);
137		assert_eq!(
138			jsonwebtoken::Algorithm::from(Algorithm::HS384),
139			jsonwebtoken::Algorithm::HS384
140		);
141		assert_eq!(
142			jsonwebtoken::Algorithm::from(Algorithm::HS512),
143			jsonwebtoken::Algorithm::HS512
144		);
145		assert_eq!(
146			jsonwebtoken::Algorithm::from(Algorithm::ES256),
147			jsonwebtoken::Algorithm::ES256
148		);
149		assert_eq!(
150			jsonwebtoken::Algorithm::from(Algorithm::ES384),
151			jsonwebtoken::Algorithm::ES384
152		);
153		assert_eq!(
154			jsonwebtoken::Algorithm::from(Algorithm::RS256),
155			jsonwebtoken::Algorithm::RS256
156		);
157		assert_eq!(
158			jsonwebtoken::Algorithm::from(Algorithm::RS384),
159			jsonwebtoken::Algorithm::RS384
160		);
161		assert_eq!(
162			jsonwebtoken::Algorithm::from(Algorithm::RS512),
163			jsonwebtoken::Algorithm::RS512
164		);
165		assert_eq!(
166			jsonwebtoken::Algorithm::from(Algorithm::PS256),
167			jsonwebtoken::Algorithm::PS256
168		);
169		assert_eq!(
170			jsonwebtoken::Algorithm::from(Algorithm::PS384),
171			jsonwebtoken::Algorithm::PS384
172		);
173		assert_eq!(
174			jsonwebtoken::Algorithm::from(Algorithm::PS512),
175			jsonwebtoken::Algorithm::PS512
176		);
177		assert_eq!(
178			jsonwebtoken::Algorithm::from(Algorithm::EdDSA),
179			jsonwebtoken::Algorithm::EdDSA
180		);
181	}
182
183	#[test]
184	fn test_algorithm_serde() {
185		let alg = Algorithm::HS256;
186		let json = serde_json::to_string(&alg).unwrap();
187		assert_eq!(json, "\"HS256\"");
188
189		let deserialized: Algorithm = serde_json::from_str(&json).unwrap();
190		assert_eq!(deserialized, alg);
191	}
192
193	#[test]
194	fn test_algorithm_equality() {
195		assert_eq!(Algorithm::HS256, Algorithm::HS256);
196		assert_ne!(Algorithm::HS256, Algorithm::HS384);
197		assert_ne!(Algorithm::HS384, Algorithm::HS512);
198		assert_eq!(Algorithm::ES256, Algorithm::ES256);
199		assert_eq!(Algorithm::ES384, Algorithm::ES384);
200		assert_ne!(Algorithm::HS384, Algorithm::ES256);
201		assert_ne!(Algorithm::ES256, Algorithm::ES384);
202		assert_eq!(Algorithm::RS256, Algorithm::RS256);
203		assert_eq!(Algorithm::RS384, Algorithm::RS384);
204		assert_eq!(Algorithm::RS512, Algorithm::RS512);
205		assert_ne!(Algorithm::RS256, Algorithm::RS512);
206		assert_ne!(Algorithm::RS256, Algorithm::PS256);
207		assert_eq!(Algorithm::PS256, Algorithm::PS256);
208		assert_eq!(Algorithm::PS384, Algorithm::PS384);
209		assert_eq!(Algorithm::PS512, Algorithm::PS512);
210		assert_ne!(Algorithm::PS256, Algorithm::PS512);
211		assert_eq!(Algorithm::EdDSA, Algorithm::EdDSA);
212		assert_ne!(Algorithm::EdDSA, Algorithm::ES256);
213		assert_ne!(Algorithm::EdDSA, Algorithm::RS512);
214	}
215
216	#[test]
217	fn test_algorithm_clone() {
218		let alg = Algorithm::HS256;
219		let cloned = alg;
220		assert_eq!(alg, cloned);
221	}
222}