Overview

Namespaces

  • MvcCore
    • Ext
      • Auth
        • Virtual
      • Debug
        • Tracy
      • Form
        • Core
        • Validators
      • Request
      • Router
        • Lang
      • View
        • Helpers
  • None

Classes

  • MvcCore
  • MvcCore\Config
  • MvcCore\Controller
  • MvcCore\Debug
  • MvcCore\Ext\Auth
  • MvcCore\Ext\Auth\Controller
  • MvcCore\Ext\Auth\SignInForm
  • MvcCore\Ext\Auth\SignOutForm
  • MvcCore\Ext\Auth\User
  • MvcCore\Ext\Auth\Virtual\Controller
  • MvcCore\Ext\Auth\Virtual\Form
  • MvcCore\Ext\Auth\Virtual\User
  • MvcCore\Ext\Debug\Tracy
  • MvcCore\Ext\Debug\Tracy\AuthPanel
  • MvcCore\Ext\Debug\Tracy\IncludePanel
  • MvcCore\Ext\Debug\Tracy\MvcCorePanel
  • MvcCore\Ext\Debug\Tracy\RoutingPanel
  • MvcCore\Ext\Debug\Tracy\SessionPanel
  • MvcCore\Ext\Form
  • MvcCore\Ext\Form\Button
  • MvcCore\Ext\Form\Checkbox
  • MvcCore\Ext\Form\CheckboxGroup
  • MvcCore\Ext\Form\Core\Base
  • MvcCore\Ext\Form\Core\Configuration
  • MvcCore\Ext\Form\Core\Field
  • MvcCore\Ext\Form\Core\FieldGroup
  • MvcCore\Ext\Form\Core\Helpers
  • MvcCore\Ext\Form\Core\Validator
  • MvcCore\Ext\Form\Core\View
  • MvcCore\Ext\Form\CountrySelect
  • MvcCore\Ext\Form\Date
  • MvcCore\Ext\Form\DateTime
  • MvcCore\Ext\Form\Email
  • MvcCore\Ext\Form\Hidden
  • MvcCore\Ext\Form\NoType
  • MvcCore\Ext\Form\Number
  • MvcCore\Ext\Form\Password
  • MvcCore\Ext\Form\RadioGroup
  • MvcCore\Ext\Form\Range
  • MvcCore\Ext\Form\ResetButton
  • MvcCore\Ext\Form\ResetInput
  • MvcCore\Ext\Form\Select
  • MvcCore\Ext\Form\SubmitButton
  • MvcCore\Ext\Form\SubmitInput
  • MvcCore\Ext\Form\Text
  • MvcCore\Ext\Form\Textarea
  • MvcCore\Ext\Form\Time
  • MvcCore\Ext\Form\Validators\CompanyId
  • MvcCore\Ext\Form\Validators\CompanyVatId
  • MvcCore\Ext\Form\Validators\Date
  • MvcCore\Ext\Form\Validators\Email
  • MvcCore\Ext\Form\Validators\FloatVal
  • MvcCore\Ext\Form\Validators\Integer
  • MvcCore\Ext\Form\Validators\Maxlength
  • MvcCore\Ext\Form\Validators\MaxSelectedOptions
  • MvcCore\Ext\Form\Validators\MinSelectedOptions
  • MvcCore\Ext\Form\Validators\NumberField
  • MvcCore\Ext\Form\Validators\Pattern
  • MvcCore\Ext\Form\Validators\Phone
  • MvcCore\Ext\Form\Validators\RangeField
  • MvcCore\Ext\Form\Validators\SafeString
  • MvcCore\Ext\Form\Validators\Time
  • MvcCore\Ext\Form\Validators\Url
  • MvcCore\Ext\Form\Validators\ValueInOptions
  • MvcCore\Ext\Form\Validators\ZipCode
  • MvcCore\Ext\Request\ApacheDpi
  • MvcCore\Ext\Request\Cli
  • MvcCore\Ext\Router\Lang
  • MvcCore\Ext\Router\Lang\Route
  • MvcCore\Ext\Router\Media
  • MvcCore\Ext\Router\MediaSiteKey
  • MvcCore\Ext\View\Helpers\Assets
  • MvcCore\Ext\View\Helpers\Css
  • MvcCore\Ext\View\Helpers\Js
  • MvcCore\Ext\View\Helpers\LineBreaks
  • MvcCore\Model
  • MvcCore\Request
  • MvcCore\Response
  • MvcCore\Route
  • MvcCore\Router
  • MvcCore\Session
  • MvcCore\Tool
  • MvcCore\View

