Passed
Push — master ( a23055...584f3d )
by Jochen
02:14
created

initialize_account()   A

Complexity

Conditions 1

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 8
nop 1
dl 0
loc 12
rs 10
c 0
b 0
f 0
1
"""
2
byceps.blueprints.admin.user.views
3
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4
5
:Copyright: 2006-2019 Jochen Kupperschmidt
6
:License: Modified BSD, see LICENSE for details.
7
"""
8
9
from flask import abort, g, redirect, request, url_for
10
11
from ....services.authentication.password import service as password_service
12
from ....services.authorization import service as authorization_service
13
from ....services.orga_team import service as orga_team_service
14
from ....services.shop.order import service as order_service
15
from ....services.shop.shop import service as shop_service
16
from ....services.user import command_service as user_command_service
17
from ....services.user import creation_service as user_creation_service
18
from ....services.user import service as user_service
19
from ....services.user import stats_service as user_stats_service
20
from ....services.user_badge import service as badge_service
21
from ....util.framework.blueprint import create_blueprint
22
from ....util.framework.flash import flash_error, flash_success
23
from ....util.framework.templating import templated
24
from ....util.views import redirect_to, respond_no_content
25
26
from ...authorization.decorators import permission_required
27
from ...authorization.registry import permission_registry
28
from ...user.signals import account_created, account_deleted, \
29
    account_suspended, account_unsuspended, screen_name_changed
30
31
from ..authorization.authorization import RolePermission
32
33
from .authorization import UserPermission
34
from .forms import ChangeScreenNameForm, CreateAccountForm, \
35
    DeleteAccountForm, SetPasswordForm, SuspendAccountForm
36
from .models import UserStateFilter
37
from . import service
38
39
40
blueprint = create_blueprint('user_admin', __name__)
41
42
43
permission_registry.register_enum(UserPermission)
44
45
46
@blueprint.route('/', defaults={'page': 1})
47
@blueprint.route('/pages/<int:page>')
48
@permission_required(UserPermission.view)
49
@templated
50
def index(page):
51
    """List users."""
52
    per_page = request.args.get('per_page', type=int, default=20)
53
    search_term = request.args.get('search_term', default='').strip()
54
    only = request.args.get('only')
55
56
    user_state_filter = UserStateFilter.__members__.get(only,
57
                                                        UserStateFilter.none)
58
59
    users = service.get_users_paginated(page, per_page,
60
                                        search_term=search_term,
61
                                        state_filter=user_state_filter)
62
63
    total_uninitialized = user_stats_service.count_uninitialized_users()
64
    total_enabled = user_stats_service.count_enabled_users()
65
    total_disabled = user_stats_service.count_disabled_users()
66
    total_suspended = user_stats_service.count_suspended_users()
67
    total_deleted = user_stats_service.count_deleted_users()
68
    total_overall = total_enabled + total_disabled
69
70
    return {
71
        'users': users,
72
        'total_uninitialized': total_uninitialized,
73
        'total_enabled': total_enabled,
74
        'total_disabled': total_disabled,
75
        'total_suspended': total_suspended,
76
        'total_deleted': total_deleted,
77
        'total_overall': total_overall,
78
        'search_term': search_term,
79
        'only': only,
80
        'UserStateFilter': UserStateFilter,
81
        'user_state_filter': user_state_filter,
82
    }
83
84
85
@blueprint.route('/<uuid:user_id>')
86
@permission_required(UserPermission.view)
87
@templated
88
def view(user_id):
89
    """Show a user's interal profile."""
90
    user = user_service.find_user_with_details(user_id)
91
    if user is None:
92
        abort(404)
93
94
    orga_team_memberships = orga_team_service.get_memberships_for_user(user.id)
95
96
    newsletter_subscriptions = service.get_newsletter_subscriptions(user.id)
97
98
    orders = order_service.get_orders_placed_by_user(user.id)
99
100
    order_shop_ids = {order.shop_id for order in orders}
101
    shops = shop_service.find_shops(order_shop_ids)
102
    shops_by_id = {shop.id: shop for shop in shops}
103
104
    parties_and_tickets = service.get_parties_and_tickets(user.id)
105
106
    attended_parties = service.get_attended_parties(user.id)
107
108
    badges_with_awarding_quantity = badge_service.get_badges_for_user(user.id)
109
110
    return {
111
        'user': user,
112
        'orga_team_memberships': orga_team_memberships,
113
        'newsletter_subscriptions': newsletter_subscriptions,
114
        'orders': orders,
115
        'shops_by_id': shops_by_id,
116
        'parties_and_tickets': parties_and_tickets,
117
        'attended_parties': attended_parties,
118
        'badges_with_awarding_quantity': badges_with_awarding_quantity,
119
    }
