common: make gsignond-identity-info.h private, as it's not used by anything in the...
[platform/upstream/gsignond.git] / src / common / gsignond-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 gsignond
5  *
6  * Copyright (C) 2012-2013 Intel Corporation.
7  *
8  * Contact: Imran Zaman <imran.zaman@linux.intel.com>
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License as published by the Free Software Foundation; either
13  * version 2.1 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful, but
16  * WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with this library; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23  * 02110-1301 USA
24  */
25
26 #include "gsignond-identity-info.h"
27 #include "gsignond-identity-info-internal.h"
28
29
30 static gboolean
31 _gsignond_identity_info_seq_cmp (
32         GSequence *one,
33         GSequence *two)
34 {
35     GSequenceIter *iter1 = NULL, *iter2 = NULL;
36     gboolean equal = TRUE;
37
38    if (one == two)
39         return TRUE;
40
41    if (one == NULL) {
42         if (g_sequence_get_length (two) == 0)
43             return TRUE;
44         else
45             return FALSE;
46    }
47
48    if (two == NULL) {
49         if (g_sequence_get_length (one) == 0)
50             return TRUE;
51         else
52             return FALSE;
53     }
54
55     if (g_sequence_get_length (one) != g_sequence_get_length (two))
56         return FALSE;
57
58     iter1 = g_sequence_get_begin_iter (one);
59     while (!g_sequence_iter_is_end (iter1)) {
60         iter2 = g_sequence_get_iter_at_pos (two,
61                     g_sequence_iter_get_position (iter1));
62         if (g_strcmp0 (g_sequence_get (iter1), g_sequence_get (iter2)) != 0) {
63             equal = FALSE;
64             break;
65         }
66         iter1 = g_sequence_iter_next (iter1);
67     }
68
69     return equal;
70 }
71
72 static gint
73 _compare_strings (
74                 const gchar* a,
75                 const gchar* b,
76                 gpointer data)
77 {
78         (void)data;
79         return g_strcmp0 (a,b);
80 }
81
82 static GVariant *
83 _gsignond_identity_info_sequence_to_variant (GSequence *seq)
84
85 {
86     GSequenceIter * iter = NULL;
87     GVariant *var = NULL;
88     GVariantBuilder builder;
89
90     if (!seq) return NULL;
91
92     g_variant_builder_init (&builder, G_VARIANT_TYPE_STRING_ARRAY);
93     iter = g_sequence_get_begin_iter (seq);
94     while (!g_sequence_iter_is_end (iter)) {
95         const gchar * d = g_sequence_get (iter);
96         g_variant_builder_add (&builder, "s", d);
97         iter = g_sequence_iter_next (iter);
98     }
99     var = g_variant_builder_end (&builder);
100     return var;
101 }
102
103 static GSequence *
104 _gsignond_identity_info_variant_to_sequence (GVariant *var)
105
106 {
107     GVariantIter iter;
108     GSequence *seq = NULL;
109     gchar *item = NULL;
110
111     if (!var) return NULL;
112
113     seq = g_sequence_new ((GDestroyNotify)g_free);
114     g_variant_iter_init (&iter, var);
115     while (g_variant_iter_next (&iter, "s", &item)) {
116         g_sequence_insert_sorted (seq,
117                                   item,
118                                   (GCompareDataFunc) _compare_strings,
119                                   NULL);
120     }
121     return seq;
122 }
123
124 static gchar **
125 _gsignond_identity_info_sequence_to_array (GSequence *seq)
126 {
127     gchar **items, **temp;
128     GSequenceIter *iter;
129
130     if (!seq) return NULL;
131
132     items = g_malloc0 ((g_sequence_get_length (seq) + 1) * sizeof (gchar *));
133     temp = items;
134     for (iter = g_sequence_get_begin_iter (seq);
135          iter != g_sequence_get_end_iter (seq);
136          iter = g_sequence_iter_next (iter)) {
137         *temp = g_sequence_get (iter);
138         temp++;
139     }
140     return items;
141 }
142
143 static GSequence *
144 _gsignond_identity_info_array_to_sequence (gchar **items)
145
146 {
147     GSequence *seq = NULL;
148
149     if (!items) return NULL;
150
151     seq = g_sequence_new ((GDestroyNotify) g_free);
152     while (*items) {
153         g_sequence_insert_sorted (seq,
154                                   *items,
155                                   (GCompareDataFunc) _compare_strings,
156                                   NULL);
157         items++;
158     }
159     return seq;
160 }
161
162 static gboolean
163 _gsignond_identity_info_sec_context_list_cmp (
164         GSignondSecurityContextList *one,
165         GSignondSecurityContextList *two)
166 {
167     GSignondSecurityContextList *list_elem1 = NULL, *list_elem2 = NULL;
168     gboolean equal = TRUE;
169
170     if (one == NULL && two == NULL)
171         return TRUE;
172
173     if ((one != NULL && two == NULL) ||
174         (one == NULL && two != NULL) ||
175         (g_list_length (one) != g_list_length (two)))
176         return FALSE;
177
178     if (one == two)
179         return TRUE;
180
181     list_elem1 = one;
182     for ( ; list_elem1 != NULL; list_elem1 = g_list_next (list_elem1)) {
183         list_elem2 = g_list_nth (two, g_list_position (one, list_elem1));
184         if (!gsignond_security_context_match (
185                 (GSignondSecurityContext *)list_elem1->data,
186                 (GSignondSecurityContext *)list_elem2->data)) {
187             equal = FALSE;
188             break;
189         }
190     }
191
192     return equal;
193 }
194
195 static gboolean
196 _gsignond_identity_info_methods_cmp (
197         GHashTable *one,
198         GHashTable *two)
199 {
200     GHashTableIter iter1;
201     GSequence *mechs1 = NULL, *mechs2 = NULL;
202     gchar *key = NULL;
203     gboolean equal = TRUE;
204
205     if (one == NULL && two == NULL)
206         return TRUE;
207
208     if ((one != NULL && two == NULL) ||
209         (one == NULL && two != NULL) ||
210         (g_hash_table_size (one) != g_hash_table_size (two)))
211         return FALSE;
212
213     if (one == two)
214         return TRUE;
215
216     g_hash_table_iter_init(&iter1, one);
217     while (g_hash_table_iter_next (&iter1, (gpointer *)&key,
218             (gpointer *)&mechs1)) {
219         mechs2 = (GSequence *)g_hash_table_lookup (two, key);
220         equal = _gsignond_identity_info_seq_cmp (mechs1, mechs2);
221         if (!equal) {
222             break;
223         }
224     }
225
226     return equal;
227 }
228
229 /**
230  * gsignond_identity_info_new:
231  *
232  * Creates new instance of GSignondIdentityInfo.
233  *
234  * Returns: (transfer full): #GSignondIdentityInfo object if successful,
235  * NULL otherwise.
236  */
237 GSignondIdentityInfo *
238 gsignond_identity_info_new (void)
239 {
240     GSignondIdentityInfo *info;
241
242     info = gsignond_dictionary_new ();
243     gsignond_identity_info_set_id (info, GSIGNOND_IDENTITY_INFO_NEW_IDENTITY);
244
245     return info;
246 }
247
248 /**
249  * gsignond_identity_info_copy:
250  * @info: instance of #GSignondIdentityInfo
251  *
252  * Creates a copy of info structure.
253  *
254  * Returns: copy of the info.
255  */
256 GSignondIdentityInfo *
257 gsignond_identity_info_copy (GSignondIdentityInfo *info)
258 {
259     if (!info)
260         return NULL;
261
262     return gsignond_dictionary_copy (info);
263 }
264
265 /**
266  * gsignond_identity_info_ref:
267  * @info: instance of #GSignondIdentityInfo
268  *
269  * Increment reference count of the info structure.
270  */
271 void
272 gsignond_identity_info_ref (GSignondIdentityInfo *info)
273 {
274     g_return_if_fail (info != NULL);
275
276     gsignond_dictionary_ref (info);
277 }
278
279 /**
280  * gsignond_identity_info_unref:
281  * @info: instance of #GSignondIdentityInfo
282  *
283  * Decrement reference count of the info structure.
284  */
285 void
286 gsignond_identity_info_unref (GSignondIdentityInfo *info)
287 {
288     if (!info)
289         return;
290
291     gsignond_dictionary_unref (info);
292 }
293
294 /**
295  * gsignond_identity_info_get_id:
296  * @info: instance of #GSignondIdentityInfo
297  *
298  * Retrieves the id from the info.
299  *
300  * Returns: the id; negative id is returned in case of failure.
301  */
302 guint32
303 gsignond_identity_info_get_id (GSignondIdentityInfo *info)
304 {
305     g_assert (info != NULL);
306
307     GVariant *var = NULL;
308     var = gsignond_dictionary_get (info, GSIGNOND_IDENTITY_INFO_ID);
309
310     g_return_val_if_fail (var != NULL, -1);
311
312     return g_variant_get_uint32 (var);
313 }
314
315 /**
316  * gsignond_identity_info_set_id:
317  * @info: instance of #GSignondIdentityInfo
318  *
319  * @id: id to be set
320  *
321  * Sets the id of the info.
322  *
323  * Returns: TRUE if successful, FALSE otherwise.
324  */
325 gboolean
326 gsignond_identity_info_set_id (
327         GSignondIdentityInfo *info,
328         guint32 id)
329 {
330     g_assert (info != NULL);
331
332     return gsignond_dictionary_set (
333             info,
334             GSIGNOND_IDENTITY_INFO_ID,
335             g_variant_new_uint32 (id));
336 }
337
338 /**
339  * gsignond_identity_info_get_is_identity_new:
340  * @info: instance of #GSignondIdentityInfo
341  *
342  * Retrieves the info whether the identity is new or not.
343  *
344  * Returns: TRUE if new, FALSE otherwise.
345  */
346 gboolean
347 gsignond_identity_info_get_is_identity_new (GSignondIdentityInfo *info)
348 {
349     g_assert (info != NULL);
350
351     return GSIGNOND_IDENTITY_INFO_NEW_IDENTITY ==
352             gsignond_identity_info_get_id (info);
353 }
354
355 /**
356  * gsignond_identity_info_set_identity_new:
357  * @info: instance of #GSignondIdentityInfo
358  *
359  * Sets the id of the identity info to be new.
360  *
361  * Returns: TRUE if successful, FALSE otherwise.
362  */
363 gboolean
364 gsignond_identity_info_set_identity_new (
365         GSignondIdentityInfo *info)
366 {
367     g_assert (info != NULL);
368     
369     return gsignond_identity_info_set_id (
370             info,
371             GSIGNOND_IDENTITY_INFO_NEW_IDENTITY);
372 }
373
374 /**
375  * gsignond_identity_info_get_username:
376  * @info: instance of #GSignondIdentityInfo
377  *
378  * Retrieves the username from the info.
379  *
380  * Returns: the username if successful, NULL otherwise.
381  */
382 const gchar *
383 gsignond_identity_info_get_username (GSignondIdentityInfo *info)
384 {
385     g_assert (info != NULL);
386     
387     GVariant *var = NULL;
388     var = gsignond_dictionary_get (info, GSIGNOND_IDENTITY_INFO_USERNAME);
389     if (var != NULL) {
390         return g_variant_get_string (var, NULL);
391     }
392     return NULL;
393 }
394
395 /**
396  * gsignond_identity_info_set_username:
397  * @info: instance of #GSignondIdentityInfo
398  *
399  * @username: username to be set
400  *
401  * Sets the username of the info.
402  *
403  * Returns: TRUE if successful, FALSE otherwise.
404  */
405 gboolean
406 gsignond_identity_info_set_username (
407         GSignondIdentityInfo *info,
408         const gchar *username)
409 {
410     g_assert (info != NULL);
411
412     if (!username) {
413         return gsignond_dictionary_remove (info,
414                             GSIGNOND_IDENTITY_INFO_USERNAME);
415     }
416     return gsignond_dictionary_set (
417                     info,
418                     GSIGNOND_IDENTITY_INFO_USERNAME,
419                     g_variant_new_string (username));
420 }
421
422 /**
423  * gsignond_identity_info_remove_username:
424  * @info: instance of #GSignondIdentityInfo
425  *
426  * Removes username from the info.
427  */
428 void
429 gsignond_identity_info_remove_username (GSignondIdentityInfo *info)
430 {
431     g_assert (info != NULL);
432     
433     gsignond_dictionary_remove (info, GSIGNOND_IDENTITY_INFO_USERNAME);
434 }
435
436 /**
437  * gsignond_identity_info_get_is_username_secret:
438  * @info: instance of #GSignondIdentityInfo
439  *
440  * Retrieves the is_username_secret flag from the info.
441  *
442  * Returns: the is_username_secret flag.
443  */
444 gboolean
445 gsignond_identity_info_get_is_username_secret (GSignondIdentityInfo *info)
446 {
447     g_assert (info != NULL);
448
449     GVariant *var = NULL;
450     var = gsignond_dictionary_get (info,
451             GSIGNOND_IDENTITY_INFO_USERNAME_IS_SECRET);
452     if (var != NULL) {
453         return g_variant_get_boolean (var);
454     }
455     return FALSE;
456 }
457
458 /**
459  * gsignond_identity_info_set_username_secret:
460  * @info: instance of #GSignondIdentityInfo
461  *
462  * @store_secret: store_secret to be set
463  *
464  * Sets the store_secret of the info.
465  *
466  * Returns: TRUE if successful, FALSE otherwise.
467  */
468 gboolean
469 gsignond_identity_info_set_username_secret (
470         GSignondIdentityInfo *info,
471         gboolean username_secret)
472 {
473     g_assert (info != NULL);
474
475     return gsignond_dictionary_set (
476             info,
477             GSIGNOND_IDENTITY_INFO_USERNAME_IS_SECRET,
478             g_variant_new_boolean(username_secret));
479 }
480
481 /**
482  * gsignond_identity_info_get_secret:
483  * @info: instance of #GSignondIdentityInfo
484  *
485  * Retrieves the secret from the info.
486  *
487  * Returns: the secret if successful, NULL otherwise.
488  */
489 const gchar *
490 gsignond_identity_info_get_secret (GSignondIdentityInfo *info)
491 {
492     g_assert (info != NULL);
493
494     GVariant *var = NULL;
495     var = gsignond_dictionary_get (info, GSIGNOND_IDENTITY_INFO_SECRET);
496     if (var != NULL) {
497         return g_variant_get_string (var, NULL);
498     }
499     return NULL;
500 }
501
502 /**
503  * gsignond_identity_info_set_secret:
504  * @info: instance of #GSignondIdentityInfo
505  *
506  * @secret: secret to be set
507  *
508  * Sets the secret of the info.
509  *
510  * Returns: TRUE if successful, FALSE otherwise.
511  */
512 gboolean
513 gsignond_identity_info_set_secret (
514         GSignondIdentityInfo *info,
515         const gchar *secret)
516 {
517     g_assert (info != NULL);
518
519     if (!secret) {
520         return gsignond_dictionary_remove (info,
521                 GSIGNOND_IDENTITY_INFO_SECRET);
522     }
523     return gsignond_dictionary_set (
524             info,
525             GSIGNOND_IDENTITY_INFO_SECRET,
526             g_variant_new_string (secret));
527 }
528
529 /**
530  * gsignond_identity_info_remove_secret:
531  * @info: instance of #GSignondIdentityInfo
532  *
533  * Removes secret from the info.
534  */
535 void
536 gsignond_identity_info_remove_secret (GSignondIdentityInfo *info)
537 {
538     g_assert (info != NULL);
539
540     gsignond_dictionary_remove (info, GSIGNOND_IDENTITY_INFO_SECRET);
541 }
542
543 /**
544  * gsignond_identity_info_get_store_secret:
545  * @info: instance of #GSignondIdentityInfo
546  *
547  * Retrieves the store_secret flag from the info.
548  *
549  * Returns: the store_secret flag.
550  */
551 gboolean
552 gsignond_identity_info_get_store_secret (GSignondIdentityInfo *info)
553 {
554     g_assert (info != NULL);
555
556     GVariant *var = NULL;
557     var = gsignond_dictionary_get (info, GSIGNOND_IDENTITY_INFO_STORESECRET);
558     if (var != NULL) {
559         return g_variant_get_boolean (var);
560     }
561     return FALSE;
562 }
563
564 /**
565  * gsignond_identity_info_set_store_secret:
566  * @info: instance of #GSignondIdentityInfo
567  *
568  * @store_secret: store_secret to be set
569  *
570  * Sets the store_secret of the info.
571  *
572  * Returns: TRUE if successful, FALSE otherwise.
573  */
574 gboolean
575 gsignond_identity_info_set_store_secret (
576         GSignondIdentityInfo *info,
577         gboolean store_secret)
578 {
579     g_assert (info != NULL);
580
581     return gsignond_dictionary_set (
582             info,
583             GSIGNOND_IDENTITY_INFO_STORESECRET,
584             g_variant_new_boolean(store_secret));
585 }
586
587 /**
588  * gsignond_identity_info_get_caption:
589  * @info: instance of #GSignondIdentityInfo
590  *
591  * Retrieves the caption from the info.
592  *
593  * Returns: the caption if successful, NULL otherwise.
594  */
595 const gchar *
596 gsignond_identity_info_get_caption (GSignondIdentityInfo *info)
597 {
598     g_assert (info != NULL);
599
600     GVariant *var = NULL;
601     var = gsignond_dictionary_get (info, GSIGNOND_IDENTITY_INFO_CAPTION);
602     if (var != NULL) {
603         return g_variant_get_string (var, NULL);
604     }
605     return NULL;
606 }
607
608 /**
609  * gsignond_identity_info_set_caption:
610  * @info: instance of #GSignondIdentityInfo
611  *
612  * @caption: caption to be set
613  *
614  * Sets the caption of the info.
615  *
616  * Returns: TRUE in case of success, FALSE otherwise.
617  */
618 gboolean
619 gsignond_identity_info_set_caption (
620         GSignondIdentityInfo *info,
621         const gchar *caption)
622 {
623     g_assert (info != NULL);
624
625     if (!caption) {
626         return gsignond_dictionary_remove (info,
627                 GSIGNOND_IDENTITY_INFO_CAPTION);
628     }
629     return gsignond_dictionary_set (
630             info,
631             GSIGNOND_IDENTITY_INFO_CAPTION,
632             g_variant_new_string (caption));
633 }
634
635 /**
636  * gsignond_identity_info_get_realms:
637  * @info: instance of #GSignondIdentityInfo
638  *
639  * Retrieves the realms from the info.
640  *
641  * Returns: (transfer full): the realms if successful, NULL Otherwise.
642  * when done realms should be freed using g_sequence_free.
643  */
644 GSequence *
645 gsignond_identity_info_get_realms (GSignondIdentityInfo *info)
646 {
647     g_assert (info != NULL);
648
649     GVariant *var = NULL;
650     var = gsignond_dictionary_get (info, GSIGNOND_IDENTITY_INFO_REALMS);
651     if (var != NULL) {
652         return _gsignond_identity_info_variant_to_sequence (var);
653     }
654     return NULL;
655 }
656
657 /**
658  * gsignond_identity_info_set_realms:
659  * @info: instance of #GSignondIdentityInfo
660  *
661  * @realms: (transfer none): realms to be set
662  *
663  * Sets the realms of the info.
664  *
665  * Returns: TRUE if successful, FALSE otherwise.
666  */
667 gboolean
668 gsignond_identity_info_set_realms (
669         GSignondIdentityInfo *info,
670         GSequence *realms)
671 {
672     g_assert (info != NULL);
673
674     g_return_val_if_fail (realms != NULL, FALSE);
675     return gsignond_dictionary_set (
676             info,
677             GSIGNOND_IDENTITY_INFO_REALMS,
678             _gsignond_identity_info_sequence_to_variant (realms));
679 }
680
681 /**
682  * gsignond_identity_info_get_methods:
683  * @info: instance of #GSignondIdentityInfo
684  *
685  * Retrieves the methods from the info whereas #GHashTable consists of
686  * (gchar*,GSequence*) and #GSequence is a sequence of gchar *.
687  *
688  * Returns: (transfer full): the methods if successful, NULL otherwise.
689  * when done, methods should be freed using g_hash_table_unref.
690  */
691 GHashTable *
692 gsignond_identity_info_get_methods (GSignondIdentityInfo *info)
693 {
694     g_assert (info != NULL);
695
696     GVariant *var = NULL;
697     GHashTable *methods = NULL;
698     var = gsignond_dictionary_get (info, GSIGNOND_IDENTITY_INFO_AUTHMETHODS);
699     if (var != NULL) {
700         GVariantIter iter;
701         gchar *vmethod;
702         gchar **vmechanisms = NULL;
703         GSequence *seq = NULL;
704
705         methods = g_hash_table_new_full ((GHashFunc) g_str_hash,
706                                          (GEqualFunc) g_str_equal,
707                                          (GDestroyNotify) g_free,
708                                          (GDestroyNotify) g_sequence_free);
709
710         g_variant_iter_init (&iter, var);
711         while (g_variant_iter_next (&iter, "{s^as}", &vmethod, &vmechanisms))
712         {
713             /* ownership of all content is transferred */
714             seq = _gsignond_identity_info_array_to_sequence (vmechanisms);
715             g_hash_table_insert (methods, vmethod, seq);
716             g_free (vmechanisms);
717         }
718     }
719     return methods;
720 }
721
722 /**
723  * gsignond_identity_info_set_methods:
724  * @info: instance of #GSignondIdentityInfo
725  *
726  * @methods: (transfer none): methods to be set whereas #GHashTable consists of
727  * (gchar*,#GSequence*) and #GSequence is a sequence of gchar *.
728  *
729  * Sets the methods of the info.
730  *
731  * Returns: TRUE if successful, FALSE otherwise.
732  */
733 gboolean
734 gsignond_identity_info_set_methods (
735         GSignondIdentityInfo *info,
736         GHashTable *methods)
737 {
738     g_assert (info != NULL);
739
740     gchar **items = NULL;
741     GVariantBuilder builder;
742
743     GHashTableIter iter;
744     const gchar *method;
745     GSequence *mechanisms = NULL;
746
747     g_return_val_if_fail (info != NULL, FALSE);
748     g_return_val_if_fail (methods != NULL, FALSE);
749
750     g_variant_builder_init (&builder, (const GVariantType *)"a{sas}");
751     g_hash_table_iter_init (&iter, methods);
752     while (g_hash_table_iter_next (&iter,
753                                    (gpointer)&method,
754                                    (gpointer)&mechanisms))
755     {
756         items = _gsignond_identity_info_sequence_to_array (mechanisms);
757         g_variant_builder_add (&builder, "{s^as}", method, items);
758         g_free (items);
759     }
760     return gsignond_dictionary_set (
761             info,
762             GSIGNOND_IDENTITY_INFO_AUTHMETHODS,
763             g_variant_builder_end (&builder));
764 }
765
766 /**
767  * gsignond_identity_info_get_mechanisms:
768  * @info: instance of #GSignondIdentityInfo
769  *
770  * @method: the method for which mechanisms are sought
771  *
772  * Retrieves the mechanisms from the info.
773  *
774  * Returns: (transfer full): the mechanisms if successful, NULL otherwise.
775  * when done, mechanisms should be freed using g_sequence_free; #GSequence is a
776  * sequence of gchar *.
777  */
778 GSequence *
779 gsignond_identity_info_get_mechanisms (
780         GSignondIdentityInfo *info,
781         const gchar *method)
782 {
783     g_assert (info != NULL);
784
785     GVariant *var = NULL;
786     GSequence *mechanisms = NULL;
787
788     g_return_val_if_fail (method != NULL, NULL);
789
790     var = gsignond_dictionary_get (info, GSIGNOND_IDENTITY_INFO_AUTHMETHODS);
791     if (var != NULL) {
792         GVariantIter iter;
793         gchar *vmethod;
794         gchar **vmechanisms;
795
796         g_variant_iter_init (&iter, var);
797         while (g_variant_iter_next (&iter, "{s^as}", &vmethod, &vmechanisms))
798         {
799             /* ownership of content is transferred */
800             if (vmethod != NULL && g_strcmp0 (vmethod, method) == 0) {
801                 mechanisms = _gsignond_identity_info_array_to_sequence (
802                                  vmechanisms);
803                 g_free (vmethod);
804                 g_free (vmechanisms);
805                 break;
806             }
807             g_free (vmethod); vmethod = NULL;
808             g_strfreev (vmechanisms); vmechanisms = NULL;
809         }
810     }
811     return mechanisms;
812 }
813
814 /**
815  * gsignond_identity_info_remove_method:
816  * @info: instance of #GSignondIdentityInfo
817  *
818  * Removes the method from the info.
819  *
820  * Returns: TRUE if successful, FALSE otherwise.
821  */
822 gboolean
823 gsignond_identity_info_remove_method (
824         GSignondIdentityInfo *info,
825         const gchar *method)
826 {
827     g_assert (info != NULL);
828
829     GHashTable *methods = NULL;
830     gboolean ret = FALSE;
831
832     g_return_val_if_fail (method != NULL, FALSE);
833
834     methods = gsignond_identity_info_get_methods (info);
835     if (methods && g_hash_table_remove (methods, method)) {
836         ret = gsignond_identity_info_set_methods (info, methods);
837     }
838     if (methods)
839         g_hash_table_unref (methods);
840     return ret;
841 }
842
843 /**
844  * gsignond_identity_info_get_access_control_list:
845  * @info: instance of #GSignondIdentityInfo
846  *
847  * Retrieves the access control list from the info.
848  *
849  * Returns: (transfer full): the list if successful, NULL otherwise.
850  * when done, list should be freed using gsignond_security_context_list_free.
851  */
852 GSignondSecurityContextList *
853 gsignond_identity_info_get_access_control_list (GSignondIdentityInfo *info)
854 {
855     g_assert (info != NULL);
856
857     GVariant *var = NULL;
858     var = gsignond_dictionary_get (info, GSIGNOND_IDENTITY_INFO_ACL);
859     if (var != NULL) {
860         return gsignond_security_context_list_from_variant (var);
861     }
862     return NULL;
863 }
864
865 /**
866  * gsignond_identity_info_set_access_control_list:
867  * @info: instance of #GSignondIdentityInfo
868  *
869  * @acl: (transfer none): access control list to be set
870  *
871  * Sets the access control list of the info.
872  *
873  * Returns: TRUE if successful, FALSE otherwise.
874  */
875 gboolean
876 gsignond_identity_info_set_access_control_list (
877         GSignondIdentityInfo *info,
878         const GSignondSecurityContextList *acl)
879 {
880     g_assert (info != NULL);
881
882     g_return_val_if_fail (acl != NULL, FALSE);
883     return gsignond_dictionary_set (
884             info,
885             GSIGNOND_IDENTITY_INFO_ACL,
886             gsignond_security_context_list_to_variant (acl));
887 }
888
889 /**
890  * gsignond_identity_info_get_owner:
891  * @info: instance of #GSignondIdentityInfo
892  *
893  * Retrieves the id from the info.
894  *
895  * Returns: (transfer full): the owner if successful, NULL otherwise.
896  * when done, owner list should be freed using
897  * gsignond_security_context_free.
898  */
899 GSignondSecurityContext *
900 gsignond_identity_info_get_owner (GSignondIdentityInfo *info)
901 {
902     g_assert (info != NULL);
903
904     GVariant *var = NULL;
905     var = gsignond_dictionary_get (info, GSIGNOND_IDENTITY_INFO_OWNER);
906     if (var != NULL) {
907         return gsignond_security_context_from_variant (var);
908     }
909     return NULL;
910 }
911
912 /**
913  * gsignond_identity_info_set_owner:
914  * @info: instance of #GSignondIdentityInfo
915  *
916  * @owners: (transfer none): owner to be set
917  *
918  * Sets the owner of the info.
919  *
920  * Returns: TRUE if successful, FALSE otherwise.
921  */
922 gboolean
923 gsignond_identity_info_set_owner (
924         GSignondIdentityInfo *info,
925         const GSignondSecurityContext *owners)
926 {
927     g_assert (info != NULL);
928
929     g_return_val_if_fail (owners != NULL, FALSE);
930     return gsignond_dictionary_set (
931             info,
932             GSIGNOND_IDENTITY_INFO_OWNER,
933             gsignond_security_context_to_variant (owners));
934 }
935
936 /**
937  * gsignond_identity_info_get_validated:
938  * @info: instance of #GSignondIdentityInfo
939  *
940  * Retrieves the validated flag from the info.
941  *
942  * Returns: the validated flag.
943  */
944 gboolean
945 gsignond_identity_info_get_validated (GSignondIdentityInfo *info)
946 {
947     g_assert (info != NULL);
948
949     GVariant *var = NULL;
950     var = gsignond_dictionary_get (info, GSIGNOND_IDENTITY_INFO_VALIDATED);
951     if (var != NULL) {
952         return g_variant_get_boolean (var);
953     }
954     return FALSE;
955 }
956
957 /**
958  * gsignond_identity_info_set_validated:
959  * @info: instance of #GSignondIdentityInfo
960  *
961  * @validated: validated flag to be set
962  *
963  * Sets the validated flag of the info.
964  *
965  * Returns: TRUE if successful, FALSE otherwise.
966  */
967 gboolean
968 gsignond_identity_info_set_validated (
969         GSignondIdentityInfo *info,
970         gboolean validated)
971 {
972     g_assert (info != NULL);
973
974     return gsignond_dictionary_set (
975             info,
976             GSIGNOND_IDENTITY_INFO_VALIDATED,
977             g_variant_new_boolean (validated));
978 }
979
980 /**
981  * gsignond_identity_info_get_identity_type:
982  * @info: instance of #GSignondIdentityInfo
983  *
984  * Retrieves the type from the info.
985  *
986  * Returns: the type; negative type is returned in case of failure.
987  */
988 guint32
989 gsignond_identity_info_get_identity_type (GSignondIdentityInfo *info)
990 {
991     g_assert (info != NULL);
992
993     GVariant *var = NULL;
994     var = gsignond_dictionary_get (info, GSIGNOND_IDENTITY_INFO_TYPE);
995     if (var != NULL) {
996         return g_variant_get_int32 (var);
997     }
998     return -1;
999 }
1000
1001 /**
1002  * gsignond_identity_info_set_identity_type:
1003  * @info: instance of #GSignondIdentityInfo
1004  *
1005  * @type: type to be set
1006  *
1007  * Sets the type of the info.
1008  *
1009  * Returns: TRUE if successful, FALSE otherwise.
1010  */
1011 gboolean
1012 gsignond_identity_info_set_identity_type (
1013         GSignondIdentityInfo *info,
1014         guint32 type)
1015 {
1016     g_assert (info != NULL);
1017
1018     return gsignond_dictionary_set (
1019             info,
1020             GSIGNOND_IDENTITY_INFO_TYPE,
1021             g_variant_new_int32 (type));
1022 }
1023
1024 /**
1025  * gsignond_identity_info_compare:
1026  * @info: instance1 of #GSignondIdentityInfo
1027  *
1028  * @other: instance2 of #GSignondIdentityInfo
1029  *
1030  * Compares two instances of #GSignondIdentityInfo for equality.
1031  *
1032  * Returns: TRUE if the two instances are equal, FALSE otherwise.
1033  */
1034 gboolean
1035 gsignond_identity_info_compare (
1036         GSignondIdentityInfo *info,
1037         GSignondIdentityInfo *other)
1038 {
1039     g_assert (info != NULL && other != NULL);
1040
1041     GSequence *info_realms = NULL, *other_realms = NULL;
1042     GHashTable *info_methods = NULL, *other_methods = NULL;
1043     GSignondSecurityContextList *info_acl = NULL, *other_acl = NULL;
1044     GSignondSecurityContext *info_owner = NULL, *other_owner = NULL;
1045     gboolean equal = FALSE;
1046
1047     if (info == other)
1048         return TRUE;
1049
1050     if (info == NULL || other == NULL)
1051         return FALSE;
1052
1053     if (gsignond_identity_info_get_id (info) !=
1054         gsignond_identity_info_get_id (other)) {
1055         return FALSE;
1056     }
1057
1058     if (g_strcmp0 (gsignond_identity_info_get_username (info),
1059         gsignond_identity_info_get_username (other)) != 0) {
1060         return FALSE;
1061     }
1062
1063     if (g_strcmp0 (gsignond_identity_info_get_secret (info),
1064         gsignond_identity_info_get_secret (other)) != 0) {
1065         return FALSE;
1066     }
1067
1068     if (gsignond_identity_info_get_store_secret (info) !=
1069         gsignond_identity_info_get_store_secret (other)) {
1070         return FALSE;
1071     }
1072
1073     if (g_strcmp0 (gsignond_identity_info_get_caption (info),
1074         gsignond_identity_info_get_caption (other)) != 0) {
1075         return FALSE;
1076     }
1077
1078     info_realms = gsignond_identity_info_get_realms (info);
1079     other_realms = gsignond_identity_info_get_realms (other);
1080     equal = _gsignond_identity_info_seq_cmp (info_realms, other_realms);
1081     if (info_realms) g_sequence_free (info_realms);
1082     if (other_realms) g_sequence_free (other_realms);
1083     if (!equal) {
1084         return FALSE;
1085     }
1086
1087     info_methods = gsignond_identity_info_get_methods (info);
1088     other_methods = gsignond_identity_info_get_methods (other);
1089     equal = _gsignond_identity_info_methods_cmp (info_methods, other_methods);
1090     if (info_methods) g_hash_table_unref (info_methods);
1091     if (other_methods) g_hash_table_unref (other_methods);
1092     if (!equal) {
1093         return FALSE;
1094     }
1095
1096     info_acl = gsignond_identity_info_get_access_control_list (info);
1097     if (info_acl)
1098         info_acl = g_list_sort (
1099                         info_acl,
1100                         (GCompareFunc)gsignond_security_context_compare);
1101     other_acl = gsignond_identity_info_get_access_control_list (other);
1102     if (other_acl)
1103         other_acl = g_list_sort (
1104                         other_acl,
1105                         (GCompareFunc)gsignond_security_context_compare);
1106     equal = _gsignond_identity_info_sec_context_list_cmp (info_acl, other_acl);
1107     if (info_acl) gsignond_security_context_list_free (info_acl);
1108     if (other_acl) gsignond_security_context_list_free (other_acl);
1109     if (!equal) {
1110         return FALSE;
1111     }
1112
1113     info_owner = gsignond_identity_info_get_owner (info);
1114     other_owner = gsignond_identity_info_get_owner (other);
1115     equal = gsignond_security_context_match (info_owner, other_owner);
1116     if (info_owner) gsignond_security_context_free (info_owner);
1117     if (other_owner) gsignond_security_context_free (other_owner);
1118     if (!equal) {
1119         return FALSE;
1120     }
1121
1122     if (gsignond_identity_info_get_validated (info) !=
1123         gsignond_identity_info_get_validated (other)) {
1124         return FALSE;
1125     }
1126
1127     if (gsignond_identity_info_get_identity_type (info) !=
1128         gsignond_identity_info_get_identity_type (other)) {
1129         return FALSE;
1130     }
1131
1132     return TRUE;
1133 }
1134
1135 void
1136 gsignond_identity_info_list_free (GSignondIdentityInfoList *list)
1137 {
1138     g_return_if_fail (list != NULL);
1139     g_list_free_full (list, (GDestroyNotify)gsignond_identity_info_unref);
1140 }
1141