GCC Code Coverage Report


Directory: ./
File: libgsystemservice/peer-manager.c
Date: 2024-04-09 14:29:48
Exec Total Coverage
Lines: 10 30 33.3%
Functions: 3 6 50.0%
Branches: 8 50 16.0%

Line Branch Exec Source
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
2 *
3 * Copyright © 2018 Endless Mobile, Inc.
4 *
5 * SPDX-License-Identifier: LGPL-2.1-or-later
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 *
21 * Authors:
22 * - Philip Withnall <withnall@endlessm.com>
23 */
24
25 #include "config.h"
26
27 #include <glib.h>
28 #include <glib-object.h>
29 #include <glib/gi18n-lib.h>
30 #include <gio/gio.h>
31 #include <libgsystemservice/peer-manager.h>
32
33
34 /**
35 * SECTION:peer-manager
36 * @short_description: D-Bus peer management and notification
37 * @stability: Stable
38 * @include: libgsystemservice/peer-manager.h
39 *
40 * A peer manager is an abstraction over the management of peers on a D-Bus
41 * connection, monitoring when they disappear, and allowing querying and caching
42 * of their credentials.
43 *
44 * Currently, the only credential stored is the path to the peer’s executable,
45 * which can be used to identify that peer. In future, other credentials may be
46 * added (and the API will change accordingly).
47 *
48 * The default implementation for production use is #GssPeerManagerDBus,
49 * which uses the D-Bus daemon to get credentials. Unit tests will use a
50 * different implementation, allowing them to provide fake data to the service
51 * easily.
52 *
53 * Since: 0.1.0
54 */
55
56 G_DEFINE_QUARK (GssPeerManagerError, gss_peer_manager_error)
57
58 /**
59 * GssPeerManager:
60 *
61 * An interface for D-Bus peer management. The typical production implementation
62 * of this is #GssPeerManagerDBus; other implementations can be written to be
63 * used during testing, returning mock results.
64 *
65 * Since: 0.1.0
66 */
67
68
5/6
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✓ Branch 6 taken 3 times.
4 G_DEFINE_INTERFACE (GssPeerManager, gss_peer_manager, G_TYPE_OBJECT)
69
70 static void
71 1 gss_peer_manager_default_init (GssPeerManagerInterface *iface)
72 {
73 /**
74 * GssPeerManager::peer-vanished:
75 * @self: a #GssPeerManager
76 * @name: unique name of the D-Bus peer which vanished
77 *
78 * Emitted when a peer disappears off the bus. The peer’s unique name will be
79 * given as @name.
80 *
81 * Since: 0.1.0
82 */
83 1 g_signal_new ("peer-vanished", G_TYPE_FROM_INTERFACE (iface),
84 G_SIGNAL_RUN_LAST,
85 0, NULL, NULL, NULL,
86 G_TYPE_NONE, 1,
87 G_TYPE_STRING);
88 1 }
89
90 /**
91 * gss_peer_manager_ensure_peer_credentials_async:
92 * @self: a #GssPeerManager
93 * @sender: D-Bus unique name for the peer
94 * @cancellable: (nullable): a #GCancellable, or %NULL
95 * @callback: callback to call once the asynchronous operation is complete
96 * @user_data: data to pass to @callback
97 *
98 * Ensure the credentials for a peer are in the peer manager, querying them from
99 * the D-Bus daemon if needed. Also start watching the @sender, so that if it
100 * disappears from the bus, a #GssPeerManager::peer-vanished signal will be
101 * emitted.
102 *
103 * Since: 0.1.0
104 */
105 void
106 gss_peer_manager_ensure_peer_credentials_async (GssPeerManager *self,
107 const gchar *sender,
108 GCancellable *cancellable,
109 GAsyncReadyCallback callback,
110 gpointer user_data)
111 {
112 g_return_if_fail (GSS_IS_PEER_MANAGER (self));
113 g_return_if_fail (g_dbus_is_unique_name (sender));
114 g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
115
116 GssPeerManagerInterface *iface = GSS_PEER_MANAGER_GET_IFACE (self);
117 g_assert (iface->ensure_peer_credentials_async != NULL);
118 iface->ensure_peer_credentials_async (self, sender, cancellable, callback, user_data);
119 }
120
121 /**
122 * gss_peer_manager_ensure_peer_credentials_finish:
123 * @self: a #GssPeerManager
124 * @result: asynchronous operation result
125 * @error: return location for a #GError
126 *
127 * Finish ensuring the credentials for a peer are in the peer manager. See
128 * gss_peer_manager_ensure_peer_credentials_async().
129 *
130 * Returns: (transfer full): path to the executable for the peer,
131 * or %NULL on error
132 * Since: 0.1.0
133 */
134 gchar *
135 gss_peer_manager_ensure_peer_credentials_finish (GssPeerManager *self,
136 GAsyncResult *result,
137 GError **error)
138 {
139 g_return_val_if_fail (GSS_IS_PEER_MANAGER (self), NULL);
140 g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
141 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
142
143 GssPeerManagerInterface *iface = GSS_PEER_MANAGER_GET_IFACE (self);
144 g_assert (iface->ensure_peer_credentials_finish != NULL);
145
146 g_autoptr(GError) local_error = NULL;
147 g_autofree gchar *sender_path = iface->ensure_peer_credentials_finish (self, result,
148 &local_error);
149 g_return_val_if_fail ((sender_path == NULL) == (local_error != NULL), NULL);
150
151 if (local_error != NULL)
152 g_propagate_error (error, g_steal_pointer (&local_error));
153 return g_steal_pointer (&sender_path);
154 }
155
156 /**
157 * gss_peer_manager_get_peer_credentials:
158 * @self: a #GssPeerManager
159 * @sender: D-Bus unique name for the peer
160 *
161 * Get the credentials for the given peer. If no credentials are in the cache
162 * for @sender, %NULL will be returned.
163 *
164 * Returns: (nullable): path to the executable for the peer, or %NULL if it’s
165 * unknown
166 * Since: 0.1.0
167 */
168 const gchar *
169 1 gss_peer_manager_get_peer_credentials (GssPeerManager *self,
170 const gchar *sender)
171 {
172
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 g_return_val_if_fail (GSS_IS_PEER_MANAGER (self), NULL);
173
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 g_return_val_if_fail (g_dbus_is_unique_name (sender), NULL);
174
175 1 GssPeerManagerInterface *iface = GSS_PEER_MANAGER_GET_IFACE (self);
176
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 g_assert (iface->get_peer_credentials != NULL);
177
178 1 return iface->get_peer_credentials (self, sender);
179 }
180