2 use std
::collections
::HashSet
;
4 use proxmox_http_error
::HttpError
;
9 #[cfg(feature = "gotify")]
12 #[cfg(feature = "sendmail")]
14 #[cfg(feature = "smtp")]
17 // We have our own, local versions of http_err and http_bail, because
18 // we don't want to wrap the error in anyhow::Error. If we were to do that,
19 // we would need to downcast in the perlmod bindings, since we need
20 // to return `HttpError` from there.
22 macro_rules
! http_err
{
23 ($status
:ident
, $
($fmt
:tt
)+) => {{
24 proxmox_http_error
::HttpError
::new(
25 proxmox_http_error
::StatusCode
::$status
,
32 macro_rules
! http_bail
{
33 ($status
:ident
, $
($fmt
:tt
)+) => {{
34 return Err($
crate::api
::http_err
!($status
, $
($fmt
)+));
41 fn verify_digest(config
: &Config
, digest
: Option
<&[u8]>) -> Result
<(), HttpError
> {
42 if let Some(digest
) = digest
{
43 if config
.digest
!= *digest
{
46 "detected modified configuration - file changed by other user? Try again."
54 fn ensure_endpoint_exists(#[allow(unused)] config: &Config, name: &str) -> Result<(), HttpError> {
56 let mut exists
= false;
58 #[cfg(feature = "sendmail")]
60 exists
= exists
|| sendmail
::get_endpoint(config
, name
).is_ok();
62 #[cfg(feature = "gotify")]
64 exists
= exists
|| gotify
::get_endpoint(config
, name
).is_ok();
66 #[cfg(feature = "smtp")]
68 exists
= exists
|| smtp
::get_endpoint(config
, name
).is_ok();
72 http_bail
!(NOT_FOUND
, "endpoint '{name}' does not exist")
78 fn ensure_endpoints_exist
<T
: AsRef
<str>>(
81 ) -> Result
<(), HttpError
> {
82 for endpoint
in endpoints
{
83 ensure_endpoint_exists(config
, endpoint
.as_ref())?
;
89 fn ensure_unique(config
: &Config
, entity
: &str) -> Result
<(), HttpError
> {
90 if config
.config
.sections
.contains_key(entity
) {
93 "Cannot create '{entity}', an entity with the same name already exists"
100 fn get_referrers(config
: &Config
, entity
: &str) -> Result
<HashSet
<String
>, HttpError
> {
101 let mut referrers
= HashSet
::new();
103 for matcher
in matcher
::get_matchers(config
)?
{
104 if let Some(targets
) = matcher
.target
{
105 if targets
.iter().any(|target
| target
== entity
) {
106 referrers
.insert(matcher
.name
.clone());
114 fn ensure_unused(config
: &Config
, entity
: &str) -> Result
<(), HttpError
> {
115 let referrers
= get_referrers(config
, entity
)?
;
117 if !referrers
.is_empty() {
118 let used_by
= referrers
.into_iter().collect
::<Vec
<_
>>().join(", ");
122 "cannot delete '{entity}', referenced by: {used_by}"
129 fn get_referenced_entities(config
: &Config
, entity
: &str) -> HashSet
<String
> {
130 let mut to_expand
= HashSet
::new();
131 let mut expanded
= HashSet
::new();
132 to_expand
.insert(entity
.to_string());
134 let expand
= |entities
: &HashSet
<String
>| -> HashSet
<String
> {
135 let mut new
= HashSet
::new();
137 for entity
in entities
{
138 if let Ok(group
) = matcher
::get_matcher(config
, entity
) {
139 if let Some(targets
) = group
.target
{
140 for target
in targets
{
141 new
.insert(target
.clone());
150 while !to_expand
.is_empty() {
151 let new
= expand(&to_expand
);
152 expanded
.extend(to_expand
);
160 fn set_private_config_entry
<T
: Serialize
>(
165 ) -> Result
<(), HttpError
> {
168 .set_data(name
, typename
, private_config
)
171 INTERNAL_SERVER_ERROR
,
172 "could not save private config for endpoint '{}': {e}",
179 fn remove_private_config_entry(config
: &mut Config
, name
: &str) -> Result
<(), HttpError
> {
180 config
.private_config
.sections
.remove(name
);
189 pub fn empty_config() -> Config
{
190 Config
::new("", "").unwrap()
194 #[cfg(all(test, gotify, sendmail))]
197 use crate::endpoints
::gotify
::{GotifyConfig, GotifyPrivateConfig}
;
198 use crate::endpoints
::sendmail
::SendmailConfig
;
199 use crate::filter
::FilterConfig
;
200 use crate::group
::GroupConfig
;
202 fn prepare_config() -> Result
<Config
, HttpError
> {
203 let mut config
= super::test_helpers
::empty_config();
205 matcher
::add_matcher(
208 name
: "matcher".to_string(),
209 target
: Some(vec
!["sendmail".to_string(), "gotify".to_string()])
210 ..Default
::default(),
214 sendmail
::add_endpoint(
217 name
: "sendmail".to_string(),
218 mailto
: Some(vec
!["foo@example.com".to_string()]),
223 gotify
::add_endpoint(
226 name
: "gotify".to_string(),
227 server
: "localhost".to_string(),
230 &GotifyPrivateConfig
{
231 name
: "gotify".to_string(),
232 token
: "foo".to_string(),
240 fn test_get_referenced_entities() {
241 let config
= prepare_config().unwrap();
244 get_referenced_entities(&config
, "matcher"),
246 "matcher".to_string(),
247 "sendmail".to_string(),
254 fn test_get_referrers_for_entity() -> Result
<(), HttpError
> {
255 let config
= prepare_config().unwrap();
258 get_referrers(&config
, "sendmail")?
,
259 HashSet
::from(["matcher".to_string()])
263 get_referrers(&config
, "gotify")?
,
264 HashSet
::from(["matcher".to_string()])
271 fn test_ensure_unused() {
272 let config
= prepare_config().unwrap();
274 assert
!(ensure_unused(&config
, "gotify").is_err());
275 assert
!(ensure_unused(&config
, "sendmail").is_err());
276 assert
!(ensure_unused(&config
, "matcher").is_ok());
280 fn test_ensure_unique() {
281 let config
= prepare_config().unwrap();
283 assert
!(ensure_unique(&config
, "sendmail").is_err());
284 assert
!(ensure_unique(&config
, "group").is_err());
285 assert
!(ensure_unique(&config
, "new").is_ok());
289 fn test_ensure_endpoints_exist() {
290 let config
= prepare_config().unwrap();
292 assert
!(ensure_endpoints_exist(&config
, &vec
!["sendmail", "gotify"]).is_ok());