summaryrefslogtreecommitdiffstats
path: root/lasso/id-wsf
diff options
context:
space:
mode:
authorBenjamin Dauvergne <bdauvergne@entrouvert.com>2009-08-26 15:13:46 +0000
committerBenjamin Dauvergne <bdauvergne@entrouvert.com>2009-08-26 15:13:46 +0000
commit55f20515343534d990b1cd9b0986fb159b47788e (patch)
tree728dd2641371e5b62586c5413ec2e3d65ffd0519 /lasso/id-wsf
parent59926d7545ecca45086484bd9bf60ffa7d7a8b12 (diff)
downloadlasso-55f20515343534d990b1cd9b0986fb159b47788e.tar.gz
lasso-55f20515343534d990b1cd9b0986fb159b47788e.tar.xz
lasso-55f20515343534d990b1cd9b0986fb159b47788e.zip
ID-WSF: Lots of modifications
Migrate lots of code to use new utility macros. Try to simplify most code paths or to factorize with LassoWsfProfile. * lasso/id-wsf/wsf_profile.c: Add API: - lasso_wsf_profile_build_soap_response_msg to build SOAP fault for Lasso errors, - lasso_wsf_profile_set_msg_url_from_description, to set the destination URL using the chosen LassoDiscoDescription (with respect to the security mechanism), - lasso_wsf_profile_init_soap_response to initialize a response to the current request, to use in sub classes, - lasso_wsf_profile_get_remote_provider_id, retrieve the SOAP binding corresponding information, - lasso_wsf_profile_get_remote_provider, simplification of lasso_wsf_profile_get_remote_provider_id, - lasso_wsf_profile_get_soap_fault, retrieve the last setted SOAP fault, used by sub classes, - lasso_wsf_profile_set_soap_fault, set a SOAP fault, to be returned by the next call by lasso_wsf_profile_build_soap_response_msg, to use in sub classes, - lasso_wsf_profile_set/get_status_code, set/get the stored status code, to use in the next lasso_xxx_build_response_message, to use in sub classes. Change name lasso_wsf_profile_get_description_autos to lasso_wsf_profile_get_description_auto. Do not access directly the session is_dirty field (it has been sealed). * lasso/id-wsf/wsf_profile.h: Add helper macro lasso_wsf_profile_helper_set_status to set status code of an ID-WSF response message containing a Status element using the stored status code. * lasso/id-wsf/wsf_profile_private.h: Add new fields (moved public fields). Add lasso_wsf_profile_set_msg_url_from_description, lasso_wsf_profile_build_soap_fault_response_msg. * lasso/id-wsf/data_service_private.h: Remove file. * lasso/id-wsf/data_service.h: Remove all public fields. * lasso/id-wsf/data_service.c: Remove private structure. Use the equivalents LassoWsfProfile private fields. Update documentation. Use LassoWsfProfile generic functions for initializing requests. Add API lasso_data_service_get_query_item, lasso_data_service_get_answers, lasso_data_service_get_answer, lasso_data_service_get_answers_by_select, lasso_data_service_get_answer_for_item_id, lasso_data_service_add_modification. Remove lasso_data_service_need_redirect_user use equivalent function lasso_interaction_profile_service_build_redirect_response_msg. Remove lasso_data_service_get_resource_offering, lasso_data_service_set_offering. * lasso/id-wsf/discovery.c: Add documentation. Change some signatures. Remove lasso_discovery_get_description_auto. Change name of lasso_discovery_init_insert to lasso_discovery_init_modify. Add a generic lasso_discovery_process_request_msg. Add internal function lasso_discovery_init_offering, to get automatically an offering if possible. Remove useless init_from_xml. Rework lasso_discovery_build_credential implementation. overloading. Remove lasso_discovery_destroy. * lasso/id-wsf/discovery.h: Remove lasso_discovery_destroy. * lasso/id-wsf/interaction_profile_service.c: Add lasso_interaction_profile_service_build_redirect_response_msg. * lasso/id-wsf/personal_profile_service.c: Update lasso_personal_profile_service_get_email to use lasso_data_service_get_answers_by_select. * lasso/xml/dst_modify.c: make modification parameter optional to the constructor.
Diffstat (limited to 'lasso/id-wsf')
-rw-r--r--lasso/id-wsf/data_service.c1182
-rw-r--r--lasso/id-wsf/data_service.h34
-rw-r--r--lasso/id-wsf/data_service_private.h42
-rw-r--r--lasso/id-wsf/discovery.c920
-rw-r--r--lasso/id-wsf/discovery.h57
-rw-r--r--lasso/id-wsf/interaction_profile_service.c36
-rw-r--r--lasso/id-wsf/personal_profile_service.c69
-rw-r--r--lasso/id-wsf/wsf_profile.c523
-rw-r--r--lasso/id-wsf/wsf_profile.h52
-rw-r--r--lasso/id-wsf/wsf_profile_private.h10
10 files changed, 1628 insertions, 1297 deletions
diff --git a/lasso/id-wsf/data_service.c b/lasso/id-wsf/data_service.c
index 47cc1122..b25b1af9 100644
--- a/lasso/id-wsf/data_service.c
+++ b/lasso/id-wsf/data_service.c
@@ -63,7 +63,6 @@
#include <lasso/id-wsf/discovery.h>
#include <lasso/id-wsf/data_service.h>
-#include <lasso/id-wsf/data_service_private.h>
#include <lasso/xml/dst_query.h>
#include <lasso/xml/dst_query_response.h>
#include <lasso/xml/dst_modify.h>
@@ -76,129 +75,73 @@
#include <xmlsec/xmldsig.h>
#include <xmlsec/templates.h>
#include <xmlsec/crypto.h>
+#include "./wsf_profile_private.h"
extern GHashTable *dst_services_by_prefix; /* cf xml/xml.c */
-struct _LassoDataServicePrivate
-{
- gboolean dispose_has_run;
- LassoDiscoResourceOffering *offering;
- GList *credentials;
- LassoSoapFault *fault;
-};
-
static void lasso_register_idwsf_xpath_namespaces(xmlXPathContext *xpathCtx);
+static gint lasso_data_service_apply_query(LassoDataService *service,
+ LassoDstQueryResponse *query_response, xmlXPathContext *xpathCtx,
+ LassoDstQueryItem *item);
+G_GNUC_UNUSED static gint lasso_data_service_apply_queries(LassoDataService *service,
+ LassoDstQueryResponse *query_response, xmlNode *data, GList *queries);
+
+
+struct _LassoDataServicePrivate {
+ xmlNode *resource_data;
+ LassoDiscoResourceID *ResourceID;
+ LassoDiscoResourceID *EncryptedResourceID;
+};
/*****************************************************************************/
/* public methods */
/*****************************************************************************/
-gint
-lasso_data_service_add_credential(LassoDataService *service,
- LassoSamlAssertion *assertion)
-{
- service->private_data->credentials = g_list_append(
- service->private_data->credentials,
- g_object_ref(assertion));
- return 0;
-}
-
/**
* lasso_data_service_init_query
* @service: a #LassoDataService
* @select: resource selection string (typically a XPath query)
* @item_id: query item identifier (optional)
*
- * Initializes a new dst:Query request, asking for element @select (with
- * optional itemID set to @item_id). @item_id may be NULL only if the query
- * won't contain other query items.
+ * Initializes a new dst:Query request, asking for element @select (with optional itemID set to
+ * @item_id). @item_id may be NULL only if the query won't contain other query items. You must
+ * follow this constraint, it will not be checked.
*
- * If both @select and @item_id are NULL, only a skeleton request is created
- * and calls to lasso_data_service_add_query_item() will need to be done.
+ * If both @select and @item_id are NULL, only a skeleton request is created and calls to
+ * lasso_data_service_add_query_item() will need to be done.
*
* Return value: 0 on success; or a negative value otherwise.
**/
gint
lasso_data_service_init_query(LassoDataService *service, const char *select,
- const char *item_id, const char *security_mech_id)
+ const char *item_id, G_GNUC_UNUSED const char *security_mech_id)
{
- LassoWsfProfile *profile;
- LassoDstQuery *query;
- LassoDiscoResourceOffering *offering;
- LassoDiscoDescription *description;
- GList *iter;
+ LassoWsfProfile *wsf_profile = NULL;
+ LassoDstQuery *query = NULL;
+ LassoDiscoResourceOffering *offering = NULL;
+ gint rc = 0;
- profile = LASSO_WSF_PROFILE(service);
+ lasso_bad_param(DATA_SERVICE, service);
+ wsf_profile = &service->parent;
+ /* 1. build the message content */
if (select) {
query = lasso_dst_query_new(lasso_dst_query_item_new(select, item_id));
} else {
query = lasso_dst_query_new(NULL);
}
- profile->request = LASSO_NODE(query);
-
- if (service == NULL || service->private_data == NULL
- || service->private_data->offering == NULL) {
- return LASSO_PROFILE_ERROR_MISSING_RESOURCE_OFFERING;
- }
- offering = service->private_data->offering;
-
- if (offering->ServiceInstance == NULL
- || offering->ServiceInstance->ServiceType == NULL) {
- return LASSO_PROFILE_ERROR_MISSING_SERVICE_TYPE;
- }
- query->hrefServiceType = g_strdup(offering->ServiceInstance->ServiceType);
- query->prefixServiceType = lasso_get_prefix_for_dst_service_href(
- query->hrefServiceType);
- if (query->prefixServiceType == NULL) {
- return LASSO_DATA_SERVICE_ERROR_UNREGISTERED_DST;
- }
-
- if (offering->ResourceID) {
- query->ResourceID = g_object_ref(offering->ResourceID);
- } else if (offering->EncryptedResourceID) {
- query->EncryptedResourceID = g_object_ref(offering->EncryptedResourceID);
- } else {
- /* XXX: no resource id, implied:resource, etc. */
- return LASSO_ERROR_UNIMPLEMENTED;
- }
-
- lasso_wsf_profile_init_soap_request(LASSO_WSF_PROFILE(service), LASSO_NODE(query));
-
- /* Set description */
- if (security_mech_id == NULL) {
- description = LASSO_DISCO_DESCRIPTION(offering->ServiceInstance->Description->data);
- } else {
- description = lasso_discovery_get_description_auto(offering, security_mech_id);
- }
- if (description == NULL) {
- return LASSO_PROFILE_ERROR_MISSING_SERVICE_DESCRIPTION;
- }
- lasso_wsf_profile_set_description(LASSO_WSF_PROFILE(service), description);
-
- /* Set msgUrl */
- if (description->Endpoint != NULL) {
- profile->msg_url = g_strdup(description->Endpoint);
- } else {
- /* XXX: else, description->WsdlURLI, get endpoint automatically */
- return LASSO_ERROR_UNIMPLEMENTED;
- }
-
- /* Added needed credential for remote service */
- if (description->CredentialRef) {
- char *credentialRef = description->CredentialRef->data;
- iter = service->private_data->credentials;
- while (iter) {
- LassoSamlAssertion *credential = LASSO_SAML_ASSERTION(iter->data);
- if (strcmp(credentialRef, credential->AssertionID) == 0) {
- /* lasso_wsf_profile_add_saml_authentication(
- LASSO_WSF_PROFILE(service), credential); */
- iter = iter->next;
- }
- }
- }
-
- return 0;
+ lasso_assign_string(query->hrefServiceType, offering->ServiceInstance->ServiceType);
+ lasso_assign_new_string(query->prefixServiceType, lasso_get_prefix_for_dst_service_href(
+ query->hrefServiceType));
+ goto_cleanup_if_fail_with_rc (query->prefixServiceType != NULL,
+ LASSO_DATA_SERVICE_ERROR_UNREGISTERED_DST);
+
+ /* 2. build the envelope */
+ rc = lasso_wsf_profile_init_soap_request(wsf_profile, &query->parent);
+
+cleanup:
+ lasso_release_gobject(query);
+ return rc;
}
/**
@@ -207,39 +150,81 @@ lasso_data_service_init_query(LassoDataService *service, const char *select,
* @select: resource selection string (typically a XPath query)
* @item_id: query item identifier
*
- * Adds a dst:QueryItem to the current dst:Query request.
+ * Adds a dst:QueryItem to the current dst:Query request. If there are already query item in the
+ * request and @itemId is NULL, the call will fail.
*
- * Return value: a newly created #LassoDstQueryItem with the query item that
- * has been created. Note that it is internally allocated and shouldn't
- * be freed by the caller.
+ * Return value: 0 if sucessfull, an error code otherwise.
**/
-LassoDstQueryItem*
+gint
lasso_data_service_add_query_item(LassoDataService *service,
const char *select, const char *item_id)
{
- LassoDstQuery *query;
- LassoDstQueryItem *item;
-
- g_return_val_if_fail(LASSO_IS_DATA_SERVICE(service), NULL);
- g_return_val_if_fail(select != NULL, NULL);
-
- if (! LASSO_IS_DST_QUERY(LASSO_WSF_PROFILE(service)->request)) {
- return NULL;
+ LassoWsfProfile *wsf_profile;
+ LassoDstQuery *query = NULL;
+ int rc = 0;
+
+ lasso_bad_param(DATA_SERVICE, service);
+ wsf_profile = &service->parent;
+
+ lasso_return_val_if_invalid_param(DST_QUERY, wsf_profile->request,
+ LASSO_PROFILE_ERROR_MISSING_REQUEST);
+ query = (LassoDstQuery*)wsf_profile->request;
+
+ /** Check that we can add a new item */
+ if (query->QueryItem && (
+ (query->QueryItem->data &&
+ (! LASSO_IS_DST_QUERY_ITEM(query->QueryItem->data) ||
+ LASSO_DST_QUERY_ITEM(query->QueryItem->data)->itemID == NULL)) ||
+ (item_id == NULL))) {
+ return LASSO_DATA_SERVICE_CANNOT_ADD_ITEM;
}
- query = LASSO_DST_QUERY(LASSO_WSF_PROFILE(service)->request);
+ lasso_list_add_new_gobject(query->QueryItem, lasso_dst_query_item_new(select, item_id));
- if (query->QueryItem && query->QueryItem->data &&
- LASSO_DST_QUERY_ITEM(query->QueryItem->data)->itemID == NULL) {
- /* XXX: all items must have itemID if there is more than one,
- * perhaps we could generate an item id for those lacking it */
- return NULL;
- }
+ return rc;
+}
- item = lasso_dst_query_item_new(select, item_id);
- query->QueryItem = g_list_append(query->QueryItem, item);
+/**
+ * lasso_data_service_get_query_item:
+ * @service: a #LassoDataService
+ * @select: the select string of the query item to found
+ * @item_id: the item id of the query item to found
+ * @output: a #LassoDstQueryItem handle to store the result object, its reference count is not
+ * incremented.
+ *
+ * Look up the first query item in the current request matching the given criteria, @select or
+ * @item_id. At least one of the criteria must be present for the call to succeed.
+ *
+ * Return value: 0 if successful, an error code otherwise.
+ */
+gint
+lasso_data_service_get_query_item(LassoDataService *service,
+ const char *select, const char *item_id, LassoDstQueryItem **output)
+{
+ LassoDstQuery *query = NULL;
+ GList *query_items = NULL;
+ LassoWsfProfile *wsf_profile = NULL;
+ gint rc = 0;
+
+ lasso_bad_param(DATA_SERVICE, service);
+ g_return_val_if_fail(select || item_id, LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
+ wsf_profile = &service->parent;
+ lasso_extract_node_or_fail(query, wsf_profile->request, DST_QUERY, LASSO_PROFILE_ERROR_MISSING_REQUEST);
+ lasso_foreach(query_items, query->QueryItem)
+ {
+ LassoDstQueryItem *query_item = NULL;
+ lasso_extract_node_or_fail(query_item, query_items->data, DST_QUERY_ITEM, LASSO_ERROR_CAST_FAILED);
+ if ((select && g_strcmp0(select, query_item->Select)) ||
+ (item_id && g_strcmp0(item_id, query_item->itemID)))
+ {
+ if (output) {
+ lasso_assign_new_gobject(*output, query_item);
+ }
+ }
+ }
- return item;
+cleanup:
+ return rc;
}
/**
@@ -256,71 +241,35 @@ gint
lasso_data_service_process_query_msg(LassoDataService *service, const char *message,
const char *security_mech_id)
{
- LassoDstQuery *query;
- LassoWsfProfile *profile;
- int rc;
- gchar *service_type;
- GList *node_list;
- LassoSoapEnvelope *envelope;
- xmlDoc *doc;
- xmlNode *xmlnode;
-
- /* FIXME: another way to get the service type ? */
-
- g_return_val_if_fail(message != NULL, LASSO_PARAM_ERROR_INVALID_VALUE);
-
- doc = lasso_xml_parse_memory(message, strlen(message));
- if (doc == NULL) {
- return critical_error(LASSO_PROFILE_ERROR_INVALID_MSG);
- }
-
- xmlnode = xmlSecFindNode(xmlDocGetRootElement(doc), xmlSecNodeSignature,
- xmlSecDSigNs);
- if (xmlnode) {
- xmlUnlinkNode(xmlnode);
- xmlFreeNode(xmlnode);
- xmlnode = NULL;
- }
-
- envelope = LASSO_SOAP_ENVELOPE(lasso_node_new_from_xmlNode(xmlDocGetRootElement(doc)));
- if (envelope->Body == NULL || envelope->Body->any == NULL
- || envelope->Body->any->data == NULL) {
- return critical_error(LASSO_PROFILE_ERROR_INVALID_MSG);
- }
- query = LASSO_DST_QUERY(envelope->Body->any->data);
- service_type = g_strdup(query->hrefServiceType);
- lasso_release_doc(doc);
-
- profile = LASSO_WSF_PROFILE(service);
- rc = lasso_wsf_profile_process_soap_request_msg(profile, message, service_type,
- security_mech_id);
- if (rc) {
- return rc;
- }
-
- /* get provider id from soap:Header */
- for (node_list = profile->soap_envelope_request->Header->Other;
- node_list; node_list = g_list_next(node_list)) {
- LassoNode *node = node_list->data;
- if (LASSO_IS_SOAP_BINDING_PROVIDER(node)) {
- if (service->provider_id)
- g_free(service->provider_id);
- service->provider_id = g_strdup(
- LASSO_SOAP_BINDING_PROVIDER(node)->providerID);
- }
- }
-
- if (query->ResourceID) {
- service->resource_id = g_object_ref(query->ResourceID);
- } else if (query->EncryptedResourceID) {
- service->encrypted_resource_id = g_object_ref(query->EncryptedResourceID);
- } else {
- return LASSO_ERROR_UNIMPLEMENTED; /* implied ? */
- }
-
- return 0;
+ LassoWsfProfile *wsf_profile = NULL;
+ LassoDstQuery *query = NULL;
+ LassoDstQueryResponse *query_response = NULL;
+ gchar *service_type = NULL;
+ int rc = 0;
+
+ lasso_bad_param(DATA_SERVICE, service);
+ lasso_null_param(message);
+ wsf_profile = &service->parent;
+
+ rc = lasso_wsf_profile_process_soap_request_msg(wsf_profile, message, security_mech_id);
+ goto_cleanup_if_fail(! rc);
+
+ lasso_return_val_if_invalid_param(DST_QUERY, wsf_profile->request,
+ LASSO_PROFILE_ERROR_MISSING_REQUEST);
+
+ query = (LassoDstQuery*)wsf_profile->request;
+ lasso_assign_string(service_type, query->hrefServiceType);
+
+ lasso_wsf_profile_helper_assign_resource_id(service->private_data, query);
+ query_response = lasso_dst_query_response_new(NULL);
+ /* FIXME: initialize the response object */
+ rc = lasso_wsf_profile_init_soap_response(wsf_profile, LASSO_NODE(query_response));
+cleanup:
+ lasso_release_gobject(query_response);
+ return rc;
}
+
/**
* lasso_data_service_build_response_msg:
* @service: a #LassoDataService
@@ -330,190 +279,268 @@ lasso_data_service_process_query_msg(LassoDataService *service, const char *mess
* Return value: 0 on success; or a negative value otherwise.
**/
gint
-lasso_data_service_build_response_msg(LassoDataService *service)
+lasso_data_service_build_query_response_msg(LassoDataService *service)
{
- LassoWsfProfile *profile;
- LassoDstQuery *request;
- LassoDstQueryResponse *response;
- GList *iter;
- xmlDoc *doc;
- xmlXPathContext *xpathCtx;
- xmlXPathObject *xpathObj;
- LassoSoapEnvelope *envelope;
+ LassoWsfProfile *wsf_profile = NULL;
+ LassoDstQuery *request = NULL;
+ LassoDstQueryResponse *response = NULL;
+ LassoSoapEnvelope *envelope = NULL;
+ gint rc = 0;
- profile = LASSO_WSF_PROFILE(service);
- request = LASSO_DST_QUERY(profile->request);
+ lasso_bad_param(DATA_SERVICE, service);
+ wsf_profile = &service->parent;
+ lasso_extract_node_or_fail(request, wsf_profile->request, DST_QUERY, LASSO_PROFILE_ERROR_MISSING_REQUEST);
- envelope = profile->soap_envelope_response;
-
- if (service->private_data->fault != NULL) {
- envelope->Body->any = g_list_append(
- envelope->Body->any, service->private_data->fault);
- return lasso_wsf_profile_build_soap_response_msg(profile);
- }
+ envelope = wsf_profile->soap_envelope_response;
response = lasso_dst_query_response_new(
lasso_utility_status_new(LASSO_DST_STATUS_CODE_OK));
- profile->response = LASSO_NODE(response);
+ wsf_profile->response = LASSO_NODE(response);
response->prefixServiceType = g_strdup(request->prefixServiceType);
response->hrefServiceType = g_strdup(request->hrefServiceType);
envelope->Body->any = g_list_append(envelope->Body->any, response);
- doc = xmlNewDoc((xmlChar*)"1.0");
- xmlDocSetRootElement(doc, service->resource_data);
- xpathCtx = xmlXPathNewContext(doc);
- lasso_register_idwsf_xpath_namespaces(xpathCtx);
- /* XXX: needs another level, since there may be more than one <dst:Query> */
- iter = request->QueryItem;
- while (iter) {
- LassoDstQueryItem *item = iter->data;
- LassoDstData *data;
+ return lasso_wsf_profile_build_soap_response_msg(wsf_profile);
+cleanup:
+ return rc;
+}
- xpathObj = xmlXPathEvalExpression((xmlChar*)item->Select, xpathCtx);
- if (xpathObj && xpathObj->nodesetval && xpathObj->nodesetval->nodeNr) {
- xmlNode *node = xpathObj->nodesetval->nodeTab[0];
- /* XXX: assuming there is only one matching node */
- data = lasso_dst_data_new();
- data->any = g_list_append(data->any, xmlCopyNode(node, 1));
- } else if (xpathObj && xpathObj->type == XPATH_STRING) {
- data = lasso_dst_data_new();
- data->any = g_list_append(data->any,
- xmlNewText(xpathObj->stringval));
- } else {
- /* no response was found, break here */
- if (xpathObj) {
- xmlXPathFreeObject(xpathObj);
+/**
+ * lasso_data_service_get_answers:
+ * @service: a #LassoDataService object.
+ * @output: an xmlNode** pointer where to put the xmlNode* of the result
+ *
+ * Get all the xmlNode content of the first Data element of the QueryResponse message.
+ *
+ * Return value: 0 if sucessful, an error code otherwise.
+ */
+gint
+lasso_data_service_get_answers(LassoDataService *service, GList **output)
+{
+ LassoDstQueryResponse *query_response = NULL;
+ LassoDstData *data = NULL;
+ LassoWsfProfile *wsf_profile = NULL;
+ GList *datas = NULL;
+ int rc = 0;
+
+ lasso_bad_param(DATA_SERVICE, service);
+ wsf_profile = &service->parent;
+ lasso_extract_node_or_fail(query_response, wsf_profile->request, DST_QUERY_RESPONSE,
+ LASSO_PROFILE_ERROR_MISSING_REQUEST);
+
+ datas = query_response->Data;
+
+ if (datas) {
+ lasso_extract_node_or_fail(data, datas->data, DST_DATA,
+ LASSO_ERROR_CAST_FAILED);
+ }
+
+ if (data) {
+ if (output) {
+ GList *data_content = data->any;
+ lasso_release_list_of_xml_node(*output);
+ for (;data_content; data_content = g_list_next(data_content)) {
+ lasso_list_add_xml_node(*output, data_content->data);
}
- break;
}
- if (item->itemID) {
- data->itemIDRef = g_strdup(item->itemID);
- }
- response->Data = g_list_append(response->Data, data);
- xmlXPathFreeObject(xpathObj);
- xpathObj = NULL;
- iter = g_list_next(iter);
+ } else {
+ rc = LASSO_DST_ERROR_NO_DATA;
}
- xmlUnlinkNode(service->resource_data);
- xmlXPathFreeContext(xpathCtx);
- lasso_release_doc(doc);
+cleanup:
+ return rc;
+}
+/**
+ * lasso_data_service_get_answer:
+ * @service: a #LassoDataService object.
+ * @output: an xmlNode** pointer where to put the xmlNode* of the result
+ *
+ * Get the first xmlNode of the first Data element of the QueryResponse message.
+ *
+ * Return value: 0 if sucessful, an error code otherwise.
+ */
+gint
+lasso_data_service_get_answer(LassoDataService *service, xmlNode **output)
+{
+ LassoDstQueryResponse *query_response = NULL;
+ LassoDstData *data = NULL;
+ LassoWsfProfile *wsf_profile = NULL;
+ GList *datas = NULL;
+ int rc = 0;
+
+ lasso_bad_param(DATA_SERVICE, service);
+ wsf_profile = &service->parent;
+ lasso_extract_node_or_fail(query_response, wsf_profile->request, DST_QUERY_RESPONSE,
+ LASSO_PROFILE_ERROR_MISSING_REQUEST);
+
+ datas = query_response->Data;
+
+ if (datas) {
+ lasso_extract_node_or_fail(data, datas->data, DST_DATA,
+ LASSO_ERROR_CAST_FAILED);
+ }
+
+ if (data) {
+ if (output) {
+ xmlNode *first_element = NULL;
+ if (data->any) {
+ first_element = data->any->data;
+ }
+ lasso_assign_xml_node(*output, first_element);
+ }
+ } else {
+ rc = LASSO_DST_ERROR_NO_DATA;
+ }
- return lasso_wsf_profile_build_soap_response_msg(profile);
+cleanup:
+ return rc;
}
/**
- * lasso_data_service_get_answer:
+ * lasso_data_service_get_answers_by_select:
* @service: a #LassoDataService
* @select: resource selection string (typically a XPath query)
+ * @output: a GList** to store a GList* containing the result, it must be freed.
+ *
+ * Returns the answers for the specified @select request.
*
- * Returns the answer for the specified @select request.
+ * Return value: 0 if successful, an error code otheriwse
*
- * Return value: the node (libxml2 xmlNode*); or NULL if it was not found.
- * This xmlnode must be freed by caller.
**/
-xmlNode*
-lasso_data_service_get_answer(LassoDataService *service, const char *select)
+gint
+lasso_data_service_get_answers_by_select(LassoDataService *service, const char *select, GList **output)
{
- LassoDstQueryResponse *response;
+ LassoDstQuery *query = NULL;
+ LassoDstQueryResponse *query_response = NULL;
LassoDstData *data = NULL;
- GList *iter;
- char *item_id = NULL;
-
- response = LASSO_DST_QUERY_RESPONSE(LASSO_WSF_PROFILE(service)->response);
- iter = LASSO_DST_QUERY(LASSO_WSF_PROFILE(service)->request)->QueryItem;
-
- if (select == NULL) {
- /* if only one element; default to first */
- if (g_list_length(iter) > 1)
- return NULL;
- if (response->Data == NULL)
- return NULL;
- data = response->Data->data;
+ LassoWsfProfile *wsf_profile = NULL;
+ LassoDstQueryItem *query_item = NULL;
+ GList *iter = NULL;
+ GList *datas = NULL;
+ int rc = 0;
+
+ lasso_bad_param(DATA_SERVICE, service);
+ lasso_null_param(select);
+ wsf_profile = &service->parent;
+ lasso_extract_node_or_fail(query, wsf_profile->request, DST_QUERY,
+ LASSO_PROFILE_ERROR_MISSING_REQUEST);
+ lasso_extract_node_or_fail(query_response, wsf_profile->request, DST_QUERY_RESPONSE,
+ LASSO_PROFILE_ERROR_MISSING_REQUEST);
+
+ iter = query->QueryItem;
+ datas = query_response->Data;
+
+ /* one query, no need for itemID, data is the first one, or absent */
+ if (iter && iter->next == NULL) {
+ lasso_extract_node_or_fail(query_item, iter->data, DST_QUERY_ITEM,
+ LASSO_ERROR_CAST_FAILED);
+
+ if (datas) {
+ lasso_extract_node_or_fail(data, datas->data, DST_DATA,
+ LASSO_ERROR_CAST_FAILED);
+ if (g_strcmp0(select, query_item->Select) != 0) {
+ data = NULL;
+ rc = LASSO_DST_ERROR_QUERY_NOT_FOUND;
+ }
+ } else {
+ rc = LASSO_DST_ERROR_NO_DATA;
+ }
+ /* many queries */
} else {
- LassoDstQueryItem *item = NULL;
/* lookup select in query to get itemId, then get data with itemIdRef */
- /* XXX: needs another level, since there may be more than one dst:Query */
while (iter) {
- item = iter->data;
- iter = g_list_next(iter);
- if (strcmp(item->Select, select) == 0) {
+ lasso_extract_node_or_fail(query_item, iter->data, DST_QUERY_ITEM,
+ LASSO_ERROR_CAST_FAILED);
+ if (g_strcmp0(query_item->Select, select) == 0) {
break;
}
- item = NULL;
- }
-
- iter = LASSO_DST_QUERY(LASSO_WSF_PROFILE(service)->request)->QueryItem;
- if (item == NULL) {
- /* not found */
- return NULL;
+ query_item = NULL;
+ iter = g_list_next(iter);
}
- item_id = item->itemID;
- if (item_id == NULL) {
- /* item_id is not mandatory when there is only one item */
- if (response->Data == NULL)
- return NULL;
- data = response->Data->data;
+ if (query_item && ! query_item->itemID) {
+ goto_cleanup_with_rc(LASSO_DST_ERROR_MALFORMED_QUERY);
}
- iter = response->Data;
- while (iter && item_id) {
- LassoDstData *t = iter->data;
- iter = g_list_next(iter);
- if (strcmp(t->itemIDRef, item_id) == 0) {
- data = t;
+ while (datas) {
+ lasso_extract_node_or_fail(data, datas->data, DST_DATA,
+ LASSO_ERROR_CAST_FAILED);
+ if (g_strcmp0(data->itemIDRef, query_item->itemID) == 0) {
break;
}
+ data = NULL;
+ datas = g_list_next(datas);
}
- if (data == NULL) {
- /* not found */
- return NULL;
+ }
+
+ if (data) {
+ if (output) {
+ GList *data_content = data->any;
+ lasso_release_list_of_xml_node(*output);
+ for (;data_content; data_content = g_list_next(data_content)) {
+ lasso_list_add_xml_node(*output, data_content->data);
+ }
}
+ } else {
+ rc = LASSO_DST_ERROR_NO_DATA;
}
- /* XXX: there may be more than one xmlnode */
- return xmlCopyNode(data->any->data, 1);
+cleanup:
+ return rc;
}
/**
* lasso_data_service_get_answer_for_item_id:
* @service: a #LassoDataService
* @item_id: query item identifier
+ * @output: a GList** to store a GList* containing the result, it must be freed.
+ *
+ * Returns the answers for the specified @itemID request.
*
- * Returns the answer for the specified @item_id query item.
+ * Return value: 0 if successful, an error code otherwise
*
- * Return value: the node (libxml2 xmlNode*); or NULL if it was not found.
- * This xmlnode must be freed by caller.
**/
-xmlNode*
-lasso_data_service_get_answer_for_item_id(LassoDataService *service, const char *item_id)
+gint
+lasso_data_service_get_answers_by_item_id(LassoDataService *service, const char *item_id, GList **output)
{
- LassoDstQueryResponse *response;
+ LassoDstQueryResponse *query_response = NULL;
LassoDstData *data = NULL;
- GList *iter;
-
- response = LASSO_DST_QUERY_RESPONSE(LASSO_WSF_PROFILE(service)->response);
-
- iter = response->Data;
- while (iter && item_id) {
- LassoDstData *t = iter->data;
- iter = g_list_next(iter);
- if (strcmp(t->itemIDRef, item_id) == 0) {
- data = t;
+ LassoWsfProfile *wsf_profile = NULL;
+ GList *datas = NULL;
+ int rc = 0;
+
+ lasso_bad_param(DATA_SERVICE, service);
+ lasso_null_param(select);
+ wsf_profile = &service->parent;
+ lasso_extract_node_or_fail(query_response, wsf_profile->request, DST_QUERY_RESPONSE,
+ LASSO_PROFILE_ERROR_MISSING_REQUEST);
+
+ datas = query_response->Data;
+ while (datas) {
+ lasso_extract_node_or_fail(data, datas->data, DST_DATA, LASSO_ERROR_CAST_FAILED);
+ if (g_strcmp0(data->itemIDRef, item_id) == 0) {
break;
}
+ data = NULL;
+ datas = g_list_next(datas);
}
- if (data == NULL) {
- /* not found */
- return NULL;
+
+ if (data) {
+ if (output) {
+ GList *data_content = data->any;
+ lasso_release_list_of_xml_node(*output);
+ for (;data_content; data_content = g_list_next(data_content)) {
+ lasso_list_add_xml_node(*output, data_content->data);
+ }
+ }
+ } else {
+ rc = LASSO_DST_ERROR_NO_DATA;
}
- /* XXX: there may be more than one xmlnode */
- return xmlCopyNode(data->any->data, 1);
+cleanup:
+ return rc;
}
-
/**
* lasso_data_service_process_query_response_msg:
* @service: a #LassoDataService
@@ -528,53 +555,14 @@ gint
lasso_data_service_process_query_response_msg(LassoDataService *service,
const char *message)
{
- int rc;
- LassoSoapFault *fault = NULL;
- LassoIsRedirectRequest *redirect_request = NULL;
- GList *iter;
+ int rc = 0;
rc = lasso_wsf_profile_process_soap_response_msg(LASSO_WSF_PROFILE(service), message);
- if (rc) return rc;
-
- /* Process Soap Faults response */
- iter = LASSO_WSF_PROFILE(service)->soap_envelope_response->Body->any;
- while (iter) {
- if (LASSO_IS_SOAP_FAULT(iter->data) == TRUE) {
- fault = LASSO_SOAP_FAULT(iter->data);
- break;
- }
- iter = iter->next;
- }
- if (!fault)
- return 0;
-
- iter = fault->Detail->any;
- while (iter) {
- if (LASSO_IS_IS_REDIRECT_REQUEST(iter->data) == TRUE) {
- redirect_request = LASSO_IS_REDIRECT_REQUEST(iter->data);
- break;
- }
- iter = iter->next;
+ if (! rc && ! LASSO_IS_DST_QUERY_RESPONSE(service->parent.response)) {
+ rc = LASSO_PROFILE_ERROR_MISSING_RESPONSE;
}
- if (redirect_request)
- return LASSO_SOAP_FAULT_REDIRECT_REQUEST;
-
- return 0;
-}
-
-gint
-lasso_data_service_need_redirect_user(LassoDataService *service, const char *redirectUrl)
-{
- LassoSoapDetail *detail;
-
- /* Find a SOAP fault element */
- service->private_data->fault = lasso_soap_fault_new();
- service->private_data->fault->faultcode = g_strdup(LASSO_SOAP_FAULT_CODE_SERVER);
- detail = lasso_soap_detail_new();
- detail->any = g_list_append(detail->any, lasso_is_redirect_request_new(redirectUrl));
- service->private_data->fault->Detail = detail;
- return 0;
+ return rc;
}
/**
@@ -623,144 +611,173 @@ lasso_data_service_get_redirect_request_url(LassoDataService *service)
return g_strdup(redirect_request->redirectURL);
}
+/**
+ * lasso_data_service_init_modify:
+ * @service: a #LassoDataService object
+ * @select: an Select command (usually using the XPath syntax)
+ * @xmlData: the XML data for replacing the data
+ *
+ * Initialize a Data Service Template Modify request using a command to select some data, and an XML
+ * fragment to replace the selected data.
+ *
+ * Return value: 0 if successful, an error code otherwise.
+ */
gint
-lasso_data_service_init_modify(LassoDataService *service, const gchar *select,
- xmlNode *xmlData)
+lasso_data_service_init_modify(LassoDataService *service)
{
- LassoDstModification *modification;
- LassoDstNewData *newData;
- LassoDiscoResourceOffering *offering;
- LassoDiscoDescription *description = NULL;
- LassoWsfProfile *profile;
- LassoDstModify *modify;
+ LassoDiscoResourceOffering *offering = NULL;
+ LassoWsfProfile *wsf_profile = NULL;
+ LassoDstModify *modify = NULL;
+ gint rc = 0;
+
+ lasso_bad_param(DATA_SERVICE, service);
+ lasso_null_param(service);
+
+ wsf_profile = &service->parent;
+ /* Build the Modify request */
+ modify = lasso_dst_modify_new(NULL);
+
+ offering = lasso_wsf_profile_get_resource_offering(wsf_profile);
+ goto_cleanup_if_fail_with_rc (offering, LASSO_PROFILE_ERROR_MISSING_RESOURCE_OFFERING);
+ goto_cleanup_if_fail_with_rc (offering->ServiceInstance != NULL &&
+ offering->ServiceInstance->ServiceType != NULL,
+ LASSO_PROFILE_ERROR_MISSING_SERVICE_TYPE);
+ lasso_assign_string(modify->hrefServiceType, offering->ServiceInstance->ServiceType);
+ lasso_assign_new_string(modify->prefixServiceType, lasso_get_prefix_for_dst_service_href(
+ modify->hrefServiceType));
+ goto_cleanup_if_fail_with_rc (modify->prefixServiceType != NULL, LASSO_DATA_SERVICE_ERROR_UNREGISTERED_DST);
+ lasso_wsf_profile_helper_assign_resource_id(modify, offering);
+
+ rc = lasso_wsf_profile_init_soap_request(wsf_profile, &modify->parent);
+cleanup:
+ lasso_release_gobject(modify);
+ return rc;
+}
- g_return_val_if_fail(LASSO_IS_DATA_SERVICE(service),
- LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
- g_return_val_if_fail(service != NULL, LASSO_PARAM_ERROR_INVALID_VALUE);
- g_return_val_if_fail(xmlData != NULL, LASSO_PARAM_ERROR_INVALID_VALUE);
+/**
+ * lasso_data_service_add_modification:
+ * @service: a #LassoDataService object
+ * @select: a selector string
+ * @xmlData: optional NewData content
+ * @overrideAllowed: wheter to permit delete or replace of existings
+ * @notChagendSince: if not NULL, give the time (as a local time_t value) of the last known
+ * modification to the datas, it is used to permit secure concurrent accesses.
+ *
+ * Add a new modification to the current modify request. If overrideAllowed is FALSE, xmlData must
+ * absolutely be present. Refer to the ID-WSF DST 1.0 specification for the semantic of the created
+ * message.
+ *
+ * Return value: 0 if successful and the new modification object in *output, an error code
+ * otherwise.
+ */
+gint
+lasso_data_service_add_modification(LassoDataService *service, const gchar *select,
+ xmlNode *xmlData, gboolean overrideAllowed, time_t *notChangedSince,
+ LassoDstModification **output)
+{
+ LassoWsfProfile *wsf_profile = NULL;
+ LassoDstModification *modification = NULL;
+ LassoDstNewData *newData = NULL;
+ LassoDstModify *modify = NULL;
+ gint rc = 0;
+
+ lasso_bad_param(DATA_SERVICE, service);
+ lasso_null_param(select);
- profile = LASSO_WSF_PROFILE(service);
+ wsf_profile = &service->parent;
+ lasso_extract_node_or_fail(modify, wsf_profile->request, DST_MODIFY,
+ LASSO_ERROR_CAST_FAILED);
- /* init Modify */
modification = lasso_dst_modification_new(select);
newData = lasso_dst_new_data_new();
- newData->any = g_list_append(newData->any, xmlCopyNode(xmlData, 1));
- modification->NewData = newData;
-
- modify = lasso_dst_modify_new(modification);
- profile->request = LASSO_NODE(modify);
-
- if (service == NULL || service->private_data == NULL
- || service->private_data->offering == NULL) {
- return LASSO_PROFILE_ERROR_MISSING_RESOURCE_OFFERING;
- }
- offering = service->private_data->offering;
-
- if (offering->ServiceInstance == NULL
- || offering->ServiceInstance->ServiceType == NULL) {
- return LASSO_PROFILE_ERROR_MISSING_SERVICE_TYPE;
+ lasso_release_list_of_xml_node(newData->any);
+ lasso_list_add_xml_node(newData->any, xmlData);
+ lasso_assign_new_gobject(modification->NewData, newData);
+ lasso_list_add_new_gobject(modify->Modification,
+ modification);
+ modification->overrideAllowed = overrideAllowed;
+ if (notChangedSince) {
+ lasso_assign_new_string(modification->notChangedSince,
+ lasso_time_to_iso_8601_gmt(*notChangedSince));
}
- modify->hrefServiceType = g_strdup(offering->ServiceInstance->ServiceType);
- modify->prefixServiceType = lasso_get_prefix_for_dst_service_href(
- modify->hrefServiceType);
- if (modify->prefixServiceType == NULL) {
- return LASSO_DATA_SERVICE_ERROR_UNREGISTERED_DST;
- }
-
- /* get ResourceID / EncryptedResourceID */
- if (offering->ResourceID) {
- modify->ResourceID = offering->ResourceID;
- } else if (offering->EncryptedResourceID) {
- modify->EncryptedResourceID = offering->EncryptedResourceID;
- } else {
- /* XXX: no resource id, implied:resource, etc. */
- return LASSO_ERROR_UNIMPLEMENTED;
- }
-
- lasso_wsf_profile_init_soap_request(LASSO_WSF_PROFILE(service), LASSO_NODE(modify));
- /* Set description */
- if (offering->ServiceInstance != NULL && offering->ServiceInstance->Description != NULL) {
- description = LASSO_DISCO_DESCRIPTION(offering->ServiceInstance->Description->data);
- }
- if (description == NULL) {
- return LASSO_PROFILE_ERROR_MISSING_SERVICE_DESCRIPTION;
- }
- lasso_wsf_profile_set_description(LASSO_WSF_PROFILE(service), description);
-
- /* Set msgUrl */
- if (description->Endpoint != NULL) {
- profile->msg_url = g_strdup(description->Endpoint);
- } else {
- /* XXX: else, description->WsdlURLI, get endpoint automatically */
- return LASSO_ERROR_UNIMPLEMENTED;
+ if (*output) {
+ lasso_assign_gobject(*output, modification);
}
- return 0;
+cleanup:
+ return rc;
}
-LassoDstModification*
-lasso_data_service_add_modification(LassoDataService *service, const gchar *select)
+static gint
+lasso_data_service_apply_modification(G_GNUC_UNUSED LassoDataService *service, G_GNUC_UNUSED LassoDstModification *modification, G_GNUC_UNUSED xmlXPathContext *xpath_ctxt)
{
- LassoWsfProfile *profile;
- LassoDstModification *modification;
+ gint rc = 0;
+ return rc;
+}
- g_return_val_if_fail(LASSO_IS_DATA_SERVICE(service), NULL);
- g_return_val_if_fail(select != NULL, NULL);
+G_GNUC_UNUSED static gint
+lasso_data_service_apply_modifications(LassoDataService *service, GList *modifications, xmlXPathContext *xpath_ctxt)
+{
+ gint rc = 0;
+ GList *i;
- profile = LASSO_WSF_PROFILE(service);
+ lasso_foreach(i, modifications) {
+ LassoDstModification *dst_modification;
- modification = lasso_dst_modification_new(select);
- LASSO_DST_MODIFY(profile->request)->Modification = g_list_append(
- LASSO_DST_MODIFY(profile->request)->Modification, (gpointer)modification);
-
- return modification;
+ if (LASSO_IS_DST_MODIFICATION(i->data)) {
+ rc = lasso_data_service_apply_modification(service, dst_modification, xpath_ctxt);
+ // First error, stop
+ if (rc) {
+ break;
+ }
+ }
+ }
+ return rc;
}
gint
lasso_data_service_build_modify_response_msg(LassoDataService *service)
{
- LassoWsfProfile *profile;
- LassoDstModify *request;
- LassoDstModifyResponse *response;
- LassoSoapEnvelope *envelope;
- GList *iter;
- xmlNode *cur_data;
- xmlDoc *doc;
- xmlXPathContext *xpathCtx;
- xmlXPathObject *xpathObj;
- int res = 0;
+ LassoWsfProfile *wsf_profile = NULL;
+ LassoDstModify *request = NULL;
+ LassoDstModifyResponse *response = NULL;
+ GList *iter = NULL;
+ xmlNode *cur_data = NULL;
+ xmlDoc *doc = NULL;
+ xmlXPathContext *xpathCtx = NULL;
+ xmlXPathObject *xpathObj = NULL;
GList *node_to_free = NULL;
+ int res = 0;
+ xmlNode* resource_data;
+ gint rc = 0;
- profile = LASSO_WSF_PROFILE(service);
- request = LASSO_DST_MODIFY(profile->request);
-
- if (service->private_data->fault != NULL) {
- envelope = profile->soap_envelope_response;
- envelope->Body->any = g_list_append(
- envelope->Body->any, service->private_data->fault);
- return lasso_wsf_profile_build_soap_response_msg(profile);
- }
+ lasso_bad_param(DATA_SERVICE, service);
+ wsf_profile = &service->parent;
+ g_return_val_if_fail(service->private_data, LASSO_PARAM_ERROR_NON_INITIALIZED_OBJECT);
+ lasso_extract_node_or_fail(request, wsf_profile->request, DST_MODIFY,
+ LASSO_PROFILE_ERROR_MISSING_REQUEST);
+ resource_data = service->private_data->resource_data;
- if (service->resource_data == NULL) {
+ if (resource_data == NULL) {
return LASSO_DST_ERROR_MISSING_SERVICE_DATA;
} else {
- cur_data = xmlCopyNode(service->resource_data, 1);
+ cur_data = xmlCopyNode(resource_data, 1);
}
+ /* Build the Response object */
response = lasso_dst_modify_response_new(
lasso_utility_status_new(LASSO_DST_STATUS_CODE_OK));
- profile->response = LASSO_NODE(response);
- response->prefixServiceType = g_strdup(request->prefixServiceType);
- response->hrefServiceType = g_strdup(request->hrefServiceType);
- envelope = profile->soap_envelope_response;
- envelope->Body->any = g_list_append(envelope->Body->any, response);
+ lasso_assign_string(response->prefixServiceType, request->prefixServiceType);
+ lasso_assign_string(response->hrefServiceType, request->hrefServiceType);
+ /* Create the XPath workbench */
doc = xmlNewDoc((xmlChar*)"1.0");
xmlDocSetRootElement(doc, cur_data);
xpathCtx = xmlXPathNewContext(doc);
lasso_register_idwsf_xpath_namespaces(xpathCtx);
+ /* Apply modifications */
for (iter = request->Modification; iter != NULL; iter = g_list_next(iter)) {
LassoDstModification *modification = iter->data;
xmlNode *newNode = modification->NewData->any->data;
@@ -791,61 +808,54 @@ lasso_data_service_build_modify_response_msg(LassoDataService *service)
if (res == 0 && doc->children != NULL) {
/* Save new service resource data */
xmlNode *root = xmlDocGetRootElement(doc);
- xmlFreeNode(service->resource_data);
- service->resource_data = xmlCopyNode(root,1);
+ lasso_assign_xml_node(service->private_data->resource_data, root);
}
+ rc = lasso_wsf_profile_build_soap_response_msg(wsf_profile);
+cleanup:
xmlXPathFreeContext(xpathCtx);
g_list_foreach(node_to_free, (GFunc)xmlFreeNode, NULL);
lasso_release_doc(doc);
lasso_release_list(node_to_free);
-
- return lasso_wsf_profile_build_soap_response_msg(profile);
+ return rc;
}
+/**
+ * lasso_data_service_process_modify_msg:
+ * @service: a #LassoDataService object
+ * @modify_soap_msg: the SOAP request string
+ * @security_mech_id: the security mechanism to apply
+ *
+ * Parse the given request message, and initialize needed structures.
+ *
+ * Return value: 0 if successful, an error code otherwise.
+ */
gint
lasso_data_service_process_modify_msg(LassoDataService *service,
const gchar *modify_soap_msg, const gchar *security_mech_id)
{
- LassoDstModify *modify;
- LassoWsfProfile *profile;
- LassoSoapEnvelope *envelope;
- xmlDoc *doc;
- int rc;
- gchar *service_type;
-
-
- doc = lasso_xml_parse_memory(modify_soap_msg, strlen(modify_soap_msg));
- if (doc == NULL) {
- return critical_error(LASSO_PROFILE_ERROR_INVALID_MSG);
- }
-
- envelope = LASSO_SOAP_ENVELOPE(lasso_node_new_from_xmlNode(xmlDocGetRootElement(doc)));
- if (envelope->Body == NULL || envelope->Body->any == NULL
- || envelope->Body->any->data == NULL) {
- return critical_error(LASSO_PROFILE_ERROR_INVALID_MSG);
- }
-
- modify = LASSO_DST_MODIFY(envelope->Body->any->data);
- service_type = g_strdup(modify->hrefServiceType);
- lasso_release_doc(doc);
-
- profile = LASSO_WSF_PROFILE(service);
- rc = lasso_wsf_profile_process_soap_request_msg(profile, modify_soap_msg, service_type,
- security_mech_id);
- if (rc) {
- return rc;
- }
-
- if (modify->ResourceID) {
- service->resource_id = g_object_ref(modify->ResourceID);
- } else if (modify->EncryptedResourceID) {
- service->encrypted_resource_id = g_object_ref(modify->EncryptedResourceID);
- } else {
- return LASSO_ERROR_UNIMPLEMENTED; /* implied ? */
- }
-
- return 0;
+ LassoDstModify *modify = NULL;
+ LassoDstModifyResponse *modify_response = NULL;
+ LassoWsfProfile *wsf_profile = NULL;
+ int rc = 0;
+
+ lasso_bad_param(DATA_SERVICE, service);
+ lasso_null_param(modify_soap_msg);
+
+ wsf_profile = &service->parent;
+
+ rc = lasso_wsf_profile_process_soap_request_msg(wsf_profile, modify_soap_msg, security_mech_id);
+ goto_cleanup_if_fail(! rc);
+ goto_cleanup_if_fail_with_rc( ! LASSO_IS_DST_MODIFY(wsf_profile->request),
+ LASSO_PROFILE_ERROR_MISSING_RESPONSE);
+
+ modify = (LassoDstModify*)wsf_profile->request;
+ lasso_wsf_profile_helper_assign_resource_id(service->private_data, modify);
+ modify_response = lasso_dst_modify_response_new(NULL);
+ rc = lasso_wsf_profile_init_soap_response(wsf_profile, LASSO_NODE(modify_response));
+cleanup:
+ lasso_release_gobject(modify_response);
+ return rc;
}
/**
@@ -853,43 +863,25 @@ lasso_data_service_process_modify_msg(LassoDataService *service,
* @service: a #LassoDataService
* @soap_msg: the SOAP message
*
+ * Process a modify response message.
+ *
* Return value: 0 on success; or a negative value otherwise.
**/
gint
lasso_data_service_process_modify_response_msg(LassoDataService *service, const gchar *soap_msg)
{
- LassoDstModifyResponse *response;
- LassoSoapEnvelope *envelope;
+ int rc = 0;
- g_return_val_if_fail(LASSO_IS_DATA_SERVICE(service),
- LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
- g_return_val_if_fail(soap_msg != NULL, LASSO_PARAM_ERROR_INVALID_VALUE);
+ lasso_bad_param(DATA_SERVICE, service);
+ lasso_null_param(soap_msg);
- envelope = LASSO_SOAP_ENVELOPE(lasso_node_new_from_dump(soap_msg));
- if (envelope == NULL || ! envelope->Body || ! envelope->Body->any ||
- ! LASSO_IS_NODE(envelope->Body->any->data)) {
- return critical_error(LASSO_PROFILE_ERROR_INVALID_MSG);
- }
+ rc = lasso_wsf_profile_process_soap_response_msg(&service->parent, soap_msg);
- LASSO_WSF_PROFILE(service)->soap_envelope_response = envelope;
- response = envelope->Body->any->data;
- LASSO_WSF_PROFILE(service)->response = LASSO_NODE(response);
+ if (! LASSO_IS_DST_MODIFY_RESPONSE(service->parent.response)) {
+ rc = LASSO_PROFILE_ERROR_MISSING_RESPONSE;
+ }
- return 0;
-}
-
-/**
- * lasso_data_service_get_resource_offering:
- * @service: a #LassoDataService
- *
- * Gets the #LassoDiscoResourceOffering of the @service.
- *
- * Return value: the #LassoDiscoResourceOffering associated to service.
- **/
-LassoDiscoResourceOffering*
-lasso_data_service_get_resource_offering(LassoDataService *service)
-{
- return g_object_ref(service->private_data->offering);
+ return rc;
}
@@ -899,20 +891,6 @@ lasso_data_service_get_resource_offering(LassoDataService *service)
static LassoNodeClass *parent_class = NULL;
-void
-lasso_data_service_set_offering(LassoDataService *service, LassoDiscoResourceOffering *offering)
-{
- service->private_data->offering = g_object_ref(offering);
- if (offering->ResourceID != NULL) {
- service->resource_id = g_object_ref(offering->ResourceID);
- }
- if (offering->EncryptedResourceID != NULL) {
- service->encrypted_resource_id = g_object_ref(offering->EncryptedResourceID);
- }
- service->provider_id = g_strdup(offering->ServiceInstance->ProviderID);
- service->abstract_description = g_strdup(offering->Abstract);
-}
-
static void
register_xpath_namespace(gchar *prefix, gchar *href, xmlXPathContext *xpathCtx)
{
@@ -932,6 +910,119 @@ lasso_register_idwsf_xpath_namespaces(xmlXPathContext *xpathCtx)
(GHFunc)register_xpath_namespace, xpathCtx);
}
+static gint
+lasso_data_service_apply_query(LassoDataService *service, LassoDstQueryResponse *query_response, xmlXPathContext *xpathCtx, LassoDstQueryItem *item)
+{
+ gint rc = 0;
+ xmlXPathObject *xpathObj = NULL;
+ gint xpath_error_code = 0;
+
+ lasso_bad_param(DATA_SERVICE, service);
+ lasso_bad_param(DST_QUERY_RESPONSE, query_response);
+ lasso_bad_param(DST_QUERY_ITEM, item);
+
+ if (! item->Select) {
+ lasso_wsf_profile_helper_set_status(query_response, LASSO_DST_STATUS_CODE_FAILED);
+ lasso_wsf_profile_helper_set_status(query_response->Status, LASSO_DST_STATUS_CODE_MISSING_SELECT);
+ goto_cleanup_with_rc(1);
+ }
+
+ if (lasso_eval_xpath_expression(xpathCtx, item->Select, &xpathObj, &xpath_error_code)) {
+ LassoDstData *data = NULL;
+
+ /* Found zero or more node answers */
+ if (xpathObj && xpathObj->type == XPATH_NODESET){
+ int i = 0;
+
+ if (xpathObj->nodesetval && xpathObj->nodesetval->nodeNr) {
+ data = lasso_dst_data_new();
+ }
+
+ for (i = 0; xpathObj->nodesetval && i < xpathObj->nodesetval->nodeNr;
+ i++) {
+ lasso_list_add_xml_node(data->any,
+ xpathObj->nodesetval->nodeTab[i]);
+ }
+ /* Found other kind of answers, convert to string */
+ } else {
+ xmlChar *str;
+
+ data = lasso_dst_data_new();
+ str = xmlXPathCastToString(xpathObj);
+ lasso_list_add_xml_node(data->any, xmlNewText(str));
+ lasso_release_xml_string(str);
+ }
+ if (data) {
+ lasso_assign_string(data->itemIDRef, item->itemID);
+ lasso_list_add_gobject(query_response->Data, data);
+ }
+ lasso_release_gobject(data);
+ } else {
+ char *code = g_strdup_printf("LIBXML_XPATH_ERROR_%d", xpath_error_code);
+
+ lasso_wsf_profile_helper_set_status(query_response, LASSO_DST_STATUS_CODE_FAILED);
+ lasso_wsf_profile_helper_set_status(query_response->Status, LASSO_DST_STATUS_CODE_INVALID_SELECT);
+ lasso_wsf_profile_helper_set_status(query_response->Status->Status, code);
+ lasso_release_string(code);
+ goto_cleanup_with_rc(1);
+ }
+
+cleanup:
+ lasso_release_xpath_object(xpathObj);
+ return rc;
+}
+
+G_GNUC_UNUSED static gint
+lasso_data_service_apply_queries(LassoDataService *service, LassoDstQueryResponse *query_response, xmlNode *data, GList *queries)
+{
+ gint rc = 0;
+ LassoWsfProfile *wsf_profile = NULL;
+ xmlDoc *doc = NULL;
+ xmlXPathContext *xpathCtx = NULL;
+
+ lasso_bad_param(DATA_SERVICE, service);
+ g_return_val_if_fail(service->private_data, LASSO_PARAM_ERROR_NON_INITIALIZED_OBJECT);
+ wsf_profile = &service->parent;
+
+ /* 1. Check query */
+ if (queries && queries->next) {
+ GList *q = queries;
+ while (q) {
+ if (! LASSO_IS_DST_QUERY_ITEM(q->data) || !
+ LASSO_DST_QUERY_ITEM(q->data)->itemID) {
+ lasso_wsf_profile_helper_set_status(query_response,
+ LASSO_DST_STATUS_CODE_FAILED);
+ lasso_wsf_profile_helper_set_status(query_response->Status,
+ "itemID expected");
+ goto_cleanup_with_rc(LASSO_DST_ERROR_QUERY_FAILED);
+ }
+ q = g_list_next(q);
+ }
+ }
+
+ /* 1. Setup workbench */
+ doc = xmlNewDoc((xmlChar*)"1.0");
+ xmlDocSetRootElement(doc, data);
+ xpathCtx = xmlXPathNewContext(doc);
+ lasso_register_idwsf_xpath_namespaces(xpathCtx);
+
+ lasso_foreach (queries, queries) {
+ LassoDstQueryItem *item = queries->data;
+
+ goto_cleanup_if_fail_with_rc(lasso_data_service_apply_query(service, query_response,
+ xpathCtx, item) == 0, query_response->Data ?
+ LASSO_DST_ERROR_QUERY_PARTIALLY_FAILED :
+ LASSO_DST_ERROR_QUERY_FAILED);
+ }
+
+cleanup:
+ xmlUnlinkNode(service->private_data->resource_data);
+ xmlSetTreeDoc(service->private_data->resource_data, NULL);
+ lasso_release_xpath_context(xpathCtx);
+ lasso_release_doc(doc);
+
+ return rc;
+}
/*****************************************************************************/
/* overrided parent class methods */
@@ -942,11 +1033,9 @@ dispose(GObject *object)
{
LassoDataService *service = LASSO_DATA_SERVICE(object);
- if (service->private_data->dispose_has_run == TRUE)
- return;
- g_free(service->provider_id);
- service->provider_id = NULL;
- service->private_data->dispose_has_run = TRUE;
+ lasso_release_xml_node(service->private_data->resource_data);
+ lasso_release_gobject(service->private_data->ResourceID);
+ lasso_release_gobject(service->private_data->EncryptedResourceID);
G_OBJECT_CLASS(parent_class)->dispose(object);
}
@@ -954,13 +1043,8 @@ dispose(GObject *object)
static void
finalize(GObject *object)
{
- LassoDataService *service = LASSO_DATA_SERVICE(object);
- if (service->private_data->offering) {
- lasso_node_destroy(LASSO_NODE(service->private_data->offering));
- service->private_data->offering = NULL;
- }
- g_free(service->private_data);
- service->private_data = NULL;
+ g_free(((LassoDataService*)object)->private_data);
+
G_OBJECT_CLASS(parent_class)->finalize(object);
}
@@ -972,9 +1056,7 @@ finalize(GObject *object)
static void
instance_init(LassoDataService *service)
{
- service->resource_data = NULL;
service->private_data = g_new0(LassoDataServicePrivate, 1);
- service->private_data->fault = NULL;
}
static void
@@ -1054,7 +1136,7 @@ lasso_data_service_new_full(LassoServer *server, LassoDiscoResourceOffering *off
return NULL;
}
- lasso_data_service_set_offering(LASSO_DATA_SERVICE(service), offering);
+ lasso_wsf_profile_set_resource_offering(&service->parent, offering);
return service;
}
diff --git a/lasso/id-wsf/data_service.h b/lasso/id-wsf/data_service.h
index 4d6dfadd..4097ca1d 100644
--- a/lasso/id-wsf/data_service.h
+++ b/lasso/id-wsf/data_service.h
@@ -59,14 +59,6 @@ typedef struct _LassoDataServicePrivate LassoDataServicePrivate;
struct _LassoDataService {
LassoWsfProfile parent;
- /*< public >*/
- LassoDiscoResourceID *resource_id;
- LassoDiscoEncryptedResourceID *encrypted_resource_id;
- xmlNode *resource_data;
-
- gchar *provider_id;
- gchar *abstract_description;
-
/*< private >*/
LassoDataServicePrivate *private_data;
};
@@ -86,7 +78,7 @@ LASSO_EXPORT LassoDataService* lasso_data_service_new_full(LassoServer *server,
LASSO_EXPORT gint lasso_data_service_init_query(LassoDataService *service,
const char *select, const char *item_id, const char *security_mech_id);
-LASSO_EXPORT LassoDstQueryItem* lasso_data_service_add_query_item(LassoDataService *service,
+LASSO_EXPORT gint lasso_data_service_add_query_item(LassoDataService *service,
const char *select, const char *item_id);
LASSO_EXPORT gint lasso_data_service_process_query_msg(LassoDataService *service,
@@ -99,17 +91,22 @@ LASSO_EXPORT gint lasso_data_service_build_response_msg(LassoDataService *servic
LASSO_EXPORT gint lasso_data_service_process_query_response_msg(LassoDataService *service,
const char *message);
-LASSO_EXPORT xmlNode* lasso_data_service_get_answer(LassoDataService *service,
- const char *select);
+LASSO_EXPORT gint lasso_data_service_get_answer(LassoDataService *service,
+ xmlNode **output);
+
+LASSO_EXPORT gint lasso_data_service_get_answers(LassoDataService *service, GList **output);
-LASSO_EXPORT xmlNode* lasso_data_service_get_answer_for_item_id(LassoDataService *service,
- const char *item_id);
+LASSO_EXPORT gint lasso_data_service_get_answers_by_select(LassoDataService *service,
+ const char *select, GList OFTYPE(xmlNode) **output);
-LASSO_EXPORT gint lasso_data_service_init_modify(LassoDataService *service,
- const gchar *select, xmlNode *newData);
+LASSO_EXPORT gint lasso_data_service_get_answers_by_item_id(LassoDataService *service,
+ const char *item_id, GList OFTYPE(xmlNode) **output);
-LASSO_EXPORT LassoDstModification* lasso_data_service_add_modification(
- LassoDataService *service, const gchar *select);
+LASSO_EXPORT gint lasso_data_service_init_modify(LassoDataService *service);
+
+LASSO_EXPORT gint lasso_data_service_add_modification(LassoDataService *service,
+ const gchar *select, xmlNode *xmlData, gboolean overrideAllowed,
+ time_t *notChangedSince, LassoDstModification **output);
LASSO_EXPORT gint lasso_data_service_process_modify_msg(LassoDataService *service,
const gchar *soap_msg, const gchar *security_mech_id);
@@ -117,9 +114,6 @@ LASSO_EXPORT gint lasso_data_service_process_modify_msg(LassoDataService *servic
LASSO_EXPORT gint lasso_data_service_process_modify_response_msg(LassoDataService *service,
const gchar *soap_msg);
-LASSO_EXPORT gboolean lasso_data_service_need_redirect_user(LassoDataService *service,
- const char *redirectUrl);
-
LASSO_EXPORT gchar* lasso_data_service_get_redirect_request_url(LassoDataService *service);
LASSO_EXPORT LassoDiscoResourceOffering* lasso_data_service_get_resource_offering(
diff --git a/lasso/id-wsf/data_service_private.h b/lasso/id-wsf/data_service_private.h
deleted file mode 100644
index 8514b69f..00000000
--- a/lasso/id-wsf/data_service_private.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/* $Id$
- *
- * Lasso - A free implementation of the Liberty Alliance specifications.
- *
- * Copyright (C) 2004-2007 Entr'ouvert
- * http://lasso.entrouvert.org
- *
- * Authors: See AUTHORS file in top-level directory.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef __LASSO_DATA_SERVICE_PRIVATE_H__
-#define __LASSO_DATA_SERVICE_PRIVATE_H__
-
-#ifdef __cplusplus
-extern "C" {
-
-#endif /* __cplusplus */
-
-void lasso_data_service_set_offering(LassoDataService *service,
- LassoDiscoResourceOffering *offering);
-
-gint lasso_data_service_add_credential(LassoDataService *service, LassoSamlAssertion *assertion);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __LASSO_DATA_SERVICE_PRIVATE_H__ */
diff --git a/lasso/id-wsf/discovery.c b/lasso/id-wsf/discovery.c
index 5aa795d4..e044c9cb 100644
--- a/lasso/id-wsf/discovery.c
+++ b/lasso/id-wsf/discovery.c
@@ -55,6 +55,7 @@
*
* lasso_discovery_process_query_response_msg(discovery, soap_answer);
*
+ * // get an object to access the first service returned, or NULL if an error happened
* service = lasso_discovery_get_service(discovery);
* </programlisting>
* </informalexample>
@@ -67,25 +68,22 @@
#include <xmlsec/xmltree.h>
-#include <lasso/utils.h>
-#include <lasso/xml/soap_binding_correlation.h>
-#include <lasso/xml/saml_assertion.h>
-#include <lasso/xml/saml_attribute.h>
-#include <lasso/xml/saml_attribute_value.h>
-#include <lasso/xml/disco_modify.h>
-#include <lasso/xml/saml_assertion.h>
-
-#include <lasso/id-ff/server.h>
-#include <lasso/id-ff/provider.h>
-#include <lasso/id-ff/providerprivate.h>
-#include <lasso/id-ff/sessionprivate.h>
-
-#include <lasso/id-wsf/discovery.h>
-#include <lasso/id-wsf/identity.h>
-#include <lasso/id-wsf/data_service.h>
-#include <lasso/id-wsf/personal_profile_service.h>
-#include <lasso/id-wsf/wsf_profile_private.h>
-#include <lasso/id-wsf/utils.h>
+#include "../utils.h"
+#include "../xml/soap_binding_correlation.h"
+#include "../xml/saml_assertion.h"
+#include "../xml/saml_attribute.h"
+#include "../xml/saml_attribute_value.h"
+#include "../xml/disco_modify.h"
+#include "../xml/saml_assertion.h"
+
+#include "../id-ff/server.h"
+#include "../id-ff/provider.h"
+#include "../id-ff/providerprivate.h"
+#include "../id-ff/sessionprivate.h"
+
+#include "id_wsf.h"
+#include "wsf_profile_private.h"
+#include "utils.h"
#include "../utils.h"
struct _LassoDiscoveryPrivate
@@ -95,6 +93,16 @@ struct _LassoDiscoveryPrivate
char *security_mech_id;
};
+#define assign_resource_id(from,to) \
+ if ((from)->ResourceID) {\
+ lasso_assign_gobject((to)->ResourceID, (from)->ResourceID); \
+ } else if ((from)->EncryptedResourceID) {\
+ lasso_assign_gobject((to)->EncryptedResourceID, (from)->EncryptedResourceID); \
+ } else { \
+ rc = LASSO_WSF_PROFILE_ERROR_MISSING_RESOURCE_ID;\
+ goto_cleanup_if_fail(0); \
+ }
+
/*****************************************************************************/
/* static methods/functions */
/*****************************************************************************/
@@ -107,89 +115,14 @@ static void remove_registry(gchar const *service_type);
static void set_registry(gchar const *service_type, LassoWsfProfileConstructor constructor);
static LassoDsKeyInfo* lasso_discovery_build_key_info_node(LassoDiscovery *discovery,
const gchar *providerID);
-
-/* Needs REVIEW */
-static gchar*
-lasso_discovery_build_credential(LassoDiscovery *discovery, G_GNUC_UNUSED const gchar *providerId)
-{
- /* XXX: providerId parameter is never used */
-
- LassoWsfProfile *profile = NULL;
- LassoSoapHeader *header = NULL;
- LassoSoapBindingProvider *provider = NULL;
- LassoDiscoQueryResponse *response = NULL;
- LassoDiscoCredentials *credentials = NULL;
- LassoSamlAssertion *assertion = NULL;
- LassoSamlAuthenticationStatement *authentication_statement = NULL;
- LassoSamlSubject *subject = NULL;
- LassoSamlNameIdentifier *name_identifier = NULL;
- LassoSamlSubjectConfirmation *subject_confirmation = NULL;
- LassoDsKeyInfo *key_info = NULL;
- GList *iter = NULL;
- LassoProvider *our_provider =
- LASSO_PROVIDER(LASSO_WSF_PROFILE(discovery)->server);
-
- g_return_val_if_fail(LASSO_IS_DISCOVERY(discovery), NULL);
-
- /* Init assertion informations */
- assertion = lasso_saml_assertion_new();
- assertion->AssertionID = lasso_build_unique_id(32);
- assertion->MajorVersion = LASSO_SAML_MAJOR_VERSION_N;
- assertion->MinorVersion = LASSO_SAML_MINOR_VERSION_N;
- assertion->IssueInstant = lasso_get_current_time();
- assertion->Issuer = g_strdup(our_provider->ProviderID);
-
- /* Add AuthenticationStatement */
- authentication_statement = LASSO_SAML_AUTHENTICATION_STATEMENT(
- lasso_saml_authentication_statement_new());
- authentication_statement->AuthenticationInstant = lasso_get_current_time();
-
- subject = LASSO_SAML_SUBJECT(lasso_saml_subject_new());
-
- /* NameIdentifier */
- name_identifier = lasso_saml_name_identifier_new();
- name_identifier->NameQualifier = g_strdup(
- our_provider->ProviderID);
- header = LASSO_WSF_PROFILE(discovery)->soap_envelope_request->Header;
- iter = header->Other;
- while (iter) {
- if (LASSO_IS_SOAP_BINDING_PROVIDER(iter->data) == TRUE) {
- provider = LASSO_SOAP_BINDING_PROVIDER(iter->data);
- break;
- }
- }
- if (provider != NULL) {
- name_identifier->Format = g_strdup(LASSO_LIB_NAME_IDENTIFIER_FORMAT_ENTITYID);
- name_identifier->content = g_strdup(provider->providerID);
- } else {
- name_identifier->Format = g_strdup(LASSO_LIB_NAME_IDENTIFIER_FORMAT_FEDERATED);
- }
- subject->NameIdentifier = name_identifier;
-
- /* SubjectConfirmation */
- subject_confirmation = lasso_saml_subject_confirmation_new();
- lasso_list_add_string(subject_confirmation->ConfirmationMethod,
- g_strdup(LASSO_SAML_CONFIRMATION_METHOD_HOLDER_OF_KEY));
-
- /* Add public key value in credential */
- key_info = lasso_discovery_build_key_info_node(discovery, provider->providerID);
- if (key_info != NULL) {
- subject_confirmation->KeyInfo = key_info;
- }
- subject->SubjectConfirmation = subject_confirmation;
-
- /* Add the subject in the authentication statement */
- LASSO_SAML_SUBJECT_STATEMENT_ABSTRACT(authentication_statement)->Subject = subject;
- assertion->AuthenticationStatement = authentication_statement;
-
- /* Add credential to disco:QueryResponse */
- response = LASSO_DISCO_QUERY_RESPONSE(profile->response);
- credentials = lasso_disco_credentials_new();
- lasso_list_add_new_gobject(credentials->any, assertion);
- response->Credentials = credentials;
-
- return g_strdup(assertion->AssertionID);
-}
+static LassoDiscoResourceOffering* lasso_discovery_get_resource_offering_auto(
+ LassoDiscovery *discovery, const gchar *service_type);
+static gint lasso_discovery_init_resource_offering(LassoDiscovery *discovery,
+ const gchar *security_mech_id, LassoDiscoResourceOffering **output_offering);
+static gint lasso_discovery_process_modify_msg(LassoDiscovery *discovery);
+static gint lasso_discovery_process_query_msg(LassoDiscovery *discovery);
+static gint lasso_discovery_build_query_response_msg(LassoDiscovery *discovery);
+static gint lasso_discovery_build_modify_response_msg(LassoDiscovery *discovery);
/**
* lasso_discovery_add_insert_entry:
@@ -197,13 +130,13 @@ lasso_discovery_build_credential(LassoDiscovery *discovery, G_GNUC_UNUSED const
* @serviceInstance: an optional #LassoDiscoServiceInstance object
* @resourceID: the new #LassoDiscoResourceID used to create the #LassoDiscoResrouceOffering
*
- * Add an InsertEntry containing a DiscoResourceOffering for this resrouceId,
- * initialize the DiscoResourceOffering using serviceInstance.
+ * Add an #LassoDiscoInsertEntry containing a new #LassoDiscoResourceOffering, and initialize the
+ * #LassoDiscoResourceOffering using the #LassoDiscoServiceInstance and #LassoDiscoResourceId
+ * object.
*
- * Return value: the newly created #LassoDiscoInsertEntry or NULL if some
- * preconditions failed.
+ * Return value: the newly created #LassoDiscoInsertEntry or NULL if some preconditions failed.
**/
-LassoDiscoInsertEntry*
+gint
lasso_discovery_add_insert_entry(LassoDiscovery *discovery,
LassoDiscoServiceInstance *serviceInstance,
LassoDiscoResourceID *resourceId)
@@ -211,22 +144,23 @@ lasso_discovery_add_insert_entry(LassoDiscovery *discovery,
LassoDiscoModify *modify = NULL;
LassoDiscoInsertEntry *insertEntry = NULL;
LassoDiscoResourceOffering *resourceOffering = NULL;
+ int rc = 0;
- g_return_val_if_fail(LASSO_IS_DISCOVERY(discovery), NULL);
- g_return_val_if_fail(LASSO_IS_DISCO_SERVICE_INSTANCE(serviceInstance), NULL);
- g_return_val_if_fail(LASSO_IS_DISCO_RESOURCE_ID(resourceId), NULL);
-
- modify = LASSO_DISCO_MODIFY(LASSO_WSF_PROFILE(discovery)->request);
+ lasso_bad_param(DISCOVERY, discovery);
+ lasso_bad_param(DISCO_SERVICE_INSTANCE, serviceInstance);
+ lasso_bad_param(DISCO_RESOURCE_ID, resourceId);
+ g_return_val_if_fail(LASSO_IS_DISCO_MODIFY(LASSO_WSF_PROFILE(discovery)->request), LASSO_PARAM_ERROR_NON_INITIALIZED_OBJECT);
- /* ResourceOffering elements being inserted MUST NOT contain entryID attributes. */
+ lasso_extract_node_or_fail(modify, LASSO_WSF_PROFILE(discovery)->request, DISCO_MODIFY,
+ LASSO_PROFILE_ERROR_MISSING_REQUEST);
resourceOffering = lasso_disco_resource_offering_new(serviceInstance);
lasso_assign_gobject(resourceOffering->ResourceID, resourceId);
-
insertEntry = lasso_disco_insert_entry_new(resourceOffering);
+ lasso_list_add_gobject(modify->InsertEntry, insertEntry);
- lasso_list_add_new_gobject(modify->InsertEntry, insertEntry);
-
- return insertEntry;
+cleanup:
+ lasso_release_gobject(resourceOffering);
+ return rc;
}
/**
@@ -238,23 +172,24 @@ lasso_discovery_add_insert_entry(LassoDiscovery *discovery,
* to remove the resource offering identified by entryID (returned in the
* response to a Modify/InsertEntry message).
*
- * Return value: 0
+ * Return value: 0 if successful, an error code otherwise.
**/
gint
lasso_discovery_add_remove_entry(LassoDiscovery *discovery,
const gchar *entryID)
{
LassoDiscoModify *modify = NULL;
+ gint rc = 0;
- g_return_val_if_fail(LASSO_IS_DISCOVERY(discovery), LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
- g_return_val_if_fail(entryID != NULL, LASSO_PARAM_ERROR_INVALID_VALUE);
-
- modify = LASSO_DISCO_MODIFY(LASSO_WSF_PROFILE(discovery)->request);
+ lasso_bad_param(DISCOVERY, discovery);
+ lasso_null_param(entryID);
+ lasso_extract_node_or_fail(modify, LASSO_WSF_PROFILE(discovery)->request, DISCO_MODIFY,
+ LASSO_PROFILE_ERROR_MISSING_REQUEST);
- /* add RemoveEntry */
lasso_list_add_new_gobject(modify->RemoveEntry, lasso_disco_remove_entry_new(entryID));
- return 0;
+cleanup:
+ return rc;
}
/**
@@ -265,163 +200,39 @@ lasso_discovery_add_remove_entry(LassoDiscovery *discovery,
*
* Adds a request for service of @service_type to the disco:Query being built.
*
- * Return value: a newly created #LassoDiscoRequestedServiceType with the
- * request. Note that it is internally allocated and shouldn't be freed
- * by the caller.
+ * Return value: 0 if successful
**/
-LassoDiscoRequestedServiceType*
+gint
lasso_discovery_add_requested_service_type(LassoDiscovery *discovery,
const gchar *service_type,
const gchar *option)
{
- LassoWsfProfile *profile = NULL;
- LassoDiscoQuery *query = NULL;
LassoDiscoRequestedServiceType *rst = NULL;
LassoDiscoOptions *opts = NULL;
+ LassoDiscoQuery *query = NULL;
+ gint rc = 0;
- g_return_val_if_fail(LASSO_IS_DISCOVERY(discovery), NULL);
- g_return_val_if_fail(service_type != NULL, NULL);
- /* "option" parameter is optional */
-
- profile = LASSO_WSF_PROFILE(discovery);
-
- if (! LASSO_IS_DISCO_QUERY(profile->request)) {
- return NULL;
- }
- query = LASSO_DISCO_QUERY(profile->request);
+ lasso_bad_param(DISCOVERY, discovery);
+ lasso_null_param(service_type);
+ lasso_extract_node_or_fail(query, LASSO_WSF_PROFILE(discovery)->request, DISCO_QUERY,
+ LASSO_PARAM_ERROR_NON_INITIALIZED_OBJECT);
rst = lasso_disco_requested_service_type_new(service_type);
-
- /* optionals data */
if (option != NULL) {
opts = lasso_disco_options_new();
- lasso_list_add(opts->Option, (gpointer)option);
- rst->Options = opts;
+ lasso_list_add_string(opts->Option, option);
+ lasso_assign_new_gobject(rst->Options, opts);
}
-
- /* add RequestedServiceType */
lasso_list_add_new_gobject(query->RequestedServiceType, rst);
- return rst;
-}
-
-/**
- * lasso_discovery_init_modify:
- *
- * @Deprecated: Since 2.2.1, use lasso_discovery_init_insert() instead.
- **/
-gint
-lasso_discovery_init_modify(G_GNUC_UNUSED LassoDiscovery *discovery,
- G_GNUC_UNUSED LassoDiscoResourceOffering *resourceOffering,
- G_GNUC_UNUSED LassoDiscoDescription *description)
-{
- return 0;
-}
-
-static LassoDiscoResourceOffering*
-lasso_discovery_get_resource_offering_auto(LassoDiscovery *discovery, const gchar *service_type)
-{
- LassoWsfProfile *profile = LASSO_WSF_PROFILE(discovery);
- LassoDiscoResourceOffering *resource_offering = NULL;
- LassoSession *session = NULL;
- GList *assertions = NULL;
- LassoSamlAssertion *assertion = NULL;
- LassoSamlAttribute *attribute = NULL;
- LassoSamlAttributeValue *attribute_value = NULL;
- LassoDiscoResourceOffering *offering = NULL;
- GList *iter = NULL;
- GList *iter2 = NULL;
- GList *iter3 = NULL;
- GList *iter4 = NULL;
-
- if (profile->session == NULL) {
- return NULL;
- }
-
- session = profile->session;
- assertions = lasso_session_get_assertions(session, NULL);
- for (iter = assertions; iter != NULL; iter = g_list_next(iter)) {
- if (! LASSO_IS_SAML_ASSERTION(iter->data)) {
- continue;
- }
- assertion = LASSO_SAML_ASSERTION(iter->data);
- if (assertion->AttributeStatement == NULL) {
- continue;
- }
- for (iter2 = assertion->AttributeStatement->Attribute; iter2 != NULL;
- iter2 = g_list_next(iter2)) {
- if (! LASSO_IS_SAML_ATTRIBUTE(iter2->data)) {
- continue;
- }
- attribute = LASSO_SAML_ATTRIBUTE(iter2->data);
- if (strcmp(attribute->attributeName, "DiscoveryResourceOffering") != 0) {
- continue;
- }
- for (iter3 = attribute->AttributeValue; iter3 != NULL;
- iter3 = g_list_next(iter3)) {
- if (! LASSO_IS_SAML_ATTRIBUTE_VALUE(iter3->data)) {
- continue;
- }
- attribute_value = LASSO_SAML_ATTRIBUTE_VALUE(iter3->data);
- for (iter4 = attribute_value->any; iter4 != NULL;
- iter4 = g_list_next(iter4)) {
- if (! LASSO_IS_DISCO_RESOURCE_OFFERING(iter4->data)) {
- continue;
- }
- offering = LASSO_DISCO_RESOURCE_OFFERING(iter4->data);
- if (offering->ServiceInstance == NULL) {
- continue;
- }
- if (strcmp(offering->ServiceInstance->ServiceType,
- service_type) == 0) {
- resource_offering = offering;
- goto end;
- }
- }
- }
- }
- }
-
-end:
- g_list_free(assertions);
- return resource_offering;
+cleanup:
+ return rc;
}
/**
- * lasso_discovery_get_description_auto:
- *
- *
- *
- * Return value: internally allocated, don't free
- **/
-LassoDiscoDescription*
-lasso_discovery_get_description_auto(const LassoDiscoResourceOffering *offering,
- const gchar *security_mech_id)
-{
- g_return_val_if_fail(LASSO_IS_DISCO_RESOURCE_OFFERING(offering), NULL);
- g_return_val_if_fail(security_mech_id != NULL, NULL);
-
- if (offering->ServiceInstance == NULL) {
- return NULL;
- }
-
- return lasso_wsf_profile_get_description_auto(offering->ServiceInstance, security_mech_id);
-}
-
-#define assign_resource_id(from,to) \
- if ((from)->ResourceID) {\
- lasso_assign_gobject((to)->ResourceID, (from)->ResourceID); \
- } else if ((from)->EncryptedResourceID) {\
- lasso_assign_gobject((to)->EncryptedResourceID, (from)->EncryptedResourceID); \
- } else { \
- rc = LASSO_WSF_PROFILE_ERROR_MISSING_RESOURCE_ID;\
- }
-
-
-
-/**
* lasso_discovery_init_query
* @discovery: a #LassoDiscovery
+ * @security_mech_id: identifier of a wished security mechanism, or NULL if any is ok
*
* Initializes a disco:Query message.
*
@@ -433,183 +244,95 @@ lasso_discovery_init_query(LassoDiscovery *discovery, const gchar *security_mech
LassoWsfProfile *profile = NULL;
LassoDiscoQuery *query = NULL;
LassoDiscoResourceOffering *offering = NULL;
- const LassoDiscoDescription *description = NULL;
gint rc = 0;
- g_return_val_if_fail(LASSO_IS_DISCOVERY(discovery), LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
+ lasso_bad_param(DISCOVERY, discovery);
- profile = LASSO_WSF_PROFILE(discovery);
+ profile = &discovery->parent;
+ /* 1. Get an offering */
+ rc = lasso_discovery_init_resource_offering(discovery, security_mech_id, &offering);
+ goto_cleanup_if_fail(! rc);
+ /* 2. Create SOAP envelope and set profile->request */
query = lasso_disco_query_new();
- /* FIXME: we should not get it automatically,
- * we should get it from on one hand, and setup the discovery proxy
- * object with get getted resource offering. get discovery service
- * resource id from principal assertion */
- offering = lasso_discovery_get_resource_offering_auto(discovery, LASSO_DISCO_HREF);
- goto_cleanup_if_fail_with_rc(LASSO_IS_DISCO_RESOURCE_OFFERING(offering),
- LASSO_PROFILE_ERROR_MISSING_RESOURCE_OFFERING);
- lasso_wsf_profile_set_resource_offering(&discovery->parent, offering);
- rc = lasso_wsf_profile_set_security_mech_id(&discovery->parent, security_mech_id);
- if (rc)
- goto cleanup;
- /* Create SOAP envelope and set profile->request */
lasso_wsf_profile_init_soap_request(profile, LASSO_NODE(query));
assign_resource_id(offering, query);
- description = lasso_wsf_profile_get_description(&discovery->parent);
- if (description->Endpoint != NULL) {
- lasso_assign_string(profile->msg_url, description->Endpoint);
- } else {
- rc = LASSO_WSF_PROFILE_ERROR_MISSING_ENDPOINT;
- }
cleanup:
lasso_release_gobject(query);
return rc;
}
/**
- * lasso_discovery_init_insert
+ * lasso_discovery_init_modify:
* @discovery: a #LassoDiscovery
- * @new_offering: the new service offered
* @security_mech_id: the security mechanism identifier
*
* Initializes a disco Modify/InsertEntry
*
- * Return value: 0 on success; or a negative value otherwise.
+ * Return value: 0 on success; an error code otherwise.
**/
gint
-lasso_discovery_init_insert(LassoDiscovery *discovery, LassoDiscoResourceOffering *new_offering,
+lasso_discovery_init_modify(LassoDiscovery *discovery,
const char *security_mech_id)
{
LassoWsfProfile *profile = NULL;
LassoDiscoModify *modify = NULL;
LassoDiscoResourceOffering *offering = NULL;
- LassoDiscoDescription *description = NULL;
- gint rc = 0;
-
- g_return_val_if_fail(LASSO_IS_DISCOVERY(discovery), LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
- g_return_val_if_fail(LASSO_IS_DISCO_RESOURCE_OFFERING(new_offering),
- LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
-
- profile = LASSO_WSF_PROFILE(discovery);
- modify = lasso_disco_modify_new();
- lasso_wsf_profile_init_soap_request(profile, LASSO_NODE(modify));
-
- /* get discovery service resource id from principal assertion */
- offering = lasso_discovery_get_resource_offering_auto(discovery, LASSO_DISCO_HREF);
- if (! LASSO_IS_DISCO_RESOURCE_OFFERING(offering)) {
- return LASSO_PROFILE_ERROR_MISSING_RESOURCE_OFFERING;
- }
- lasso_wsf_profile_set_resource_offering(&discovery->parent, offering);
- if (security_mech_id) {
- description = lasso_discovery_get_description_auto(offering, security_mech_id);
- } else if (offering->ServiceInstance && offering->ServiceInstance->Description) {
- description = LASSO_DISCO_DESCRIPTION(offering->ServiceInstance->Description->data);
- }
- if (! LASSO_IS_DISCO_DESCRIPTION(description)) {
- return LASSO_PROFILE_ERROR_MISSING_SERVICE_DESCRIPTION;
- }
- lasso_wsf_profile_set_description(profile, description);
- assign_resource_id(offering, modify);
- lasso_node_destroy(LASSO_NODE(offering));
- lasso_list_add_new_gobject(modify->InsertEntry, lasso_disco_insert_entry_new(new_offering));
- if (description->Endpoint != NULL) {
- profile->msg_url = g_strdup(description->Endpoint);
- } /* TODO: else, description->WsdlURI, get endpoint automatically */
-
- return rc;
-}
-
-
-/**
- * lasso_discovery_init_remove
- * @discovery: a #LassoDiscovery
- * @entry_id: entry id of the resource offering to remove
- *
- * Initializes a disco Modify/RemoveEntry
- *
- * Return value: 0 on success; or a negative value otherwise.
- **/
-gint
-lasso_discovery_init_remove(LassoDiscovery *discovery, const char *entry_id)
-{
- LassoWsfProfile *profile = NULL;
- LassoDiscoModify *modify = NULL;
- LassoDiscoResourceOffering *offering = NULL;
- LassoDiscoDescription *description = NULL;
gint rc = 0;
- g_return_val_if_fail(LASSO_IS_DISCOVERY(discovery), LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
+ lasso_bad_param(DISCOVERY, discovery);
- profile = LASSO_WSF_PROFILE(discovery);
+ profile = &discovery->parent;
+ /* 1. Get an offering */
+ rc = lasso_discovery_init_resource_offering(discovery, security_mech_id, &offering);
+ goto_cleanup_if_fail (! rc);
+ /* 2. Set message content */
modify = lasso_disco_modify_new();
+ assign_resource_id(offering, modify);
lasso_wsf_profile_init_soap_request(profile, LASSO_NODE(modify));
-
- /* get discovery service resource id from principal assertion */
- offering = lasso_discovery_get_resource_offering_auto(discovery, LASSO_DISCO_HREF);
- if (! LASSO_IS_DISCO_RESOURCE_OFFERING(offering)) {
- return LASSO_PROFILE_ERROR_MISSING_RESOURCE_OFFERING;
- }
- lasso_wsf_profile_set_resource_offering(&discovery->parent, offering);
-
- description = lasso_discovery_get_description_auto(offering, LASSO_SECURITY_MECH_NULL);
- if (! LASSO_IS_DISCO_DESCRIPTION(description)) {
- return LASSO_PROFILE_ERROR_MISSING_SERVICE_DESCRIPTION;
- }
-
- /* TODO: EncryptedResourceID support */
- modify->ResourceID = g_object_ref(offering->ResourceID);
- lasso_node_destroy(LASSO_NODE(offering));
- lasso_list_add_new_gobject(modify->RemoveEntry, lasso_disco_remove_entry_new(entry_id));
- if (description->Endpoint != NULL) {
- profile->msg_url = g_strdup(description->Endpoint);
- } /* TODO: else, description->WsdlURI, get endpoint automatically */
-
+cleanup:
+ lasso_release_gobject(modify);
return rc;
}
/**
- * lasso_discovery_process_modify_msg:
- * @discovery: a #LassoDiscovery
- * @message: the disco:Modify SOAP message
+ * lasso_discovery_process_request_msg:
+ * @discovery: a #LassoDiscovery object
+ * @message: a serialized SOAP message
+ * @security_mech_id: the security mech id to use for validating authorizations
*
- * Processes a disco:Modify SOAP message. Rebuilds a request object from the
- * message and extracts ResourceID.
+ * Process a received SOAP message for the discovery service.
*
- * Return value: 0 on success; or a negative value otherwise.
- **/
+ * Return value: 0 if successfull, an error code otherwise.
+ */
gint
-lasso_discovery_process_modify_msg(LassoDiscovery *discovery, const gchar *message,
- const gchar *security_mech_id)
+lasso_discovery_process_request_msg(LassoDiscovery *discovery, const gchar *message,
+ const gchar *security_mech_id)
{
+ gint rc = 0;
LassoWsfProfile *profile = NULL;
- LassoDiscoModify *request = NULL;
- int res;
g_return_val_if_fail(LASSO_IS_DISCOVERY(discovery), LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
- g_return_val_if_fail(message != NULL, LASSO_PARAM_ERROR_INVALID_VALUE);
+ g_return_val_if_fail(message != NULL, LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
profile = LASSO_WSF_PROFILE(discovery);
-
- res = lasso_wsf_profile_process_soap_request_msg(profile, message,
- LASSO_DISCO_HREF, security_mech_id);
- if (res != 0) {
- return res;
+ rc = lasso_wsf_profile_process_soap_request_msg(profile, message,
+ security_mech_id);
+ if (rc) {
+ return rc;
}
-
- request = LASSO_DISCO_MODIFY(profile->request);
-
- if (request->ResourceID) {
- discovery->resource_id = g_object_ref(request->ResourceID);
- } else if (request->EncryptedResourceID) {
- discovery->encrypted_resource_id = g_object_ref(request->EncryptedResourceID);
+ if (LASSO_IS_DISCO_MODIFY(profile->request)) {
+ return lasso_discovery_process_modify_msg(discovery);
+ } else if (LASSO_IS_DISCO_QUERY(profile->request)) {
+ return lasso_discovery_process_query_msg(discovery);
+ } else {
+ return LASSO_PROFILE_ERROR_INVALID_MSG;
}
-
- return 0;
+ return rc;
}
-
/**
* lasso_discovery_build_modify_response_msg:
* @discovery: a #LassoDiscovery
@@ -622,12 +345,12 @@ lasso_discovery_process_modify_msg(LassoDiscovery *discovery, const gchar *messa
*
* Return value: 0 on success; or a negative value otherwise.
**/
-gint
+static gint
lasso_discovery_build_modify_response_msg(LassoDiscovery *discovery)
{
/* FIXME: Check all error cases, set the right status code,
and don't return without building a response, and
- ensure atomicity, everythin fails or everythig succeed. */
+ ensure atomicity, everything fails or everythig succeed. */
LassoWsfProfile *profile = NULL;
LassoDiscoModify *request = NULL;
@@ -647,10 +370,6 @@ lasso_discovery_build_modify_response_msg(LassoDiscovery *discovery)
profile = LASSO_WSF_PROFILE(discovery);
request = LASSO_DISCO_MODIFY(profile->request);
- if (lasso_wsf_profile_get_fault(profile)) {
- return lasso_wsf_profile_build_soap_response_msg(profile);
- }
-
if (profile->identity == NULL) {
return LASSO_PROFILE_ERROR_IDENTITY_NOT_FOUND;
}
@@ -717,8 +436,7 @@ lasso_discovery_build_modify_response_msg(LassoDiscovery *discovery)
}
if (res != 0) {
- g_free(status->code);
- status->code = g_strdup(LASSO_DISCO_STATUS_CODE_FAILED);
+ lasso_assign_string(status->code, LASSO_DISCO_STATUS_CODE_FAILED);
}
res2 = lasso_wsf_profile_build_soap_response_msg(profile);
@@ -765,48 +483,43 @@ lasso_discovery_process_modify_response_msg(LassoDiscovery *discovery, const gch
}
/**
- * lasso_discovery_process_query_msg:
- * @discovery: a #LassoDiscovery
- * @message: the disco:Query SOAP message
+ * lasso_discovery_build_response_msg:
+ * @discovery: a #LassoDiscovery object
*
- * Processes a disco:Query SOAP message. Rebuilds a request object from the
- * message and extracts ResourceID.
+ * Execute needed action for the received request, and produce a response message.
*
- * Return value: 0 on success; or a negative value otherwise.
- **/
+ * If any critical error occur, it tries to produce a SOAP fault.
+ *
+ * Return value: 0 on success; or an error code otherwise.
+ */
gint
-lasso_discovery_process_query_msg(LassoDiscovery *discovery, const gchar *message,
- const char *security_mech_id)
+lasso_discovery_build_response_msg(LassoDiscovery *discovery)
{
+ gint rc = LASSO_PROFILE_ERROR_INVALID_MSG;
LassoWsfProfile *profile = NULL;
- LassoDiscoQuery *request = NULL;
- LassoSoapEnvelope *envelope = NULL;
g_return_val_if_fail(LASSO_IS_DISCOVERY(discovery), LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
- g_return_val_if_fail(message != NULL, LASSO_PARAM_ERROR_INVALID_VALUE);
-
- profile = LASSO_WSF_PROFILE(discovery);
-
- lasso_wsf_profile_process_soap_request_msg(profile, message, LASSO_DISCO_HREF,
- security_mech_id);
+ profile = &discovery->parent;
- envelope = profile->soap_envelope_response;
- request = LASSO_DISCO_QUERY(profile->request);
+ if (G_IS_OBJECT(profile->request)) {
- if (request->ResourceID) {
- discovery->resource_id = g_object_ref(request->ResourceID);
- } else if (request->EncryptedResourceID) {
- discovery->encrypted_resource_id = g_object_ref(request->EncryptedResourceID);
- } else {
- return LASSO_ERROR_UNIMPLEMENTED; /* implied ? */
+ if (LASSO_IS_DISCO_MODIFY(profile->request)) {
+ rc = lasso_discovery_build_modify_response_msg(discovery);
+ }
+ if (LASSO_IS_DISCO_QUERY(profile->request)) {
+ rc = lasso_discovery_build_query_response_msg(discovery);
+ }
+ }
+ if (rc < 0) {
+ rc = lasso_wsf_profile_build_soap_fault_response_msg(profile, rc);
}
+ rc = lasso_wsf_profile_build_soap_response_msg(profile);
- return 0;
+ return rc;
}
-
/**
- * lasso_discovery_build_response_msg
+ * lasso_discovery_build_query_response_msg
* @discovery: a #LassoDiscovery
*
* Builds a disco:QueryResponse message; answer to the disco:Query passed to
@@ -817,8 +530,8 @@ lasso_discovery_process_query_msg(LassoDiscovery *discovery, const gchar *messag
*
* Return value: 0 on success; or a negative value otherwise.
**/
-gint
-lasso_discovery_build_response_msg(LassoDiscovery *discovery)
+static gint
+lasso_discovery_build_query_response_msg(LassoDiscovery *discovery)
{
LassoWsfProfile *profile = NULL;
LassoDiscoQuery *request = NULL;
@@ -826,7 +539,6 @@ lasso_discovery_build_response_msg(LassoDiscovery *discovery)
LassoSoapEnvelope *envelope = NULL;
LassoSoapFault *fault = NULL;
GList *offerings = NULL;
- gchar *credentialRef;
GList *iter = NULL;
GList *iter2 = NULL;
GList *iter3 = NULL;
@@ -838,10 +550,6 @@ lasso_discovery_build_response_msg(LassoDiscovery *discovery)
request = LASSO_DISCO_QUERY(profile->request);
envelope = profile->soap_envelope_response;
- if (lasso_wsf_profile_get_fault(profile)) {
- return lasso_wsf_profile_build_soap_response_msg(profile);
- }
-
if (profile->identity == NULL) {
fault = lasso_soap_fault_new();
fault->faultcode = LASSO_SOAP_FAULT_CODE_SERVER;
@@ -862,8 +570,6 @@ lasso_discovery_build_response_msg(LassoDiscovery *discovery)
/* build response */
response = lasso_disco_query_response_new(
lasso_utility_status_new(LASSO_DST_STATUS_CODE_OK));
- /* Keep refcount coherency */
- g_list_foreach(offerings, (GFunc)g_object_ref, NULL);
response->ResourceOffering = offerings;
profile->response = LASSO_NODE(response);
lasso_list_add_gobject(envelope->Body->any, response);
@@ -880,9 +586,9 @@ lasso_discovery_build_response_msg(LassoDiscovery *discovery)
while (iter3) {
if (lasso_security_mech_id_is_saml_authentication(
iter3->data) == TRUE) {
- credentialRef = lasso_discovery_build_credential(
+ gchar *credentialRef = lasso_discovery_build_credential(
discovery, NULL);
- lasso_list_add_new_gobject(description->CredentialRef, credentialRef);
+ lasso_list_add_new_string(description->CredentialRef, (void*)credentialRef);
}
iter3 = g_list_next(iter3);
}
@@ -962,7 +668,8 @@ cleanup:
* @service_type: the requested service type
*
* After a disco:query message, creates a #LassoDataService instance for the
- * requested @service_type.
+ * requested @service_type with the first resource offering found or the first resource offering
+ * matching the service type.
*
* Return value: a newly created #LassoDataService object; or NULL if an
* error occured.
@@ -971,44 +678,34 @@ LassoWsfProfile*
lasso_discovery_get_service(LassoDiscovery *discovery, const char *service_type)
{
LassoWsfProfile *profile = NULL;
- LassoDiscoQueryResponse *response;
- GList *iter;
+ LassoDiscoQueryResponse *response = NULL;
+ GList *iter = NULL;
LassoDiscoResourceOffering *offering = NULL;
- LassoWsfProfile *service;
+ LassoWsfProfile *service = NULL;
g_return_val_if_fail(LASSO_IS_DISCOVERY(discovery), NULL);
+ g_return_val_if_fail(LASSO_IS_DISCO_QUERY_RESPONSE(profile->response), NULL);
profile = LASSO_WSF_PROFILE(discovery);
-
response = LASSO_DISCO_QUERY_RESPONSE(profile->response);
- if (response == NULL) {
- /* no response; probably called at wrong time */
- return NULL;
- }
iter = response->ResourceOffering;
- if (iter == NULL) {
- return NULL; /* resource not found */
- }
- if (service_type == NULL) {
- offering = iter->data;
- } else {
- while (iter) {
- LassoDiscoResourceOffering *t = iter->data;
- iter = g_list_next(iter);
- if (t->ServiceInstance == NULL)
- continue;
- if (strcmp(t->ServiceInstance->ServiceType, service_type) == 0) {
- offering = t;
- break;
- }
+ for (;iter; iter = g_list_next(iter)) {
+ LassoDiscoResourceOffering *t = iter->data;
+
+ if (! LASSO_IS_DISCO_RESOURCE_OFFERING(t)) {
+ continue;
}
- if (offering == NULL) {
- return NULL; /* resource not found */
+ if (t->ServiceInstance == NULL)
+ continue;
+ if (service_type == NULL || strcmp(t->ServiceInstance->ServiceType, service_type) == 0) {
+ offering = t;
+ break;
}
}
- service = lasso_discovery_build_wsf_profile(discovery, offering);
-
+ if (offering) {
+ service = lasso_discovery_build_wsf_profile(discovery, offering);
+ }
return service;
}
@@ -1030,19 +727,14 @@ lasso_discovery_get_services(LassoDiscovery *discovery)
GList *iter;
LassoDiscoResourceOffering *offering;
LassoWsfProfile *service;
- GList *services;
+ GList *services = NULL;
g_return_val_if_fail(LASSO_IS_DISCOVERY(discovery), NULL);
-
profile = LASSO_WSF_PROFILE(discovery);
+ goto_cleanup_if_fail(LASSO_IS_DISCO_QUERY_RESPONSE(profile->response));
response = LASSO_DISCO_QUERY_RESPONSE(profile->response);
iter = response->ResourceOffering;
- if (iter == NULL) {
- return NULL; /* resource not found */
- }
-
- services = NULL;
while (iter) {
offering = iter->data;
iter = g_list_next(iter);
@@ -1053,6 +745,7 @@ lasso_discovery_get_services(LassoDiscovery *discovery)
lasso_list_add_new_gobject(services, service);
}
+cleanup:
return services;
}
@@ -1107,6 +800,101 @@ lasso_discovery_unregister_constructor_for_service_type(
remove_registry(service_type);
}
+/*****************************************************************************/
+/* private methods */
+/*****************************************************************************/
+
+static LassoNodeClass *parent_class = NULL;
+static GHashTable *registry = NULL;
+
+/**
+ * lasso_discovery_process_modify_msg:
+ * @discovery: a #LassoDiscovery
+ * @message: the disco:Modify SOAP message
+ *
+ * Processes a disco:Modify message. Rebuilds a request object from the
+ * message and extracts ResourceID.
+ *
+ * Return value: 0 on success; or a negative value otherwise.
+ **/
+static gint
+lasso_discovery_process_modify_msg(LassoDiscovery *discovery)
+{
+ LassoWsfProfile *profile = NULL;
+ LassoDiscoModify *request = NULL;
+ gint rc = 0;
+
+ g_return_val_if_fail(LASSO_IS_DISCOVERY(discovery), LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
+ g_return_val_if_fail(LASSO_IS_DISCO_MODIFY(LASSO_WSF_PROFILE(discovery)->request),
+ LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
+
+ profile = LASSO_WSF_PROFILE(discovery);
+ request = LASSO_DISCO_MODIFY(profile->request);
+ assign_resource_id(request, discovery);
+cleanup:
+ return rc;
+}
+
+/**
+ * lasso_discovery_process_query_msg:
+ * @discovery: a #LassoDiscovery
+ *
+ * Processes a disco:Query SOAP message. Rebuilds a request object from the
+ * message and extracts ResourceID.
+ *
+ * Return value: 0 on success; or a negative value otherwise.
+ **/
+static gint
+lasso_discovery_process_query_msg(LassoDiscovery *discovery)
+{
+ LassoWsfProfile *profile = NULL;
+ LassoDiscoQuery *request = NULL;
+ gint rc = 0;
+
+ g_return_val_if_fail(LASSO_IS_DISCOVERY(discovery), LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
+ g_return_val_if_fail(LASSO_IS_DISCO_MODIFY(LASSO_WSF_PROFILE(discovery)->request),
+ LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
+
+ profile = LASSO_WSF_PROFILE(discovery);
+ request = LASSO_DISCO_QUERY(profile->request);
+ assign_resource_id(request, discovery);
+cleanup:
+ return rc;
+}
+
+/**
+ * lasso_discovery_init_resource_offering:
+ * @discovery: a #LassoDiscovery object
+ * @security_mech_id: a security mechanism string identifier
+ * @output_offering: a pointer to a variable to hold the found resource offering
+ *
+ * Return value: 0 if successfull, an error code otherwise.
+ **/
+static gint
+lasso_discovery_init_resource_offering(LassoDiscovery *discovery,
+ const gchar *security_mech_id, LassoDiscoResourceOffering **output_offering)
+{
+ gint rc = 0;
+ LassoDiscoResourceOffering *offering = NULL;
+
+ g_return_val_if_fail(LASSO_IS_DISCOVERY(discovery), LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
+
+ if (! (offering = lasso_wsf_profile_get_resource_offering(&discovery->parent))) {
+ offering = lasso_discovery_get_resource_offering_auto(discovery, LASSO_DISCO_HREF);
+ lasso_wsf_profile_set_resource_offering(&discovery->parent, offering);
+ }
+ goto_cleanup_if_fail_with_rc(LASSO_IS_DISCO_RESOURCE_OFFERING(offering),
+ LASSO_PROFILE_ERROR_MISSING_RESOURCE_OFFERING);
+ rc = lasso_wsf_profile_set_security_mech_id(&discovery->parent, security_mech_id);
+ goto_cleanup_if_fail (! rc);
+ rc = lasso_wsf_profile_set_msg_url_from_description(&discovery->parent);
+ goto_cleanup_if_fail (! rc);
+cleanup:
+ if (output_offering) {
+ *output_offering = offering;
+ }
+ return rc;
+}
/**
* lasso_discovery_build_key_info_node:
* @discovery: a #LassoDiscovery object
@@ -1191,12 +979,180 @@ lasso_discovery_build_key_info_node(LassoDiscovery *discovery, const gchar *prov
return key_info;
}
-/*****************************************************************************/
-/* private methods */
-/*****************************************************************************/
+static LassoDiscoResourceOffering*
+lasso_discovery_get_resource_offering_auto(LassoDiscovery *discovery, const gchar *service_type)
+{
+ LassoWsfProfile *profile = LASSO_WSF_PROFILE(discovery);
+ LassoDiscoResourceOffering *resource_offering = NULL;
+ LassoSession *session = NULL;
+ GList *assertions = NULL;
+ LassoSamlAssertion *assertion = NULL;
+ LassoSamlAttribute *attribute = NULL;
+ LassoSamlAttributeValue *attribute_value = NULL;
+ LassoDiscoResourceOffering *offering = NULL;
+ GList *iter = NULL;
+ GList *iter2 = NULL;
+ GList *iter3 = NULL;
+ GList *iter4 = NULL;
-static LassoNodeClass *parent_class = NULL;
-static GHashTable *registry = NULL;
+ if (profile->session == NULL) {
+ return NULL;
+ }
+
+ session = profile->session;
+ assertions = lasso_session_get_assertions(session, NULL);
+ for (iter = assertions; iter != NULL; iter = g_list_next(iter)) {
+ if (! LASSO_IS_SAML_ASSERTION(iter->data)) {
+ continue;
+ }
+ assertion = LASSO_SAML_ASSERTION(iter->data);
+ if (assertion->AttributeStatement == NULL) {
+ continue;
+ }
+ for (iter2 = assertion->AttributeStatement->Attribute; iter2 != NULL;
+ iter2 = g_list_next(iter2)) {
+ if (! LASSO_IS_SAML_ATTRIBUTE(iter2->data)) {
+ continue;
+ }
+ attribute = LASSO_SAML_ATTRIBUTE(iter2->data);
+ if (strcmp(attribute->attributeName, "DiscoveryResourceOffering") != 0) {
+ continue;
+ }
+ for (iter3 = attribute->AttributeValue; iter3 != NULL;
+ iter3 = g_list_next(iter3)) {
+ if (! LASSO_IS_SAML_ATTRIBUTE_VALUE(iter3->data)) {
+ continue;
+ }
+ attribute_value = LASSO_SAML_ATTRIBUTE_VALUE(iter3->data);
+ for (iter4 = attribute_value->any; iter4 != NULL;
+ iter4 = g_list_next(iter4)) {
+ if (! LASSO_IS_DISCO_RESOURCE_OFFERING(iter4->data)) {
+ continue;
+ }
+ offering = LASSO_DISCO_RESOURCE_OFFERING(iter4->data);
+ if (offering->ServiceInstance == NULL) {
+ continue;
+ }
+ if (strcmp(offering->ServiceInstance->ServiceType,
+ service_type) == 0) {
+ resource_offering = offering;
+ goto cleanup;
+ }
+ }
+ }
+ }
+ }
+
+cleanup:
+ g_list_free(assertions);
+ return resource_offering;
+}
+
+/**
+ * lasso_discovery_build_credential:
+ * @discovery: an ID-WSF 1.0 discovery service object
+ * @providerId: the providerId for which the credential is build
+ *
+ * This function create a SAML assertion associating the public key of the given provider with its
+ * provider ID. This assertion will be signed by our own private key, creating a kind of
+ * certificate.
+ *
+ * Return value: the value of the attribute AssertionID of the created assertion.
+ */
+static gchar*
+lasso_discovery_build_credential(LassoDiscovery *discovery, const gchar *providerId)
+{
+ LassoWsfProfile *profile = NULL;
+ LassoSoapHeader *header = NULL;
+ LassoSoapBindingProvider *provider = NULL;
+ LassoDiscoQueryResponse *response = NULL;
+ LassoDiscoCredentials *credentials = NULL;
+ LassoSamlAssertion *assertion = NULL;
+ LassoSamlAuthenticationStatement *authentication_statement = NULL;
+ LassoSamlSubject *subject = NULL;
+ LassoSamlNameIdentifier *name_identifier = NULL;
+ LassoSamlSubjectConfirmation *subject_confirmation = NULL;
+ LassoDsKeyInfo *key_info = NULL;
+ GList *iter = NULL;
+ LassoProvider *our_provider =
+ LASSO_PROVIDER(LASSO_WSF_PROFILE(discovery)->server);
+ gchar *assertionID = NULL;
+
+ lasso_return_val_if_invalid_param(DISCOVERY, discovery, NULL);
+
+ /* Init assertion informations */
+ assertion = lasso_saml_assertion_new();
+ assertion->AssertionID = lasso_build_unique_id(32);
+ assertion->MajorVersion = LASSO_SAML_MAJOR_VERSION_N;
+ assertion->MinorVersion = LASSO_SAML_MINOR_VERSION_N;
+ assertion->IssueInstant = lasso_get_current_time();
+ lasso_assign_string(assertion->Issuer, our_provider->ProviderID);
+
+ /* Add AuthenticationStatement */
+ authentication_statement = LASSO_SAML_AUTHENTICATION_STATEMENT(
+ lasso_saml_authentication_statement_new());
+ authentication_statement->AuthenticationInstant = lasso_get_current_time();
+
+ subject = LASSO_SAML_SUBJECT(lasso_saml_subject_new());
+
+ /* NameIdentifier */
+ name_identifier = lasso_saml_name_identifier_new();
+ name_identifier->NameQualifier = g_strdup(
+ our_provider->ProviderID);
+
+ /* If no providerId was given use the one from the request */
+ if (providerId == NULL) {
+ header = LASSO_WSF_PROFILE(discovery)->soap_envelope_request->Header;
+ iter = header->Other;
+ while (iter) {
+ if (LASSO_IS_SOAP_BINDING_PROVIDER(iter->data) == TRUE) {
+ provider = LASSO_SOAP_BINDING_PROVIDER(iter->data);
+ break;
+ }
+ }
+ providerId = provider->providerID;
+ }
+
+ if (providerId != NULL) {
+ lasso_assign_string(name_identifier->Format, LASSO_LIB_NAME_IDENTIFIER_FORMAT_ENTITYID);
+ lasso_assign_string(name_identifier->content, providerId);
+ } else {
+ goto exit;
+ }
+ subject->NameIdentifier = name_identifier;
+
+ /* SubjectConfirmation */
+ subject_confirmation = lasso_saml_subject_confirmation_new();
+ lasso_list_add_string(subject_confirmation->ConfirmationMethod,
+ LASSO_SAML_CONFIRMATION_METHOD_HOLDER_OF_KEY);
+
+ /* Add public key value in credential */
+ key_info = lasso_discovery_build_key_info_node(discovery, provider->providerID);
+ if (key_info != NULL) {
+ subject_confirmation->KeyInfo = key_info;
+ }
+ subject->SubjectConfirmation = subject_confirmation;
+
+ /* Add the subject in the authentication statement */
+ LASSO_SAML_SUBJECT_STATEMENT_ABSTRACT(authentication_statement)->Subject = subject;
+ assertion->AuthenticationStatement = authentication_statement;
+
+ /* FIXME: add resource access statement */
+
+ /* Add credential to disco:QueryResponse */
+ response = LASSO_DISCO_QUERY_RESPONSE(profile->response);
+ credentials = lasso_disco_credentials_new();
+ lasso_list_add_gobject(credentials->any, assertion);
+ lasso_assign_gobject(response->Credentials, credentials);
+
+ lasso_assign_string(assertionID, assertion->AssertionID);
+
+exit:
+ lasso_release_gobject(assertion);
+ lasso_release_gobject(credentials);
+
+ return assertionID;
+}
static GHashTable *
get_constructors_registry()
@@ -1271,17 +1227,6 @@ get_xmlNode(LassoNode *node, gboolean lasso_dump)
return xmlnode;
}
-static int
-init_from_xml(LassoNode *node, xmlNode *xmlnode)
-{
- int rc;
-
- rc = parent_class->init_from_xml(node, xmlnode);
- if (rc) return rc;
-
- return 0;
-}
-
/*****************************************************************************/
/* overrided parent class methods */
/*****************************************************************************/
@@ -1324,7 +1269,6 @@ class_init(LassoDiscoveryClass *klass)
parent_class = g_type_class_peek_parent(klass);
LASSO_NODE_CLASS(klass)->get_xmlNode = get_xmlNode;
- LASSO_NODE_CLASS(klass)->init_from_xml = init_from_xml;
G_OBJECT_CLASS(klass)->dispose = dispose;
G_OBJECT_CLASS(klass)->finalize = finalize;
diff --git a/lasso/id-wsf/discovery.h b/lasso/id-wsf/discovery.h
index 4d676866..f8a77359 100644
--- a/lasso/id-wsf/discovery.h
+++ b/lasso/id-wsf/discovery.h
@@ -30,16 +30,16 @@ extern "C" {
#endif /* __cplusplus */
-#include <lasso/xml/disco_insert_entry.h>
-#include <lasso/xml/disco_modify.h>
-#include <lasso/xml/disco_modify_response.h>
-#include <lasso/xml/disco_query.h>
-#include <lasso/xml/disco_query_response.h>
-#include <lasso/xml/disco_remove_entry.h>
-#include <lasso/xml/disco_requested_service_type.h>
+#include "../xml/disco_insert_entry.h"
+#include "../xml/disco_modify.h"
+#include "../xml/disco_modify_response.h"
+#include "../xml/disco_query.h"
+#include "../xml/disco_query_response.h"
+#include "../xml/disco_remove_entry.h"
+#include "../xml/disco_requested_service_type.h"
-#include <lasso/id-wsf/wsf_profile.h>
-#include <lasso/id-wsf/data_service.h>
+#include "wsf_profile.h"
+#include "data_service.h"
#define LASSO_TYPE_DISCOVERY (lasso_discovery_get_type())
#define LASSO_DISCOVERY(obj) \
@@ -60,8 +60,8 @@ struct _LassoDiscovery {
LassoWsfProfile parent;
/*< public >*/
- LassoDiscoResourceID *resource_id;
- LassoDiscoEncryptedResourceID *encrypted_resource_id;
+ LassoDiscoResourceID *ResourceID;
+ LassoDiscoEncryptedResourceID *EncryptedResourceID;
/*< private >*/
LassoDiscoveryPrivate *private_data;
@@ -75,39 +75,31 @@ LASSO_EXPORT GType lasso_discovery_get_type(void);
LASSO_EXPORT LassoDiscovery* lasso_discovery_new(LassoServer *server);
-LASSO_EXPORT LassoDiscoInsertEntry* lasso_discovery_add_insert_entry(LassoDiscovery *discovery,
+LASSO_EXPORT void lasso_discovery_destroy(LassoDiscovery *discovery);
+
+LASSO_EXPORT gint lasso_discovery_init_modify(LassoDiscovery *discovery,
+ const char *security_mech_id);
+
+LASSO_EXPORT gint lasso_discovery_add_insert_entry(LassoDiscovery *discovery,
LassoDiscoServiceInstance *serviceInstance, LassoDiscoResourceID *resourceId);
LASSO_EXPORT gint lasso_discovery_add_remove_entry(LassoDiscovery *discovery,
const gchar *entryID);
-LASSO_EXPORT LassoDiscoRequestedServiceType* lasso_discovery_add_requested_service_type(
- LassoDiscovery *discovery, const gchar *service_type, const gchar *option);
-
-LASSO_EXPORT gint lasso_discovery_init_insert(LassoDiscovery *discovery,
- LassoDiscoResourceOffering *new_offering, const char *security_mech_id);
-
-LASSO_EXPORT gint lasso_discovery_init_remove(LassoDiscovery *discovery, const char *entry_id);
-
-LASSO_EXPORT gint lasso_discovery_build_response_msg(LassoDiscovery *discovery);
-
-LASSO_EXPORT gint lasso_discovery_build_modify_response_msg(LassoDiscovery *discovery);
-
-LASSO_EXPORT G_GNUC_DEPRECATED gint lasso_discovery_init_modify(LassoDiscovery *discovery,
- LassoDiscoResourceOffering *resourceOffering, LassoDiscoDescription *description);
-
LASSO_EXPORT gint lasso_discovery_init_query(LassoDiscovery *discovery,
const gchar *security_mech_id);
-LASSO_EXPORT gint lasso_discovery_process_modify_msg(LassoDiscovery *discovery,
+LASSO_EXPORT gint lasso_discovery_add_requested_service_type(
+ LassoDiscovery *discovery, const gchar *service_type, const gchar *option);
+
+LASSO_EXPORT gint lasso_discovery_process_request_msg(LassoDiscovery *discovery,
const gchar *message, const gchar *security_mech_id);
+LASSO_EXPORT gint lasso_discovery_build_response_msg(LassoDiscovery *discovery);
+
LASSO_EXPORT gint lasso_discovery_process_modify_response_msg(LassoDiscovery *discovery,
const gchar *message);
-LASSO_EXPORT gint lasso_discovery_process_query_msg(LassoDiscovery *discovery,
- const gchar *message, const char *security_mech_id);
-
LASSO_EXPORT gint lasso_discovery_process_query_response_msg(LassoDiscovery *discovery,
const gchar *message);
@@ -116,9 +108,6 @@ LASSO_EXPORT LassoWsfProfile* lasso_discovery_get_service(LassoDiscovery *discov
LASSO_EXPORT GList* lasso_discovery_get_services(LassoDiscovery *discovery);
-LASSO_EXPORT LassoDiscoDescription* lasso_discovery_get_description_auto(
- const LassoDiscoResourceOffering *offering, const gchar *security_mech);
-
typedef LassoWsfProfile *(*LassoWsfProfileConstructor)(LassoServer *server,
LassoDiscoResourceOffering *offering);
diff --git a/lasso/id-wsf/interaction_profile_service.c b/lasso/id-wsf/interaction_profile_service.c
index 19d93e23..8136680b 100644
--- a/lasso/id-wsf/interaction_profile_service.c
+++ b/lasso/id-wsf/interaction_profile_service.c
@@ -22,8 +22,13 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "../xml/private.h"
-#include <lasso/id-wsf/interaction_profile_service.h>
+#include "./interaction_profile_service.h"
+#include "./wsf_profile.h"
+#include "../xml/soap_detail.h"
+#include "../xml/soap_fault.h"
+#include "../xml/is_redirect_request.h"
+//#include "../xml/private.h"
+#include "../utils.h"
struct _LassoInteractionProfileServicePrivate
{
@@ -74,6 +79,33 @@ lasso_interaction_profile_service_process_response_msg(LassoInteractionProfileSe
return 0;
}
+/**
+ * lasso_interaction_profile_service_build_redirect_response_msg:
+ * @profile: a #LassoWsfProfile
+ * @redirect_url: an #xmlChar string containing an HTTP url for interaction with the user
+ *
+ * The redirect_url must contain a way for the interaction service to link this interaction with the
+ * current request, usually it is the xml:id of the original request.
+ *
+ * Return value: 0 if successful, an error code otherwise.
+ */
+gint
+lasso_interaction_profile_service_build_redirect_response_msg(LassoWsfProfile *profile, char *redirect_url)
+{
+ LassoSoapDetail *detail = NULL;
+ LassoSoapFault *fault = NULL;
+
+ lasso_bad_param(WSF_PROFILE, profile);
+
+ detail = lasso_soap_detail_new();
+ fault = lasso_soap_fault_new();
+ lasso_assign_new_gobject(fault->Detail, detail);
+ lasso_assign_string(fault->faultcode, LASSO_SOAP_FAULT_CODE_SERVER);
+ lasso_list_add_new_gobject(detail->any, lasso_is_redirect_request_new(redirect_url));
+
+ return lasso_wsf_profile_init_soap_response(profile, &fault->parent);
+}
+
/*****************************************************************************/
/* private methods */
diff --git a/lasso/id-wsf/personal_profile_service.c b/lasso/id-wsf/personal_profile_service.c
index 17b18ee9..025272f7 100644
--- a/lasso/id-wsf/personal_profile_service.c
+++ b/lasso/id-wsf/personal_profile_service.c
@@ -23,10 +23,11 @@
*/
#include "../xml/private.h"
-#include <lasso/id-wsf/personal_profile_service.h>
-#include <lasso/id-wsf/data_service_private.h>
-#include <lasso/id-wsf/discovery.h>
-
+#include "./personal_profile_service.h"
+#include "./data_service.h"
+#include "./wsf_profile_private.h"
+#include "./discovery.h"
+#include "../utils.h"
/*****************************************************************************/
/* public methods */
@@ -38,41 +39,51 @@ lasso_personal_profile_service_get_email(LassoPersonalProfileService *service)
xmlNode *xmlnode, *child;
xmlChar *msgAccount = NULL, *msgProvider = NULL;
char *email;
+ GList *answers = NULL;
+ gint rc = 0;
g_return_val_if_fail(LASSO_IS_PERSONAL_PROFILE_SERVICE(service) == TRUE, NULL);
- xmlnode = lasso_data_service_get_answer(LASSO_DATA_SERVICE(service),
- "/pp:PP/pp:MsgContact");
+ rc = lasso_data_service_get_answers_by_select(LASSO_DATA_SERVICE(service),
+ "/pp:PP/pp:MsgContact", &answers);
+
+ lasso_foreach(answers, answers)
+ {
+ xmlnode = (xmlNode*)answers->data;
+ child = xmlnode->children;
+ while (child != NULL) {
+ if (child->type != XML_ELEMENT_NODE) {
+ child = child->next;
+ continue;
+ }
+
+ if (strcmp((char *)child->name, "MsgAccount") == 0) {
+ msgAccount = xmlNodeGetContent(child);
+ } else if (strcmp((char *)child->name, "MsgProvider") == 0) {
+ msgProvider = xmlNodeGetContent(child);
+ }
+
+ if (msgAccount != NULL && msgProvider != NULL) {
+ break;
+ }
- child = xmlnode->children;
- while (child != NULL) {
- if (child->type != XML_ELEMENT_NODE) {
child = child->next;
- continue;
- }
-
- if (strcmp((char *)child->name, "MsgAccount") == 0) {
- msgAccount = xmlNodeGetContent(child);
- } else if (strcmp((char *)child->name, "MsgProvider") == 0) {
- msgProvider = xmlNodeGetContent(child);
}
- if (msgAccount != NULL && msgProvider != NULL) {
+ if (msgAccount && msgProvider) {
+ email = g_strdup_printf("%s@%s", msgAccount, msgProvider);
break;
+ } else {
+ email = NULL;
}
-
- child = child->next;
- }
-
- if (msgAccount && msgProvider) {
- email = g_strdup_printf("%s@%s", msgAccount, msgProvider);
- } else {
- email = NULL;
+ lasso_release_xml_string(msgAccount);
+ lasso_release_xml_string(msgProvider);
+ lasso_release_xml_node(xmlnode);
}
- xmlFree(msgAccount);
- xmlFree(msgProvider);
- xmlFreeNode(xmlnode);
+ lasso_release_xml_string(msgAccount);
+ lasso_release_xml_string(msgProvider);
+ lasso_release_xml_node(xmlnode);
return email;
}
@@ -131,7 +142,7 @@ lasso_personal_profile_service_new_full(LassoServer *server, LassoDiscoResourceO
return NULL;
}
- lasso_data_service_set_offering(LASSO_DATA_SERVICE(service), offering);
+ lasso_wsf_profile_set_resource_offering(&service->parent.parent, offering);
return service;
}
diff --git a/lasso/id-wsf/wsf_profile.c b/lasso/id-wsf/wsf_profile.c
index 8d153aec..e927db31 100644
--- a/lasso/id-wsf/wsf_profile.c
+++ b/lasso/id-wsf/wsf_profile.c
@@ -34,37 +34,42 @@
#include "../utils.h"
-#include <lasso/id-wsf/wsf_profile.h>
-#include <lasso/id-wsf/wsf_profile_private.h>
-#include <lasso/id-wsf/discovery.h>
-#include <lasso/id-wsf/utils.h>
-#include <lasso/xml/disco_modify.h>
-#include <lasso/xml/soap_fault.h>
-#include <lasso/xml/soap_binding_correlation.h>
-#include <lasso/xml/soap_binding_provider.h>
-#include <lasso/xml/soap_binding_processing_context.h>
-#include <lasso/xml/wsse_security.h>
-#include <lasso/xml/saml_assertion.h>
-#include <lasso/xml/saml_authentication_statement.h>
-#include <lasso/xml/saml_subject_statement_abstract.h>
-#include <lasso/xml/saml_subject.h>
-#include <lasso/xml/ds_key_info.h>
-#include <lasso/xml/ds_key_value.h>
-#include <lasso/xml/ds_rsa_key_value.h>
-#include <lasso/xml/soap_fault.h>
-#include <lasso/xml/soap_detail.h>
-#include <lasso/xml/is_redirect_request.h>
-
-
-#include <lasso/id-ff/server.h>
-#include <lasso/id-ff/providerprivate.h>
-#include <lasso/id-ff/sessionprivate.h>
+#include "wsf_profile.h"
+#include "wsf_profile_private.h"
+#include "discovery.h"
+#include "utils.h"
+#include "../xml/disco_modify.h"
+#include "../xml/soap_fault.h"
+#include "../xml/soap_binding_correlation.h"
+#include "../xml/soap_binding_provider.h"
+#include "../xml/soap_binding_processing_context.h"
+#include "../xml/wsse_security.h"
+#include "../xml/saml_assertion.h"
+#include "../xml/saml_authentication_statement.h"
+#include "../xml/saml_subject_statement_abstract.h"
+#include "../xml/saml_subject.h"
+#include "../xml/ds_key_info.h"
+#include "../xml/ds_key_value.h"
+#include "../xml/ds_rsa_key_value.h"
+#include "../xml/soap_fault.h"
+#include "../xml/soap_detail.h"
+#include "../xml/is_redirect_request.h"
+
+
+#include "../id-ff/server.h"
+#include "../id-ff/providerprivate.h"
+#include "../id-ff/sessionprivate.h"
+#include "../xml/misc_text_node.h"
/*****************************************************************************/
/* private methods */
/*****************************************************************************/
static gint lasso_wsf_profile_add_saml_signature(LassoWsfProfile *wsf_profile, xmlDoc *doc);
+static LassoSoapBindingCorrelation* lasso_wsf_profile_utils_get_header_correlation(LassoSoapEnvelope
+ *envelope);
+static char* lasso_wsf_profile_utils_get_message_id(LassoSoapEnvelope *envelope);
+static char* lasso_wsf_profile_utils_get_ref_message_id(LassoSoapEnvelope *envelope);
static struct XmlSnippet schema_snippets[] = {
{ "Server", SNIPPET_NODE_IN_CHILD, G_STRUCT_OFFSET(LassoWsfProfile, server), NULL, NULL, NULL},
@@ -81,18 +86,110 @@ static struct XmlSnippet schema_snippets[] = {
{NULL, 0, 0, NULL, NULL, NULL}
};
-/*
- * lasso_wsf_profile_get_fault:
+static LassoSoapBindingCorrelation*
+lasso_wsf_profile_utils_get_header_correlation(LassoSoapEnvelope *envelope)
+{
+ LassoSoapHeader *header;
+ GList *header_list;
+
+ if (LASSO_IS_SOAP_HEADER(envelope->Header)) {
+ header = envelope->Header;
+ } else {
+ goto cleanup;
+ }
+ lasso_foreach(header_list, header->Other)
+ {
+ if (LASSO_IS_SOAP_BINDING_CORRELATION(header_list->data)) {
+ return (LassoSoapBindingCorrelation*)header_list->data;
+ }
+ }
+cleanup:
+ return NULL;
+}
+
+static char*
+lasso_wsf_profile_utils_get_ref_message_id(LassoSoapEnvelope *envelope)
+{
+ LassoSoapBindingCorrelation *correlation_header;
+
+ correlation_header = lasso_wsf_profile_utils_get_header_correlation(envelope);
+ if (! correlation_header) {
+ return NULL;
+ }
+ return correlation_header->refToMessageID;
+}
+
+static char*
+lasso_wsf_profile_utils_get_message_id(LassoSoapEnvelope *envelope)
+{
+ LassoSoapBindingCorrelation *correlation_header;
+
+ correlation_header = lasso_wsf_profile_utils_get_header_correlation(envelope);
+ if (! correlation_header) {
+ return NULL;
+ }
+ return correlation_header->messageID;
+}
+/**
+ * lasso_wsf_profile_build_soap_fault_response_msg:
* @profile: a #LassoWsfProfile
+ * @rc: an error code from Lasso
*
- * Get the current fault present in profile private datas
+ * Build a new SOAP fault, eventually fill it with the given rc code
*/
-LassoSoapFault*
-lasso_wsf_profile_get_fault(const LassoWsfProfile *profile)
+gint
+lasso_wsf_profile_build_soap_fault_response_msg(LassoWsfProfile *profile, gint rc)
{
- return profile->private_data->fault;
+ g_return_val_if_fail(LASSO_IS_WSF_PROFILE(profile), LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
+
+ lasso_assign_new_gobject(profile->response, lasso_soap_fault_new());
+ if (rc) {
+ LassoMiscTextNode *node;
+
+ if (rc == LASSO_PROFILE_ERROR_INVALID_MSG) {
+ lasso_assign_string(LASSO_SOAP_FAULT(profile->response)->faultcode,
+ LASSO_SOAP_ENV_PREFIX ":" LASSO_SOAP_FAULT_CODE_CLIENT);
+ } else {
+ lasso_assign_string(LASSO_SOAP_FAULT(profile->response)->faultcode,
+ LASSO_SOAP_ENV_PREFIX ":" LASSO_SOAP_FAULT_CODE_SERVER);
+ }
+ lasso_assign_string(LASSO_SOAP_FAULT(profile->response)->faultstring,
+ LASSO_SOAP_FAULT_STRING_SERVER);
+ lasso_assign_new_gobject(LASSO_SOAP_FAULT(profile->response)->Detail, lasso_soap_detail_new());
+ node = (LassoMiscTextNode*)lasso_misc_text_node_new();
+ lasso_assign_string(node->content, lasso_strerror(rc));
+ node->name = "LassoError";
+ node->ns_href = LASSO_LASSO_HREF;
+ node->ns_prefix = LASSO_LASSO_PREFIX;
+ }
+ return rc;
}
+/**
+ * lasso_wsf_set_msg_url_from_description:
+ * @profile: the #LassoWsfProfile object
+ *
+ * Initialize the @msgUrl attribute of the #LassoWsfProfile to the URL of the targetted web service.
+ *
+ * Return value: 0 if successful
+ */
+gint
+lasso_wsf_profile_set_msg_url_from_description(LassoWsfProfile *wsf_profile)
+{
+ const LassoDiscoDescription *description = NULL;
+ int rc = 0;
+
+ g_return_val_if_fail(LASSO_IS_WSF_PROFILE(wsf_profile),
+ LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
+
+ description = lasso_wsf_profile_get_description(wsf_profile);
+ if (description->Endpoint != NULL) {
+ lasso_assign_string(wsf_profile->msg_url, description->Endpoint);
+ } else {
+ rc = LASSO_WSF_PROFILE_ERROR_MISSING_ENDPOINT;
+ }
+ return rc;
+}
/* Documentation of g_list_find_custom say that list element is the first pointer,
* and user_data the second */
@@ -119,7 +216,7 @@ static gint
lasso_wsf_profile_comply_with_saml_authentication(LassoWsfProfile *profile)
{
LassoSoapEnvelope *soap = NULL;
- LassoSoapHeader *header; = NULL
+ LassoSoapHeader *header = NULL;
LassoWsseSecurity *wsse_security = NULL;
LassoSession *session = NULL;
const LassoDiscoDescription *description = NULL;
@@ -132,7 +229,8 @@ lasso_wsf_profile_comply_with_saml_authentication(LassoWsfProfile *profile)
description = lasso_wsf_profile_get_description(profile);
/* Lookup in the session the credential ref from the description and
* add them to the SOAP header wsse:Security. */
- /* FIXME: should we really add every credentials to the message ? */
+ /* FIXME: should we really add every credentials to the message, or only the one identifying
+ * us? */
goto_cleanup_if_fail_with_rc(description != NULL, LASSO_WSF_PROFILE_ERROR_MISSING_DESCRIPTION);
credentialRefs = description->CredentialRef;
goto_cleanup_if_fail_with_rc(credentialRefs != NULL, LASSO_WSF_PROFILE_ERROR_MISSING_CREDENTIAL_REF);
@@ -149,7 +247,7 @@ lasso_wsf_profile_comply_with_saml_authentication(LassoWsfProfile *profile)
while (credentialRefs) {
char *ref = (char*)credentialRefs->data;
xmlNode *assertion = lasso_session_get_assertion_by_id(session, ref);
- goto_cleanup_if_fail(assertion != NULL, LASSO_WSF_PROFILE_ERROR_MISSING_CREDENTIAL_REF);
+ goto_cleanup_if_fail_with_rc(assertion != NULL, LASSO_WSF_PROFILE_ERROR_MISSING_CREDENTIAL_REF);
lasso_list_add_xml_node(wsse_security->any, assertion);
credentialRefs = g_list_next(credentialRefs);
}
@@ -182,6 +280,10 @@ lasso_wsf_profile_comply_with_security_mechanism(LassoWsfProfile *profile)
if (lasso_security_mech_id_is_saml_authentication(sec_mech_id)) {
return lasso_wsf_profile_comply_with_saml_authentication(profile);
}
+ if (lasso_security_mech_id_is_bearer_authentication(sec_mech_id)) {
+ /* Same as SAML auth, add the tokens to wss:Security header */
+ return lasso_wsf_profile_comply_with_saml_authentication(profile);
+ }
if (lasso_security_mech_id_is_null_authentication(sec_mech_id)) {
return 0;
}
@@ -259,7 +361,7 @@ lasso_wsf_profile_add_credential(G_GNUC_UNUSED LassoWsfProfile *profile, G_GNUC_
}
/*
- * lasso_wsf_profile_get_description_autos:
+ * lasso_wsf_profile_get_description_auto:
* @si: a #LassoDiscoServiceInstance
* @security_mech_id: the URI of a liberty security mechanism
*
@@ -326,8 +428,8 @@ lasso_wsf_profile_set_description_from_offering(
offering->ServiceInstance->Description->data);
}
} else {
- description = lasso_discovery_get_description_auto(
- offering, security_mech_id);
+ description = lasso_wsf_profile_get_description_auto(offering->ServiceInstance,
+ security_mech_id);
}
if (description == NULL) {
return LASSO_PROFILE_ERROR_MISSING_SERVICE_DESCRIPTION;
@@ -339,10 +441,10 @@ lasso_wsf_profile_set_description_from_offering(
/**
* lasso_wsf_profile_set_security_mech_id:
* @profile: the #LassoWsfProfile object
- * @securit_mech_id: a char* string representing the chosen security mech id.
+ * @security_mech_id: a char* string representing the chosen security mech id.
*
* Set the security mechanism to use. Currently only SAML and NULL mechanism
- * are supported for authentication. Transposrt is not handled by lasso so all
+ * are supported for authentication. Transport is not handled by lasso so all
* are supported.
*
* List of supported mechanism ids:
@@ -587,7 +689,7 @@ lasso_wsf_profile_is_identity_dirty(const LassoWsfProfile *profile)
gboolean
lasso_wsf_profile_is_session_dirty(const LassoWsfProfile *profile)
{
- return (profile->session && profile->session->is_dirty);
+ return (profile->session && lasso_session_is_dirty(profile->session));
}
@@ -630,7 +732,6 @@ lasso_wsf_profile_set_session_from_dump(LassoWsfProfile *profile, const gchar *
profile->session = lasso_session_new_from_dump(dump);
if (profile->session == NULL)
return critical_error(LASSO_PROFILE_ERROR_BAD_SESSION_DUMP);
- profile->session->is_dirty = FALSE;
return 0;
}
@@ -662,7 +763,34 @@ lasso_wsf_profile_init_soap_request(LassoWsfProfile *profile, LassoNode *request
lasso_assign_new_gobject(profile->soap_envelope_request, envelope);
lasso_list_add_gobject(envelope->Body->any, request);
lasso_assign_gobject(profile->request, request);
- return lasso_wsf_profile_comply_with_security_mechanism(profile);
+ return 0;
+}
+
+/**
+ * lasso_wsf_profile_init_soap_response:
+ * @profile: a #LassoWsfProfile object
+ * @response: a #LassoNode object
+ *
+ * Build a new SOAP envelope containing response to current SOAP request
+ */
+gint
+lasso_wsf_profile_init_soap_response(LassoWsfProfile *profile, LassoNode *response)
+{
+ char *providerID = NULL;
+ LassoSoapEnvelope *envelope = NULL;
+
+ lasso_return_val_if_invalid_param(WSF_PROFILE, profile,
+ LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
+
+ if (profile->server) {
+ providerID = profile->server->parent.ProviderID;
+ }
+ envelope = lasso_wsf_profile_build_soap_envelope_internal(lasso_wsf_profile_utils_get_message_id(profile->soap_envelope_request),
+ providerID);
+ lasso_assign_new_gobject(profile->soap_envelope_response, envelope);
+ lasso_list_add_gobject(envelope->Body->any, response);
+ lasso_assign_gobject(profile->response, response);
+ return 0;
}
/**
@@ -676,7 +804,7 @@ lasso_wsf_profile_init_soap_request(LassoWsfProfile *profile, LassoNode *request
* Return value: 0 if construction is successfull.
**/
gint
-lasso_wsf_profile_build_soap_request_msg(LassoWsfProfile *profile)
+lasso_wsf_profile_build_soap_request_msg(LassoWsfProfile *wsf_profile)
{
LassoSoapEnvelope *envelope;
xmlOutputBuffer *buf;
@@ -686,33 +814,39 @@ lasso_wsf_profile_build_soap_request_msg(LassoWsfProfile *profile)
char *sec_mech_id = NULL;
int rc = 0;
- g_return_val_if_fail(LASSO_IS_WSF_PROFILE(profile), LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
- g_return_val_if_fail(LASSO_IS_SOAP_ENVELOPE(profile->soap_envelope_request),
- LASSO_SOAP_ERROR_MISSING_ENVELOPE);
+ lasso_bad_param(WSF_PROFILE, wsf_profile);
+ lasso_return_val_if_invalid_param(SOAP_ENVELOPE, wsf_profile->soap_envelope_request,
+ LASSO_SOAP_ERROR_MISSING_ENVELOPE);
- envelope = profile->soap_envelope_request;
+ rc = lasso_wsf_profile_comply_with_security_mechanism(wsf_profile);
+ goto_cleanup_if_fail(rc == 0);
+ envelope = wsf_profile->soap_envelope_request;
doc = xmlNewDoc((xmlChar*)"1.0");
envelope_node = lasso_node_get_xmlNode(LASSO_NODE(envelope), FALSE);
xmlDocSetRootElement(doc, envelope_node);
/* Sign request if necessary */
- sec_mech_id = profile->private_data->security_mech_id;
+ sec_mech_id = wsf_profile->private_data->security_mech_id;
if (lasso_security_mech_id_is_saml_authentication(sec_mech_id)) {
- rc = lasso_wsf_profile_add_saml_signature(profile, doc);
+ rc = lasso_wsf_profile_add_saml_signature(wsf_profile, doc);
if (rc != 0) {
goto cleanup;
}
+ } else if (lasso_security_mech_id_is_bearer_authentication(sec_mech_id)) {
+ // Nothing to do
} else if (lasso_security_mech_id_is_null_authentication(sec_mech_id) == FALSE) {
rc = LASSO_WSF_PROFILE_ERROR_UNSUPPORTED_SECURITY_MECHANISM;
goto cleanup;
}
+
/* Dump soap request */
handler = xmlFindCharEncodingHandler("utf-8");
buf = xmlAllocOutputBuffer(handler);
xmlNodeDumpOutput(buf, NULL, envelope_node, 0, 0, "utf-8");
xmlOutputBufferFlush(buf);
- profile->msg_body = g_strdup(
+ wsf_profile->msg_body = g_strdup(
(char*)(buf->conv ? buf->conv->content : buf->buffer->content));
lasso_release_output_buffer(buf);
+ rc = lasso_wsf_profile_set_msg_url_from_description(wsf_profile);
cleanup:
lasso_release_doc(doc);
@@ -721,65 +855,78 @@ cleanup:
/**
* lasso_wsf_profile_build_soap_response_msg:
- * @profile: the #LassoWsfProfile object
+ * @wsf_profile: a #LassoWsfProfile object
*
* Create the char* string containing XML document for the SOAP ID-WSF
* response.
*
* Return value: 0 if construction is successfull.
**/
-int
-lasso_wsf_profile_build_soap_response_msg(LassoWsfProfile *profile)
+gint
+lasso_wsf_profile_build_soap_response_msg(LassoWsfProfile *wsf_profile)
{
- LassoSoapEnvelope *envelope;
- xmlNode *soap_envelope;
- xmlDoc *doc;
- xmlOutputBuffer *buf;
- xmlCharEncodingHandler *handler;
+ LassoSoapEnvelope *envelope = NULL;
+ LassoSoapFault *soap_fault = NULL;
+ int rc = 0;
- lasso_return_val_if_invalid_param(WSF_PROFILE, profile,
- LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
+ lasso_bad_param(WSF_PROFILE, wsf_profile);
+ envelope = wsf_profile->soap_envelope_response;
+ if (! LASSO_IS_SOAP_ENVELOPE(envelope)) {
+ return LASSO_SOAP_ERROR_MISSING_ENVELOPE;
+ }
- envelope = profile->soap_envelope_response;
- doc = xmlNewDoc((xmlChar*)"1.0");
- soap_envelope = lasso_node_get_xmlNode(LASSO_NODE(envelope), TRUE);
- xmlDocSetRootElement(doc, soap_envelope);
- /* FIXME: does we need signature ? */
- /* Dump soap response */
- handler = xmlFindCharEncodingHandler("utf-8");
- buf = xmlAllocOutputBuffer(handler);
- xmlNodeDumpOutput(buf, NULL, soap_envelope, 0, 0, "utf-8");
- xmlOutputBufferFlush(buf);
- profile->msg_body = g_strdup(
- (char*)(buf->conv ? buf->conv->content : buf->buffer->content));
- xmlOutputBufferClose(buf);
- lasso_release_doc(doc);
+ /* If SOAP fault replace response by the SOAP fault */
+ if ((soap_fault = lasso_wsf_profile_get_soap_fault(wsf_profile))) {
+ LassoSoapBody *body = NULL;
+ lasso_extract_node_or_fail(body, envelope->Body, SOAP_BODY, LASSO_SOAP_ERROR_MISSING_BODY);
+ lasso_release_list_of_gobjects(body->any);
+ lasso_list_add_gobject(body->any, soap_fault);
+ }
- return 0;
+ lasso_assign_new_string(wsf_profile->msg_body,
+ lasso_node_export_to_xml((LassoNode*)envelope));
+cleanup:
+ return rc;
}
+/** FIXME: add support for security mechanisms SAML and Bearer. */
+/**
+ * lasso_wsf_profile_process_soap_request_msg:
+ * @profile: a #LassoWsfProfile object
+ * @message: a SOAP request message string
+ * @security_mech_id: the security mechanism to apply
+ *
+ * Process an ID-WSF SOAP request, extract headers information, and check compliance with the
+ * security mechanism.
+ *
+ * Return value: 0 if successful, an error code otherwise.
+ */
gint
lasso_wsf_profile_process_soap_request_msg(LassoWsfProfile *profile, const gchar *message,
- G_GNUC_UNUSED const gchar *service_type, const gchar *security_mech_id)
+ const gchar *security_mech_id)
{
LassoSoapBindingCorrelation *correlation = NULL;
LassoSoapEnvelope *envelope = NULL;
- gchar *messageId;
+ gchar *messageId = NULL;
int rc = 0;
- xmlDoc *doc;
+ xmlDoc *doc = NULL;
GList *iter = NULL;
+ GList *node_list = NULL;
- g_return_val_if_fail(LASSO_IS_WSF_PROFILE(profile), LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
- g_return_val_if_fail(message != NULL, LASSO_PARAM_ERROR_INVALID_VALUE);
+ lasso_bad_param(WSF_PROFILE, profile);
+ lasso_null_param(message);
+
+ g_return_val_if_fail(profile->private_data, LASSO_PARAM_ERROR_NON_INITIALIZED_OBJECT);
+ lasso_wsf_profile_set_soap_fault(profile, NULL);
doc = lasso_xml_parse_memory(message, strlen(message));
goto_cleanup_if_fail_with_rc (doc != NULL, critical_error(LASSO_PROFILE_ERROR_INVALID_SOAP_MSG));
/* Get soap request and his message id */
envelope = LASSO_SOAP_ENVELOPE(lasso_node_new_from_xmlNode(xmlDocGetRootElement(doc)));
if (LASSO_IS_SOAP_ENVELOPE(envelope)) {
- lasso_assign_gobject(profile->soap_envelope_request, LASSO_SOAP_ENVELOPE(envelope));
+ lasso_assign_gobject(profile->soap_envelope_request, envelope);
} else {
- goto_cleanup_if_fail_with_rc(FALSE, LASSO_PROFILE_ERROR_INVALID_SOAP_MSG);
+ goto_cleanup_with_rc(LASSO_PROFILE_ERROR_INVALID_SOAP_MSG);
}
goto_cleanup_if_fail_with_rc(envelope != NULL, LASSO_SOAP_ERROR_MISSING_ENVELOPE);
goto_cleanup_if_fail_with_rc(envelope->Body != NULL, LASSO_SOAP_ERROR_MISSING_BODY);
@@ -803,27 +950,31 @@ lasso_wsf_profile_process_soap_request_msg(LassoWsfProfile *profile, const gchar
messageId = correlation->messageID;
/* Comply with security mechanism */
if (lasso_security_mech_id_is_null_authentication(security_mech_id) == FALSE) {
- /** FIXME: add security mechanisms */
goto_cleanup_if_fail_with_rc(FALSE, LASSO_WSF_PROFILE_ERROR_UNSUPPORTED_SECURITY_MECHANISM);
}
- /* Set soap response */
- lasso_release_gobject(envelope);
- envelope = lasso_wsf_profile_build_soap_envelope_internal(messageId,
- LASSO_PROVIDER(profile->server)->ProviderID);
- lasso_assign_gobject(LASSO_WSF_PROFILE(profile)->soap_envelope_response, envelope);
+ /* Extract the remote provider ID if present */
+ if (LASSO_IS_SOAP_HEADER(envelope->Header)) {
+ for (node_list = envelope->Header->Other;
+ node_list; node_list = g_list_next(node_list)) {
+ LassoSoapBindingProvider *node = node_list->data;
-cleanup:
- if (envelope) {
- lasso_release_gobject(envelope);
- }
- if (doc) {
- lasso_release_doc(doc);
+ if (LASSO_IS_SOAP_BINDING_PROVIDER(node)) {
+ lasso_assign_string(profile->private_data->remote_provider_id,
+ node->providerID);
+ break; /* Only treat the first one */
+ }
+ }
}
+cleanup:
+ lasso_release_gobject(envelope);
+ lasso_release_doc(doc);
+
return rc;
}
+
/**
* lasso_wsf_profile_process_soap_response_msg:
* @profile: a #LassoWsfProfile object
@@ -838,34 +989,45 @@ gint
lasso_wsf_profile_process_soap_response_msg(LassoWsfProfile *profile, const gchar *message)
{
xmlDoc *doc = NULL;
- xmlNode *root = NULL;
LassoSoapEnvelope *envelope = NULL;
gint rc = 0;
- g_return_val_if_fail(LASSO_IS_WSF_PROFILE(profile),
- LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
- g_return_val_if_fail(message != NULL,
- LASSO_PARAM_ERROR_INVALID_VALUE);
+ lasso_bad_param(WSF_PROFILE, profile);
+ lasso_null_param(message);
+
+ g_return_val_if_fail(profile->private_data, LASSO_PARAM_ERROR_NON_INITIALIZED_OBJECT);
+ lasso_wsf_profile_set_soap_fault(profile, NULL);
doc = lasso_xml_parse_memory(message, strlen(message));
goto_cleanup_if_fail_with_rc (doc != NULL, critical_error(LASSO_PROFILE_ERROR_INVALID_SOAP_MSG));
- root = xmlDocGetRootElement(doc);
- /* Parse the message */
- envelope = LASSO_SOAP_ENVELOPE(lasso_node_new_from_xmlNode(root));
+ envelope = (LassoSoapEnvelope*)lasso_node_new_from_xmlNode(xmlDocGetRootElement(doc));
if (LASSO_IS_SOAP_ENVELOPE(envelope)) {
- lasso_assign_gobject(profile->soap_envelope_response, LASSO_SOAP_ENVELOPE(envelope));
+ lasso_assign_gobject(profile->soap_envelope_response, envelope);
} else {
- goto_cleanup_if_fail_with_rc(FALSE, LASSO_PROFILE_ERROR_INVALID_SOAP_MSG);
+ goto_cleanup_with_rc(LASSO_PROFILE_ERROR_INVALID_SOAP_MSG);
}
- goto_cleanup_if_fail_with_rc(envelope != NULL, LASSO_SOAP_ERROR_MISSING_ENVELOPE);
goto_cleanup_if_fail_with_rc(envelope->Body != NULL, LASSO_SOAP_ERROR_MISSING_BODY);
- if (envelope->Body->any) {
- lasso_assign_gobject(profile->response, LASSO_NODE(envelope->Body->any->data));
+ if (envelope->Body->any && LASSO_IS_NODE(envelope->Body->any->data)) {
+ lasso_assign_gobject(profile->response, envelope->Body->any->data);
} else {
- profile->response = NULL;
- rc = LASSO_PROFILE_ERROR_MISSING_RESPONSE;
+ lasso_release_gobject(profile->response);
+ goto_cleanup_with_rc(LASSO_PROFILE_ERROR_MISSING_RESPONSE);
}
- /* XXX: Validate MessageID */
+
+ /* Check correlation header */
+ goto_cleanup_if_fail_with_rc(
+ lasso_wsf_profile_utils_get_header_correlation(
+ profile->soap_envelope_response),
+ LASSO_WSF_PROFILE_ERROR_MISSING_CORRELATION);
+
+ /* Check message ID */
+ goto_cleanup_if_fail_with_rc(
+ g_strcmp0(lasso_wsf_profile_utils_get_message_id(
+ profile->soap_envelope_request),
+ lasso_wsf_profile_utils_get_ref_message_id(
+ profile->soap_envelope_response)) == 0,
+ LASSO_WSF_PROFILE_ERROR_INVALID_OR_MISSING_REFERENCE_TO_MESSAGE_ID);
+
/* Signal soap fault specifically,
* find soap redirects. */
if (LASSO_IS_SOAP_FAULT(profile->response)) {
@@ -887,12 +1049,8 @@ lasso_wsf_profile_process_soap_response_msg(LassoWsfProfile *profile, const gcha
}
}
cleanup:
- if (envelope) {
- lasso_release_gobject(envelope);
- }
- if (doc) {
- lasso_release_doc(doc);
- }
+ lasso_release_gobject(envelope);
+ lasso_release_doc(doc);
return rc;
}
@@ -923,6 +1081,12 @@ dispose(GObject *object)
if (profile->private_data->dispose_has_run == TRUE)
return;
+ lasso_release_string(profile->private_data->security_mech_id);
+ lasso_release_gobject(profile->private_data->offering);
+ lasso_release_gobject(profile->private_data->description);
+ lasso_release_string(profile->private_data->remote_provider_id);
+ lasso_release_gobject(profile->private_data->soap_fault);
+ lasso_release_string(profile->private_data->status_code);
profile->private_data->dispose_has_run = TRUE;
G_OBJECT_CLASS(parent_class)->dispose(object);
@@ -1191,6 +1355,7 @@ add_key_info_security_token_reference(xmlDocPtr doc, xmlNode *signature, xmlChar
xmlSetProp(reference, (xmlChar*) "URI", value);
lasso_release(value);
}
+
/**
* lasso_wsf_profile_add_saml_signature:
* @wsf_profile: a #LassoWsfProfile
@@ -1306,3 +1471,129 @@ cleanup:
lasso_release_xml_string(assertion_id);
return rc;
}
+
+/**
+ * lasso_wsf_profile_get_remote_provider_id:
+ * @wsf_profile: a #LassoWsfProfile object
+ *
+ * Return the remote provider id parsed in the last processing of a SOAP request or a SOAP response.
+ *
+ * Return value: the provider id string or NULL.
+ */
+const char*
+lasso_wsf_profile_get_remote_provider_id(LassoWsfProfile *wsf_profile)
+{
+ lasso_return_val_if_invalid_param(WSF_PROFILE, wsf_profile, NULL);
+
+ return wsf_profile->private_data->remote_provider_id;
+}
+
+/**
+ * lasso_wsf_profile_get_remote_provider:
+ * @wsf_profile: a #LassoWsfProfile object
+ * @provider_ref: an output pointer to #LassoProvider object variable.
+ *
+ * Return the remote provider parsed in the last processing of a SOAP request or a SOAP response.
+ *
+ * Return value: 0 if successfull, LASSO_PROFILE_ERROR_MISSING_REMOTE_PROVIDERID if no provider id
+ * is present in the SOAP headers, or LASSO_PROFILE_ERROR_UNKNOWN_PROVIDER if the provider is
+ * unknown to us.
+ */
+gint
+lasso_wsf_profile_get_remote_provider(LassoWsfProfile *wsf_profile, LassoProvider **provider)
+{
+ LassoProvider *_provider = NULL;
+
+ lasso_bad_param(WSF_PROFILE, wsf_profile);
+
+ if (! wsf_profile->private_data->remote_provider_id)
+ return LASSO_PROFILE_ERROR_MISSING_REMOTE_PROVIDERID;
+
+ if (! LASSO_IS_SERVER(wsf_profile->server))
+ return LASSO_PROFILE_ERROR_UNKNOWN_PROVIDER;
+
+ _provider = lasso_server_get_provider(wsf_profile->server, wsf_profile->private_data->remote_provider_id);
+ if (! _provider)
+ return LASSO_PROFILE_ERROR_UNKNOWN_PROVIDER;
+
+ if (provider) {
+ lasso_assign_gobject(*provider, _provider);
+ }
+ return 0;
+}
+
+/**
+ * lasso_wsf_profile_get_fault:
+ * @wsf_profile: a #LassoWsfProfile object
+ *
+ * If a fault is going to be returned as next response, return it.
+ *
+ * Return value: a #LassoSoapFault, or NULL if none is currently present in the object.
+ */
+LassoSoapFault*
+lasso_wsf_profile_get_soap_fault(LassoWsfProfile *wsf_profile)
+{
+ lasso_return_val_if_invalid_param(WSF_PROFILE, wsf_profile, NULL);
+
+ if (wsf_profile->private_data)
+ return wsf_profile->private_data->soap_fault;
+ return NULL;
+}
+
+/**
+ * lasso_wsf_profile_set_soap_fault:
+ * @wsf_profile: a #LassoWsfProfile object
+ * @soap_fault: a #LassoSoapFault object
+ *
+ * Set a SOAP fault to be returned in next SOAP response message. The SOAP fault is removed by
+ * lasso_wsf_profile_init_soap_request.
+ *
+ * Return value: 0 if successful, an error code otherwise.
+ */
+gint
+lasso_wsf_profile_set_soap_fault(LassoWsfProfile *wsf_profile, LassoSoapFault *soap_fault)
+{
+ lasso_bad_param(WSF_PROFILE, wsf_profile);
+ if (! LASSO_IS_SOAP_FAULT(soap_fault) && soap_fault)
+ return LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ;
+ if (! wsf_profile->private_data)
+ return LASSO_PARAM_ERROR_NON_INITIALIZED_OBJECT;
+ lasso_assign_gobject(wsf_profile->private_data->soap_fault, soap_fault);
+ return 0;
+}
+
+/**
+ * lasso_wsf_profile_set_status_code:
+ * @wsf_profile: a #LassoWsfProfile
+ * @status_code: a string representing the status code
+ *
+ * Set the status code to set in the next built response.
+ *
+ * Return value: 0 if successful, an error code otherwise.
+ */
+gint
+lasso_wsf_profile_set_status_code(LassoWsfProfile *wsf_profile, const char *status_code)
+{
+ lasso_bad_param(WSF_PROFILE, wsf_profile);
+ if (! wsf_profile->private_data)
+ return LASSO_PARAM_ERROR_NON_INITIALIZED_OBJECT;
+ lasso_assign_string(wsf_profile->private_data->status_code, status_code);
+ return 0;
+}
+
+/**
+ * lasso_wsf_profile_get_status_code:
+ * @wsf_profile: a #LassoWsfProfile object
+ *
+ * Return the actual status code for this protocol object.
+ *
+ * Return value: a string owned by the profile object or NULL.
+ */
+const char*
+lasso_wsf_profile_get_status_code(LassoWsfProfile *wsf_profile) {
+ lasso_return_val_if_invalid_param(WSF_PROFILE, wsf_profile, NULL);
+
+ if (wsf_profile->private_data)
+ return wsf_profile->private_data->status_code;
+ return NULL;
+}
diff --git a/lasso/id-wsf/wsf_profile.h b/lasso/id-wsf/wsf_profile.h
index ffd0cba8..a71f05bf 100644
--- a/lasso/id-wsf/wsf_profile.h
+++ b/lasso/id-wsf/wsf_profile.h
@@ -30,15 +30,16 @@ extern "C" {
#endif /* __cplusplus */
-#include <lasso/id-ff/server.h>
-#include <lasso/id-ff/identity.h>
-#include <lasso/id-ff/session.h>
-#include <lasso/xml/soap_envelope.h>
-#include <lasso/xml/soap_binding_provider.h>
-#include <lasso/xml/saml_assertion.h>
-#include <lasso/xml/disco_description.h>
-#include <lasso/xml/disco_resource_offering.h>
-#include <lasso/xml/disco_description.h>
+#include <../id-ff/server.h>
+#include <../id-ff/identity.h>
+#include <../id-ff/session.h>
+#include <../xml/soap_envelope.h>
+#include <../xml/soap_binding_provider.h>
+#include <../xml/soap_fault.h>
+#include <../xml/saml_assertion.h>
+#include <../xml/disco_description.h>
+#include <../xml/disco_resource_offering.h>
+#include <../xml/disco_description.h>
#define LASSO_TYPE_WSF_PROFILE (lasso_wsf_profile_get_type())
#define LASSO_WSF_PROFILE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), \
@@ -102,11 +103,13 @@ LASSO_EXPORT gint lasso_wsf_profile_build_soap_request_msg(LassoWsfProfile *prof
LASSO_EXPORT gint lasso_wsf_profile_build_soap_response_msg(LassoWsfProfile *profile);
-LASSO_EXPORT gint lasso_wsf_profile_init_soap_request(LassoWsfProfile *profile,
- LassoNode *request);
+LASSO_EXPORT gint lasso_wsf_profile_init_soap_request(LassoWsfProfile *profile, LassoNode *request);
+
+LASSO_EXPORT gint lasso_wsf_profile_init_soap_response(LassoWsfProfile *profile, LassoNode
+ *response);
LASSO_EXPORT gint lasso_wsf_profile_process_soap_request_msg(LassoWsfProfile *profile,
- const gchar *message, const gchar *service_type, const gchar *security_mech_id);
+ const gchar *message, const gchar *security_mech_id);
LASSO_EXPORT gint lasso_wsf_profile_process_soap_response_msg(LassoWsfProfile *profile,
const gchar *message);
@@ -156,6 +159,31 @@ G_GNUC_DEPRECATED LASSO_EXPORT void lasso_wsf_profile_set_principal_offline(
LASSO_EXPORT gint lasso_wsf_profile_init(LassoWsfProfile *profile, LassoServer *server,
LassoDiscoResourceOffering *offering);
+LASSO_EXPORT gint lasso_wsf_profile_get_remote_provider(LassoWsfProfile *wsf_profile,
+ LassoProvider **provider);
+
+LASSO_EXPORT const char* lasso_wsf_profile_get_remote_provider_id(LassoWsfProfile *wsf_profile);
+
+LASSO_EXPORT LassoSoapFault* lasso_wsf_profile_get_soap_fault(LassoWsfProfile *wsf_profile);
+
+LASSO_EXPORT gint lasso_wsf_profile_set_soap_fault(LassoWsfProfile *wsf_profile, LassoSoapFault *soap_fault);
+
+LASSO_EXPORT gint lasso_wsf_profile_set_status_code(LassoWsfProfile *wsf_profile, const char *code);
+
+LASSO_EXPORT const char* lasso_wsf_profile_get_status_code(LassoWsfProfile *wsf_profile);
+
+#define lasso_wsf_profile_helper_assign_resource_id(from,to) \
+ if ((from)->ResourceID) {\
+ lasso_assign_gobject((to)->ResourceID, (from)->ResourceID); \
+ } else if ((from)->EncryptedResourceID) {\
+ lasso_assign_gobject((to)->EncryptedResourceID, (from)->EncryptedResourceID); \
+ }
+
+#define lasso_wsf_profile_helper_set_status(message, code) \
+ { \
+ lasso_assign_new_gobject(message->Status, lasso_utility_status_new(code)); \
+ }
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/lasso/id-wsf/wsf_profile_private.h b/lasso/id-wsf/wsf_profile_private.h
index a8f25925..859cee1d 100644
--- a/lasso/id-wsf/wsf_profile_private.h
+++ b/lasso/id-wsf/wsf_profile_private.h
@@ -30,7 +30,7 @@ extern "C" {
#endif /* __cplusplus */
-#include <lasso/xml/soap_fault.h>
+#include "../xml/soap_fault.h"
struct _LassoWsfProfilePrivate
{
@@ -38,16 +38,18 @@ struct _LassoWsfProfilePrivate
char *security_mech_id;
LassoDiscoResourceOffering *offering;
LassoDiscoDescription *description;
- LassoSoapFault *fault;
+ char *remote_provider_id;
+ LassoSoapFault *soap_fault;
+ char *status_code;
};
LassoSoapFault* lasso_wsf_profile_get_fault(const LassoWsfProfile *profile);
-
LassoDiscoDescription* lasso_wsf_profile_get_description_auto(const LassoDiscoServiceInstance *si,
const gchar *security_mech_id);
-
void lasso_wsf_profile_set_resource_offering(LassoWsfProfile *profile,
LassoDiscoResourceOffering *offering);
+gint lasso_wsf_profile_set_msg_url_from_description(LassoWsfProfile *wsf_profile);
+gint lasso_wsf_profile_build_soap_fault_response_msg(LassoWsfProfile *profile, gint rc);
#ifdef __cplusplus
}