1use std::fmt::{Debug, Display, Formatter};
2use crate::GOOGLE_ISS;
3#[cfg(feature = "wasm")]
4use web_time::SystemTimeError;
5#[cfg(not(feature = "wasm"))]
6use std::time::SystemTimeError;
7
8pub type Result<T> = core::result::Result<T, Error>;
9
10#[derive(Debug)]
11pub enum Error {
12 JsonError(serde_json::Error),
14 Base64DecodeError(base64::DecodeError),
16 IDTokenSplitError(IDTokenSplitError),
18 IDTokenExpiredError(IDTokenExpiredError),
20 SystemTimeError(SystemTimeError),
22 GoogleIssuerNotMatchError(GoogleIssuerNotMatchError),
24 IDTokenClientIDNotFoundError(IDTokenClientIDNotFoundError),
26 RS256SignatureError(rsa::signature::Error),
28 RS256Error(rsa::errors::Error),
30 HashAlgorithmUnimplementedError(HashAlgorithmUnimplementedError),
32 IDTokenCertNotFoundError(IDTokenCertNotFoundError),
34 ReqwestError(reqwest::Error),
36}
37
38impl Display for Error {
39 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
40 match self {
41 Self::JsonError(e) => Display::fmt(&e, f),
42 Self::Base64DecodeError(e) => Display::fmt(&e, f),
43 Self::IDTokenSplitError(e) => Display::fmt(&e, f),
44 Self::IDTokenExpiredError(e) => Display::fmt(&e, f),
45 Self::SystemTimeError(e) => Display::fmt(&e, f),
46 Self::GoogleIssuerNotMatchError(e) => Display::fmt(&e, f),
47 Self::IDTokenClientIDNotFoundError(e) => Display::fmt(&e, f),
48 Self::RS256SignatureError(e) => Display::fmt(&e, f),
49 Self::RS256Error(e) => Display::fmt(&e, f),
50 Self::HashAlgorithmUnimplementedError(e) => Display::fmt(&e, f),
51 Self::IDTokenCertNotFoundError(e) => Display::fmt(&e, f),
52 Self::ReqwestError(e) => Display::fmt(&e, f),
53 }
54 }
55}
56
57impl std::error::Error for Error {}
58
59impl From<serde_json::Error> for Error {
60 #[inline]
61 fn from(err: serde_json::Error) -> Self {
62 Self::JsonError(err)
63 }
64}
65
66impl From<base64::DecodeError> for Error {
67 #[inline]
68 fn from(err: base64::DecodeError) -> Self {
69 Self::Base64DecodeError(err)
70 }
71}
72
73#[derive(Debug, Clone, Copy)]
74pub struct IDTokenSplitError {
75 pub expected: usize,
76 pub get: usize,
77}
78
79impl Display for IDTokenSplitError {
80 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
81 write!(f, "id_token split error, expected {} segments, but get {}", self.expected, self.get)
82 }
83}
84
85impl std::error::Error for IDTokenSplitError {}
86
87impl From<IDTokenSplitError> for Error {
88 #[inline]
89 fn from(err: IDTokenSplitError) -> Self {
90 Self::IDTokenSplitError(err)
91 }
92}
93
94impl IDTokenSplitError {
95 #[inline]
96 pub fn new(expected: usize, get: usize) -> Self {
97 Self { expected, get }
98 }
99}
100
101#[derive(Debug)]
102pub struct IDTokenExpiredError {
103 pub now: u64,
104 pub exp: u64,
105}
106
107impl IDTokenExpiredError {
108 #[inline]
109 pub fn new(now: u64, exp: u64) -> Self {
110 Self { now, exp }
111 }
112}
113
114impl From<IDTokenExpiredError> for Error {
115 #[inline]
116 fn from(err: IDTokenExpiredError) -> Self {
117 Self::IDTokenExpiredError(err)
118 }
119}
120
121impl Display for IDTokenExpiredError {
122 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
123 write!(f, "token expired, {} > {}", self.now, self.exp)
124 }
125}
126
127impl std::error::Error for IDTokenExpiredError {}
128
129impl From<SystemTimeError> for Error {
130 #[inline]
131 fn from(err: SystemTimeError) -> Self {
132 Self::SystemTimeError(err)
133 }
134}
135
136#[derive(Debug)]
137pub struct GoogleIssuerNotMatchError {
138 pub get: String,
139 pub expected: [&'static str; 2],
140}
141
142impl GoogleIssuerNotMatchError {
143 #[inline]
144 pub fn new<S: ToString>(get: S) -> Self {
145 Self {
146 get: get.to_string(),
147 expected: GOOGLE_ISS,
148 }
149 }
150}
151
152impl Display for GoogleIssuerNotMatchError {
153 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
154 write!(f, "id_token issue error, iss = {}, but expects one of {:?}", self.get, self.expected)
155 }
156}
157
158impl std::error::Error for GoogleIssuerNotMatchError {}
159
160impl From<GoogleIssuerNotMatchError> for Error {
161 #[inline]
162 fn from(err: GoogleIssuerNotMatchError) -> Self {
163 Self::GoogleIssuerNotMatchError(err)
164 }
165}
166
167#[derive(Debug)]
168pub struct IDTokenClientIDNotFoundError {
169 pub get: String,
170 pub expected: Vec<String>,
171}
172
173impl Display for IDTokenClientIDNotFoundError {
174 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
175 write!(f, "id_token client_id not found, get {}, but expected one of {:?}", &self.get, &self.expected)
176 }
177}
178
179impl std::error::Error for IDTokenClientIDNotFoundError {}
180
181impl From<IDTokenClientIDNotFoundError> for Error {
182 fn from(err: IDTokenClientIDNotFoundError) -> Self {
183 Self::IDTokenClientIDNotFoundError(err)
184 }
185}
186
187impl IDTokenClientIDNotFoundError {
188 pub fn new<S, T, V>(get: S, expected: T) -> Self
189 where
190 S: ToString,
191 T: AsRef<[V]>,
192 V: AsRef<str>
193 {
194 Self {
195 get: get.to_string(),
196 expected: expected.as_ref().iter().map(|e| e.as_ref().to_string()).collect(),
197 }
198 }
199}
200
201impl From<rsa::signature::Error> for Error {
202 #[inline]
203 fn from(err: rsa::signature::Error) -> Self {
204 Self::RS256SignatureError(err)
205 }
206}
207
208impl From<rsa::errors::Error> for Error {
209 #[inline]
210 fn from(err: rsa::errors::Error) -> Self {
211 Self::RS256Error(err)
212 }
213}
214
215#[derive(Debug)]
216pub struct HashAlgorithmUnimplementedError {
217 pub get: String,
218}
219
220impl HashAlgorithmUnimplementedError {
221 #[inline]
222 pub fn new<S: ToString>(get: S) -> Self {
223 Self { get: get.to_string() }
224 }
225}
226
227impl Display for HashAlgorithmUnimplementedError {
228 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
229 write!(f, "id_token: unimplemented hash alg: {}", self.get)
230 }
231}
232
233impl std::error::Error for HashAlgorithmUnimplementedError {}
234
235impl From<HashAlgorithmUnimplementedError> for Error {
236 #[inline]
237 fn from(err: HashAlgorithmUnimplementedError) -> Self {
238 Self::HashAlgorithmUnimplementedError(err)
239 }
240}
241
242#[derive(Debug)]
243pub struct IDTokenCertNotFoundError {
244 alg: String,
245 kid: String,
246}
247
248impl IDTokenCertNotFoundError {
249 #[inline]
250 pub fn new<S: ToString>(alg: S, kid: S) -> Self {
251 Self {
252 alg: alg.to_string(),
253 kid: kid.to_string(),
254 }
255 }
256}
257
258impl Display for IDTokenCertNotFoundError {
259 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
260 write!(f, "alg={}, kid={} not found in google certs", &self.alg, &self.kid)
261 }
262}
263
264impl std::error::Error for IDTokenCertNotFoundError {}
265
266impl From<IDTokenCertNotFoundError> for Error {
267 #[inline]
268 fn from(err: IDTokenCertNotFoundError) -> Self {
269 Self::IDTokenCertNotFoundError(err)
270 }
271}
272
273impl From<reqwest::Error> for Error {
274 #[inline]
275 fn from(err: reqwest::Error) -> Self {
276 Self::ReqwestError(err)
277 }
278}