docs: fix GSignonPlugin's signal name
[platform/upstream/libgsignon-glib.git] / libgsignon-glib / signon-identity-info.c
1 /* vi: set et sw=4 ts=4 cino=t0,(0: */
2 /* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 /*
4  * This file is part of libgsignon-glib
5  *
6  * Copyright (C) 2009-2010 Nokia Corporation.
7  * Copyright (C) 2011-2012 Canonical Ltd.
8  * Copyright (C) 2012-2013 Intel Corporation.
9  *
10  * Contact: Alberto Mardegan <alberto.mardegan@canonical.com>
11  * Contact: Jussi Laako <jussi.laako@linux.intel.com>
12  *
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.
16  *
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.
21  *
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
25  * 02110-1301 USA
26  */
27
28 /**
29  * SECTION:signon-identity-info
30  * @title: SignonIdentityInfo
31  * @short_description: data contained in a SignonIdentity.
32  *
33  * #SignonIdentityInfo represents data contained in a database record for an identity
34  * and provides getters and setters for individual items.
35  * 
36  * See #SignonIdentity for a detailed discussion
37  * of what each item means and how and when it's used. 
38  */
39
40 #include "signon-identity-info.h"
41
42 #include "signon-internals.h"
43 #include "signon-utils.h"
44
45 G_DEFINE_BOXED_TYPE (SignonIdentityInfo, signon_identity_info,
46                      (GBoxedCopyFunc)signon_identity_info_copy,
47                      (GBoxedFreeFunc)signon_identity_info_free);
48
49
50 static GVariant *
51 signon_variant_new_string (const gchar *string)
52 {
53     return g_variant_new_string (string != NULL ? string : "");
54 }
55
56 static const gchar *identity_info_get_secret (const SignonIdentityInfo *info)
57 {
58     g_return_val_if_fail (info != NULL, NULL);
59
60     return info->secret;
61 }
62
63 static void identity_info_set_id (SignonIdentityInfo *info, gint id)
64 {
65     g_return_if_fail (info != NULL);
66     g_return_if_fail (id >= 0);
67
68     info->id = id;
69 }
70
71 static void identity_methods_copy (gpointer key, gpointer value, gpointer user_data)
72 {
73     signon_identity_info_set_method ((SignonIdentityInfo *)user_data,
74                                      (const gchar *)key,
75                                      (const gchar* const *)value);
76 }
77
78 /**
79  * signon_identity_info_set_methods:
80  * @info: the #SignonIdentityInfo.
81  * @methods: (transfer none): (element-type utf8 GStrv): methods.
82  *
83  * Set authentication methods that are allowed to be used with this identity. 
84  */
85 void signon_identity_info_set_methods (SignonIdentityInfo *info,
86                                        const GHashTable *methods)
87 {
88     g_return_if_fail (info != NULL);
89     g_return_if_fail (methods != NULL);
90
91     DEBUG("%s", G_STRFUNC);
92
93     if (info->methods)
94         g_hash_table_remove_all (info->methods);
95     else
96         info->methods = g_hash_table_new_full (g_str_hash, g_str_equal,
97                                                g_free, (GDestroyNotify)g_strfreev);
98
99     g_hash_table_foreach ((GHashTable *)methods, identity_methods_copy, info);
100 }
101
102 SignonIdentityInfo *
103 signon_identity_info_new_from_variant (GVariant *variant)
104 {
105     GVariant *method_map;
106     GVariant *owner;
107     GVariant *acl;
108
109     if (!variant)
110         return NULL;
111
112     SignonIdentityInfo *info = signon_identity_info_new ();
113
114     DEBUG("%s: ", G_STRFUNC);
115
116     g_variant_lookup (variant,
117                       SIGNOND_IDENTITY_INFO_ID,
118                       "u",
119                       &info->id);
120
121     g_variant_lookup (variant,
122                       SIGNOND_IDENTITY_INFO_USERNAME,
123                       "s",
124                       &info->username);
125
126     if (g_variant_lookup (variant,
127                           SIGNOND_IDENTITY_INFO_SECRET,
128                           "s",
129                           &info->secret))
130     {
131         g_variant_lookup (variant,
132                           SIGNOND_IDENTITY_INFO_STORESECRET,
133                           "b",
134                           &info->store_secret);
135     }
136
137     g_variant_lookup (variant,
138                       SIGNOND_IDENTITY_INFO_CAPTION,
139                       "s",
140                       &info->caption);
141
142     g_variant_lookup (variant,
143                       SIGNOND_IDENTITY_INFO_REALMS,
144                       "^as",
145                       &info->realms);
146
147     /* get the methods */
148     if (g_variant_lookup (variant,
149                           SIGNOND_IDENTITY_INFO_AUTHMETHODS,
150                           "@a{sas}",
151                           &method_map))
152     {
153         GVariantIter iter;
154         gchar *method;
155         gchar **mechanisms;
156
157         g_variant_iter_init (&iter, method_map);
158         while (g_variant_iter_next (&iter, "{s^as}", &method, &mechanisms))
159         {
160             g_hash_table_insert (info->methods, method, mechanisms);
161         }
162         g_variant_unref (method_map);
163     }
164
165     if (g_variant_lookup (variant,
166                       SIGNOND_IDENTITY_INFO_OWNER,
167                       "@(ss)",
168                       &owner))
169     {
170         info->owner = signon_security_context_deconstruct_variant (owner);
171         g_variant_unref (owner);
172     }
173
174     if (g_variant_lookup (variant,
175                           SIGNOND_IDENTITY_INFO_ACL,
176                           "@a(ss)",
177                           &acl))
178     {
179         info->access_control_list =
180             signon_security_context_list_deconstruct_variant (acl);
181         g_variant_unref (acl);
182     }
183
184     g_variant_lookup (variant,
185                       SIGNOND_IDENTITY_INFO_TYPE,
186                       "u",
187                       &info->type);
188
189     return info;
190 }
191
192 GVariant *
193 signon_identity_info_to_variant (const SignonIdentityInfo *self)
194 {
195     GVariantBuilder builder;
196     GVariantBuilder method_builder;
197     GVariant *method_map;
198     GHashTableIter iter;
199     const gchar *method;
200     const gchar **mechanisms;
201
202     g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
203
204     g_variant_builder_add (&builder, "{sv}",
205                            SIGNOND_IDENTITY_INFO_ID,
206                            g_variant_new_uint32 (self->id));
207
208     g_variant_builder_add (&builder, "{sv}",
209                            SIGNOND_IDENTITY_INFO_USERNAME,
210                            signon_variant_new_string (self->username));
211
212     g_variant_builder_add (&builder, "{sv}",
213                            SIGNOND_IDENTITY_INFO_SECRET,
214                            signon_variant_new_string (self->secret));
215
216     g_variant_builder_add (&builder, "{sv}",
217                            SIGNOND_IDENTITY_INFO_CAPTION,
218                            signon_variant_new_string (self->caption));
219
220     g_variant_builder_add (&builder, "{sv}",
221                            SIGNOND_IDENTITY_INFO_STORESECRET,
222                            g_variant_new_boolean (self->store_secret));
223
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,
228                                    (gpointer)&method,
229                                    (gpointer)&mechanisms))
230     {
231         g_variant_builder_add (&method_builder, "{s^as}",
232                                method,
233                                mechanisms);
234     }
235     method_map = g_variant_builder_end (&method_builder);
236
237     g_variant_builder_add (&builder, "{sv}",
238                            SIGNOND_IDENTITY_INFO_AUTHMETHODS,
239                            method_map);
240
241     if (self->realms != NULL)
242     {
243         g_variant_builder_add (&builder, "{sv}",
244                                SIGNOND_IDENTITY_INFO_REALMS,
245                                g_variant_new_strv ((const gchar * const *)
246                                                    self->realms,
247                                                    -1));
248     }
249
250     if (self->owner != NULL)
251     {
252         g_variant_builder_add (&builder, "{sv}",
253                                SIGNOND_IDENTITY_INFO_OWNER,
254                                signon_security_context_build_variant (
255                                                                   self->owner));
256     }
257
258     if (self->access_control_list != NULL)
259     {
260         g_variant_builder_add (&builder, "{sv}",
261                                SIGNOND_IDENTITY_INFO_ACL,
262                                signon_security_context_list_build_variant (
263                                                     self->access_control_list));
264     }
265
266     g_variant_builder_add (&builder, "{sv}",
267                            SIGNOND_IDENTITY_INFO_TYPE,
268                            g_variant_new_int32 (self->type));
269
270     return g_variant_builder_end (&builder);
271 }
272
273 /*
274  * Public methods:
275  */
276
277 /**
278  * signon_identity_info_new:
279  *
280  * Creates a new #SignonIdentityInfo item.
281  *
282  * Returns: a new #SignonIdentityInfo item.
283  */
284 SignonIdentityInfo *signon_identity_info_new ()
285 {
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;
290
291     return info;
292 }
293
294 /**
295  * signon_identity_info_free:
296  * @info: the #SignonIdentityInfo.
297  *
298  * Destroys the given #SignonIdentityInfo item.
299  */
300 void signon_identity_info_free (SignonIdentityInfo *info)
301 {
302     if (info == NULL) return;
303
304     g_free (info->username);
305     g_free (info->secret);
306     g_free (info->caption);
307
308     g_hash_table_destroy (info->methods);
309
310     g_strfreev (info->realms);
311     signon_security_context_free (info->owner);
312     signon_security_context_list_free (info->access_control_list);
313
314     g_slice_free (SignonIdentityInfo, info);
315 }
316
317 /**
318  * signon_identity_info_copy:
319  * @other: the #SignonIdentityInfo.
320  *
321  * Get a newly-allocated copy of @info.
322  *
323  * Returns: a copy of the given #SignonIdentityInfo, or %NULL on failure.
324  */
325 SignonIdentityInfo *signon_identity_info_copy (const SignonIdentityInfo *other)
326 {
327     g_return_val_if_fail (other != NULL, NULL);
328     SignonIdentityInfo *info = signon_identity_info_new ();
329
330     identity_info_set_id (info, signon_identity_info_get_id (other));
331
332     signon_identity_info_set_username (info,
333         signon_identity_info_get_username (other));
334
335     signon_identity_info_set_secret (info, identity_info_get_secret(other),
336         signon_identity_info_get_storing_secret (other));
337
338     signon_identity_info_set_caption (info,
339         signon_identity_info_get_caption(other));
340
341     signon_identity_info_set_methods (info,
342         signon_identity_info_get_methods (other));
343
344     signon_identity_info_set_realms (info,
345         signon_identity_info_get_realms (other));
346
347     signon_identity_info_set_owner (info,
348         signon_identity_info_get_owner (other));
349
350     signon_identity_info_set_access_control_list (info,
351         signon_identity_info_get_access_control_list (other));
352
353     signon_identity_info_set_identity_type (info,
354         signon_identity_info_get_identity_type (other));
355
356     return info;
357 }
358
359 /**
360  * signon_identity_info_get_id:
361  * @info: the #SignonIdentityInfo.
362  *
363  * Get the numeric identity ID of @info.
364  *
365  * Returns: the numeric ID of the identity.
366  */
367 gint signon_identity_info_get_id (const SignonIdentityInfo *info)
368 {
369     g_return_val_if_fail (info != NULL, -1);
370     return info->id;
371 }
372
373 /**
374  * signon_identity_info_get_username:
375  * @info: the #SignonIdentityInfo.
376  *
377  * Get the username associated with an identity.
378  *
379  * Returns: the username, or %NULL.
380  */
381 const gchar *signon_identity_info_get_username (const SignonIdentityInfo *info)
382 {
383     g_return_val_if_fail (info != NULL, NULL);
384     return info->username;
385 }
386
387 /**
388  * signon_identity_info_get_storing_secret:
389  * @info: the #SignonIdentityInfo.
390  *
391  * Get whether the secret of @info should be stored by gSSO in the secret database.
392  *
393  * Returns: %TRUE if gSSO must store the secret, %FALSE otherwise.
394  */
395 gboolean signon_identity_info_get_storing_secret (const SignonIdentityInfo *info)
396 {
397     g_return_val_if_fail (info != NULL, FALSE);
398     return info->store_secret;
399 }
400
401 /**
402  * signon_identity_info_get_caption:
403  * @info: the #SignonIdentityInfo.
404  *
405  * Get the display name of @info.
406  *
407  * Returns: the display name for the identity.
408  */
409 const gchar *signon_identity_info_get_caption (const SignonIdentityInfo *info)
410 {
411     g_return_val_if_fail (info != NULL, NULL);
412     return info->caption;
413 }
414
415 /**
416  * signon_identity_info_get_methods:
417  * @info: the #SignonIdentityInfo.
418  *
419  * Get a hash table of the methods and mechanisms of @info. See 
420  * signon_identity_info_set_methods().
421  *
422  * Returns: (transfer none): (element-type utf8 GStrv): the table of allowed
423  * methods and mechanisms.
424  */
425 const GHashTable *signon_identity_info_get_methods (const SignonIdentityInfo *info)
426 {
427     g_return_val_if_fail (info != NULL, NULL);
428     return info->methods;
429 }
430
431 /**
432  * signon_identity_info_get_realms:
433  * @info: the #SignonIdentityInfo.
434  *
435  * Get an array of the allowed realms of @info.
436  *
437  * Returns: (transfer none): a %NULL terminated array of realms.
438  */
439 const gchar* const *signon_identity_info_get_realms (const SignonIdentityInfo *info)
440 {
441     g_return_val_if_fail (info != NULL, NULL);
442     return (const gchar* const *)info->realms;
443 }
444
445 /**
446  * signon_identity_info_get_owner:
447  * @info: the #SignonIdentityInfo.
448  *
449  * Get identity owner's security context. 
450  * 
451  * Returns: (transfer none): a security context.
452  */
453 const SignonSecurityContext *signon_identity_info_get_owner (const SignonIdentityInfo *info)
454 {
455     g_return_val_if_fail (info != NULL, NULL);
456     return info->owner;
457 }
458
459 /**
460  * signon_identity_info_get_access_control_list:
461  * @info: the #SignonIdentityInfo.
462  *
463  * Get an access control list associated with an identity. 
464  *
465  * Returns: (transfer none): a list of ACL security contexts.
466  */
467 const SignonSecurityContextList *signon_identity_info_get_access_control_list (const SignonIdentityInfo *info)
468 {
469     g_return_val_if_fail (info != NULL, NULL);
470     return info->access_control_list;
471 }
472
473 /**
474  * signon_identity_info_get_identity_type:
475  * @info: the #SignonIdentityInfo.
476  *
477  * Get the type of the identity.
478  *
479  * Returns: the type of the identity.
480  */
481 SignonIdentityType signon_identity_info_get_identity_type (const SignonIdentityInfo *info)
482 {
483     g_return_val_if_fail (info != NULL, -1);
484     return (SignonIdentityType)info->type;
485 }
486
487 /**
488  * signon_identity_info_set_username:
489  * @info: the #SignonIdentityInfo.
490  * @username: the username.
491  *
492  * Sets the username for the identity.
493  *
494  */
495 void signon_identity_info_set_username (SignonIdentityInfo *info, const gchar *username)
496 {
497     g_return_if_fail (info != NULL);
498
499     if (info->username) g_free (info->username);
500
501     info->username = g_strdup (username);
502 }
503
504 /**
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.
509  *
510  * Sets the secret (password) for the identity, and whether the gSSO daemon
511  * should remember it.
512  *
513  */
514 void signon_identity_info_set_secret (SignonIdentityInfo *info, const gchar *secret,
515                                       gboolean store_secret)
516 {
517     g_return_if_fail (info != NULL);
518
519     if (info->secret) g_free (info->secret);
520
521     info->secret = g_strdup (secret);
522     info->store_secret = store_secret;
523 }
524
525 /**
526  * signon_identity_info_set_caption:
527  * @info: the #SignonIdentityInfo.
528  * @caption: the caption.
529  *
530  * Sets the caption (display name) for the identity.
531  *
532  */
533 void signon_identity_info_set_caption (SignonIdentityInfo *info, const gchar *caption)
534 {
535     g_return_if_fail (info != NULL);
536
537     if (info->caption) g_free (info->caption);
538
539     info->caption = g_strdup (caption);
540 }
541
542 /**
543  * signon_identity_info_set_method:
544  * @info: the #SignonIdentityInfo.
545  * @method: an authentication method.
546  * @mechanisms: a %NULL-terminated list of mechanisms.
547  *
548  * Adds a method to the list of allowed authentication methods. 
549  */
550 void signon_identity_info_set_method (SignonIdentityInfo *info, const gchar *method,
551                                       const gchar* const *mechanisms)
552 {
553     g_return_if_fail (info != NULL);
554
555     g_return_if_fail (info->methods != NULL);
556     g_return_if_fail (method != NULL);
557     g_return_if_fail (mechanisms != NULL);
558
559     g_hash_table_replace (info->methods,
560                           g_strdup(method), g_strdupv((gchar **)mechanisms));
561 }
562
563 /**
564  * signon_identity_info_remove_method:
565  * @info: the #SignonIdentityInfo.
566  * @method: an authentication method.
567  *
568  * Remove @method from the list of allowed authentication methods.
569  */
570 void signon_identity_info_remove_method (SignonIdentityInfo *info, const gchar *method)
571 {
572     g_return_if_fail (info != NULL);
573     g_return_if_fail (info->methods != NULL);
574
575     g_hash_table_remove (info->methods, method);
576 }
577
578 /**
579  * signon_identity_info_set_realms:
580  * @info: the #SignonIdentityInfo.
581  * @realms: a %NULL-terminated list of realms.
582  *
583  * Specify what realms this identity can be used in. 
584  */
585 void signon_identity_info_set_realms (SignonIdentityInfo *info,
586                                       const gchar* const *realms)
587 {
588     g_return_if_fail (info != NULL);
589
590     if (info->realms) g_strfreev (info->realms);
591
592     info->realms = g_strdupv ((gchar **)realms);
593 }
594
595 /**
596  * signon_identity_info_set_owner:
597  * @info: the #SignonIdentityInfo.
598  * @owner: (transfer none): a security context of owner.
599  *
600  * Set identity owner's security context. 
601  */
602 void signon_identity_info_set_owner (SignonIdentityInfo *info,
603                                      const SignonSecurityContext *owner)
604 {
605     g_return_if_fail (info != NULL);
606
607     if (info->owner) signon_security_context_free (info->owner);
608
609     info->owner = signon_security_context_copy (owner);
610 }
611
612 /**
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.
617  *
618  * Set identity owner's security context. 
619  */
620 void signon_identity_info_set_owner_from_values (
621                                                SignonIdentityInfo *info,
622                                                const gchar *system_context,
623                                                const gchar *application_context)
624 {
625     g_return_if_fail (info != NULL &&
626                       system_context != NULL &&
627                       application_context != NULL);
628
629     if (info->owner) signon_security_context_free (info->owner);
630
631     info->owner = signon_security_context_new_from_values(system_context,
632                                                           application_context);
633 }
634
635 /**
636  * signon_identity_info_set_access_control_list:
637  * @info: the #SignonIdentityInfo.
638  * @access_control_list: (transfer none): a list of ACL security contexts.
639  *
640  * Set an access control list associated with an identity. 
641  */
642 void signon_identity_info_set_access_control_list (SignonIdentityInfo *info,
643                            const SignonSecurityContextList *access_control_list)
644 {
645     g_return_if_fail (info != NULL);
646
647     if (info->access_control_list)
648         signon_security_context_list_free (info->access_control_list);
649
650     info->access_control_list =
651         signon_security_context_list_copy (access_control_list);
652 }
653
654 /**
655  * signon_identity_info_access_control_list_append:
656  * @info: the #SignonIdentityInfo.
657  * @security_context: (transfer full): a security context to be appended.
658  *
659  * Appends a new #SignonSecurityContext item to the access control list.
660  */
661 void signon_identity_info_access_control_list_append (
662                                         SignonIdentityInfo *info,
663                                         SignonSecurityContext *security_context)
664 {
665     g_return_if_fail (info != NULL);
666     g_return_if_fail (security_context != NULL);
667
668     info->access_control_list = g_list_append (info->access_control_list,
669                                                security_context);
670 }
671
672 /**
673  * signon_identity_info_set_identity_type:
674  * @info: the #SignonIdentityInfo.
675  * @type: the type of the identity.
676  *
677  * Specifies the type of this identity.
678  */
679 void signon_identity_info_set_identity_type (SignonIdentityInfo *info,
680                                              SignonIdentityType type)
681 {
682     g_return_if_fail (info != NULL);
683     info->type = (gint)type;
684 }