Projet

Général

Profil

Télécharger (11,5 ko) Statistiques
| Branche: | Tag: | Révision:

root / auquotidien / modules / myspace.py @ cb4c30bc

1
try:
2
    import lasso
3
except ImportError:
4
    pass
5

    
6
import json
7
import time
8

    
9
from quixote import get_publisher, get_request, redirect, get_response, get_session_manager, get_session
10
from quixote.directory import AccessControlled, Directory
11
from quixote.html import TemplateIO, htmltext
12
from quixote.util import StaticFile, FileStream
13

    
14
from wcs.qommon import _, N_
15
from wcs.qommon import template
16
from wcs.qommon.form import *
17
from wcs.qommon import get_cfg, get_logger
18
from wcs.qommon import errors
19
from wcs.api import get_user_from_api_query_string
20

    
21
import wcs.qommon.ident.password
22
from wcs.qommon.ident.password_accounts import PasswordAccount
23

    
24
from wcs.qommon.admin.texts import TextsDirectory
25

    
26
from wcs.formdef import FormDef
27
import wcs.myspace
28

    
29

    
30
class JsonDirectory(Directory):
31
    """Export of several lists in json, related to the current user or the
32
    SAMLv2 NameID we'd get in the URL"""
33

    
34
    _q_exports = ['forms']
35

    
36
    user = None
37

    
38
    def _q_traverse(self, path):
39
        self.user = get_user_from_api_query_string() or get_request().user
40
        if not self.user:
41
            raise errors.AccessUnauthorizedError()
42
        return Directory._q_traverse(self, path)
43

    
44
    def forms(self):
45
        formdefs = FormDef.select(order_by='name', ignore_errors=True)
46
        user_forms = []
47
        for formdef in formdefs:
48
            user_forms.extend(formdef.data_class().get_with_indexed_value('user_id', self.user.id))
49
        epoch = time.localtime(1970)
50
        user_forms.sort(key=lambda x: x.receipt_time or epoch)
51

    
52
        get_response().set_content_type('application/json')
53

    
54
        forms_output = []
55
        for form in user_forms:
56
            visible_status = form.get_visible_status(user=self.user)
57
            # skip drafts and hidden forms
58
            if not visible_status:
59
                continue
60
            name = form.formdef.name
61
            id = form.get_display_id()
62
            status = visible_status.name
63
            title = _('%(name)s #%(id)s (%(status)s)') % {'name': name, 'id': id, 'status': status}
64
            url = form.get_url()
65
            d = {'title': title, 'url': url}
66
            d.update(form.get_substitution_variables(minimal=True))
67
            forms_output.append(d)
68
        return json.dumps(forms_output, cls=misc.JSONEncoder)
69

    
70

    
71
class MyspaceDirectory(wcs.myspace.MyspaceDirectory):
72
    _q_exports = ['', 'profile', 'new', 'password', 'remove', 'drafts', 'forms', 'json']
73

    
74
    json = JsonDirectory()
75

    
76
    def _q_traverse(self, path):
77
        get_response().filter['bigdiv'] = 'profile'
78
        get_response().breadcrumb.append(('myspace/', _('My Space')))
79

    
80
        # Migrate custom text settings
81
        texts_cfg = get_cfg('texts', {})
82
        if 'text-aq-top-of-profile' in texts_cfg and (not 'text-top-of-profile' in texts_cfg):
83
            texts_cfg['text-top-of-profile'] = texts_cfg['text-aq-top-of-profile']
84
            del texts_cfg['text-aq-top-of-profile']
85
            get_publisher().write_cfg()
86

    
87
        return Directory._q_traverse(self, path)
88

    
89
    def _q_index(self):
90
        user = get_request().user
91
        if not user:
92
            raise errors.AccessUnauthorizedError()
93
        template.html_top(_('My Space'))
94
        r = TemplateIO(html=True)
95
        if user.anonymous:
96
            return redirect('new')
97

    
98
        user_formdef = user.get_formdef()
99

    
100
        user_forms = []
101
        if user:
102
            formdefs = FormDef.select(order_by='name', ignore_errors=True)
103
            user_forms = []
104
            for formdef in formdefs:
105
                user_forms.extend(formdef.data_class().get_with_indexed_value('user_id', user.id))
