gio/auto/
debug_controller_dbus.rs

1// This file was generated by gir (https://github.com/gtk-rs/gir)
2// from gir-files (https://github.com/gtk-rs/gir-files)
3// DO NOT EDIT
4
5use crate::{ffi, Cancellable, DBusConnection, DBusMethodInvocation, DebugController, Initable};
6use glib::{
7    object::ObjectType as _,
8    prelude::*,
9    signal::{connect_raw, SignalHandlerId},
10    translate::*,
11};
12use std::boxed::Box as Box_;
13
14glib::wrapper! {
15    /// `GDebugControllerDBus` is an implementation of [`DebugController`][crate::DebugController]
16    /// which exposes debug settings as a D-Bus object.
17    ///
18    /// It is a [`Initable`][crate::Initable] object, and will register an object at
19    /// `/org/gtk/Debugging` on the bus given as
20    /// [`connection`][struct@crate::DebugControllerDBus#connection] once it’s initialized. The
21    /// object will be unregistered when the last reference to the
22    /// `GDebugControllerDBus` is dropped.
23    ///
24    /// This D-Bus object can be used by remote processes to enable or disable debug
25    /// output in this process. Remote processes calling
26    /// `org.gtk.Debugging.SetDebugEnabled()` will affect the value of
27    /// [`debug-enabled`][struct@crate::DebugController#debug-enabled] and, by default,
28    /// `log_get_debug_enabled()`.
29    ///
30    /// By default, no processes are allowed to call `SetDebugEnabled()` unless a
31    /// [`authorize`][struct@crate::DebugControllerDBus#authorize] signal handler is installed. This
32    /// is because the process may be privileged, or might expose sensitive
33    /// information in its debug output. You may want to restrict the ability to
34    /// enable debug output to privileged users or processes.
35    ///
36    /// One option is to install a D-Bus security policy which restricts access to
37    /// `SetDebugEnabled()`, installing something like the following in
38    /// `$datadir/dbus-1/system.d/`:
39    ///
40    /// ```xml
41    /// <?xml version="1.0"?> <!--*-nxml-*-->
42    /// <!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
43    ///      "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
44    /// <busconfig>
45    ///   <policy user="root">
46    ///     <allow send_destination="com.example.MyService" send_interface="org.gtk.Debugging"/>
47    ///   </policy>
48    ///   <policy context="default">
49    ///     <deny send_destination="com.example.MyService" send_interface="org.gtk.Debugging"/>
50    ///   </policy>
51    /// </busconfig>
52    /// ```
53    ///
54    /// This will prevent the `SetDebugEnabled()` method from being called by all
55    /// except root. It will not prevent the `DebugEnabled` property from being read,
56    /// as it’s accessed through the `org.freedesktop.DBus.Properties` interface.
57    ///
58    /// Another option is to use polkit to allow or deny requests on a case-by-case
59    /// basis, allowing for the possibility of dynamic authorisation. To do this,
60    /// connect to the [`authorize`][struct@crate::DebugControllerDBus#authorize] signal and query
61    /// polkit in it:
62    ///
63    /// **⚠️ The following code is in c ⚠️**
64    ///
65    /// ```c
66    ///   g_autoptr(GError) child_error = NULL;
67    ///   g_autoptr(GDBusConnection) connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL);
68    ///   gulong debug_controller_authorize_id = 0;
69    ///
70    ///   // Set up the debug controller.
71    ///   debug_controller = G_DEBUG_CONTROLLER (g_debug_controller_dbus_new (priv->connection, NULL, &child_error));
72    ///   if (debug_controller == NULL)
73    ///     {
74    ///       g_error ("Could not register debug controller on bus: %s"),
75    ///                child_error->message);
76    ///     }
77    ///
78    ///   debug_controller_authorize_id = g_signal_connect (debug_controller,
79    ///                                                     "authorize",
80    ///                                                     G_CALLBACK (debug_controller_authorize_cb),
81    ///                                                     self);
82    ///
83    ///   static gboolean
84    ///   debug_controller_authorize_cb (GDebugControllerDBus  *debug_controller,
85    ///                                  GDBusMethodInvocation *invocation,
86    ///                                  gpointer               user_data)
87    ///   {
88    ///     g_autoptr(PolkitAuthority) authority = NULL;
89    ///     g_autoptr(PolkitSubject) subject = NULL;
90    ///     g_autoptr(PolkitAuthorizationResult) auth_result = NULL;
91    ///     g_autoptr(GError) local_error = NULL;
92    ///     GDBusMessage *message;
93    ///     GDBusMessageFlags message_flags;
94    ///     PolkitCheckAuthorizationFlags flags = POLKIT_CHECK_AUTHORIZATION_FLAGS_NONE;
95    ///
96    ///     message = g_dbus_method_invocation_get_message (invocation);
97    ///     message_flags = g_dbus_message_get_flags (message);
98    ///
99    ///     authority = polkit_authority_get_sync (NULL, &local_error);
100    ///     if (authority == NULL)
101    ///       {
102    ///         g_warning ("Failed to get polkit authority: %s", local_error->message);
103    ///         return FALSE;
104    ///       }
105    ///
106    ///     if (message_flags & G_DBUS_MESSAGE_FLAGS_ALLOW_INTERACTIVE_AUTHORIZATION)
107    ///       flags |= POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION;
108    ///
109    ///     subject = polkit_system_bus_name_new (g_dbus_method_invocation_get_sender (invocation));
110    ///
111    ///     auth_result = polkit_authority_check_authorization_sync (authority,
112    ///                                                              subject,
113    ///                                                              "com.example.MyService.set-debug-enabled",
114    ///                                                              NULL,
115    ///                                                              flags,
116    ///                                                              NULL,
117    ///                                                              &local_error);
118    ///     if (auth_result == NULL)
119    ///       {
120    ///         g_warning ("Failed to get check polkit authorization: %s", local_error->message);
121    ///         return FALSE;
122    ///       }
123    ///
124    ///     return polkit_authorization_result_get_is_authorized (auth_result);
125    ///   }
126    /// ```
127    ///
128    /// ## Properties
129    ///
130    ///
131    /// #### `connection`
132    ///  The D-Bus connection to expose the debugging interface on.
133    ///
134    /// Typically this will be the same connection (to the system or session bus)
135    /// which the rest of the application or service’s D-Bus objects are registered
136    /// on.
137    ///
138    /// Readable | Writeable | Construct Only
139    /// <details><summary><h4>DebugController</h4></summary>
140    ///
141    ///
142    /// #### `debug-enabled`
143    ///  [`true`] if debug output should be exposed (for example by forwarding it to
144    /// the journal), [`false`] otherwise.
145    ///
146    /// Readable | Writeable
147    /// </details>
148    ///
149    /// ## Signals
150    ///
151    ///
152    /// #### `authorize`
153    ///  Emitted when a D-Bus peer is trying to change the debug settings and used
154    /// to determine if that is authorized.
155    ///
156    /// This signal is emitted in a dedicated worker thread, so handlers are
157    /// allowed to perform blocking I/O. This means that, for example, it is
158    /// appropriate to call `polkit_authority_check_authorization_sync()` to check
159    /// authorization using polkit.
160    ///
161    /// If [`false`] is returned then no further handlers are run and the request to
162    /// change the debug settings is rejected.
163    ///
164    /// Otherwise, if [`true`] is returned, signal emission continues. If no handlers
165    /// return [`false`], then the debug settings are allowed to be changed.
166    ///
167    /// Signal handlers must not modify @invocation, or cause it to return a value.
168    ///
169    /// The default class handler just returns [`true`].
170    ///
171    ///
172    ///
173    /// # Implements
174    ///
175    /// [`DebugControllerDBusExt`][trait@crate::prelude::DebugControllerDBusExt], [`trait@glib::ObjectExt`], [`DebugControllerExt`][trait@crate::prelude::DebugControllerExt], [`InitableExt`][trait@crate::prelude::InitableExt], [`DebugControllerDBusExtManual`][trait@crate::prelude::DebugControllerDBusExtManual]
176    #[doc(alias = "GDebugControllerDBus")]
177    pub struct DebugControllerDBus(Object<ffi::GDebugControllerDBus, ffi::GDebugControllerDBusClass>) @implements DebugController, Initable;
178
179    match fn {
180        type_ => || ffi::g_debug_controller_dbus_get_type(),
181    }
182}
183
184impl DebugControllerDBus {
185    pub const NONE: Option<&'static DebugControllerDBus> = None;
186
187    /// Create a new #GDebugControllerDBus and synchronously initialize it.
188    ///
189    /// Initializing the object will export the debug object on @connection. The
190    /// object will remain registered until the last reference to the
191    /// #GDebugControllerDBus is dropped.
192    ///
193    /// Initialization may fail if registering the object on @connection fails.
194    /// ## `connection`
195    /// a #GDBusConnection to register the debug object on
196    /// ## `cancellable`
197    /// a #GCancellable, or [`None`]
198    ///
199    /// # Returns
200    ///
201    /// a new #GDebugControllerDBus, or [`None`]
202    ///   on failure
203    #[doc(alias = "g_debug_controller_dbus_new")]
204    pub fn new(
205        connection: &DBusConnection,
206        cancellable: Option<&impl IsA<Cancellable>>,
207    ) -> Result<Option<DebugControllerDBus>, glib::Error> {
208        unsafe {
209            let mut error = std::ptr::null_mut();
210            let ret = ffi::g_debug_controller_dbus_new(
211                connection.to_glib_none().0,
212                cancellable.map(|p| p.as_ref()).to_glib_none().0,
213                &mut error,
214            );
215            if error.is_null() {
216                Ok(from_glib_full(ret))
217            } else {
218                Err(from_glib_full(error))
219            }
220        }
221    }
222}
223
224mod sealed {
225    pub trait Sealed {}
226    impl<T: super::IsA<super::DebugControllerDBus>> Sealed for T {}
227}
228
229/// Trait containing all [`struct@DebugControllerDBus`] methods.
230///
231/// # Implementors
232///
233/// [`DebugControllerDBus`][struct@crate::DebugControllerDBus]
234pub trait DebugControllerDBusExt: IsA<DebugControllerDBus> + sealed::Sealed + 'static {
235    /// Stop the debug controller, unregistering its object from the bus.
236    ///
237    /// Any pending method calls to the object will complete successfully, but new
238    /// ones will return an error. This method will block until all pending
239    /// #GDebugControllerDBus::authorize signals have been handled. This is expected
240    /// to not take long, as it will just be waiting for threads to join. If any
241    /// #GDebugControllerDBus::authorize signal handlers are still executing in other
242    /// threads, this will block until after they have returned.
243    ///
244    /// This method will be called automatically when the final reference to the
245    /// #GDebugControllerDBus is dropped. You may want to call it explicitly to know
246    /// when the controller has been fully removed from the bus, or to break
247    /// reference count cycles.
248    ///
249    /// Calling this method from within a #GDebugControllerDBus::authorize signal
250    /// handler will cause a deadlock and must not be done.
251    #[doc(alias = "g_debug_controller_dbus_stop")]
252    fn stop(&self) {
253        unsafe {
254            ffi::g_debug_controller_dbus_stop(self.as_ref().to_glib_none().0);
255        }
256    }
257
258    /// Emitted when a D-Bus peer is trying to change the debug settings and used
259    /// to determine if that is authorized.
260    ///
261    /// This signal is emitted in a dedicated worker thread, so handlers are
262    /// allowed to perform blocking I/O. This means that, for example, it is
263    /// appropriate to call `polkit_authority_check_authorization_sync()` to check
264    /// authorization using polkit.
265    ///
266    /// If [`false`] is returned then no further handlers are run and the request to
267    /// change the debug settings is rejected.
268    ///
269    /// Otherwise, if [`true`] is returned, signal emission continues. If no handlers
270    /// return [`false`], then the debug settings are allowed to be changed.
271    ///
272    /// Signal handlers must not modify @invocation, or cause it to return a value.
273    ///
274    /// The default class handler just returns [`true`].
275    /// ## `invocation`
276    /// A #GDBusMethodInvocation.
277    ///
278    /// # Returns
279    ///
280    /// [`true`] if the call is authorized, [`false`] otherwise.
281    #[cfg(feature = "v2_72")]
282    #[cfg_attr(docsrs, doc(cfg(feature = "v2_72")))]
283    #[doc(alias = "authorize")]
284    fn connect_authorize<F: Fn(&Self, &DBusMethodInvocation) -> bool + 'static>(
285        &self,
286        f: F,
287    ) -> SignalHandlerId {
288        unsafe extern "C" fn authorize_trampoline<
289            P: IsA<DebugControllerDBus>,
290            F: Fn(&P, &DBusMethodInvocation) -> bool + 'static,
291        >(
292            this: *mut ffi::GDebugControllerDBus,
293            invocation: *mut ffi::GDBusMethodInvocation,
294            f: glib::ffi::gpointer,
295        ) -> glib::ffi::gboolean {
296            let f: &F = &*(f as *const F);
297            f(
298                DebugControllerDBus::from_glib_borrow(this).unsafe_cast_ref(),
299                &from_glib_borrow(invocation),
300            )
301            .into_glib()
302        }
303        unsafe {
304            let f: Box_<F> = Box_::new(f);
305            connect_raw(
306                self.as_ptr() as *mut _,
307                b"authorize\0".as_ptr() as *const _,
308                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
309                    authorize_trampoline::<Self, F> as *const (),
310                )),
311                Box_::into_raw(f),
312            )
313        }
314    }
315}
316
317impl<O: IsA<DebugControllerDBus>> DebugControllerDBusExt for O {}