saml-2.0: improve support for free content inside samlp2:Extensions (fixes #18581)

Four new accesors:

	lasso_samlp2_extensions_get_any
	lasso_samlp2_extensions_set_any
	lasso_samlp2_extensions_get_attributes
	lasso_samlp2_extensions_set_attributes

The two new pseudo field are fully supported in the python binding.

	node = lasso.Samlp2Extensions()
	node.any = '<test>ok</test>'
	node.attributes = {'{http://entrouvert.org/}attribute1': 'value'}
	print node.dump()
This commit is contained in:
Benjamin Dauvergne 2017-09-11 12:07:48 +02:00
parent 51b5874c38
commit 81fad67ad2
8 changed files with 178 additions and 36 deletions

View File

@ -374,7 +374,7 @@ class DocString:
raise Exception('should not happen: could not found type for default: ' + annotation)
arg[2]['default'] = prefix + m.group(1)
arg[2]['optional'] = True
m = re.search(r'\(\s*element-type\s+(\w+)(?:\s+(\w+))?', annotation)
m = re.search(r'\(\s*element-type\s+([\w*]+)(?:\s+([\w*]+))?', annotation)
if m:
if len(m.groups()) > 2:
arg[2]['key-type'] = \

View File

@ -198,6 +198,10 @@
<func name="lasso_log_set_handler" skip="true"/>
<func name="lasso_log_remove_handler" skip="true"/>
<func name="lasso_key_new_for_signature_from_memory" skip="true"/>
<func name="lasso_samlp2_extensions_get_any" skip="php5,perl,java"/>
<func name="lasso_samlp2_extensions_set_any" skip="php5,perl,java"/>
<func name="lasso_samlp2_extensions_get_attributes" skip="php5,perl,java"/>
<func name="lasso_samlp2_extensions_set_attributes" skip="php5,perl,java"/>
<!-- Xml -->
<func name="lasso_node_export_to_soap_with_headers">
<param name="node"/>

View File

@ -87,7 +87,13 @@ class Binding:
else:
raise Exception('Unsupported caller owned return type %s' % ((repr(type), name),))
elif is_hashtable(type):
raise Exception('Unsupported caller owned return type %s' % ((repr(type), name),))
el_type = element_type(type)
k_type = key_type(type)
v_type = value_type(type)
if is_cstring(el_type) or (is_cstring(k_type) and is_cstring(v_type)):
print_(' g_hash_table_destroy(%s);' % name, file=fd)
else:
raise Exception('Unsupported free value of type GHashTable: %s' % type)
elif is_object(type):
print_(' if (return_value) g_object_unref(%s);' % name, file=fd)
else:
@ -528,7 +534,9 @@ if WSF_SUPPORT:
print_(' rc = _lasso.%s(self._cptr%s)' % (
function_name, c_args), file=fd)
print_(' Error.raise_on_rc(rc)', file=fd)
elif is_int(m.return_arg, self.binding_data) or is_xml_node(m.return_arg) or is_cstring(m.return_arg) or is_boolean(m.return_arg):
elif (is_int(m.return_arg, self.binding_data) or is_xml_node(m.return_arg) or
is_cstring(m.return_arg) or is_boolean(m.return_arg) or
is_hashtable(m.return_arg)):
print_(' return _lasso.%s(self._cptr%s)' % (
function_name, c_args), file=fd)
elif is_glist(m.return_arg):
@ -539,13 +547,11 @@ if WSF_SUPPORT:
print_(' if value is not None:', file=fd)
print_(' value = tuple([cptrToPy(x) for x in value])', file=fd)
print_(' return value', file=fd)
elif is_cstring(el_type):
elif is_cstring(el_type) or is_xml_node(el_type):
print_(' return _lasso.%s(self._cptr%s)' % (
function_name, c_args), file=fd)
else:
raise Exception('Return Type GList<%s> is not supported' % el_type)
elif is_hashtable(m.return_arg):
raise Exception('Return type GHashTable unsupported')
elif is_object(m.return_arg):
print_(' return cptrToPy(_lasso.%s(self._cptr%s))' % (
function_name, c_args), file=fd)
@ -929,7 +935,7 @@ register_constants(PyObject *d)
arg_def = ' %s %s = %s;' % (arg[0], arg[1], defval)
else:
arg_def = ' %s %s;' % (arg[0], arg[1])
elif is_xml_node(arg) or is_list(arg) or is_time_t_pointer(arg):
elif is_hashtable(arg) or is_xml_node(arg) or is_list(arg) or is_time_t_pointer(arg):
parse_tuple_format.append('O')
parse_tuple_args.append('&cvt_%s' % aname)
arg_def = ' %s %s = NULL;' % (arg[0], arg[1])
@ -970,7 +976,7 @@ register_constants(PyObject *d)
qualifier = element_type(arg)
if is_cstring(qualifier):
print_(' set_list_of_strings(&%s, cvt_%s);' % (arg[1], arg[1]), file=fd)
elif qualifier == 'xmlNode*':
elif is_xml_node(qualifier):
print_(' set_list_of_xml_nodes(&%s, cvt_%s);' % (arg[1], arg[1]), file=fd)
elif isinstance(qualifier, str) and qualifier.startswith('Lasso'):
print_(' set_list_of_pygobject(&%s, cvt_%s);' % (arg[1], arg[1]), file=fd)
@ -980,6 +986,14 @@ register_constants(PyObject *d)
print_(' %s = get_xml_node_from_pystring(cvt_%s);' % (arg[1], arg[1]), file=fd)
elif is_time_t_pointer(arg):
print_(' %s = get_time_t(cvt_%s);' % (arg[1], arg[1]), file=fd)
elif is_hashtable(arg):
el_type = element_type(arg)
k_type = key_type(arg)
v_type = value_type(arg)
if is_cstring(el_type) or (is_cstring(k_type) and is_cstring(v_type)):
print_(' %s = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);' % arg[1], file=fd)
print_(' set_hashtable_of_strings(%s, cvt_%s);' % (arg[1], arg[1]), file=fd)
elif f == 'O':
if is_optional(arg):
print_(' if (PyObject_TypeCheck((PyObject*)cvt_%s, &PyGObjectPtrType)) {' % arg[1], file=fd)
@ -1021,14 +1035,16 @@ register_constants(PyObject *d)
print_(' PyList_SetItem(cvt_%s_out, 0, out_pyvalue);' % arg[1], file=fd)
elif arg[0] == 'GList*':
qualifier = arg[2].get('element-type')
if qualifier == 'char*':
if is_cstring(qualifier):
print_(' free_list(&%s, (GFunc)g_free);' % arg[1], file=fd)
elif qualifier == 'xmlNode*':
elif is_xml_node(qualifier):
print_(' free_list(&%s, (GFunc)xmlFreeNode);' % arg[1], file=fd)
elif qualifier == 'LassoNode':
elif is_object(qualifier):
print_(' free_list(&%s, (GFunc)g_object_unref);' % arg[1], file=fd)
elif is_time_t_pointer(arg):
print_(' if (%s) free(%s);' % (arg[1], arg[1]), file=fd)
elif not is_transfer_full(arg) and is_hashtable(arg):
self.free_value(fd, arg)
elif not is_transfer_full(arg) and is_xml_node(arg):
self.free_value(fd, arg)

View File

@ -301,6 +301,28 @@ class BindingTestCase(unittest.TestCase):
server = lasso.Server.newFromDump(server_dump)
assert isinstance(server, lasso.Server)
def test12(self):
node = lasso.Samlp2Extensions()
assert not node.any
content = '''<samlp:Extensions
xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
xmlns:eo="https://www.entrouvert.com/" eo:huhu="xxx">
<eo:next_url>%s</eo:next_url>
</samlp:Extensions>'''
node = lasso.Node.newFromXmlNode(content)
assert 'next_url' in node.any[1]
assert 'huhu' in node.attributes.keys()[0]
assert node.attributes.values()[0] == 'xxx'
node.any = ('<zob>coin</zob>',)
node.attributes = {'michou': 'zozo'}
assert '<zob>coin</zob>' in node.dump()
assert 'michou="zozo"' in node.dump()
node = lasso.Node.newFromDump(node.dump())
assert node.any == ('<zob>coin</zob>',)
# on reparse non namespaces attributes are ignore, they should not exist
assert node.attributes == {}
bindingSuite = unittest.makeSuite(BindingTestCase, 'test')
allTests = unittest.TestSuite((bindingSuite, ))

View File

@ -148,18 +148,20 @@ get_dict_from_hashtable_of_strings(GHashTable *value)
dict = PyDict_New();
begin = keys = g_hash_table_get_keys(value);
for (; keys; keys = g_list_next(keys)) {
item_value = g_hash_table_lookup(value, keys->data);
if (item_value) {
item = PyString_FromString(item_value);
PyDict_SetItemString(dict, (char*)keys->data, item);
Py_DECREF(item);
} else {
PyErr_Warn(PyExc_RuntimeWarning, "hashtable contains a null value");
if (value) {
begin = keys = g_hash_table_get_keys(value);
for (; keys; keys = g_list_next(keys)) {
item_value = g_hash_table_lookup(value, keys->data);
if (item_value) {
item = PyString_FromString(item_value);
PyDict_SetItemString(dict, (char*)keys->data, item);
Py_DECREF(item);
} else {
PyErr_Warn(PyExc_RuntimeWarning, "hashtable contains a null value");
}
}
g_list_free(begin);
}
g_list_free(begin);
proxy = PyDictProxy_New(dict);
Py_DECREF(dict);
@ -303,7 +305,7 @@ set_hashtable_of_strings(GHashTable *a_hash, PyObject *dict)
while (PyDict_Next(dict, &i, &key, &value)) {
char *ckey = PyString_AsString(key);
char *cvalue = PyString_AsString(value);
g_hash_table_insert (a_hash, ckey, cvalue);
g_hash_table_insert (a_hash, g_strdup(ckey), g_strdup(cvalue));
}
failure:
return;

View File

@ -325,6 +325,17 @@
} \
}
#define lasso_assign_list_of_xml_node(dest, src) \
{ \
GList *__tmp = src; \
GList *__iter_dest; \
lasso_release_list_of_xml_node(dest); \
dest = g_list_copy(__tmp); \
for (__iter_dest = dest ; __iter_dest != NULL ; __iter_dest = g_list_next(__iter_dest)) { \
__iter_dest->data = xmlCopyNode(__iter_dest->data, 1); \
} \
}
#define lasso_assign_new_sec_key(dest, src) \
{ \
xmlSecKey *__tmp = (src); \
@ -344,6 +355,21 @@
dest = __tmp; \
}
G_GNUC_UNUSED static void
_lasso_copy_helper_assign_table_of_attributes(gpointer key, gpointer val, gpointer dest){
g_hash_table_insert((GHashTable*) dest, g_strdup(key), g_strdup(val));
}
#define lasso_assign_table_of_attributes(dest, src) \
{\
if (!dest) {\
(dest) = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);\
}\
g_hash_table_remove_all(dest);\
g_hash_table_foreach(src, _lasso_copy_helper_assign_table_of_attributes, dest);\
}
/* List appending */
/* lasso_list_add_xxx macros, simplify code around list manipulation (g_list_append needs to be

View File

@ -45,33 +45,35 @@
*
*/
typedef struct _LassoSamlp2ExtensionsPrivate LassoSamlp2ExtensionsPrivate;
struct _LassoSamlp2ExtensionsPrivate {
GList *any;
GHashTable *attributes;
};
/*****************************************************************************/
/* private methods */
/*****************************************************************************/
static struct XmlSnippet schema_snippets[] = {
{"", SNIPPET_LIST_XMLNODES | SNIPPET_ANY | SNIPPET_PRIVATE,
G_STRUCT_OFFSET(LassoSamlp2ExtensionsPrivate, any), NULL, NULL, NULL},
{"", SNIPPET_ATTRIBUTE | SNIPPET_ANY | SNIPPET_PRIVATE,
G_STRUCT_OFFSET(LassoSamlp2ExtensionsPrivate, attributes), NULL, NULL, NULL},
{NULL, 0, 0, NULL, NULL, NULL}
};
static LassoNodeClass *parent_class = NULL;
#define GET_PRIVATE(x) G_TYPE_INSTANCE_GET_PRIVATE(x, \
LASSO_TYPE_SAMLP2_EXTENSIONS, LassoSamlp2ExtensionsPrivate)
/*****************************************************************************/
/* instance and class init functions */
/*****************************************************************************/
static xmlNode*
get_xmlNode(LassoNode *node, gboolean lasso_dump)
{
LassoNodeClass *parent_class = NULL;
xmlNode *cur;
parent_class = g_type_class_peek_parent(LASSO_NODE_GET_CLASS(node));
cur = parent_class->get_xmlNode(node, lasso_dump);
return lasso_node_get_xmlnode_for_any_type(node, cur);
}
static void
class_init(LassoSamlp2ExtensionsClass *klass)
{
@ -80,10 +82,10 @@ class_init(LassoSamlp2ExtensionsClass *klass)
parent_class = g_type_class_peek_parent(klass);
nclass->node_data = g_new0(LassoNodeClassData, 1);
nclass->node_data->keep_xmlnode = TRUE;
nclass->get_xmlNode = get_xmlNode;
lasso_node_class_set_nodename(nclass, "Extensions");
lasso_node_class_set_ns(nclass, LASSO_SAML2_PROTOCOL_HREF, LASSO_SAML2_PROTOCOL_PREFIX);
lasso_node_class_add_snippets(nclass, schema_snippets);
g_type_class_add_private(G_OBJECT_CLASS(klass), sizeof(LassoSamlp2ExtensionsPrivate));
}
GType
@ -123,3 +125,70 @@ lasso_samlp2_extensions_new()
{
return g_object_new(LASSO_TYPE_SAMLP2_EXTENSIONS, NULL);
}
/**
* lasso_samlp2_extensions_get_any:
*
* Return the list of contained XML nodes.
*
* Return value:(element-type xmlNode)(transfer none): a #GList of xmlNode.
*/
GList*
lasso_samlp2_extensions_get_any(LassoSamlp2Extensions *extensions)
{
LassoSamlp2ExtensionsPrivate *pv = NULL;
pv = GET_PRIVATE(extensions);
return pv->any;
}
/**
* lasso_samlp2_extensions_set_any:
* @any:(allow-none)(element-type xmlNode)(transfer none): a list of xmlNode.
*
* Set the list of contained XML nodes.
*
*/
void
lasso_samlp2_extensions_set_any(LassoSamlp2Extensions *extensions, GList *any)
{
LassoSamlp2ExtensionsPrivate *pv = NULL;
pv = GET_PRIVATE(extensions);
lasso_assign_list_of_xml_node(pv->any, any);
}
/**
* lasso_samlp2_extensions_get_attributes:
*
* Return the list of contained XML nodes.
*
* Return value:(element-type xmlNode)(transfer none): a #GList of xmlNode.
*/
GHashTable*
lasso_samlp2_extensions_get_attributes(LassoSamlp2Extensions *extensions)
{
LassoSamlp2ExtensionsPrivate *pv = NULL;
pv = GET_PRIVATE(extensions);
return pv->attributes;
}
/**
* lasso_samlp2_extensions_set_attributes:
* @attributes:(element-type char* char*): table of attributes.
*
* Set the table of XML attributes.
*/
void
lasso_samlp2_extensions_set_attributes(LassoSamlp2Extensions *extensions, GHashTable *attributes)
{
LassoSamlp2ExtensionsPrivate *pv = NULL;
pv = GET_PRIVATE(extensions);
lasso_assign_table_of_attributes(pv->attributes, attributes);
}

View File

@ -62,7 +62,10 @@ struct _LassoSamlp2ExtensionsClass {
LASSO_EXPORT GType lasso_samlp2_extensions_get_type(void);
LASSO_EXPORT LassoNode* lasso_samlp2_extensions_new(void);
LASSO_EXPORT GList* lasso_samlp2_extensions_get_any(LassoSamlp2Extensions *extensions);
LASSO_EXPORT void lasso_samlp2_extensions_set_any(LassoSamlp2Extensions *extensions, GList *any);
LASSO_EXPORT GHashTable* lasso_samlp2_extensions_get_attributes(LassoSamlp2Extensions *extensions);
LASSO_EXPORT void lasso_samlp2_extensions_set_attributes(LassoSamlp2Extensions *extensions, GHashTable *attributes);
#ifdef __cplusplus