this repo has no description
1use super::super::OAuthError;
2use serde::{Deserialize, Serialize};
3use sqlx::PgPool;
4
5#[derive(Debug, Clone, Serialize, Deserialize)]
6pub struct ScopePreference {
7 pub scope: String,
8 pub granted: bool,
9}
10
11pub async fn get_scope_preferences(
12 pool: &PgPool,
13 did: &str,
14 client_id: &str,
15) -> Result<Vec<ScopePreference>, OAuthError> {
16 let rows = sqlx::query!(
17 r#"
18 SELECT scope, granted FROM oauth_scope_preference
19 WHERE did = $1 AND client_id = $2
20 "#,
21 did,
22 client_id
23 )
24 .fetch_all(pool)
25 .await?;
26
27 Ok(rows
28 .into_iter()
29 .map(|r| ScopePreference {
30 scope: r.scope,
31 granted: r.granted,
32 })
33 .collect())
34}
35
36pub async fn upsert_scope_preferences(
37 pool: &PgPool,
38 did: &str,
39 client_id: &str,
40 prefs: &[ScopePreference],
41) -> Result<(), OAuthError> {
42 for pref in prefs {
43 sqlx::query!(
44 r#"
45 INSERT INTO oauth_scope_preference (did, client_id, scope, granted, created_at, updated_at)
46 VALUES ($1, $2, $3, $4, NOW(), NOW())
47 ON CONFLICT (did, client_id, scope) DO UPDATE SET granted = $4, updated_at = NOW()
48 "#,
49 did,
50 client_id,
51 pref.scope,
52 pref.granted
53 )
54 .execute(pool)
55 .await?;
56 }
57 Ok(())
58}
59
60pub async fn should_show_consent(
61 pool: &PgPool,
62 did: &str,
63 client_id: &str,
64 requested_scopes: &[String],
65) -> Result<bool, OAuthError> {
66 if requested_scopes.is_empty() {
67 return Ok(false);
68 }
69
70 let stored_prefs = get_scope_preferences(pool, did, client_id).await?;
71 if stored_prefs.is_empty() {
72 return Ok(true);
73 }
74
75 let stored_scopes: std::collections::HashSet<&str> =
76 stored_prefs.iter().map(|p| p.scope.as_str()).collect();
77
78 for scope in requested_scopes {
79 if !stored_scopes.contains(scope.as_str()) {
80 return Ok(true);
81 }
82 }
83
84 Ok(false)
85}
86
87pub async fn delete_scope_preferences(
88 pool: &PgPool,
89 did: &str,
90 client_id: &str,
91) -> Result<(), OAuthError> {
92 sqlx::query!(
93 r#"
94 DELETE FROM oauth_scope_preference
95 WHERE did = $1 AND client_id = $2
96 "#,
97 did,
98 client_id
99 )
100 .execute(pool)
101 .await?;
102 Ok(())
103}