pradosoft /
prado
| 1 | <?php |
||||||
| 2 | |||||||
| 3 | /** |
||||||
| 4 | * TAuthManager class file |
||||||
| 5 | * |
||||||
| 6 | * @author Qiang Xue <[email protected]> |
||||||
| 7 | * @link https://github.com/pradosoft/prado |
||||||
| 8 | * @license https://github.com/pradosoft/prado/blob/master/LICENSE |
||||||
| 9 | */ |
||||||
| 10 | |||||||
| 11 | namespace Prado\Security; |
||||||
| 12 | |||||||
| 13 | use Prado\Exceptions\TConfigurationException; |
||||||
| 14 | use Prado\Exceptions\TInvalidOperationException; |
||||||
| 15 | use Prado\TPropertyValue; |
||||||
| 16 | use Prado\Web\Services\TPageService; |
||||||
| 17 | use Prado\Web\THttpCookie; |
||||||
| 18 | |||||||
| 19 | /** |
||||||
| 20 | * TAuthManager class |
||||||
| 21 | * |
||||||
| 22 | * TAuthManager performs user authentication and authorization for a Prado application. |
||||||
| 23 | * TAuthManager works together with a {@see \Prado\Security\IUserManager} module that can be |
||||||
| 24 | * specified via the {@see setUserManager UserManager} property. |
||||||
| 25 | * If an authorization fails, TAuthManager will try to redirect the client |
||||||
| 26 | * browser to a login page that is specified via the {@see setLoginPage LoginPage}. |
||||||
| 27 | * To login or logout a user, call {@see login} or {@see logout}, respectively. |
||||||
| 28 | * |
||||||
| 29 | * The {@see setAuthExpire AuthExpire} property can be used to define the time |
||||||
| 30 | * in seconds after which the authentication should expire. |
||||||
| 31 | * {@see setAllowAutoLogin AllowAutoLogin} specifies if the login information |
||||||
| 32 | * should be stored in a cookie to perform automatic login. Enabling this |
||||||
| 33 | * feature will cause that {@see setAuthExpire AuthExpire} has no effect |
||||||
| 34 | * since the user will be logged in again on authentication expiration. |
||||||
| 35 | * |
||||||
| 36 | * To load TAuthManager, configure it in application configuration as follows, |
||||||
| 37 | * <module id="auth" class="Prado\Security\TAuthManager" UserManager="users" LoginPage="login" /> |
||||||
| 38 | * <module id="users" class="Prado\Security\TUserManager" /> |
||||||
| 39 | * |
||||||
| 40 | * When a user logs in, onLogin event is raised with the TUser as the parameter. |
||||||
| 41 | * If the user trying to login but fails the check, onLoginFailed is raised with the |
||||||
| 42 | * user name as parameter. When the user logs out, onLogout is raised with the TUser |
||||||
| 43 | * as parameter. |
||||||
| 44 | * |
||||||
| 45 | * @author Qiang Xue <[email protected]> |
||||||
| 46 | * @since 3.0 |
||||||
| 47 | */ |
||||||
| 48 | class TAuthManager extends \Prado\TModule |
||||||
| 49 | { |
||||||
| 50 | /** |
||||||
| 51 | * GET variable name for return url |
||||||
| 52 | */ |
||||||
| 53 | public const RETURN_URL_VAR = 'ReturnUrl'; |
||||||
| 54 | /** |
||||||
| 55 | * @var bool if the module has been initialized |
||||||
| 56 | */ |
||||||
| 57 | private $_initialized = false; |
||||||
| 58 | /** |
||||||
| 59 | * @var IUserManager user manager instance |
||||||
| 60 | */ |
||||||
| 61 | private $_userManager; |
||||||
| 62 | /** |
||||||
| 63 | * @var string login page |
||||||
| 64 | */ |
||||||
| 65 | private $_loginPage; |
||||||
| 66 | /** |
||||||
| 67 | * @var bool whether authorization should be skipped |
||||||
| 68 | */ |
||||||
| 69 | private $_skipAuthorization = false; |
||||||
| 70 | /** |
||||||
| 71 | * @var string the session var name for storing return URL |
||||||
| 72 | */ |
||||||
| 73 | private $_returnUrlVarName; |
||||||
| 74 | /** |
||||||
| 75 | * @var bool whether to allow auto login (using cookie) |
||||||
| 76 | */ |
||||||
| 77 | private $_allowAutoLogin = false; |
||||||
| 78 | /** |
||||||
| 79 | * @var string variable name used to store user session or cookie |
||||||
| 80 | */ |
||||||
| 81 | private $_userKey; |
||||||
| 82 | /** |
||||||
| 83 | * @var int authentication expiration time in seconds. Defaults to zero (no expiration) |
||||||
| 84 | */ |
||||||
| 85 | private $_authExpire = 0; |
||||||
| 86 | |||||||
| 87 | /** |
||||||
| 88 | * Initializes this module. |
||||||
| 89 | 3 | * This method is required by the IModule interface. |
|||||
| 90 | * @param \Prado\Xml\TXmlElement $config configuration for this module, can be null |
||||||
| 91 | 3 | * @throws TConfigurationException if user manager does not exist or is not IUserManager |
|||||
| 92 | 1 | */ |
|||||
| 93 | public function init($config) |
||||||
| 94 | 3 | { |
|||||
| 95 | 3 | if ($this->_userManager === null) { |
|||||
| 96 | throw new TConfigurationException('authmanager_usermanager_required'); |
||||||
| 97 | 3 | } |
|||||
| 98 | 3 | if ($this->_returnUrlVarName === null) { |
|||||
| 99 | 3 | $this->_returnUrlVarName = $this->getApplication()->getID() . ':' . self::RETURN_URL_VAR; |
|||||
| 100 | } |
||||||
| 101 | $application = $this->getApplication(); |
||||||
| 102 | 3 | if (is_string($this->_userManager)) { |
|||||
|
0 ignored issues
–
show
introduced
by
Loading history...
|
|||||||
| 103 | if (($users = $application->getModule($this->_userManager)) === null) { |
||||||
| 104 | throw new TConfigurationException('authmanager_usermanager_inexistent', $this->_userManager); |
||||||
| 105 | 3 | } |
|||||
| 106 | if (!($users instanceof IUserManager)) { |
||||||
| 107 | 3 | throw new TConfigurationException('authmanager_usermanager_invalid', $this->_userManager); |
|||||
| 108 | 3 | } |
|||||
| 109 | 3 | $this->_userManager = $users; |
|||||
| 110 | 3 | } |
|||||
| 111 | 3 | $application->attachEventHandler('OnAuthentication', [$this, 'doAuthentication']); |
|||||
| 112 | $application->attachEventHandler('OnEndRequest', [$this, 'leave']); |
||||||
| 113 | $application->attachEventHandler('OnAuthorization', [$this, 'doAuthorization']); |
||||||
| 114 | $this->_initialized = true; |
||||||
| 115 | parent::init($config); |
||||||
| 116 | 2 | } |
|||||
| 117 | |||||||
| 118 | 2 | /** |
|||||
| 119 | * @return IUserManager user manager instance |
||||||
| 120 | */ |
||||||
| 121 | public function getUserManager() |
||||||
| 122 | { |
||||||
| 123 | return $this->_userManager; |
||||||
| 124 | } |
||||||
| 125 | 3 | ||||||
| 126 | /** |
||||||
| 127 | 3 | * @param IUserManager|string $provider the user manager module ID or the user manager object |
|||||
| 128 | 1 | * @throws TInvalidOperationException if the module has been initialized or the user manager object is not IUserManager |
|||||
| 129 | */ |
||||||
| 130 | 3 | public function setUserManager($provider) |
|||||
| 131 | { |
||||||
| 132 | if ($this->_initialized) { |
||||||
| 133 | 3 | throw new TInvalidOperationException('authmanager_usermanager_unchangeable'); |
|||||
| 134 | 3 | } |
|||||
| 135 | if (!is_string($provider) && !($provider instanceof IUserManager)) { |
||||||
|
0 ignored issues
–
show
|
|||||||
| 136 | throw new TConfigurationException('authmanager_usermanager_invalid', $provider); |
||||||
| 137 | } |
||||||
| 138 | $this->_userManager = $provider; |
||||||
|
0 ignored issues
–
show
It seems like
$provider can also be of type string. However, the property $_userManager is declared as type Prado\Security\IUserManager. Maybe add an additional type check?
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly. For example, imagine you have a variable Either this assignment is in error or a type check should be added for that assignment. class Id
{
public $id;
public function __construct($id)
{
$this->id = $id;
}
}
class Account
{
/** @var Id $id */
public $id;
}
$account_id = false;
if (starsAreRight()) {
$account_id = new Id(42);
}
$account = new Account();
if ($account instanceof Id)
{
$account->id = $account_id;
}
Loading history...
|
|||||||
| 139 | 1 | } |
|||||
| 140 | |||||||
| 141 | 1 | /** |
|||||
| 142 | * @return string path of login page should login is required |
||||||
| 143 | */ |
||||||
| 144 | public function getLoginPage() |
||||||
| 145 | { |
||||||
| 146 | return $this->_loginPage; |
||||||
| 147 | } |
||||||
| 148 | |||||||
| 149 | /** |
||||||
| 150 | 1 | * Sets the login page that the client browser will be redirected to if login is needed. |
|||||
| 151 | * Login page should be specified in the format of page path. |
||||||
| 152 | 1 | * @param string $pagePath path of login page should login is required |
|||||
| 153 | 1 | * @see TPageService |
|||||
| 154 | */ |
||||||
| 155 | public function setLoginPage($pagePath) |
||||||
| 156 | { |
||||||
| 157 | $this->_loginPage = $pagePath; |
||||||
| 158 | } |
||||||
| 159 | |||||||
| 160 | /** |
||||||
| 161 | * Performs authentication. |
||||||
| 162 | * This is the event handler attached to application's Authentication event. |
||||||
| 163 | * Do not call this method directly. |
||||||
| 164 | * @param mixed $sender sender of the Authentication event |
||||||
| 165 | * @param mixed $param event parameter |
||||||
| 166 | */ |
||||||
| 167 | public function doAuthentication($sender, $param) |
||||||
| 168 | { |
||||||
| 169 | $this->onAuthenticate($param); |
||||||
| 170 | |||||||
| 171 | $service = $this->getService(); |
||||||
| 172 | if (($service instanceof TPageService) && $service->getRequestedPagePath() === $this->getLoginPage()) { |
||||||
| 173 | $this->_skipAuthorization = true; |
||||||
| 174 | } |
||||||
| 175 | } |
||||||
| 176 | |||||||
| 177 | /** |
||||||
| 178 | * Performs authorization. |
||||||
| 179 | * This is the event handler attached to application's Authorization event. |
||||||
| 180 | * Do not call this method directly. |
||||||
| 181 | * @param mixed $sender sender of the Authorization event |
||||||
| 182 | * @param mixed $param event parameter |
||||||
| 183 | */ |
||||||
| 184 | public function doAuthorization($sender, $param) |
||||||
| 185 | { |
||||||
| 186 | if (!$this->_skipAuthorization) { |
||||||
| 187 | $this->onAuthorize($param); |
||||||
| 188 | } |
||||||
| 189 | } |
||||||
| 190 | |||||||
| 191 | /** |
||||||
| 192 | * Performs login redirect if authorization fails. |
||||||
| 193 | * This is the event handler attached to application's EndRequest event. |
||||||
| 194 | * Do not call this method directly. |
||||||
| 195 | * @param mixed $sender sender of the event |
||||||
| 196 | * @param mixed $param event parameter |
||||||
| 197 | */ |
||||||
| 198 | public function leave($sender, $param) |
||||||
|
0 ignored issues
–
show
The parameter
$sender is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. Loading history...
The parameter
$param is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. Loading history...
|
|||||||
| 199 | { |
||||||
| 200 | $application = $this->getApplication(); |
||||||
| 201 | if ($application->getResponse()->getStatusCode() === 401) { |
||||||
| 202 | $service = $application->getService(); |
||||||
| 203 | if ($service instanceof TPageService) { |
||||||
| 204 | $returnUrl = $application->getRequest()->getRequestUri(); |
||||||
| 205 | $this->setReturnUrl($returnUrl); |
||||||
| 206 | $url = $service->constructUrl($this->getLoginPage()); |
||||||
| 207 | $application->getResponse()->redirect($url); |
||||||
| 208 | } |
||||||
| 209 | } |
||||||
| 210 | } |
||||||
| 211 | |||||||
| 212 | /** |
||||||
| 213 | * @return string the name of the session variable storing return URL. It defaults to 'AppID:ReturnUrl' |
||||||
| 214 | */ |
||||||
| 215 | public function getReturnUrlVarName() |
||||||
| 216 | { |
||||||
| 217 | return $this->_returnUrlVarName; |
||||||
| 218 | } |
||||||
| 219 | |||||||
| 220 | /** |
||||||
| 221 | * @param string $value the name of the session variable storing return URL. |
||||||
| 222 | */ |
||||||
| 223 | public function setReturnUrlVarName($value) |
||||||
| 224 | { |
||||||
| 225 | $this->_returnUrlVarName = $value; |
||||||
| 226 | } |
||||||
| 227 | |||||||
| 228 | /** |
||||||
| 229 | * @return string URL that the browser should be redirected to when login succeeds. |
||||||
| 230 | */ |
||||||
| 231 | public function getReturnUrl() |
||||||
| 232 | { |
||||||
| 233 | return $this->getSession()->itemAt($this->getReturnUrlVarName()); |
||||||
| 234 | } |
||||||
| 235 | |||||||
| 236 | /** |
||||||
| 237 | * Sets the URL that the browser should be redirected to when login succeeds. |
||||||
| 238 | * @param string $value the URL to be redirected to. |
||||||
| 239 | */ |
||||||
| 240 | public function setReturnUrl($value) |
||||||
| 241 | { |
||||||
| 242 | $this->getSession()->add($this->getReturnUrlVarName(), $value); |
||||||
| 243 | } |
||||||
| 244 | |||||||
| 245 | /** |
||||||
| 246 | * @return bool whether to allow remembering login so that the user logs on automatically next time. Defaults to false. |
||||||
| 247 | * @since 3.1.1 |
||||||
| 248 | */ |
||||||
| 249 | public function getAllowAutoLogin() |
||||||
| 250 | { |
||||||
| 251 | return $this->_allowAutoLogin; |
||||||
| 252 | } |
||||||
| 253 | |||||||
| 254 | /** |
||||||
| 255 | * @param bool $value whether to allow remembering login so that the user logs on automatically next time. Users have to enable cookie to make use of this feature. |
||||||
| 256 | * @since 3.1.1 |
||||||
| 257 | */ |
||||||
| 258 | public function setAllowAutoLogin($value) |
||||||
| 259 | { |
||||||
| 260 | $this->_allowAutoLogin = TPropertyValue::ensureBoolean($value); |
||||||
| 261 | } |
||||||
| 262 | |||||||
| 263 | /** |
||||||
| 264 | * @return int authentication expiration time in seconds. Defaults to zero (no expiration). |
||||||
| 265 | * @since 3.1.3 |
||||||
| 266 | */ |
||||||
| 267 | public function getAuthExpire() |
||||||
| 268 | { |
||||||
| 269 | return $this->_authExpire; |
||||||
| 270 | } |
||||||
| 271 | |||||||
| 272 | /** |
||||||
| 273 | * @param int $value authentication expiration time in seconds. Defaults to zero (no expiration). |
||||||
| 274 | * @since 3.1.3 |
||||||
| 275 | */ |
||||||
| 276 | public function setAuthExpire($value) |
||||||
| 277 | { |
||||||
| 278 | $this->_authExpire = TPropertyValue::ensureInteger($value); |
||||||
| 279 | } |
||||||
| 280 | |||||||
| 281 | /** |
||||||
| 282 | * Performs the real authentication work. |
||||||
| 283 | * An OnAuthenticate event will be raised if there is any handler attached to it. |
||||||
| 284 | * If the application already has a non-null user, it will return without further authentication. |
||||||
| 285 | * Otherwise, user information will be restored from session data. |
||||||
| 286 | * @param mixed $param parameter to be passed to OnAuthenticate event |
||||||
| 287 | * @throws TConfigurationException if session module does not exist. |
||||||
| 288 | */ |
||||||
| 289 | public function onAuthenticate($param) |
||||||
| 290 | { |
||||||
| 291 | $application = $this->getApplication(); |
||||||
| 292 | |||||||
| 293 | // restoring user info from session |
||||||
| 294 | if (($session = $application->getSession()) === null) { |
||||||
| 295 | throw new TConfigurationException('authmanager_session_required'); |
||||||
| 296 | } |
||||||
| 297 | $session->open(); |
||||||
| 298 | $sessionInfo = $session->itemAt($this->getUserKey()); |
||||||
| 299 | $user = $this->_userManager->getUser(null)->loadFromString($sessionInfo); |
||||||
| 300 | |||||||
| 301 | // check for authentication expiration |
||||||
| 302 | $isAuthExpired = $this->_authExpire > 0 && !$user->getIsGuest() && |
||||||
| 303 | ($expiretime = $session->itemAt('AuthExpireTime')) && $expiretime < time(); |
||||||
| 304 | |||||||
| 305 | // try authenticating through cookie if possible |
||||||
| 306 | if ($this->getAllowAutoLogin() && ($user->getIsGuest() || $isAuthExpired)) { |
||||||
| 307 | $cookie = $this->getRequest()->getCookies()->itemAt($this->getUserKey()); |
||||||
| 308 | if ($cookie instanceof THttpCookie) { |
||||||
|
0 ignored issues
–
show
|
|||||||
| 309 | if (($user2 = $this->_userManager->getUserFromCookie($cookie)) !== null) { |
||||||
| 310 | $user = $user2; |
||||||
| 311 | $this->updateSessionUser($user); |
||||||
| 312 | // user is restored from cookie, auth may not expire |
||||||
| 313 | $isAuthExpired = false; |
||||||
| 314 | } |
||||||
| 315 | } |
||||||
| 316 | } |
||||||
| 317 | |||||||
| 318 | $application->setUser($user); |
||||||
| 319 | |||||||
| 320 | // handle authentication expiration or update expiration time |
||||||
| 321 | if ($isAuthExpired) { |
||||||
| 322 | $this->onAuthExpire($param); |
||||||
| 323 | } else { |
||||||
| 324 | $session->add('AuthExpireTime', time() + $this->_authExpire); |
||||||
| 325 | } |
||||||
| 326 | |||||||
| 327 | // event handler gets a chance to do further auth work |
||||||
| 328 | if ($this->hasEventHandler('OnAuthenticate')) { |
||||||
| 329 | $this->raiseEvent('OnAuthenticate', $this, $application); |
||||||
|
0 ignored issues
–
show
$application of type Prado\TApplication is incompatible with the type Prado\TEventParameter expected by parameter $param of Prado\TComponent::raiseEvent().
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
| 330 | } |
||||||
| 331 | } |
||||||
| 332 | |||||||
| 333 | /** |
||||||
| 334 | * Performs user logout on authentication expiration. |
||||||
| 335 | * An 'OnAuthExpire' event will be raised if there is any handler attached to it. |
||||||
| 336 | * @param mixed $param parameter to be passed to OnAuthExpire event. |
||||||
| 337 | */ |
||||||
| 338 | public function onAuthExpire($param) |
||||||
| 339 | { |
||||||
| 340 | $this->logout(); |
||||||
| 341 | if ($this->hasEventHandler('OnAuthExpire')) { |
||||||
| 342 | $this->raiseEvent('OnAuthExpire', $this, $param); |
||||||
| 343 | } |
||||||
| 344 | } |
||||||
| 345 | |||||||
| 346 | /** |
||||||
| 347 | * Performs the real authorization work. |
||||||
| 348 | * Authorization rules obtained from the application will be used to check |
||||||
| 349 | * if a user is allowed. If authorization fails, the response status code |
||||||
| 350 | * will be set as 401 and the application terminates. |
||||||
| 351 | * @param mixed $param parameter to be passed to OnAuthorize event |
||||||
| 352 | */ |
||||||
| 353 | public function onAuthorize($param) |
||||||
|
0 ignored issues
–
show
The parameter
$param is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. Loading history...
|
|||||||
| 354 | { |
||||||
| 355 | $application = $this->getApplication(); |
||||||
| 356 | if ($this->hasEventHandler('OnAuthorize')) { |
||||||
| 357 | $this->raiseEvent('OnAuthorize', $this, $application); |
||||||
|
0 ignored issues
–
show
$application of type Prado\TApplication is incompatible with the type Prado\TEventParameter expected by parameter $param of Prado\TComponent::raiseEvent().
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
| 358 | } |
||||||
| 359 | if (!$application->getAuthorizationRules()->isUserAllowed($application->getUser(), $application->getRequest()->getRequestType(), $application->getRequest()->getUserHostAddress())) { |
||||||
| 360 | $application->getResponse()->setStatusCode(401); |
||||||
| 361 | $application->completeRequest(); |
||||||
| 362 | } |
||||||
| 363 | } |
||||||
| 364 | |||||||
| 365 | /** |
||||||
| 366 | * @return string a unique variable name for storing user session/cookie data |
||||||
| 367 | * @since 3.1.1 |
||||||
| 368 | */ |
||||||
| 369 | public function getUserKey() |
||||||
| 370 | { |
||||||
| 371 | if ($this->_userKey === null) { |
||||||
| 372 | $this->_userKey = $this->generateUserKey(); |
||||||
| 373 | } |
||||||
| 374 | return $this->_userKey; |
||||||
| 375 | } |
||||||
| 376 | |||||||
| 377 | /** |
||||||
| 378 | * @return string a key used to store user information in session |
||||||
| 379 | * @since 3.1.1 |
||||||
| 380 | */ |
||||||
| 381 | protected function generateUserKey() |
||||||
| 382 | { |
||||||
| 383 | return md5($this->getApplication()->getUniqueID() . 'prado:user'); |
||||||
| 384 | } |
||||||
| 385 | |||||||
| 386 | /** |
||||||
| 387 | * Updates the user data stored in session. |
||||||
| 388 | * @param IUser $user user object |
||||||
| 389 | * @throws TConfigurationException if session module is not loaded. |
||||||
| 390 | */ |
||||||
| 391 | public function updateSessionUser($user) |
||||||
| 392 | { |
||||||
| 393 | if (php_sapi_name() !== 'cli' && !$user->getIsGuest()) { |
||||||
| 394 | if (($session = $this->getSession()) === null) { |
||||||
| 395 | throw new TConfigurationException('authmanager_session_required'); |
||||||
| 396 | } else { |
||||||
| 397 | $session->add($this->getUserKey(), $user->saveToString()); |
||||||
| 398 | $session->regenerate(true); |
||||||
| 399 | } |
||||||
| 400 | } |
||||||
| 401 | } |
||||||
| 402 | |||||||
| 403 | /** |
||||||
| 404 | * Switches to a new user. |
||||||
| 405 | * This method will logout the current user first and login with a new one (without password.) |
||||||
| 406 | * @param string $username the new username |
||||||
| 407 | * @return bool if the switch is successful |
||||||
| 408 | */ |
||||||
| 409 | public function switchUser($username) |
||||||
| 410 | { |
||||||
| 411 | if (($user = $this->_userManager->getUser($username)) === null) { |
||||||
| 412 | return false; |
||||||
| 413 | } |
||||||
| 414 | $this->updateSessionUser($user); |
||||||
| 415 | $this->getApplication()->setUser($user); |
||||||
| 416 | return true; |
||||||
| 417 | } |
||||||
| 418 | |||||||
| 419 | /** |
||||||
| 420 | * Logs in a user with username and password. |
||||||
| 421 | * The username and password will be used to validate if login is successful. |
||||||
| 422 | * If yes, a user object will be created for the application. |
||||||
| 423 | * On successful Login, onLogin is raised with the TUser as parameter. |
||||||
| 424 | * When the login fails, onLoginFailed is raised with the username as parameter. |
||||||
| 425 | * @param string $username username |
||||||
| 426 | * @param string $password password |
||||||
| 427 | * @param int $expire number of seconds that automatic login will remain effective. If 0, it means user logs out when session ends. This parameter is added since 3.1.1. |
||||||
| 428 | * @return bool if login is successful |
||||||
| 429 | */ |
||||||
| 430 | public function login($username, #[\SensitiveParameter] $password, $expire = 0) |
||||||
| 431 | { |
||||||
| 432 | if ($this->_userManager->validateUser($username, $password)) { |
||||||
| 433 | if (($user = $this->_userManager->getUser($username)) === null) { |
||||||
| 434 | return false; |
||||||
| 435 | } |
||||||
| 436 | $this->updateSessionUser($user); |
||||||
| 437 | $this->getApplication()->setUser($user); |
||||||
| 438 | |||||||
| 439 | if ($expire > 0) { |
||||||
| 440 | $cookie = new THttpCookie($this->getUserKey(), ''); |
||||||
| 441 | $cookie->setExpire(time() + $expire); |
||||||
| 442 | $this->_userManager->saveUserToCookie($cookie); |
||||||
| 443 | $this->getResponse()->getCookies()->add($cookie); |
||||||
| 444 | } |
||||||
| 445 | $this->onLogin($user); |
||||||
| 446 | return true; |
||||||
| 447 | } else { |
||||||
| 448 | $this->onLoginFailed($username); |
||||||
| 449 | return false; |
||||||
| 450 | } |
||||||
| 451 | } |
||||||
| 452 | |||||||
| 453 | /** |
||||||
| 454 | * Logs out a user. Raises onLogout with the TUser as parameter |
||||||
| 455 | * before logging out. User session will be destroyed after this |
||||||
| 456 | * method is called. |
||||||
| 457 | * @throws TConfigurationException if session module is not loaded. |
||||||
| 458 | */ |
||||||
| 459 | public function logout() |
||||||
| 460 | { |
||||||
| 461 | $this->onLogout($this->getApplication()->getUser()); |
||||||
| 462 | if (($session = $this->getSession()) === null) { |
||||||
| 463 | throw new TConfigurationException('authmanager_session_required'); |
||||||
| 464 | } |
||||||
| 465 | $this->getApplication()->getUser()->setIsGuest(true); |
||||||
| 466 | $session->destroy(); |
||||||
| 467 | if ($this->getAllowAutoLogin()) { |
||||||
| 468 | $cookie = new THttpCookie($this->getUserKey(), ''); |
||||||
| 469 | $this->getResponse()->getCookies()->add($cookie); |
||||||
| 470 | } |
||||||
| 471 | } |
||||||
| 472 | |||||||
| 473 | /** |
||||||
| 474 | * onLogin event is raised when a user logs in |
||||||
| 475 | * @param TUser $user user being logged in |
||||||
| 476 | * @since 4.2.0 |
||||||
| 477 | */ |
||||||
| 478 | public function onLogin($user) |
||||||
| 479 | { |
||||||
| 480 | $this->raiseEvent('onLogin', $this, $user); |
||||||
|
0 ignored issues
–
show
$user of type Prado\Security\TUser is incompatible with the type Prado\TEventParameter expected by parameter $param of Prado\TComponent::raiseEvent().
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
| 481 | } |
||||||
| 482 | |||||||
| 483 | /** |
||||||
| 484 | * onLoginFailed event is raised when a user login fails |
||||||
| 485 | * @param string $username username trying to log in |
||||||
| 486 | * @since 4.2.0 |
||||||
| 487 | */ |
||||||
| 488 | public function onLoginFailed($username) |
||||||
| 489 | { |
||||||
| 490 | $this->raiseEvent('onLoginFailed', $this, $username); |
||||||
|
0 ignored issues
–
show
$username of type string is incompatible with the type Prado\TEventParameter expected by parameter $param of Prado\TComponent::raiseEvent().
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
| 491 | } |
||||||
| 492 | |||||||
| 493 | /** |
||||||
| 494 | * onLogout event is raised when a user logs out. |
||||||
| 495 | * @param TUser $user user being logged out |
||||||
| 496 | * @since 4.2.0 |
||||||
| 497 | */ |
||||||
| 498 | public function onLogout($user) |
||||||
| 499 | { |
||||||
| 500 | $this->raiseEvent('onLogout', $this, $user); |
||||||
|
0 ignored issues
–
show
$user of type Prado\Security\TUser is incompatible with the type Prado\TEventParameter expected by parameter $param of Prado\TComponent::raiseEvent().
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
| 501 | } |
||||||
| 502 | } |
||||||
| 503 |