systemprompt_api/routes/oauth/error/
conversions.rs1use systemprompt_config::SecretsBootstrapError;
5use systemprompt_oauth::OauthError;
6use systemprompt_traits::auth::AuthProviderError;
7
8use super::{OAuthErrorCode, OAuthHttpError};
9
10impl From<OauthError> for OAuthHttpError {
11 fn from(err: OauthError) -> Self {
12 match &err {
13 OauthError::InvalidClient(_) | OauthError::ClientNotFound(_) => {
14 Self::invalid_client(err.to_string())
15 },
16 OauthError::InvalidGrant(_)
17 | OauthError::CodeNotFound(_)
18 | OauthError::TokenNotFound(_)
19 | OauthError::PkceMismatch(_)
20 | OauthError::Expired(_) => Self::invalid_grant(err.to_string()),
21 OauthError::Validation(_) => Self::invalid_request(err.to_string()),
22 OauthError::Unauthorized(_) => Self::access_denied(err.to_string()),
23 OauthError::UsernameTaken(_) => Self::username_unavailable(
24 "Username is already taken. Please choose a different username.",
25 ),
26 OauthError::EmailRegistered(_) => {
27 Self::email_exists("An account with this email already exists.")
28 },
29 OauthError::UserNotFound(_) => Self::not_found(err.to_string()),
30 OauthError::RegistrationStateExpired => Self::expired_challenge(
31 "Registration challenge has expired. Please start the registration process again.",
32 ),
33 OauthError::WebAuthnVerificationFailed(_) => Self::invalid_credential(
34 "WebAuthn verification failed. Please ensure your authenticator and browser are \
35 compatible.",
36 ),
37 OauthError::WebAuthn(_)
38 | OauthError::User(_)
39 | OauthError::Session(_)
40 | OauthError::TokenInvalid(_)
41 | OauthError::TokenAlgMismatch { .. }
42 | OauthError::TokenMissingKid
43 | OauthError::TokenUnknownKid { .. }
44 | OauthError::Provider(_)
45 | OauthError::Repository(_)
46 | OauthError::DatabaseRepository(_)
47 | OauthError::Config(_)
48 | OauthError::Crypto(_)
49 | OauthError::Internal(_) => Self::server_error(err.to_string()),
50 }
51 }
52}
53
54impl From<AuthProviderError> for OAuthHttpError {
55 fn from(err: AuthProviderError) -> Self {
56 match &err {
57 AuthProviderError::InvalidCredentials | AuthProviderError::InvalidToken => {
58 Self::invalid_client(err.to_string())
59 },
60 AuthProviderError::UserNotFound => Self::not_found(err.to_string()),
61 AuthProviderError::TokenExpired => Self::invalid_grant(err.to_string()),
62 AuthProviderError::InsufficientPermissions => Self::access_denied(err.to_string()),
63 _ => Self::server_error(err.to_string()),
64 }
65 }
66}
67
68impl From<SecretsBootstrapError> for OAuthHttpError {
69 fn from(err: SecretsBootstrapError) -> Self {
70 Self::server_error(err.to_string())
71 }
72}
73
74impl From<sqlx::Error> for OAuthHttpError {
75 fn from(err: sqlx::Error) -> Self {
76 if let sqlx::Error::Database(db_err) = &err
77 && db_err.is_unique_violation()
78 {
79 return Self::new(OAuthErrorCode::UsernameUnavailable, err.to_string());
80 }
81 Self::server_error(err.to_string())
82 }
83}
84
85impl From<anyhow::Error> for OAuthHttpError {
86 fn from(err: anyhow::Error) -> Self {
87 Self::server_error(err.to_string())
88 }
89}