try: import lasso except ImportError: pass import json 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 _ 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 from .payments import Invoice, Regie, is_payment_supported class MyInvoicesDirectory(Directory): _q_exports = [''] def _q_traverse(self, path): if not is_payment_supported(): raise errors.TraversalError() get_response().breadcrumb.append(('invoices/', _('Invoices'))) return Directory._q_traverse(self, path) def _q_index(self): user = get_request().user if not user or user.anonymous: raise errors.AccessUnauthorizedError() template.html_top(_('Invoices')) r = TemplateIO(html=True) r += TextsDirectory.get_html_text('aq-myspace-invoice') r += get_session().display_message() invoices = [] invoices.extend(Invoice.get_with_indexed_value( str('user_id'), str(user.id))) invoices.sort(key=lambda x: (x.regie_id, -x.date.toordinal())) last_regie_id = None unpaid = False for invoice in invoices: if invoice.regie_id != last_regie_id: if last_regie_id: r += htmltext('') if unpaid: r += htmltext('') % _('Pay Selected Invoices') r += htmltext('') last_regie_id = invoice.regie_id r += htmltext('

%s

') % Regie.get(last_regie_id).label unpaid = False r += htmltext('
' % get_publisher().get_frontoffice_url()) r += htmltext('') if unpaid: r += htmltext('') % _('Pay Selected Invoices') r += htmltext('
') return r.getvalue() 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)) user_forms.sort(key=lambda x: x.receipt_time) 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', 'invoices', 'json'] invoices = MyInvoicesDirectory() json = JsonDirectory() def _q_traverse(self, path): get_response().filter['bigdiv'] = 'profile' 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)) user_forms.sort(key=lambda x: x.receipt_time) profile_links = [] if not get_cfg('sp', {}).get('idp-manage-user-attributes', False): if user_formdef: profile_links.append('%s' % _('My Profile')) if user_forms: profile_links.append('%s' % _('My Forms')) if is_payment_supported(): profile_links.append('%s' % _('My Invoices')) root_url = get_publisher().get_root_url() if user.can_go_in_backoffice(): profile_links.append('%s' % (root_url, _('Back office'))) if user.is_admin: profile_links.append('%s' % (root_url, _('Admin'))) if profile_links: r += htmltext('') 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('

') 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(' %s.') % _('Delete My Account') r += htmltext('

') if user_forms: r += htmltext('

%s

') % _('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('

%s

') % _('My Profile') r += TextsDirectory.get_html_text('top-of-profile') if user.form_data: r += htmltext('') else: r += htmltext('

%s

') % _('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('

%s

') % _('Edit My Profile') if ident_method == 'password' and passwords_cfg.get('can_change', False): r += htmltext('

%s

') % _('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('

%s

' % _( '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() TextsDirectory.register('aq-myspace-invoice', N_('Message on top of invoices page'), category = N_('Invoices'))