Exceptions

  • MvcCore\Ext\Form\Core\Exception
  • Overview
  • Namespace
  • Class
  • Tree
  1:   2:   3:   4:   5:   6:   7:   8:   9:  10:  11:  12:  13:  14:  15:  16:  17:  18:  19:  20:  21:  22:  23:  24:  25:  26:  27:  28:  29:  30:  31:  32:  33:  34:  35:  36:  37:  38:  39:  40:  41:  42:  43:  44:  45:  46:  47:  48:  49:  50:  51:  52:  53:  54:  55:  56:  57:  58:  59:  60:  61:  62:  63:  64:  65:  66:  67:  68:  69:  70:  71:  72:  73:  74:  75:  76:  77:  78:  79:  80:  81:  82:  83:  84:  85:  86:  87:  88:  89:  90:  91:  92:  93:  94:  95:  96:  97:  98:  99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215: 216: 217: 218: 219: 220: 221: 222: 223: 224: 225: 226: 227: 228: 229: 230: 231: 232: 233: 234: 235: 236: 237: 238: 239: 240: 241: 242: 243: 244: 245: 246: 247: 248: 249: 250: 251: 252: 253: 254: 255: 256: 257: 258: 259: 260: 261: 262: 263: 264: 265: 266: 267: 268: 269: 270: 271: 272: 273: 274: 275: 276: 277: 278: 279: 280: 281: 282: 283: 284: 285: 286: 287: 288: 289: 290: 291: 292: 293: 294: 295: 296: 297: 298: 299: 300: 301: 302: 303: 304: 305: 306: 307: 308: 309: 310: 311: 312: 313: 314: 315: 316: 317: 318: 319: 320: 321: 322: 323: 324: 325: 326: 327: 328: 329: 330: 331: 332: 333: 334: 335: 336: 337: 338: 339: 340: 341: 342: 343: 344: 345: 346: 347: 348: 349: 350: 351: 352: 353: 354: 355: 356: 357: 358: 359: 360: 361: 362: 363: 364: 365: 366: 367: 368: 369: 370: 371: 372: 373: 374: 375: 376: 377: 378: 379: 380: 381: 382: 383: 384: 385: 386: 387: 388: 389: 390: 391: 392: 393: 394: 395: 396: 397: 398: 399: 400: 401: 402: 403: 404: 405: 406: 407: 408: 409: 410: 411: 412: 413: 414: 415: 416: 417: 418: 419: 420: 421: 422: 423: 424: 425: 426: 427: 428: 429: 430: 431: 432: 433: 434: 435: 436: 437: 438: 439: 440: 441: 442: 443: 444: 445: 446: 447: 
<?php

/**
 * MvcCore
 *
 * This source file is subject to the BSD 3 License
 * For the full copyright and license information, please view
 * the LICENSE.md file that are distributed with this source code.
 *
 * @copyright   Copyright (c) 2016 Tom FlĂ­dr (https://github.com/mvccore/mvccore)
 * @license     https://mvccore.github.io/docs/mvccore/4.0.0/LICENCE.md
 */

namespace MvcCore\Ext;

