use axum::body::Body;
use axum::http::{Request, StatusCode};
use laterite_admin::{router, AdminConfig};
use laterite_auth::{AuthConfig, AuthService, NewOperator, RequestContext};
use laterite_core::Db;
use tower::ServiceExt;
const SESSION_COOKIE: &str = "laterite_session";
async fn test_db() -> (Db, laterite_core::testing::TestGuard) {
laterite_core::testing::connect_test(&laterite_admin::builtin_migrations()).await
}
async fn login(svc: &AuthService, username: &str, password: &str) -> String {
svc.authenticate(username, password, &RequestContext::default())
.await
.expect("authenticate")
.token
}
fn post_form(path: &str, token: &str, body: &'static str) -> Request<Body> {
Request::builder()
.method("POST")
.uri(path)
.header("cookie", format!("{SESSION_COOKIE}={token}"))
.header("content-type", "application/x-www-form-urlencoded")
.body(Body::from(body))
.unwrap()
}
#[tokio::test]
async fn editor_saves_only_registered_permissions() {
let (pool, _guard) = test_db().await;
let svc = AuthService::new(pool.clone(), AuthConfig::default());
svc.create_superuser(NewOperator {
username: "root",
email: "root@acme.test",
first_name: "Root",
last_name: None,
password: "rootpw12345",
timezone: None,
})
.await
.unwrap();
let root = login(&svc, "root", "rootpw12345").await;
let app = || {
router(
AuthService::new(pool.clone(), AuthConfig::default()),
pool.clone(),
Vec::new(),
Vec::new(),
Vec::new(),
AdminConfig::default(),
)
};
let body = "code=editors&name=Editors\
&perm=backend.manage_users&perm=nope.invalid&perm=backend.manage_roles";
let status = app()
.oneshot(post_form("/admin/roles/new", &root, body))
.await
.unwrap()
.status();
assert_eq!(status, StatusCode::SEE_OTHER);
let (sql, values) = laterite_core::query::build(
pool.backend,
sea_query::Query::select()
.column(sea_query::Alias::new("permissions"))
.from(sea_query::Alias::new("backend_roles"))
.and_where(sea_query::Expr::col(sea_query::Alias::new("code")).eq("editors"))
.to_owned(),
);
let row = laterite_core::query::bind_values(sqlx::query(&sql), values)
.fetch_one(&pool.pool)
.await
.unwrap();
let saved_json = laterite_core::AnyRowExt::get_text(&row, "permissions").unwrap();
let saved: Vec<String> = serde_json::from_str(&saved_json).unwrap();
assert_eq!(saved, ["backend.manage_users", "backend.manage_roles"]);
}