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-2014 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,
75 g_hash_table_insert ((GHashTable *) user_data,
76 g_strdup ((const gchar *) key),
77 g_strdupv ((gchar **) value));
81 * signon_identity_info_set_methods:
82 * @info: the #SignonIdentityInfo.
83 * @methods: (transfer none): (element-type utf8 GStrv): methods.
85 * Set authentication methods that are allowed to be used with this identity.
87 void signon_identity_info_set_methods (SignonIdentityInfo *info,
90 g_return_if_fail (info != NULL);
91 g_return_if_fail (methods != NULL);
93 DEBUG("%s", G_STRFUNC);
95 GHashTable *new_methods =
96 g_hash_table_new_full (g_str_hash,
99 (GDestroyNotify) g_strfreev);
100 g_hash_table_foreach (methods, identity_methods_copy, new_methods);
101 g_hash_table_unref (info->methods);
102 info->methods = new_methods;
106 * signon_identity_info_own_methods:
107 * @info: the #SignonIdentityInfo.
108 * @methods: (transfer none): (element-type utf8 GStrv): methods.
110 * Set authentication methods that are allowed to be used with this identity.
112 * This function will just increment reference count of hash table, so
113 * it should be constructed with #g_hash_table_new_full.
115 void signon_identity_info_own_methods (SignonIdentityInfo *info,
118 g_return_if_fail (info != NULL);
119 g_return_if_fail (methods != NULL);
121 DEBUG("%s", G_STRFUNC);
123 g_hash_table_ref (methods);
124 info->methods = methods;
128 signon_identity_info_new_from_variant (GVariant *variant)
130 GVariant *method_map;
137 SignonIdentityInfo *info = signon_identity_info_new ();
139 DEBUG("%s: ", G_STRFUNC);
141 g_variant_lookup (variant,
142 SIGNOND_IDENTITY_INFO_ID,
146 g_variant_lookup (variant,
147 SIGNOND_IDENTITY_INFO_USERNAME,
151 g_variant_lookup (variant,
152 SIGNOND_IDENTITY_INFO_SECRET,
156 g_variant_lookup (variant,
157 SIGNOND_IDENTITY_INFO_STORESECRET,
159 &info->store_secret);
161 g_variant_lookup (variant,
162 SIGNOND_IDENTITY_INFO_CAPTION,
166 g_variant_lookup (variant,
167 SIGNOND_IDENTITY_INFO_REALMS,
171 /* get the methods */
172 if (g_variant_lookup (variant,
173 SIGNOND_IDENTITY_INFO_AUTHMETHODS,
181 g_variant_iter_init (&iter, method_map);
182 while (g_variant_iter_next (&iter, "{s^as}", &method, &mechanisms))
184 g_hash_table_insert (info->methods, method, mechanisms);
186 g_variant_unref (method_map);
189 if (g_variant_lookup (variant,
190 SIGNOND_IDENTITY_INFO_OWNER,
194 info->owner = signon_security_context_deconstruct_variant (owner);
195 g_variant_unref (owner);
198 if (g_variant_lookup (variant,
199 SIGNOND_IDENTITY_INFO_ACL,
203 info->access_control_list =
204 signon_security_context_list_deconstruct_variant (acl);
205 g_variant_unref (acl);
208 g_variant_lookup (variant,
209 SIGNOND_IDENTITY_INFO_TYPE,
217 signon_identity_info_to_variant (const SignonIdentityInfo *self)
219 GVariantBuilder builder;
220 GVariantBuilder method_builder;
221 GVariant *method_map;
224 const gchar **mechanisms;
226 g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
228 g_variant_builder_add (&builder, "{sv}",
229 SIGNOND_IDENTITY_INFO_ID,
230 g_variant_new_uint32 (self->id));
232 if (self->username != NULL) {
233 g_variant_builder_add (&builder, "{sv}",
234 SIGNOND_IDENTITY_INFO_USERNAME,
235 signon_variant_new_string (self->username));
238 if (self->secret != NULL) {
239 g_variant_builder_add (&builder, "{sv}",
240 SIGNOND_IDENTITY_INFO_SECRET,
241 signon_variant_new_string (self->secret));
244 if (self->caption != NULL) {
245 g_variant_builder_add (&builder, "{sv}",
246 SIGNOND_IDENTITY_INFO_CAPTION,
247 signon_variant_new_string (self->caption));
250 g_variant_builder_add (&builder, "{sv}",
251 SIGNOND_IDENTITY_INFO_STORESECRET,
252 g_variant_new_boolean (self->store_secret));
254 if (g_hash_table_size(self->methods) > 0) {
255 g_variant_builder_init (&method_builder,
256 (const GVariantType *)"a{sas}");
257 g_hash_table_iter_init (&iter, self->methods);
258 while (g_hash_table_iter_next (&iter,
260 (gpointer)&mechanisms))
262 g_variant_builder_add (&method_builder, "{s^as}",
266 method_map = g_variant_builder_end (&method_builder);
268 g_variant_builder_add (&builder, "{sv}",
269 SIGNOND_IDENTITY_INFO_AUTHMETHODS,
273 if (self->realms != NULL)
275 g_variant_builder_add (&builder, "{sv}",
276 SIGNOND_IDENTITY_INFO_REALMS,
277 g_variant_new_strv ((const gchar * const *)
282 if (self->owner != NULL)
284 g_variant_builder_add (&builder, "{sv}",
285 SIGNOND_IDENTITY_INFO_OWNER,
286 signon_security_context_build_variant (
290 if (self->access_control_list != NULL)
292 g_variant_builder_add (&builder, "{sv}",
293 SIGNOND_IDENTITY_INFO_ACL,
294 signon_security_context_list_build_variant (
295 self->access_control_list));
298 g_variant_builder_add (&builder, "{sv}",
299 SIGNOND_IDENTITY_INFO_TYPE,
300 g_variant_new_int32 (self->type));
302 return g_variant_builder_end (&builder);
310 * signon_identity_info_new:
312 * Creates a new #SignonIdentityInfo item.
314 * Returns: a new #SignonIdentityInfo item.
316 SignonIdentityInfo *signon_identity_info_new ()
318 SignonIdentityInfo *info = g_slice_new0 (SignonIdentityInfo);
319 info->methods = g_hash_table_new_full (g_str_hash,
322 (GDestroyNotify) g_strfreev);
323 info->store_secret = FALSE;
329 * signon_identity_info_free:
330 * @info: the #SignonIdentityInfo.
332 * Destroys the given #SignonIdentityInfo item.
334 void signon_identity_info_free (SignonIdentityInfo *info)
336 if (info == NULL) return;
338 g_free (info->username);
339 g_free (info->secret);
340 g_free (info->caption);
342 g_hash_table_unref (info->methods);
344 g_strfreev (info->realms);
345 signon_security_context_free (info->owner);
346 signon_security_context_list_free (info->access_control_list);
348 g_slice_free (SignonIdentityInfo, info);
352 * signon_identity_info_copy:
353 * @other: the #SignonIdentityInfo.
355 * Get a newly-allocated copy of @info.
357 * Returns: a copy of the given #SignonIdentityInfo, or %NULL on failure.
359 SignonIdentityInfo *signon_identity_info_copy (const SignonIdentityInfo *other)
361 g_return_val_if_fail (other != NULL, NULL);
362 SignonIdentityInfo *info = signon_identity_info_new ();
364 identity_info_set_id (info, signon_identity_info_get_id (other));
366 signon_identity_info_set_username (info,
367 signon_identity_info_get_username (other));
369 signon_identity_info_set_secret (info, identity_info_get_secret(other),
370 signon_identity_info_get_storing_secret (other));
372 signon_identity_info_set_caption (info,
373 signon_identity_info_get_caption(other));
375 signon_identity_info_set_methods (info,
376 signon_identity_info_get_methods (other));
378 signon_identity_info_set_realms (info,
379 signon_identity_info_get_realms (other));
381 signon_identity_info_set_owner (info,
382 signon_identity_info_get_owner (other));
384 signon_identity_info_set_access_control_list (info,
385 signon_identity_info_get_access_control_list (other));
387 signon_identity_info_set_identity_type (info,
388 signon_identity_info_get_identity_type (other));
394 * signon_identity_info_get_id:
395 * @info: the #SignonIdentityInfo.
397 * Get the numeric identity ID of @info.
399 * Returns: the numeric ID of the identity.
401 gint signon_identity_info_get_id (const SignonIdentityInfo *info)
403 g_return_val_if_fail (info != NULL, -1);
408 * signon_identity_info_get_username:
409 * @info: the #SignonIdentityInfo.
411 * Get the username associated with an identity.
413 * Returns: the username, or %NULL.
415 const gchar *signon_identity_info_get_username (const SignonIdentityInfo *info)
417 g_return_val_if_fail (info != NULL, NULL);
418 return info->username;
422 * signon_identity_info_get_storing_secret:
423 * @info: the #SignonIdentityInfo.
425 * Get whether the secret of @info should be stored by gSSO in the secret database.
427 * Returns: %TRUE if gSSO must store the secret, %FALSE otherwise.
429 gboolean signon_identity_info_get_storing_secret (const SignonIdentityInfo *info)
431 g_return_val_if_fail (info != NULL, FALSE);
432 return info->store_secret;
436 * signon_identity_info_get_caption:
437 * @info: the #SignonIdentityInfo.
439 * Get the display name of @info.
441 * Returns: the display name for the identity.
443 const gchar *signon_identity_info_get_caption (const SignonIdentityInfo *info)
445 g_return_val_if_fail (info != NULL, NULL);
446 return info->caption;
450 * signon_identity_info_get_methods:
451 * @info: the #SignonIdentityInfo.
453 * Get a hash table of the methods and mechanisms of @info. See
454 * signon_identity_info_set_methods().
456 * Returns: (transfer none): (element-type utf8 GStrv): the table of allowed
457 * methods and mechanisms.
459 GHashTable *signon_identity_info_get_methods (const SignonIdentityInfo *info)
461 g_return_val_if_fail (info != NULL, NULL);
462 return info->methods;
466 * signon_identity_info_get_realms:
467 * @info: the #SignonIdentityInfo.
469 * Get an array of the allowed realms of @info.
471 * Returns: (transfer none): a %NULL terminated array of realms.
473 const gchar* const *signon_identity_info_get_realms (const SignonIdentityInfo *info)
475 g_return_val_if_fail (info != NULL, NULL);
476 return (const gchar* const *)info->realms;
480 * signon_identity_info_get_owner:
481 * @info: the #SignonIdentityInfo.
483 * Get identity owner's security context.
485 * Returns: (transfer none): a security context.
487 const SignonSecurityContext *signon_identity_info_get_owner (const SignonIdentityInfo *info)
489 g_return_val_if_fail (info != NULL, NULL);
494 * signon_identity_info_get_access_control_list:
495 * @info: the #SignonIdentityInfo.
497 * Get an access control list associated with an identity.
499 * Returns: (transfer none): a list of ACL security contexts.
501 SignonSecurityContextList *signon_identity_info_get_access_control_list (const SignonIdentityInfo *info)
503 g_return_val_if_fail (info != NULL, NULL);
504 return info->access_control_list;
508 * signon_identity_info_get_identity_type:
509 * @info: the #SignonIdentityInfo.
511 * Get the type of the identity.
513 * Returns: the type of the identity.
515 SignonIdentityType signon_identity_info_get_identity_type (const SignonIdentityInfo *info)
517 g_return_val_if_fail (info != NULL, -1);
518 return (SignonIdentityType)info->type;
522 static void _replace_string (gchar **dst, const gchar *src)
524 gchar *new_str = g_strdup (src);
530 * signon_identity_info_set_username:
531 * @info: the #SignonIdentityInfo.
532 * @username: the username.
534 * Sets the username for the identity.
537 void signon_identity_info_set_username (SignonIdentityInfo *info,
538 const gchar *username)
540 g_return_if_fail (info != NULL);
542 _replace_string (&info->username, username);
546 * signon_identity_info_set_secret:
547 * @info: the #SignonIdentityInfo.
548 * @secret: the secret.
549 * @store_secret: whether signond should store the secret in its DB.
551 * Sets the secret (password) for the identity, and whether the gSSO daemon
552 * should remember it.
555 void signon_identity_info_set_secret (SignonIdentityInfo *info,
557 gboolean store_secret)
559 g_return_if_fail (info != NULL);
561 _replace_string (&info->secret, secret);
562 info->store_secret = store_secret;
566 * signon_identity_info_set_caption:
567 * @info: the #SignonIdentityInfo.
568 * @caption: the caption.
570 * Sets the caption (display name) for the identity.
573 void signon_identity_info_set_caption (SignonIdentityInfo *info,
574 const gchar *caption)
576 g_return_if_fail (info != NULL);
578 _replace_string (&info->caption, caption);
582 * signon_identity_info_set_method:
583 * @info: the #SignonIdentityInfo.
584 * @method: an authentication method.
585 * @mechanisms: a %NULL-terminated list of mechanisms.
587 * Adds a method to the list of allowed authentication methods.
589 void signon_identity_info_set_method (SignonIdentityInfo *info, const gchar *method,
590 const gchar* const *mechanisms)
592 g_return_if_fail (info != NULL);
594 g_return_if_fail (info->methods != NULL);
595 g_return_if_fail (method != NULL);
596 g_return_if_fail (mechanisms != NULL);
598 g_hash_table_replace (info->methods,
599 g_strdup(method), g_strdupv((gchar **)mechanisms));
603 * signon_identity_info_remove_method:
604 * @info: the #SignonIdentityInfo.
605 * @method: an authentication method.
607 * Remove @method from the list of allowed authentication methods.
609 void signon_identity_info_remove_method (SignonIdentityInfo *info, const gchar *method)
611 g_return_if_fail (info != NULL);
612 g_return_if_fail (info->methods != NULL);
614 g_hash_table_remove (info->methods, method);
618 * signon_identity_info_set_realms:
619 * @info: the #SignonIdentityInfo.
620 * @realms: a %NULL-terminated list of realms.
622 * Specify what realms this identity can be used in.
624 void signon_identity_info_set_realms (SignonIdentityInfo *info,
625 const gchar* const *realms)
627 g_return_if_fail (info != NULL);
629 gchar **new_realms = g_strdupv ((gchar **) realms);
631 if (info->realms) g_strfreev (info->realms);
633 info->realms = new_realms;
637 * signon_identity_info_set_owner:
638 * @info: the #SignonIdentityInfo.
639 * @owner: (transfer none): a security context of owner.
641 * Set identity owner's security context.
643 void signon_identity_info_set_owner (SignonIdentityInfo *info,
644 const SignonSecurityContext *owner)
646 g_return_if_fail (info != NULL);
648 SignonSecurityContext *new_owner = signon_security_context_copy (owner);
650 if (info->owner) signon_security_context_free (info->owner);
652 info->owner = new_owner;
656 * signon_identity_info_set_owner_from_values:
657 * @info: the #SignonIdentityInfo.
658 * @system_context: owner's system context.
659 * @application_context: owner's application context.
661 * Set identity owner's security context.
663 void signon_identity_info_set_owner_from_values (
664 SignonIdentityInfo *info,
665 const gchar *system_context,
666 const gchar *application_context)
668 g_return_if_fail (info != NULL &&
669 system_context != NULL &&
670 application_context != NULL);
672 if (info->owner) signon_security_context_free (info->owner);
674 info->owner = signon_security_context_new_from_values(system_context,
675 application_context);
679 * signon_identity_info_set_access_control_list:
680 * @info: the #SignonIdentityInfo.
681 * @access_control_list: (transfer none): a list of ACL security contexts.
683 * Set an access control list associated with an identity.
685 void signon_identity_info_set_access_control_list (SignonIdentityInfo *info,
686 SignonSecurityContextList *access_control_list)
688 g_return_if_fail (info != NULL);
690 SignonSecurityContextList *new_acl =
691 signon_security_context_list_copy (access_control_list);
693 if (info->access_control_list)
694 signon_security_context_list_free (info->access_control_list);
696 info->access_control_list = new_acl;
700 * signon_identity_info_access_control_list_append:
701 * @info: the #SignonIdentityInfo.
702 * @security_context: (transfer full): a security context to be appended.
704 * Appends a new #SignonSecurityContext item to the access control list.
706 void signon_identity_info_access_control_list_append (
707 SignonIdentityInfo *info,
708 SignonSecurityContext *security_context)
710 g_return_if_fail (info != NULL);
711 g_return_if_fail (security_context != NULL);
713 info->access_control_list = g_list_append (info->access_control_list,
718 * signon_identity_info_set_identity_type:
719 * @info: the #SignonIdentityInfo.
720 * @type: the type of the identity.
722 * Specifies the type of this identity.
724 void signon_identity_info_set_identity_type (SignonIdentityInfo *info,
725 SignonIdentityType type)
727 g_return_if_fail (info != NULL);
728 info->type = (gint) type;