google_oauth/
error.rs

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    /// Any JSON error from [serde_json]
13    JsonError(serde_json::Error),
14    /// Any base64 decode error, from [base64]
15    Base64DecodeError(base64::DecodeError),
16    /// Error when id_token splits into 3 parts
17    IDTokenSplitError(IDTokenSplitError),
18    /// Error when id_token is expired
19    IDTokenExpiredError(IDTokenExpiredError),
20    /// Any [SystemTimeError]
21    SystemTimeError(SystemTimeError),
22    /// Error when id_token has an issuer which not listed in [GOOGLE_ISS]
23    GoogleIssuerNotMatchError(GoogleIssuerNotMatchError),
24    /// Error when id_token has a client_id which not listed when client was created.
25    IDTokenClientIDNotFoundError(IDTokenClientIDNotFoundError),
26    /// Any [rsa::signature::Error]
27    RS256SignatureError(rsa::signature::Error),
28    /// Any [rsa::errors::Error]
29    RS256Error(rsa::errors::Error),
30    /// Error when id_token has an unimplemented hash algorithm
31    HashAlgorithmUnimplementedError(HashAlgorithmUnimplementedError),
32    /// Error when alg and kid (in header of id_token) not found in any cert from google server
33    IDTokenCertNotFoundError(IDTokenCertNotFoundError),
34    /// Any [reqwest::Error]
35    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}