Source code for ciodashboard

"""CioDashboard, a module for Chrysalio."""

from __future__ import annotations
from sys import exit as sys_exit
from os.path import dirname, join

from pyramid.config import Configurator

from chrysalio.initialize import Initialize
from chrysalio.includes.cache import cache_user_access, cache_global_item
from chrysalio.includes.cache import cache_namespace
from chrysalio.includes.modules.models import DBModule
from chrysalio.modules import Module
from chrysalio.lib.navigation import NavEntry
from chrysalio.scripts import ScriptRegistry
from .relaxng import RELAXNG_CIODASHBOARD
from .security import PRINCIPALS_CIODASHBOARD
from .menu import MENU_CIODASHBOARD
from .lib.i18n import _, translate
from .lib.dashboard import Dashboard
from .models.populate import xml2db as _xml2db, db2xml as _db2xml
from .models.dbdashboard import DBDashboard, DBDashboardUser, DBDashboardGroup
from .lib.utils import CIODASHBOARD_NS, CACHE_REGION_USER, CACHE_REGION_GLOBAL


# =============================================================================
[docs] def includeme(configurator: Configurator | ScriptRegistry): """Function to include module. :type configurator: pyramid.config.Configurator :param configurator: Object used to do configuration declaration within the application. """ # Registration Module.register(configurator, ModuleCioDashboard) if not isinstance(configurator, Configurator): return # Cache if 'cache_user' not in configurator.registry or \ 'cache_global' not in configurator.registry: sys_exit(translate(_('*** You must register a cache manager.'))) # Permissions configurator.include('ciodashboard.security') # Routes configurator.include('ciodashboard.routes') # Translation configurator.add_translation_dirs(join(dirname(__file__), 'Locale')) # Views static_dir = join(dirname(__file__), 'Static') Initialize(configurator).add_static_views( __package__, ( ('css', join(static_dir, 'Css')), ('images', join(static_dir, 'Images')))) configurator.scan('ciodashboard.views')
# ============================================================================= # =============================================================================
[docs] class ModuleCioDashboard(Module): """Class for CioDashboard module. :param str config_ini: Absolute path to the configuration file (e.g. development.ini). """ name = _('Dashboard') implements = ('dashboard', ) dependencies = ('warehouse', ) relaxng = RELAXNG_CIODASHBOARD xml2db = (_xml2db, ) db2xml = (_db2xml, ) _DBModule = DBModule # ------------------------------------------------------------------------- def __init__(self, config_ini): """Constructor method.""" super(ModuleCioDashboard, self).__init__(config_ini) self._dashboards = {} self._nav_entry = NavDashboards() # -------------------------------------------------------------------------
[docs] def activate(self, registry, dbsession): """Method to activate the module. See: :meth:`chrysalio.modules.Module.activate` """ # Security if PRINCIPALS_CIODASHBOARD[0] not in registry['principals']: registry['principals'].append(PRINCIPALS_CIODASHBOARD[0]) # Navigation if 'navigation' in registry and 'main' in registry['navigation'] \ and self._nav_entry not in registry['navigation']['main']: registry['navigation']['main'].insert(1, self._nav_entry) # Menu (DEPRECATED) if 'menu' in registry and MENU_CIODASHBOARD not in registry['menu']: registry['menu'].insert(1, MENU_CIODASHBOARD)
# -------------------------------------------------------------------------
[docs] def deactivate(self, registry, dbsession): """Method to deactivate the module. See: :meth:`chrysalio.modules.Module.deactivate` """ # Security if PRINCIPALS_CIODASHBOARD[0] in registry['principals']: registry['principals'].remove(PRINCIPALS_CIODASHBOARD[0]) # Navigation if 'navigation' in registry and 'main' in registry['navigation'] \ and self._nav_entry in registry['navigation']['main']: registry['navigation']['main'].remove(self._nav_entry) # Menu (DEPRECATED) if 'menu' in registry and MENU_CIODASHBOARD in registry['menu']: registry['menu'].remove(MENU_CIODASHBOARD) # Dashboards for dashboard_id in self._dashboards: registry['cache_global'].clear( namespace=cache_namespace(CIODASHBOARD_NS, dashboard_id)) self._dashboards = {}
# ------------------------------------------------------------------------- @cache_user_access(CIODASHBOARD_NS, CACHE_REGION_USER) @classmethod def dashboard_access(cls, request, dashboard): """Return a dictionary defining the authorization of the user on the dashboard. :type request: pyramid.request.Request :param request: Current request. :type dashboard: .lib.dashboard.Dashboard :param dashboard: Current dashboard object. :rtype: tuple :return: A tuple such as ``(True,)``. Thanks to the decorator, the user cache ``ciodsh-<dashboard_id>`` stores the access to the dashboard. """ if dashboard is None: return (None, ) # Compute rights user_id = request.session['user']['user_id'] \ if 'user' in request.session else '' rights = request.dbsession.query(DBDashboardUser)\ .filter_by(dashboard_id=dashboard.uid, user_id=user_id).first() rights = rights is not None if not rights: groups = request.session['user']['groups'] \ if 'user' in request.session else () rights = request.dbsession.query(DBDashboardGroup)\ .filter_by(dashboard_id=dashboard.uid)\ .filter(DBDashboardGroup.group_id.in_(groups)).first() rights = rights is not None i_creator = request.has_permission('dashboard-create') # Compute access if dashboard.access == 'closed': access = (True if i_creator else None, ) elif dashboard.access == 'free' or i_creator: access = (True, ) else: access = (rights or None, ) return access # ------------------------------------------------------------------------- @cache_global_item(CIODASHBOARD_NS, CACHE_REGION_GLOBAL, dashboard_access) @classmethod def dashboard(cls, request, dashboard_id): """Return the dashboard with ID ``dashboard_id`` or ``None``. :type request: pyramid.request.Request :param request: Current request. :param str dashboard_id: ID of the dashboard to return. :rtype: :class:`.lib.dashboard.Dashboard` or ``None`` Thanks to the decorator, the global cache ``ciodsh-<dashboard_id>`` stores the current state of the dashboard. """ if not dashboard_id: return None dbdashboard = request.dbsession.query(DBDashboard).filter_by( dashboard_id=dashboard_id).first() if dbdashboard is None: return None return Dashboard(request, dbdashboard)