atomic_lti/
dynamic_registration.rs1use self::{platform_configuration::PlatformConfiguration, tool_configuration::ToolConfiguration};
2use crate::{errors::DynamicRegistrationError, request::send_request, url::parse_host};
3use reqwest::header;
4use serde::Deserialize;
5
6pub mod lti_message;
7pub mod platform_configuration;
8pub mod tool_configuration;
9
10#[derive(Deserialize, Clone, Debug)]
13pub struct DynamicRegistrationParams {
14 pub openid_configuration: String,
15 pub registration_token: Option<String>,
16}
17
18#[derive(Deserialize, Clone, Debug)]
20pub struct DynamicRegistrationFinishParams {
21 pub registration_endpoint: String,
22 pub registration_token: Option<String>,
23 pub product_family_code: Option<String>,
24}
25
26pub fn validate_platform_config(
27 platform_config: &PlatformConfiguration,
28 openid_configuration_url: &str,
29) -> Result<bool, DynamicRegistrationError> {
30 let original_host = parse_host(openid_configuration_url)?;
32 let provided_host = parse_host(&platform_config.issuer)?;
33
34 if original_host != provided_host {
35 return Err(DynamicRegistrationError::InvalidConfig(
36 "The issuer domain must match the openid-configuration URL domain".to_string(),
37 ));
38 }
39
40 Ok(true)
41}
42
43pub async fn request_platform_config(
44 openid_configuration_url: &str,
45) -> Result<PlatformConfiguration, DynamicRegistrationError> {
46 let client = reqwest::Client::new();
47 let request = client
48 .get(openid_configuration_url)
49 .header(header::ACCEPT, "application/json");
50 let body = send_request(request).await?;
51 let platform_config: PlatformConfiguration = serde_json::from_str(&body)
52 .map_err(|e| DynamicRegistrationError::RequestFailed(e.to_string()))?;
53
54 Ok(platform_config)
55}
56
57pub async fn register_tool(
59 registration_endpoint: &str,
60 registration_token: &str,
61 client_registration_request: &ToolConfiguration,
62) -> Result<ToolConfiguration, DynamicRegistrationError> {
63 let json = serde_json::to_string(&client_registration_request)
64 .map_err(|e| DynamicRegistrationError::RequestFailed(e.to_string()))?;
65 let client: reqwest::Client = reqwest::Client::new();
66 let mut request = client
67 .post(registration_endpoint)
68 .header(header::CONTENT_TYPE, "application/json")
69 .header(header::ACCEPT, "application/json")
70 .body(json);
71
72 if !registration_token.is_empty() {
73 request = request.header(
74 header::AUTHORIZATION,
75 format!("Bearer {}", registration_token),
76 );
77 }
78
79 let body = send_request(request).await?;
80 let platform_response: ToolConfiguration = serde_json::from_str(&body)
81 .map_err(|e| DynamicRegistrationError::RequestFailed(e.to_string()))?;
82
83 Ok(platform_response)
84}