106
            epoch = time.localtime(1970)
107
            user_forms.sort(key=lambda x: x.receipt_time or epoch)
108

    
109
        profile_links = []
110
        if not get_cfg('sp', {}).get('idp-manage-user-attributes', False):
111
            if user_formdef:
112
                profile_links.append('<a href="#my-profile">%s</a>' % _('My Profile'))
113
        if user_forms:
114
            profile_links.append('<a href="#my-forms">%s</a>' % _('My Forms'))
115

    
116
        root_url = get_publisher().get_root_url()
117
        if user.can_go_in_backoffice():
118
            profile_links.append('<a href="%sbackoffice/">%s</a>' % (root_url, _('Back office')))
119
        if user.is_admin:
120
            profile_links.append('<a href="%sadmin/">%s</a>' % (root_url, _('Admin')))
121

    
122
        if profile_links:
123
            r += htmltext('<p id="profile-links">')
124
            r += htmltext(' - '.join(profile_links))
125
            r += htmltext('</p>')
126

    
127
        if not get_cfg('sp', {}).get('idp-manage-user-attributes', False):
128
            if user_formdef:
129
                r += self._my_profile(user_formdef, user)
130

    
131
            r += self._index_buttons(user_formdef)
132

    
133
            try:
134
                x = PasswordAccount.get_on_index(get_request().user.id, str('user_id'))
135
            except KeyError:
136
                pass
137
            else:
138
                r += htmltext('<p>')
139
                r += _(
140
                    'You can delete your account freely from the services portal. '
141
                    'This action is irreversible; it will destruct your personal '
142
                    'datas and destruct the access to your request history.'
143
                )
144
                r += htmltext(' <strong><a href="remove" rel="popup">%s</a></strong>.') % _(
145
                    'Delete My Account'
146
                )
147
                r += htmltext('</p>')
148

    
149
        if user_forms:
150
            r += htmltext('<h3 id="my-forms">%s</h3>') % _('My Forms')
151
            from . import root
152

    
153
            r += root.FormsRootDirectory().user_forms(user_forms)
154

    
155
        return r.getvalue()
156

    
157
    def _my_profile(self, user_formdef, user):
158
        r = TemplateIO(html=True)
159
        r += htmltext('<h3 id="my-profile">%s</h3>') % _('My Profile')
160

    
161
        r += TextsDirectory.get_html_text('top-of-profile')
162

    
163
        if user.form_data:
164
            r += htmltext('<ul>')
165
            for field in user_formdef.fields:
166
                if not hasattr(field, str('get_view_value')):
167
                    continue
168
                value = user.form_data.get(field.id)
169
                r += htmltext('<li>')
170
                r += field.label
171
                r += ' : '
172
                if value:
173
                    r += field.get_view_value(value)
174
                r += htmltext('</li>')
175
            r += htmltext('</ul>')
176
        else:
177
            r += htmltext('<p>%s</p>') % _('Empty profile')
178
        return r.getvalue()
179

    
180
    def _index_buttons(self, form_data):
181
        r = TemplateIO(html=True)
182
        passwords_cfg = get_cfg('passwords', {})
183
        ident_method = get_cfg('identification', {}).get('methods', ['idp'])[0]
184
        if get_session().lasso_session_dump:
185
            ident_method = 'idp'
186

    
187
        if form_data and ident_method != 'idp':
188
            r += htmltext('<p class="command"><a href="profile" rel="popup">%s</a></p>') % _(
189
                'Edit My Profile'
190
            )
191

    
192
        if ident_method == 'password' and passwords_cfg.get('can_change', False):
193
            r += htmltext('<p class="command"><a href="password" rel="popup">%s</a></p>') % _(
194
                'Change My Password'
195
            )
196

    
197
        return r.getvalue()
198

    
199
    def profile(self):
200
        user = get_request().user
201
        if not user or user.anonymous:
202
            raise errors.AccessUnauthorizedError()
203

    
204
        form = Form(enctype='multipart/form-data')
205
        formdef = user.get_formdef()
206
        formdef.add_fields_to_form(form, form_data=user.form_data)
207

    
208
        form.add_submit('submit', _('Apply Changes'))
209
        form.add_submit('cancel', _('Cancel'))
