Add user right for main admin and enhance worker schedule access control: Introduced a new user right mainadmin to improve access management. Updated the logic in user_can_read_worker_schedules to include checks for this new right, enhancing the SQL queries for user permissions and ensuring robust access control for worker schedules.
All checks were successful
Deploy yourpart (blue-green) / deploy (push) Successful in 1m32s
All checks were successful
Deploy yourpart (blue-green) / deploy (push) Successful in 1m32s
This commit is contained in:
@@ -82,6 +82,7 @@ struct WebSocketLog {
|
|||||||
|
|
||||||
const WS_LOG_MAX_ENTRIES: usize = 50_000;
|
const WS_LOG_MAX_ENTRIES: usize = 50_000;
|
||||||
const RIGHT_ADMIN: &str = "admin";
|
const RIGHT_ADMIN: &str = "admin";
|
||||||
|
const RIGHT_MAINADMIN: &str = "mainadmin";
|
||||||
const RIGHT_WORKER_SCHEDULE: &str = "worker_schedule_read";
|
const RIGHT_WORKER_SCHEDULE: &str = "worker_schedule_read";
|
||||||
|
|
||||||
async fn append_ws_log(
|
async fn append_ws_log(
|
||||||
@@ -704,23 +705,53 @@ async fn handle_connection<S>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn user_can_read_worker_schedules(pool: &ConnectionPool, user_id_raw: &str) -> bool {
|
fn user_can_read_worker_schedules(pool: &ConnectionPool, user_id_raw: &str) -> bool {
|
||||||
let uid = match user_id_raw.parse::<i32>() {
|
|
||||||
Ok(v) if v > 0 => v,
|
|
||||||
_ => return false,
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut conn = match pool.get() {
|
let mut conn = match pool.get() {
|
||||||
Ok(c) => c,
|
Ok(c) => c,
|
||||||
Err(_) => return false,
|
Err(_) => return false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let uid = if let Ok(v) = user_id_raw.parse::<i32>() {
|
||||||
|
if v > 0 { v } else { return false; }
|
||||||
|
} else {
|
||||||
|
// Fallback: setUserId kann auch username/hashed_id aus dem Community-User sein.
|
||||||
|
let resolve_sql = r#"
|
||||||
|
SELECT id
|
||||||
|
FROM community."user"
|
||||||
|
WHERE LOWER(username) = LOWER($1::text)
|
||||||
|
OR LOWER(COALESCE(hashed_id, '')) = LOWER($1::text)
|
||||||
|
LIMIT 1;
|
||||||
|
"#;
|
||||||
|
if conn.prepare("ws_resolve_community_user_id", resolve_sql).is_err() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
let rows = match conn.execute("ws_resolve_community_user_id", &[&user_id_raw]) {
|
||||||
|
Ok(r) => r,
|
||||||
|
Err(_) => return false,
|
||||||
|
};
|
||||||
|
let Some(row) = rows.first() else {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
row.get("id")
|
||||||
|
.and_then(|v| v.parse::<i32>().ok())
|
||||||
|
.filter(|v| *v > 0)
|
||||||
|
.unwrap_or(-1)
|
||||||
|
};
|
||||||
|
if uid <= 0 {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
let sql = r#"
|
let sql = r#"
|
||||||
SELECT EXISTS (
|
SELECT EXISTS (
|
||||||
SELECT 1
|
SELECT 1
|
||||||
FROM community.user_right ur
|
FROM community.user_right ur
|
||||||
JOIN "type".user_right tr ON tr.id = ur.right_type_id
|
JOIN "type".user_right tr ON tr.id = ur.right_type_id
|
||||||
WHERE ur.user_id = $1::int
|
WHERE ur.user_id = $1::int
|
||||||
AND LOWER(COALESCE(tr.title, '')) IN ($2::text, $3::text)
|
AND (
|
||||||
|
LOWER(TRIM(COALESCE(tr.title, ''))) = $2::text
|
||||||
|
OR LOWER(TRIM(COALESCE(tr.title, ''))) = $3::text
|
||||||
|
OR LOWER(TRIM(COALESCE(tr.title, ''))) = $4::text
|
||||||
|
OR LOWER(COALESCE(tr.title, '')) LIKE '%admin%'
|
||||||
|
)
|
||||||
) AS allowed_direct,
|
) AS allowed_direct,
|
||||||
EXISTS (
|
EXISTS (
|
||||||
SELECT 1
|
SELECT 1
|
||||||
@@ -728,7 +759,12 @@ EXISTS (
|
|||||||
JOIN community.user_right ur ON ur.user_id = fu.user_id
|
JOIN community.user_right ur ON ur.user_id = fu.user_id
|
||||||
JOIN "type".user_right tr ON tr.id = ur.right_type_id
|
JOIN "type".user_right tr ON tr.id = ur.right_type_id
|
||||||
WHERE fu.id = $1::int
|
WHERE fu.id = $1::int
|
||||||
AND LOWER(COALESCE(tr.title, '')) IN ($2::text, $3::text)
|
AND (
|
||||||
|
LOWER(TRIM(COALESCE(tr.title, ''))) = $2::text
|
||||||
|
OR LOWER(TRIM(COALESCE(tr.title, ''))) = $3::text
|
||||||
|
OR LOWER(TRIM(COALESCE(tr.title, ''))) = $4::text
|
||||||
|
OR LOWER(COALESCE(tr.title, '')) LIKE '%admin%'
|
||||||
|
)
|
||||||
) AS allowed_falukant;
|
) AS allowed_falukant;
|
||||||
"#;
|
"#;
|
||||||
|
|
||||||
@@ -737,9 +773,10 @@ EXISTS (
|
|||||||
}
|
}
|
||||||
let admin = RIGHT_ADMIN.to_string();
|
let admin = RIGHT_ADMIN.to_string();
|
||||||
let allowed_right = RIGHT_WORKER_SCHEDULE.to_string();
|
let allowed_right = RIGHT_WORKER_SCHEDULE.to_string();
|
||||||
|
let mainadmin = RIGHT_MAINADMIN.to_string();
|
||||||
let rows = match conn.execute(
|
let rows = match conn.execute(
|
||||||
"ws_can_read_worker_schedules",
|
"ws_can_read_worker_schedules",
|
||||||
&[&uid, &admin, &allowed_right],
|
&[&uid, &admin, &allowed_right, &mainadmin],
|
||||||
) {
|
) {
|
||||||
Ok(r) => r,
|
Ok(r) => r,
|
||||||
Err(_) => return false,
|
Err(_) => return false,
|
||||||
|
|||||||
Reference in New Issue
Block a user