headless_lms_server/programs/seed/
seed_oauth_clients.rs1use std::str::FromStr;
2
3use headless_lms_models::{
4 library::oauth::{Digest, GrantTypeName, pkce},
5 oauth_client,
6};
7use sqlx::{Pool, Postgres};
8use uuid::Uuid;
9
10pub struct SeedOAuthClientsResult {
11 pub client_db_id: Uuid,
12}
13
14pub async fn seed_oauth_clients(db_pool: Pool<Postgres>) -> anyhow::Result<SeedOAuthClientsResult> {
15 info!("Inserting OAuth Clients");
16 let secret =
17 Digest::from_str("396b544a35b29f7d613452a165dcaebf4d71b80e981e687e91ce6d9ba9679cb2")
18 .unwrap(); let mut conn = db_pool.acquire().await?;
20 let mut redirect_uris: Vec<String> = (8765..=8784)
23 .map(|p| format!("http://127.0.0.1:{p}/callback"))
24 .collect();
25 redirect_uris.push("https://localhost.emobix.co.uk:8443/test/a/testing/callback".to_string());
26
27 let scopes = vec![
28 "openid".to_string(),
29 "profile".to_string(),
30 "email".to_string(),
31 "offline_access".to_string(),
32 ];
33 let allowed_grant_types = vec![
34 GrantTypeName::AuthorizationCode,
35 GrantTypeName::RefreshToken,
36 ];
37 let pkce_methods_allowed = vec![pkce::PkceMethod::S256];
38 let allowed_origins = vec!["http://localhost".to_string()];
39
40 let new_client_parms = oauth_client::NewClientParams {
41 client_name: "Test Client",
42 application_type: oauth_client::ApplicationType::Web,
43 client_id: "test-client-id",
44 client_secret: Some(&secret), client_secret_expires_at: None,
46 redirect_uris: redirect_uris.as_slice(),
47 allowed_grant_types: &allowed_grant_types,
48 scopes: scopes.as_slice(),
49 allowed_origins: Some(allowed_origins.as_slice()),
50 bearer_allowed: true,
51 pkce_methods_allowed: &pkce_methods_allowed,
52 post_logout_redirect_uris: None,
53 require_pkce: true,
54 token_endpoint_auth_method: oauth_client::TokenEndpointAuthMethod::ClientSecretPost,
55 };
56
57 let client = if let Some(existing) =
58 oauth_client::OAuthClient::find_by_client_id_optional(&mut conn, "test-client-id").await?
59 {
60 existing
61 } else {
62 oauth_client::OAuthClient::insert(&mut conn, new_client_parms).await?
63 };
64
65 let new_client_parms_2 = oauth_client::NewClientParams {
66 client_name: "Test Client 2",
67 application_type: oauth_client::ApplicationType::Web,
68 client_id: "test-client-id-2",
69 client_secret: Some(&secret), client_secret_expires_at: None,
71 redirect_uris: redirect_uris.as_slice(),
72 allowed_grant_types: &allowed_grant_types,
73 scopes: scopes.as_slice(),
74 allowed_origins: Some(allowed_origins.as_slice()),
75 bearer_allowed: true,
76 pkce_methods_allowed: &pkce_methods_allowed,
77 post_logout_redirect_uris: None,
78 require_pkce: false,
79 token_endpoint_auth_method: oauth_client::TokenEndpointAuthMethod::ClientSecretPost,
80 };
81 if oauth_client::OAuthClient::find_by_client_id_optional(&mut conn, "test-client-id-2")
82 .await?
83 .is_none()
84 {
85 let _client_2 = oauth_client::OAuthClient::insert(&mut conn, new_client_parms_2).await?;
86 }
87
88 let new_client_parms_3 = oauth_client::NewClientParams {
89 client_name: "Test Client 3",
90 application_type: oauth_client::ApplicationType::Web,
91 client_id: "test-client-id-3",
92 client_secret: Some(&secret), client_secret_expires_at: None,
94 redirect_uris: redirect_uris.as_slice(),
95 allowed_grant_types: &allowed_grant_types,
96 scopes: scopes.as_slice(),
97 allowed_origins: Some(allowed_origins.as_slice()),
98 bearer_allowed: true,
99 pkce_methods_allowed: &pkce_methods_allowed,
100 post_logout_redirect_uris: None,
101 require_pkce: false,
102 token_endpoint_auth_method: oauth_client::TokenEndpointAuthMethod::ClientSecretPost,
103 };
104 if oauth_client::OAuthClient::find_by_client_id_optional(&mut conn, "test-client-id-3")
105 .await?
106 .is_none()
107 {
108 let _client_3 = oauth_client::OAuthClient::insert(&mut conn, new_client_parms_3).await?;
109 }
110
111 Ok(SeedOAuthClientsResult {
112 client_db_id: client.id,
113 })
114}