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

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.         $password self::preparePlainTextPassword($user->getName(), $password);
  156.         if (!password_verify($password$user->getPassword())) {
  157.             return false;
  158.         }
  159.         $config \Pimcore::getContainer()->getParameter('pimcore.config')['security']['password'];
  160.         if (password_needs_rehash($user->getPassword(), $config['algorithm'], $config['options'])) {
  161.             $user->setPassword(self::getPasswordHash($user->getName(), $password));
  162.             $user->save();
  163.         }
  164.         return true;
  165.     }
  166.     /**
  167.      * @param User|null $user
  168.      *
  169.      * @return bool
  170.      */
  171.     public static function isValidUser($user)
  172.     {
  173.         if ($user instanceof User && $user->isActive() && $user->getId() && $user->getPassword()) {
  174.             return true;
  175.         }
  176.         return false;
  177.     }
  178.     /**
  179.      * @internal
  180.      *
  181.      * @param string $username
  182.      * @param string $plainTextPassword
  183.      *
  184.      * @return string
  185.      *
  186.      * @throws \Exception
  187.      */
  188.     public static function getPasswordHash($username$plainTextPassword)
  189.     {
  190.         $password self::preparePlainTextPassword($username$plainTextPassword);
  191.         $config \Pimcore::getContainer()->getParameter('pimcore.config')['security']['password'];
  192.         if ($hash password_hash($password$config['algorithm'], $config['options'])) {
  193.             return $hash;
  194.         }
  195.         throw new \Exception('Unable to create password hash for user: ' $username);
  196.     }
  197.     /**
  198.      * @param string $username
  199.      * @param string $plainTextPassword
  200.      *
  201.      * @return string
  202.      */
  203.     private static function preparePlainTextPassword($username$plainTextPassword)
  204.     {
  205.         // plaintext password is prepared as digest A1 hash, this is to be backward compatible because this was
  206.         // the former hashing algorithm in pimcore (< version 2.1.1)
  207.         return md5($username ':pimcore:' $plainTextPassword);
  208.     }
  209.     /**
  210.      * @internal
  211.      *
  212.      * @param string $username
  213.      *
  214.      * @return string
  215.      */
  216.     public static function generateToken($username)
  217.     {
  218.         $secret \Pimcore::getContainer()->getParameter('secret');
  219.         $data time() - '|' $username;
  220.         $token Crypto::encryptWithPassword($data$secret);
  221.         return $token;
  222.     }
  223.     /**
  224.      * @param string $token
  225.      *
  226.      * @return array
  227.      */
  228.     private static function tokenDecrypt($token)
  229.     {
  230.         $secret \Pimcore::getContainer()->getParameter('secret');
  231.         $decrypted Crypto::decryptWithPassword($token$secret);
  232.         return explode('|'$decrypted);
  233.     }
  234. }