PageRenderTime 21ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/users/password.php

https://github.com/bernard357/yacs
PHP | 271 lines | 136 code | 60 blank | 75 comment | 35 complexity | aeccedbac503b15ebe3c6903f844b2a4 MD5 | raw file
  1. <?php
  2. /**
  3. * change the password for an existing user
  4. *
  5. * This page allows users that have been registered locally to change their password.
  6. * Associates can change any password as well.
  7. *
  8. * Users that have only a shadow user profile are invited to go to the origin server.
  9. *
  10. * To avoid replay attacks YACS generates a random string and asks anonymous users to type it.
  11. *
  12. * This page also helps to recover from lost password. Non-authenticated users
  13. * can provide their nick name, and a message is sent to the related e-mail
  14. * address, with a link to authenticate back to the site.
  15. *
  16. * @author Bernard Paques
  17. * @author GnapZ
  18. * @tester Guillaume Perez
  19. * @reference
  20. * @license http://www.gnu.org/copyleft/lesser.txt GNU Lesser General Public License
  21. */
  22. // common definitions and initial processing
  23. include_once '../shared/global.php';
  24. // look for the id
  25. $id = NULL;
  26. if(isset($_REQUEST['id']))
  27. $id = $_REQUEST['id'];
  28. elseif(isset($context['arguments'][0]))
  29. $id = $context['arguments'][0];
  30. elseif(Surfer::is_logged())
  31. $id = Surfer::get_id();
  32. $id = strip_tags($id);
  33. // get existing user data, if any
  34. $item = Users::get($id);
  35. // is this is a shadow record?
  36. $origin = '';
  37. if(isset($item['password'])) {
  38. $parts = parse_url($item['password']);
  39. if(isset($parts['host']))
  40. $origin = $parts['host'];
  41. }
  42. // optional processing steps
  43. $with_form = FALSE;
  44. // load the skin
  45. load_skin('users');
  46. // the path to this page
  47. $context['path_bar'] = array( 'users/' => i18n::s('People') );
  48. // the title of the page
  49. if(!Surfer::is_logged())
  50. $context['page_title'] = i18n::s('Lost password');
  51. elseif(isset($item['full_name']) && $item['full_name'])
  52. $context['page_title'] = sprintf(i18n::s('%s: %s'), i18n::s('Password'), $item['full_name']);
  53. elseif(isset($item['nick_name']))
  54. $context['page_title'] = sprintf(i18n::s('%s: %s'), i18n::s('Password'), $item['nick_name']);
  55. else
  56. $context['page_title'] = i18n::s('Change password');
  57. // stop crawlers
  58. if(Surfer::is_crawler()) {
  59. Safe::header('Status: 401 Unauthorized', TRUE, 401);
  60. Logger::error(i18n::s('You are not allowed to perform this operation.'));
  61. // we are using an external authenticator
  62. } elseif(isset($context['users_authenticator']) && $context['users_authenticator']) {
  63. Safe::header('Status: 401 Unauthorized', TRUE, 401);
  64. Logger::error(i18n::s('You are not allowed to perform this operation.'));
  65. // no user id has been provided
  66. } elseif(!isset($item['id']) || !$item['id']) {
  67. $context['page_title'] = i18n::s('Lost password');
  68. // redirect to the query form if mail has been enabled at this site
  69. if(!isset($context['with_email']) || ($context['with_email'] != 'Y'))
  70. Safe::redirect($context['url_to_home'].$context['url_to_root'].'query.php');
  71. // ask for nick name
  72. $with_form = TRUE;
  73. // anonymous surfers that are recovering from lost password
  74. } elseif(!Surfer::is_logged()) {
  75. // redirect to the query form if mail has been enabled at this site
  76. if(!isset($context['with_email']) || ($context['with_email'] != 'Y'))
  77. Safe::redirect($context['url_to_home'].$context['url_to_root'].'query.php');
  78. // redirect also if this user has no email address
  79. if(!isset($item['email']) || !trim($item['email']))
  80. Safe::redirect($context['url_to_home'].$context['url_to_root'].'query.php');
  81. // direct arrival
  82. if(Surfer::may_be_a_robot())
  83. $with_form = TRUE;
  84. // send authentication message
  85. else {
  86. // message title
  87. $subject = sprintf(i18n::s('Your account at %s'), strip_tags($context['site_name']));
  88. // top of the message
  89. $message = '<p>'.sprintf(i18n::s('This message relates to your account at %s.'),
  90. '<a href="'.$context['url_to_home'].$context['url_to_root'].'">'.strip_tags($context['site_name']).'</a>').'</p>';
  91. // mention nick name
  92. $message .= '<p>'.sprintf(i18n::s('Your nick name is %s'), $item['nick_name']).'</p>';
  93. // direct link to login page --see users/login.php
  94. $link = $context['url_to_home'].$context['url_to_root'].Users::get_login_url('login', $id, rand(1000, 9999), $item['handle']);
  95. $message .= '<p>'.i18n::s('Record this message and use the following link to authenticate to the site at any time:').'</p>'
  96. .'<p><a href="'.$link.'">'.$link.'</a></p>';
  97. // caution note
  98. $message .= '<p>'.i18n::s('Caution: This hyperlink contains your login credentials encrypted. Please be aware anyone who uses this link will have full access to your account.').'</p>';
  99. // bottom of the message
  100. $message .= '<p>'.sprintf(i18n::s('On-line help is available at %s'),
  101. '<a href="'.$context['url_to_home'].$context['url_to_root'].'help/'.'">'.$context['url_to_home'].$context['url_to_root'].'help/'.'</a>').'</p>'
  102. .'<p>'.sprintf(i18n::s('Thank you for your interest into %s.'),
  103. '<a href="'.$context['url_to_home'].$context['url_to_root'].'">'.strip_tags($context['site_name']).'</a>').'</p>';
  104. // enable threading
  105. $headers = Mailer::set_thread('user:'.$item['id']);
  106. // post the confirmation message
  107. Mailer::notify(NULL, $item['email'], $subject, $message, $headers);
  108. // feed-back message
  109. $context['text'] .= '<p>'.i18n::s('A reminder message has been sent to you. Check your mailbox and use provided information to authenticate to this site.').'</p>';
  110. // back to the anchor page
  111. $links = array();
  112. $links[] = Skin::build_link('users/login.php', i18n::s('Login'));
  113. $context['text'] .= Skin::finalize_list($links, 'assistant_bar');
  114. }
  115. // redirect to the origin server
  116. } elseif($origin) {
  117. Logger::error(sprintf(i18n::s('We are only keeping a shadow record for this profile. Please handle this account at %s'), Skin::build_link('http://'.$origin, $origin, 'external')));
  118. // password is changing
  119. } elseif(isset($_REQUEST['confirm'])) {
  120. // restrictions: anyone can modify its own profile; associates can modify everything
  121. if(($item['id'] != Surfer::get_id()) && !Surfer::is_associate()) {
  122. Safe::header('Status: 401 Unauthorized', TRUE, 401);
  123. Logger::error(i18n::s('You are not allowed to perform this operation.'));
  124. // passwords have to be confirmed
  125. } elseif(!isset($_REQUEST['password']) || !$_REQUEST['password'] || strcmp($_REQUEST['confirm'], $_REQUEST['password'])) {
  126. Logger::error(i18n::s('Please confirm your new password.'));
  127. $with_form = TRUE;
  128. // stop robots and replay attacks
  129. } elseif(Surfer::may_be_a_robot()) {
  130. Logger::error(i18n::s('Please prove you are not a robot.'));
  131. $with_form = TRUE;
  132. // display the form on error
  133. } elseif(!Users::put($_REQUEST)) {
  134. $with_form = TRUE;
  135. // save one click to associates
  136. } elseif(Surfer::is_associate())
  137. Safe::redirect(Users::get_permalink($item));
  138. // follow-up
  139. else {
  140. // splash message
  141. $context['text'] .= '<p>'.i18n::s('Password has been changed.').'</p>';
  142. // back to the anchor page
  143. $links = array();
  144. $links[] = Skin::build_link(Users::get_permalink($item), i18n::s('Done'), 'button');
  145. $context['text'] .= Skin::finalize_list($links, 'assistant_bar');
  146. }
  147. // display the form on GET
  148. } else
  149. $with_form = TRUE;
  150. // display the form
  151. if($with_form) {
  152. // splash message
  153. if(!isset($item['id']))
  154. $context['text'] .= '<p>'.i18n::s('If you have registered to this site, type your nick name below and we will send you a web link to authenticate.').'</p>';
  155. elseif(!Surfer::is_logged())
  156. $context['text'] .= '<p>'.i18n::s('Please confirm that you would like to receive a message to authenticate to the following account.').'</p>';
  157. // the form
  158. $context['text'] .= '<form method="post" action="'.$context['script_url'].'" id="main_form"><div>';
  159. $fields = array();
  160. // get nick name
  161. if(!isset($item['id'])) {
  162. $label = i18n::s('Nick name');
  163. $input = '<input type="text" name="id" size="40" />';
  164. $fields[] = array($label, $input);
  165. }
  166. // display full name
  167. if(isset($item['full_name']) && $item['full_name']) {
  168. $label = i18n::s('Full name');
  169. $field = $item['full_name'];
  170. $fields[] = array($label, $field);
  171. }
  172. // display email address
  173. if(isset($item['email']) && $item['email']) {
  174. $label = i18n::s('E-mail address');
  175. $field = $item['email'];
  176. $fields[] = array($label, $field);
  177. }
  178. // surfer is changing password
  179. if(Surfer::is_logged()) {
  180. // the password
  181. $label = i18n::s('New password');
  182. $input = '<input type="password" name="password" id="password" size="20" value="'.encode_field(isset($_REQUEST['password']) ? $_REQUEST['password'] : '').'" />';
  183. $fields[] = array($label, $input);
  184. // the password has to be repeated for confirmation
  185. $label = i18n::s('Password confirmation');
  186. $input = '<input type="password" name="confirm" size="20" value="'.encode_field(isset($_REQUEST['confirm']) ? $_REQUEST['confirm'] : '').'" />';
  187. $fields[] = array($label, $input);
  188. // append the script used for data checking on the browser
  189. $context['page_footer'] .= JS_PREFIX
  190. .'$("#password").focus();'."\n"
  191. .JS_SUFFIX."\n";
  192. }
  193. // stop replay attacks and robots
  194. if($field = Surfer::get_robot_stopper())
  195. $fields[] = $field;
  196. // build the form
  197. $context['text'] .= Skin::build_form($fields);
  198. // bottom commands
  199. $context['text'] .= Skin::finalize_list(array(
  200. Skin::build_submit_button(i18n::s('Submit'), i18n::s('Press [s] to submit data'), 's'),
  201. Skin::build_link(Users::get_permalink($item), i18n::s('Cancel'), 'span')
  202. ), 'assistant_bar');
  203. // hidden field that have to be saved as well
  204. if(isset($item['id']) && $item['id'])
  205. $context['text'] .= '<input type="hidden" name="id" value="'.$item['id'].'" />';
  206. // end of the form
  207. $context['text'] .= '</div></form>';
  208. }
  209. // render the skin
  210. render_skin();
  211. ?>