Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Allow groups ACL for layer export capabilities #625

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion lizmap/definitions/attribute_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
from qgis.core import QgsAttributeTableConfig, QgsVectorLayer

from lizmap.definitions.base import BaseDefinitions, InputType
from lizmap.definitions.definitions import LwcVersions
from lizmap.toolbelt.i18n import tr

__copyright__ = 'Copyright 2020, 3Liz'
__copyright__ = 'Copyright 2025, 3Liz'
__license__ = 'GPL version 3'
__email__ = '[email protected]'

Expand Down Expand Up @@ -41,6 +42,21 @@ def __init__(self):
'default': '',
'tooltip': tr('List of fields to hide in the attribute table.')
}
self._layer_config['export_enabled'] = {
'type': InputType.CheckBox,
'header': tr('Export enabled'),
'default': True,
'tooltip': tr('If the export of the layer is enabled.'),
'version': LwcVersions.Lizmap_3_9,
'use_json': True,
}
self._layer_config['export_allowed_groups'] = {
'type': InputType.Text,
'header': tr('Allowed groups for export'),
'default': '',
'tooltip': tr('Allowed list of groups for exporting the data. If empty, everyone can export the data.'),
'version': LwcVersions.Lizmap_3_9,
}
self._layer_config['pivot'] = {
'type': InputType.CheckBox,
'header': tr('Pivot table'),
Expand Down
27 changes: 25 additions & 2 deletions lizmap/forms/attribute_table_edition.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""Dialog for attribute table edition."""

from qgis.core import QgsMapLayerProxyModel
from qgis.PyQt.QtGui import QIcon

from lizmap.definitions.attribute_table import (
AttributeTableDefinitions,
Expand All @@ -9,9 +10,9 @@
from lizmap.definitions.definitions import LwcVersions
from lizmap.forms.base_edition_dialog import BaseEditionDialog
from lizmap.toolbelt.i18n import tr
from lizmap.toolbelt.resources import load_ui
from lizmap.toolbelt.resources import load_ui, resources_path

__copyright__ = 'Copyright 2020, 3Liz'
__copyright__ = 'Copyright 2025, 3Liz'
__license__ = 'GPL version 3'
__email__ = '[email protected]'

Expand All @@ -28,6 +29,8 @@ def __init__(self, parent=None, unicity=None, lwc_version: LwcVersions = None):
self.config.add_layer_widget('layerId', self.layer)
self.config.add_layer_widget('primaryKey', self.primary_key)
self.config.add_layer_widget('hiddenFields', self.fields_to_hide)
self.config.add_layer_widget('export_enabled', self.export_enabled)
self.config.add_layer_widget('export_allowed_groups', self.export_allowed_groups)
self.config.add_layer_widget('pivot', self.pivot_table)
self.config.add_layer_widget('hideAsChild', self.hide_subpanels)
self.config.add_layer_widget('hideLayer', self.hide_layer)
Expand All @@ -36,6 +39,8 @@ def __init__(self, parent=None, unicity=None, lwc_version: LwcVersions = None):
self.config.add_layer_label('layerId', self.label_layer)
self.config.add_layer_label('primaryKey', self.label_primary_key)
self.config.add_layer_label('hiddenFields', self.label_fields_to_hide)
self.config.add_layer_label('export_enabled', self.label_export_enabled)
self.config.add_layer_label('export_allowed_groups', self.label_export_allowed_groups)
self.config.add_layer_label('pivot', self.label_pivot_table)
self.config.add_layer_label('hideAsChild', self.label_hide_subpanels)
self.config.add_layer_label('hideLayer', self.label_hide_layer)
Expand All @@ -51,6 +56,15 @@ def __init__(self, parent=None, unicity=None, lwc_version: LwcVersions = None):
self.fields_to_hide.set_layer(self.layer.currentLayer())

self.setup_ui()

# Wizard ACL group
self.export_enabled.stateChanged.connect(self.export_allowed_groups.setEnabled)
icon = QIcon(resources_path('icons', 'user_group.svg'))
self.button_wizard_group.setText('')
self.button_wizard_group.setIcon(icon)
self.button_wizard_group.clicked.connect(self.open_wizard_group)
self.button_wizard_group.setToolTip(tr("Open the group wizard"))

self.check_layer_wfs()
self.enable_primary_key_field()

Expand All @@ -64,6 +78,15 @@ def check_layer_wfs(self):
not_in_wfs = self.is_layer_in_wfs(layer)
self.show_error(not_in_wfs)

def open_wizard_group(self):
""" When the user clicks on the group wizard. """
layer = self.layer.currentLayer()
if not layer:
return

helper = tr("Setting groups for the layer exporting capabilities '{}'").format(layer.name())
super().open_wizard_dialog(helper)

def post_load_form(self):
self.layer_changed()

Expand Down
3 changes: 2 additions & 1 deletion lizmap/forms/base_edition_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
from lizmap.qt_style_sheets import NEW_FEATURE_COLOR, NEW_FEATURE_CSS
from lizmap.toolbelt.i18n import tr

__copyright__ = 'Copyright 2023, 3Liz'
__copyright__ = 'Copyright 2025, 3Liz'
__license__ = 'GPL version 3'
__email__ = '[email protected]'

Expand Down Expand Up @@ -61,6 +61,7 @@ def __init__(self, parent: QDialog = None, unicity=None, lwc_version: LwcVersion
self.lwc_versions[LwcVersions.Lizmap_3_6] = []
self.lwc_versions[LwcVersions.Lizmap_3_7] = []
self.lwc_versions[LwcVersions.Lizmap_3_8] = []
self.lwc_versions[LwcVersions.Lizmap_3_9] = []

def setup_ui(self):
""" Build the UI. """
Expand Down
57 changes: 46 additions & 11 deletions lizmap/resources/ui/ui_form_attribute_table.ui
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>425</width>
<height>303</height>
<width>554</width>
<height>390</height>
</rect>
</property>
<property name="windowTitle">
Expand Down Expand Up @@ -43,6 +43,9 @@
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="ListFieldsSelection" name="fields_to_hide"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_pivot_table">
<property name="text">
Expand Down Expand Up @@ -71,6 +74,13 @@
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_hide_layer">
<property name="text">
<string>Hide layer in the list</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QCheckBox" name="hide_layer">
<property name="toolTip">
Expand All @@ -81,27 +91,52 @@
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_hide_layer">
<item row="6" column="0">
<widget class="QLabel" name="label_has_custom_config">
<property name="text">
<string>Hide layer in the list</string>
<string notr="true">Has a custom config</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="ListFieldsSelection" name="fields_to_hide"/>
</item>
<item row="6" column="1">
<widget class="QCheckBox" name="has_custom_config">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_has_custom_config">
<item row="8" column="0">
<widget class="QLabel" name="label_export_allowed_groups">
<property name="text">
<string notr="true">Has a custom config</string>
<string>Export allowed groups</string>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QCheckBox" name="export_enabled">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="8" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLineEdit" name="export_allowed_groups"/>
</item>
<item>
<widget class="QPushButton" name="button_wizard_group">
<property name="text">
<string notr="true">WIZARD</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="7" column="0">
<widget class="QLabel" name="label_export_enabled">
<property name="text">
<string>Export enabled</string>
</property>
</widget>
</item>
Expand Down
37 changes: 37 additions & 0 deletions lizmap/test/test_table_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -991,6 +991,43 @@ def test_attribute_table(self):
# Automatically added, so we add it manually for the comparaison
json['lines']['custom_config'] = 'False'

# Allowing groups for exporting
json['lines']['export_enabled'] = True
self.assertIsNone(json['lines'].get('export_allowed_groups'))

self.assertDictEqual(data, json)

self.assertDictEqual({self.layer.id(): ['id']}, table_manager.wfs_fields_used())

def test_attribute_table_export_acl(self):
"""Test table manager with attribute table with export ACL"""
table = QTableWidget()
definitions = AttributeTableDefinitions()

table_manager = TableManager(
None, definitions, None, table, None, None, None, None)

json = {
'lines': {
'primaryKey': 'id',
'export_enabled': True,
'export_allowed_groups': 'admins',
'hiddenFields': 'id,name,value',
'pivot': 'False',
'hideAsChild': 'False',
'hideLayer': 'False',
'layerId': self.layer.id(),
'order': 0
}
}
self.assertEqual(table_manager.table.rowCount(), 0)
table_manager.from_json(json)
self.assertEqual(table_manager.table.rowCount(), 1)
data = table_manager.to_json(LwcVersions.latest())

# Automatically added, so we add it manually for the comparaison
json['lines']['custom_config'] = 'False'

self.assertDictEqual(data, json)

self.assertDictEqual({self.layer.id(): ['id']}, table_manager.wfs_fields_used())
Expand Down