Skip to content

Commit

Permalink
Autodetect document_templates from files below document_templates_dir…
Browse files Browse the repository at this point in the history
…, honour permissions_default_allow when generating document_templates permissions
  • Loading branch information
manisandro committed Sep 10, 2024
1 parent 3b1ef29 commit 9a17864
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 14 deletions.
5 changes: 5 additions & 0 deletions schemas/qwc-config-generator.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@
"description": "Subdirectory path relative to qgis_print_layouts_dir. If specified, only layouts within this subdir will be processed. Useful to specify separate print layouts per tenant.",
"type": "string"
},
"document_templates_dir": {
"description": "Directory containing the jasper report templates (*.jrxml).",
"type": "string",
"default": "/reports"
},
"qgis_projects_scan_base_dir": {
"description": "Path for QGIS projects, which should be automatically detected. Must be a subdir qgis_projects_base_dir. Example: /data/scan",
"type": "string"
Expand Down
2 changes: 1 addition & 1 deletion src/config_generator/config_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ def __init__(self, config, logger, config_file_dir, use_cached_project_metadata)
self.service_config('search'), self.logger
),
'document': DocumentServiceConfig(
self.config_models, self.schema_urls.get('document'),
generator_config, self.config_models, self.schema_urls.get('document'),
self.service_config('document'), self.logger
),
'legend': LegendServiceConfig(
Expand Down
101 changes: 88 additions & 13 deletions src/config_generator/document_service_config.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from collections import OrderedDict
import os

from .permissions_query import PermissionsQuery
from .service_config import ServiceConfig
Expand All @@ -10,7 +11,7 @@ class DocumentServiceConfig(ServiceConfig):
Generate Document service config.
"""

def __init__(self, config_models, schema_url, service_config, logger):
def __init__(self, generator_config, config_models, schema_url, service_config, logger):
"""Constructor
:param ConfigModels config_models: Helper for ORM models
Expand All @@ -20,20 +21,43 @@ def __init__(self, config_models, schema_url, service_config, logger):
"""
super().__init__('document', schema_url, service_config, logger)

self.report_dir = generator_config.get("document_templates_dir", "/reports")
self.permissions_default_allow = generator_config.get(
'permissions_default_allow', True
)

self.config_models = config_models
self.permissions_query = PermissionsQuery(config_models, logger)

def config(self):
"""Return service config."""
# get base config
config = super().config()

# scan for reports
scanned_document_templates = []
for root, dirs, files in os.walk(self.report_dir):
subdir = os.path.relpath(root, self.report_dir)
scanned_document_templates += [
os.path.join(subdir, file[:-6]) for file in files if file.endswith(".jrxml")
]

# additional service config
cfg_resources = self.service_config.get('resources', {})
config['resources'] = config.get('resources', {})
resources = config['resources']

# get resources directly from service config()
resources['document_templates'] = resources.get('document_templates', [])

# get resources directly from service config
resources = OrderedDict()
resources['document_templates'] = cfg_resources.get('document_templates', {})
config['resources'] = resources
# add templates from scanned_document_templates which are not already anually defined
for entry in resources['document_templates']:
try:
scanned_document_templates.remove(entry["template"])
except:
pass

for template in scanned_document_templates:
resources['document_templates'].append({"template": template})

return config

Expand All @@ -46,16 +70,67 @@ def permissions(self, role):
permissions = OrderedDict()

if 'permissions' not in self.service_config:
# helper method alias
non_public_resources = self.permissions_query.non_public_resources
permitted_resources = self.permissions_query.permitted_resources

# collect permissions from ConfigDB
with self.config_models.session() as session:
# helper method alias
permitted_resources = self.permissions_query.permitted_resources

# collect role permissions from ConfigDB
document_templates = permitted_resources(
'document_templates', role, session
).keys()
permissions['document_templates'] = sorted(list(document_templates))
role_permissions = {
'document_templates': permitted_resources(
'document_templates', role, session
)
}

# collect public permissions from ConfigDB
public_role = self.permissions_query.public_role()
public_permissions = {
'document_templates': permitted_resources(
'document_templates', public_role, session
)
}

# collect public restrictions from ConfigDB
public_restrictions = {
'document_templates': non_public_resources('document_templates', session)
}

# Collect available templates
available_document_templates = []
for root, dirs, files in os.walk(self.report_dir):
subdir = os.path.relpath(root, self.report_dir)
available_document_templates += [
os.path.join(subdir, file[:-6]) for file in files if file.endswith(".jrxml")
]
available_document_templates += [
entry["template"]
for entry in self.service_config.get('resources', {}).get('document_templates', [])
]
available_document_templates = list(set(available_document_templates))

permitted_templates = []
for template in available_document_templates:
# lookup permissions
if self.permissions_default_allow:
template_restricted_for_public = template in public_restrictions['document_templates']
else:
template_restricted_for_public = template not in public_permissions['document_templates']

template_permitted_for_role = template in role_permissions['document_templates']

# If map is not permitted, skip
if (
template_restricted_for_public
and not template_permitted_for_role
):
continue

permitted_templates.append(template)

permissions['document_templates'] = permitted_templates

else:
# use permissions from additional service config if present
self.logger.debug("Reading permissions from tenantConfig")
Expand All @@ -76,4 +151,4 @@ def permissions(self, role):

break

return permissions
return permissions

0 comments on commit 9a17864

Please sign in to comment.