From 76b94d7ee88bdd82ca614afef70055281711d510 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= Date: Tue, 19 Dec 2023 11:40:23 +0100 Subject: [PATCH] data sources: export detailed roles infos (#84889) --- tests/test_datasource_users.py | 61 ++++++++++++++++++++++++++++++++++ wcs/data_sources.py | 4 +-- wcs/qommon/xml_storage.py | 23 ++++++++++++- 3 files changed, 85 insertions(+), 3 deletions(-) diff --git a/tests/test_datasource_users.py b/tests/test_datasource_users.py index 9e0ad56e6..3bce97a3a 100644 --- a/tests/test_datasource_users.py +++ b/tests/test_datasource_users.py @@ -1,3 +1,5 @@ +import xml.etree.ElementTree as ET + import pytest from wcs import data_sources @@ -525,3 +527,62 @@ def test_datasource_users_user_formdef(pub): }, ) ] + + +def test_legacy_format_import(pub): + data_source_xml = """ + Agents de la ville + agents_de_la_ville + + wcs:users + + + 8201764fc2c24b92bd691fd231a4cf76 + +""" + ds = NamedDataSource.import_from_xml_tree(ET.fromstring(data_source_xml)) + assert ds.users_included_roles == ['8201764fc2c24b92bd691fd231a4cf76'] + + +def test_new_format_import(pub): + data_source_xml = """ + Agents de la ville + agents_de_la_ville + + wcs:users + + + Agents + +""" + ds = NamedDataSource.import_from_xml_tree(ET.fromstring(data_source_xml)) + assert ds.users_included_roles == [] # role doesn't exist + + # import with id match + pub.role_class.wipe() + role1 = pub.role_class(name='role') + role1.id = '8201764fc2c24b92bd691fd231a4cf76' + role1.store() + + ds = NamedDataSource.import_from_xml_tree(ET.fromstring(data_source_xml), include_id=True) + assert ds.users_included_roles == [role1.id] + + # import with slug match + pub.role_class.wipe() + role1 = pub.role_class(name='Agents') + role1.slug = 'agent' + role1.store() + + ds = NamedDataSource.import_from_xml_tree(ET.fromstring(data_source_xml), include_id=False) + assert ds.users_included_roles == [role1.id] + + # import with name match + pub.role_class.wipe() + role1 = pub.role_class(name='Agents') + role1.slug = 'agent' + role1.store() + + ds = NamedDataSource.import_from_xml_tree( + ET.fromstring(data_source_xml.replace('role-slug="agent"', '')), include_id=False + ) + assert ds.users_included_roles == [role1.id] diff --git a/wcs/data_sources.py b/wcs/data_sources.py index 31c33c558..1c845dd87 100644 --- a/wcs/data_sources.py +++ b/wcs/data_sources.py @@ -717,8 +717,8 @@ class NamedDataSource(XmlStorableObject): ('data_source', 'data_source'), ('notify_on_errors', 'bool'), ('record_on_errors', 'bool'), - ('users_included_roles', 'str_list'), - ('users_excluded_roles', 'str_list'), + ('users_included_roles', 'ds_roles'), + ('users_excluded_roles', 'ds_roles'), ('include_disabled_users', 'bool'), ] diff --git a/wcs/qommon/xml_storage.py b/wcs/qommon/xml_storage.py index 427c74562..f8d86adb4 100644 --- a/wcs/qommon/xml_storage.py +++ b/wcs/qommon/xml_storage.py @@ -20,7 +20,7 @@ import xml.etree.ElementTree as ET from quixote import get_publisher from .misc import indent_xml, xml_node_text -from .storage import Equal, Or, StorableObject +from .storage import Contains, Equal, Or, StorableObject class XmlStorableObject(StorableObject): @@ -141,6 +141,8 @@ class XmlStorableObject(StorableObject): def import_roles_from_xml(self, element, include_id=False, **kwargs): criterias = [] for sub in element: + if sub.tag != 'role': + continue if include_id and 'role-id' in sub.attrib: criterias.append(Equal('id', sub.attrib['role-id'])) elif 'role-slug' in sub.attrib: @@ -156,3 +158,22 @@ class XmlStorableObject(StorableObject): return get_publisher().role_class.select([Or(criterias)], order_by='name') return lazy_roles + + def import_ds_roles_from_xml(self, element, include_id=False, **kwargs): + imported_roles = self.import_roles_from_xml(element, include_id=include_id, **kwargs) + if callable(imported_roles): + imported_roles = imported_roles() + role_ids = [x.id for x in imported_roles] + for sub in element: + if sub.tag == 'item': # legacy support for {id} + role_ids.append(xml_node_text(sub)) + return role_ids + + def export_ds_roles_to_xml(self, element, attribute_name, include_id=False, **kwargs): + for role in get_publisher().role_class.select( + [Contains('id', getattr(self, attribute_name, None) or [])] + ): + sub = ET.SubElement(element, 'role') + sub.attrib['role-id'] = role.id # always include id + sub.attrib['role-slug'] = role.slug + sub.text = role.name