~ubuntu-branches/ubuntu/karmic/lasso/karmic

« back to all changes in this revision

Viewing changes to lasso/id-wsf-2.0/data_service.c

  • Committer: Bazaar Package Importer
  • Author(s): Michael Bienia
  • Date: 2007-11-01 20:01:20 UTC
  • mfrom: (1.1.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20071101200120-9ruoui67n24xyz9c
Tags: 2.1.1-2ubuntu1
* Merge from debian unstable (LP: #134095), remaining changes:
  + debian/control:
    - Modify Maintainer value to match DebianMaintainerField spec.
  + configure{,.ac}:
    - Add missing quotes around the value for PHP[45]_LIBS.
* Fix two lintian warnings:
  + debian/control:
    - liblasso3-dev: Replace ${Source-Version} with ${binary:Version}
  + debian/rules:
    - Don't ignore a make clean error.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: idwsf2_data_service.c 3101 2007-05-30 11:40:10Z dlaniel $
 
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, write to the Free Software
 
22
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
23
 */
 
24
 
 
25
#include <libxml/xpath.h>
 
26
#include <libxml/xpathInternals.h>
 
27
 
 
28
#include <lasso/id-wsf-2.0/discovery.h>
 
29
#include <lasso/id-wsf-2.0/data_service.h>
 
30
 
 
31
#include <lasso/xml/id-wsf-2.0/disco_service_type.h>
 
32
#include <lasso/xml/id-wsf-2.0/dstref_query.h>
 
33
#include <lasso/xml/id-wsf-2.0/dstref_query_response.h>
 
34
#include <lasso/xml/id-wsf-2.0/dstref_data.h>
 
35
#include <lasso/xml/id-wsf-2.0/util_status.h>
 
36
#include <lasso/xml/id-wsf-2.0/sb2_redirect_request.h>
 
37
#include <lasso/xml/id-wsf-2.0/dstref_modify.h>
 
38
#include <lasso/xml/id-wsf-2.0/dstref_modify_item.h>
 
39
#include <lasso/xml/id-wsf-2.0/dstref_modify_response.h>
 
40
 
 
41
#include <lasso/xml/soap_fault.h>
 
42
 
 
43
struct _LassoIdWsf2DataServicePrivate
 
44
{
 
45
        gboolean dispose_has_run;
 
46
        LassoWsAddrEndpointReference *epr;
 
47
        GList *credentials;
 
48
};
 
49
 
 
50
/*****************************************************************************/
 
51
/* public methods                                                            */
 
52
/*****************************************************************************/
 
53
 
 
54
gint
 
55
lasso_idwsf2_data_service_init_query(LassoIdWsf2DataService *service)
 
56
{
 
57
        LassoIdWsf2Profile *profile = LASSO_IDWSF2_PROFILE(service);
 
58
        LassoIdWsf2DstRefQuery *query;
 
59
        LassoWsAddrEndpointReference *epr;
 
60
        GList *metadata_item;
 
61
        GList *i;
 
62
        gchar *service_type = NULL;
 
63
 
 
64
        g_return_val_if_fail(LASSO_IS_IDWSF2_DATA_SERVICE(service),
 
65
                LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
 
66
 
 
67
        query = lasso_idwsf2_dstref_query_new();
 
68
 
 
69
        if (LASSO_PROFILE(profile)->request) {
 
70
                lasso_node_destroy(LASSO_NODE(LASSO_PROFILE(profile)->request));
 
71
        }
 
72
        LASSO_PROFILE(profile)->request = LASSO_NODE(query);
 
73
 
 
74
        if (service == NULL || service->private_data == NULL
 
75
                        || service->private_data->epr == NULL
 
76
                        || service->private_data->epr->Metadata == NULL) {
 
77
                return LASSO_PROFILE_ERROR_MISSING_ENDPOINT_REFERENCE;
 
78
        }
 
79
 
 
80
        epr = service->private_data->epr;
 
81
 
 
82
        /* Get the service type from the EPR */
 
83
        metadata_item = epr->Metadata->any;
 
84
        for (i = g_list_first(metadata_item); i != NULL; i = g_list_next(i)) {
 
85
                if (LASSO_IS_IDWSF2_DISCO_SERVICE_TYPE(i->data)) {
 
86
                        service_type = LASSO_IDWSF2_DISCO_SERVICE_TYPE(i->data)->content;
 
87
                        break;
 
88
                }
 
89
        }
 
90
 
 
91
        /* Set hrefServiceType and prefixServiceType in query in order to set the profile */
 
92
        /* namespace in the request */
 
93
        if (service_type != NULL) {
 
94
                query->hrefServiceType = g_strdup(service_type);
 
95
                query->prefixServiceType = lasso_get_prefix_for_idwsf2_dst_service_href(
 
96
                        query->hrefServiceType);
 
97
        }
 
98
        if (query->prefixServiceType == NULL) {
 
99
                return LASSO_PROFILE_ERROR_MISSING_SERVICE_TYPE;
 
100
        }
 
101
 
 
102
        lasso_idwsf2_profile_init_soap_request(profile, LASSO_NODE(query), service_type);
 
103
 
 
104
        /* Set msg_url as epr address, which is the SoapEndpoint */
 
105
        if (epr->Address != NULL) {
 
106
                LASSO_PROFILE(profile)->msg_url = g_strdup(epr->Address->content);
 
107
        } else {
 
108
                return LASSO_PROFILE_ERROR_MISSING_ENDPOINT_REFERENCE_ADDRESS;
 
109
        }
 
110
 
 
111
        return 0;
 
112
}
 
113
 
 
114
gint
 
115
lasso_idwsf2_data_service_add_query_item(LassoIdWsf2DataService *service, const gchar *item_xpath,
 
116
        const gchar *item_id)
 
117
{
 
118
        LassoIdWsf2Profile *profile = LASSO_IDWSF2_PROFILE(service);
 
119
        LassoIdWsf2DstRefQuery *query;
 
120
        LassoIdWsf2DstRefQueryItem *item;
 
121
 
 
122
        g_return_val_if_fail(LASSO_IS_IDWSF2_DATA_SERVICE(service),
 
123
                LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
 
124
        g_return_val_if_fail(item_xpath != NULL, LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
 
125
        g_return_val_if_fail(item_id != NULL, LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
 
126
 
 
127
        if (! LASSO_IS_IDWSF2_DSTREF_QUERY(LASSO_PROFILE(profile)->request)) {
 
128
                return LASSO_PROFILE_ERROR_MISSING_REQUEST;
 
129
        }
 
130
 
 
131
        query = LASSO_IDWSF2_DSTREF_QUERY(LASSO_PROFILE(profile)->request);
 
132
 
 
133
        item = lasso_idwsf2_dstref_query_item_new_full(item_xpath, item_id);
 
134
        query->QueryItem = g_list_append(query->QueryItem, item);
 
135
 
 
136
        return 0;
 
137
}
 
138
 
 
139
gint
 
140
lasso_idwsf2_data_service_process_query_msg(LassoIdWsf2DataService *service, const gchar *message)
 
141
{
 
142
        LassoIdWsf2Profile *profile = LASSO_IDWSF2_PROFILE(service);
 
143
        LassoIdWsf2DstRefQuery *request = NULL;
 
144
        LassoIdWsf2DstRefResultQuery *item = NULL;
 
145
        GList *i;
 
146
        int res = 0;
 
147
 
 
148
        g_return_val_if_fail(LASSO_IS_IDWSF2_DATA_SERVICE(service),
 
149
                LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
 
150
        g_return_val_if_fail(message != NULL, LASSO_PARAM_ERROR_INVALID_VALUE);
 
151
 
 
152
        res = lasso_idwsf2_profile_process_soap_request_msg(profile, message);
 
153
 
 
154
        if (! LASSO_IS_IDWSF2_DSTREF_QUERY(LASSO_PROFILE(profile)->request)) {
 
155
                res = LASSO_PROFILE_ERROR_INVALID_SOAP_MSG;
 
156
        } else {
 
157
                request = LASSO_IDWSF2_DSTREF_QUERY(LASSO_PROFILE(profile)->request);
 
158
                service->type = g_strdup(request->hrefServiceType);
 
159
        }
 
160
 
 
161
        if (res == 0) {
 
162
                /* Parse QueryItems to get a list of Xpath strings */
 
163
                for (i = g_list_first(request->QueryItem); i != NULL; i = g_list_next(i)) {
 
164
                        item = LASSO_IDWSF2_DSTREF_RESULT_QUERY(i->data);
 
165
                        if (item->Select != NULL) {
 
166
                                service->query_items = g_list_append(
 
167
                                        service->query_items, g_strdup(item->Select));
 
168
                        }
 
169
                }
 
170
        }
 
171
 
 
172
        return res;
 
173
}
 
174
 
 
175
gint
 
176
lasso_idwsf2_data_service_parse_query_items(LassoIdWsf2DataService *service)
 
177
{
 
178
        LassoIdWsf2Profile *profile = LASSO_IDWSF2_PROFILE(service);
 
179
        LassoIdWsf2DstRefQuery *request;
 
180
        LassoIdWsf2DstRefQueryResponse *response;
 
181
        LassoIdWsf2UtilResponse *response2;
 
182
        LassoSoapEnvelope *envelope;
 
183
        xmlDoc *doc;
 
184
        xmlXPathContext *xpathCtx;
 
185
        xmlXPathObject *xpathObj;
 
186
        LassoIdWsf2DstRefQueryItem *item;
 
187
        LassoIdWsf2DstRefResultQuery *item_result_query;
 
188
        LassoIdWsf2DstResultQueryBase *item_result_query_base;
 
189
        LassoIdWsf2DstRefData *data;
 
190
        LassoIdWsf2DstRefItemData *data_item;
 
191
        xmlNode *node;
 
192
        GList *iter;
 
193
        int res = 0;
 
194
 
 
195
        g_return_val_if_fail(LASSO_IS_IDWSF2_DATA_SERVICE(service),
 
196
                LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
 
197
 
 
198
        if (! LASSO_IS_IDWSF2_DSTREF_QUERY(LASSO_PROFILE(profile)->request)) {
 
199
                return LASSO_PROFILE_ERROR_MISSING_REQUEST;
 
200
        }
 
201
        request = LASSO_IDWSF2_DSTREF_QUERY(LASSO_PROFILE(profile)->request);
 
202
 
 
203
        if (service->data == NULL) {
 
204
                return LASSO_DST_ERROR_MISSING_SERVICE_DATA;
 
205
        }
 
206
 
 
207
        /* Response envelope and body */
 
208
        envelope = profile->soap_envelope_response;
 
209
        if (envelope == NULL) {
 
210
                return LASSO_SOAP_ERROR_MISSING_ENVELOPE;
 
211
        }
 
212
        response = lasso_idwsf2_dstref_query_response_new();
 
213
        response->prefixServiceType = g_strdup(request->prefixServiceType);
 
214
        response->hrefServiceType = g_strdup(request->hrefServiceType);
 
215
        LASSO_PROFILE(profile)->response = LASSO_NODE(response);
 
216
        envelope->Body->any = g_list_append(envelope->Body->any, response);
 
217
 
 
218
        response2 = LASSO_IDWSF2_UTIL_RESPONSE(response);
 
219
        /* Default is Failed, will be OK or Partial when some items are successfully parsed */
 
220
        response2->Status = lasso_idwsf2_util_status_new();
 
221
        response2->Status->code = g_strdup(LASSO_DST_STATUS_CODE_FAILED);
 
222
 
 
223
        /* Initialise XML parsing */
 
224
        doc = xmlNewDoc((xmlChar*)"1.0");
 
225
        xmlDocSetRootElement(doc, service->data);
 
226
        xpathCtx = xmlXPathNewContext(doc);
 
227
        xmlXPathRegisterNs(xpathCtx, (xmlChar*)response->prefixServiceType,
 
228
                (xmlChar*)response->hrefServiceType);
 
229
 
 
230
        /* Parse request QueryItems and fill response Data accordingly */
 
231
        /* XXX: needs another level, since there may be more than one <dst:Query> */
 
232
        for (iter = g_list_first(request->QueryItem); iter != NULL; iter = g_list_next(iter)) {
 
233
                item = iter->data;
 
234
                item_result_query = LASSO_IDWSF2_DSTREF_RESULT_QUERY(item);
 
235
                item_result_query_base = LASSO_IDWSF2_DST_RESULT_QUERY_BASE(item);
 
236
                xpathObj = xmlXPathEvalExpression((xmlChar*)item_result_query->Select, xpathCtx);
 
237
                if (xpathObj && xpathObj->nodesetval && xpathObj->nodesetval->nodeNr) {
 
238
                        /* XXX: assuming there is only one matching node */
 
239
                        node = xpathObj->nodesetval->nodeTab[0];
 
240
                        data = lasso_idwsf2_dstref_data_new();
 
241
                        data_item = LASSO_IDWSF2_DSTREF_ITEM_DATA(data);
 
242
                        LASSO_IDWSF2_DSTREF_APP_DATA(data_item)->any = g_list_append(
 
243
                                        LASSO_IDWSF2_DSTREF_APP_DATA(data_item)->any,
 
244
                                        xmlCopyNode(node, 1));
 
245
                        if (item_result_query_base->itemID != NULL) {
 
246
                                data_item->itemIDRef = g_strdup(item_result_query_base->itemID);
 
247
                        }
 
248
                        response->Data = g_list_append(response->Data, data);
 
249
                        /* Success : change status code to OK */
 
250
                        if (strcmp(response2->Status->code, LASSO_DST_STATUS_CODE_FAILED) == 0) {
 
251
                                g_free(response2->Status->code);
 
252
                                response2->Status->code = g_strdup(LASSO_DST_STATUS_CODE_OK);
 
253
                        }
 
254
                        xmlXPathFreeObject(xpathObj);
 
255
                        xpathObj = NULL;
 
256
                } else {
 
257
                        /* If status was OK, change it to Partial */
 
258
                        if (strcmp(response2->Status->code, LASSO_DST_STATUS_CODE_OK) == 0) {
 
259
                                g_free(response2->Status->code);
 
260
                                response2->Status->code = g_strdup(LASSO_DST_STATUS_CODE_PARTIAL);
 
261
                        } else {
 
262
                                res = LASSO_DST_ERROR_QUERY_FAILED;
 
263
                        }
 
264
                        if (xpathObj != NULL) {
 
265
                                xmlXPathFreeObject(xpathObj);
 
266
                                xpathObj = NULL;
 
267
                        }
 
268
                        /* Stop processing at first error */
 
269
                        break;
 
270
                }
 
271
        }
 
272
 
 
273
        /* Free XML parsing objects */
 
274
        xmlUnlinkNode(service->data);
 
275
        xmlXPathFreeContext(xpathCtx);
 
276
        xmlFreeDoc(doc);
 
277
 
 
278
        if (res == 0 && strcmp(response2->Status->code, LASSO_DST_STATUS_CODE_FAILED) == 0) {
 
279
                res = LASSO_DST_ERROR_QUERY_FAILED;
 
280
        }
 
281
 
 
282
        return res;
 
283
}
 
284
 
 
285
static gint
 
286
lasso_idwsf2_data_service_process_query_response_soap_fault_msg(LassoIdWsf2DataService *service,
 
287
        const gchar *message)
 
288
{
 
289
        LassoIdWsf2Profile *profile = LASSO_IDWSF2_PROFILE(service);
 
290
        LassoSoapFault *fault;
 
291
        LassoIdWsf2Sb2RedirectRequest *redirect_request = NULL;
 
292
        GList *iter;
 
293
        int res;
 
294
 
 
295
        if (! LASSO_IS_SOAP_FAULT(LASSO_PROFILE(profile)->response)) {
 
296
                /* Should not happen as it should be checked in caller */
 
297
                return 0;
 
298
        }
 
299
 
 
300
        fault = LASSO_SOAP_FAULT(LASSO_PROFILE(profile)->response);
 
301
 
 
302
        if (fault->Detail == NULL || fault->Detail->any == NULL) {
 
303
                return LASSO_SOAP_ERROR_MISSING_SOAP_FAULT_DETAIL;
 
304
        }
 
305
 
 
306
        /* Get RedirectRequest element from soap fault detail */
 
307
        for (iter = fault->Detail->any; iter != NULL; iter = iter->next) {
 
308
                if (LASSO_IS_IDWSF2_SB2_REDIRECT_REQUEST(iter->data) == TRUE) {
 
309
                        redirect_request = LASSO_IDWSF2_SB2_REDIRECT_REQUEST(iter->data);
 
310
                        break;
 
311
                }
 
312
        }
 
313
 
 
314
        if (redirect_request != NULL) {
 
315
                /* This is not a failure, this exception code indicates the WSP needs to ask */
 
316
                /* user consent to get an attribute */
 
317
                res = LASSO_SOAP_FAULT_REDIRECT_REQUEST;
 
318
                /* Get redirect request url */
 
319
                service->redirect_url = g_strdup(redirect_request->redirectURL);
 
320
        }
 
321
 
 
322
        return res;
 
323
}
 
324
 
 
325
gint
 
326
lasso_idwsf2_data_service_process_query_response_msg(LassoIdWsf2DataService *service,
 
327
        const gchar *message)
 
328
{
 
329
        LassoIdWsf2Profile *profile = LASSO_IDWSF2_PROFILE(service);
 
330
        LassoIdWsf2UtilResponse *response;
 
331
        int res;
 
332
 
 
333
        g_return_val_if_fail(LASSO_IS_IDWSF2_DATA_SERVICE(service),
 
334
                LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
 
335
        g_return_val_if_fail(message != NULL, LASSO_PARAM_ERROR_INVALID_VALUE);
 
336
 
 
337
        res = lasso_idwsf2_profile_process_soap_response_msg(profile, message);
 
338
        if (res != 0) {
 
339
                return res;
 
340
        }
 
341
 
 
342
        /* Message can be either a SoapFault or a QueryResponse */
 
343
        if (LASSO_IS_SOAP_FAULT(LASSO_PROFILE(profile)->response)) {
 
344
                return lasso_idwsf2_data_service_process_query_response_soap_fault_msg(
 
345
                        service, message);
 
346
        }
 
347
 
 
348
        if (! LASSO_IS_IDWSF2_DSTREF_QUERY_RESPONSE(LASSO_PROFILE(profile)->response)) {
 
349
                return LASSO_PROFILE_ERROR_INVALID_SOAP_MSG;
 
350
        }
 
351
 
 
352
        /* Check response status code */
 
353
        response = LASSO_IDWSF2_UTIL_RESPONSE(LASSO_PROFILE(profile)->response);
 
354
        if (response->Status == NULL || response->Status->code == NULL) {
 
355
                return LASSO_PROFILE_ERROR_MISSING_STATUS_CODE;
 
356
        }
 
357
        if (strcmp(response->Status->code, LASSO_DST_STATUS_CODE_PARTIAL) == 0) {
 
358
                return LASSO_DST_ERROR_QUERY_PARTIALLY_FAILED;
 
359
        } else if (strcmp(response->Status->code, LASSO_DST_STATUS_CODE_OK) != 0) {
 
360
                return LASSO_DST_ERROR_QUERY_FAILED;
 
361
        }
 
362
 
 
363
        return 0;
 
364
}
 
365
 
 
366
xmlNode*
 
367
lasso_idwsf2_data_service_get_attribute_node(LassoIdWsf2DataService *service, const gchar *item_id)
 
368
{
 
369
        LassoIdWsf2Profile *profile = LASSO_IDWSF2_PROFILE(service);
 
370
        LassoIdWsf2DstRefQueryResponse *response;
 
371
        LassoIdWsf2DstRefAppData *data = NULL;
 
372
        GList *iter;
 
373
 
 
374
        g_return_val_if_fail(LASSO_IS_IDWSF2_DATA_SERVICE(service), NULL);
 
375
 
 
376
        g_return_val_if_fail(LASSO_IS_IDWSF2_DSTREF_QUERY_RESPONSE(
 
377
                                LASSO_PROFILE(profile)->response), NULL);
 
378
 
 
379
        response = LASSO_IDWSF2_DSTREF_QUERY_RESPONSE(LASSO_PROFILE(profile)->response);
 
380
 
 
381
        /* If no item_id is given, return the first item */
 
382
        if (item_id == NULL && response->Data != NULL && response->Data->data != NULL) {
 
383
                data = LASSO_IDWSF2_DSTREF_APP_DATA(response->Data->data);
 
384
                if (data->any != NULL && data->any->data != NULL) {
 
385
                        return xmlCopyNode(data->any->data, 1);
 
386
                }
 
387
        }
 
388
        if (item_id == NULL) {
 
389
                return NULL;
 
390
        }
 
391
 
 
392
        /* Find the item which has the given item_id */
 
393
        for (iter = g_list_first(response->Data); iter != NULL; iter = g_list_next(iter)) {
 
394
                if (! LASSO_IS_IDWSF2_DSTREF_ITEM_DATA(iter->data)) {
 
395
                        continue;
 
396
                }
 
397
                if (strcmp(LASSO_IDWSF2_DSTREF_ITEM_DATA(iter->data)->itemIDRef, item_id) == 0) {
 
398
                        data = LASSO_IDWSF2_DSTREF_APP_DATA(iter->data);
 
399
                        break;
 
400
                }
 
401
        }
 
402
 
 
403
        if (data == NULL || data->any == NULL || data->any->data == NULL) {
 
404
                /* Item not found */
 
405
                return NULL;
 
406
        }
 
407
 
 
408
        /* XXX: there may be more than one xmlnode */
 
409
        return xmlCopyNode(data->any->data, 1);
 
410
}
 
411
 
 
412
gchar*
 
413
lasso_idwsf2_data_service_get_attribute_string(LassoIdWsf2DataService *service,
 
414
        const gchar *item_id)
 
415
{
 
416
        xmlNode *node;
 
417
        xmlChar *xml_content;
 
418
        gchar *content;
 
419
        
 
420
        g_return_val_if_fail(LASSO_IS_IDWSF2_DATA_SERVICE(service), NULL);
 
421
        
 
422
        node = lasso_idwsf2_data_service_get_attribute_node(service, item_id);
 
423
        xml_content = xmlNodeGetContent(node);
 
424
        content = g_strdup((gchar*)xml_content);
 
425
 
 
426
        xmlFree(xml_content);
 
427
        xmlFreeNode(node);
 
428
 
 
429
        return content;
 
430
}
 
431
 
 
432
gint
 
433
lasso_idwsf2_data_service_init_redirect_user_for_consent(LassoIdWsf2DataService *service,
 
434
        const gchar *redirect_url)
 
435
{
 
436
        LassoIdWsf2Profile *profile = LASSO_IDWSF2_PROFILE(service);
 
437
        LassoSoapEnvelope *envelope;
 
438
        LassoSoapFault *fault;
 
439
        LassoSoapDetail *detail;
 
440
 
 
441
        g_return_val_if_fail(LASSO_IS_IDWSF2_DATA_SERVICE(service),
 
442
                LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
 
443
        g_return_val_if_fail(redirect_url != NULL, LASSO_PARAM_ERROR_INVALID_VALUE);
 
444
 
 
445
        /* Response envelope */
 
446
        envelope = profile->soap_envelope_response;
 
447
        if (envelope == NULL) {
 
448
                return LASSO_SOAP_ERROR_MISSING_ENVELOPE;
 
449
        }
 
450
 
 
451
        /* Build soap fault node */
 
452
        fault = lasso_soap_fault_new();
 
453
        fault->faultcode = g_strdup(LASSO_SOAP_FAULT_CODE_SERVER);
 
454
        fault->faultstring = g_strdup(LASSO_SOAP_FAULT_STRING_SERVER);
 
455
        detail = lasso_soap_detail_new();
 
456
        detail->any = g_list_append(
 
457
                detail->any, lasso_idwsf2_sb2_redirect_request_new_full(redirect_url));
 
458
        fault->Detail = detail;
 
459
 
 
460
        /* Response envelope body */
 
461
        envelope->Body->any = g_list_append(envelope->Body->any, fault);
 
462
 
 
463
        return 0;
 
464
}
 
465
 
 
466
gint
 
467
lasso_idwsf2_data_service_init_modify(LassoIdWsf2DataService *service)
 
468
{
 
469
        LassoIdWsf2Profile *profile = LASSO_IDWSF2_PROFILE(service);
 
470
        LassoIdWsf2DstRefModify *modify;
 
471
        LassoWsAddrEndpointReference *epr;
 
472
        GList *metadata_item;
 
473
        GList *i;
 
474
        gchar *service_type = NULL;
 
475
 
 
476
        g_return_val_if_fail(LASSO_IS_IDWSF2_DATA_SERVICE(service),
 
477
                LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
 
478
 
 
479
        modify = lasso_idwsf2_dstref_modify_new();
 
480
 
 
481
        if (LASSO_PROFILE(profile)->request) {
 
482
                lasso_node_destroy(LASSO_NODE(LASSO_PROFILE(profile)->request));
 
483
        }
 
484
        LASSO_PROFILE(profile)->request = LASSO_NODE(modify);
 
485
 
 
486
        if (service == NULL || service->private_data == NULL
 
487
                        || service->private_data->epr == NULL
 
488
                        || service->private_data->epr->Metadata == NULL) {
 
489
                return LASSO_PROFILE_ERROR_MISSING_ENDPOINT_REFERENCE;
 
490
        }
 
491
 
 
492
        epr = service->private_data->epr;
 
493
 
 
494
        /* Get the service type from the EPR */
 
495
        metadata_item = epr->Metadata->any;
 
496
        for (i = g_list_first(metadata_item); i != NULL; i = g_list_next(i)) {
 
497
                if (LASSO_IS_IDWSF2_DISCO_SERVICE_TYPE(i->data)) {
 
498
                        service_type = LASSO_IDWSF2_DISCO_SERVICE_TYPE(i->data)->content;
 
499
                        break;
 
500
                }
 
501
        }
 
502
 
 
503
        /* Set hrefServiceType and prefixServiceType in query in order to set the profile */
 
504
        /* namespace in the request */
 
505
        if (service_type != NULL) {
 
506
                modify->hrefServiceType = g_strdup(service_type);
 
507
                modify->prefixServiceType = lasso_get_prefix_for_idwsf2_dst_service_href(
 
508
                        modify->hrefServiceType);
 
509
        }
 
510
        if (modify->prefixServiceType == NULL) {
 
511
                return LASSO_PROFILE_ERROR_MISSING_SERVICE_TYPE;
 
512
        }
 
513
 
 
514
        lasso_idwsf2_profile_init_soap_request(profile, LASSO_NODE(modify), service_type);
 
515
 
 
516
        /* Set msg_url as epr address, which is the SoapEndpoint */
 
517
        if (epr->Address != NULL) {
 
518
                LASSO_PROFILE(profile)->msg_url = g_strdup(epr->Address->content);
 
519
        } else {
 
520
                return LASSO_PROFILE_ERROR_MISSING_ENDPOINT_REFERENCE_ADDRESS;
 
521
        }
 
522
 
 
523
        return 0;
 
524
}
 
525
 
 
526
static void set_xml_string(xmlNode **xmlnode, const char* string)
 
527
{
 
528
        xmlDoc *doc;
 
529
        xmlNode *node;
 
530
 
 
531
        doc = xmlReadDoc((xmlChar*)string, NULL, NULL, XML_PARSE_NONET);
 
532
        node = xmlDocGetRootElement(doc);
 
533
        if (node != NULL) {
 
534
                node = xmlCopyNode(node, 1);
 
535
        }
 
536
        xmlFreeDoc(doc);
 
537
 
 
538
        if (*xmlnode) {
 
539
                xmlFreeNode(*xmlnode);
 
540
        }
 
541
 
 
542
        *xmlnode = node;
 
543
}
 
544
 
 
545
gint
 
546
lasso_idwsf2_data_service_add_modify_item(LassoIdWsf2DataService *service, const gchar *item_xpath,
 
547
        const gchar *item_id, const gchar *new_data, const gboolean overrideAllowed)
 
548
{
 
549
        LassoIdWsf2Profile *profile = LASSO_IDWSF2_PROFILE(service);
 
550
        LassoIdWsf2DstRefModify *modify;
 
551
        LassoIdWsf2DstRefModifyItem *item;
 
552
        xmlNode *new_data_node = NULL;
 
553
 
 
554
        g_return_val_if_fail(LASSO_IS_IDWSF2_DATA_SERVICE(service),
 
555
                LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
 
556
        g_return_val_if_fail(item_xpath != NULL, LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
 
557
        g_return_val_if_fail(item_id != NULL, LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
 
558
 
 
559
        if (! LASSO_IS_IDWSF2_DSTREF_MODIFY(LASSO_PROFILE(profile)->request)) {
 
560
                return LASSO_PROFILE_ERROR_MISSING_REQUEST;
 
561
        }
 
562
 
 
563
        modify = LASSO_IDWSF2_DSTREF_MODIFY(LASSO_PROFILE(profile)->request);
 
564
 
 
565
        set_xml_string(&new_data_node, new_data);
 
566
        item = lasso_idwsf2_dstref_modify_item_new_full(
 
567
                item_xpath, item_id, new_data_node, overrideAllowed);
 
568
        modify->ModifyItem = g_list_append(modify->ModifyItem, item);
 
569
 
 
570
        return 0;
 
571
}
 
572
 
 
573
gint
 
574
lasso_idwsf2_data_service_process_modify_msg(LassoIdWsf2DataService *service, const gchar *message)
 
575
{
 
576
        LassoIdWsf2Profile *profile = LASSO_IDWSF2_PROFILE(service);
 
577
        LassoIdWsf2DstRefModify *request = NULL;
 
578
        int res = 0;
 
579
 
 
580
        g_return_val_if_fail(LASSO_IS_IDWSF2_DATA_SERVICE(service),
 
581
                LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
 
582
        g_return_val_if_fail(message != NULL, LASSO_PARAM_ERROR_INVALID_VALUE);
 
583
 
 
584
        res = lasso_idwsf2_profile_process_soap_request_msg(profile, message);
 
585
 
 
586
        if (! LASSO_IS_IDWSF2_DSTREF_MODIFY(LASSO_PROFILE(profile)->request)) {
 
587
                res = LASSO_PROFILE_ERROR_INVALID_SOAP_MSG;
 
588
        } else {
 
589
                request = LASSO_IDWSF2_DSTREF_MODIFY(LASSO_PROFILE(profile)->request);
 
590
                service->type = g_strdup(request->hrefServiceType);
 
591
        }
 
592
 
 
593
        return res;
 
594
}
 
595
 
 
596
static gint
 
597
lasso_idwsf2_data_service_parse_one_modify_item(LassoIdWsf2DstRefModifyItem *item,
 
598
        LassoIdWsf2DstRefModifyResponse *response, xmlDoc *cur_doc, xmlXPathContext *cur_xpathCtx)
 
599
{
 
600
        xmlXPathObject *cur_xpathObj;
 
601
        xmlNode *new_node;
 
602
        xmlNode *cur_node;
 
603
        int res = 0;
 
604
 
 
605
        if (item == NULL) {
 
606
                return LASSO_DST_ERROR_MODIFY_FAILED;
 
607
        }
 
608
 
 
609
        /* Check NewData existence */
 
610
        if (item->NewData == NULL || item->NewData->any == NULL
 
611
                        || item->NewData->any->data == NULL) {
 
612
                if (item->overrideAllowed == TRUE) {
 
613
                        new_node = NULL;
 
614
                } else {
 
615
                        return LASSO_DST_ERROR_NEW_DATA_MISSING;
 
616
                }
 
617
        } else {
 
618
                new_node = (xmlNode*)item->NewData->any->data;
 
619
        }
 
620
 
 
621
        if (item->overrideAllowed == FALSE) {
 
622
                /* Add the new item and add it to the current data */
 
623
                /* FIXME : when the ancestor nodes of the new node do not */
 
624
                /* exist either, they MUST be added */
 
625
                xmlAddChild(xmlDocGetRootElement(cur_doc), xmlCopyNode(new_node, 1));
 
626
        } else {
 
627
                /* Modify an existing node */
 
628
                cur_xpathObj = xmlXPathEvalExpression((xmlChar*)item->Select, cur_xpathCtx);
 
629
                if (cur_xpathObj && cur_xpathObj->nodesetval && cur_xpathObj->nodesetval->nodeNr) {
 
630
                        /* XXX: assuming there is only one matching node */
 
631
                        cur_node = cur_xpathObj->nodesetval->nodeTab[0];
 
632
                        if (new_node != NULL) {
 
633
                                /* Replace old node with new data */
 
634
                                xmlReplaceNode(cur_node, xmlCopyNode(new_node, 1));
 
635
                        } else {
 
636
                                /* Remove old node as new data is empty */
 
637
                                xmlUnlinkNode(cur_node);
 
638
                                xmlFreeNode(cur_node);
 
639
                        }
 
640
                } else {
 
641
                        res = LASSO_DST_ERROR_MODIFY_FAILED;
 
642
                }
 
643
                xmlXPathFreeObject(cur_xpathObj);
 
644
        }
 
645
 
 
646
        return res;
 
647
}
 
648
 
 
649
gint
 
650
lasso_idwsf2_data_service_parse_modify_items(LassoIdWsf2DataService *service)
 
651
{
 
652
        LassoIdWsf2Profile *profile = LASSO_IDWSF2_PROFILE(service);
 
653
        LassoIdWsf2DstRefModify *request;
 
654
        LassoIdWsf2DstRefModifyResponse *response;
 
655
        LassoIdWsf2UtilResponse *response2;
 
656
        LassoSoapEnvelope *envelope;
 
657
        xmlDoc *cur_doc;
 
658
        xmlXPathContext *cur_xpathCtx;
 
659
        LassoIdWsf2DstRefModifyItem *item;
 
660
        xmlNode *cur_data;
 
661
        LassoIdWsf2UtilStatus *secondary_status;
 
662
        GList *iter;
 
663
        int res = 0;
 
664
 
 
665
        g_return_val_if_fail(LASSO_IS_IDWSF2_DATA_SERVICE(service),
 
666
                LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
 
667
 
 
668
        if (! LASSO_IS_IDWSF2_DSTREF_MODIFY(LASSO_PROFILE(profile)->request)) {
 
669
                return LASSO_PROFILE_ERROR_MISSING_REQUEST;
 
670
        }
 
671
        request = LASSO_IDWSF2_DSTREF_MODIFY(LASSO_PROFILE(profile)->request);
 
672
 
 
673
        if (service->data == NULL) {
 
674
                return LASSO_DST_ERROR_MISSING_SERVICE_DATA;
 
675
        } else {
 
676
                cur_data = xmlCopyNode(service->data, 1);
 
677
        }
 
678
 
 
679
        /* Response envelope and body */
 
680
        envelope = profile->soap_envelope_response;
 
681
        if (envelope == NULL) {
 
682
                return LASSO_SOAP_ERROR_MISSING_ENVELOPE;
 
683
        }
 
684
        response = lasso_idwsf2_dstref_modify_response_new();
 
685
        response->prefixServiceType = g_strdup(request->prefixServiceType);
 
686
        response->hrefServiceType = g_strdup(request->hrefServiceType);
 
687
        LASSO_PROFILE(profile)->response = LASSO_NODE(response);
 
688
        envelope->Body->any = g_list_append(envelope->Body->any, response);
 
689
 
 
690
        response2 = LASSO_IDWSF2_UTIL_RESPONSE(response);
 
691
        response2->Status = lasso_idwsf2_util_status_new();
 
692
 
 
693
        /* Initialise XML parsing */
 
694
        cur_doc = xmlNewDoc((xmlChar*)"1.0");
 
695
        xmlDocSetRootElement(cur_doc, cur_data);
 
696
        cur_xpathCtx = xmlXPathNewContext(cur_doc);
 
697
        xmlXPathRegisterNs(cur_xpathCtx, (xmlChar*)response->prefixServiceType,
 
698
                (xmlChar*)response->hrefServiceType);
 
699
 
 
700
        /* Parse request ModifyItems and modify user current data accordingly */
 
701
        /* XXX: needs another level, since there may be more than one <dst:Modify> */
 
702
        for (iter = g_list_first(request->ModifyItem); iter != NULL; iter = g_list_next(iter)) {
 
703
                item = iter->data;
 
704
                res = lasso_idwsf2_data_service_parse_one_modify_item(
 
705
                        item, response, cur_doc, cur_xpathCtx);
 
706
                if (res != 0) {
 
707
                        /* If one item fails, stop and roll back */
 
708
                        break;
 
709
                }
 
710
        }
 
711
 
 
712
        if (res == 0) {
 
713
                response2->Status->code = g_strdup(LASSO_DST_STATUS_CODE_OK);
 
714
                /* Save new service data */
 
715
                xmlFreeNode(service->data);
 
716
                service->data = xmlCopyNode(cur_data, 1);
 
717
        } else {
 
718
                response2->Status->code = g_strdup(LASSO_DST_STATUS_CODE_FAILED);
 
719
                if (res == LASSO_DST_ERROR_NEW_DATA_MISSING) {
 
720
                        secondary_status = lasso_idwsf2_util_status_new();
 
721
                        secondary_status->code = g_strdup(
 
722
                                LASSO_DST_STATUS_CODE_MISSING_NEW_DATA_ELEMENT);
 
723
                        response2->Status->Status = g_list_append(
 
724
                                response2->Status->Status, secondary_status);
 
725
                }
 
726
        }
 
727
 
 
728
        /* Free XML parsing objects */
 
729
        xmlXPathFreeContext(cur_xpathCtx);
 
730
        xmlFreeDoc(cur_doc);
 
731
 
 
732
        return res;
 
733
}
 
734
 
 
735
gint
 
736
lasso_idwsf2_data_service_process_modify_response_msg(LassoIdWsf2DataService *service,
 
737
        const gchar *message)
 
738
{
 
739
        LassoIdWsf2Profile *profile = LASSO_IDWSF2_PROFILE(service);
 
740
        LassoIdWsf2UtilResponse *response;
 
741
        int res;
 
742
 
 
743
        g_return_val_if_fail(LASSO_IS_IDWSF2_DATA_SERVICE(service),
 
744
                LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
 
745
        g_return_val_if_fail(message != NULL, LASSO_PARAM_ERROR_INVALID_VALUE);
 
746
 
 
747
        res = lasso_idwsf2_profile_process_soap_response_msg(profile, message);
 
748
        if (res != 0) {
 
749
                return res;
 
750
        }
 
751
 
 
752
        if (! LASSO_IS_IDWSF2_DSTREF_MODIFY_RESPONSE(LASSO_PROFILE(profile)->response)) {
 
753
                return LASSO_PROFILE_ERROR_INVALID_SOAP_MSG;
 
754
        }
 
755
 
 
756
        /* Check response status code */
 
757
        response = LASSO_IDWSF2_UTIL_RESPONSE(LASSO_PROFILE(profile)->response);
 
758
        if (response->Status == NULL || response->Status->code == NULL) {
 
759
                return LASSO_PROFILE_ERROR_MISSING_STATUS_CODE;
 
760
        }
 
761
        if (strcmp(response->Status->code, LASSO_DST_STATUS_CODE_PARTIAL) == 0) {
 
762
                return LASSO_DST_ERROR_MODIFY_PARTIALLY_FAILED;
 
763
        } else if (strcmp(response->Status->code, LASSO_DST_STATUS_CODE_OK) != 0) {
 
764
                return LASSO_DST_ERROR_MODIFY_FAILED;
 
765
        }
 
766
 
 
767
        return 0;
 
768
}
 
769
 
 
770
/*****************************************************************************/
 
771
/* private methods                                                           */
 
772
/*****************************************************************************/
 
773
 
 
774
static LassoNodeClass *parent_class = NULL;
 
775
 
 
776
/*****************************************************************************/
 
777
/* overrided parent class methods */
 
778
/*****************************************************************************/
 
779
 
 
780
static void
 
781
dispose(GObject *object)
 
782
{
 
783
        LassoIdWsf2DataService *service = LASSO_IDWSF2_DATA_SERVICE(object);
 
784
 
 
785
        if (service->private_data->dispose_has_run == TRUE)
 
786
                return;
 
787
        service->private_data->dispose_has_run = TRUE;
 
788
 
 
789
        if (service->type != NULL) {
 
790
                g_free(service->type);
 
791
                service->type = NULL;
 
792
        }
 
793
        if (service->redirect_url != NULL) {
 
794
                g_free(service->redirect_url);
 
795
                service->redirect_url = NULL;
 
796
        }
 
797
        if (service->query_items != NULL) {
 
798
                g_list_free(service->query_items);
 
799
                service->query_items = NULL;
 
800
        }
 
801
 
 
802
        if (service->private_data->epr != NULL) {
 
803
                lasso_node_destroy(LASSO_NODE(service->private_data->epr));
 
804
                service->private_data->epr = NULL;
 
805
        }
 
806
 
 
807
        G_OBJECT_CLASS(parent_class)->dispose(object);
 
808
}
 
809
 
 
810
static void
 
811
finalize(GObject *object)
 
812
 
813
        LassoIdWsf2DataService *service = LASSO_IDWSF2_DATA_SERVICE(object);
 
814
        g_free(service->private_data);
 
815
        service->private_data = NULL;
 
816
        G_OBJECT_CLASS(parent_class)->finalize(object);
 
817
}
 
818
 
 
819
 
 
820
/*****************************************************************************/
 
821
/* instance and class init functions                                         */
 
822
/*****************************************************************************/
 
823
 
 
824
static void
 
825
instance_init(LassoIdWsf2DataService *service)
 
826
{
 
827
        service->data = NULL;
 
828
        service->type = NULL;
 
829
        service->redirect_url = NULL;
 
830
        service->query_items = NULL;
 
831
        service->private_data = g_new0(LassoIdWsf2DataServicePrivate, 1);
 
832
        service->private_data->epr = NULL;
 
833
}
 
834
 
 
835
static void
 
836
class_init(LassoIdWsf2DataServiceClass *klass)
 
837
{
 
838
        parent_class = g_type_class_peek_parent(klass);
 
839
        
 
840
        G_OBJECT_CLASS(klass)->dispose = dispose;
 
841
        G_OBJECT_CLASS(klass)->finalize = finalize;
 
842
}
 
843
 
 
844
GType
 
845
lasso_idwsf2_data_service_get_type()
 
846
{
 
847
        static GType this_type = 0;
 
848
 
 
849
        if (!this_type) {
 
850
                static const GTypeInfo this_info = {
 
851
                        sizeof(LassoIdWsf2DataServiceClass),
 
852
                        NULL,
 
853
                        NULL,
 
854
                        (GClassInitFunc) class_init,
 
855
                        NULL,
 
856
                        NULL,
 
857
                        sizeof(LassoIdWsf2DataService),
 
858
                        0,
 
859
                        (GInstanceInitFunc) instance_init,
 
860
                };
 
861
 
 
862
                this_type = g_type_register_static(LASSO_TYPE_IDWSF2_PROFILE,
 
863
                                "LassoIdWsf2DataService", &this_info, 0);
 
864
        }
 
865
        return this_type;
 
866
}
 
867
 
 
868
 
 
869
/**
 
870
 * lasso_idwsf2_data_service_new:
 
871
 *
 
872
 * Creates a new #LassoIdWsf2DataService.
 
873
 *
 
874
 * Return value: a newly created #LassoIdWsf2DataService object
 
875
 **/
 
876
LassoIdWsf2DataService*
 
877
lasso_idwsf2_data_service_new(LassoServer *server)
 
878
{
 
879
        LassoIdWsf2DataService *service;
 
880
 
 
881
        g_return_val_if_fail(LASSO_IS_SERVER(server), NULL);
 
882
 
 
883
        service = g_object_new(LASSO_TYPE_IDWSF2_DATA_SERVICE, NULL);
 
884
 
 
885
        LASSO_PROFILE(service)->server = g_object_ref(server);
 
886
 
 
887
        return service;
 
888
}
 
889
 
 
890
LassoIdWsf2DataService*
 
891
lasso_idwsf2_data_service_new_full(LassoServer *server, LassoWsAddrEndpointReference *epr)
 
892
{
 
893
        LassoIdWsf2DataService *service;
 
894
 
 
895
        g_return_val_if_fail(LASSO_IS_SERVER(server), NULL);
 
896
        g_return_val_if_fail(LASSO_IS_WSA_ENDPOINT_REFERENCE(epr), NULL);
 
897
 
 
898
        service = lasso_idwsf2_data_service_new(server);
 
899
 
 
900
        service->private_data->epr = g_object_ref(epr);
 
901
 
 
902
        return service;
 
903
}
 
904