1 /* $Id$
2 *
3 * Lasso - A free implementation of the Liberty Alliance specifications.
4 *
5 * Copyright (C) 2004-2007 Entr'ouvert
6 * http://lasso.entrouvert.org
7 *
8 * Authors: See AUTHORS file in top-level directory.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, see <http://www.gnu.org/licenses/>.
22 */
23
24 /**
25 * SECTION:identity
26 * @short_description: Principal identity
27 *
28 * A #LassoIdentity object records the identifers that a principal use two federate pairs of
29 * providers.
30 *
31 **/
32
33 #include "../xml/private.h"
34 #include <config.h>
35 #include "../utils.h"
36 #include "identity.h"
37
38 #ifdef LASSO_WSF_ENABLED
39 #include "../id-wsf/id_ff_extensions.h"
40 #endif
41
42 #include "identityprivate.h"
43 #include "../lasso_config.h"
44
45 /*****************************************************************************/
46 /* public methods */
47 /*****************************************************************************/
48
49 /**
50 * lasso_identity_add_federation:
51 * @identity: a #LassoIdentity
52 * @federation: the #LassoFederation
53 *
54 * Adds @federation as a known federation for @identity. @federation is
55 * then owned by the identity; caller must not free it.
56 *
57 * Return value: 0 on success; or a negative value otherwise.
58 **/
59 gint
lasso_identity_add_federation(LassoIdentity * identity,LassoFederation * federation)60 lasso_identity_add_federation(LassoIdentity *identity, LassoFederation *federation)
61 {
62 g_return_val_if_fail(LASSO_IS_IDENTITY(identity), LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
63 g_return_val_if_fail(LASSO_IS_FEDERATION(federation),
64 LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
65
66 /* add the federation, replace if one already exists */
67 g_hash_table_insert(identity->federations,
68 g_strdup(federation->remote_providerID), federation);
69 identity->is_dirty = TRUE;
70
71 return 0;
72 }
73
74 /**
75 * lasso_identity_get_federation:
76 * @identity: a #LassoIdentity
77 * @providerID: the provider ID
78 *
79 * Looks up and returns the #LassoFederation for this provider ID.
80 *
81 * Return value:(transfer none): the #LassoFederation; or NULL if it didn't exist. The
82 * #LassoFederation is internally allocated. It must not be freed,
83 * modified or stored.
84 **/
85 LassoFederation*
lasso_identity_get_federation(LassoIdentity * identity,const char * providerID)86 lasso_identity_get_federation(LassoIdentity *identity, const char *providerID)
87 {
88 if (! LASSO_IS_IDENTITY(identity) ||
89 providerID == NULL ||
90 identity->federations == NULL) {
91 return NULL;
92 }
93
94 return g_hash_table_lookup(identity->federations, providerID);
95 }
96
97 /**
98 * lasso_identity_remove_federation:
99 * @identity: a #LassoIdentity
100 * @providerID: the provider ID
101 *
102 * Remove federation between identity and provider with @providerID
103 *
104 * Return value: 0 on success; or a negative value otherwise.
105 **/
106 gint
lasso_identity_remove_federation(LassoIdentity * identity,const char * providerID)107 lasso_identity_remove_federation(LassoIdentity *identity, const char *providerID)
108 {
109 g_return_val_if_fail(LASSO_IS_IDENTITY(identity), LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
110 g_return_val_if_fail(providerID != NULL, LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
111
112 if (g_hash_table_remove(identity->federations, providerID) == FALSE) {
113 return LASSO_PROFILE_ERROR_FEDERATION_NOT_FOUND;
114 }
115 identity->is_dirty = TRUE;
116
117 return 0;
118 }
119
120 /**
121 * lasso_identity_destroy:
122 * @identity: a #LassoIdentity
123 *
124 * Destroys an identity.
125 **/
126 void
lasso_identity_destroy(LassoIdentity * identity)127 lasso_identity_destroy(LassoIdentity *identity)
128 {
129 if (identity == NULL)
130 return;
131 lasso_node_destroy(LASSO_NODE(identity));
132 }
133
134
135 /*****************************************************************************/
136 /* private methods */
137 /*****************************************************************************/
138
139 static LassoNodeClass *parent_class = NULL;
140
141 static void
add_childnode_from_hashtable(G_GNUC_UNUSED gchar * key,LassoNode * value,xmlNode * xmlnode)142 add_childnode_from_hashtable(G_GNUC_UNUSED gchar *key, LassoNode *value, xmlNode *xmlnode)
143 {
144 xmlAddChild(xmlnode, lasso_node_get_xmlNode(LASSO_NODE(value), TRUE));
145 }
146
147 #ifdef LASSO_WSF_ENABLED
148 static void
add_text_childnode_from_list(gchar * value,xmlNode * xmlnode)149 add_text_childnode_from_list(gchar *value, xmlNode *xmlnode)
150 {
151 xmlNewTextChild(xmlnode, NULL, (xmlChar*)"SvcMDID", (xmlChar*)value);
152 }
153 #endif
154
155 static xmlNode*
get_xmlNode(LassoNode * node,G_GNUC_UNUSED gboolean lasso_dump)156 get_xmlNode(LassoNode *node, G_GNUC_UNUSED gboolean lasso_dump)
157 {
158 xmlNode *xmlnode;
159 LassoIdentity *identity = LASSO_IDENTITY(node);
160 #ifdef LASSO_WSF_ENABLED
161 xmlNode *t;
162 #endif
163
164 xmlnode = xmlNewNode(NULL, (xmlChar*)"Identity");
165 xmlSetNs(xmlnode, xmlNewNs(xmlnode, (xmlChar*)LASSO_LASSO_HREF, NULL));
166 xmlSetProp(xmlnode, (xmlChar*)"Version", (xmlChar*)"2");
167
168 /* Federations */
169 if (g_hash_table_size(identity->federations))
170 g_hash_table_foreach(identity->federations,
171 (GHFunc)add_childnode_from_hashtable, xmlnode);
172 #ifdef LASSO_WSF_ENABLED
173 /* Resource Offerings */
174 g_hash_table_foreach(identity->private_data->resource_offerings_map,
175 (GHFunc)add_childnode_from_hashtable, xmlnode);
176
177 /* Service Metadatas IDs (svcMDID) */
178 if (identity->private_data->svcMDID != NULL) {
179 t = xmlNewTextChild(xmlnode, NULL, (xmlChar*)"SvcMDIDs", NULL);
180 g_list_foreach(identity->private_data->svcMDID,
181 (GFunc)add_text_childnode_from_list, t);
182 }
183 #endif
184
185 return xmlnode;
186 }
187
188 static int
init_from_xml(LassoNode * node,xmlNode * xmlnode)189 init_from_xml(LassoNode *node, xmlNode *xmlnode)
190 {
191 LassoIdentity *identity = LASSO_IDENTITY(node);
192 xmlNode *t;
193 #ifdef LASSO_WSF_ENABLED
194 xmlNode *t2;
195 xmlChar *xml_content;
196 gchar *content;
197 #endif
198
199 t = xmlnode->children;
200 while (t) {
201 if (t->type != XML_ELEMENT_NODE) {
202 t = t->next;
203 continue;
204 }
205
206 /* Federations */
207 if (strcmp((char*)t->name, "Federation") == 0) {
208 LassoFederation *federation;
209 federation = LASSO_FEDERATION(lasso_node_new_from_xmlNode(t));
210 g_hash_table_insert(
211 identity->federations,
212 g_strdup(federation->remote_providerID), federation);
213 }
214
215 #ifdef LASSO_WSF_ENABLED
216 /* Resource Offerings */
217 if (strcmp((char*)t->name, "ResourceOffering") == 0) {
218 LassoDiscoResourceOffering *offering;
219 offering = LASSO_DISCO_RESOURCE_OFFERING(lasso_node_new_from_xmlNode(t));
220 g_hash_table_insert(identity->private_data->resource_offerings_map,
221 g_strdup(offering->entryID),
222 g_object_ref(offering));
223 }
224
225 /* Service Metadatas IDs (SvcMDID) */
226 if (strcmp((char*)t->name, "SvcMDIDs") == 0) {
227 t2 = t->children;
228 while (t2) {
229 if (t2->type != XML_ELEMENT_NODE) {
230 t2 = t2->next;
231 continue;
232 }
233 xml_content = xmlNodeGetContent(t2);
234 content = g_strdup((gchar *)xml_content);
235 identity->private_data->svcMDID = g_list_append(
236 identity->private_data->svcMDID, content);
237 xmlFree(xml_content);
238 t2 = t2->next;
239 }
240 }
241 #endif
242
243 t = t->next;
244 }
245
246 return 0;
247 }
248
249
250 /*****************************************************************************/
251 /* overridden parent class methods */
252 /*****************************************************************************/
253
254 static void
dispose(GObject * object)255 dispose(GObject *object)
256 {
257 LassoIdentity *identity = LASSO_IDENTITY(object);
258
259
260 if (identity->private_data->dispose_has_run == FALSE) {
261 identity->private_data->dispose_has_run = TRUE;
262 #ifdef LASSO_WSF_ENABLED
263 lasso_release_list_of_strings(identity->private_data->svcMDID);
264 lasso_release_ghashtable(identity->private_data->resource_offerings_map);
265 #endif
266
267 lasso_release_ghashtable(identity->federations);
268
269 G_OBJECT_CLASS(parent_class)->dispose(object);
270 }
271 }
272
273 static void
finalize(GObject * object)274 finalize(GObject *object)
275 {
276 LassoIdentity *identity = LASSO_IDENTITY(object);
277 lasso_release(identity->private_data);
278 identity->private_data = NULL;
279 G_OBJECT_CLASS(parent_class)->finalize(object);
280 }
281
282 /*****************************************************************************/
283 /* instance and class init functions */
284 /*****************************************************************************/
285
286 static void
instance_init(LassoIdentity * identity)287 instance_init(LassoIdentity *identity)
288 {
289 identity->private_data = g_new0(LassoIdentityPrivate, 1);
290 identity->private_data->dispose_has_run = FALSE;
291 #ifdef LASSO_WSF_ENABLED
292 identity->private_data->svcMDID = NULL;
293 identity->private_data->last_entry_id = 0;
294 identity->private_data->resource_offerings_map = g_hash_table_new_full(g_str_hash,
295 g_str_equal, (GDestroyNotify)g_free, (GDestroyNotify)g_object_unref);
296 #endif
297 identity->federations = g_hash_table_new_full(g_str_hash, g_str_equal,
298 (GDestroyNotify)g_free,
299 (GDestroyNotify)lasso_federation_destroy);
300 identity->is_dirty = FALSE;
301 }
302
303 static void
class_init(LassoIdentityClass * klass,void * unused G_GNUC_UNUSED)304 class_init(LassoIdentityClass *klass, void *unused G_GNUC_UNUSED)
305 {
306 parent_class = g_type_class_peek_parent(klass);
307 LassoNodeClass *nclass = LASSO_NODE_CLASS(klass);
308
309 nclass->get_xmlNode = get_xmlNode;
310 nclass->init_from_xml = init_from_xml;
311 nclass->node_data = g_new0(LassoNodeClassData, 1);
312 lasso_node_class_set_nodename(nclass, "Identity");
313 lasso_node_class_set_ns(nclass, LASSO_LASSO_HREF, LASSO_LASSO_PREFIX);
314
315 G_OBJECT_CLASS(klass)->dispose = dispose;
316 G_OBJECT_CLASS(klass)->finalize = finalize;
317 }
318
319 GType
lasso_identity_get_type()320 lasso_identity_get_type()
321 {
322 static GType this_type = 0;
323
324 if (!this_type) {
325 static const GTypeInfo this_info = {
326 sizeof (LassoIdentityClass),
327 NULL,
328 NULL,
329 (GClassInitFunc) class_init,
330 NULL,
331 NULL,
332 sizeof(LassoIdentity),
333 0,
334 (GInstanceInitFunc) instance_init,
335 NULL
336 };
337
338 this_type = g_type_register_static(LASSO_TYPE_NODE,
339 "LassoIdentity", &this_info, 0);
340 }
341 return this_type;
342 }
343
344 /**
345 * lasso_identity_new:
346 *
347 * Creates a new #LassoIdentity.
348 *
349 * Return value: a newly created #LassoIdentity
350 **/
351 LassoIdentity*
lasso_identity_new()352 lasso_identity_new()
353 {
354 return g_object_new(LASSO_TYPE_IDENTITY, NULL);
355 }
356
357 /**
358 * lasso_identity_new_from_dump:
359 * @dump: XML server dump
360 *
361 * Restores the @dump to a new #LassoIdentity.
362 *
363 * Return value: a newly created #LassoIdentity; or NULL if an error occured
364 **/
365 LassoIdentity*
lasso_identity_new_from_dump(const gchar * dump)366 lasso_identity_new_from_dump(const gchar *dump)
367 {
368 LassoIdentity *identity;
369
370 identity = (LassoIdentity*)lasso_node_new_from_dump(dump);
371 if (! LASSO_IS_IDENTITY(identity)) {
372 lasso_release_gobject(identity);
373 }
374
375 return identity;
376 }
377
378 /**
379 * lasso_identity_dump:
380 * @identity: a #LassoIdentity
381 *
382 * Dumps @identity content to an XML string.
383 *
384 * Return value:(transfer full): the dump string. It must be freed by the caller.
385 **/
386 gchar*
lasso_identity_dump(LassoIdentity * identity)387 lasso_identity_dump(LassoIdentity *identity)
388 {
389 return lasso_node_dump(LASSO_NODE(identity));
390 }
391