From e5996e619d737b3a87962ef7ed4d5ee76de6384e Mon Sep 17 00:00:00 2001 From: Priec Date: Wed, 2 Sep 2026 19:10:50 +0200 Subject: [PATCH] errors can be looked up also migrations changed --- common/proto/auth.proto | 50 ++++++- common/src/proto/descriptor.bin | Bin 237152 -> 239828 bytes common/src/proto/komp_ac.auth.rs | 249 ++++++++++++++++++++++++++++++- komp-app/src/auth.rs | 34 ++++- server | 2 +- 5 files changed, 330 insertions(+), 5 deletions(-) diff --git a/common/proto/auth.proto b/common/proto/auth.proto index f8c057cb..c3eda68b 100644 --- a/common/proto/auth.proto +++ b/common/proto/auth.proto @@ -34,6 +34,10 @@ service AuthService { rpc ListRolePermissions(ListRolePermissionsRequest) returns (RolePermissions); rpc ListGrantableObjects(ListGrantableObjectsRequest) returns (ListGrantableObjectsResponse); + // Support diagnostics. Requires read on diagnostics:internal-errors. + rpc ListInternalErrors(ListInternalErrorsRequest) returns (ListInternalErrorsResponse); + rpc GetInternalError(GetInternalErrorRequest) returns (InternalError); + // User administration. rpc AssignUserRole(AssignUserRoleRequest) returns (UserSummary); // Resets a lower-ranked user's password. @@ -184,7 +188,7 @@ message GrantableObject { string profile = 2; // Set only for a table-family root. string table = 3; - // One of global_data, global_journal, profile, journal, or table. + // One of global_data, global_journal, profile, journal, table, or diagnostics. string kind = 4; // Actions the caller may grant to target_role for this object. repeated string allowed_actions = 5; @@ -194,6 +198,50 @@ message ListGrantableObjectsResponse { repeated GrantableObject objects = 1; } +message InternalError { + string reference_id = 1; + string user_id = 2; + string username = 3; + string grpc_method = 4; + string detail = 5; + int64 occurred_at_unix_milliseconds = 6; +} + +message ListInternalErrorsRequest { + // Every non-empty text/UUID field is an optional filter. Username and method + // use case-insensitive substring matching. + string reference_id = 1; + string user_id = 2; + string username = 3; + string grpc_method = 4; + int64 occurred_from_unix_seconds = 5; + int64 occurred_to_unix_seconds = 6; + InternalErrorSort sort = 7; + // Unspecified sort always means newest first. For an explicit sort, false is + // ascending and true is descending. + bool descending = 8; + // Defaults to 100 and is capped at 500. + uint32 limit = 9; + uint64 offset = 10; +} + +enum InternalErrorSort { + INTERNAL_ERROR_SORT_UNSPECIFIED = 0; + INTERNAL_ERROR_SORT_OCCURRED_AT = 1; + INTERNAL_ERROR_SORT_REFERENCE_ID = 2; + INTERNAL_ERROR_SORT_USERNAME = 3; + INTERNAL_ERROR_SORT_GRPC_METHOD = 4; +} + +message ListInternalErrorsResponse { + repeated InternalError errors = 1; + uint64 total_count = 2; +} + +message GetInternalErrorRequest { + string reference_id = 1; +} + message AssignUserRoleRequest { string username = 1; string role = 2; diff --git a/common/src/proto/descriptor.bin b/common/src/proto/descriptor.bin index 0250087823445c0d6c8a871f4487c6b701e41297..95136937575e7fbb17b4ff57111b586ddf01f1c1 100644 GIT binary patch delta 9590 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 kbAT{^4{vdfM#Mk!*Puhxo&PdM$bE>E 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 diff --git a/common/src/proto/komp_ac.auth.rs b/common/src/proto/komp_ac.auth.rs index 372b82d1..7b4d94b0 100644 --- a/common/src/proto/komp_ac.auth.rs +++ b/common/src/proto/komp_ac.auth.rs @@ -235,7 +235,7 @@ pub struct GrantableObject { /// 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. + /// One of global_data, global_journal, profile, journal, table, or diagnostics. #[prost(string, tag = "4")] pub kind: ::prost::alloc::string::String, /// Actions the caller may grant to target_role for this object. @@ -250,6 +250,65 @@ pub struct ListGrantableObjectsResponse { } #[derive(serde::Serialize, serde::Deserialize)] #[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct InternalError { + #[prost(string, tag = "1")] + pub reference_id: ::prost::alloc::string::String, + #[prost(string, tag = "2")] + pub user_id: ::prost::alloc::string::String, + #[prost(string, tag = "3")] + pub username: ::prost::alloc::string::String, + #[prost(string, tag = "4")] + pub grpc_method: ::prost::alloc::string::String, + #[prost(string, tag = "5")] + pub detail: ::prost::alloc::string::String, + #[prost(int64, tag = "6")] + pub occurred_at_unix_milliseconds: i64, +} +#[derive(serde::Serialize, serde::Deserialize)] +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct ListInternalErrorsRequest { + /// Every non-empty text/UUID field is an optional filter. Username and method + /// use case-insensitive substring matching. + #[prost(string, tag = "1")] + pub reference_id: ::prost::alloc::string::String, + #[prost(string, tag = "2")] + pub user_id: ::prost::alloc::string::String, + #[prost(string, tag = "3")] + pub username: ::prost::alloc::string::String, + #[prost(string, tag = "4")] + pub grpc_method: ::prost::alloc::string::String, + #[prost(int64, tag = "5")] + pub occurred_from_unix_seconds: i64, + #[prost(int64, tag = "6")] + pub occurred_to_unix_seconds: i64, + #[prost(enumeration = "InternalErrorSort", tag = "7")] + pub sort: i32, + /// Unspecified sort always means newest first. For an explicit sort, false is + /// ascending and true is descending. + #[prost(bool, tag = "8")] + pub descending: bool, + /// Defaults to 100 and is capped at 500. + #[prost(uint32, tag = "9")] + pub limit: u32, + #[prost(uint64, tag = "10")] + pub offset: u64, +} +#[derive(serde::Serialize, serde::Deserialize)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ListInternalErrorsResponse { + #[prost(message, repeated, tag = "1")] + pub errors: ::prost::alloc::vec::Vec, + #[prost(uint64, tag = "2")] + pub total_count: u64, +} +#[derive(serde::Serialize, serde::Deserialize)] +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct GetInternalErrorRequest { + #[prost(string, tag = "1")] + pub reference_id: ::prost::alloc::string::String, +} +#[derive(serde::Serialize, serde::Deserialize)] +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] pub struct AssignUserRoleRequest { #[prost(string, tag = "1")] pub username: ::prost::alloc::string::String, @@ -287,6 +346,42 @@ pub struct ListUsersResponse { #[prost(message, repeated, tag = "1")] pub users: ::prost::alloc::vec::Vec, } +#[derive(serde::Serialize, serde::Deserialize)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum InternalErrorSort { + Unspecified = 0, + OccurredAt = 1, + ReferenceId = 2, + Username = 3, + GrpcMethod = 4, +} +impl InternalErrorSort { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Self::Unspecified => "INTERNAL_ERROR_SORT_UNSPECIFIED", + Self::OccurredAt => "INTERNAL_ERROR_SORT_OCCURRED_AT", + Self::ReferenceId => "INTERNAL_ERROR_SORT_REFERENCE_ID", + Self::Username => "INTERNAL_ERROR_SORT_USERNAME", + Self::GrpcMethod => "INTERNAL_ERROR_SORT_GRPC_METHOD", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "INTERNAL_ERROR_SORT_UNSPECIFIED" => Some(Self::Unspecified), + "INTERNAL_ERROR_SORT_OCCURRED_AT" => Some(Self::OccurredAt), + "INTERNAL_ERROR_SORT_REFERENCE_ID" => Some(Self::ReferenceId), + "INTERNAL_ERROR_SORT_USERNAME" => Some(Self::Username), + "INTERNAL_ERROR_SORT_GRPC_METHOD" => Some(Self::GrpcMethod), + _ => None, + } + } +} /// Generated client implementations. pub mod auth_service_client { #![allow( @@ -716,6 +811,54 @@ pub mod auth_service_client { ); self.inner.unary(req, path, codec).await } + /// Support diagnostics. Requires read on diagnostics:internal-errors. + pub async fn list_internal_errors( + &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/ListInternalErrors", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert( + GrpcMethod::new("komp_ac.auth.AuthService", "ListInternalErrors"), + ); + self.inner.unary(req, path, codec).await + } + pub async fn get_internal_error( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result, 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/GetInternalError", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert(GrpcMethod::new("komp_ac.auth.AuthService", "GetInternalError")); + self.inner.unary(req, path, codec).await + } /// User administration. pub async fn assign_user_role( &mut self, @@ -886,6 +1029,18 @@ pub mod auth_service_server { tonic::Response, tonic::Status, >; + /// Support diagnostics. Requires read on diagnostics:internal-errors. + async fn list_internal_errors( + &self, + request: tonic::Request, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + >; + async fn get_internal_error( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status>; /// User administration. async fn assign_user_role( &self, @@ -1614,6 +1769,98 @@ pub mod auth_service_server { }; Box::pin(fut) } + "/komp_ac.auth.AuthService/ListInternalErrors" => { + #[allow(non_camel_case_types)] + struct ListInternalErrorsSvc(pub Arc); + impl< + T: AuthService, + > tonic::server::UnaryService + for ListInternalErrorsSvc { + type Response = super::ListInternalErrorsResponse; + 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_internal_errors(&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 = ListInternalErrorsSvc(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/GetInternalError" => { + #[allow(non_camel_case_types)] + struct GetInternalErrorSvc(pub Arc); + impl< + T: AuthService, + > tonic::server::UnaryService + for GetInternalErrorSvc { + type Response = super::InternalError; + 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 { + ::get_internal_error(&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 = GetInternalErrorSvc(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/komp-app/src/auth.rs b/komp-app/src/auth.rs index db6eaa44..6f533dab 100644 --- a/komp-app/src/auth.rs +++ b/komp-app/src/auth.rs @@ -1,8 +1,9 @@ use anyhow::{Context, Result}; use common::proto::komp_ac::auth::{ AddRoleRequest, AssignUserRoleRequest, AuthResponse, AuthorizationSnapshot, - ChangePasswordRequest, GetAuthorizationRequest, GrantPermissionRequest, - GrantableObject, ListGrantableObjectsRequest, ListRolePermissionsRequest, ListRolesRequest, + ChangePasswordRequest, GetAuthorizationRequest, GetInternalErrorRequest, GrantPermissionRequest, + GrantableObject, InternalError, ListGrantableObjectsRequest, ListInternalErrorsRequest, + ListInternalErrorsResponse, ListRolePermissionsRequest, ListRolesRequest, ListUsersRequest, LoginRequest, LoginResponse, LogoutRequest, PasswordOperationResponse, RegisterRequest, RemoveRoleRequest, ResetUserPasswordRequest, RevokePermissionRequest, RevokeUserSessionsRequest, Role, RolePermissions, UserSummary, @@ -245,6 +246,35 @@ impl AuthClient { .objects) } + pub async fn list_internal_errors( + &mut self, + token: &str, + request: ListInternalErrorsRequest, + ) -> Result { + Ok(self + .client + .list_internal_errors(authenticated_request(Some(token), request)?) + .await + .context("gRPC ListInternalErrors call failed")? + .into_inner()) + } + + pub async fn get_internal_error( + &mut self, + token: &str, + reference_id: String, + ) -> Result { + Ok(self + .client + .get_internal_error(authenticated_request( + Some(token), + GetInternalErrorRequest { reference_id }, + )?) + .await + .context("gRPC GetInternalError call failed")? + .into_inner()) + } + pub async fn assign_user_role( &mut self, token: &str, diff --git a/server b/server index f43dc625..81a105b9 160000 --- a/server +++ b/server @@ -1 +1 @@ -Subproject commit f43dc62578245aabad13de2b5336f178d1b5f750 +Subproject commit 81a105b98d6486ec88fc52dc3ee721496da4d1df