mirror of
https://codeberg.org/likwid/likwid.git
synced 2026-06-25 15:37:42 +00:00
Verified changes: - modify backend/src/api/approvals.rs - modify backend/src/api/auth.rs - modify backend/src/api/communities.rs - modify backend/src/api/delegation.rs - modify backend/src/api/demo.rs - modify backend/src/api/moderation.rs - modify backend/src/api/permissions.rs - modify backend/src/api/plugins.rs - modify backend/src/api/settings.rs - modify backend/src/auth/middleware.rs - modify backend/src/config/mod.rs - modify backend/src/demo/mod.rs - modify backend/src/main.rs - modify backend/src/plugins/builtin/conflict_resolution.rs - modify backend/src/plugins/builtin/moderation_ledger.rs - modify backend/src/plugins/manager.rs - modify backend/src/plugins/wasm/host_api.rs - modify backend/src/voting/mod.rs - modify backend/src/voting/ranked_choice.rs - modify backend/src/voting/star.rs Diffstat: - 20 files changed, 800 insertions(+), 127 deletions(-)
131 lines
4.1 KiB
Rust
131 lines
4.1 KiB
Rust
//! Permission checking utilities for API endpoints.
|
|
//!
|
|
//! Provides reusable functions to check user permissions against the role system.
|
|
|
|
use axum::http::StatusCode;
|
|
use sqlx::PgPool;
|
|
use uuid::Uuid;
|
|
|
|
/// Check if a user has a specific permission, optionally within a community scope.
|
|
pub async fn user_has_permission(
|
|
pool: &PgPool,
|
|
user_id: Uuid,
|
|
permission: &str,
|
|
community_id: Option<Uuid>,
|
|
) -> Result<bool, (StatusCode, String)> {
|
|
let has_perm = sqlx::query_scalar!(
|
|
"SELECT user_has_permission($1, $2, $3)",
|
|
user_id,
|
|
permission,
|
|
community_id
|
|
)
|
|
.fetch_one(pool)
|
|
.await
|
|
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?
|
|
.unwrap_or(false);
|
|
|
|
Ok(has_perm)
|
|
}
|
|
|
|
/// Require a permission, returning Forbidden error if not granted.
|
|
pub async fn require_permission(
|
|
pool: &PgPool,
|
|
user_id: Uuid,
|
|
permission: &str,
|
|
community_id: Option<Uuid>,
|
|
) -> Result<(), (StatusCode, String)> {
|
|
if !user_has_permission(pool, user_id, permission, community_id).await? {
|
|
return Err((
|
|
StatusCode::FORBIDDEN,
|
|
format!("Permission '{}' required", permission),
|
|
));
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
/// Require any of the given permissions.
|
|
pub async fn require_any_permission(
|
|
pool: &PgPool,
|
|
user_id: Uuid,
|
|
permissions: &[&str],
|
|
community_id: Option<Uuid>,
|
|
) -> Result<(), (StatusCode, String)> {
|
|
for perm in permissions {
|
|
if user_has_permission(pool, user_id, perm, community_id).await? {
|
|
return Ok(());
|
|
}
|
|
}
|
|
Err((
|
|
StatusCode::FORBIDDEN,
|
|
format!("One of these permissions required: {}", permissions.join(", ")),
|
|
))
|
|
}
|
|
|
|
/// Check if user is a platform admin (has platform.admin permission).
|
|
#[allow(dead_code)]
|
|
pub async fn is_platform_admin(
|
|
pool: &PgPool,
|
|
user_id: Uuid,
|
|
) -> Result<bool, (StatusCode, String)> {
|
|
user_has_permission(pool, user_id, "platform.admin", None).await
|
|
}
|
|
|
|
/// Require platform admin access.
|
|
#[allow(dead_code)]
|
|
pub async fn require_platform_admin(
|
|
pool: &PgPool,
|
|
user_id: Uuid,
|
|
) -> Result<(), (StatusCode, String)> {
|
|
require_permission(pool, user_id, "platform.admin", None).await
|
|
}
|
|
|
|
/// Check if user is a community admin or moderator.
|
|
#[allow(dead_code)]
|
|
pub async fn is_community_staff(
|
|
pool: &PgPool,
|
|
user_id: Uuid,
|
|
community_id: Uuid,
|
|
) -> Result<bool, (StatusCode, String)> {
|
|
let is_admin = user_has_permission(pool, user_id, "community.settings", Some(community_id)).await?;
|
|
if is_admin {
|
|
return Ok(true);
|
|
}
|
|
user_has_permission(pool, user_id, "moderation.users.warn", Some(community_id)).await
|
|
}
|
|
|
|
/// Permission constants for common operations.
|
|
/// Used throughout API handlers for authorization.
|
|
pub mod perms {
|
|
// Platform-level
|
|
pub const PLATFORM_ADMIN: &str = "platform.admin";
|
|
pub const PLATFORM_SETTINGS: &str = "platform.settings";
|
|
pub const PLATFORM_PLUGINS: &str = "plugins.configure";
|
|
|
|
// Community-level
|
|
pub const COMMUNITY_CREATE: &str = "community.create";
|
|
pub const COMMUNITY_ADMIN: &str = "community.settings";
|
|
pub const COMMUNITY_SETTINGS: &str = "community.settings";
|
|
pub const COMMUNITY_MODERATE: &str = "moderation.users.warn";
|
|
|
|
// Proposals
|
|
pub const PROPOSAL_CREATE: &str = "proposals.create";
|
|
pub const PROPOSAL_EDIT_OWN: &str = "proposals.edit.own";
|
|
pub const PROPOSAL_EDIT_ANY: &str = "proposals.edit.any";
|
|
pub const PROPOSAL_DELETE_OWN: &str = "proposals.delete.own";
|
|
pub const PROPOSAL_DELETE_ANY: &str = "proposals.delete.any";
|
|
pub const PROPOSAL_MANAGE_STATUS: &str = "proposals.moderate";
|
|
|
|
// Voting
|
|
pub const VOTE_CAST: &str = "voting.vote";
|
|
pub const VOTE_VIEW_RESULTS: &str = "voting.results.view";
|
|
pub const VOTING_CONFIG: &str = "voting.configure";
|
|
|
|
// Moderation
|
|
pub const MOD_BAN_USERS: &str = "platform.users.ban";
|
|
pub const MOD_REMOVE_CONTENT: &str = "moderation.comments.delete";
|
|
pub const MOD_VIEW_REPORTS: &str = "moderation.log.view";
|
|
|
|
// Users
|
|
pub const USER_MANAGE: &str = "platform.users.manage";
|
|
pub const USER_INVITE: &str = "community.members.invite";
|
|
}
|