class Auth {
    /**
     * MvcCore Extension - Auth - version:
     * Comparation by PHP function version_compare();
     * @see http://php.net/manual/en/function.version-compare.php
     */
    const VERSION = '4.2.0';
    /**
     * Singleton instance of authentication extension service.
     * @var \MvcCore\Ext\Auth
     */
    protected static $instance = NULL;
    /**
     * User model isntace or null if user is not authenticated in session.
     * @var \MvcCore\Ext\Auth\Virtual\User
     */
    protected $user = NULL;
    /**
     * If user is authenticated in session, there is scompleted 
     * sign in form, else there is sign out form.
     * @var \MvcCore\Ext\Auth\Virtual\Form
     */
    protected $form = NULL;
    /**
     * Authentication configuration, there is possible to change 
     * any configuration option ne by one by any setter method
     * multiple values or by \MvcCore\Ext\Auth::GetInstance()->Configure([...]) method.
     * Config array is retyped to stdClass in __constructor().
     * @var \stdClass
     */
    protected $config = array(
        'expirationSeconds' => 600, // 10 minutes
        'userClass'         => '\User',
        'controllerClass'   => '\Controller',
        'signInFormClass'   => '\SignInForm',
        'signOutFormClass'  => '\SignOutForm',
        'signedInUrl'       => '',
        'signedOutUrl'      => '',
        'errorUrl'          => '',
        'signInRoute'       => "#^/signin#",
        'signOutRoute'      => "#^/signout#",
        'passwordHashSalt'  => 'S3F8OI2P3X6ER1F6XY2Q9ZCY',
        'translator'        => NULL,
    );
    /**
     * If true, authentication service allready try to load
     * user from session and authentication detection os not
     * necessary to run again. False by default.
     * @var bool
     */
    protected $userInitialized = FALSE;

