171 lines
6.7 KiB
Rust
171 lines
6.7 KiB
Rust
mod common;
|
|
|
|
use axum::http::StatusCode;
|
|
use common::*;
|
|
|
|
// ═══════════════════════════════════════════════════════════════════
|
|
// Role listing
|
|
// ═══════════════════════════════════════════════════════════════════
|
|
|
|
#[tokio::test]
|
|
async fn list_roles_includes_system_roles() {
|
|
let (app, pool) = build_test_app().await;
|
|
let admin = admin_token(&app, &pool, "roleadmin").await;
|
|
let (status, body) = send(&app, get("/api/v1/roles", &admin)).await;
|
|
assert_eq!(status, StatusCode::OK);
|
|
let roles = body.as_array().unwrap();
|
|
let ids: Vec<&str> = roles.iter().map(|r| r["id"].as_str().unwrap()).collect();
|
|
assert!(ids.contains(&"super_admin"));
|
|
assert!(ids.contains(&"admin"));
|
|
assert!(ids.contains(&"user"));
|
|
}
|
|
|
|
// ═══════════════════════════════════════════════════════════════════
|
|
// Role CRUD
|
|
// ═══════════════════════════════════════════════════════════════════
|
|
|
|
#[tokio::test]
|
|
async fn role_crud() {
|
|
let (app, pool) = build_test_app().await;
|
|
let admin = admin_token(&app, &pool, "rolecrud").await;
|
|
|
|
// Create custom role
|
|
let (status, body) = send(
|
|
&app,
|
|
post(
|
|
"/api/v1/roles",
|
|
&admin,
|
|
serde_json::json!({
|
|
"id": "custom-role-1",
|
|
"name": "Custom Role",
|
|
"description": "A test role",
|
|
"permissions": ["model:read", "relay:use"]
|
|
}),
|
|
),
|
|
).await;
|
|
assert_eq!(status, StatusCode::CREATED, "create role: {body}");
|
|
|
|
// Get
|
|
let (status, body) = send(&app, get("/api/v1/roles/custom-role-1", &admin)).await;
|
|
assert_eq!(status, StatusCode::OK);
|
|
assert_eq!(body["name"], "Custom Role");
|
|
|
|
// Update
|
|
let (status, body) = send(
|
|
&app,
|
|
put(
|
|
"/api/v1/roles/custom-role-1",
|
|
&admin,
|
|
serde_json::json!({ "description": "Updated description" }),
|
|
),
|
|
).await;
|
|
assert_eq!(status, StatusCode::OK);
|
|
assert_eq!(body["description"], "Updated description");
|
|
|
|
// Delete custom role
|
|
let (status, _) = send(&app, delete("/api/v1/roles/custom-role-1", &admin)).await;
|
|
assert_eq!(status, StatusCode::OK);
|
|
}
|
|
|
|
// ═══════════════════════════════════════════════════════════════════
|
|
// System role protection
|
|
// ═══════════════════════════════════════════════════════════════════
|
|
|
|
#[tokio::test]
|
|
async fn cannot_delete_system_role() {
|
|
let (app, pool) = build_test_app().await;
|
|
let admin = admin_token(&app, &pool, "sysrole").await;
|
|
let (status, _) = send(&app, delete("/api/v1/roles/super_admin", &admin)).await;
|
|
assert_ne!(status, StatusCode::OK);
|
|
}
|
|
|
|
// ═══════════════════════════════════════════════════════════════════
|
|
// Role creation forbidden for regular user
|
|
// ═══════════════════════════════════════════════════════════════════
|
|
|
|
#[tokio::test]
|
|
async fn role_create_forbidden_for_user() {
|
|
let (app, _pool) = build_test_app().await;
|
|
let token = register_token(&app, "rolenouser").await;
|
|
let (status, _) = send(
|
|
&app,
|
|
post(
|
|
"/api/v1/roles",
|
|
&token,
|
|
serde_json::json!({ "id": "x", "name": "X", "permissions": [] }),
|
|
),
|
|
).await;
|
|
assert_eq!(status, StatusCode::FORBIDDEN);
|
|
}
|
|
|
|
// ═══════════════════════════════════════════════════════════════════
|
|
// Permission templates
|
|
// ═══════════════════════════════════════════════════════════════════
|
|
|
|
#[tokio::test]
|
|
async fn permission_template_crud() {
|
|
let (app, pool) = build_test_app().await;
|
|
let admin = admin_token(&app, &pool, "tmpladmin").await;
|
|
|
|
// Create template
|
|
let (status, body) = send(
|
|
&app,
|
|
post(
|
|
"/api/v1/permission-templates",
|
|
&admin,
|
|
serde_json::json!({
|
|
"name": "Read-Only Template",
|
|
"description": "Only read access",
|
|
"permissions": ["model:read", "config:read", "prompt:read"]
|
|
}),
|
|
),
|
|
).await;
|
|
assert_eq!(status, StatusCode::CREATED, "create template: {body}");
|
|
let tmpl_id = body["id"].as_str().unwrap();
|
|
|
|
// List templates
|
|
let (status, list) = send(&app, get("/api/v1/permission-templates", &admin)).await;
|
|
assert_eq!(status, StatusCode::OK);
|
|
assert!(list.is_array());
|
|
|
|
// Get template
|
|
let (status, _) = send(&app, get(&format!("/api/v1/permission-templates/{tmpl_id}"), &admin)).await;
|
|
assert_eq!(status, StatusCode::OK);
|
|
|
|
// Delete template
|
|
let (status, _) = send(&app, delete(&format!("/api/v1/permission-templates/{tmpl_id}"), &admin)).await;
|
|
assert_eq!(status, StatusCode::OK);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn apply_permission_template() {
|
|
let (app, pool) = build_test_app().await;
|
|
let admin = admin_token(&app, &pool, "applyadmin").await;
|
|
|
|
// Create template
|
|
let (_, tmpl_body) = send(
|
|
&app,
|
|
post(
|
|
"/api/v1/permission-templates",
|
|
&admin,
|
|
serde_json::json!({ "name": "Apply Test", "permissions": ["model:read"] }),
|
|
),
|
|
).await;
|
|
let tmpl_id = tmpl_body["id"].as_str().unwrap();
|
|
|
|
// Create a target user
|
|
let (_, _, reg) = register(&app, "targetuser", "target@test.io", DEFAULT_PASSWORD).await;
|
|
let target_id = reg["account"]["id"].as_str().unwrap();
|
|
|
|
// Apply template
|
|
let (status, _) = send(
|
|
&app,
|
|
post(
|
|
&format!("/api/v1/permission-templates/{tmpl_id}/apply"),
|
|
&admin,
|
|
serde_json::json!({ "account_ids": [target_id] }),
|
|
),
|
|
).await;
|
|
assert_eq!(status, StatusCode::OK);
|
|
}
|