web synchronized with the new changes

This commit is contained in:
Priec
2026-08-09 16:30:27 +02:00
parent e66b025188
commit fd551ef7fb
44 changed files with 1215 additions and 88 deletions

View File

@@ -13,7 +13,7 @@ use tonic::transport::Channel;
use crate::{
AppState,
auth::GetAuthorizationRequest,
auth::{GetAuthorizationRequest, ListGrantableObjectsRequest, ListRolePermissionsRequest, ListRolesRequest},
definitions::{
common::Empty,
table_definition::{
@@ -27,7 +27,7 @@ use crate::{
use super::state::{
DetailColumn, LoadError, PageInputs, RenameEntry, ScriptView, TableDefinitionPageState,
TableDetailView, TableSummary,
TableDetailView, TablePermissionAction, TableRolePermissions, TableSummary,
};
/// Reads the column-type vocabulary on its own.
@@ -67,7 +67,7 @@ pub(crate) async fn load_page(
_ => LoadError::Backend(error.message().to_string()),
})?
.into_inner();
if authorization.role != "admin" {
if !crate::authz::can_manage(&authorization, crate::authz::STRUCT_TABLE) {
return Err(LoadError::Forbidden);
}
@@ -220,8 +220,83 @@ pub(crate) async fn load_page(
false => Vec::new(),
};
let mut permission_object = String::new();
let mut role_permissions = Vec::new();
if inputs.selection.has_table()
&& crate::authz::can_manage(&authorization, crate::authz::STRUCT_ROLE)
{
let expected_object = crate::authz::table_object(
&inputs.selection.profile,
&inputs.selection.table,
);
let roles = auth
.list_roles(
authenticated_request(headers, ListRolesRequest {})
.map_err(|_| LoadError::Unauthenticated)?,
)
.await
.map_err(|error| LoadError::Backend(error.message().to_string()))?
.into_inner()
.roles;
for role in roles.into_iter().filter(|role| role.kind == "data") {
let grantable = auth
.list_grantable_objects(
authenticated_request(
headers,
ListGrantableObjectsRequest {
target_role: role.name.clone(),
},
)
.map_err(|_| LoadError::Unauthenticated)?,
)
.await
.map_err(|error| LoadError::Backend(error.message().to_string()))?
.into_inner()
.objects
.into_iter()
.find(|object| object.object == expected_object);
let Some(grantable) = grantable else {
continue;
};
permission_object = expected_object.clone();
let permissions = auth
.list_role_permissions(
authenticated_request(
headers,
ListRolePermissionsRequest {
role: role.name.clone(),
},
)
.map_err(|_| LoadError::Unauthenticated)?,
)
.await
.map_err(|error| LoadError::Backend(error.message().to_string()))?
.into_inner();
role_permissions.push(TableRolePermissions {
role: role.name,
actions: grantable
.allowed_actions
.into_iter()
.map(|action| TablePermissionAction {
direct: crate::authz::is_direct_permission(
&permissions.permissions,
&expected_object,
&action,
),
effective: crate::authz::permissions_permit(
&permissions.effective_permissions,
&expected_object,
&action,
),
action,
})
.collect(),
});
}
}
Ok(TableDefinitionPageState {
nav: crate::ui::Nav::new(headers, "admin").with_role(authorization.role),
nav: crate::ui::Nav::new(headers, "admin").with_authorization(&authorization),
profiles,
tables,
detail,
@@ -235,5 +310,7 @@ pub(crate) async fn load_page(
error: inputs.error,
sql: inputs.sql,
generated: inputs.generated,
permission_object,
role_permissions,
})
}