atomic_lti/dynamic_registration/
platform_configuration.rs

1use serde::{Deserialize, Serialize};
2use serde_with::skip_serializing_none;
3
4// https://www.imsglobal.org/spec/lti-dr/v1p0#platform-configuration
5#[derive(Serialize, Deserialize, Debug)]
6#[skip_serializing_none]
7pub struct PlatformConfiguration {
8  pub issuer: String,
9  pub authorization_endpoint: String,
10  pub token_endpoint: String,
11  pub token_endpoint_auth_methods_supported: Vec<String>,
12  pub token_endpoint_auth_signing_alg_values_supported: Vec<String>,
13  pub jwks_uri: String,
14  pub registration_endpoint: String,
15  pub scopes_supported: Vec<String>,
16  pub response_types_supported: Vec<String>,
17  pub subject_types_supported: Vec<String>,
18  pub id_token_signing_alg_values_supported: Vec<String>,
19  pub claims_supported: Vec<String>,
20  pub authorization_server: Option<String>,
21  #[serde(rename = "https://purl.imsglobal.org/spec/lti-platform-configuration")]
22  pub lti_platform_configuration: LtiPlatformConfiguration,
23}
24
25#[derive(Serialize, Deserialize, Debug)]
26#[skip_serializing_none]
27pub struct LtiPlatformConfiguration {
28  pub product_family_code: String,
29  pub version: String,
30  pub messages_supported: Vec<MessageSupported>,
31  pub variables: Option<Vec<String>>,
32}
33
34#[derive(Serialize, Deserialize, Debug)]
35#[skip_serializing_none]
36pub struct MessageSupported {
37  #[serde(rename = "type")]
38  pub message_type: String,
39  pub placements: Option<Vec<String>>,
40}
41
42#[cfg(test)]
43mod tests {
44  use super::*;
45  use serde_json::json;
46
47  #[test]
48  fn test_platform_configuration_deserialization() {
49    let data = json!({
50        "issuer": "https://server.example.com",
51        "authorization_endpoint":  "https://server.example.com/connect/authorize",
52        "token_endpoint": "https://server.example.com/connect/token",
53        "token_endpoint_auth_methods_supported": ["private_key_jwt"],
54        "token_endpoint_auth_signing_alg_values_supported": ["RS256"],
55        "jwks_uri": "https://server.example.com/jwks.json",
56        "registration_endpoint": "https://server.example.com/connect/register",
57        "scopes_supported": ["openid", "https://purl.imsglobal.org/spec/lti-gs/scope/contextgroup.readonly",
58           "https://purl.imsglobal.org/spec/lti-ags/scope/lineitem",
59           "https://purl.imsglobal.org/spec/lti-ags/scope/result.readonly",
60           "https://purl.imsglobal.org/spec/lti-ags/scope/score",
61           "https://purl.imsglobal.org/spec/lti-reg/scope/registration"],
62        "response_types_supported": ["id_token"],
63        "subject_types_supported": ["public", "pairwise"],
64        "id_token_signing_alg_values_supported":
65          ["RS256", "ES256"],
66        "claims_supported":
67          ["sub", "iss", "name", "given_name", "family_name", "nickname", "picture", "email", "locale"],
68         "https://purl.imsglobal.org/spec/lti-platform-configuration": {
69            "product_family_code": "ExampleLMS",
70            "version": "1.0.0",
71            "messages_supported": [
72                {"type": "LtiResourceLinkRequest"},
73                {"type": "LtiDeepLinkingRequest"}],
74            "variables": ["CourseSection.timeFrame.end", "CourseSection.timeFrame.begin", "Context.id.history", "ResourceLink.id.history"]
75        }
76    });
77
78    let config: PlatformConfiguration = serde_json::from_value(data).unwrap();
79
80    assert_eq!(config.issuer, "https://server.example.com");
81    assert_eq!(
82      config.authorization_endpoint,
83      "https://server.example.com/connect/authorize"
84    );
85    // Add more assertions for the rest of the fields...
86  }
87}