    /**
     * Return singleton instance. If instance exists, return existing instance,
     * if not, create new Auth service instance, store it and return it.
     * @return \MvcCore\Ext\Auth
     */
    public static function GetInstance () {
        if (is_null(static::$instance)) {
            static::$instance = new static();
        }
        return static::$instance;
    }
    /**
     * Create new Auth service instance.
     * For each configuration item- check if it is class definition
     * and if it is, complete whole class definition.
     */
    public function __construct () {
        foreach ($this->config as $key => & $value) {
            if (strpos($key, 'Class') !== FALSE) {
                $value = __CLASS__ . $value;
            }
        }
        $this->config = (object) $this->config;
    }
    /**
     * Return configuration object.
     * @return \stdClass
     */
    public function & GetConfig () {
        return $this->config;
    }
    /**
     * Set up authorization service configuration.
     * Each array key must have key by default configuration item.
     * If configuration item is class, it's checked if it exists.
     * @param array $config 
     * @return \MvcCore\Ext\Auth
     */
    public function Configure ($config = array()) {
        foreach ($config as $key => $value) {
            if (isset($this->config->$key)) {
                if (strpos($key, 'Class') !== FALSE) {
                    $this->_checkClass($value);
                }
                $this->config->$key = $value;
            }
        }
        return $this;
    }
    /**
     * Set authorization expiration seconds, 10 minutes by default.
     * @param int $expirationSeconds 
     * @return \MvcCore\Ext\Auth
     */
    public function SetExpirationSeconds ($expirationSeconds = 600) {
        $this->config->expirationSeconds = $expirationSeconds;
        return $this;
    }
    /**
     * Set user's passwords hash salt, put here any string, every request the same.
     * @param string $passwordHashSalt 
     * @return \MvcCore\Ext\Auth
     */
    public function SetPasswordHashSalt ($passwordHashSalt = '') {
        $this->config->passwordHashSalt = $passwordHashSalt;
        return $this;
    }
    /**
     * Set authorization service user class
     * to get store username from session stored from previous 
     * requests for 10 minutes by default, by sign in action to compare
     * sender credentials with any user from your custom place
     * and by sign out action to remove username from session.
     * It has to extend \MvcCore\Ext\Auth\Virtual\User.
     * @param string $userClass 
     * @return \MvcCore\Ext\Auth
     */
    public function SetUserClass ($userClass = '') {
        $this->config->userClass = $this->_checkClass($userClass);
        return $this;
    }
    /**
     * Set authorization service controller class
     * to handle signin and signout actions,
     * it has to extend \MvcCore\Ext\Auth\Virtual\Controller.
     * @param string $controllerClass 
     * @return \MvcCore\Ext\Auth
     */
    public function SetControllerClass ($controllerClass = '') {
        $this->config->controllerClass = $this->_checkClass($controllerClass);
        return $this;
    }
    /**
     * Set authorization service sign in form class,
     * to create, render and submit sign in user.
     * it has to implement \MvcCore\Ext\Auth\Virtual\Form.
     * @param string $signInFormClass 
     * @return \MvcCore\Ext\Auth
     */
    public function SetSignInFormClass ($signInFormClass = '') {
        $this->config->signInFormClass = $this->_checkClass($signInFormClass);
        return $this;
    }
    /**
     * Set authorization service sign out form class,
     * to create, render and submit sign out user.
     * it has to implement \MvcCore\Ext\Auth\Virtual\Form.
     * @param string $signInFormClass
     * @return \MvcCore\Ext\Auth
     */
    public function SetSignOutFormClass ($signOutFormClass = '') {
        $this->config->signOutFormClass = $this->_checkClass($signOutFormClass);
        return $this;
    }
    /**
     * Set translator callable if you want to translate 
     * sign in and sign out forms labels, placeholders and error messages.
     * @param callable $translator 
     * @return \MvcCore\Ext\Auth
     */
    public function SetTranslator (callable $translator = NULL) {
        $this->config->translator = $translator;
        return $this;
    }
    /**
     * Set url to redirect user after sign in process was successfull.
     * By default signed in url is the same as current request url, 
     * internaly configured by default authentication service pre request handler.
     * @param string $signedInUrl 
     * @return \MvcCore\Ext\Auth
     */
    public function SetSignedInUrl ($signedInUrl ='') {
        $this->config->signedInUrl = $signedInUrl;
        return $this;
    }
    /**
     * Set url to redirect user after sign out process was successfull.
     * By default signed out url is the same as current request url,
     * internaly configured by default authentication service pre request handler.
     * @param string $signedOutUrl
     * @return \MvcCore\Ext\Auth
     */
    public function SetSignedOutUrl ($signedOutUrl ='') {
        $this->config->signedOutUrl = $signedOutUrl;
        return $this;
    }
    /**
     * Set url to redirect user after sign in or sign out process was 
     * not successfull. By default signed in/out error url is the same as 
     * current request url, internaly configured by default 
     * authentication service pre request handler.
     * @param string $errorUrl
     * @return \MvcCore\Ext\Auth
     */
    public function SetErrorUrl ($errorUrl ='') {
        $this->config->errorUrl = $errorUrl;
        return $this;
    }
    /**
     * Set sign in route, where to navigate user browser after
     * user clicks on submit button in sign in form and
     * where to run authentication process.
     * Route shoud be any pattern string without any groups, 
     * or route configuration array/stdClass or \MvcCore\Route
     * instance. Sign in route is prepended before all routes
     * in default service preroute handler.
     * @param string|array|\stdClass|\MvcCore\Route $signInRoute 
     * @return \MvcCore\Ext\Auth
     */
    public function SetSignInRoute ($signInRoute = NULL) {
        $this->config->signInRoute = $signInRoute;
        return $this;
    }
    /**
     * Set sign out route, where to navigate user browser after
     * user clicks on submit button in sign out form and
     * where to run deauthentication process.
     * Route shoud be any pattern string without any groups,
     * or route configuration array/stdClass or \MvcCore\Route
     * instance. Sign out route is prepended before all routes
     * in default service preroute handler.
     * @param string|array|\stdClass|\MvcCore\Route $signInRoute
     * @return \MvcCore\Ext\Auth
     */
    public function SetSignOutRoute ($signOutRoute = NULL) {
        $this->config->signOutRoute = $signOutRoute;
        return $this;
    }
    /**
     * Return TRUE if user is authenticated/signed in.
     * If user is not loaded yet, load the user internaly by $auth->GetUser();
     * to start session and try to load user by session username record.
     * @return bool
     */
    public function IsAuthenticated () {
        return !is_null($this->GetUser());
    }
    /**
     * Get authenticated user instance reference or null if user is not authenticated.
     * If user is not loaded yet, load the user internaly by $auth->GetUser();
     * to start session and try to load user by session username record.
     * @return \MvcCore\Ext\Auth\Virtual\User
     */
    public function & GetUser () {
        if (!$this->userInitialized && is_null($this->user)) {
            $userClass = $this->config->userClass;
            $this->user = $userClass::GetUserBySession();
            $this->userInitialized = TRUE;
        }
        return $this->user;
    }
    /**
     * Set user instance by you custom external authorization service.
     * If user instance is not null, set internal $auth->userInitialized property
     * to TRUE to not load user internaly again.
     * @param \MvcCore\Ext\Auth\Virtual\User $user 
     * @return \MvcCore\Ext\Auth
     */
    public function SetUser (\MvcCore\Ext\Auth\Virtual\User & $user) {
        $this->user = $user;
        if (!is_null($user)) $this->userInitialized = TRUE;
        return $this;
    }
    /**
     * Return completed signin/signout form instance.
     * Form instance completiion is processed only once,
     * created instance is stored in $auth->form property.
     * This method is always called by you, your application 
     * to set form into you custom template to render it for user.
     * If user is not authenticated, sign in form is returned and
     * if user is authenticated, opposite sign out form is returned.
     * @return \MvcCore\Ext\Auth\SignInForm|\MvcCore\Ext\Auth\SignOutForm|mixed
     */
    public function & GetForm () {
        if (is_null($this->form)) {
            $controller = \MvcCore::GetInstance()->GetController();
            if ($this->IsAuthenticated()) {
                $this->form = new \MvcCore\Ext\Auth\SignOutForm($controller);
                $this->form->Action = \MvcCore::GetInstance()->Url($this->config->signOutRoute->Name);
                $this->form->SuccessUrl = $this->config->signedOutUrl;
            } else {
                $this->form = new \MvcCore\Ext\Auth\SignInForm($controller);
                $this->form->Action = \MvcCore::GetInstance()->Url($this->config->signInRoute->Name);
                $this->form->SuccessUrl = $this->config->signedInUrl;
            }
            $this->form->ErrorUrl = $this->config->errorUrl;
            $this->form->SetTranslator($this->config->translator);
        }
        return $this->form;
    }
    /**
     * Set sign in/sign out form instance.
     * Use this method only if you need sometimes to 
     * complete different form to render.
     * @param \MvcCore\Ext\Auth\Virtual\Form $form 
     * @return \MvcCore\Ext\Auth
     */
    public function SetForm (& $form) {
        $this->form = $form;
        return $this;
    }
    /**
     * Initialize necessary authentication service handlers.
     * Call this method always in Bootstrap before request is routed by:
     * MvcCore\Ext\Auth::GetInstance()->Init();
     * @return \MvcCore\Ext\Auth
     */
    public function Init () {
        // add sing in or sing out forms routes, complete form success and error addresses
        \MvcCore::AddPreRouteHandler(function (\MvcCore\Request & $request) {
            $this->PrepareHandler($request);
        });
        return $this;
    }
    /**
     * Process necessary operations before request is routed.
     * This method is called internaly by default and it's called
     * by \MvcCore pre route handler initialized in $auth->Init(); method.
     * 
     * - Try to load user by stored session username from previous requests.
     * 
     * - If controller class begins with substring containing this 
     *   authentication class name, then it is obvious that controller 
     *   has to have in route definition full class name defined by slash
     *   character in class name begin - so correct this controller class
     *   name if necessary to set up routes properly immediately on lines bellow.
     * - If configured singin/out routes are still strings only, create
     *   from those strings new \MvcCore\Route instances into the same config
     *   place to add them into router immediately on lines bellow.
     *   
     * - Set up sign in form success url, sign out form success url and error 
     *   url for both ign in/out forms, as current request url by default.
     *   If any url is configured already, nothing is changed.
     *   
     * - Set up sign in or sign out route into router, only route which
     *   is currently by authenticated/not authenticated user necessary 
     *   to process in $router->Route() processing.
     * @return void
     */
    public function PrepareHandler () {
        $this->GetUser();
        $this->PrepareRoutes();
        $this->PrepareAdresses();
        $this->PrepareRouter();
    }
    /**
     * Second prepare handler internal method:
     * - If controller class begins with substring containing this
     *   authentication class name, then it is obvious that controller
     *   has to have in route definition full class name defined by slash
     *   character in class name begin - so correct this controller class
     *   name if necessary to set up routes properly immediately on lines bellow.
     * - If configured singin/out routes are still strings only, create
     *   from those strings new \MvcCore\Route instances into the same config
     *   place to add them into router immediately on lines bellow.
     * @return void
     */
    public function PrepareRoutes () {
        $authControllerClass = & $this->config->controllerClass;
        if (strpos($authControllerClass, __CLASS__) === 0) {
            $authControllerClass = '\\'.$authControllerClass;
        }
        $authenticated = $this->IsAuthenticated();
        if (!$authenticated && is_string($this->config->signInRoute)) {
            $this->config->signInRoute = \MvcCore\Route::GetInstance(array(
                'name'      => "$authControllerClass:SignIn",
                'pattern'   => $this->config->signInRoute,
            ));
        }
        if ($authenticated && is_string($this->config->signOutRoute)) {
            $this->config->signOutRoute = \MvcCore\Route::GetInstance(array(
                'name'      => "$authControllerClass:SignOut",
                'pattern'   => $this->config->signOutRoute,
            ));
        }
    }
    /**
     * Third prepare handler internal method:
     * - Set up sign in form success url, sign out form success url and error
     *   url for both ign in/out forms, as current request url by default.
     *   If any url is configured already, nothing is changed.
     * @return void
     */
    public function PrepareAdresses () {
        $request = & \MvcCore::GetInstance()->GetRequest();
        if (!$this->config->signedInUrl)    $this->config->signedInUrl = $request->FullUrl;
        if (!$this->config->signedOutUrl)   $this->config->signedOutUrl = $request->FullUrl;
        if (!$this->config->errorUrl)       $this->config->errorUrl = $request->FullUrl;
    }
    /**
     * Fourth prepare handler internal method:
     * - Set up sign in or sign out route into router, only route which
     *   is currently by authenticated/not authenticated user necessary
     *   to process in $router->Route() processing.
     * @return void
     */
    public function PrepareRouter () {
        if ($this->IsAuthenticated()) {
            \MvcCore\Router::GetInstance()->AddRoute(
                $this->config->signOutRoute, TRUE
            );
        } else {
            \MvcCore\Router::GetInstance()->AddRoute(
                $this->config->signInRoute, TRUE
            );
        }
    }
    /**
     * Check if configured class exists and thrown exception if not.
     * @param string $className 
     * @throws \Exception 
     * @return string
     */
    private function _checkClass (& $className) {
        if (!class_exists($className)) {
            throw new \Exception("[".__CLASS__."] Configured class: '$className' doesn't exists.'");
        }
        return $className;
    }
}
MvcCore API documentation generated by ApiGen