ethanlin01x commented on code in PR #3727:
URL: https://github.com/apache/iggy/pull/3727#discussion_r3652251767


##########
foreign/python/src/permissions.rs:
##########
@@ -0,0 +1,406 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+use iggy::prelude::{
+    GlobalPermissions as RustGlobalPermissions, Permissions as RustPermissions,
+    StreamPermissions as RustStreamPermissions, TopicPermissions as 
RustTopicPermissions,
+};
+use pyo3::prelude::*;
+use pyo3_stub_gen::derive::{gen_stub_pyclass, gen_stub_pymethods};
+use std::collections::BTreeMap;
+
+/// The permissions of a user: global permissions applied to all streams,
+/// optionally extended by per-stream permissions.
+#[derive(Debug, Clone, PartialEq)]
+#[gen_stub_pyclass]
+#[pyclass(eq, from_py_object)]
+pub struct Permissions {
+    pub(crate) inner: RustPermissions,
+}
+
+impl From<RustPermissions> for Permissions {
+    fn from(permissions: RustPermissions) -> Self {
+        Self { inner: permissions }
+    }
+}
+
+#[gen_stub_pymethods]
+#[pymethods]
+impl Permissions {
+    /// Create permissions from global permissions and optional per-stream 
permissions.
+    ///
+    /// Args:
+    ///     global_: Global permissions as `GlobalPermissions | None`; 
defaults to all denied.
+    ///     streams: Per-stream permissions keyed by stream ID as
+    ///         `dict[int, StreamPermissions] | None`.
+    #[new]
+    #[pyo3(signature = (global_=None, streams=None))]
+    fn new(
+        #[gen_stub(override_type(type_repr = "GlobalPermissions | None"))] 
global_: Option<
+            GlobalPermissions,
+        >,
+        #[gen_stub(override_type(type_repr = "dict[int, StreamPermissions] | 
None"))]
+        streams: Option<BTreeMap<u32, StreamPermissions>>,
+    ) -> Self {
+        Self {
+            inner: RustPermissions {
+                global: global_.map(|global| global.inner).unwrap_or_default(),
+                streams: streams.map(|streams| {
+                    streams
+                        .into_iter()
+                        .map(|(stream_id, stream)| (stream_id as usize, 
stream.inner))
+                        .collect()
+                }),
+            },
+        }
+    }
+
+    /// The global permissions, applied to all streams.
+    #[getter]
+    fn global_(&self) -> GlobalPermissions {
+        GlobalPermissions {
+            inner: self.inner.global.clone(),
+        }
+    }
+
+    /// The per-stream permissions keyed by stream ID, or `None` when not set.
+    #[getter]
+    #[gen_stub(override_return_type(type_repr = "dict[int, StreamPermissions] 
| None"))]
+    fn streams(&self) -> Option<BTreeMap<u32, StreamPermissions>> {
+        self.inner.streams.as_ref().map(|streams| {
+            streams
+                .iter()
+                .map(|(stream_id, stream)| {
+                    // IDs are u32 on the wire, so the cast cannot truncate.
+                    (
+                        *stream_id as u32,
+                        StreamPermissions {
+                            inner: stream.clone(),
+                        },
+                    )
+                })
+                .collect()
+        })
+    }
+}
+
+/// Global permissions, applied to all streams without specifying them one by 
one.
+#[derive(Debug, Clone, PartialEq)]
+#[gen_stub_pyclass]
+#[pyclass(eq, from_py_object)]
+pub struct GlobalPermissions {
+    pub(crate) inner: RustGlobalPermissions,
+}
+
+#[gen_stub_pymethods]
+#[pymethods]
+impl GlobalPermissions {
+    /// Create global permissions. Every flag defaults to `False`.
+    ///
+    /// Args:
+    ///     manage_servers: Allow managing servers; includes `read_servers`.
+    ///     read_servers: Allow reading server info (stats, clients).
+    ///     manage_users: Allow managing users; includes `read_users`.
+    ///     read_users: Allow reading user info.
+    ///     manage_streams: Allow managing all streams; includes 
`manage_topics`.
+    ///     read_streams: Allow reading all streams; includes `read_topics`.
+    ///     manage_topics: Allow managing all topics; includes `read_topics`.
+    ///     read_topics: Allow reading all topics and consumer groups.
+    ///     poll_messages: Allow polling messages from all streams.
+    ///     send_messages: Allow sending messages to all streams.

Review Comment:
   Fixed, c2120e6a509fcffbd9d640eca8ac11a8e6966b08. 
   Documented the direct inclusion edges per the server permissioner rules with 
a note that they apply transitively. Also covered a few grants beyond the 
listed ones: `read_topics` / `read_topic` additionally allow managing 
(including creating and deleting) consumer groups, `poll_messages` allows 
managing consumer offsets, and stream-level `read_stream` also permits polling 
via `read_topics`.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to