120
121
122
@blueprint.route('/create')
123
@permission_required(UserPermission.create)
124
@templated
125
def create_account_form(erroneous_form=None):
126
    """Show a form to create a user account."""
127
    form = erroneous_form if erroneous_form else CreateAccountForm()
128
129
    return {'form': form}
130
131
132
@blueprint.route('/', methods=['POST'])
133
@permission_required(UserPermission.create)
134
def create_account():
135
    """Create a user account."""
136
    form = CreateAccountForm(request.form)
137
138
    if not form.validate():
139
        return create_account_form(form)
140
141
    screen_name = form.screen_name.data.strip()
142
    first_names = form.first_names.data.strip()
143
    last_name = form.last_name.data.strip()
144
    email_address = form.email_address.data.lower()
145
    password = form.password.data
146
147
    if user_service.is_screen_name_already_assigned(screen_name):
148
        flash_error(
149
            'Dieser Benutzername ist bereits einem Benutzerkonto zugeordnet.')
150
        return create_account_form(form)
151
152
    if user_service.is_email_address_already_assigned(email_address):
153
        flash_error(
154
            'Diese E-Mail-Adresse ist bereits einem Benutzerkonto zugeordnet.')
155
        return create_account_form(form)
156
157
    try:
158
        user = user_creation_service.create_basic_user(
159
            screen_name, email_address, password, first_names=first_names,
160
            last_name=last_name, creator_id=g.current_user.id)
161
    except user_creation_service.UserCreationFailed:
162
        flash_error('Das Benutzerkonto für "{}" konnte nicht angelegt werden.',
163
                    screen_name)
164
        return create_account_form(form)
165
166
    flash_success('Das Benutzerkonto "{}" wurde angelegt.', user.screen_name)
167
    account_created.send(None, user_id=user.id)
168
169
    return redirect_to('.view', user_id=user.id)
170
171
172
@blueprint.route('/<uuid:user_id>/password')
173
@permission_required(UserPermission.set_password)
174
@templated
175
def set_password_form(user_id, erroneous_form=None):
176
    """Show a form to set a new password for the user."""
177
    user = _get_user_or_404(user_id)
178
179
    form = erroneous_form if erroneous_form else SetPasswordForm()
180
181
    return {
182
        'user': user,
183
        'form': form,
184
    }
185
186
187
@blueprint.route('/<uuid:user_id>/password', methods=['POST'])
188
@permission_required(UserPermission.set_password)
189
def set_password(user_id):
190
    """Set a new password for the user."""
191
    user = _get_user_or_404(user_id)
192
193
    form = SetPasswordForm(request.form)
194
    if not form.validate():
195
        return set_password_form(user.id, form)
196
197
    new_password = form.password.data
198
    initiator_id = g.current_user.id
199
200
    password_service.update_password_hash(user.id, new_password, initiator_id)
201
202
    flash_success("Für Benutzerkonto '{}' wurde ein neues Passwort gesetzt.",
203
                  user.screen_name)
204
205
    return redirect(url_for('.view', user_id=user.id))
206
207
208
@blueprint.route('/<uuid:user_id>/initialize', methods=['POST'])
209
@permission_required(UserPermission.administrate)
210
@respond_no_content
211
def initialize_account(user_id):
212
    """Initialize the user account."""
213
    user = _get_user_or_404(user_id)
214
215
    initiator_id = g.current_user.id
216
217
    user_command_service.initialize_account(user.id, initiator_id)
218
219
    flash_success("Das Benutzerkonto '{}' wurde initialisiert.", user.screen_name)
220
221
222
@blueprint.route('/<uuid:user_id>/flags/enabled', methods=['POST'])
223
@permission_required(UserPermission.administrate)
224
@respond_no_content
225
def set_enabled_flag(user_id):
226
    """Enable the user."""
227
    user = _get_user_or_404(user_id)
228
229
    initiator_id = g.current_user.id
230
231
    user_command_service.enable_user(user.id, initiator_id)
232
233
    flash_success("Das Benutzerkonto '{}' wurde aktiviert.", user.screen_name)
234
235
236
@blueprint.route('/<uuid:user_id>/flags/enabled', methods=['DELETE'])
237
@permission_required(UserPermission.administrate)
238
@respond_no_content
239
def unset_enabled_flag(user_id):
240
    """Disable the user."""
241
    user = _get_user_or_404(user_id)
242
243
    initiator_id = g.current_user.id
244
245
    user_command_service.disable_user(user.id, initiator_id)
246
247
    flash_success("Das Benutzerkonto '{}' wurde deaktiviert.", user.screen_name)
248
249
250
@blueprint.route('/<uuid:user_id>/suspend')
251
@permission_required(UserPermission.administrate)
252
@templated
253
def suspend_account_form(user_id, erroneous_form=None):
254
    """Show form to suspend the user account."""
