]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - modules/Users/authentication/AuthenticationController.php
Release 6.5.16
[Github/sugarcrm.git] / modules / Users / authentication / AuthenticationController.php
1 <?php
2 if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
3 /*********************************************************************************
4  * SugarCRM Community Edition is a customer relationship management program developed by
5  * SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc.
6  * 
7  * This program is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU Affero General Public License version 3 as published by the
9  * Free Software Foundation with the addition of the following permission added
10  * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
11  * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
12  * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
13  * 
14  * This program is distributed in the hope that it will be useful, but WITHOUT
15  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16  * FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
17  * details.
18  * 
19  * You should have received a copy of the GNU Affero General Public License along with
20  * this program; if not, see http://www.gnu.org/licenses or write to the Free
21  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22  * 02110-1301 USA.
23  * 
24  * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
25  * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
26  * 
27  * The interactive user interfaces in modified source and object code versions
28  * of this program must display Appropriate Legal Notices, as required under
29  * Section 5 of the GNU Affero General Public License version 3.
30  * 
31  * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
32  * these Appropriate Legal Notices must retain the display of the "Powered by
33  * SugarCRM" logo. If the display of the logo is not reasonably feasible for
34  * technical reasons, the Appropriate Legal Notices must display the words
35  * "Powered by SugarCRM".
36  ********************************************************************************/
37
38
39
40 class AuthenticationController
41 {
42         public $loggedIn = false; //if a user has attempted to login
43         public $authenticated = false;
44         public $loginSuccess = false;// if a user has successfully logged in
45
46         protected static $authcontrollerinstance = null;
47
48     /**
49      * @var SugarAuthenticate
50      */
51     public $authController;
52
53         /**
54          * Creates an instance of the authentication controller and loads it
55          *
56          * @param STRING $type - the authentication Controller
57          * @return AuthenticationController -
58          */
59         public function __construct($type = null)
60         {
61         $this->authController = $this->getAuthController($type);
62         }
63
64     /**
65      * Get auth controller object
66      * @param string $type 
67      * @return SugarAuthenticate
68      */
69     protected function getAuthController($type)
70     {
71         if (!$type) {
72             $type = !empty($GLOBALS['sugar_config']['authenticationClass'])
73                 ? $GLOBALS['sugar_config']['authenticationClass'] : 'SugarAuthenticate';
74         }
75
76         if ($type == 'SugarAuthenticate' && !empty($GLOBALS['system_config']->settings['system_ldap_enabled']) && empty($_SESSION['sugar_user'])) {
77             $type = 'LDAPAuthenticate';
78         }
79
80         // check in custom dir first, in case someone want's to override an auth controller
81                 if (file_exists('custom/modules/Users/authentication/'.$type.'/' . $type . '.php')) {
82             require_once('custom/modules/Users/authentication/'.$type.'/' . $type . '.php');
83         } elseif (file_exists('modules/Users/authentication/'.$type.'/' . $type . '.php')) {
84             require_once('modules/Users/authentication/'.$type.'/' . $type . '.php');
85         } else {
86             require_once('modules/Users/authentication/SugarAuthenticate/SugarAuthenticate.php');
87             $type = 'SugarAuthenticate';
88         }
89
90         if (!empty($_REQUEST['no_saml']) 
91             && (is_subclass_of($type, 'SAMLAuthenticate') || 'SAMLAuthenticate' == $type)) {
92             $type = 'SugarAuthenticate';
93         }
94
95         return new $type();
96     }
97
98         /**
99          * Returns an instance of the authentication controller
100          *
101          * @param string $type this is the type of authetnication you want to use default is SugarAuthenticate
102          * @return an instance of the authetnciation controller
103          */
104         public static function getInstance($type = null)
105         {
106                 if (empty(self::$authcontrollerinstance)) {
107                         self::$authcontrollerinstance = new AuthenticationController($type);
108                 }
109
110                 return self::$authcontrollerinstance;
111         }
112
113         /**
114          * This function is called when a user initially tries to login.
115          *
116          * @param string $username
117          * @param string $password
118          * @param array $PARAMS
119          * @return boolean true if the user successfully logs in or false otherwise.
120          */
121         public function login($username, $password, $PARAMS = array())
122         {
123                 //kbrill bug #13225
124                 $_SESSION['loginAttempts'] = (isset($_SESSION['loginAttempts']))? $_SESSION['loginAttempts'] + 1: 1;
125                 unset($GLOBALS['login_error']);
126
127                 if($this->loggedIn)return $this->loginSuccess;
128                 LogicHook::initialize()->call_custom_logic('Users', 'before_login');
129
130                 $this->loginSuccess = $this->authController->loginAuthenticate($username, $password, false, $PARAMS);
131                 $this->loggedIn = true;
132
133                 if($this->loginSuccess){
134                         //Ensure the user is authorized
135                         checkAuthUserStatus();
136
137                         loginLicense();
138                         if(!empty($GLOBALS['login_error'])){
139                                 unset($_SESSION['authenticated_user_id']);
140                                 $GLOBALS['log']->fatal('FAILED LOGIN: potential hack attempt:'.$GLOBALS['login_error']);
141                                 $this->loginSuccess = false;
142                                 return false;
143                         }
144
145                         //call business logic hook
146                         if(isset($GLOBALS['current_user']))
147                                 $GLOBALS['current_user']->call_custom_logic('after_login');
148
149                         // Check for running Admin Wizard
150                         $config = new Administration();
151                         $config->retrieveSettings();
152                     if ( is_admin($GLOBALS['current_user']) && empty($config->settings['system_adminwizard']) && $_REQUEST['action'] != 'AdminWizard' ) {
153                                 $GLOBALS['module'] = 'Configurator';
154                                 $GLOBALS['action'] = 'AdminWizard';
155                                 ob_clean();
156                                 header("Location: index.php?module=Configurator&action=AdminWizard");
157                                 sugar_cleanup(true);
158                         }
159
160                         $ut = $GLOBALS['current_user']->getPreference('ut');
161                         $checkTimeZone = true;
162                         if (is_array($PARAMS) && !empty($PARAMS) && isset($PARAMS['passwordEncrypted'])) {
163                                 $checkTimeZone = false;
164                         } // if
165                         if(empty($ut) && $checkTimeZone && $_REQUEST['action'] != 'SetTimezone' && $_REQUEST['action'] != 'SaveTimezone' ) {
166                                 $GLOBALS['module'] = 'Users';
167                                 $GLOBALS['action'] = 'Wizard';
168                                 ob_clean();
169                                 header("Location: index.php?module=Users&action=Wizard");
170                                 sugar_cleanup(true);
171                         }
172                 }else{
173                         //kbrill bug #13225
174                         LogicHook::initialize();
175                         $GLOBALS['logic_hook']->call_custom_logic('Users', 'login_failed');
176                         $GLOBALS['log']->fatal('FAILED LOGIN:attempts[' .$_SESSION['loginAttempts'] .'] - '. $username);
177                 }
178                 // if password has expired, set a session variable
179
180                 return $this->loginSuccess;
181         }
182
183         /**
184          * This is called on every page hit.
185          * It returns true if the current session is authenticated or false otherwise
186          *
187          * @return booelan
188          */
189         public function sessionAuthenticate()
190         {
191                 if(!$this->authenticated){
192                         $this->authenticated = $this->authController->sessionAuthenticate();
193                 }
194                 if($this->authenticated){
195                         if(!isset($_SESSION['userStats']['pages'])){
196                             $_SESSION['userStats']['loginTime'] = time();
197                             $_SESSION['userStats']['pages'] = 0;
198                         }
199                         $_SESSION['userStats']['lastTime'] = time();
200                         $_SESSION['userStats']['pages']++;
201
202                 }
203                 return $this->authenticated;
204         }
205
206         /**
207          * Called when a user requests to logout. Should invalidate the session and redirect
208          * to the login page.
209          */
210         public function logout()
211         {
212                 $GLOBALS['current_user']->call_custom_logic('before_logout');
213                 $this->authController->logout();
214                 LogicHook::initialize();
215                 $GLOBALS['logic_hook']->call_custom_logic('Users', 'after_logout');
216         }
217 }