From 09daafe00fc3a9fc3240886e17eca01b0ed0f3e3 Mon Sep 17 00:00:00 2001 From: Benjamin Dauvergne Date: Fri, 12 Sep 2008 10:17:26 +0000 Subject: [PATCH] * Add support of lasso_registry to lasso_node_new_from_xmlNode. * Add full support for xsi:type, with lookup of the QName namespace, will only work if lib: namespace is correctly declared in the dumped XML fragment. * Add a test for the new functionnality in lasso_node_new_from_xmlNode. --- lasso/xml/xml.c | 137 ++++++++++++++++++++++++-------------------- tests/basic_tests.c | 31 ++++++++++ 2 files changed, 106 insertions(+), 62 deletions(-) diff --git a/lasso/xml/xml.c b/lasso/xml/xml.c index abb59005..fa900e0b 100644 --- a/lasso/xml/xml.c +++ b/lasso/xml/xml.c @@ -49,6 +49,7 @@ #include #include #include "../utils.h" +#include "../registry.h" static char* lasso_node_build_query(LassoNode *node); @@ -1520,11 +1521,11 @@ LassoNode* lasso_node_new_from_xmlNode(xmlNode *xmlnode) { char *prefix = NULL; - char *typename; - char *tmp; - char *node_name; - xmlChar *xsitype; - LassoNode *node; + char *typename = NULL; + char *tmp = NULL; + char *node_name = NULL; + xmlChar *xsitype = NULL; + LassoNode *node = NULL; if (xmlnode == NULL || xmlnode->ns == NULL) { message(G_LOG_LEVEL_CRITICAL, "Impossible to build LassoNode from xml node"); @@ -1572,73 +1573,85 @@ lasso_node_new_from_xmlNode(xmlNode *xmlnode) prefix = "IdWsf2Sec"; else if (strcmp((char*)xmlnode->ns->href, LASSO_WSA_HREF) == 0) prefix = "WsAddr"; +#if 0 /* Desactivate DGME lib special casing */ else if (strcmp((char*)xmlnode->ns->href, "urn:dgme:msp:ed:2007-01") == 0) /* FIXME: new namespaces should be possible to add from another library than lasso */ prefix = "DgmeMspEd"; - else { +#endif + else if ((tmp = lasso_get_prefix_for_idwsf2_dst_service_href((char*)xmlnode->ns->href)) + != NULL) { /* ID-WSF 2 Profile */ - tmp = lasso_get_prefix_for_idwsf2_dst_service_href((char*)xmlnode->ns->href); - if (tmp) { - prefix = "IdWsf2DstRef"; - g_free(tmp); + prefix = "IdWsf2DstRef"; + g_free(tmp); + } else if ((tmp = lasso_get_prefix_for_dst_service_href((char*)xmlnode->ns->href)) + != NULL) { + /* ID-WSF 1 Profile */ + prefix = "Dst"; + g_free(tmp); + } + + if (prefix != NULL && strcmp(prefix, "Dst") == 0 && strcmp((char*)xmlnode->name, "Status") == 0) + prefix = "Utility"; + else if (prefix != NULL && strcmp(prefix, "Disco") == 0 && strcmp((char*)xmlnode->name, "Status") == 0) + prefix = "Utility"; + else if (prefix != NULL && strcmp(prefix, "Sa") == 0 && strcmp((char*)xmlnode->name, "Status") == 0) + prefix = "Utility"; +#if 0 /* Remove special casing for DGME lib */ + else if (strcmp(prefix, "DgmeMspEd") == 0 && strcmp((char*)xmlnode->name, "Status") == 0) + prefix = "Utility"; +#endif + + xsitype = xmlGetNsProp(xmlnode, (xmlChar*)"type", (xmlChar*)LASSO_XSI_HREF); + if (xsitype) { + xmlNsPtr ns; + xmlChar *xmlPrefix, *separator; + + /** Honor xsi:type if the QName is in the LASSO_LASSO_HREF namespace */ + xmlPrefix = (xmlChar*)xsitype; + separator = (xmlChar*)strchr((char*)xsitype, ':'); + if (separator != NULL) { + xmlPrefix = (xmlChar*)g_strndup((char*)xmlPrefix, (size_t)(separator - xmlPrefix)); + ns = xmlSearchNs(NULL, xmlnode, xmlPrefix); + if (ns != NULL && strcmp((char*)ns->href, LASSO_LASSO_HREF) == 0) { + typename = g_strdup((char*)(separator+1)); + } + lasso_release(xmlPrefix); + } + lasso_release_xmlchar(xsitype); + } + + if (typename == NULL) { + node_name = (char*)xmlnode->name; + if (strcmp(node_name, "EncryptedAssertion") == 0) { + typename = g_strdup("LassoSaml2EncryptedElement"); + } else if (strcmp(node_name, "SvcMD") == 0) { + typename = g_strdup("LassoIdWsf2DiscoSvcMetadata"); + } else if (prefix != NULL && strcmp(prefix, "IdWsf2DstRef") == 0 && strcmp(node_name, "Status") == 0) { + typename = g_strdup("LassoIdWsf2UtilStatus"); + } else if (prefix != NULL && strcmp(prefix, "WsSec1") == 0 && strcmp(node_name, "Security") == 0) { + typename = g_strdup("LassoWsSec1SecurityHeader"); + } else if (prefix != NULL && strcmp(prefix, "Soap") == 0 && strcmp(node_name, "detail") == 0) { /* FIXME */ + typename = g_strdup("LassoSoapDetail"); +#if 0 /* Remove special casing for DGME lib */ + } else if (prefix != NULL && strcmp(prefix, "DgmeMspEd") == 0 && strcmp(node_name, "file") == 0) { /* FIXME */ + typename = g_strdup("LassoDgmeMspEdFile"); +#endif } else { - /* ID-WSF 1 Profile */ - tmp = lasso_get_prefix_for_dst_service_href((char*)xmlnode->ns->href); - if (tmp) { - prefix = "Dst"; - g_free(tmp); + if (prefix != NULL) { + typename = g_strdup_printf("Lasso%s%s", prefix, node_name); + } else { + if (xmlnode->ns != NULL && xmlnode->ns->href != NULL) { + const char *ctypename = lasso_registry_default_get_mapping((char*)xmlnode->ns->href, node_name, LASSO_LASSO_HREF); + if (ctypename) { + typename = g_strdup(ctypename); + } + } } } } - if (prefix == NULL) - return NULL; - - if (strcmp(prefix, "Dst") == 0 && strcmp((char*)xmlnode->name, "Status") == 0) - prefix = "Utility"; - else if (strcmp(prefix, "Disco") == 0 && strcmp((char*)xmlnode->name, "Status") == 0) - prefix = "Utility"; - else if (strcmp(prefix, "Sa") == 0 && strcmp((char*)xmlnode->name, "Status") == 0) - prefix = "Utility"; - else if (strcmp(prefix, "DgmeMspEd") == 0 && strcmp((char*)xmlnode->name, "Status") == 0) - prefix = "Utility"; - - xsitype = xmlGetNsProp(xmlnode, (xmlChar*)"type", (xmlChar*)LASSO_XSI_HREF); - if (xsitype) { - /* XXX: should look for proper namespace prefix declaration - * and not assumes blindly that lib: is the liberty prefix; - * should also use the declared type to get the proper typename - * instead of falling back to good ol' xmlnode->name later. - * yada yada - */ - if (strncmp((char*)xsitype, "lib:", 4) == 0) - prefix = "Lib"; - xmlFree(xsitype); - xsitype = NULL; - } - - if (prefix == NULL) - return NULL; - - node_name = (char*)xmlnode->name; - if (strcmp(node_name, "EncryptedAssertion") == 0) { - typename = g_strdup("LassoSaml2EncryptedElement"); - } else if (strcmp(node_name, "SvcMD") == 0) { - typename = g_strdup("LassoIdWsf2DiscoSvcMetadata"); - } else if (strcmp(prefix, "IdWsf2DstRef") == 0 && strcmp(node_name, "Status") == 0) { - typename = g_strdup("LassoIdWsf2UtilStatus"); - } else if (strcmp(prefix, "WsSec1") == 0 && strcmp(node_name, "Security") == 0) { - typename = g_strdup("LassoWsSec1SecurityHeader"); - } else if (strcmp(prefix, "Soap") == 0 && strcmp(node_name, "detail") == 0) { /* FIXME */ - typename = g_strdup("LassoSoapDetail"); - } else if (strcmp(prefix, "DgmeMspEd") == 0 && strcmp(node_name, "file") == 0) { /* FIXME */ - typename = g_strdup("LassoDgmeMspEdFile"); - } else { - typename = g_strdup_printf("Lasso%s%s", prefix, node_name); - } - node = lasso_node_new_from_xmlNode_with_type(xmlnode, typename); - g_free(typename); + lasso_release(typename); return node; } diff --git a/tests/basic_tests.c b/tests/basic_tests.c index 00880bd3..cd29118a 100644 --- a/tests/basic_tests.c +++ b/tests/basic_tests.c @@ -124,6 +124,34 @@ START_TEST(test07_registry_functional_mapping) } END_TEST +START_TEST(test08_test_new_from_xmlNode) +{ + static GType this_type = 0; + gint r; + LassoNode *node = NULL; + + static const GTypeInfo this_info = { + sizeof (LassoNodeClass), + NULL, + NULL, + NULL, + NULL, + NULL, + sizeof(LassoNode), + 0, + NULL, + }; + + this_type = g_type_register_static(LASSO_TYPE_NODE, + "LassoTest", &this_info, 0); + r = lasso_registry_default_add_direct_mapping("http://example.com", "Test1", LASSO_LASSO_HREF, "LassoTest"); + fail_unless(r == 0, "no mapping for http://example.com:Test1 should exist"); + node = lasso_node_new_from_dump(""); + fail_unless(node != NULL, "parsing should return an object"); + fail_unless(strcmp(G_OBJECT_TYPE_NAME(node), "LassoTest") == 0, "node classname should be LassoTest"); +} +END_TEST + Suite* basic_suite() @@ -136,6 +164,7 @@ basic_suite() TCase *tc_identity_load_dump_empty = tcase_create("Create identity from empty string"); TCase *tc_registry_direct_mapping = tcase_create("Test QName registry with direct mapping"); TCase *tc_registry_functional_mapping = tcase_create("Test QName registry with functional mapping"); + TCase *tc_registry_new_from_xmlNode = tcase_create("Test parsing a node that has a mapping to Lasso Object in the registry"); suite_add_tcase(s, tc_server_load_dump_empty_string); suite_add_tcase(s, tc_server_load_dump_random_string); suite_add_tcase(s, tc_server_load_dump_random_xml); @@ -143,6 +172,7 @@ basic_suite() suite_add_tcase(s, tc_identity_load_dump_empty); suite_add_tcase(s, tc_registry_direct_mapping); suite_add_tcase(s, tc_registry_functional_mapping); + suite_add_tcase(s, tc_registry_new_from_xmlNode); tcase_add_test(tc_server_load_dump_empty_string, test01_server_load_dump_empty_string); tcase_add_test(tc_server_load_dump_random_string, test02_server_load_dump_random_string); tcase_add_test(tc_server_load_dump_random_xml, test03_server_load_dump_random_xml); @@ -150,6 +180,7 @@ basic_suite() tcase_add_test(tc_identity_load_dump_empty, test05_identity_load_dump_empty); tcase_add_test(tc_registry_direct_mapping, test06_registry_direct_mapping); tcase_add_test(tc_registry_functional_mapping, test07_registry_functional_mapping); + tcase_add_test(tc_registry_new_from_xmlNode, test08_test_new_from_xmlNode); return s; }