From 280c79a94a9c38d56bde0ff4b608e1bc9ef9401e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= Date: Thu, 29 Dec 2022 11:03:00 +0100 Subject: [PATCH] misc: remove root directory changes (#72822) --- auquotidien/modules/root.py | 505 ------------------------------------ tests/test_admin_pages.py | 2 +- 2 files changed, 1 insertion(+), 506 deletions(-) diff --git a/auquotidien/modules/root.py b/auquotidien/modules/root.py index 982588f..d22bebc 100644 --- a/auquotidien/modules/root.py +++ b/auquotidien/modules/root.py @@ -1,212 +1,14 @@ -import urllib.parse - -from quixote import get_publisher, get_response, get_request, redirect, get_session -from quixote.directory import Directory -from quixote.html import TemplateIO, htmltext - -from wcs.qommon import _ -from wcs.qommon.misc import get_variadic_url, simplify - -import os -import re -import string - -try: - import lasso -except ImportError: - pass - import wcs import wcs.root from wcs import qommon -from wcs.forms.root import RootDirectory as FormsRootDirectory -from wcs.qommon import N_, get_cfg, get_logger -from wcs.qommon import template -from wcs.qommon import errors -from wcs.qommon.form import * -from wcs.qommon import logger -from wcs.roles import logged_users_role - -from wcs.qommon import emails -from wcs.qommon.sms import SMS -from wcs.categories import Category -from wcs.formdef import FormDef -from wcs.data_sources import NamedDataSource -from wcs.qommon.tokens import Token -from wcs.qommon.admin.emails import EmailsDirectory -from wcs.qommon.admin.texts import TextsDirectory import wcs.forms.root -from wcs.workflows import Workflow from wcs.forms.preview import PreviewDirectory from .saml2 import Saml2Directory OldRootDirectory = wcs.root.RootDirectory -import wcs.qommon.ident.password -import wcs.qommon.ident.idp - - -def category_get_homepage_position(self): - if hasattr(self, 'homepage_position') and self.homepage_position: - return self.homepage_position - if self.url_name == 'consultations': - return '2nd' - return '1st' - - -Category.get_homepage_position = category_get_homepage_position - - -def category_get_limit(self): - if hasattr(self, 'limit') and self.limit is not None: - return self.limit - return 7 - - -Category.get_limit = category_get_limit - -Category.TEXT_ATTRIBUTES = ['name', 'url_name', 'description', 'homepage_position'] -Category.INT_ATTRIBUTES = ['position', 'limit'] - -OldRegisterDirectory = wcs.root.RegisterDirectory - - -class AlternateRegisterDirectory(OldRegisterDirectory): - def _q_traverse(self, path): - return OldRegisterDirectory._q_traverse(self, path) - - def _q_index(self): - get_logger().info('register') - ident_methods = get_cfg('identification', {}).get('methods', []) - - if len(ident_methods) == 0: - idps = get_cfg('idp', {}) - if len(idps) == 0: - return template.error_page(_('Authentication subsystem is not yet configured.')) - ident_methods = ['idp'] # fallback to old behaviour; saml. - - if len(ident_methods) == 1: - method = ident_methods[0] - else: - method = 'password' - - return wcs.qommon.ident.register(method) - - -OldLoginDirectory = wcs.root.LoginDirectory - - -class AlternateLoginDirectory(OldLoginDirectory): - def _q_traverse(self, path): - return OldLoginDirectory._q_traverse(self, path) - - def _q_index(self): - get_logger().info('login') - ident_methods = get_cfg('identification', {}).get('methods', []) - - if get_request().form.get('ReturnUrl'): - get_request().form['next'] = get_request().form.pop('ReturnUrl') - - if 'IsPassive' in get_request().form and 'idp' in ident_methods: - # if isPassive is given in query parameters, we restrict ourselves - # to saml login. - ident_methods = ['idp'] - - if len(ident_methods) > 1 and 'idp' in ident_methods: - # if there is more than one identification method, and there is a - # possibility of SSO, if we got there as a consequence of an access - # unauthorized url on admin/ or backoffice/, then idp auth method - # is chosen forcefully. - after_url = get_request().form.get('next') - if after_url: - root_url = get_publisher().get_root_url() - after_path = urllib.parse.urlparse(after_url)[2] - after_path = after_path[len(root_url) :] - if after_path.startswith(str('admin')) or after_path.startswith(str('backoffice')): - ident_methods = ['idp'] - - # don't display authentication system choice - if len(ident_methods) == 1: - method = ident_methods[0] - try: - return wcs.qommon.ident.login(method) - except KeyError: - get_logger().error('failed to login with method %s' % method) - return errors.TraversalError() - - if sorted(ident_methods) == ['idp', 'password']: - r = TemplateIO(html=True) - get_response().breadcrumb.append(('login', _('Login'))) - identities_cfg = get_cfg('identities', {}) - form = Form(enctype='multipart/form-data', id='login-form', use_tokens=False) - if identities_cfg.get('email-as-username', False): - form.add(StringWidget, 'username', title=_('Email'), size=25, required=True) - else: - form.add(StringWidget, 'username', title=_('Username'), size=25, required=True) - form.add(PasswordWidget, 'password', title=_('Password'), size=25, required=True) - form.add_submit('submit', _('Connect')) - if form.is_submitted() and not form.has_errors(): - tmp = wcs.qommon.ident.password.MethodDirectory().login_submit(form) - if not form.has_errors(): - return tmp - - r += htmltext('
') - r += get_session().display_message() - r += form.render() - - base_url = get_publisher().get_root_url() - r += htmltext('

%s

') % ( - base_url, - _('Forgotten password ?'), - ) - - r += htmltext('
') - - # XXX: this part only supports a single IdP - r += htmltext('
') - r += TextsDirectory.get_html_text('aq-sso-text') - form = Form(enctype='multipart/form-data', action='%sident/idp/login' % base_url) - form.add_hidden('method', 'idp') - for kidp, idp in get_cfg('idp', {}).items(): - p = lasso.Provider( - lasso.PROVIDER_ROLE_IDP, - misc.get_abs_path(idp['metadata']), - misc.get_abs_path(idp.get('publickey')), - None, - ) - form.add_hidden('idp', p.providerId) - break - form.add_submit('submit', _('Connect')) - - r += form.render() - r += htmltext('
') - - get_request().environ['REQUEST_METHOD'] = 'GET' - - r += htmltext( - """""" - ) - return r.getvalue() - else: - return OldLoginDirectory._q_index(self) - - -OldIdentDirectory = wcs.root.IdentDirectory - - -class AlternateIdentDirectory(OldIdentDirectory): - def _q_traverse(self, path): - return OldIdentDirectory._q_traverse(self, path) - - -class AlternatePreviewDirectory(PreviewDirectory): - def _q_traverse(self, path): - return super(AlternatePreviewDirectory, self)._q_traverse(path) - class AlternateRootDirectory(OldRootDirectory): _q_exports = [ @@ -240,318 +42,11 @@ class AlternateRootDirectory(OldRootDirectory): 'actions', ] - register = AlternateRegisterDirectory() - login = AlternateLoginDirectory() - ident = AlternateIdentDirectory() saml = Saml2Directory() code = wcs.forms.root.TrackingCodesDirectory() - preview = AlternatePreviewDirectory() - - def get_substitution_variables(self): - return {'links': ''} - - def _q_traverse(self, path): - self.feed_substitution_parts() - - response = get_response() - if not hasattr(response, 'filter'): - response.filter = {} - - response.filter['auquotidien'] = True - if not path or (path[0] not in ('api', 'backoffice') and not get_request().is_json()): - # api & backoffice have no use for a side box - response.filter['gauche'] = lambda x: self.box_side(path) - get_publisher().substitutions.feed(self) - - response.breadcrumb = [('', _('Home'))] - - if not self.admin: - self.admin = get_publisher().admin_directory_class() - - if not self.backoffice: - self.backoffice = get_publisher().backoffice_directory_class() - - return super()._q_traverse(path) - - def json(self): - return FormsRootDirectory().json() - - def categories(self): - return FormsRootDirectory().categories() - - def _q_index(self): - if get_request().is_json(): - return FormsRootDirectory().json() - - root_url = get_publisher().get_root_url() - if get_request().user and get_request().user.anonymous and get_request().user.lasso_dump: - return redirect('%smyspace/new' % root_url) - - redirect_url = get_cfg('misc', {}).get('homepage-redirect-url') - if redirect_url: - return redirect( - misc.get_variadic_url(redirect_url, get_publisher().substitutions.get_context_variables()) - ) - - template.html_top() - r = TemplateIO(html=True) - get_response().filter['is_index'] = True - - r += htmltext('
') - r += self.box_services(position='1st') - r += htmltext('
') - r += htmltext('
') - r += self.myspace_snippet() - r += self.box_services(position='2nd') - r += self.consultations() - r += htmltext('
') - - user = get_request().user - if user and user.can_go_in_backoffice(): - get_response().filter['backoffice'] = True - - return r.getvalue() - - def services(self): - template.html_top() - return self.box_services(level=2) - - def box_services(self, level=3, position=None): - ## Services - if get_request().user and get_request().user.roles: - accepted_roles = get_request().user.roles - else: - accepted_roles = [] - - cats = Category.select(order_by='name') - cats = [x for x in cats if x.url_name != 'consultations'] - Category.sort_by_position(cats) - - all_formdefs = FormDef.select( - lambda x: not x.is_disabled() or x.disabled_redirection, order_by='name' - ) - - if position: - t = self.display_list_of_formdefs( - [x for x in cats if x.get_homepage_position() == position], all_formdefs, accepted_roles - ) - else: - t = self.display_list_of_formdefs(cats, all_formdefs, accepted_roles) - - if not t: - return - - r = TemplateIO(html=True) - - if position == '2nd': - r += htmltext('
') - else: - r += htmltext('
') - if level == 2: - r += htmltext('

%s

') % _('Services') - else: - r += htmltext('

%s

') % _('Services') - - if 'auquotidien-welcome-in-services' in get_response().filter.get('keywords', []): - homepage_text = TextsDirectory.get_html_text('aq-home-page') - if homepage_text: - r += htmltext('
') - r += homepage_text - r += htmltext('
') - - r += htmltext('
    ') - r += t - r += htmltext('
') - - r += htmltext('
') - return r.getvalue() - - def display_list_of_formdefs(self, cats, all_formdefs, accepted_roles): - r = TemplateIO(html=True) - for category in cats: - if category.url_name == 'consultations': - self.consultations_category = category - continue - formdefs = [x for x in all_formdefs if str(x.category_id) == str(category.id)] - formdefs_advertise = [] - - for formdef in formdefs[:]: - if formdef.is_disabled(): # is a redirection - continue - if not formdef.roles: - continue - if not get_request().user: - if formdef.always_advertise: - formdefs_advertise.append(formdef) - formdefs.remove(formdef) - continue - if logged_users_role().id in formdef.roles: - continue - for q in accepted_roles: - if q in formdef.roles: - break - else: - if formdef.always_advertise: - formdefs_advertise.append(formdef) - formdefs.remove(formdef) - - if not formdefs and not formdefs_advertise: - continue - - keywords = {} - for formdef in formdefs: - for keyword in formdef.keywords_list: - keywords[keyword] = True - - r += htmltext('
  • ') % ( - category.url_name, - ' '.join(keywords), - ) - r += htmltext('') - r += htmltext('') % category.url_name - r += category.name - r += htmltext('\n') - r += category.get_description_html_text() - r += htmltext('
      ') - limit = category.get_limit() - for formdef in formdefs[:limit]: - r += htmltext('
    • ') % ' '.join(formdef.keywords_list) - classes = [] - if formdef.is_disabled() and formdef.disabled_redirection: - classes.append('redirection') - r += htmltext('%s') % ( - ' '.join(classes), - category.url_name, - formdef.url_name, - formdef.name, - ) - r += htmltext('
    • \n') - if len(formdefs) < limit: - for formdef in formdefs_advertise[: limit - len(formdefs)]: - r += htmltext('
    • ') - r += htmltext('%s') % ( - category.url_name, - formdef.url_name, - formdef.name, - ) - r += htmltext(' (%s)') % _('authentication required') - r += htmltext('
    • \n') - if (len(formdefs) + len(formdefs_advertise)) > limit: - r += htmltext('
    • %s
    • ') % ( - category.url_name, - _('Access to all forms of the "%s" category') % category.name, - _('Access to all forms in this category'), - ) - r += htmltext('
    ') - r += htmltext('
  • \n') - - return r.getvalue() - - def consultations(self): - cats = [x for x in Category.select() if x.url_name == 'consultations'] - if not cats: - return - consultations_category = cats[0] - formdefs = FormDef.select( - lambda x: ( - str(x.category_id) == str(consultations_category.id) - and (not x.is_disabled() or x.disabled_redirection) - ), - order_by='name', - ) - if not formdefs: - return - ## Consultations - r = TemplateIO(html=True) - r += htmltext('
    ') - r += htmltext('

    %s

    ') % _('Consultations') - r += consultations_category.get_description_html_text() - r += htmltext('
      ') - for formdef in formdefs: - r += htmltext('
    • ') - r += htmltext('%s') % ( - consultations_category.url_name, - formdef.url_name, - formdef.name, - ) - r += htmltext('
    • ') - r += htmltext('
    ') - r += htmltext('
    ') - return r.getvalue() - - def box_side(self, path): - r = TemplateIO(html=True) - root_url = get_publisher().get_root_url() - - if ( - path == [''] - and 'include-tracking-code-form' in get_response().filter.get('keywords', []) - and self.has_anonymous_access_codes() - ): - r += htmltext('
    ') % root_url - r += htmltext('

    %s

    ') % _('Tracking code') - r += htmltext('') % _('ex: RPQDFVCD') - r += htmltext('') % _('Load') - r += htmltext('
    ') - - cats = Category.select(order_by='name') - cats = [x for x in cats if x.url_name != 'consultations' and x.get_homepage_position() == 'side'] - Category.sort_by_position(cats) - if cats: - r += htmltext('
    ') - r += htmltext('

    %s

    ') % _('Services') - r += htmltext('
      ') - for cat in cats: - r += htmltext('
    • %s
    • ') % (cat.url_name, cat.name) - r += htmltext('
    ') - r += htmltext('
    ') - - v = r.getvalue() - if v: - r = TemplateIO(html=True) - r += htmltext('') - return r.getvalue() - - return None - - def has_anonymous_access_codes(self): - return any((x for x in FormDef.select() if x.enable_tracking_codes)) - - def myspace_snippet(self): - r = TemplateIO(html=True) - r += htmltext('
    ') - r += htmltext('

    %s

    ') % _('My Space') - r += htmltext('
      ') - if get_request().user and not get_request().user.anonymous: - r += htmltext('
    • %s
    • ') % _( - 'Access to your personal space' - ) - r += htmltext('
    • %s
    • ') % _('Logout') - else: - r += htmltext('
    • %s
    • ') % _('Registration') - r += htmltext('
    • %s
    • ') % _('Login') - r += htmltext('
    ') - r += htmltext('
    ') - return r.getvalue() from qommon.publisher import get_publisher_class -get_publisher_class().root_directory_class = AlternateRootDirectory get_publisher_class().after_login_url = 'myspace/' get_publisher_class().use_sms_feature = True - - -TextsDirectory.register( - 'aq-sso-text', - N_('Connecting with Identity Provider'), - default=N_( - '''

    Connecting with Identity Provider

    -

    You can also use your identity provider to connect. -

    ''' - ), -) - -TextsDirectory.register('aq-home-page', N_('Home Page'), wysiwyg=True) diff --git a/tests/test_admin_pages.py b/tests/test_admin_pages.py index e673548..26bb023 100644 --- a/tests/test_admin_pages.py +++ b/tests/test_admin_pages.py @@ -81,4 +81,4 @@ def test_with_superuser(): create_superuser() app = login(get_app(pub)) # this makes sure the extension loaded properly - resp = app.get('/backoffice/settings/texts/aq-home-page', status=200) + assert 'auquotidien' in pub.translation_domains