| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286 |
- <?php
- if (!defined('USER_ROLE_KEY')) {
- define('USER_ROLE_KEY', 'Role');
- }
- if (!defined('CLASS_USER')) {
- define('CLASS_USER', 'User');
- }
- App::uses('AuthComponent', 'Controller/Component');
- /**
- * Important:
- * index the ACO on alias, index the Aro on model+id
- *
- * Extends AuthComponent with the following addons:
- * - allows multiple roles per user
- * - auto-raises login counter and sets last_login date
- * - preps the session data according to completeAuth() method (adds parent data etc)
- * - dynamic login scope validation
- *
- * @author Mark Scherer
- * @cakephp 2.x
- * @license MIT
- * 2011-12-18 ms
- */
- class AuthExtComponent extends AuthComponent {
- public $intermediateModel = 'RoleUser';
- public $roleModel = 'Role';
- public $fieldKey = 'role_id';
- public $loginAction = array('controller' => 'account', 'action' => 'login', 'admin' => false, 'plugin' => false);
- public $loginRedirect = array('controller' => 'overview', 'action' => 'home', 'admin' => false, 'plugin' => false);
- public $autoRedirect = false;
- public $loginError = null;
- public $settings = array(
- 'multi' => null, # null=auto - yes/no multiple roles (HABTM table between users and roles)
- 'parentModelAlias' => USER_ROLE_KEY,
- 'userModel' => CLASS_USER //TODO: allow plugin syntax
- );
- # field name in DB , if none is specified there will be no floodProtection
- public $floodProtection = null;
- /**
- * Merge in Configure::read('Auth') settings
- *
- * @param mixed $Collection
- * @param mixed $settings
- * @return void
- */
- public function __construct(ComponentCollection $Collection, $settings = array()) {
- $settings = array_merge($this->settings, (array)Configure::read('Auth'), (array)$settings);
- parent::__construct($Collection, $settings);
- }
- public function initialize(Controller $Controller) {
- $this->Controller = $Controller;
- parent::initialize($Controller);
- }
- /**
- * AuthExtComponent::login()
- *
- * @overwrite
- * @param mixed $user
- * @return boolean Success
- */
- public function login($user = null) {
- $Model = $this->getModel();
- $this->_setDefaults();
- if (empty($user)) {
- $user = $this->identify($this->Controller->request, $this->Controller->response);
- }
- $user = $this->completeAuth($user);
- if (empty($user)) {
- $this->loginError = __('invalidLoginCredentials');
- return false;
- }
- # custom checks
- if (isset($user['active'])) {
- if (empty($user['active'])) {
- $this->loginError = __('Account not active yet');
- return false;
- }
- if (!empty($user['suspended'])) {
- $this->loginError = __('Account wurde vorübergehend gesperrt');
- if (!empty($user['suspended_reason'])) {
- $this->loginError .= BR . BR . 'Grund:' . BR . nl2br(h($user['suspended_reason']));
- }
- return false;
- }
- } else {
- if (isset($user['status']) && empty($user['status'])) {
- $this->loginError = __('Account not active yet');
- return false;
- }
- if (isset($user['status']) && defined('User::STATUS_PENDING') && $user['status'] == User::STATUS_PENDING) {
- $this->loginError = __('Account wurde noch nicht freigeschalten');
- return false;
- }
- if (isset($user['status']) && defined('User::STATUS_SUSPENDED') && $user['status'] == User::STATUS_SUSPENDED) {
- $this->loginError = 'Account wurde vorübergehend gesperrt';
- if (!empty($user['suspended_reason'])) {
- $this->loginError .= BR . BR . 'Grund:' . BR . nl2br(h($user['suspended_reason']));
- }
- return false;
- }
- if (isset($user['status']) && defined('User::STATUS_DEL') && $user['status'] == User::STATUS_DEL) {
- $this->loginError = 'Account wurde gelöscht';
- if (!empty($user['suspended_reason'])) {
- $this->loginError .= BR . BR . 'Grund:' . BR . nl2br(h($user['suspended_reason']));
- }
- return false;
- }
- if (isset($user['status']) && defined('User::STATUS_ACTIVE') && $user['status'] != User::STATUS_ACTIVE) {
- $this->loginError = __('Unknown Error');
- return false;
- }
- }
- if (isset($user['email_confirmed']) && empty($user['email_confirmed'])) {
- $this->loginError = __('Email not active yet');
- return false;
- }
- if ($user) {
- # update login counter
- if (isset($user['logins'])) {
- $user['logins'] = $user['logins'] + 1;
- if (method_exists($Model, 'loginUpdate')) {
- $Model->loginUpdate($user);
- }
- }
- $this->Session->renew();
- $this->Session->write(self::$sessionKey, $user);
- }
- return $this->loggedIn();
- }
- /**
- * Gather session data.
- *
- * @return array User
- * 2011-11-03 ms
- */
- public function completeAuth($user) {
- $Model = $this->getModel();
- $userArray = $user;
- if (!is_array($userArray)) {
- $user = $Model->get($user);
- if (!$user) {
- return array();
- }
- $userArray = array_shift($user);
- }
- if (isset($Model->hasAndBelongsToMany[$this->roleModel]['className'])) {
- $with = $Model->hasAndBelongsToMany[$this->roleModel]['className'];
- } elseif (isset($Model->hasMany[$this->intermediateModel]['className'])) {
- $with = $Model->hasMany[$this->intermediateModel]['className'];
- } elseif (isset($Model->belongsTo[$this->roleModel]['className'])) {
- $with = $Model->belongsTo[$this->roleModel]['className'];
- }
- if (empty($with) && $this->settings['parentModelAlias'] !== false) {
- trigger_error('No relation from user to role found');
- return $user;
- }
- # roles
- if (!empty($with)) {
- list($plugin, $withModel) = pluginSplit($with);
- if (!isset($this->{$withModel})) {
- $this->{$withModel} = ClassRegistry::init($with);
- }
- # only for multi
- if ($this->settings['multi'] || !isset($userArray['role_id'])) {
- $parentModelAlias = $this->settings['parentModelAlias'];
- $userArray[$parentModelAlias] = array(); # default: no roles!
- $roles = $this->{$withModel}->find('list', array('fields' => array($withModel.'.role_id'), 'conditions' => array($withModel.'.user_id' => $user['id'])));
- if (!empty($roles)) {
- //$primaryRole = $this->user($this->fieldKey);
- // retrieve associated role that are not the primary one
- # MAYBE USEFUL FOR GUEST!!!
- //$roles = set::extract('/'.$with.'['.$this->fieldKey.'!='.$primaryRole.']/'.$this->fieldKey, $roles);
- // add the suplemental roles id under the Auth session key
- $userArray[$parentModelAlias] = $roles;
- //pr($completeAuth);
- }
- } else {
- //$userArray[$parentModelAlias][] = $userArray['role_id'];
- }
- }
- if (method_exists($Model, 'completeAuth')) {
- $userArray = $Model->completeAuth($userArray);
- }
- return $userArray;
- }
- /**
- * Main execution method. Handles redirecting of invalid users, and processing
- * of login form data.
- *
- * @overwrite
- * @param Controller $controller A reference to the instantiating controller object
- * @return boolean
- */
- public function startup(Controller $controller) {
- if ($controller->name === 'CakeError') {
- return true;
- }
- $methods = array_flip(array_map('strtolower', $controller->methods));
- # fix: reverse camelCase first
- $action = strtolower(Inflector::underscore($controller->request->params['action']));
- $isMissingAction = (
- $controller->scaffold === false &&
- !isset($methods[$action])
- );
- if ($isMissingAction) {
- return true;
- }
- if (!$this->_setDefaults()) {
- return false;
- }
- if ($this->_isAllowed($controller)) {
- return true;
- }
- if (!$this->_getUser()) {
- return $this->_unauthenticated($controller);
- }
- if (empty($this->authorize) || $this->isAuthorized($this->user())) {
- return true;
- }
- return $this->_unauthorized($controller);
- }
- /**
- * Returns the current User model
- *
- * @return object $User
- */
- public function getModel() {
- $model = $this->settings['userModel'];
- return ClassRegistry::init($model);
- }
- /**
- * @deprecated
- * @return boolean Success
- */
- public function verifyUser($id, $pwd) {
- trigger_error('deprecated - use Authenticate class');
- $options = array(
- 'conditions' => array('id' => $id, 'password' => $this->password($pwd)),
- );
- return $this->getModel()->find('first', $options);
- $this->constructAuthenticate();
- $this->request->data['User']['password'] = $pwd;
- return $this->identify($this->request, $this->response);
- }
- }
|