1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
|
# -*- coding: utf-8 -*-
from __future__ import absolute_import
from copy import deepcopy
from flask import Blueprint
from flask import current_app, redirect, render_template, request, g, \
flash, url_for
from flask.ext.login import login_required, login_user, logout_user, current_user
from werkzeug.exceptions import Forbidden
from accounts.forms import RegisterForm, RegisterCompleteForm, \
LostPasswordForm, SettingsForm
from accounts.utils import templated
from accounts.utils.confirmation import Confirmation
from accounts.utils.login import logout_required
from accounts.models import Account
bp = Blueprint('default', __name__)
@bp.route('/register', methods=['GET', 'POST'])
@templated('register.html')
@logout_required
def register():
form = RegisterForm()
if form.validate_on_submit():
current_app.mail_backend.send(form.mail.data, 'mail/register.txt',
username=form.username.data)
flash(u'Es wurde eine E-Mail an die angegebene Adresse geschickt, '
u'um diese zu überprüfen. Bitte folge den Anweisungen in der '
u'E-Mail.', 'success')
return redirect(url_for('.index'))
return {'form': form}
@bp.route('/register/<token>', methods=['GET', 'POST'])
@templated('register_complete.html')
@logout_required
def register_complete(token):
#TODO: check for double uids and mail
username, mail = Confirmation('register').loads_http(token, max_age=3*24*60*60)
try:
current_app.user_backend.get_by_uid(username)
current_app.user_backend.get_by_mail(mail)
except current_app.user_backend.NoSuchUserError:
pass
else:
flash(u'Du hast den Benutzer bereits angelegt! Du kannst dich jetzt einfach einloggen:')
return redirect(url_for('.index'))
form = RegisterCompleteForm()
if form.validate_on_submit():
user = Account(username, mail, password=form.password.data)
current_app.user_backend.register(user)
login_user(user)
current_app.mail_backend.send(
current_app.config['MAIL_REGISTER_NOTIFY'],
'mail/register_notify.txt',
username=username, mail=mail)
flash(u'Benutzer erfolgreich angelegt.', 'success')
return redirect(url_for('.index'))
return {
'form': form,
'token': token,
'username': username,
'mail': mail,
}
@bp.route('/lost_password', methods=['GET', 'POST'])
@templated('lost_password.html')
@logout_required
def lost_password():
form = LostPasswordForm()
if form.validate_on_submit():
#TODO: make the link only usable once (e.g include a hash of the old pw)
# atm the only thing we do is make the link valid for only little time
current_app.mail_backend.send(
form.user.mail, 'mail/lost_password.txt', username=form.user.uid)
flash(u'Wir haben dir eine E-Mail mit einem Link zum Passwort ändern '
u'geschickt. Bitte folge den Anweisungen in der E-Mail.', 'success')
return redirect(url_for('.index'))
return {'form': form}
@bp.route('/lost_password/<token>', methods=['GET', 'POST'])
@templated('lost_password_complete.html')
@logout_required
def lost_password_complete(token):
(username,) = Confirmation('lost_password').loads_http(token, max_age=4*60*60)
form = RegisterCompleteForm()
if form.validate_on_submit():
user = current_app.user_backend.get_by_uid(username)
user.change_password(form.password.data)
current_app.user_backend.update(user, as_admin=True)
login_user(user)
flash(u'Passwort geändert.', 'success')
return redirect(url_for('.index'))
return {
'form': form,
'token': token,
'username': username,
}
@bp.route('/', methods=['GET', 'POST'])
@templated('index.html')
@login_required
def index():
form = SettingsForm(mail=current_user.mail)
if form.validate_on_submit():
changed = False
if request.form.get('submit_services'):
for service in current_app.all_services:
field = form.get_servicedelete(service.id)
if field.data:
current_user.reset_password(service.id)
changed = True
elif request.form.get('submit_main'):
if form.mail.data and form.mail.data != current_user.mail:
current_app.mail_backend.send(
form.mail.data, 'mail/change_mail.txt',
username=current_user.uid)
flash(u'Es wurde eine E-Mail an die angegebene Adresse geschickt, '
u'um diese zu überprüfen. Bitte folge den Anweisungen in der '
u'E-Mail.', 'success')
changed = True
if form.password.data:
current_user.change_password(form.password.data, form.old_password.data)
flash(u'Passwort geändert', 'success')
changed = True
for service in current_app.all_services:
field = form.get_servicepassword(service.id)
if field.data:
changed = True
current_user.change_password(field.data, None, service.id)
if changed:
current_app.user_backend.update(current_user)
login_user(current_user)
return redirect(url_for('.index'))
else:
flash(u'Nichts geändert.')
services = deepcopy(current_app.all_services)
for s in services:
s.changed = s.id in current_user.services
return {
'form': form,
'services': services,
}
@bp.route('/change_mail/<token>')
@login_required
def change_mail(token):
username, mail = Confirmation('change_mail').loads_http(token, max_age=3*24*60*60)
if current_user.uid != username:
raise Forbidden(u'Bitte logge dich als der Benutzer ein, dessen E-Mail-Adresse du ändern willst.')
results = current_app.user_backend.find_by_mail(mail)
for user in results:
if user.uid != current_user.uid:
raise Forbidden(u'Diese E-Mail-Adresse wird schon von einem anderen account benutzt!')
current_user.change_email(mail)
current_app.user_backend.update(current_user)
flash(u'E-Mail-Adresse geändert.', 'success')
return redirect(url_for('.index'))
@bp.route('/about')
@templated('about.html')
def about():
return {
'app': current_app,
}
@bp.app_errorhandler(403)
@bp.app_errorhandler(404)
@bp.app_errorhandler(Exception)
def errorhandler(e):
try:
code = e.code
except AttributeError:
code = 500
return render_template('error.html', error=e), code
|