From a5c8e0851314024258eda0ed185fd98af324ee8c Mon Sep 17 00:00:00 2001 From: Priec Date: Sun, 9 Aug 2026 13:26:59 +0200 Subject: [PATCH] dynamic rbac and roles2 --- common/proto/auth.proto | 25 +++++++ common/src/proto/descriptor.bin | Bin 156384 -> 157801 bytes common/src/proto/komp_ac.auth.rs | 110 +++++++++++++++++++++++++++++++ server | 2 +- 4 files changed, 136 insertions(+), 1 deletion(-) diff --git a/common/proto/auth.proto b/common/proto/auth.proto index 39aa6eb9..55283319 100644 --- a/common/proto/auth.proto +++ b/common/proto/auth.proto @@ -22,6 +22,7 @@ service AuthService { rpc GrantPermission(GrantPermissionRequest) returns (RolePermissions); rpc RevokePermission(RevokePermissionRequest) returns (RolePermissions); rpc ListRolePermissions(ListRolePermissionsRequest) returns (RolePermissions); + rpc ListGrantableObjects(ListGrantableObjectsRequest) returns (ListGrantableObjectsResponse); // User administration. rpc AssignUserRole(AssignUserRoleRequest) returns (UserSummary); @@ -145,6 +146,30 @@ message RolePermissions { repeated Permission effective_permissions = 3; } +message ListGrantableObjectsRequest { + // The role being edited. The response contains only actions that may be + // granted to this role by the caller. + string target_role = 1; +} + +message GrantableObject { + // Canonical value accepted by GrantPermission, for example + // data:acme/invoices. + string object = 1; + // Empty only for the data:* and journal:* global wildcards. + string profile = 2; + // Set only for a table-family root. + string table = 3; + // One of global_data, global_journal, profile, journal, or table. + string kind = 4; + // Actions the caller may grant to target_role for this object. + repeated string allowed_actions = 5; +} + +message ListGrantableObjectsResponse { + repeated GrantableObject objects = 1; +} + message AssignUserRoleRequest { string username = 1; string role = 2; diff --git a/common/src/proto/descriptor.bin b/common/src/proto/descriptor.bin index ff0f25cb5bfcca1fd15541287075fde9ee4d1590..469176c60d1a0996ac2f6a82753c24e0984db79f 100644 GIT binary patch delta 5222 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 I#4nxr4<^5YW&i*H delta 3802 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, } #[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct ListGrantableObjectsRequest { + /// The role being edited. The response contains only actions that may be + /// granted to this role by the caller. + #[prost(string, tag = "1")] + pub target_role: ::prost::alloc::string::String, +} +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct GrantableObject { + /// Canonical value accepted by GrantPermission, for example + /// data:acme/invoices. + #[prost(string, tag = "1")] + pub object: ::prost::alloc::string::String, + /// Empty only for the data:\* and journal:\* global wildcards. + #[prost(string, tag = "2")] + pub profile: ::prost::alloc::string::String, + /// Set only for a table-family root. + #[prost(string, tag = "3")] + pub table: ::prost::alloc::string::String, + /// One of global_data, global_journal, profile, journal, or table. + #[prost(string, tag = "4")] + pub kind: ::prost::alloc::string::String, + /// Actions the caller may grant to target_role for this object. + #[prost(string, repeated, tag = "5")] + pub allowed_actions: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ListGrantableObjectsResponse { + #[prost(message, repeated, tag = "1")] + pub objects: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] pub struct AssignUserRoleRequest { #[prost(string, tag = "1")] pub username: ::prost::alloc::string::String, @@ -550,6 +581,32 @@ pub mod auth_service_client { ); self.inner.unary(req, path, codec).await } + pub async fn list_grantable_objects( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + > { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::unknown( + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic_prost::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/komp_ac.auth.AuthService/ListGrantableObjects", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert( + GrpcMethod::new("komp_ac.auth.AuthService", "ListGrantableObjects"), + ); + self.inner.unary(req, path, codec).await + } /// User administration. pub async fn assign_user_role( &mut self, @@ -665,6 +722,13 @@ pub mod auth_service_server { &self, request: tonic::Request, ) -> std::result::Result, tonic::Status>; + async fn list_grantable_objects( + &self, + request: tonic::Request, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + >; /// User administration. async fn assign_user_role( &self, @@ -1249,6 +1313,52 @@ pub mod auth_service_server { }; Box::pin(fut) } + "/komp_ac.auth.AuthService/ListGrantableObjects" => { + #[allow(non_camel_case_types)] + struct ListGrantableObjectsSvc(pub Arc); + impl< + T: AuthService, + > tonic::server::UnaryService + for ListGrantableObjectsSvc { + type Response = super::ListGrantableObjectsResponse; + type Future = BoxFuture< + tonic::Response, + tonic::Status, + >; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + ::list_grantable_objects(&inner, request) + .await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let method = ListGrantableObjectsSvc(inner); + let codec = tonic_prost::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.unary(method, req).await; + Ok(res) + }; + Box::pin(fut) + } "/komp_ac.auth.AuthService/AssignUserRole" => { #[allow(non_camel_case_types)] struct AssignUserRoleSvc(pub Arc); diff --git a/server b/server index 5dd123bf..3f4c9dfd 160000 --- a/server +++ b/server @@ -1 +1 @@ -Subproject commit 5dd123bf34e3254520e4d198494872601a34f8d0 +Subproject commit 3f4c9dfdfa480c7213fb0850b72e114379bb4c47