From 784f536b178e27550b448248399ecb3d5a386927 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= <fpeters@entrouvert.com>
Date: Thu, 29 Dec 2022 10:04:45 +0100
Subject: [PATCH] misc: remove custom myspace page (#72820)

---
 auquotidien/modules/myspace.py | 321 ---------------------------------
 auquotidien/modules/root.py    |   3 -
 tests/test_user_pages.py       |  55 ------
 3 files changed, 379 deletions(-)
 delete mode 100644 auquotidien/modules/myspace.py

diff --git a/auquotidien/modules/myspace.py b/auquotidien/modules/myspace.py
deleted file mode 100644
index ed861e4..0000000
--- a/auquotidien/modules/myspace.py
+++ /dev/null
@@ -1,321 +0,0 @@
-try:
-    import lasso
-except ImportError:
-    pass
-
-import json
-import time
-
-from quixote import get_publisher, get_request, redirect, get_response, get_session_manager, get_session
-from quixote.directory import AccessControlled, Directory
-from quixote.html import TemplateIO, htmltext
-from quixote.util import StaticFile, FileStream
-
-from wcs.qommon import _, N_
-from wcs.qommon import template
-from wcs.qommon.form import *
-from wcs.qommon import get_cfg, get_logger
-from wcs.qommon import errors
-from wcs.api import get_user_from_api_query_string
-
-import wcs.qommon.ident.password
-from wcs.qommon.ident.password_accounts import PasswordAccount
-
-from wcs.qommon.admin.texts import TextsDirectory
-
-from wcs.formdef import FormDef
-import wcs.myspace
-
-
-class JsonDirectory(Directory):
-    """Export of several lists in json, related to the current user or the
-    SAMLv2 NameID we'd get in the URL"""
-
-    _q_exports = ['forms']
-
-    user = None
-
-    def _q_traverse(self, path):
-        self.user = get_user_from_api_query_string() or get_request().user
-        if not self.user:
-            raise errors.AccessUnauthorizedError()
-        return Directory._q_traverse(self, path)
-
-    def forms(self):
-        formdefs = FormDef.select(order_by='name', ignore_errors=True)
-        user_forms = []
-        for formdef in formdefs:
-            user_forms.extend(formdef.data_class().get_with_indexed_value('user_id', self.user.id))
-        epoch = time.localtime(1970)
-        user_forms.sort(key=lambda x: x.receipt_time or epoch)
-
-        get_response().set_content_type('application/json')
-
-        forms_output = []
-        for form in user_forms:
-            visible_status = form.get_visible_status(user=self.user)
-            # skip drafts and hidden forms
-            if not visible_status:
-                continue
-            name = form.formdef.name
-            id = form.get_display_id()
-            status = visible_status.name
-            title = _('%(name)s #%(id)s (%(status)s)') % {'name': name, 'id': id, 'status': status}
-            url = form.get_url()
-            d = {'title': title, 'url': url}
-            d.update(form.get_substitution_variables(minimal=True))
-            forms_output.append(d)
-        return json.dumps(forms_output, cls=misc.JSONEncoder)
-
-
-class MyspaceDirectory(wcs.myspace.MyspaceDirectory):
-    _q_exports = ['', 'profile', 'new', 'password', 'remove', 'drafts', 'forms', 'json']
-
-    json = JsonDirectory()
-
-    def _q_traverse(self, path):
-        get_response().breadcrumb.append(('myspace/', _('My Space')))
-
-        # Migrate custom text settings
-        texts_cfg = get_cfg('texts', {})
-        if 'text-aq-top-of-profile' in texts_cfg and (not 'text-top-of-profile' in texts_cfg):
-            texts_cfg['text-top-of-profile'] = texts_cfg['text-aq-top-of-profile']
-            del texts_cfg['text-aq-top-of-profile']
-            get_publisher().write_cfg()
-
-        return Directory._q_traverse(self, path)
-
-    def _q_index(self):
-        user = get_request().user
-        if not user:
-            raise errors.AccessUnauthorizedError()
-        template.html_top(_('My Space'))
-        r = TemplateIO(html=True)
-        if user.anonymous:
-            return redirect('new')
-
-        user_formdef = user.get_formdef()
-
-        user_forms = []
-        if user:
-            formdefs = FormDef.select(order_by='name', ignore_errors=True)
-            user_forms = []
-            for formdef in formdefs:
-                user_forms.extend(formdef.data_class().get_with_indexed_value('user_id', user.id))
-            epoch = time.localtime(1970)
-            user_forms.sort(key=lambda x: x.receipt_time or epoch)
-
-        profile_links = []
-        if not get_cfg('sp', {}).get('idp-manage-user-attributes', False):
-            if user_formdef:
-                profile_links.append('<a href="#my-profile">%s</a>' % _('My Profile'))
-        if user_forms:
-            profile_links.append('<a href="#my-forms">%s</a>' % _('My Forms'))
-
-        root_url = get_publisher().get_root_url()
-        if user.can_go_in_backoffice():
-            profile_links.append('<a href="%sbackoffice/">%s</a>' % (root_url, _('Back office')))
-        if user.is_admin:
-            profile_links.append('<a href="%sadmin/">%s</a>' % (root_url, _('Admin')))
-
-        if profile_links:
-            r += htmltext('<p id="profile-links">')
-            r += htmltext(' - '.join(profile_links))
-            r += htmltext('</p>')
-
-        if not get_cfg('sp', {}).get('idp-manage-user-attributes', False):
-            if user_formdef:
-                r += self._my_profile(user_formdef, user)
-
-            r += self._index_buttons(user_formdef)
-
-            try:
-                x = PasswordAccount.get_on_index(get_request().user.id, str('user_id'))
-            except KeyError:
-                pass
-            else:
-                r += htmltext('<p>')
-                r += _(
-                    'You can delete your account freely from the services portal. '
-                    'This action is irreversible; it will destruct your personal '
-                    'datas and destruct the access to your request history.'
-                )
-                r += htmltext(' <strong><a href="remove" rel="popup">%s</a></strong>.') % _(
-                    'Delete My Account'
-                )
-                r += htmltext('</p>')
-
-        if user_forms:
-            r += htmltext('<h3 id="my-forms">%s</h3>') % _('My Forms')
-            from . import root
-
-            r += root.FormsRootDirectory().user_forms(user_forms)
-
-        return r.getvalue()
-
-    def _my_profile(self, user_formdef, user):
-        r = TemplateIO(html=True)
-        r += htmltext('<h3 id="my-profile">%s</h3>') % _('My Profile')
-
-        r += TextsDirectory.get_html_text('top-of-profile')
-
-        if user.form_data:
-            r += htmltext('<ul>')
-            for field in user_formdef.fields:
-                if not hasattr(field, str('get_view_value')):
-                    continue
-                value = user.form_data.get(field.id)
-                r += htmltext('<li>')
-                r += field.label
-                r += ' : '
-                if value:
-                    r += field.get_view_value(value)
-                r += htmltext('</li>')
-            r += htmltext('</ul>')
-        else:
-            r += htmltext('<p>%s</p>') % _('Empty profile')
-        return r.getvalue()
-
-    def _index_buttons(self, form_data):
-        r = TemplateIO(html=True)
-        passwords_cfg = get_cfg('passwords', {})
-        ident_method = get_cfg('identification', {}).get('methods', ['idp'])[0]
-        if get_session().lasso_session_dump:
-            ident_method = 'idp'
-
-        if form_data and ident_method != 'idp':
-            r += htmltext('<p class="command"><a href="profile" rel="popup">%s</a></p>') % _(
-                'Edit My Profile'
-            )
-
-        if ident_method == 'password' and passwords_cfg.get('can_change', False):
-            r += htmltext('<p class="command"><a href="password" rel="popup">%s</a></p>') % _(
-                'Change My Password'
-            )
-
-        return r.getvalue()
-
-    def profile(self):
-        user = get_request().user
-        if not user or user.anonymous:
-            raise errors.AccessUnauthorizedError()
-
-        form = Form(enctype='multipart/form-data')
-        formdef = user.get_formdef()
-        formdef.add_fields_to_form(form, form_data=user.form_data)
-
-        form.add_submit('submit', _('Apply Changes'))
-        form.add_submit('cancel', _('Cancel'))
-
-        if form.get_submit() == 'cancel':
-            return redirect('.')
-
-        if form.is_submitted() and not form.has_errors():
-            self.profile_submit(form, formdef)
-            return redirect('.')
-
-        template.html_top(_('Edit Profile'))
-        return form.render()
-
-    def profile_submit(self, form, formdef):
-        user = get_request().user
-        data = formdef.get_data(form)
-
-        user.set_attributes_from_formdata(data)
-        user.form_data = data
-
-        user.store()
-
-    def password(self):
-        ident_method = get_cfg('identification', {}).get('methods', ['idp'])[0]
-        if ident_method != 'password':
-            raise errors.TraversalError()
-
-        user = get_request().user
-        if not user or user.anonymous:
-            raise errors.AccessUnauthorizedError()
-
-        form = Form(enctype='multipart/form-data')
-        form.add(PasswordWidget, 'new_password', title=_('New Password'), required=True)
-        form.add(PasswordWidget, 'new2_password', title=_('New Password (confirm)'), required=True)
-
-        form.add_submit('submit', _('Change Password'))
-        form.add_submit('cancel', _('Cancel'))
-
-        if form.get_submit() == 'cancel':
-            return redirect('.')
-
-        if form.is_submitted() and not form.has_errors():
-            wcs.qommon.ident.password.check_password(form, 'new_password')
-            new_password = form.get_widget('new_password').parse()
-            new2_password = form.get_widget('new2_password').parse()
-            if new_password != new2_password:
-                form.set_error('new2_password', _('Passwords do not match'))
-
-        if form.is_submitted() and not form.has_errors():
-            self.submit_password(new_password)
-            return redirect('.')
-
-        template.html_top(_('Change Password'))
-        return form.render()
-
-    def submit_password(self, new_password):
-        passwords_cfg = get_cfg('passwords', {})
-        account = PasswordAccount.get(get_session().username)
-        account.hashing_algo = passwords_cfg.get('hashing_algo')
-        account.set_password(new_password)
-        account.store()
-
-    def new(self):
-        if not get_request().user or not get_request().user.anonymous:
-            raise errors.AccessUnauthorizedError()
-
-        form = Form(enctype='multipart/form-data')
-        formdef = get_publisher().user_class.get_formdef()
-        if formdef:
-            formdef.add_fields_to_form(form)
-        else:
-            get_logger().error('missing user formdef (in myspace/new)')
-
-        form.add_submit('submit', _('Register'))
-
-        if form.is_submitted() and not form.has_errors():
-            user = get_publisher().user_class()
-            data = formdef.get_data(form)
-            user.set_attributes_from_formdata(data)
-            user.name_identifiers = get_request().user.name_identifiers
-            user.lasso_dump = get_request().user.lasso_dump
-            user.set_attributes_from_formdata(data)
-            user.form_data = data
-            user.store()
-            get_session().set_user(user.id)
-            root_url = get_publisher().get_root_url()
-            return redirect('%smyspace' % root_url)
-
-        template.html_top(_('Welcome'))
-        return form.render()
-
-    def remove(self):
-        user = get_request().user
-        if not user or user.anonymous:
-            raise errors.AccessUnauthorizedError()
-
-        form = Form(enctype='multipart/form-data')
-        form.widgets.append(
-            HtmlWidget('<p>%s</p>' % _('Are you really sure you want to remove your account?'))
-        )
-        form.add_submit('submit', _('Remove my account'))
-        form.add_submit('cancel', _('Cancel'))
-
-        if form.get_submit() == 'cancel':
-            return redirect('.')
-
-        if form.is_submitted() and not form.has_errors():
-            user = get_request().user
-            account = PasswordAccount.get_on_index(user.id, str('user_id'))
-            get_session_manager().expire_session()
-            account.remove_self()
-            return redirect(get_publisher().get_root_url())
-
-        template.html_top(_('Removing Account'))
-        return form.render()
diff --git a/auquotidien/modules/root.py b/auquotidien/modules/root.py
index 6986a01..982588f 100644
--- a/auquotidien/modules/root.py
+++ b/auquotidien/modules/root.py
@@ -36,8 +36,6 @@ from wcs.qommon.tokens import Token
 from wcs.qommon.admin.emails import EmailsDirectory
 from wcs.qommon.admin.texts import TextsDirectory
 
-from .myspace import MyspaceDirectory
-
 import wcs.forms.root
 from wcs.workflows import Workflow
 from wcs.forms.preview import PreviewDirectory
@@ -245,7 +243,6 @@ class AlternateRootDirectory(OldRootDirectory):
     register = AlternateRegisterDirectory()
     login = AlternateLoginDirectory()
     ident = AlternateIdentDirectory()
-    myspace = MyspaceDirectory()
     saml = Saml2Directory()
     code = wcs.forms.root.TrackingCodesDirectory()
     preview = AlternatePreviewDirectory()
diff --git a/tests/test_user_pages.py b/tests/test_user_pages.py
index 85b83da..90d42a4 100644
--- a/tests/test_user_pages.py
+++ b/tests/test_user_pages.py
@@ -69,61 +69,6 @@ def test_with_user():
     user = create_user()
     app = login(get_app(pub), username='user', password='user')
     resp = app.get('/', status=200)
-    resp = app.get('/myspace/', status=200)
-
-
-def test_myspace_with_user_forms():
-    user = create_user()
-    formdef = create_formdef()
-
-    cat = Category(name='cat')
-    cat.store()
-    formdef.category_id = cat.id
-    formdef.enable_tracking_codes = True
-
-    wf = Workflow(name='status')
-    st1 = wf.add_status('Status1', 'st1')
-    wf.store()
-    formdef.workflow_id = wf.id
-    formdef.store()
-
-    formdef.data_class().wipe()
-    formdata = formdef.data_class()()
-    formdata.user_id = user.id
-    formdata.status = 'wf-st1'
-    formdata.receipt_time = time.localtime()
-    formdata.data = {}
-    formdata.store()
-    draft = formdef.data_class()()
-    draft.user_id = user.id
-    draft.status = 'draft'
-    draft.receipt_time = time.localtime()
-    draft.data = {}
-    draft.store()
-
-    app = login(get_app(pub), username='user', password='user')
-    resp = app.get('/myspace/')
-    assert formdata.id != draft.id
-    assert '<a href="/test/%s/"' % formdata.id in resp
-    assert '<a href="/test/%s/"' % draft.id in resp
-    resp = app.get('/test/%s/' % formdata.id, status=302)
-    assert resp.location == 'http://example.net/cat/test/%s/' % formdata.id
-    resp = app.get('/test/%s/' % draft.id, status=302)
-    resp = resp.follow(status=302)
-    assert resp.location.startswith('http://example.net/cat/test/?mt=')
-    resp = resp.follow(status=200)
-
-    # disable formdef: formdatas are still visible and accessible, drafts are not
-    formdef.disabled = True
-    formdef.store()
-    resp = app.get('/myspace/')
-    assert formdata.id != draft.id
-    assert '<a href="/test/%s/"' % formdata.id in resp
-    assert not '<a href="/test/%s"' % draft.id in resp
-    resp = app.get('/cat/test/%s' % formdata.id)
-    resp.status_int = 200
-    resp = app.get('/cat/test/%s/' % draft.id, status=302)
-    resp = resp.follow(status=403)
 
 
 def test_form_category_redirection():
-- 
2.39.0

