Skip to main content

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    /// An emailed link to accept or decline an invitation.
17    #[sqlx(rename = "invitation")]
18    Invitation,
19    /// A SMART EHR launch: the opaque `launch` value an app is started with,
20    /// standing for the patient (and encounter) it is launched for.
21    #[sqlx(rename = "smart_launch")]
22    SmartLaunch,
23}
24
25#[derive(Clone, Debug, PartialEq, PartialOrd, sqlx::Type, serde::Deserialize, serde::Serialize)]
26#[sqlx(type_name = "pkce_method")] // only for PostgreSQL to match a type definition
27pub enum PKCECodeChallengeMethod {
28    S256,
29}
30
31impl<'a> TryFrom<&'a str> for PKCECodeChallengeMethod {
32    type Error = OperationOutcomeError;
33
34    fn try_from(value: &'a str) -> Result<Self, Self::Error> {
35        match value {
36            "S256" => Ok(PKCECodeChallengeMethod::S256),
37            _ => Err(OperationOutcomeError::error(
38                IssueType::invalid(),
39                "Invalid PKCE code challenge method.".to_string(),
40            )),
41        }
42    }
43}
44
45impl From<PKCECodeChallengeMethod> for String {
46    fn from(method: PKCECodeChallengeMethod) -> Self {
47        match method {
48            PKCECodeChallengeMethod::S256 => "S256".to_string(),
49        }
50    }
51}
52
53pub struct AuthorizationCodeSearchClaims {
54    pub client_id: Option<String>,
55    pub code: Option<String>,
56    pub kind: Option<AuthorizationCodeKind>,
57    pub user_id: Option<String>,
58    pub user_agent: Option<String>,
59    pub is_expired: Option<bool>,
60}
61
62pub struct CreateAuthorizationCode {
63    pub membership: Option<String>,
64    pub expires_in: Duration,
65    pub kind: AuthorizationCodeKind,
66    pub user_id: String,
67    pub client_id: Option<String>,
68    pub pkce_code_challenge: Option<String>,
69    pub pkce_code_challenge_method: Option<PKCECodeChallengeMethod>,
70    pub redirect_uri: Option<String>,
71    pub meta: Option<Json<serde_json::Value>>,
72}
73
74#[derive(sqlx::FromRow, Debug)]
75pub struct AuthorizationCode {
76    pub membership: Option<String>,
77    pub tenant: TenantId,
78    pub is_expired: Option<bool>,
79    pub kind: AuthorizationCodeKind,
80    pub code: String,
81    pub user_id: String,
82    pub project: Option<ProjectId>,
83    pub client_id: Option<String>,
84    pub pkce_code_challenge: Option<String>,
85    pub pkce_code_challenge_method: Option<PKCECodeChallengeMethod>,
86    pub redirect_uri: Option<String>,
87    pub meta: Option<Json<serde_json::Value>>,
88    pub created_at: Option<OffsetDateTime>,
89}
90
91#[derive(OperationOutcomeError)]
92pub enum CodeErrors {
93    #[error(code = "invalid", diagnostic = "Invalid duration for expires.")]
94    InvalidDuration,
95}