Mercurial > hg > vamp-website
comparison forum/Sources/Reminder.php @ 76:e3e11437ecea website
Add forum code
author | Chris Cannam |
---|---|
date | Sun, 07 Jul 2013 11:25:48 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
75:72f59aa7e503 | 76:e3e11437ecea |
---|---|
1 <?php | |
2 | |
3 /** | |
4 * Simple Machines Forum (SMF) | |
5 * | |
6 * @package SMF | |
7 * @author Simple Machines http://www.simplemachines.org | |
8 * @copyright 2011 Simple Machines | |
9 * @license http://www.simplemachines.org/about/smf/license.php BSD | |
10 * | |
11 * @version 2.0.4 | |
12 */ | |
13 | |
14 if (!defined('SMF')) | |
15 die('Hacking attempt...'); | |
16 | |
17 /* This file deals with sending out reminders, and checking the secret answer | |
18 and question. It uses just a few functions to do this, which are: | |
19 | |
20 void RemindMe() | |
21 - this is just the controlling delegator. | |
22 - uses the Profile language files and Reminder template. | |
23 | |
24 void RemindMail() | |
25 // !!! | |
26 | |
27 void setPassword() | |
28 // !!! | |
29 | |
30 void setPassword2() | |
31 // !!! | |
32 | |
33 void SecretAnswerInput() | |
34 // !!! | |
35 | |
36 void SecretAnswer2() | |
37 // !!! | |
38 */ | |
39 | |
40 // Forgot 'yer password? | |
41 function RemindMe() | |
42 { | |
43 global $txt, $context; | |
44 | |
45 loadLanguage('Profile'); | |
46 loadTemplate('Reminder'); | |
47 | |
48 $context['page_title'] = $txt['authentication_reminder']; | |
49 $context['robot_no_index'] = true; | |
50 | |
51 // Delegation can be useful sometimes. | |
52 $subActions = array( | |
53 'picktype' => 'RemindPick', | |
54 'secret2' => 'SecretAnswer2', | |
55 'setpassword' =>'setPassword', | |
56 'setpassword2' =>'setPassword2' | |
57 ); | |
58 | |
59 // Any subaction? If none, fall through to the main template, which will ask for one. | |
60 if (isset($_REQUEST['sa']) && isset($subActions[$_REQUEST['sa']])) | |
61 $subActions[$_REQUEST['sa']](); | |
62 } | |
63 | |
64 // Pick a reminder type. | |
65 function RemindPick() | |
66 { | |
67 global $context, $txt, $scripturl, $sourcedir, $user_info, $webmaster_email, $smcFunc, $language, $modSettings; | |
68 | |
69 checkSession(); | |
70 | |
71 // Coming with a known ID? | |
72 if (!empty($_REQUEST['uid'])) | |
73 { | |
74 $where = 'id_member = {int:id_member}'; | |
75 $where_params['id_member'] = (int) $_REQUEST['uid']; | |
76 } | |
77 elseif (isset($_POST['user']) && $_POST['user'] != '') | |
78 { | |
79 $where = 'member_name = {string:member_name}'; | |
80 $where_params['member_name'] = $_POST['user']; | |
81 $where_params['email_address'] = $_POST['user']; | |
82 } | |
83 | |
84 // You must enter a username/email address. | |
85 if (empty($where)) | |
86 fatal_lang_error('username_no_exist', false); | |
87 | |
88 // Find the user! | |
89 $request = $smcFunc['db_query']('', ' | |
90 SELECT id_member, real_name, member_name, email_address, is_activated, validation_code, lngfile, openid_uri, secret_question | |
91 FROM {db_prefix}members | |
92 WHERE ' . $where . ' | |
93 LIMIT 1', | |
94 array_merge($where_params, array( | |
95 )) | |
96 ); | |
97 // Maybe email? | |
98 if ($smcFunc['db_num_rows']($request) == 0 && empty($_REQUEST['uid'])) | |
99 { | |
100 $smcFunc['db_free_result']($request); | |
101 | |
102 $request = $smcFunc['db_query']('', ' | |
103 SELECT id_member, real_name, member_name, email_address, is_activated, validation_code, lngfile, openid_uri, secret_question | |
104 FROM {db_prefix}members | |
105 WHERE email_address = {string:email_address} | |
106 LIMIT 1', | |
107 array_merge($where_params, array( | |
108 )) | |
109 ); | |
110 if ($smcFunc['db_num_rows']($request) == 0) | |
111 fatal_lang_error('no_user_with_email', false); | |
112 } | |
113 | |
114 $row = $smcFunc['db_fetch_assoc']($request); | |
115 $smcFunc['db_free_result']($request); | |
116 | |
117 $context['account_type'] = !empty($row['openid_uri']) ? 'openid' : 'password'; | |
118 | |
119 // If the user isn't activated/approved, give them some feedback on what to do next. | |
120 if ($row['is_activated'] != 1) | |
121 { | |
122 // Awaiting approval... | |
123 if (trim($row['validation_code']) == '') | |
124 fatal_error($txt['registration_not_approved'] . ' <a href="' . $scripturl . '?action=activate;user=' . $_POST['user'] . '">' . $txt['here'] . '</a>.', false); | |
125 else | |
126 fatal_error($txt['registration_not_activated'] . ' <a href="' . $scripturl . '?action=activate;user=' . $_POST['user'] . '">' . $txt['here'] . '</a>.', false); | |
127 } | |
128 | |
129 // You can't get emailed if you have no email address. | |
130 $row['email_address'] = trim($row['email_address']); | |
131 if ($row['email_address'] == '') | |
132 fatal_error($txt['no_reminder_email'] . '<br />' . $txt['send_email'] . ' <a href="mailto:' . $webmaster_email . '">webmaster</a> ' . $txt['to_ask_password'] . '.'); | |
133 | |
134 // If they have no secret question then they can only get emailed the item, or they are requesting the email, send them an email. | |
135 if (empty($row['secret_question']) || (isset($_POST['reminder_type']) && $_POST['reminder_type'] == 'email')) | |
136 { | |
137 // Randomly generate a new password, with only alpha numeric characters that is a max length of 10 chars. | |
138 require_once($sourcedir . '/Subs-Members.php'); | |
139 $password = generateValidationCode(); | |
140 | |
141 require_once($sourcedir . '/Subs-Post.php'); | |
142 $replacements = array( | |
143 'REALNAME' => $row['real_name'], | |
144 'REMINDLINK' => $scripturl . '?action=reminder;sa=setpassword;u=' . $row['id_member'] . ';code=' . $password, | |
145 'IP' => $user_info['ip'], | |
146 'MEMBERNAME' => $row['member_name'], | |
147 'OPENID' => $row['openid_uri'], | |
148 ); | |
149 | |
150 $emaildata = loadEmailTemplate('forgot_' . $context['account_type'], $replacements, empty($row['lngfile']) || empty($modSettings['userLanguage']) ? $language : $row['lngfile']); | |
151 $context['description'] = $txt['reminder_' . (!empty($row['openid_uri']) ? 'openid_' : '') . 'sent']; | |
152 | |
153 // If they were using OpenID simply email them their OpenID identity. | |
154 sendmail($row['email_address'], $emaildata['subject'], $emaildata['body'], null, null, false, 0); | |
155 if (empty($row['openid_uri'])) | |
156 // Set the password in the database. | |
157 updateMemberData($row['id_member'], array('validation_code' => substr(md5($password), 0, 10))); | |
158 | |
159 // Set up the template. | |
160 $context['sub_template'] = 'sent'; | |
161 | |
162 // Dont really. | |
163 return; | |
164 } | |
165 // Otherwise are ready to answer the question? | |
166 elseif (isset($_POST['reminder_type']) && $_POST['reminder_type'] == 'secret') | |
167 { | |
168 return SecretAnswerInput(); | |
169 } | |
170 | |
171 // No we're here setup the context for template number 2! | |
172 $context['sub_template'] = 'reminder_pick'; | |
173 $context['current_member'] = array( | |
174 'id' => $row['id_member'], | |
175 'name' => $row['member_name'], | |
176 ); | |
177 } | |
178 | |
179 // Set your new password | |
180 function setPassword() | |
181 { | |
182 global $txt, $context; | |
183 | |
184 loadLanguage('Login'); | |
185 | |
186 // You need a code! | |
187 if (!isset($_REQUEST['code'])) | |
188 fatal_lang_error('no_access', false); | |
189 | |
190 // Fill the context array. | |
191 $context += array( | |
192 'page_title' => $txt['reminder_set_password'], | |
193 'sub_template' => 'set_password', | |
194 'code' => $_REQUEST['code'], | |
195 'memID' => (int) $_REQUEST['u'] | |
196 ); | |
197 } | |
198 | |
199 function setPassword2() | |
200 { | |
201 global $context, $txt, $modSettings, $smcFunc, $sourcedir; | |
202 | |
203 checkSession(); | |
204 | |
205 if (empty($_POST['u']) || !isset($_POST['passwrd1']) || !isset($_POST['passwrd2'])) | |
206 fatal_lang_error('no_access', false); | |
207 | |
208 $_POST['u'] = (int) $_POST['u']; | |
209 | |
210 if ($_POST['passwrd1'] != $_POST['passwrd2']) | |
211 fatal_lang_error('passwords_dont_match', false); | |
212 | |
213 if ($_POST['passwrd1'] == '') | |
214 fatal_lang_error('no_password', false); | |
215 | |
216 loadLanguage('Login'); | |
217 | |
218 // Get the code as it should be from the database. | |
219 $request = $smcFunc['db_query']('', ' | |
220 SELECT validation_code, member_name, email_address, passwd_flood | |
221 FROM {db_prefix}members | |
222 WHERE id_member = {int:id_member} | |
223 AND is_activated = {int:is_activated} | |
224 AND validation_code != {string:blank_string} | |
225 LIMIT 1', | |
226 array( | |
227 'id_member' => $_POST['u'], | |
228 'is_activated' => 1, | |
229 'blank_string' => '', | |
230 ) | |
231 ); | |
232 | |
233 // Does this user exist at all? | |
234 if ($smcFunc['db_num_rows']($request) == 0) | |
235 fatal_lang_error('invalid_userid', false); | |
236 | |
237 list ($realCode, $username, $email, $flood_value) = $smcFunc['db_fetch_row']($request); | |
238 $smcFunc['db_free_result']($request); | |
239 | |
240 // Is the password actually valid? | |
241 require_once($sourcedir . '/Subs-Auth.php'); | |
242 $passwordError = validatePassword($_POST['passwrd1'], $username, array($email)); | |
243 | |
244 // What - it's not? | |
245 if ($passwordError != null) | |
246 fatal_lang_error('profile_error_password_' . $passwordError, false); | |
247 | |
248 require_once($sourcedir . '/LogInOut.php'); | |
249 | |
250 // Quit if this code is not right. | |
251 if (empty($_POST['code']) || substr($realCode, 0, 10) !== substr(md5($_POST['code']), 0, 10)) | |
252 { | |
253 // Stop brute force attacks like this. | |
254 validatePasswordFlood($_POST['u'], $flood_value, false); | |
255 | |
256 fatal_error($txt['invalid_activation_code'], false); | |
257 } | |
258 | |
259 // Just in case, flood control. | |
260 validatePasswordFlood($_POST['u'], $flood_value, true); | |
261 | |
262 // User validated. Update the database! | |
263 updateMemberData($_POST['u'], array('validation_code' => '', 'passwd' => sha1(strtolower($username) . $_POST['passwrd1']))); | |
264 | |
265 call_integration_hook('integrate_reset_pass', array($username, $username, $_POST['passwrd1'])); | |
266 | |
267 loadTemplate('Login'); | |
268 $context += array( | |
269 'page_title' => $txt['reminder_password_set'], | |
270 'sub_template' => 'login', | |
271 'default_username' => $username, | |
272 'default_password' => $_POST['passwrd1'], | |
273 'never_expire' => false, | |
274 'description' => $txt['reminder_password_set'] | |
275 ); | |
276 } | |
277 | |
278 // Get the secret answer. | |
279 function SecretAnswerInput() | |
280 { | |
281 global $txt, $context, $smcFunc; | |
282 | |
283 checkSession(); | |
284 | |
285 // Strings for the register auto javascript clever stuffy wuffy. | |
286 loadLanguage('Login'); | |
287 | |
288 // Check they entered something... | |
289 if (empty($_REQUEST['uid'])) | |
290 fatal_lang_error('username_no_exist', false); | |
291 | |
292 // Get the stuff.... | |
293 $request = $smcFunc['db_query']('', ' | |
294 SELECT id_member, real_name, member_name, secret_question, openid_uri | |
295 FROM {db_prefix}members | |
296 WHERE id_member = {int:id_member} | |
297 LIMIT 1', | |
298 array( | |
299 'id_member' => (int) $_REQUEST['uid'], | |
300 ) | |
301 ); | |
302 if ($smcFunc['db_num_rows']($request) == 0) | |
303 fatal_lang_error('username_no_exist', false); | |
304 | |
305 $row = $smcFunc['db_fetch_assoc']($request); | |
306 $smcFunc['db_free_result']($request); | |
307 | |
308 $context['account_type'] = !empty($row['openid_uri']) ? 'openid' : 'password'; | |
309 | |
310 // If there is NO secret question - then throw an error. | |
311 if (trim($row['secret_question']) == '') | |
312 fatal_lang_error('registration_no_secret_question', false); | |
313 | |
314 // Ask for the answer... | |
315 $context['remind_user'] = $row['id_member']; | |
316 $context['remind_type'] = ''; | |
317 $context['secret_question'] = $row['secret_question']; | |
318 | |
319 $context['sub_template'] = 'ask'; | |
320 } | |
321 | |
322 function SecretAnswer2() | |
323 { | |
324 global $txt, $context, $modSettings, $smcFunc, $sourcedir; | |
325 | |
326 checkSession(); | |
327 | |
328 // Hacker? How did you get this far without an email or username? | |
329 if (empty($_REQUEST['uid'])) | |
330 fatal_lang_error('username_no_exist', false); | |
331 | |
332 loadLanguage('Login'); | |
333 | |
334 // Get the information from the database. | |
335 $request = $smcFunc['db_query']('', ' | |
336 SELECT id_member, real_name, member_name, secret_answer, secret_question, openid_uri, email_address | |
337 FROM {db_prefix}members | |
338 WHERE id_member = {int:id_member} | |
339 LIMIT 1', | |
340 array( | |
341 'id_member' => $_REQUEST['uid'], | |
342 ) | |
343 ); | |
344 if ($smcFunc['db_num_rows']($request) == 0) | |
345 fatal_lang_error('username_no_exist', false); | |
346 | |
347 $row = $smcFunc['db_fetch_assoc']($request); | |
348 $smcFunc['db_free_result']($request); | |
349 | |
350 // Check if the secret answer is correct. | |
351 if ($row['secret_question'] == '' || $row['secret_answer'] == '' || md5($_POST['secret_answer']) != $row['secret_answer']) | |
352 { | |
353 log_error(sprintf($txt['reminder_error'], $row['member_name']), 'user'); | |
354 fatal_lang_error('incorrect_answer', false); | |
355 } | |
356 | |
357 // If it's OpenID this is where the music ends. | |
358 if (!empty($row['openid_uri'])) | |
359 { | |
360 $context['sub_template'] = 'sent'; | |
361 $context['description'] = sprintf($txt['reminder_openid_is'], $row['openid_uri']); | |
362 return; | |
363 } | |
364 | |
365 // You can't use a blank one! | |
366 if (strlen(trim($_POST['passwrd1'])) === 0) | |
367 fatal_lang_error('no_password', false); | |
368 | |
369 // They have to be the same too. | |
370 if ($_POST['passwrd1'] != $_POST['passwrd2']) | |
371 fatal_lang_error('passwords_dont_match', false); | |
372 | |
373 // Make sure they have a strong enough password. | |
374 require_once($sourcedir . '/Subs-Auth.php'); | |
375 $passwordError = validatePassword($_POST['passwrd1'], $row['member_name'], array($row['email_address'])); | |
376 | |
377 // Invalid? | |
378 if ($passwordError != null) | |
379 fatal_lang_error('profile_error_password_' . $passwordError, false); | |
380 | |
381 // Alright, so long as 'yer sure. | |
382 updateMemberData($row['id_member'], array('passwd' => sha1(strtolower($row['member_name']) . $_POST['passwrd1']))); | |
383 | |
384 call_integration_hook('integrate_reset_pass', array($row['member_name'], $row['member_name'], $_POST['passwrd1'])); | |
385 | |
386 // Tell them it went fine. | |
387 loadTemplate('Login'); | |
388 $context += array( | |
389 'page_title' => $txt['reminder_password_set'], | |
390 'sub_template' => 'login', | |
391 'default_username' => $row['member_name'], | |
392 'default_password' => $_POST['passwrd1'], | |
393 'never_expire' => false, | |
394 'description' => $txt['reminder_password_set'] | |
395 ); | |
396 } | |
397 | |
398 ?> |