173 lines
5.2 KiB
Rust
173 lines
5.2 KiB
Rust
//! WP-02: /api/settings (SMTP, schedules).
|
|
mod common;
|
|
|
|
use axum::http::StatusCode;
|
|
use common::{get, post, send_json, test_app_with_admin};
|
|
use serde_json::json;
|
|
|
|
const ADMIN: &str = "admin@example.com";
|
|
const PW: &str = "admin-password-123";
|
|
|
|
fn smtp() -> serde_json::Value {
|
|
json!({"host": "mail.example.com", "port": 587, "security": "starttls", "username": "bot",
|
|
"password": "s3cret", "from": "monitoring@example.com", "notify_to": ["ops@example.com"]})
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn smtp_settings_roundtrip_without_exposing_password() {
|
|
let app = test_app_with_admin().await;
|
|
let token = common::login(&app, ADMIN, PW).await.access;
|
|
|
|
let res = get(&app, "/api/settings/smtp", Some(&token)).await;
|
|
assert_eq!(res.status, StatusCode::OK);
|
|
assert_eq!(res.json["configured"], false);
|
|
|
|
let res = send_json(&app, "PUT", "/api/settings/smtp", smtp(), Some(&token)).await;
|
|
assert_eq!(res.status, StatusCode::NO_CONTENT, "{}", res.json);
|
|
|
|
let res = get(&app, "/api/settings/smtp", Some(&token)).await;
|
|
assert_eq!(res.json["configured"], true);
|
|
assert_eq!(res.json["smtp"]["host"], "mail.example.com");
|
|
assert_eq!(res.json["smtp"]["password_set"], true);
|
|
assert!(res.json["smtp"].get("password").is_none());
|
|
|
|
// empty password keeps the stored one
|
|
let mut upd = smtp();
|
|
upd["password"] = json!("");
|
|
upd["port"] = json!(2525);
|
|
assert_eq!(
|
|
send_json(&app, "PUT", "/api/settings/smtp", upd, Some(&token))
|
|
.await
|
|
.status,
|
|
StatusCode::NO_CONTENT
|
|
);
|
|
let res = get(&app, "/api/settings/smtp", Some(&token)).await;
|
|
assert_eq!(res.json["smtp"]["port"], 2525);
|
|
assert_eq!(res.json["smtp"]["password_set"], true);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn smtp_validation_and_test_mail() {
|
|
let app = test_app_with_admin().await;
|
|
let token = common::login(&app, ADMIN, PW).await.access;
|
|
let mut bad = smtp();
|
|
bad["from"] = json!("nope");
|
|
assert_eq!(
|
|
send_json(&app, "PUT", "/api/settings/smtp", bad, Some(&token))
|
|
.await
|
|
.status,
|
|
StatusCode::UNPROCESSABLE_ENTITY
|
|
);
|
|
|
|
// not configured yet -> 422
|
|
let res = post(
|
|
&app,
|
|
"/api/settings/smtp/test",
|
|
json!({"to": "me@example.com"}),
|
|
Some(&token),
|
|
)
|
|
.await;
|
|
assert_eq!(res.status, StatusCode::UNPROCESSABLE_ENTITY);
|
|
|
|
send_json(&app, "PUT", "/api/settings/smtp", smtp(), Some(&token)).await;
|
|
let res = post(
|
|
&app,
|
|
"/api/settings/smtp/test",
|
|
json!({"to": "me@example.com"}),
|
|
Some(&token),
|
|
)
|
|
.await;
|
|
assert_eq!(res.status, StatusCode::NO_CONTENT, "{}", res.json);
|
|
let sent = api::test_support::sent_mails(&app);
|
|
assert_eq!(sent.len(), 1);
|
|
assert_eq!(sent[0].0, vec!["me@example.com".to_string()]);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn schedules_list_and_update() {
|
|
let app = test_app_with_admin().await;
|
|
let token = common::login(&app, ADMIN, PW).await.access;
|
|
let res = get(&app, "/api/settings/schedules", Some(&token)).await;
|
|
assert_eq!(res.status, StatusCode::OK);
|
|
let list = res.json.as_array().unwrap();
|
|
let pr = list
|
|
.iter()
|
|
.find(|s| s["kind"] == "package_refresh")
|
|
.unwrap();
|
|
assert_eq!(pr["cron"], "0 0 * * * *");
|
|
|
|
let res = send_json(
|
|
&app,
|
|
"PUT",
|
|
"/api/settings/schedules/package_refresh",
|
|
json!({"cron": "0 */30 * * * *"}),
|
|
Some(&token),
|
|
)
|
|
.await;
|
|
assert_eq!(res.status, StatusCode::NO_CONTENT, "{}", res.json);
|
|
let res = send_json(
|
|
&app,
|
|
"PUT",
|
|
"/api/settings/schedules/package_refresh",
|
|
json!({"cron": "bad"}),
|
|
Some(&token),
|
|
)
|
|
.await;
|
|
assert_eq!(res.status, StatusCode::UNPROCESSABLE_ENTITY);
|
|
let res = send_json(
|
|
&app,
|
|
"PUT",
|
|
"/api/settings/schedules/package_refresh",
|
|
json!({"cron": null}),
|
|
Some(&token),
|
|
)
|
|
.await;
|
|
assert_eq!(res.status, StatusCode::NO_CONTENT);
|
|
let res = get(&app, "/api/settings/schedules", Some(&token)).await;
|
|
let pr = res
|
|
.json
|
|
.as_array()
|
|
.unwrap()
|
|
.iter()
|
|
.find(|s| s["kind"] == "package_refresh")
|
|
.unwrap()
|
|
.clone();
|
|
assert!(pr["cron"].is_null());
|
|
assert_eq!(
|
|
send_json(
|
|
&app,
|
|
"PUT",
|
|
"/api/settings/schedules/nope",
|
|
json!({"cron": null}),
|
|
Some(&token)
|
|
)
|
|
.await
|
|
.status,
|
|
StatusCode::NOT_FOUND
|
|
);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn settings_writes_are_admin_only_reads_for_all() {
|
|
let app = test_app_with_admin().await;
|
|
let admin = common::login(&app, ADMIN, PW).await.access;
|
|
post(&app, "/api/users", json!({"email": "u@x.de", "display_name": "U", "password": "user-password-123", "role": "user"}), Some(&admin)).await;
|
|
let user = common::login(&app, "u@x.de", "user-password-123")
|
|
.await
|
|
.access;
|
|
assert_eq!(
|
|
get(&app, "/api/settings/smtp", Some(&user)).await.status,
|
|
StatusCode::OK
|
|
);
|
|
assert_eq!(
|
|
send_json(&app, "PUT", "/api/settings/smtp", smtp(), Some(&user))
|
|
.await
|
|
.status,
|
|
StatusCode::FORBIDDEN
|
|
);
|
|
assert_eq!(
|
|
get(&app, "/api/settings/smtp", None).await.status,
|
|
StatusCode::UNAUTHORIZED
|
|
);
|
|
}
|