Auth.php 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. <?php
  2. class Application_Model_Auth
  3. {
  4. const TOKEN_LIFETIME = 'P2D'; // DateInterval syntax
  5. private function generateToken($action, $user_id)
  6. {
  7. $salt = md5("pro");
  8. $token = self::generateRandomString();
  9. $info = new CcSubjsToken();
  10. $info->setDbUserId($user_id);
  11. $info->setDbAction($action);
  12. $info->setDbToken(sha1($token.$salt));
  13. $info->setDbCreated(gmdate('Y-m-d H:i:s'));
  14. $info->save();
  15. Logging::debug("generated token {$token}");
  16. return $token;
  17. }
  18. public function sendPasswordRestoreLink($user, $view)
  19. {
  20. $token = $this->generateToken('password.restore', $user->getDbId());
  21. $e_link_protocol = empty($_SERVER['HTTPS']) ? "http" : "https";
  22. $e_link_base = $_SERVER['SERVER_NAME'];
  23. $e_link_port = $_SERVER['SERVER_PORT'];
  24. $e_link_path = $view->url(array('user_id' => $user->getDbId(), 'token' => $token), 'password-change');
  25. $message = sprintf(_("Hi %s, \n\nClick this link to reset your password: "), $user->getDbLogin());
  26. $message .= "{$e_link_protocol}://{$e_link_base}:{$e_link_port}{$e_link_path}";
  27. $str = sprintf(_('%s Password Reset'), PRODUCT_NAME);
  28. $success = Application_Model_Email::send($str, $message, $user->getDbEmail());
  29. return $success;
  30. }
  31. public function invalidateTokens($user, $action)
  32. {
  33. CcSubjsTokenQuery::create()
  34. ->filterByDbAction($action)
  35. ->filterByDbUserId($user->getDbId())
  36. ->delete();
  37. }
  38. public function checkToken($user_id, $token, $action)
  39. {
  40. $salt = md5("pro");
  41. $token_info = CcSubjsTokenQuery::create()
  42. ->filterByDbAction($action)
  43. ->filterByDbUserId($user_id)
  44. ->filterByDbToken(sha1($token.$salt))
  45. ->findOne();
  46. if (empty($token_info)) {
  47. return false;
  48. }
  49. $now = new DateTime();
  50. $token_life = new DateInterval(self::TOKEN_LIFETIME);
  51. $token_created = new DateTime($token_info->getDbCreated(), new DateTimeZone("UTC"));
  52. return $now->sub($token_life)->getTimestamp() < $token_created->getTimestamp();
  53. }
  54. /**
  55. * Gets the adapter for authentication against a database table
  56. *
  57. * @return object
  58. */
  59. public static function getAuthAdapter()
  60. {
  61. $dbAdapter = Zend_Db_Table::getDefaultAdapter();
  62. $authAdapter = new Zend_Auth_Adapter_DbTable($dbAdapter);
  63. $authAdapter->setTableName('cc_subjs')
  64. ->setIdentityColumn('login')
  65. ->setCredentialColumn('pass')
  66. ->setCredentialTreatment('MD5(?)');
  67. return $authAdapter;
  68. }
  69. /**
  70. * Get random string
  71. *
  72. * @param int $length
  73. * @param string $allowed_chars
  74. * @return string
  75. */
  76. final public function generateRandomString($length = 12, $allowed_chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789')
  77. {
  78. $string = '';
  79. for ($i = 0; $i < $length; $i++) {
  80. $string .= $allowed_chars[mt_rand(0, strlen($allowed_chars) - 1)];
  81. }
  82. return $string;
  83. }
  84. /** It is essential to do this before interacting with Zend_Auth otherwise sessions could be shared between
  85. * different copies of Airtime on the same webserver. This essentially pins this session to:
  86. * - The server hostname - including subdomain so we segment multiple Airtime installs on different subdomains
  87. * - The remote IP of the browser - to help prevent session hijacking
  88. * - The client ID - same reason as server hostname
  89. * @param Zend_Auth $auth Get this with Zend_Auth::getInstance().
  90. */
  91. public static function pinSessionToClient($auth)
  92. {
  93. $CC_CONFIG = Config::getConfig();
  94. $serverName = isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : "";
  95. $remoteAddr = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : "";
  96. $sessionIdentifier = 'Airtime' . '-' . $serverName . '-' . $remoteAddr . '-' . Application_Model_Preference::GetClientId() . '-' . $CC_CONFIG["baseDir"];
  97. $auth->setStorage(new Zend_Auth_Storage_Session($sessionIdentifier));
  98. }
  99. }