Files
tranquil-pds/src/oauth/db/request.rs
T
2025-12-26 20:15:45 +02:00

251 lines
5.9 KiB
Rust

use super::super::{AuthorizationRequestParameters, ClientAuth, OAuthError, RequestData};
use super::helpers::{from_json, to_json};
use sqlx::PgPool;
pub async fn create_authorization_request(
pool: &PgPool,
request_id: &str,
data: &RequestData,
) -> Result<(), OAuthError> {
let client_auth_json = match &data.client_auth {
Some(ca) => Some(to_json(ca)?),
None => None,
};
let parameters_json = to_json(&data.parameters)?;
sqlx::query!(
r#"
INSERT INTO oauth_authorization_request
(id, did, device_id, client_id, client_auth, parameters, expires_at, code)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
"#,
request_id,
data.did,
data.device_id,
data.client_id,
client_auth_json,
parameters_json,
data.expires_at,
data.code,
)
.execute(pool)
.await?;
Ok(())
}
pub async fn get_authorization_request(
pool: &PgPool,
request_id: &str,
) -> Result<Option<RequestData>, OAuthError> {
let row = sqlx::query!(
r#"
SELECT did, device_id, client_id, client_auth, parameters, expires_at, code, controller_did
FROM oauth_authorization_request
WHERE id = $1
"#,
request_id
)
.fetch_optional(pool)
.await?;
match row {
Some(r) => {
let client_auth: Option<ClientAuth> = match r.client_auth {
Some(v) => Some(from_json(v)?),
None => None,
};
let parameters: AuthorizationRequestParameters = from_json(r.parameters)?;
Ok(Some(RequestData {
client_id: r.client_id,
client_auth,
parameters,
expires_at: r.expires_at,
did: r.did,
device_id: r.device_id,
code: r.code,
controller_did: r.controller_did,
}))
}
None => Ok(None),
}
}
pub async fn set_authorization_did(
pool: &PgPool,
request_id: &str,
did: &str,
device_id: Option<&str>,
) -> Result<(), OAuthError> {
sqlx::query!(
r#"
UPDATE oauth_authorization_request
SET did = $2, device_id = $3
WHERE id = $1
"#,
request_id,
did,
device_id
)
.execute(pool)
.await?;
Ok(())
}
pub async fn update_authorization_request(
pool: &PgPool,
request_id: &str,
did: &str,
device_id: Option<&str>,
code: &str,
) -> Result<(), OAuthError> {
sqlx::query!(
r#"
UPDATE oauth_authorization_request
SET did = $2, device_id = $3, code = $4
WHERE id = $1
"#,
request_id,
did,
device_id,
code
)
.execute(pool)
.await?;
Ok(())
}
pub async fn consume_authorization_request_by_code(
pool: &PgPool,
code: &str,
) -> Result<Option<RequestData>, OAuthError> {
let row = sqlx::query!(
r#"
DELETE FROM oauth_authorization_request
WHERE code = $1
RETURNING did, device_id, client_id, client_auth, parameters, expires_at, code, controller_did
"#,
code
)
.fetch_optional(pool)
.await?;
match row {
Some(r) => {
let client_auth: Option<ClientAuth> = match r.client_auth {
Some(v) => Some(from_json(v)?),
None => None,
};
let parameters: AuthorizationRequestParameters = from_json(r.parameters)?;
Ok(Some(RequestData {
client_id: r.client_id,
client_auth,
parameters,
expires_at: r.expires_at,
did: r.did,
device_id: r.device_id,
code: r.code,
controller_did: r.controller_did,
}))
}
None => Ok(None),
}
}
pub async fn delete_authorization_request(
pool: &PgPool,
request_id: &str,
) -> Result<(), OAuthError> {
sqlx::query!(
r#"
DELETE FROM oauth_authorization_request WHERE id = $1
"#,
request_id
)
.execute(pool)
.await?;
Ok(())
}
pub async fn delete_expired_authorization_requests(pool: &PgPool) -> Result<u64, OAuthError> {
let result = sqlx::query!(
r#"
DELETE FROM oauth_authorization_request
WHERE expires_at < NOW()
"#
)
.execute(pool)
.await?;
Ok(result.rows_affected())
}
pub async fn mark_request_authenticated(
pool: &PgPool,
request_id: &str,
did: &str,
device_id: Option<&str>,
) -> Result<(), OAuthError> {
sqlx::query!(
r#"
UPDATE oauth_authorization_request
SET did = $2, device_id = $3
WHERE id = $1
"#,
request_id,
did,
device_id
)
.execute(pool)
.await?;
Ok(())
}
pub async fn update_request_scope(
pool: &PgPool,
request_id: &str,
scope: &str,
) -> Result<(), OAuthError> {
sqlx::query!(
r#"
UPDATE oauth_authorization_request
SET parameters = jsonb_set(parameters, '{scope}', to_jsonb($2::text))
WHERE id = $1
"#,
request_id,
scope
)
.execute(pool)
.await?;
Ok(())
}
pub async fn set_controller_did(
pool: &PgPool,
request_id: &str,
controller_did: &str,
) -> Result<(), OAuthError> {
sqlx::query!(
r#"
UPDATE oauth_authorization_request
SET controller_did = $2
WHERE id = $1
"#,
request_id,
controller_did
)
.execute(pool)
.await?;
Ok(())
}
pub async fn set_request_did(pool: &PgPool, request_id: &str, did: &str) -> Result<(), OAuthError> {
sqlx::query!(
r#"
UPDATE oauth_authorization_request
SET did = $2
WHERE id = $1
"#,
request_id,
did
)
.execute(pool)
.await?;
Ok(())
}