255
    user = _get_user_or_404(user_id)
256
257
    if user.suspended:
258
        flash_error("Das Benutzerkonto '{}' ist bereits gesperrt.",
259
                    user.screen_name)
260
        return redirect_to('.view', user_id=user.id)
261
262
    form = erroneous_form if erroneous_form else SuspendAccountForm()
263
264
    return {
265
        'user': user,
266
        'form': form,
267
    }
268
269
270
@blueprint.route('/<uuid:user_id>/suspend', methods=['POST'])
271
@permission_required(UserPermission.administrate)
272
def suspend_account(user_id):
273
    """Suspend the user account."""
274
    user = _get_user_or_404(user_id)
275
276
    if user.suspended:
277
        flash_error("Das Benutzerkonto '{}' ist bereits gesperrt.",
278
                    user.screen_name)
279
        return redirect_to('.view', user_id=user.id)
280
281
    form = SuspendAccountForm(request.form)
282
    if not form.validate():
283
        return suspend_account_form(user.id, form)
284
285
    initiator_id = g.current_user.id
286
    reason = form.reason.data.strip()
287
288
    user_command_service.suspend_account(user.id, initiator_id, reason)
289
290
    account_suspended.send(None, user_id=user.id, initiator_id=initiator_id)
291
292
    flash_success("Das Benutzerkonto '{}' wurde gesperrt.", user.screen_name)
293
    return redirect_to('.view', user_id=user.id)
294
295
296
@blueprint.route('/<uuid:user_id>/unsuspend')
297
@permission_required(UserPermission.administrate)
298
@templated
299
def unsuspend_account_form(user_id, erroneous_form=None):
300
    """Show form to unsuspend the user account."""
301
    user = _get_user_or_404(user_id)
302
303
    if not user.suspended:
304
        flash_error("Das Benutzerkonto '{}' ist bereits entsperrt.",
305
                    user.screen_name)
306
        return redirect_to('.view', user_id=user.id)
307
308
    form = erroneous_form if erroneous_form else SuspendAccountForm()
309
310
    return {
311
        'user': user,
312
        'form': form,
313
    }
314
315
316
@blueprint.route('/<uuid:user_id>/unsuspend', methods=['POST'])
317
@permission_required(UserPermission.administrate)
318
def unsuspend_account(user_id):
319
    """Unsuspend the user account."""
320
    user = _get_user_or_404(user_id)
321
322
    if not user.suspended:
323
        flash_error("Das Benutzerkonto '{}' ist bereits entsperrt.",
324
                    user.screen_name)
325
        return redirect_to('.view', user_id=user.id)
326
327
    form = SuspendAccountForm(request.form)
328
    if not form.validate():
329
        return unsuspend_account_form(user.id, form)
330
331
    initiator_id = g.current_user.id
332
    reason = form.reason.data.strip()
333
334
    user_command_service.unsuspend_account(user.id, initiator_id, reason)
335
336
    account_unsuspended.send(None, user_id=user.id, initiator_id=initiator_id)
337
338
    flash_success("Das Benutzerkonto '{}' wurde entsperrt.", user.screen_name)
339
    return redirect_to('.view', user_id=user.id)
340
341
342
@blueprint.route('/<uuid:user_id>/delete')
343
@permission_required(UserPermission.administrate)
344
@templated
345
def delete_account_form(user_id, erroneous_form=None):
346
    """Show form to delete the user account."""
347
    user = _get_user_or_404(user_id)
348
349
    if user.deleted:
350
        flash_error("Das Benutzerkonto '{}' ist bereits gelöscht worden.",
351
                    user.screen_name)
352
        return redirect_to('.view', user_id=user.id)
353
354
    form = erroneous_form if erroneous_form else DeleteAccountForm()
355
356
    return {
357
        'user': user,
358
        'form': form,
359
    }
360
361
362
@blueprint.route('/<uuid:user_id>/delete', methods=['POST'])
363
@permission_required(UserPermission.administrate)
364
def delete_account(user_id):
365
    """Delete the user account."""
366
    user = _get_user_or_404(user_id)
367
368
    if user.deleted:
369
        flash_error("Das Benutzerkonto '{}' ist bereits gelöscht worden.",
370
                    user.screen_name)
371
        return redirect_to('.view', user_id=user.id)
372
373
    form = DeleteAccountForm(request.form)
374
    if not form.validate():
375
        return delete_account_form(user.id, form)
376
377
    initiator_id = g.current_user.id
378
    reason = form.reason.data.strip()
379
380
    user_command_service.delete_account(user.id, initiator_id, reason)
381
382
    account_deleted.send(None, user_id=user.id, initiator_id=initiator_id)
383
384
    flash_success("Das Benutzerkonto '{}' wurde gelöscht.", user.screen_name)
