PageRenderTime 52ms CodeModel.GetById 27ms RepoModel.GetById 1ms app.codeStats 0ms

/application/controllers/AuthController.php

https://github.com/jverkoey/snaapilookup
PHP | 320 lines | 218 code | 66 blank | 36 comment | 43 complexity | 4c94025f8cdd8af14ce6e577f306751a MD5 | raw file
  1. <?php
  2. include_once APPLICATION_PATH . '/controllers/SnaapiController.php';
  3. #
  4. # RFC822 Email Parser
  5. #
  6. # By Cal Henderson <cal@iamcal.com>
  7. # This code is licensed under a Creative Commons Attribution-ShareAlike 2.5 License
  8. # http://creativecommons.org/licenses/by-sa/2.5/
  9. #
  10. # $Revision: 1.1 $
  11. #
  12. function is_valid_email_address($email){
  13. $qtext = '[^\\x0d\\x22\\x5c\\x80-\\xff]';
  14. $dtext = '[^\\x0d\\x5b-\\x5d\\x80-\\xff]';
  15. $atom = '[^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c'.
  16. '\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+';
  17. $quoted_pair = '\\x5c[\\x00-\\x7f]';
  18. $domain_literal = "\\x5b($dtext|$quoted_pair)*\\x5d";
  19. $quoted_string = "\\x22($qtext|$quoted_pair)*\\x22";
  20. $domain_ref = $atom;
  21. $sub_domain = "($domain_ref|$domain_literal)";
  22. $word = "($atom|$quoted_string)";
  23. $domain = "$sub_domain(\\x2e$sub_domain)*";
  24. $local_part = "$word(\\x2e$word)*";
  25. $addr_spec = "$local_part\\x40$domain";
  26. return preg_match("!^$addr_spec$!", $email) ? 1 : 0;
  27. }
  28. class AuthController extends SnaapiController {
  29. /**
  30. * /auth/
  31. */
  32. public function indexAction() {
  33. $this->_helper->getHelper('Redirector')
  34. ->setGotoSimple('index', 'login');
  35. $this->_helper->viewRenderer->setNoRender();
  36. }
  37. /**
  38. * /auth/login
  39. */
  40. public function loginAction() {
  41. if( $this->getRequest()->isPost() && isset($_POST['openid_action']) ||
  42. $this->getRequest()->isGet() && isset($_GET['openid_mode']) ) {
  43. $this->loginOpenID();
  44. } else if( $this->getRequest()->isPost() && isset($_POST['login_action']) ) {
  45. $this->loginUserID();
  46. } else {
  47. $this->_helper->getHelper('Redirector')
  48. ->setGotoSimple('index', 'login');
  49. }
  50. $this->_helper->viewRenderer->setNoRender();
  51. }
  52. /**
  53. * /auth/signup
  54. */
  55. public function signupAction() {
  56. if( $this->getRequest()->isPost() && isset($_POST['signup_action']) ) {
  57. $this->createAccount();
  58. } else {
  59. $this->_helper->getHelper('Redirector')
  60. ->setGotoSimple('index', 'signup');
  61. }
  62. $this->_helper->viewRenderer->setNoRender();
  63. }
  64. /**
  65. * /auth/logout
  66. */
  67. public function logoutAction() {
  68. Zend_Auth::getInstance()->clearIdentity();
  69. $this->_helper->getHelper('Redirector')
  70. ->setGotoSimple('index', 'login');
  71. }
  72. protected function failToCreateAccount($error) {
  73. $this->_forward('index', 'signup', null, array(
  74. 'signup_error' => $error,
  75. 'username' => $_POST['username'],
  76. 'email' => $_POST['email']));
  77. return false;
  78. }
  79. /**
  80. * Use the data passed in by the user to create a new account.
  81. */
  82. protected function createAccount() {
  83. if( !isset($_POST['signup_action']) ) {
  84. $this->_forward('index', 'signup', null, array(
  85. 'signup_error' => 'Improper post data.'));
  86. return false;
  87. }
  88. if( empty($_POST['username']) || empty($_POST['password']) || empty($_POST['email']) ) {
  89. return $this->failToCreateAccount('Missing fields.');
  90. }
  91. $username = $_POST['username'];
  92. $exists = $this->_getUsersModel()->nicknameExists($username);
  93. if( $exists ) {
  94. return $this->failToCreateAccount('The username you chose already exists.');
  95. }
  96. $password = $_POST['password'];
  97. if( strlen($password) < 5 || $password == $username ) {
  98. return $this->failToCreateAccount('Please provide a better password.');
  99. }
  100. $email = trim($_POST['email']);
  101. if( !is_valid_email_address($email) ) {
  102. return $this->failToCreateAccount('Invalid email provided.');
  103. }
  104. // Create the user now!
  105. $profile = array('nickname' => $username, 'email' => $email);
  106. $user_id = $this->_getUsersModel()
  107. ->createNewUserFromProfile($profile);
  108. $this->_getUserIDModel()->attachUserID($username, $password, $user_id);
  109. $authAdapter = new Zend_Auth_Adapter_DbTable(
  110. Zend_Registry::get('dbAdapter'),
  111. 'userid',
  112. 'username',
  113. 'password',
  114. "MD5(CONCAT('".Zend_Registry::get('staticSalt')."', ?, salt))"
  115. );
  116. $authAdapter->setIdentity($username)
  117. ->setCredential($password);
  118. $auth = Zend_Auth::getInstance();
  119. $result = $auth->authenticate($authAdapter);
  120. if( $result->isValid() ) {
  121. $this->_storeUserProfile($auth, $user_id, $profile);
  122. $this->_helper->getHelper('Redirector')
  123. ->setGotoSimple('edit', 'profile');
  124. } else {
  125. return $this->failToCreateAccount('Failed to authenticate you.');
  126. }
  127. return true;
  128. }
  129. protected function failToLoginUserID($error) {
  130. $params = array('login_error' => $error);
  131. $this->_forward('index', 'login', null, $params);
  132. return false;
  133. }
  134. protected function loginUserID() {
  135. $auth = Zend_Auth::getInstance();
  136. if( empty($_POST['username']) || empty($_POST['password'])) {
  137. return $this->failToLoginUserID('We weren\'t given much to work with. Make sure you fill in your username and password.');
  138. }
  139. $authAdapter = new Zend_Auth_Adapter_DbTable(
  140. Zend_Registry::get('dbAdapter'),
  141. 'userid',
  142. 'username',
  143. 'password',
  144. "MD5(CONCAT('".Zend_Registry::get('staticSalt')."', ?, salt))"
  145. );
  146. $authAdapter->setIdentity($_POST['username'])
  147. ->setCredential($_POST['password']);
  148. $auth = Zend_Auth::getInstance();
  149. $result = $auth->authenticate($authAdapter);
  150. if( !$result->isValid() ) {
  151. return $this->failToLoginUserID(implode($result->getMessages(), '<br/>'));
  152. }
  153. $user_id = $this->_getUsersModel()->fetchUserIdByNickname($auth->getIdentity());
  154. $this->_storeUserProfile($auth, $user_id, $this->_getUsersModel()->fetchUserProfile($user_id));
  155. $this->_getUsersModel()->updateLoginTime($user_id);
  156. // A great success!
  157. $this->_helper->getHelper('Redirector')
  158. ->setGotoSimple('index', 'index');
  159. return true;
  160. }
  161. /**
  162. * Map a specific OpenID url to its equivalent, valid OpenID url.
  163. * Example: flickr.com doesn't actually provide OpenID support, so we redirect to me.yahoo.com.
  164. *
  165. * @param string $url
  166. * @return null|string
  167. */
  168. protected function mapOpenIDUrl($url) {
  169. $urlmap = array(
  170. 'http://flickr.com/' => 'http://me.yahoo.com/'
  171. );
  172. $normalizedUrl = $url;
  173. if( Zend_OpenId::normalizeUrl($normalizedUrl) ) {
  174. foreach( $urlmap as $key => $val ) {
  175. Zend_OpenId::normalizeUrl($key);
  176. if( $normalizedUrl == $key ) {
  177. $normalizedUrl = $val;
  178. Zend_OpenId::normalizeUrl($normalizedUrl);
  179. break;
  180. }
  181. }
  182. return $normalizedUrl;
  183. }
  184. return null;
  185. }
  186. protected function isOpenIDCallback() {
  187. return isset($_GET['openid_mode']) || isset($_POST['openid_mode']);
  188. }
  189. protected function failToLoginOpenID($error, $url = null) {
  190. $params = array('error' => $error);
  191. if( $url ) {
  192. $params['openid_url'] = $url;
  193. }
  194. $this->_forward('index', 'login', null, $params);
  195. return false;
  196. }
  197. protected function loginOpenID() {
  198. $auth = Zend_Auth::getInstance();
  199. if( isset($_POST['openid_action']) || $this->isOpenIDCallback() ) {
  200. if( !$this->isOpenIDCallback() && empty($_POST['openid_url']) ) {
  201. return $this->failToLoginOpenID('We weren\'t given much to work with. Make sure you fill in your OpenID url.');
  202. }
  203. $normalizedUrl = !$this->isOpenIDCallback() ? $_POST['openid_url'] : null;
  204. if( $this->isOpenIDCallback() || ($normalizedUrl = $this->mapOpenIDUrl($normalizedUrl)) ) {
  205. $sreg = new Zend_OpenId_Extension_Sreg(array(
  206. 'nickname' => false,
  207. 'email' => false,
  208. 'fullname' => false,
  209. 'dob' => false,
  210. 'gender' => false,
  211. 'postcode' => false,
  212. 'country' => false,
  213. 'language' => false,
  214. 'timezone' => false
  215. ), null, 1.1);
  216. $result = $auth->authenticate(
  217. new Zend_Auth_Adapter_OpenId($normalizedUrl, null, null, null, $sreg));
  218. if( !$result->isValid() ) {
  219. return $this->failToLoginOpenID(implode($result->getMessages(), '<br/>'),
  220. !$this->isOpenIDCallback() ? $_POST['openid_url'] : null);
  221. }
  222. $user_id = $this->_getOpenIDModel()->fetchUserId($auth->getIdentity());
  223. if( !$user_id ) {
  224. // This is a new user.
  225. $profile = $sreg->getProperties();
  226. // Avoid dupes.
  227. if( isset($profile['nickname']) && !empty($profile['nickname']) ) {
  228. $exists = $this->_getUsersModel()->nicknameExists($profile['nickname']);
  229. unset($profile['nickname']);
  230. }
  231. $user_id = $this->_getUsersModel()
  232. ->createNewUserFromProfile($profile);
  233. $this->_getOpenIDModel()->attachOpenID($auth->getIdentity(), $user_id);
  234. $this->_storeUserProfile($auth, $user_id, $profile);
  235. $this->_helper->getHelper('Redirector')
  236. ->setGotoSimple('confirm', 'profile');
  237. } else {
  238. // A great success!
  239. $this->_getUsersModel()->updateLoginTime($user_id);
  240. $this->_storeUserProfile($auth, $user_id, $this->_getUsersModel()->fetchUserProfile($user_id));
  241. $this->_helper->getHelper('Redirector')
  242. ->setGotoSimple('index', 'index');
  243. }
  244. } else if( !$this->isOpenIDCallback() ){
  245. $this->_forward('index', 'login', null, array(
  246. 'error' => 'The OpenID url you provided isn\'t valid.',
  247. 'openid_url' => $_POST['openid_url']));
  248. }
  249. } else {
  250. return $this->failToLoginOpenID('No data sent over the wire.');
  251. }
  252. return true;
  253. }
  254. }