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 |