Commit | Line | Data |
---|---|---|
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 | 17 | import urlparse |
4b5f4e87 | 18 | |
1972a888 | 19 | from nose.tools import assert_equal |
4b5f4e87 | 20 | |
1972a888 | 21 | from mediagoblin.auth import lib as auth_lib |
460ce564 | 22 | from mediagoblin.tests.tools import get_test_app |
651403f0 | 23 | from mediagoblin import globals as mgoblin_globals |
460ce564 CAW |
24 | from mediagoblin import util |
25 | ||
4b5f4e87 CAW |
26 | |
27 | ######################## | |
28 | # Test bcrypt auth funcs | |
29 | ######################## | |
30 | ||
31 | def 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 | ||
49 | def 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 | ||
68 | def 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 |