Make sure we can register, and then that we get the verification email
[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():
69 util.clear_test_template_context()
70 test_app = get_test_app()
71
72 # Test doing a simple GET on the page
651403f0
CAW
73 # -----------------------------------
74
460ce564
CAW
75 test_app.get('/auth/register/')
76 # Make sure it rendered with the appropriate template
77 assert util.TEMPLATE_TEST_CONTEXT.has_key(
78 'mediagoblin/auth/register.html')
79
80 # Try to register without providing anything, should error
651403f0
CAW
81 # --------------------------------------------------------
82
460ce564
CAW
83 util.clear_test_template_context()
84 test_app.post(
85 '/auth/register/', {})
86 context = util.TEMPLATE_TEST_CONTEXT['mediagoblin/auth/register.html']
87 form = context['register_form']
88 assert form.username.errors == [u'This field is required.']
89 assert form.password.errors == [u'This field is required.']
90 assert form.confirm_password.errors == [u'This field is required.']
91 assert form.email.errors == [u'This field is required.']
651403f0
CAW
92
93 # Try to register with fields that are known to be invalid
94 # --------------------------------------------------------
95
96 ## too short
97 util.clear_test_template_context()
98 test_app.post(
99 '/auth/register/', {
100 'username': 'l',
101 'password': 'o',
102 'confirm_password': 'o',
103 'email': 'l'})
104 context = util.TEMPLATE_TEST_CONTEXT['mediagoblin/auth/register.html']
105 form = context['register_form']
106
107 assert form.username.errors == [
108 u'Field must be between 3 and 30 characters long.']
109 assert form.password.errors == [
110 u'Field must be between 6 and 30 characters long.']
111
112 ## bad form
113 util.clear_test_template_context()
114 test_app.post(
115 '/auth/register/', {
116 'username': '@_@',
117 'email': 'lollerskates'})
118 context = util.TEMPLATE_TEST_CONTEXT['mediagoblin/auth/register.html']
119 form = context['register_form']
120
121 assert form.username.errors == [
122 u'Invalid input.']
123 assert form.email.errors == [
124 u'Invalid email address.']
125
126 ## mismatching passwords
127 util.clear_test_template_context()
128 test_app.post(
129 '/auth/register/', {
130 'password': 'herpderp',
131 'confirm_password': 'derpherp'})
132 context = util.TEMPLATE_TEST_CONTEXT['mediagoblin/auth/register.html']
133 form = context['register_form']
134
135 assert form.password.errors == [
136 u'Passwords must match.']
137
138 ## At this point there should be no users in the database ;)
139 assert not mgoblin_globals.database.User.find().count()
140
141 # Successful register
142 # -------------------
1972a888
CAW
143 util.clear_test_template_context()
144 response = test_app.post(
145 '/auth/register/', {
146 'username': 'happygirl',
147 'password': 'iamsohappy',
148 'confirm_password': 'iamsohappy',
149 'email': 'happygrrl@example.org'})
150 response.follow()
151
651403f0 152 ## Did we redirect to the proper page? Use the right template?
1972a888
CAW
153 assert_equal(
154 urlparse.urlsplit(response.location)[2],
155 '/auth/register/success/')
156 assert util.TEMPLATE_TEST_CONTEXT.has_key(
157 'mediagoblin/auth/register_success.html')
158
651403f0 159 ## Make sure user is in place
1972a888
CAW
160 new_user = mgoblin_globals.database.User.find_one(
161 {'username': 'happygirl'})
162 assert new_user
163 assert new_user['status'] == u'needs_email_verification'
164 assert new_user['email_verified'] == False
165
166 ## Make sure we get email confirmation, and try verifying
167 assert len(util.EMAIL_TEST_INBOX) == 1
168 message = util.EMAIL_TEST_INBOX.pop()
169 assert message['To'] == 'happygrrl@example.org'
170 email_context = util.TEMPLATE_TEST_CONTEXT[
171 'mediagoblin/auth/verification_email.txt']
172 assert email_context['verification_url'] in message.get_payload(decode=True)
173
174 path = urlparse.urlsplit(email_context['verification_url'])[2]
175 get_params = urlparse.urlsplit(email_context['verification_url'])[3]
176 assert path == u'/auth/verify_email/'
177 parsed_get_params = urlparse.parse_qs(get_params)
178
179 ### user should have these same parameters
180 assert parsed_get_params['userid'] == [
181 unicode(new_user['_id'])]
182 assert parsed_get_params['token'] == [
183 new_user['verification_key']]
184
185 ## Verify the email
186
187 ## TODO: Try logging in
651403f0 188
cb9bac0c
CAW
189 # Uniqueness checks
190 # -----------------
191 ## We shouldn't be able to register with that user twice
651403f0 192
cb9bac0c 193 ## Also check for double instances of an email address