A clear_test_buckets() method
[mediagoblin.git] / mediagoblin / tests / test_auth.py
CommitLineData
8e1e744d 1# GNU MediaGoblin -- federated, autonomous media hosting
4b5f4e87
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
1972a888 17import urlparse
4b5f4e87 18
1972a888 19from nose.tools import assert_equal
4b5f4e87 20
1972a888 21from mediagoblin.auth import lib as auth_lib
460ce564 22from mediagoblin.tests.tools import get_test_app
651403f0 23from mediagoblin import globals as mgoblin_globals
460ce564
CAW
24from mediagoblin import util
25
4b5f4e87
CAW
26
27########################
28# Test bcrypt auth funcs
29########################
30
31def test_bcrypt_check_password():
32 # Check known 'lollerskates' password against check function
33 assert auth_lib.bcrypt_check_password(
34 'lollerskates',
35 '$2a$12$PXU03zfrVCujBhVeICTwtOaHTUs5FFwsscvSSTJkqx/2RQ0Lhy/nO')
36
db780024
CAW
37 assert not auth_lib.bcrypt_check_password(
38 'notthepassword',
39 '$2a$12$PXU03zfrVCujBhVeICTwtOaHTUs5FFwsscvSSTJkqx/2RQ0Lhy/nO')
40
41
4b5f4e87 42 # Same thing, but with extra fake salt.
db780024
CAW
43 assert not auth_lib.bcrypt_check_password(
44 'notthepassword',
4b5f4e87
CAW
45 '$2a$12$ELVlnw3z1FMu6CEGs/L8XO8vl0BuWSlUHgh0rUrry9DUXGMUNWwl6',
46 '3><7R45417')
47
48
49def test_bcrypt_gen_password_hash():
50 pw = 'youwillneverguessthis'
51
52 # Normal password hash generation, and check on that hash
53 hashed_pw = auth_lib.bcrypt_gen_password_hash(pw)
54 assert auth_lib.bcrypt_check_password(
55 pw, hashed_pw)
db780024
CAW
56 assert not auth_lib.bcrypt_check_password(
57 'notthepassword', hashed_pw)
58
4b5f4e87
CAW
59
60 # Same thing, extra salt.
61 hashed_pw = auth_lib.bcrypt_gen_password_hash(pw, '3><7R45417')
62 assert auth_lib.bcrypt_check_password(
63 pw, hashed_pw, '3><7R45417')
db780024
CAW
64 assert not auth_lib.bcrypt_check_password(
65 'notthepassword', hashed_pw, '3><7R45417')
460ce564
CAW
66
67
68def test_register_views():
2fecc29d
CAW
69 """
70 Massive test function that all our registration-related views all work.
71 """
460ce564
CAW
72 util.clear_test_template_context()
73 test_app = get_test_app()
74
75 # Test doing a simple GET on the page
651403f0
CAW
76 # -----------------------------------
77
460ce564
CAW
78 test_app.get('/auth/register/')
79 # Make sure it rendered with the appropriate template
80 assert util.TEMPLATE_TEST_CONTEXT.has_key(
81 'mediagoblin/auth/register.html')
82
83 # Try to register without providing anything, should error
651403f0
CAW
84 # --------------------------------------------------------
85
460ce564
CAW
86 util.clear_test_template_context()
87 test_app.post(
88 '/auth/register/', {})
89 context = util.TEMPLATE_TEST_CONTEXT['mediagoblin/auth/register.html']
90 form = context['register_form']
91 assert form.username.errors == [u'This field is required.']
92 assert form.password.errors == [u'This field is required.']
93 assert form.confirm_password.errors == [u'This field is required.']
94 assert form.email.errors == [u'This field is required.']
651403f0
CAW
95
96 # Try to register with fields that are known to be invalid
97 # --------------------------------------------------------
98
99 ## too short
100 util.clear_test_template_context()
101 test_app.post(
102 '/auth/register/', {
103 'username': 'l',
104 'password': 'o',
105 'confirm_password': 'o',
106 'email': 'l'})
107 context = util.TEMPLATE_TEST_CONTEXT['mediagoblin/auth/register.html']
108 form = context['register_form']
109
110 assert form.username.errors == [
111 u'Field must be between 3 and 30 characters long.']
112 assert form.password.errors == [
113 u'Field must be between 6 and 30 characters long.']
114
115 ## bad form
116 util.clear_test_template_context()
117 test_app.post(
118 '/auth/register/', {
119 'username': '@_@',
120 'email': 'lollerskates'})
121 context = util.TEMPLATE_TEST_CONTEXT['mediagoblin/auth/register.html']
122 form = context['register_form']
123
124 assert form.username.errors == [
125 u'Invalid input.']
126 assert form.email.errors == [
127 u'Invalid email address.']
128
129 ## mismatching passwords
130 util.clear_test_template_context()
131 test_app.post(
132 '/auth/register/', {
133 'password': 'herpderp',
134 'confirm_password': 'derpherp'})
135 context = util.TEMPLATE_TEST_CONTEXT['mediagoblin/auth/register.html']
136 form = context['register_form']
137
138 assert form.password.errors == [
139 u'Passwords must match.']
140
141 ## At this point there should be no users in the database ;)
142 assert not mgoblin_globals.database.User.find().count()
143
144 # Successful register
145 # -------------------
1972a888
CAW
146 util.clear_test_template_context()
147 response = test_app.post(
148 '/auth/register/', {
149 'username': 'happygirl',
150 'password': 'iamsohappy',
151 'confirm_password': 'iamsohappy',
152 'email': 'happygrrl@example.org'})
153 response.follow()
154
651403f0 155 ## Did we redirect to the proper page? Use the right template?
1972a888
CAW
156 assert_equal(
157 urlparse.urlsplit(response.location)[2],
158 '/auth/register/success/')
159 assert util.TEMPLATE_TEST_CONTEXT.has_key(
160 'mediagoblin/auth/register_success.html')
161
651403f0 162 ## Make sure user is in place
1972a888
CAW
163 new_user = mgoblin_globals.database.User.find_one(
164 {'username': 'happygirl'})
165 assert new_user
166 assert new_user['status'] == u'needs_email_verification'
167 assert new_user['email_verified'] == False
168
169 ## Make sure we get email confirmation, and try verifying
170 assert len(util.EMAIL_TEST_INBOX) == 1
171 message = util.EMAIL_TEST_INBOX.pop()
172 assert message['To'] == 'happygrrl@example.org'
173 email_context = util.TEMPLATE_TEST_CONTEXT[
174 'mediagoblin/auth/verification_email.txt']
175 assert email_context['verification_url'] in message.get_payload(decode=True)
176
177 path = urlparse.urlsplit(email_context['verification_url'])[2]
178 get_params = urlparse.urlsplit(email_context['verification_url'])[3]
179 assert path == u'/auth/verify_email/'
180 parsed_get_params = urlparse.parse_qs(get_params)
181
182 ### user should have these same parameters
183 assert parsed_get_params['userid'] == [
184 unicode(new_user['_id'])]
185 assert parsed_get_params['token'] == [
186 new_user['verification_key']]
187
7b1e17ed
CAW
188 ## Try verifying with bs verification key, shouldn't work
189 util.clear_test_template_context()
190 test_app.get(
191 "/auth/verify_email/?userid=%s&token=total_bs" % unicode(
192 new_user['_id']))
193 context = util.TEMPLATE_TEST_CONTEXT[
194 'mediagoblin/auth/verify_email.html']
195 assert context['verification_successful'] == False
196 new_user = mgoblin_globals.database.User.find_one(
197 {'username': 'happygirl'})
198 assert new_user
199 assert new_user['status'] == u'needs_email_verification'
200 assert new_user['email_verified'] == False
201
202 ## Verify the email activation works
203 util.clear_test_template_context()
204 test_app.get("%s?%s" % (path, get_params))
205 context = util.TEMPLATE_TEST_CONTEXT[
206 'mediagoblin/auth/verify_email.html']
207 assert context['verification_successful'] == True
208 new_user = mgoblin_globals.database.User.find_one(
209 {'username': 'happygirl'})
210 assert new_user
211 assert new_user['status'] == u'active'
212 assert new_user['email_verified'] == True
1972a888
CAW
213
214 ## TODO: Try logging in
651403f0 215
cb9bac0c
CAW
216 # Uniqueness checks
217 # -----------------
218 ## We shouldn't be able to register with that user twice
8a869db8
CAW
219 util.clear_test_template_context()
220 response = test_app.post(
221 '/auth/register/', {
222 'username': 'happygirl',
223 'password': 'iamsohappy2',
224 'confirm_password': 'iamsohappy2',
225 'email': 'happygrrl2@example.org'})
226
227 context = util.TEMPLATE_TEST_CONTEXT[
228 'mediagoblin/auth/register.html']
229 form = context['register_form']
230 assert form.username.errors == [
231 u'Sorry, a user with that name already exists.']
651403f0 232
8a869db8 233 ## TODO: Also check for double instances of an email address?