1 /* vi: set et sw=4 ts=4 cino=t0,(0: */
2 /* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
4 * This file is part of libgsignon-glib
6 * Copyright (C) 2009-2010 Nokia Corporation.
7 * Copyright (C) 2011-2012 Canonical Ltd.
8 * Copyright (C) 2012-2013 Intel Corporation.
10 * Contact: Alberto Mardegan <alberto.mardegan@canonical.com>
11 * Contact: Jussi Laako <jussi.laako@linux.intel.com>
13 * This library is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU Lesser General Public License
15 * version 2.1 as published by the Free Software Foundation.
17 * This library is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with this library; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
29 * SECTION:signon-identity-info
30 * @title: SignonIdentityInfo
31 * @short_description: data contained in a SignonIdentity.
33 * #SignonIdentityInfo represents data contained in a database record for an identity
34 * and provides getters and setters for individual items.
36 * See #SignonIdentity for a detailed discussion
37 * of what each item means and how and when it's used.
40 #include "signon-identity-info.h"
42 #include "signon-internals.h"
43 #include "signon-utils.h"
45 G_DEFINE_BOXED_TYPE (SignonIdentityInfo, signon_identity_info,
46 (GBoxedCopyFunc)signon_identity_info_copy,
47 (GBoxedFreeFunc)signon_identity_info_free);
51 signon_variant_new_string (const gchar *string)
53 return g_variant_new_string (string != NULL ? string : "");
56 static const gchar *identity_info_get_secret (const SignonIdentityInfo *info)
58 g_return_val_if_fail (info != NULL, NULL);
63 static void identity_info_set_id (SignonIdentityInfo *info, gint id)
65 g_return_if_fail (info != NULL);
66 g_return_if_fail (id >= 0);
71 static void identity_methods_copy (gpointer key, gpointer value, gpointer user_data)
73 signon_identity_info_set_method ((SignonIdentityInfo *)user_data,
75 (const gchar* const *)value);
79 * signon_identity_info_set_methods:
80 * @info: the #SignonIdentityInfo.
81 * @methods: (transfer none): (element-type utf8 GStrv): methods.
83 * Set authentication methods that are allowed to be used with this identity.
85 void signon_identity_info_set_methods (SignonIdentityInfo *info,
86 const GHashTable *methods)
88 g_return_if_fail (info != NULL);
89 g_return_if_fail (methods != NULL);
91 DEBUG("%s", G_STRFUNC);
94 g_hash_table_remove_all (info->methods);
96 info->methods = g_hash_table_new_full (g_str_hash, g_str_equal,
97 g_free, (GDestroyNotify)g_strfreev);
99 g_hash_table_foreach ((GHashTable *)methods, identity_methods_copy, info);
103 signon_identity_info_new_from_variant (GVariant *variant)
105 GVariant *method_map;
112 SignonIdentityInfo *info = signon_identity_info_new ();
114 DEBUG("%s: ", G_STRFUNC);
116 g_variant_lookup (variant,
117 SIGNOND_IDENTITY_INFO_ID,
121 g_variant_lookup (variant,
122 SIGNOND_IDENTITY_INFO_USERNAME,
126 if (g_variant_lookup (variant,
127 SIGNOND_IDENTITY_INFO_SECRET,
131 g_variant_lookup (variant,
132 SIGNOND_IDENTITY_INFO_STORESECRET,
134 &info->store_secret);
137 g_variant_lookup (variant,
138 SIGNOND_IDENTITY_INFO_CAPTION,
142 g_variant_lookup (variant,
143 SIGNOND_IDENTITY_INFO_REALMS,
147 /* get the methods */
148 if (g_variant_lookup (variant,
149 SIGNOND_IDENTITY_INFO_AUTHMETHODS,
157 g_variant_iter_init (&iter, method_map);
158 while (g_variant_iter_next (&iter, "{s^as}", &method, &mechanisms))
160 g_hash_table_insert (info->methods, method, mechanisms);
162 g_variant_unref (method_map);
165 if (g_variant_lookup (variant,
166 SIGNOND_IDENTITY_INFO_OWNER,
170 info->owner = signon_security_context_deconstruct_variant (owner);
171 g_variant_unref (owner);
174 if (g_variant_lookup (variant,
175 SIGNOND_IDENTITY_INFO_ACL,
179 info->access_control_list =
180 signon_security_context_list_deconstruct_variant (acl);
181 g_variant_unref (acl);
184 g_variant_lookup (variant,
185 SIGNOND_IDENTITY_INFO_TYPE,
193 signon_identity_info_to_variant (const SignonIdentityInfo *self)
195 GVariantBuilder builder;
196 GVariantBuilder method_builder;
197 GVariant *method_map;
200 const gchar **mechanisms;
202 g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
204 g_variant_builder_add (&builder, "{sv}",
205 SIGNOND_IDENTITY_INFO_ID,
206 g_variant_new_uint32 (self->id));
208 g_variant_builder_add (&builder, "{sv}",
209 SIGNOND_IDENTITY_INFO_USERNAME,
210 signon_variant_new_string (self->username));
212 g_variant_builder_add (&builder, "{sv}",
213 SIGNOND_IDENTITY_INFO_SECRET,
214 signon_variant_new_string (self->secret));
216 g_variant_builder_add (&builder, "{sv}",
217 SIGNOND_IDENTITY_INFO_CAPTION,
218 signon_variant_new_string (self->caption));
220 g_variant_builder_add (&builder, "{sv}",
221 SIGNOND_IDENTITY_INFO_STORESECRET,
222 g_variant_new_boolean (self->store_secret));
224 g_variant_builder_init (&method_builder,
225 (const GVariantType *)"a{sas}");
226 g_hash_table_iter_init (&iter, self->methods);
227 while (g_hash_table_iter_next (&iter,
229 (gpointer)&mechanisms))
231 g_variant_builder_add (&method_builder, "{s^as}",
235 method_map = g_variant_builder_end (&method_builder);
237 g_variant_builder_add (&builder, "{sv}",
238 SIGNOND_IDENTITY_INFO_AUTHMETHODS,
241 if (self->realms != NULL)
243 g_variant_builder_add (&builder, "{sv}",
244 SIGNOND_IDENTITY_INFO_REALMS,
245 g_variant_new_strv ((const gchar * const *)
250 if (self->owner != NULL)
252 g_variant_builder_add (&builder, "{sv}",
253 SIGNOND_IDENTITY_INFO_OWNER,
254 signon_security_context_build_variant (
258 if (self->access_control_list != NULL)
260 g_variant_builder_add (&builder, "{sv}",
261 SIGNOND_IDENTITY_INFO_ACL,
262 signon_security_context_list_build_variant (
263 self->access_control_list));
266 g_variant_builder_add (&builder, "{sv}",
267 SIGNOND_IDENTITY_INFO_TYPE,
268 g_variant_new_int32 (self->type));
270 return g_variant_builder_end (&builder);
278 * signon_identity_info_new:
280 * Creates a new #SignonIdentityInfo item.
282 * Returns: a new #SignonIdentityInfo item.
284 SignonIdentityInfo *signon_identity_info_new ()
286 SignonIdentityInfo *info = g_slice_new0 (SignonIdentityInfo);
287 info->methods = g_hash_table_new_full (g_str_hash, g_str_equal,
288 g_free, (GDestroyNotify)g_strfreev);
289 info->store_secret = FALSE;
295 * signon_identity_info_free:
296 * @info: the #SignonIdentityInfo.
298 * Destroys the given #SignonIdentityInfo item.
300 void signon_identity_info_free (SignonIdentityInfo *info)
302 if (info == NULL) return;
304 g_free (info->username);
305 g_free (info->secret);
306 g_free (info->caption);
308 g_hash_table_destroy (info->methods);
310 g_strfreev (info->realms);
311 signon_security_context_free (info->owner);
312 signon_security_context_list_free (info->access_control_list);
314 g_slice_free (SignonIdentityInfo, info);
318 * signon_identity_info_copy:
319 * @other: the #SignonIdentityInfo.
321 * Get a newly-allocated copy of @info.
323 * Returns: a copy of the given #SignonIdentityInfo, or %NULL on failure.
325 SignonIdentityInfo *signon_identity_info_copy (const SignonIdentityInfo *other)
327 g_return_val_if_fail (other != NULL, NULL);
328 SignonIdentityInfo *info = signon_identity_info_new ();
330 identity_info_set_id (info, signon_identity_info_get_id (other));
332 signon_identity_info_set_username (info,
333 signon_identity_info_get_username (other));
335 signon_identity_info_set_secret (info, identity_info_get_secret(other),
336 signon_identity_info_get_storing_secret (other));
338 signon_identity_info_set_caption (info,
339 signon_identity_info_get_caption(other));
341 signon_identity_info_set_methods (info,
342 signon_identity_info_get_methods (other));
344 signon_identity_info_set_realms (info,
345 signon_identity_info_get_realms (other));
347 signon_identity_info_set_owner (info,
348 signon_identity_info_get_owner (other));
350 signon_identity_info_set_access_control_list (info,
351 signon_identity_info_get_access_control_list (other));
353 signon_identity_info_set_identity_type (info,
354 signon_identity_info_get_identity_type (other));
360 * signon_identity_info_get_id:
361 * @info: the #SignonIdentityInfo.
363 * Get the numeric identity ID of @info.
365 * Returns: the numeric ID of the identity.
367 gint signon_identity_info_get_id (const SignonIdentityInfo *info)
369 g_return_val_if_fail (info != NULL, -1);
374 * signon_identity_info_get_username:
375 * @info: the #SignonIdentityInfo.
377 * Get the username associated with an identity.
379 * Returns: the username, or %NULL.
381 const gchar *signon_identity_info_get_username (const SignonIdentityInfo *info)
383 g_return_val_if_fail (info != NULL, NULL);
384 return info->username;
388 * signon_identity_info_get_storing_secret:
389 * @info: the #SignonIdentityInfo.
391 * Get whether the secret of @info should be stored by gSSO in the secret database.
393 * Returns: %TRUE if gSSO must store the secret, %FALSE otherwise.
395 gboolean signon_identity_info_get_storing_secret (const SignonIdentityInfo *info)
397 g_return_val_if_fail (info != NULL, FALSE);
398 return info->store_secret;
402 * signon_identity_info_get_caption:
403 * @info: the #SignonIdentityInfo.
405 * Get the display name of @info.
407 * Returns: the display name for the identity.
409 const gchar *signon_identity_info_get_caption (const SignonIdentityInfo *info)
411 g_return_val_if_fail (info != NULL, NULL);
412 return info->caption;
416 * signon_identity_info_get_methods:
417 * @info: the #SignonIdentityInfo.
419 * Get a hash table of the methods and mechanisms of @info. See
420 * signon_identity_info_set_methods().
422 * Returns: (transfer none): (element-type utf8 GStrv): the table of allowed
423 * methods and mechanisms.
425 const GHashTable *signon_identity_info_get_methods (const SignonIdentityInfo *info)
427 g_return_val_if_fail (info != NULL, NULL);
428 return info->methods;
432 * signon_identity_info_get_realms:
433 * @info: the #SignonIdentityInfo.
435 * Get an array of the allowed realms of @info.
437 * Returns: (transfer none): a %NULL terminated array of realms.
439 const gchar* const *signon_identity_info_get_realms (const SignonIdentityInfo *info)
441 g_return_val_if_fail (info != NULL, NULL);
442 return (const gchar* const *)info->realms;
446 * signon_identity_info_get_owner:
447 * @info: the #SignonIdentityInfo.
449 * Get identity owner's security context.
451 * Returns: (transfer none): a security context.
453 const SignonSecurityContext *signon_identity_info_get_owner (const SignonIdentityInfo *info)
455 g_return_val_if_fail (info != NULL, NULL);
460 * signon_identity_info_get_access_control_list:
461 * @info: the #SignonIdentityInfo.
463 * Get an access control list associated with an identity.
465 * Returns: (transfer none): a list of ACL security contexts.
467 const SignonSecurityContextList *signon_identity_info_get_access_control_list (const SignonIdentityInfo *info)
469 g_return_val_if_fail (info != NULL, NULL);
470 return info->access_control_list;
474 * signon_identity_info_get_identity_type:
475 * @info: the #SignonIdentityInfo.
477 * Get the type of the identity.
479 * Returns: the type of the identity.
481 SignonIdentityType signon_identity_info_get_identity_type (const SignonIdentityInfo *info)
483 g_return_val_if_fail (info != NULL, -1);
484 return (SignonIdentityType)info->type;
488 * signon_identity_info_set_username:
489 * @info: the #SignonIdentityInfo.
490 * @username: the username.
492 * Sets the username for the identity.
495 void signon_identity_info_set_username (SignonIdentityInfo *info, const gchar *username)
497 g_return_if_fail (info != NULL);
499 if (info->username) g_free (info->username);
501 info->username = g_strdup (username);
505 * signon_identity_info_set_secret:
506 * @info: the #SignonIdentityInfo.
507 * @secret: the secret.
508 * @store_secret: whether signond should store the secret in its DB.
510 * Sets the secret (password) for the identity, and whether the gSSO daemon
511 * should remember it.
514 void signon_identity_info_set_secret (SignonIdentityInfo *info, const gchar *secret,
515 gboolean store_secret)
517 g_return_if_fail (info != NULL);
519 if (info->secret) g_free (info->secret);
521 info->secret = g_strdup (secret);
522 info->store_secret = store_secret;
526 * signon_identity_info_set_caption:
527 * @info: the #SignonIdentityInfo.
528 * @caption: the caption.
530 * Sets the caption (display name) for the identity.
533 void signon_identity_info_set_caption (SignonIdentityInfo *info, const gchar *caption)
535 g_return_if_fail (info != NULL);
537 if (info->caption) g_free (info->caption);
539 info->caption = g_strdup (caption);
543 * signon_identity_info_set_method:
544 * @info: the #SignonIdentityInfo.
545 * @method: an authentication method.
546 * @mechanisms: a %NULL-terminated list of mechanisms.
548 * Adds a method to the list of allowed authentication methods.
550 void signon_identity_info_set_method (SignonIdentityInfo *info, const gchar *method,
551 const gchar* const *mechanisms)
553 g_return_if_fail (info != NULL);
555 g_return_if_fail (info->methods != NULL);
556 g_return_if_fail (method != NULL);
557 g_return_if_fail (mechanisms != NULL);
559 g_hash_table_replace (info->methods,
560 g_strdup(method), g_strdupv((gchar **)mechanisms));
564 * signon_identity_info_remove_method:
565 * @info: the #SignonIdentityInfo.
566 * @method: an authentication method.
568 * Remove @method from the list of allowed authentication methods.
570 void signon_identity_info_remove_method (SignonIdentityInfo *info, const gchar *method)
572 g_return_if_fail (info != NULL);
573 g_return_if_fail (info->methods != NULL);
575 g_hash_table_remove (info->methods, method);
579 * signon_identity_info_set_realms:
580 * @info: the #SignonIdentityInfo.
581 * @realms: a %NULL-terminated list of realms.
583 * Specify what realms this identity can be used in.
585 void signon_identity_info_set_realms (SignonIdentityInfo *info,
586 const gchar* const *realms)
588 g_return_if_fail (info != NULL);
590 if (info->realms) g_strfreev (info->realms);
592 info->realms = g_strdupv ((gchar **)realms);
596 * signon_identity_info_set_owner:
597 * @info: the #SignonIdentityInfo.
598 * @owner: (transfer none): a security context of owner.
600 * Set identity owner's security context.
602 void signon_identity_info_set_owner (SignonIdentityInfo *info,
603 const SignonSecurityContext *owner)
605 g_return_if_fail (info != NULL);
607 if (info->owner) signon_security_context_free (info->owner);
609 info->owner = signon_security_context_copy (owner);
613 * signon_identity_info_set_owner_from_values:
614 * @info: the #SignonIdentityInfo.
615 * @system_context: owner's system context.
616 * @application_context: owner's application context.
618 * Set identity owner's security context.
620 void signon_identity_info_set_owner_from_values (
621 SignonIdentityInfo *info,
622 const gchar *system_context,
623 const gchar *application_context)
625 g_return_if_fail (info != NULL &&
626 system_context != NULL &&
627 application_context != NULL);
629 if (info->owner) signon_security_context_free (info->owner);
631 info->owner = signon_security_context_new_from_values(system_context,
632 application_context);
636 * signon_identity_info_set_access_control_list:
637 * @info: the #SignonIdentityInfo.
638 * @access_control_list: (transfer none): a list of ACL security contexts.
640 * Set an access control list associated with an identity.
642 void signon_identity_info_set_access_control_list (SignonIdentityInfo *info,
643 const SignonSecurityContextList *access_control_list)
645 g_return_if_fail (info != NULL);
647 if (info->access_control_list)
648 signon_security_context_list_free (info->access_control_list);
650 info->access_control_list =
651 signon_security_context_list_copy (access_control_list);
655 * signon_identity_info_access_control_list_append:
656 * @info: the #SignonIdentityInfo.
657 * @security_context: (transfer full): a security context to be appended.
659 * Appends a new #SignonSecurityContext item to the access control list.
661 void signon_identity_info_access_control_list_append (
662 SignonIdentityInfo *info,
663 SignonSecurityContext *security_context)
665 g_return_if_fail (info != NULL);
666 g_return_if_fail (security_context != NULL);
668 info->access_control_list = g_list_append (info->access_control_list,
673 * signon_identity_info_set_identity_type:
674 * @info: the #SignonIdentityInfo.
675 * @type: the type of the identity.
677 * Specifies the type of this identity.
679 void signon_identity_info_set_identity_type (SignonIdentityInfo *info,
680 SignonIdentityType type)
682 g_return_if_fail (info != NULL);
683 info->type = (gint)type;