web permission system updated

This commit is contained in:
Priec
2026-08-09 18:49:54 +02:00
parent fd551ef7fb
commit ff044d65f1
12 changed files with 40 additions and 34 deletions

View File

@@ -36,15 +36,17 @@ pub(crate) async fn add_role(
headers: HeaderMap,
Form(form): Form<AddRoleForm>,
) -> Response {
let role = form.name.trim().to_string();
let destination = format!("/admin/permissions?role={role}&updated=true");
let request_headers = headers.clone();
mutate(&headers, async move {
mutate(&headers, &destination, async move {
let mut auth = state.auth;
auth.add_role(authenticated_request(&request_headers, AddRoleRequest {
name: form.name.trim().to_string(),
name: role,
parent: form.parent.trim().to_string(),
}).map_err(|_| "Missing session".to_string())?)
.await.map_err(|error| error.message().to_string())?;
Ok("Role created. Sign in again to continue.")
Ok(())
}).await
}
@@ -53,14 +55,15 @@ pub(crate) async fn remove_role(
headers: HeaderMap,
Form(form): Form<RoleForm>,
) -> Response {
let destination = "/admin/permissions?updated=true";
let request_headers = headers.clone();
mutate(&headers, async move {
mutate(&headers, destination, async move {
let mut auth = state.auth;
auth.remove_role(authenticated_request(&request_headers, RemoveRoleRequest {
name: form.role,
}).map_err(|_| "Missing session".to_string())?)
.await.map_err(|error| error.message().to_string())?;
Ok("Role removed. Sign in again to continue.")
Ok(())
}).await
}
@@ -69,8 +72,9 @@ pub(crate) async fn grant(
headers: HeaderMap,
Form(form): Form<PermissionForm>,
) -> Response {
let destination = format!("/admin/permissions?role={}&updated=true", form.role);
let request_headers = headers.clone();
mutate(&headers, async move {
mutate(&headers, &destination, async move {
let mut auth = state.auth;
auth.grant_permission(authenticated_request(&request_headers, GrantPermissionRequest {
role: form.role,
@@ -78,7 +82,7 @@ pub(crate) async fn grant(
action: form.action,
}).map_err(|_| "Missing session".to_string())?)
.await.map_err(|error| error.message().to_string())?;
Ok("Permission granted. Sign in again to continue.")
Ok(())
}).await
}
@@ -87,8 +91,9 @@ pub(crate) async fn revoke(
headers: HeaderMap,
Form(form): Form<PermissionForm>,
) -> Response {
let destination = format!("/admin/permissions?role={}&updated=true", form.role);
let request_headers = headers.clone();
mutate(&headers, async move {
mutate(&headers, &destination, async move {
let mut auth = state.auth;
auth.revoke_permission(authenticated_request(&request_headers, RevokePermissionRequest {
role: form.role,
@@ -96,7 +101,7 @@ pub(crate) async fn revoke(
action: form.action,
}).map_err(|_| "Missing session".to_string())?)
.await.map_err(|error| error.message().to_string())?;
Ok("Permission revoked. Sign in again to continue.")
Ok(())
}).await
}
@@ -105,27 +110,28 @@ pub(crate) async fn assign_user_role(
headers: HeaderMap,
Form(form): Form<AssignRoleForm>,
) -> Response {
let destination = "/admin/permissions?updated=true";
let request_headers = headers.clone();
mutate(&headers, async move {
mutate(&headers, destination, async move {
let mut auth = state.auth;
auth.assign_user_role(authenticated_request(&request_headers, AssignUserRoleRequest {
username: form.username,
role: form.role,
}).map_err(|_| "Missing session".to_string())?)
.await.map_err(|error| error.message().to_string())?;
Ok("User role changed. Sign in again to continue.")
Ok(())
}).await
}
async fn mutate<F>(headers: &HeaderMap, operation: F) -> Response
async fn mutate<F>(headers: &HeaderMap, destination: &str, operation: F) -> Response
where
F: std::future::Future<Output = Result<&'static str, String>>,
F: std::future::Future<Output = Result<(), String>>,
{
if let Some(rejection) = reject_cross_site(headers) {
return rejection;
}
match operation.await {
Ok(_) => stale_session_response(),
Ok(()) => success_redirect(destination),
Err(message) => (
StatusCode::UNPROCESSABLE_ENTITY,
Html(ui::render_mutation_error(&message)),
@@ -133,19 +139,18 @@ where
}
}
fn stale_session_response() -> Response {
fn success_redirect(destination: &str) -> Response {
let mut response = StatusCode::SEE_OTHER.into_response();
response.headers_mut().insert(
header::SET_COOKIE,
HeaderValue::from_static("analytics_token=; Path=/; HttpOnly; SameSite=Strict; Max-Age=0"),
);
let Ok(destination) = HeaderValue::try_from(destination) else {
return (StatusCode::INTERNAL_SERVER_ERROR, "Invalid redirect").into_response();
};
response.headers_mut().insert(
header::LOCATION,
HeaderValue::from_static("/login?permissions_changed=1"),
destination.clone(),
);
response.headers_mut().insert(
"hx-redirect",
HeaderValue::from_static("/login?permissions_changed=1"),
destination,
);
response
}