haste_repository/types/
authorization_code.rs

1use haste_fhir_model::r4::generated::terminology::IssueType;
2use haste_fhir_operation_error::{OperationOutcomeError, derive::OperationOutcomeError};
3use haste_jwt::{ProjectId, TenantId};
4use sqlx::types::{Json, time::OffsetDateTime};
5use std::time::Duration;
6
7#[derive(Clone, Debug, PartialEq, PartialOrd, sqlx::Type, serde::Deserialize, serde::Serialize)]
8#[sqlx(type_name = "code_kind", rename_all = "lowercase")] // only for PostgreSQL to match a type definition
9pub enum AuthorizationCodeKind {
10    #[sqlx(rename = "password_reset")]
11    PasswordReset,
12    #[sqlx(rename = "oauth2_code_grant")]
13    OAuth2CodeGrant,
14    #[sqlx(rename = "refresh_token")]
15    RefreshToken,
16}
17
18#[derive(Clone, Debug, PartialEq, PartialOrd, sqlx::Type, serde::Deserialize, serde::Serialize)]
19#[sqlx(type_name = "pkce_method")] // only for PostgreSQL to match a type definition
20pub enum PKCECodeChallengeMethod {
21    S256,
22    #[sqlx(rename = "plain")]
23    Plain,
24}
25
26impl<'a> TryFrom<&'a str> for PKCECodeChallengeMethod {
27    type Error = OperationOutcomeError;
28
29    fn try_from(value: &'a str) -> Result<Self, Self::Error> {
30        match value {
31            "S256" => Ok(PKCECodeChallengeMethod::S256),
32            "plain" => Ok(PKCECodeChallengeMethod::Plain),
33            _ => Err(OperationOutcomeError::error(
34                IssueType::Invalid(None),
35                "Invalid PKCE code challenge method.".to_string(),
36            )),
37        }
38    }
39}
40
41impl From<PKCECodeChallengeMethod> for String {
42    fn from(method: PKCECodeChallengeMethod) -> Self {
43        match method {
44            PKCECodeChallengeMethod::S256 => "S256".to_string(),
45            PKCECodeChallengeMethod::Plain => "plain".to_string(),
46        }
47    }
48}
49
50pub struct AuthorizationCodeSearchClaims {
51    pub client_id: Option<String>,
52    pub code: Option<String>,
53    pub kind: Option<AuthorizationCodeKind>,
54    pub user_id: Option<String>,
55    pub user_agent: Option<String>,
56    pub is_expired: Option<bool>,
57}
58
59pub struct CreateAuthorizationCode {
60    pub membership: Option<String>,
61    pub expires_in: Duration,
62    pub kind: AuthorizationCodeKind,
63    pub user_id: String,
64    pub client_id: Option<String>,
65    pub pkce_code_challenge: Option<String>,
66    pub pkce_code_challenge_method: Option<PKCECodeChallengeMethod>,
67    pub redirect_uri: Option<String>,
68    pub meta: Option<Json<serde_json::Value>>,
69}
70
71#[derive(sqlx::FromRow, Debug)]
72pub struct AuthorizationCode {
73    pub membership: Option<String>,
74    pub tenant: TenantId,
75    pub is_expired: Option<bool>,
76    pub kind: AuthorizationCodeKind,
77    pub code: String,
78    pub user_id: String,
79    pub project: Option<ProjectId>,
80    pub client_id: Option<String>,
81    pub pkce_code_challenge: Option<String>,
82    pub pkce_code_challenge_method: Option<PKCECodeChallengeMethod>,
83    pub redirect_uri: Option<String>,
84    pub meta: Option<Json<serde_json::Value>>,
85    pub created_at: Option<OffsetDateTime>,
86}
87
88#[derive(OperationOutcomeError)]
89pub enum CodeErrors {
90    #[error(code = "invalid", diagnostic = "Invalid duration for expires.")]
91    InvalidDuration,
92}