1 /* Mission Control plugin API - interface to an McdAccountManager for plugins
2 *
3 * Copyright © 2010 Nokia Corporation
4 * Copyright © 2010 Collabora Ltd.
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include "config.h"
22
23 #include <mission-control-plugins/mission-control-plugins.h>
24 #include <mission-control-plugins/implementation.h>
25 #include <mission-control-plugins/debug-internal.h>
26
27 #define MCP_DEBUG_TYPE MCP_DEBUG_ACCOUNT
28
29 /**
30 * SECTION:account
31 * @title: McpAccountManager
32 * @short_description: Object representing the account manager, implemented
33 * by Mission Control
34 * @see_also: #McpAccountStorage
35 * @include: mission-control-plugins/mission-control-plugins.h
36 *
37 * This object represents the Telepathy AccountManager.
38 *
39 * Most virtual methods on the McpAccountStorageIface interface receive an
40 * object provided by Mission Control that implements this interface.
41 * It can be used to manipulate Mission Control's in-memory cache of accounts.
42 *
43 * Only Mission Control should implement this interface.
44 */
45
46 GType
mcp_account_manager_get_type(void)47 mcp_account_manager_get_type (void)
48 {
49 static gsize once = 0;
50 static GType type = 0;
51
52 if (g_once_init_enter (&once))
53 {
54 static const GTypeInfo info = {
55 sizeof (McpAccountManagerIface),
56 NULL, /* base_init */
57 NULL, /* base_finalize */
58 NULL, /* class_init */
59 NULL, /* class_finalize */
60 NULL, /* class_data */
61 0, /* instance_size */
62 0, /* n_preallocs */
63 NULL, /* instance_init */
64 NULL /* value_table */
65 };
66
67 type = g_type_register_static (G_TYPE_INTERFACE,
68 "McpAccountManager", &info, 0);
69 g_type_interface_add_prerequisite (type, G_TYPE_OBJECT);
70 g_once_init_leave (&once, 1);
71 }
72
73 return type;
74 }
75
76 /**
77 * mcp_account_manager_set_value:
78 * @mcpa: an #McpAccountManager instance
79 * @account: the unique name of an account
80 * @key: the setting whose value we wish to change: either an attribute
81 * like "DisplayName", or "param-" plus a parameter like "account"
82 * @value: the new value, escaped as if for a #GKeyFile, or %NULL to delete
83 * the setting/parameter
84 *
85 * Inform Mission Control that @key has changed its value to @value.
86 *
87 * This function may either be called from mcp_account_storage_get(),
88 * or just before emitting #McpAccountStorage::altered-one.
89 *
90 * New plugins should call mcp_account_manager_set_attribute() or
91 * mcp_account_manager_set_parameter() instead.
92 */
93 void
mcp_account_manager_set_value(const McpAccountManager * mcpa,const gchar * account,const gchar * key,const gchar * value)94 mcp_account_manager_set_value (const McpAccountManager *mcpa,
95 const gchar *account,
96 const gchar *key,
97 const gchar *value)
98 {
99 McpAccountManagerIface *iface = MCP_ACCOUNT_MANAGER_GET_IFACE (mcpa);
100
101 g_return_if_fail (iface != NULL);
102 g_return_if_fail (iface->set_value != NULL);
103
104 iface->set_value (mcpa, account, key, value);
105 }
106
107 /**
108 * mcp_account_manager_set_attribute:
109 * @mcpa: an #McpAccountManager instance
110 * @account: the unique name of an account
111 * @attribute: the name of an attribute, such as "DisplayName"
112 * @value: (allow-none): the new value, or %NULL to delete the attribute
113 * @flags: flags for the new value (only used if @value is non-%NULL)
114 *
115 * Inform Mission Control that @attribute has changed its value to @value.
116 *
117 * If @value is a floating reference, Mission Control will take ownership
118 * of it, much like g_variant_builder_add_value().
119 *
120 * This function may either be called from mcp_account_storage_get(),
121 * or just before emitting #McpAccountStorage::altered-one.
122 */
123 void
mcp_account_manager_set_attribute(const McpAccountManager * mcpa,const gchar * account,const gchar * attribute,GVariant * value,McpAttributeFlags flags)124 mcp_account_manager_set_attribute (const McpAccountManager *mcpa,
125 const gchar *account,
126 const gchar *attribute,
127 GVariant *value,
128 McpAttributeFlags flags)
129 {
130 McpAccountManagerIface *iface = MCP_ACCOUNT_MANAGER_GET_IFACE (mcpa);
131
132 g_return_if_fail (iface != NULL);
133 g_return_if_fail (iface->set_attribute != NULL);
134
135 iface->set_attribute (mcpa, account, attribute, value, flags);
136 }
137
138 /**
139 * mcp_account_manager_set_parameter:
140 * @mcpa: an #McpAccountManager instance
141 * @account: the unique name of an account
142 * @parameter: the name of a parameter, such as "account", without
143 * the "param-" prefix
144 * @value: (allow-none): the new value, or %NULL to delete the parameter
145 * @flags: flags for the new value (only used if @value is non-%NULL)
146 *
147 * Inform Mission Control that @parameter has changed its value to @value.
148 *
149 * If @value is a floating reference, Mission Control will take ownership
150 * of it, much like g_variant_builder_add_value().
151 *
152 * This function may either be called from mcp_account_storage_get(),
153 * or just before emitting #McpAccountStorage::altered-one.
154 */
155 void
mcp_account_manager_set_parameter(const McpAccountManager * mcpa,const gchar * account,const gchar * parameter,GVariant * value,McpParameterFlags flags)156 mcp_account_manager_set_parameter (const McpAccountManager *mcpa,
157 const gchar *account,
158 const gchar *parameter,
159 GVariant *value,
160 McpParameterFlags flags)
161 {
162 McpAccountManagerIface *iface = MCP_ACCOUNT_MANAGER_GET_IFACE (mcpa);
163
164 g_return_if_fail (iface != NULL);
165 g_return_if_fail (iface->set_parameter != NULL);
166
167 iface->set_parameter (mcpa, account, parameter, value, flags);
168 }
169
170 /**
171 * mcp_account_manage_list_keys:
172 * @mcpa: a #McpAccountManager instance
173 * @account: the unique name of an account
174 *
175 * <!-- -->
176 *
177 * Returns: (transfer full): a list of all keys (attributes and
178 * "param-"-prefixed parameters) stored for @account by any plugin
179 */
180 GStrv
mcp_account_manager_list_keys(const McpAccountManager * mcpa,const gchar * account)181 mcp_account_manager_list_keys (const McpAccountManager *mcpa,
182 const gchar *account)
183 {
184 McpAccountManagerIface *iface = MCP_ACCOUNT_MANAGER_GET_IFACE (mcpa);
185
186 g_return_val_if_fail (iface != NULL, NULL);
187 g_return_val_if_fail (iface->list_keys != NULL, NULL);
188 g_return_val_if_fail (account != NULL, NULL);
189
190 return iface->list_keys (mcpa, account);
191 }
192
193 /**
194 * mcp_account_manager_get_value:
195 * @mcpa: an #McpAccountManager instance
196 * @account: the unique name of an account
197 * @key: the setting whose value we wish to fetch: either an attribute
198 * like "DisplayName", or "param-" plus a parameter like "account"
199 *
200 * Fetch a copy of the current value of an account setting held by
201 * the account manager.
202 *
203 * Returns: (transfer full): the value of @key
204 */
205 gchar *
mcp_account_manager_get_value(const McpAccountManager * mcpa,const gchar * account,const gchar * key)206 mcp_account_manager_get_value (const McpAccountManager *mcpa,
207 const gchar *account,
208 const gchar *key)
209 {
210 McpAccountManagerIface *iface = MCP_ACCOUNT_MANAGER_GET_IFACE (mcpa);
211
212 g_return_val_if_fail (iface != NULL, NULL);
213 g_return_val_if_fail (iface->set_value != NULL, NULL);
214
215 return iface->get_value (mcpa, account, key);
216 }
217
218 /**
219 * mcp_account_manager_parameter_is_secret:
220 * @mcpa: an #McpAccountManager instance
221 * @account: the unique name of an account
222 * @key: the constant string "param-", plus a parameter name like
223 * "account" or "password"
224 *
225 * Determine whether a given account parameter is secret.
226 * Generally this is determined by MC and passed down to plugins,
227 * but any #McpAccountStorage plugin may decide a parameter is
228 * secret, in which case the return value for this call will
229 * indicate that fact too.
230 *
231 * For historical reasons, this function only operates on parameters,
232 * but requires its argument to be prefixed with "param-".
233 *
234 * Returns: %TRUE for secret settings, %FALSE otherwise
235 */
236 gboolean
mcp_account_manager_parameter_is_secret(const McpAccountManager * mcpa,const gchar * account,const gchar * key)237 mcp_account_manager_parameter_is_secret (const McpAccountManager *mcpa,
238 const gchar *account,
239 const gchar *key)
240 {
241 McpAccountManagerIface *iface = MCP_ACCOUNT_MANAGER_GET_IFACE (mcpa);
242
243 g_return_val_if_fail (iface != NULL, FALSE);
244 g_return_val_if_fail (iface->is_secret != NULL, FALSE);
245
246 return iface->is_secret (mcpa, account, key);
247 }
248
249 /**
250 * mcp_account_manager_parameter_make_secret:
251 * @mcpa: an #McpAccountManager instance
252 * @account: the unique name of an account
253 * @key: the constant string "param-", plus a parameter name like
254 * "account" or "password"
255 *
256 * Flag an account setting as secret for the lifetime of this
257 * #McpAccountManager. For instance, this should be called if
258 * @key has been retrieved from gnome-keyring.
259 *
260 * For historical reasons, this function only operates on parameters,
261 * but requires its argument to be prefixed with "param-".
262 */
263 void
mcp_account_manager_parameter_make_secret(const McpAccountManager * mcpa,const gchar * account,const gchar * key)264 mcp_account_manager_parameter_make_secret (const McpAccountManager *mcpa,
265 const gchar *account,
266 const gchar *key)
267 {
268 McpAccountManagerIface *iface = MCP_ACCOUNT_MANAGER_GET_IFACE (mcpa);
269
270 g_return_if_fail (iface != NULL);
271 g_return_if_fail (iface->make_secret != NULL);
272
273 g_debug ("%s.%s should be secret", account, key);
274 iface->make_secret (mcpa, account, key);
275 }
276
277 /**
278 * mcp_account_manager_get_unique_name:
279 * @mcpa: an #McpAccountManager instance
280 * @manager: the name of the manager
281 * @protocol: the name of the protocol
282 * @params: A gchar * / GValue * hash table of account parameters.
283 *
284 * Generate and return the canonical unique name of this [new] account.
285 * Should not be called for accounts which have already had a name
286 * assigned: Intended for use when a plugin encounters an account which
287 * MC has not previously seen before (ie one created by a 3rd party
288 * in the back-end that the plugin in question provides an interface to).
289 *
290 * Returns: the newly allocated account name, which should be freed
291 * once the caller is done with it.
292 */
293 gchar *
mcp_account_manager_get_unique_name(McpAccountManager * mcpa,const gchar * manager,const gchar * protocol,const GHashTable * params)294 mcp_account_manager_get_unique_name (McpAccountManager *mcpa,
295 const gchar *manager,
296 const gchar *protocol,
297 const GHashTable *params)
298 {
299 McpAccountManagerIface *iface = MCP_ACCOUNT_MANAGER_GET_IFACE (mcpa);
300
301 g_return_val_if_fail (iface != NULL, NULL);
302 g_return_val_if_fail (iface->unique_name != NULL, NULL);
303
304 return iface->unique_name (mcpa, manager, protocol, params);
305 }
306
307 /**
308 * mcp_account_manager_escape_value_from_keyfile:
309 * @mcpa: a #McpAccountManager
310 * @value: a value with a supported #GType
311 *
312 * Escape @value so it could be passed to g_key_file_set_value().
313 * For instance, escaping the boolean value TRUE returns "true",
314 * and escaping the string value containing one space returns "\s".
315 *
316 * It is a programming error to use an unsupported type.
317 * The supported types are currently %G_TYPE_STRING, %G_TYPE_BOOLEAN,
318 * %G_TYPE_INT, %G_TYPE_UINT, %G_TYPE_INT64, %G_TYPE_UINT64, %G_TYPE_UCHAR,
319 * %G_TYPE_STRV, %DBUS_TYPE_G_OBJECT_PATH and %TP_ARRAY_TYPE_OBJECT_PATH_LIST.
320 *
321 * Returns: the escaped form of @value
322 */
323 gchar *
mcp_account_manager_escape_value_for_keyfile(const McpAccountManager * mcpa,const GValue * value)324 mcp_account_manager_escape_value_for_keyfile (const McpAccountManager *mcpa,
325 const GValue *value)
326 {
327 McpAccountManagerIface *iface = MCP_ACCOUNT_MANAGER_GET_IFACE (mcpa);
328
329 g_return_val_if_fail (iface != NULL, NULL);
330 g_return_val_if_fail (iface->escape_value_for_keyfile != NULL, NULL);
331
332 return iface->escape_value_for_keyfile (mcpa, value);
333 }
334
335 /**
336 * mcp_account_manager_escape_variant_for_keyfile:
337 * @mcpa: a #McpAccountManager
338 * @variant: a #GVariant with a supported #GVariantType
339 *
340 * Escape @variant so it could be passed to g_key_file_set_value().
341 * For instance, escaping the boolean value TRUE returns "true",
342 * and escaping the string value containing one space returns "\s".
343 *
344 * It is a programming error to use an unsupported type.
345 * The supported types are currently %G_VARIANT_TYPE_STRING,
346 * %G_VARIANT_TYPE_BOOLEAN, %G_VARIANT_TYPE_INT32, %G_VARIANT_TYPE_UINT32,
347 * %G_VARIANT_TYPE_INT64, %G_VARIANT_TYPE_UINT64, %G_VARIANT_TYPE_BYTE,
348 * %G_VARIANT_TYPE_STRING_ARRAY, %G_VARIANT_TYPE_OBJECT_PATH and
349 * %G_VARIANT_TYPE_OBJECT_PATH_ARRAY.
350 *
351 * Returns: (transfer full): the escaped form of @variant
352 */
353 gchar *
mcp_account_manager_escape_variant_for_keyfile(const McpAccountManager * mcpa,GVariant * variant)354 mcp_account_manager_escape_variant_for_keyfile (const McpAccountManager *mcpa,
355 GVariant *variant)
356 {
357 McpAccountManagerIface *iface = MCP_ACCOUNT_MANAGER_GET_IFACE (mcpa);
358
359 g_return_val_if_fail (iface != NULL, NULL);
360 g_return_val_if_fail (iface->escape_variant_for_keyfile != NULL, NULL);
361
362 return iface->escape_variant_for_keyfile (mcpa, variant);
363 }
364
365 /**
366 * mcp_account_manager_unescape_value_from_keyfile:
367 * @mcpa: a #McpAccountManager
368 * @escaped: an escaped string as returned by g_key_file_get_value()
369 * @value: a value to populate, with a supported #GType
370 * @error: used to raise an error if %FALSE is returned
371 *
372 * Attempt to interpret @escaped as a value of @value's type.
373 * If successful, put it in @value and return %TRUE.
374 *
375 * It is a programming error to try to escape an unsupported type.
376 * The supported types are currently %G_TYPE_STRING, %G_TYPE_BOOLEAN,
377 * %G_TYPE_INT, %G_TYPE_UINT, %G_TYPE_INT64, %G_TYPE_UINT64, %G_TYPE_UCHAR,
378 * %G_TYPE_STRV, %DBUS_TYPE_G_OBJECT_PATH and %TP_ARRAY_TYPE_OBJECT_PATH_LIST.
379 *
380 * Returns: %TRUE if @value was filled in
381 */
382 gboolean
mcp_account_manager_unescape_value_from_keyfile(const McpAccountManager * mcpa,const gchar * escaped,GValue * value,GError ** error)383 mcp_account_manager_unescape_value_from_keyfile (const McpAccountManager *mcpa,
384 const gchar *escaped,
385 GValue *value,
386 GError **error)
387 {
388 McpAccountManagerIface *iface = MCP_ACCOUNT_MANAGER_GET_IFACE (mcpa);
389
390 g_return_val_if_fail (iface != NULL, FALSE);
391 g_return_val_if_fail (iface->unescape_value_from_keyfile != NULL, FALSE);
392
393 return iface->unescape_value_from_keyfile (mcpa, escaped, value, error);
394 }
395
396 /**
397 * mcp_account_manager_init_value_for_attribute:
398 * @mcpa: a #McpAccountManager
399 * @value: a zero-filled value to initialize
400 * @attribute: a supported Mission Control attribute
401 *
402 * If @attribute is a known Mission Control attribute, initialize @value
403 * with an appropriate type for @attribute and return %TRUE. Otherwise,
404 * return %FALSE.
405 *
406 * Returns: %TRUE if @value was initialized
407 */
408 gboolean
mcp_account_manager_init_value_for_attribute(const McpAccountManager * mcpa,GValue * value,const gchar * attribute)409 mcp_account_manager_init_value_for_attribute (const McpAccountManager *mcpa,
410 GValue *value,
411 const gchar *attribute)
412 {
413 McpAccountManagerIface *iface = MCP_ACCOUNT_MANAGER_GET_IFACE (mcpa);
414
415 g_return_val_if_fail (iface != NULL, FALSE);
416 g_return_val_if_fail (iface->init_value_for_attribute != NULL, FALSE);
417
418 return iface->init_value_for_attribute (mcpa, value, attribute);
419 }
420