Skip to main content

openauth_plugins/admin/
options.rs

1use std::collections::BTreeMap;
2
3use serde_json::json;
4
5use super::access::{default_roles, Role};
6
7#[derive(Debug, Clone, PartialEq, Eq)]
8pub struct AdminOptions {
9    pub default_role: String,
10    pub admin_roles: Vec<String>,
11    pub default_ban_reason: Option<String>,
12    pub default_ban_expires_in: Option<i64>,
13    pub impersonation_session_duration: i64,
14    pub roles: BTreeMap<String, Role>,
15    pub admin_user_ids: Vec<String>,
16    pub banned_user_message: String,
17    pub allow_impersonating_admins: bool,
18    pub schema: AdminSchemaOptions,
19}
20
21#[derive(Debug, Clone, PartialEq, Eq)]
22pub struct AdminSchemaOptions {
23    pub user_role_field: String,
24    pub user_banned_field: String,
25    pub user_ban_reason_field: String,
26    pub user_ban_expires_field: String,
27    pub session_impersonated_by_field: String,
28}
29
30impl Default for AdminOptions {
31    fn default() -> Self {
32        Self {
33            default_role: "user".to_owned(),
34            admin_roles: vec!["admin".to_owned()],
35            default_ban_reason: None,
36            default_ban_expires_in: None,
37            impersonation_session_duration: 60 * 60,
38            roles: default_roles(),
39            admin_user_ids: Vec::new(),
40            banned_user_message: "You have been banned from this application. Please contact support if you believe this is an error.".to_owned(),
41            allow_impersonating_admins: false,
42            schema: AdminSchemaOptions::default(),
43        }
44    }
45}
46
47impl Default for AdminSchemaOptions {
48    fn default() -> Self {
49        Self {
50            user_role_field: "role".to_owned(),
51            user_banned_field: "banned".to_owned(),
52            user_ban_reason_field: "ban_reason".to_owned(),
53            user_ban_expires_field: "ban_expires".to_owned(),
54            session_impersonated_by_field: "impersonated_by".to_owned(),
55        }
56    }
57}
58
59impl AdminOptions {
60    pub fn with_defaults(mut self) -> Self {
61        if self.default_role.trim().is_empty() {
62            self.default_role = "user".to_owned();
63        }
64        if self.admin_roles.is_empty() {
65            self.admin_roles = vec!["admin".to_owned()];
66        }
67        if self.impersonation_session_duration <= 0 {
68            self.impersonation_session_duration = 60 * 60;
69        }
70        if self.roles.is_empty() {
71            self.roles = default_roles();
72        }
73        if self.banned_user_message.trim().is_empty() {
74            self.banned_user_message = Self::default().banned_user_message;
75        }
76        self.schema = self.schema.with_defaults();
77        self
78    }
79
80    pub fn validate(&self) -> Result<(), String> {
81        for role in &self.admin_roles {
82            if !self
83                .roles
84                .keys()
85                .any(|candidate: &String| candidate.eq_ignore_ascii_case(role))
86            {
87                return Err(format!(
88                    "Invalid admin role `{role}`. Admin roles must be defined in roles."
89                ));
90            }
91        }
92        Ok(())
93    }
94
95    pub fn to_json(&self) -> serde_json::Value {
96        json!({
97            "defaultRole": self.default_role,
98            "adminRoles": self.admin_roles,
99            "adminUserIds": self.admin_user_ids,
100            "bannedUserMessage": self.banned_user_message,
101            "allowImpersonatingAdmins": self.allow_impersonating_admins,
102        })
103    }
104}
105
106impl AdminSchemaOptions {
107    fn with_defaults(mut self) -> Self {
108        let defaults = Self::default();
109        if self.user_role_field.trim().is_empty() {
110            self.user_role_field = defaults.user_role_field;
111        }
112        if self.user_banned_field.trim().is_empty() {
113            self.user_banned_field = defaults.user_banned_field;
114        }
115        if self.user_ban_reason_field.trim().is_empty() {
116            self.user_ban_reason_field = defaults.user_ban_reason_field;
117        }
118        if self.user_ban_expires_field.trim().is_empty() {
119            self.user_ban_expires_field = defaults.user_ban_expires_field;
120        }
121        if self.session_impersonated_by_field.trim().is_empty() {
122            self.session_impersonated_by_field = defaults.session_impersonated_by_field;
123        }
124        self
125    }
126}