Moving import to outside of this function
[mediagoblin.git] / mediagoblin / auth / views.py
CommitLineData
8e1e744d 1# GNU MediaGoblin -- federated, autonomous media hosting
24181820
CAW
2# Copyright (C) 2011 Free Software Foundation, Inc
3#
4# This program is free software: you can redistribute it and/or modify
5# it under the terms of the GNU Affero General Public License as published by
6# the Free Software Foundation, either version 3 of the License, or
7# (at your option) any later version.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU Affero General Public License for more details.
13#
14# You should have received a copy of the GNU Affero General Public License
15# along with this program. If not, see <http://www.gnu.org/licenses/>.
16
73a1bc85 17import bson.objectid
24181820
CAW
18from webob import Response, exc
19
20from mediagoblin.auth import lib as auth_lib
21from mediagoblin.auth import forms as auth_forms
5c42a82c 22from mediagoblin.util import send_email
4c093e85 23from mediagoblin import globals as mgoblin_globals
24181820
CAW
24
25
26def register(request):
27 """
28 Your classic registration view!
29 """
30 register_form = auth_forms.RegistrationForm(request.POST)
31
32 if request.method == 'POST' and register_form.validate():
33 # TODO: Make sure the user doesn't exist already
ce72a1bb 34
24181820 35 users_with_username = \
ce72a1bb
JK
36 request.db.User.find({
37 'username': request.POST['username'].lower()
38 }).count()
24181820
CAW
39
40 if users_with_username:
41 register_form.username.errors.append(
42 u'Sorry, a user with that name already exists.')
43
44 else:
45 # Create the user
46 entry = request.db.User()
ce72a1bb 47 entry['username'] = request.POST['username'].lower()
24181820
CAW
48 entry['email'] = request.POST['email']
49 entry['pw_hash'] = auth_lib.bcrypt_gen_password_hash(
50 request.POST['password'])
51 entry.save(validate=True)
5c42a82c 52
4c093e85
JW
53 email_template = request.template_env.get_template(
54 'mediagoblin/auth/verification_email.txt')
55
56 # TODO: There is no error handling in place
57 send_email(
58 mgoblin_globals.email_sender_address,
3eae207c 59 [entry['email']],
4c093e85
JW
60 # TODO
61 # Due to the distributed nature of GNU MediaGoblin, we should
62 # find a way to send some additional information about the
63 # specific GNU MediaGoblin instance in the subject line. For
64 # example "GNU MediaGoblin @ Wandborg - [...]".
65 'GNU MediaGoblin - Verify email',
66 email_template.render(
db5912e3 67 username=entry['username'],
4c093e85
JW
68 verification_url='http://{host}{uri}?userid={userid}&token={verification_key}'.format(
69 host=request.host,
70 uri=request.urlgen('mediagoblin.auth.verify_email'),
71 userid=unicode(entry['_id']),
72 verification_key=entry['verification_key'])))
5c42a82c 73
24181820 74 # Redirect to register_success
73cb7b8e 75 return exc.HTTPFound(
24181820
CAW
76 location=request.urlgen("mediagoblin.auth.register_success"))
77
78 # render
79 template = request.template_env.get_template(
80 'mediagoblin/auth/register.html')
81 return Response(
82 template.render(
83 {'request': request,
84 'register_form': register_form}))
85
86
87def register_success(request):
88 template = request.template_env.get_template(
89 'mediagoblin/auth/register_success.html')
90 return Response(
91 template.render(
92 {'request': request}))
93
94
692fd1c9 95def login(request):
a3776717 96 """
8e1e744d 97 MediaGoblin login view.
a3776717
CAW
98
99 If you provide the POST with 'next', it'll redirect to that view.
100 """
692fd1c9
CAW
101 login_form = auth_forms.LoginForm(request.POST)
102
a3776717
CAW
103 login_failed = False
104
692fd1c9 105 if request.method == 'POST' and login_form.validate():
b058cf15 106 user = request.db.User.one(
ce72a1bb 107 {'username': request.POST['username'].lower()})
692fd1c9 108
d1938963 109 if user and user.check_login(request.POST['password']):
692fd1c9
CAW
110 # set up login in session
111 request.session['user_id'] = unicode(user['_id'])
a3776717 112 request.session.save()
692fd1c9 113
574d1511 114 if request.POST.get('next'):
a3776717
CAW
115 return exc.HTTPFound(location=request.POST['next'])
116 else:
117 return exc.HTTPFound(
118 location=request.urlgen("index"))
692fd1c9
CAW
119
120 else:
121 # Prevent detecting who's on this system by testing login
122 # attempt timings
123 auth_lib.fake_login_attempt()
a3776717 124 login_failed = True
692fd1c9
CAW
125
126 # render
127 template = request.template_env.get_template(
128 'mediagoblin/auth/login.html')
129 return Response(
130 template.render(
131 {'request': request,
a3776717
CAW
132 'login_form': login_form,
133 'next': request.GET.get('next') or request.POST.get('next'),
134 'login_failed': login_failed}))
692fd1c9
CAW
135
136
137def logout(request):
b97232fa
CAW
138 # Maybe deleting the user_id parameter would be enough?
139 request.session.delete()
140
141 return exc.HTTPFound(
142 location=request.urlgen("index"))
db1a438f 143
5866d1a8 144
db1a438f 145def verify_email(request):
4c093e85
JW
146 """
147 Email verification view
148
149 validates GET parameters against database and unlocks the user account, if
150 you are lucky :)
151 """
db1a438f 152 user = request.db.User.find_one(
4c093e85 153 {'_id': bson.objectid.ObjectId(unicode(request.GET.get('userid')))})
db1a438f
JW
154
155 verification_successful = bool
156
4c093e85 157 if user and user['verification_key'] == unicode(request.GET.get('token')):
db1a438f
JW
158 user['status'] = u'active'
159 user['email_verified'] = True
160 verification_successful = True
161 user.save()
162 else:
163 verification_successful = False
164
165 template = request.template_env.get_template(
166 'mediagoblin/auth/verify_email.html')
167 return Response(
168 template.render(
169 {'request': request,
170 'user': user,
171 'verification_successful': verification_successful}))
28afb47c
AM
172
173def verify_email_notice(request):
174 """
175 Verify warning view.
176
177 When the user tries to do some action that requires their account
178 to be verified beforehand, this view is called upon!
179 """
180
181 template = request.template_env.get_template(
182 'mediagoblin/auth/verification_needed.html')
183 return Response(
184 template.render(
185 {'request': request}))
186
5866d1a8 187
b93a6a22
AM
188def resend_activation(request):
189 """
190 The reactivation view
191
192 Resend the activation email.
193 """
194
195 request.user.generate_new_verification_key()
196
197 # Copied shamelessly from the register view above.
198
199 email_template = request.template_env.get_template(
200 'mediagoblin/auth/verification_email.txt')
201
202 # TODO: There is no error handling in place
203 send_email(
204 mgoblin_globals.email_sender_address,
205 [request.user['email']],
206 # TODO
207 # Due to the distributed nature of GNU MediaGoblin, we should
208 # find a way to send some additional information about the
209 # specific GNU MediaGoblin instance in the subject line. For
210 # example "GNU MediaGoblin @ Wandborg - [...]".
211 'GNU MediaGoblin - Verify email',
212 email_template.render(
213 username=request.user['username'],
214 verification_url='http://{host}{uri}?userid={userid}&token={verification_key}'.format(
215 host=request.host,
216 uri=request.urlgen('mediagoblin.auth.verify_email'),
217 userid=unicode(request.user['_id']),
218 verification_key=request.user['verification_key'])))
219
5866d1a8
CAW
220 return exc.HTTPFound(
221 location=request.urlgen('mediagoblin.auth.resend_verification_success'))
b93a6a22 222
b93a6a22 223
5866d1a8 224def resend_activation_success(request):
b93a6a22 225 template = request.template_env.get_template(
5866d1a8
CAW
226 'mediagoblin/auth/resent_verification_email.html')
227 return Response(
228 template.render(
229 {'request': request}))