1 /// Configure OpenId realms
3 use anyhow
::{bail, Error}
;
5 use ::serde
::{Deserialize, Serialize}
;
7 use proxmox
::api
::{api, Permission, Router, RpcEnvironment}
;
10 PROXMOX_CONFIG_DIGEST_SCHEMA
, REALM_ID_SCHEMA
, PRIV_SYS_AUDIT
, PRIV_REALM_ALLOCATE
,
12 use pbs_config
::domains
::{self, OpenIdRealmConfig, OpenIdRealmConfigUpdater}
;
19 description
: "List of configured OpenId realms.",
21 items
: { type: OpenIdRealmConfig }
,
24 permission
: &Permission
::Privilege(&["access", "domains"], PRIV_REALM_ALLOCATE
, false),
27 /// List configured OpenId realms
28 pub fn list_openid_realms(
30 mut rpcenv
: &mut dyn RpcEnvironment
,
31 ) -> Result
<Vec
<OpenIdRealmConfig
>, Error
> {
33 let (config
, digest
) = domains
::config()?
;
35 let list
= config
.convert_to_typed_array("openid")?
;
37 rpcenv
["digest"] = proxmox
::tools
::digest_to_hex(&digest
).into();
47 type: OpenIdRealmConfig
,
53 permission
: &Permission
::Privilege(&["access", "domains"], PRIV_REALM_ALLOCATE
, false),
56 /// Create a new OpenId realm
57 pub fn create_openid_realm(config
: OpenIdRealmConfig
) -> Result
<(), Error
> {
59 let _lock
= domains
::lock_config()?
;
61 let (mut domains
, _digest
) = domains
::config()?
;
63 if config
.realm
== "pbs" ||
64 config
.realm
== "pam" ||
65 domains
.sections
.get(&config
.realm
).is_some()
67 bail
!("realm '{}' already exists.", config
.realm
);
70 domains
.set_data(&config
.realm
, "openid", &config
)?
;
72 domains
::save_config(&domains
)?
;
82 schema
: REALM_ID_SCHEMA
,
86 schema
: PROXMOX_CONFIG_DIGEST_SCHEMA
,
91 permission
: &Permission
::Privilege(&["access", "domains"], PRIV_REALM_ALLOCATE
, false),
94 /// Remove a OpenID realm configuration
95 pub fn delete_openid_realm(
97 digest
: Option
<String
>,
98 _rpcenv
: &mut dyn RpcEnvironment
,
99 ) -> Result
<(), Error
> {
101 let _lock
= domains
::lock_config()?
;
103 let (mut domains
, expected_digest
) = domains
::config()?
;
105 if let Some(ref digest
) = digest
{
106 let digest
= proxmox
::tools
::hex_to_digest(digest
)?
;
107 crate::tools
::detect_modified_configuration_file(&digest
, &expected_digest
)?
;
110 if domains
.sections
.remove(&realm
).is_none() {
111 bail
!("realm '{}' does not exist.", realm
);
114 domains
::save_config(&domains
)?
;
123 schema
: REALM_ID_SCHEMA
,
127 returns
: { type: OpenIdRealmConfig }
,
129 permission
: &Permission
::Privilege(&["access", "domains"], PRIV_SYS_AUDIT
, false),
132 /// Read the OpenID realm configuration
133 pub fn read_openid_realm(
135 mut rpcenv
: &mut dyn RpcEnvironment
,
136 ) -> Result
<OpenIdRealmConfig
, Error
> {
138 let (domains
, digest
) = domains
::config()?
;
140 let config
= domains
.lookup("openid", &realm
)?
;
142 rpcenv
["digest"] = proxmox
::tools
::digest_to_hex(&digest
).into();
148 #[derive(Serialize, Deserialize)]
149 #[serde(rename_all="kebab-case")]
150 #[allow(non_camel_case_types)]
151 /// Deletable property name
152 pub enum DeletableProperty
{
153 /// Delete the client key.
155 /// Delete the comment property.
157 /// Delete the autocreate property
166 schema
: REALM_ID_SCHEMA
,
169 type: OpenIdRealmConfigUpdater
,
173 description
: "List of properties to delete.",
177 type: DeletableProperty
,
182 schema
: PROXMOX_CONFIG_DIGEST_SCHEMA
,
186 returns
: { type: OpenIdRealmConfig }
,
188 permission
: &Permission
::Privilege(&["access", "domains"], PRIV_REALM_ALLOCATE
, false),
191 /// Update an OpenID realm configuration
192 pub fn update_openid_realm(
194 update
: OpenIdRealmConfigUpdater
,
195 delete
: Option
<Vec
<DeletableProperty
>>,
196 digest
: Option
<String
>,
197 _rpcenv
: &mut dyn RpcEnvironment
,
198 ) -> Result
<(), Error
> {
200 let _lock
= domains
::lock_config()?
;
202 let (mut domains
, expected_digest
) = domains
::config()?
;
204 if let Some(ref digest
) = digest
{
205 let digest
= proxmox
::tools
::hex_to_digest(digest
)?
;
206 crate::tools
::detect_modified_configuration_file(&digest
, &expected_digest
)?
;
209 let mut config
: OpenIdRealmConfig
= domains
.lookup("openid", &realm
)?
;
211 if let Some(delete
) = delete
{
212 for delete_prop
in delete
{
214 DeletableProperty
::client_key
=> { config.client_key = None; }
,
215 DeletableProperty
::comment
=> { config.comment = None; }
,
216 DeletableProperty
::autocreate
=> { config.autocreate = None; }
,
221 if let Some(comment
) = update
.comment
{
222 let comment
= comment
.trim().to_string();
223 if comment
.is_empty() {
224 config
.comment
= None
;
226 config
.comment
= Some(comment
);
230 if let Some(issuer_url
) = update
.issuer_url { config.issuer_url = issuer_url; }
231 if let Some(client_id
) = update
.client_id { config.client_id = client_id; }
233 if update
.client_key
.is_some() { config.client_key = update.client_key; }
234 if update
.autocreate
.is_some() { config.autocreate = update.autocreate; }
236 domains
.set_data(&realm
, "openid", &config
)?
;
238 domains
::save_config(&domains
)?
;
243 const ITEM_ROUTER
: Router
= Router
::new()
244 .get(&API_METHOD_READ_OPENID_REALM
)
245 .put(&API_METHOD_UPDATE_OPENID_REALM
)
246 .delete(&API_METHOD_DELETE_OPENID_REALM
);
248 pub const ROUTER
: Router
= Router
::new()
249 .get(&API_METHOD_LIST_OPENID_REALMS
)
250 .post(&API_METHOD_CREATE_OPENID_REALM
)
251 .match_all("realm", &ITEM_ROUTER
);