385
    return redirect_to('.view', user_id=user.id)
386
387
388
@blueprint.route('/<uuid:user_id>/change_screen_name')
389
@permission_required(UserPermission.administrate)
390
@templated
391
def change_screen_name_form(user_id, erroneous_form=None):
392
    """Show form to change the user's screen name."""
393
    user = _get_user_or_404(user_id)
394
395
    form = erroneous_form if erroneous_form else ChangeScreenNameForm()
396
397
    return {
398
        'user': user,
399
        'form': form,
400
    }
401
402
403
@blueprint.route('/<uuid:user_id>/change_screen_name', methods=['POST'])
404
@permission_required(UserPermission.administrate)
405
def change_screen_name(user_id):
406
    """Change the user's screen name."""
407
    user = _get_user_or_404(user_id)
408
409
    form = ChangeScreenNameForm(request.form)
410
    if not form.validate():
411
        return change_screen_name_form(user.id, form)
412
413
    old_screen_name = user.screen_name
414
    new_screen_name = form.screen_name.data.strip()
415
    initiator_id = g.current_user.id
416
    reason = form.reason.data.strip()
417
418
    user_command_service.change_screen_name(user.id, new_screen_name,
419
                                            initiator_id, reason=reason)
420
421
    screen_name_changed.send(None, user_id=user.id,
422
                             old_screen_name=old_screen_name,
423
                             new_screen_name=new_screen_name,
424
                             initiator_id=initiator_id)
425
426
    flash_success("Das Benutzerkonto '{}' wurde umbenannt in '{}'.",
427
                  old_screen_name, new_screen_name)
428
    return redirect_to('.view', user_id=user.id)
429
430
431
@blueprint.route('/<uuid:user_id>/permissions')
432
@permission_required(UserPermission.view)
433
@templated
434
def view_permissions(user_id):
435
    """Show user's permissions."""
436
    user = _get_user_or_404(user_id)
437
438
    permissions_by_role = authorization_service \
439
        .get_permissions_by_roles_for_user_with_titles(user.id)
440
441
    return {
442
        'user': user,
443
        'permissions_by_role': permissions_by_role,
444
    }
445
446
447
@blueprint.route('/<uuid:user_id>/roles/assignment')
448
@permission_required(RolePermission.assign)
449
@templated
450
def manage_roles(user_id):
451
    """Manage what roles are assigned to the user."""
452
    user = _get_user_or_404(user_id)
453
454
    permissions_by_role = authorization_service \
455
        .get_permissions_by_roles_with_titles()
456
457
    user_role_ids = authorization_service.find_role_ids_for_user(user.id)
458
459
    return {
460
        'user': user,
461
        'permissions_by_role': permissions_by_role,
462
        'user_role_ids': user_role_ids,
463
    }
464
465
466
@blueprint.route('/<uuid:user_id>/roles/<role_id>', methods=['POST'])
467
@permission_required(RolePermission.assign)
468
@respond_no_content
469
def role_assign(user_id, role_id):
470
    """Assign the role to the user."""
471
    user = _get_user_or_404(user_id)
472
    role = _get_role_or_404(role_id)
473
    initiator_id = g.current_user.id
474
475
    authorization_service.assign_role_to_user(role.id, user.id,
476
                                              initiator_id=initiator_id)
477
478
    flash_success('{} wurde die Rolle "{}" zugewiesen.',
479
                  user.screen_name, role.title)
480
481
482
@blueprint.route('/<uuid:user_id>/roles/<role_id>', methods=['DELETE'])
483
@permission_required(RolePermission.assign)
484
@respond_no_content
485
def role_deassign(user_id, role_id):
486
    """Deassign the role from the user."""
487
    user = _get_user_or_404(user_id)
488
    role = _get_role_or_404(role_id)
489
    initiator_id = g.current_user.id
490
491
    authorization_service.deassign_role_from_user(role.id, user.id,
492
                                                  initiator_id=initiator_id)
493
494
    flash_success('{} wurde die Rolle "{}" genommen.',
495
                  user.screen_name, role.title)
496
497
498
@blueprint.route('/<uuid:user_id>/events')
499
@permission_required(UserPermission.view)
500
@templated
501
def view_events(user_id):
502
    """Show user's events."""
503
    user = _get_user_or_404(user_id)
504
505
    events = service.get_events(user.id)
506
507
    return {
508
        'user': user,
509
        'events': events,
510
    }
511
512
513
def _get_user_or_404(user_id):
514
    user = user_service.find_user_with_details(user_id)
515
516
    if user is None:
517
        abort(404)
518
519
    return user
520
521
522
def _get_role_or_404(role_id):
523
    role = authorization_service.find_role(role_id)
524
525
    if role is None:
526
        abort(404)
527
528
    return role
529