210

    
211
        if form.get_submit() == 'cancel':
212
            return redirect('.')
213

    
214
        if form.is_submitted() and not form.has_errors():
215
            self.profile_submit(form, formdef)
216
            return redirect('.')
217

    
218
        template.html_top(_('Edit Profile'))
219
        return form.render()
220

    
221
    def profile_submit(self, form, formdef):
222
        user = get_request().user
223
        data = formdef.get_data(form)
224

    
225
        user.set_attributes_from_formdata(data)
226
        user.form_data = data
227

    
228
        user.store()
229

    
230
    def password(self):
231
        ident_method = get_cfg('identification', {}).get('methods', ['idp'])[0]
232
        if ident_method != 'password':
233
            raise errors.TraversalError()
234

    
235
        user = get_request().user
236
        if not user or user.anonymous:
237
            raise errors.AccessUnauthorizedError()
238

    
239
        form = Form(enctype='multipart/form-data')
240
        form.add(PasswordWidget, 'new_password', title=_('New Password'), required=True)
241
        form.add(PasswordWidget, 'new2_password', title=_('New Password (confirm)'), required=True)
242

    
243
        form.add_submit('submit', _('Change Password'))
244
        form.add_submit('cancel', _('Cancel'))
245

    
246
        if form.get_submit() == 'cancel':
247
            return redirect('.')
248

    
249
        if form.is_submitted() and not form.has_errors():
250
            wcs.qommon.ident.password.check_password(form, 'new_password')
251
            new_password = form.get_widget('new_password').parse()
252
            new2_password = form.get_widget('new2_password').parse()
253
            if new_password != new2_password:
254
                form.set_error('new2_password', _('Passwords do not match'))
255

    
256
        if form.is_submitted() and not form.has_errors():
257
            self.submit_password(new_password)
258
            return redirect('.')
259

    
260
        template.html_top(_('Change Password'))
261
        return form.render()
262

    
263
    def submit_password(self, new_password):
264
        passwords_cfg = get_cfg('passwords', {})
265
        account = PasswordAccount.get(get_session().username)
266
        account.hashing_algo = passwords_cfg.get('hashing_algo')
267
        account.set_password(new_password)
268
        account.store()
269

    
270
    def new(self):
271
        if not get_request().user or not get_request().user.anonymous:
272
            raise errors.AccessUnauthorizedError()
273

    
274
        form = Form(enctype='multipart/form-data')
275
        formdef = get_publisher().user_class.get_formdef()
276
        if formdef:
277
            formdef.add_fields_to_form(form)
278
        else:
279
            get_logger().error('missing user formdef (in myspace/new)')
280

    
281
        form.add_submit('submit', _('Register'))
282

    
283
        if form.is_submitted() and not form.has_errors():
284
            user = get_publisher().user_class()
285
            data = formdef.get_data(form)
286
            user.set_attributes_from_formdata(data)
287
            user.name_identifiers = get_request().user.name_identifiers
288
            user.lasso_dump = get_request().user.lasso_dump
289
            user.set_attributes_from_formdata(data)
290
            user.form_data = data
291
            user.store()
292
            get_session().set_user(user.id)
293
            root_url = get_publisher().get_root_url()
294
            return redirect('%smyspace' % root_url)
295

    
296
        template.html_top(_('Welcome'))
297
        return form.render()
298

    
299
    def remove(self):
300
        user = get_request().user
301
        if not user or user.anonymous:
302
            raise errors.AccessUnauthorizedError()
303

    
304
        form = Form(enctype='multipart/form-data')
305
        form.widgets.append(
306
            HtmlWidget('<p>%s</p>' % _('Are you really sure you want to remove your account?'))
307
        )
308
        form.add_submit('submit', _('Remove my account'))
309
        form.add_submit('cancel', _('Cancel'))
310

    
311
        if form.get_submit() == 'cancel':
312
            return redirect('.')
313

    
314
        if form.is_submitted() and not form.has_errors():
315
            user = get_request().user
316
            account = PasswordAccount.get_on_index(user.id, str('user_id'))
317
            get_session_manager().expire_session()
318
            account.remove_self()
319
            return redirect(get_publisher().get_root_url())
320

    
321
        template.html_top(_('Removing Account'))
322
        return form.render()
(7-7/11)