vendor/pimcore/pimcore/lib/Tool/Authentication.php line 73

Open in your IDE?
  1. <?php
  2. /**
  3.  * Pimcore
  4.  *
  5.  * This source file is available under two different licenses:
  6.  * - GNU General Public License version 3 (GPLv3)
  7.  * - Pimcore Commercial License (PCL)
  8.  * Full copyright and license information is available in
  9.  * LICENSE.md which is distributed with this source code.
  10.  *
  11.  *  @copyright  Copyright (c) Pimcore GmbH (http://www.pimcore.org)
  12.  *  @license    http://www.pimcore.org/license     GPLv3 and PCL
  13.  */
  14. namespace Pimcore\Tool;
  15. use Defuse\Crypto\Crypto;
  16. use Defuse\Crypto\Exception\CryptoException;
  17. use Pimcore\Logger;
  18. use Pimcore\Model\User;
  19. use Pimcore\Tool;
  20. use Symfony\Component\HttpFoundation\Request;
  21. class Authentication
  22. {
  23.     /**
  24.      * @deprecated
  25.      *
  26.      * @param string $username
  27.      * @param string $password
  28.      *
  29.      * @return null|User
  30.      */
  31.     public static function authenticatePlaintext($username$password)
  32.     {
  33.         trigger_deprecation(
  34.             'pimcore/pimcore',
  35.             '10.6',
  36.             sprintf('%s is deprecated and will be removed in Pimcore 11'__METHOD__),
  37.         );
  38.         /** @var User $user */
  39.         $user User::getByName($username);
  40.         // user needs to be active, needs a password and an ID (do not allow system user to login, ...)
  41.         if (self::isValidUser($user)) {
  42.             if (self::verifyPassword($user$password)) {
  43.                 $user->setLastLoginDate(); //set user current login date
  44.                 return $user;
  45.             }
  46.         }
  47.         return null;
  48.     }
  49.     /**
  50.      * @param Request|null $request
  51.      *
  52.      * @return User|null
  53.      */
  54.     public static function authenticateSession(Request $request null)
  55.     {
  56.         if (null === $request) {
  57.             $request \Pimcore::getContainer()->get('request_stack')->getCurrentRequest();
  58.             if (null === $request) {
  59.                 return null;
  60.             }
  61.         }
  62.         if (!Session::requestHasSessionId($requesttrue)) {
  63.             // if no session cookie / ID no authentication possible, we don't need to start a session
  64.             return null;
  65.         }
  66.         $session Session::getReadOnly();
  67.         $user $session->get('user');
  68.         if ($user instanceof User) {
  69.             // renew user
  70.             $user User::getById($user->getId());
  71.             if (self::isValidUser($user)) {
  72.                 return $user;
  73.             }
  74.         }
  75.         return null;
  76.     }
  77.     /**
  78.      * @deprecated
  79.      *
  80.      * @throws \Exception
  81.      *
  82.      * @return User
  83.      */
  84.     public static function authenticateHttpBasic()
  85.     {
  86.         trigger_deprecation(
  87.             'pimcore/pimcore',
  88.             '10.6',
  89.             sprintf('%s is deprecated and will be removed in Pimcore 11'__METHOD__),
  90.         );
  91.         // we're using Sabre\HTTP for basic auth
  92.         $request \Sabre\HTTP\Sapi::getRequest();
  93.         $response = new \Sabre\HTTP\Response();
  94.         $auth = new \Sabre\HTTP\Auth\Basic(Tool::getHostname(), $request$response);
  95.         $result $auth->getCredentials();
  96.         if (is_array($result)) {
  97.             list($username$password) = $result;
  98.             $user self::authenticatePlaintext($username$password);
  99.             if ($user) {
  100.                 return $user;
  101.             }
  102.         }
  103.         $auth->requireLogin();
  104.         $response->setBody('Authentication required');
  105.         Logger::error('Authentication Basic (WebDAV) required');
  106.         \Sabre\HTTP\Sapi::sendResponse($response);
  107.         die();
  108.     }
  109.     /**
  110.      * @param string $token
  111.      * @param bool $adminRequired
  112.      *
  113.      * @return null|User
  114.      */
  115.     public static function authenticateToken($token$adminRequired false)
  116.     {
  117.         $username null;
  118.         $timestamp null;
  119.         try {
  120.             $decrypted self::tokenDecrypt($token);
  121.             list($timestamp$username) = $decrypted;
  122.         } catch (CryptoException $e) {
  123.             return null;
  124.         }
  125.         $user User::getByName($username);
  126.         if (self::isValidUser($user)) {
  127.             if ($adminRequired && !$user->isAdmin()) {
  128.                 return null;
  129.             }
  130.             try {
  131.                 $timeZone date_default_timezone_get();
  132.                 date_default_timezone_set('UTC');
  133.                 if ($timestamp time() || $timestamp < (time() - (60 60 24))) {
  134.                     return null;
  135.                 }
  136.             } finally {
  137.                 date_default_timezone_set($timeZone);
  138.             }
  139.             return $user;
  140.         }
  141.         return null;
  142.     }
  143.     /**
  144.      * @param User $user
  145.      * @param string $password
  146.      *
  147.      * @return bool
  148.      */
  149.     public static function verifyPassword($user$password)
  150.     {
  151.         if (!$user->getPassword()) {
  152.             // do not allow logins for users without a password
  153.             return false;
  154.         }
  155.         if (!password_verify(self::preparePlainTextPassword($user->getName(), $password), $user->getPassword())) {
  156.             return false;
  157.         }
  158.         $config \Pimcore::getContainer()->getParameter('pimcore.config')['security']['password'];
  159.         if (password_needs_rehash($user->getPassword(), $config['algorithm'], $config['options'])) {
  160.             $user->setPassword(self::getPasswordHash($user->getName(), $password));
  161.             $user->save();
  162.         }
  163.         return true;
  164.     }
  165.     /**
  166.      * @param User|null $user
  167.      *
  168.      * @return bool
  169.      */
  170.     public static function isValidUser($user)
  171.     {
  172.         if ($user instanceof User && $user->isActive() && $user->getId() && $user->getPassword()) {
  173.             return true;
  174.         }
  175.         return false;
  176.     }
  177.     /**
  178.      * @internal
  179.      *
  180.      * @param string $username
  181.      * @param string $plainTextPassword
  182.      *
  183.      * @return string
  184.      *
  185.      * @throws \Exception
  186.      */
  187.     public static function getPasswordHash($username$plainTextPassword)
  188.     {
  189.         $password self::preparePlainTextPassword($username$plainTextPassword);
  190.         $config \Pimcore::getContainer()->getParameter('pimcore.config')['security']['password'];
  191.         if ($hash password_hash($password$config['algorithm'], $config['options'])) {
  192.             return $hash;
  193.         }
  194.         throw new \Exception('Unable to create password hash for user: ' $username);
  195.     }
  196.     /**
  197.      * @param string $username
  198.      * @param string $plainTextPassword
  199.      *
  200.      * @return string
  201.      */
  202.     private static function preparePlainTextPassword($username$plainTextPassword)
  203.     {
  204.         // plaintext password is prepared as digest A1 hash, this is to be backward compatible because this was
  205.         // the former hashing algorithm in pimcore (< version 2.1.1)
  206.         return md5($username ':pimcore:' $plainTextPassword);
  207.     }
  208.     /**
  209.      * @internal
  210.      *
  211.      * @param string $username
  212.      *
  213.      * @return string
  214.      */
  215.     public static function generateToken($username)
  216.     {
  217.         $secret \Pimcore::getContainer()->getParameter('secret');
  218.         $data time() - '|' $username;
  219.         $token Crypto::encryptWithPassword($data$secret);
  220.         return $token;
  221.     }
  222.     /**
  223.      * @param string $token
  224.      *
  225.      * @return array
  226.      */
  227.     private static function tokenDecrypt($token)
  228.     {
  229.         $secret \Pimcore::getContainer()->getParameter('secret');
  230.         $decrypted Crypto::decryptWithPassword($token$secret);
  231.         return explode('|'$decrypted);
  232.     }
  233. }