Skip to main content

mas_config/sections/
oauth.rs

1// Copyright 2025, 2026 Element Creations Ltd.
2// Copyright 2025 New Vector Ltd.
3//
4// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
5// Please see LICENSE files in the repository root for full details.
6
7use schemars::JsonSchema;
8use serde::{Deserialize, Serialize};
9
10use crate::ConfigurationSection;
11
12const fn default_true() -> bool {
13    true
14}
15
16const fn default_false() -> bool {
17    false
18}
19
20#[expect(clippy::trivially_copy_pass_by_ref)]
21const fn is_default_true(value: &bool) -> bool {
22    *value == default_true()
23}
24
25#[expect(clippy::trivially_copy_pass_by_ref)]
26const fn is_default_false(value: &bool) -> bool {
27    *value == default_false()
28}
29
30/// Configuration section for OAuth 2.0 protocol options
31#[derive(Clone, Debug, Deserialize, JsonSchema, Serialize)]
32pub struct OAuthConfig {
33    /// Whether the Device Authorization Grant (RFC 8628) is enabled. Defaults
34    /// to `true`.
35    ///
36    /// When disabled, the device authorization endpoint will reject requests,
37    /// the discovery metadata will not advertise the device authorization
38    /// endpoint, and dynamic client registrations requesting the
39    /// `urn:ietf:params:oauth:grant-type:device_code` grant type will be
40    /// rejected.
41    #[serde(default = "default_true", skip_serializing_if = "is_default_true")]
42    pub device_code_grant_enabled: bool,
43
44    /// Whether the device authorization endpoint advertises a
45    /// `verification_uri_complete` that auto-fills the user code on the
46    /// `/link` page. Defaults to `false`.
47    ///
48    /// When disabled, the device authorization response will omit
49    /// `verification_uri_complete`, and the `/link` route will ignore any
50    /// `code` query parameter, forcing users to type their user code
51    /// manually.
52    #[serde(default = "default_false", skip_serializing_if = "is_default_false")]
53    pub device_code_user_code_auto_fill_enabled: bool,
54}
55
56impl Default for OAuthConfig {
57    fn default() -> Self {
58        Self {
59            device_code_grant_enabled: default_true(),
60            device_code_user_code_auto_fill_enabled: default_false(),
61        }
62    }
63}
64
65impl OAuthConfig {
66    /// Returns true if the configuration is the default one
67    pub(crate) fn is_default(&self) -> bool {
68        is_default_true(&self.device_code_grant_enabled)
69            && is_default_false(&self.device_code_user_code_auto_fill_enabled)
70    }
71}
72
73impl ConfigurationSection for OAuthConfig {
74    const PATH: Option<&'static str> = Some("oauth");
75}