Project

General

Profile

wb-2_10_x / branches / main / framework / Login.php @ 10

1
<?php
2
/**
3
 *
4
 * @category        framework
5
 * @package         backend login
6
 * @author          Ryan Djurovich, WebsiteBaker Project
7
 * @copyright       WebsiteBaker Org. e.V.
8
 * @link            http://websitebaker.org/
9
 * @license         http://www.gnu.org/licenses/gpl.html
10
 * @platform        WebsiteBaker 2.8.3
11
 * @requirements    PHP 5.3.6 and higher
12
 * @version         $Id: Login.php 2 2017-07-02 15:14:29Z Manuela $
13
 * @filesource      $HeadURL: svn://isteam.dynxs.de/wb/2.10.x/branches/main/framework/Login.php $
14
 * @lastmodified    $Date: 2017-07-02 17:14:29 +0200 (Sun, 02 Jul 2017) $
15
 *
16
 */
17
/* -------------------------------------------------------- */
18
// Must include code to stop this file being accessed directly
19
if(!defined('WB_PATH')) {
20
    require_once(dirname(__FILE__).'/globalExceptionHandler.php');
21
    throw new IllegalFileException();
22
}
23
/* -------------------------------------------------------- */
24
define('LOGIN_CLASS_LOADED', true);
25

    
26
// Load the other required class files if they are not already loaded
27
require_once(WB_PATH."/framework/class.admin.php");
28
// Get WB version
29
require_once(ADMIN_PATH.'/interface/version.php');
30

    
31
class Login extends admin {
32

    
33
    const PASS_CHARS = '[\,w!#$%&*+\-.:=?@\|]';
34
    const USER_CHARS = '[a-z0-9&\-.=@_]';
35

    
36
    protected $aConfig = array();
37
    protected $oDb     = null;
38
    protected $oTrans  = null;
39

    
40
    public function __construct($config_array) {
41
        // Get language vars
42
/*        global $MESSAGE, $database; */
43
        $this->oDb    = $GLOBALS['database'];
44
        $this->oTrans = $GLOBALS['MESSAGE'];
45
        parent::__construct();
46
    // Get configuration values
47
        while(list($key, $value) = each($config_array)) {
48
//            $this->{(strtolower($key))} = $value;
49
            $this->aConfig[strtolower($key)] = $value;
50
        }
51
        if (!isset($this->frontend)) { $this->frontend = false; }
52
        if (!isset($this->redirect_url)) { $this->redirect_url = ''; }
53

    
54
    // calculate redirect URL
55
    // begin new routine
56
        $sProtokol = ((!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] == 'off' ) ? 'http' : 'https') . '://';;
57
        $sInstallFolderRel = dirname(dirname($_SERVER['SCRIPT_NAME']));
58
        $sServerUrl = $sProtokol.$_SERVER['HTTP_HOST'].($_SERVER['SERVER_PORT'] == 80 ? '' : $_SERVER['SERVER_PORT'].':').'/'.$sInstallFolderRel;
59
    // end new routine
60
/*
61
        $aRedirecthUrl = null;
62
        $sServerUrl = $_SERVER['SERVER_NAME'];
63
        $aServerUrl = $this->mb_parse_url(WB_URL);
64
        $sServerScheme = isset($_SERVER['REQUEST_SCHEME']) ? $_SERVER['REQUEST_SCHEME'] : isset($aServerUrl['scheme']) ? $aServerUrl['scheme'] : ' http';
65
        $sServerPath = $_SERVER['SCRIPT_NAME'];
66
*/
67

    
68
        // If the url is blank, set it to the default url
69
        $this->url = @$this->get_post('url')?:@$this->get_post('redirect')?:$this->default_url;
70
/*
71
        if ( !$this->frontend ){ $this->redirect_url = ( @$this->url ? : '' );}
72
        if ( $this->frontend ){ $this->url = ( @$this->redirect_url ? : null );}
73
*/
74
        if (preg_match('/%0d|%0a|\s/i', $this->url)) {
75
            throw new Exception('Warning: possible intruder detected on login');
76
        }
77
/*
78
        $aUrl = $this->mb_parse_url( $this->url );
79
        if ($this->redirect_url!='') {
80
            $aRedirecthUrl = $this->mb_parse_url( $this->redirect_url );
81
            $this->redirect_url = isset($aRedirecthUrl['host']) &&($sServerUrl==$aRedirecthUrl['host']) ? $this->redirect_url:$sServerScheme.'://'.$sServerUrl;
82
            $this->url = $this->redirect_url;
83
        }
84
        $this->url = isset($aRedirecthUrl['host']) &&($sServerUrl==$aUrl['host']) ? $this->url:ADMIN_URL.'/start/index.php';
85
        if(strlen($this->url) < 2) {
86
            $aDefaultUrl = $this->mb_parse_url( $this->default_url );
87
            $this->default_url = isset($aDefaultUrl['host']) &&($sServerUrl==$aDefaultUrl['host']) ? $this->default_url:$sServerScheme.'://'.$sServerUrl;
88
            $this->url = $this->default_url;
89
        }
90
*/
91
    // get username & password and validate it
92
        $username_fieldname = (string)$this->get_post('username_fieldname');
93
        $username_fieldname = (preg_match('/^_?[a-z][\w]+$/i', $username_fieldname) ? $username_fieldname : 'username');
94
        $sUsername = strtolower(trim((string)$this->get_post($username_fieldname)));
95
        $this->username = (preg_match(
96
            '/^'.self::USER_CHARS.'{'.$this->min_username_len.','.$this->max_username_len.'}$/is',
97
            $sUsername
98
        ) ? $sUsername : '');
99
        $password_fieldname = (string)$this->get_post('password_fieldname');
100
        $password_fieldname = (preg_match('/^_?[a-z][\w]+$/i', $password_fieldname) ? $password_fieldname : 'password');
101

    
102
        if ($this->username) {
103
/** @TODO implement crypting */
104
            $this->password = md5(trim((string)$this->get_post($password_fieldname)));
105
            // Figure out if the "remember me" option has been checked
106
            $this->remember = (@$_POST['remember'] == 'true' ? true : false);
107
        // try to authenticate
108
            $bSuccess = false;
109
            if (!($bSuccess = $this->is_authenticated())) {
110
                if ($this->is_remembered()) {
111
                    $sql = 'SELECT * FROM `'.TABLE_PREFIX.'users` '
112
                         . 'WHERE `user_id`='.$this->get_safe_remember_key();
113
                    if (($oUsers = $this->oDb->query($sql))) {
114
                        if (($aUser = $oUsers->fetchRow(MYSQLI_ASSOC))) {
115
                            $this->username = $aUser['username'];
116
                            $this->password = $aUser['password'];
117
                            // Check if the user exists (authenticate them)
118
                            $bSuccess = $this->authenticate();
119
                        }
120
                    }
121
                } else {
122
                    // Check if the user exists (authenticate them)
123
                    $bSuccess = $this->authenticate();
124
                }
125
            }
126
            if ($bSuccess) {
127
                // Authentication successful
128
                $this->send_header($this->url);
129
            } else {
130
                $this->message = $this->_oTrans->MESSAGE_LOGIN_AUTHENTICATION_FAILED;
131
                $this->increase_attemps();
132
            }
133
        } else {
134
            $this->message = $this->_oTrans->MESSAGE_LOGIN_BOTH_BLANK;
135
            $this->display_login();
136
        }
137
    }
138

    
139
    public function __isset($name)
140
    {
141
        return isset($this->aConfig[$name]);
142
    }
143

    
144
    public function __set($name, $value)
145
    {
146
         return $this->aConfig[$name] = $value;
147
    }
148

    
149
   public function __get ($name){
150
        $retval = null;
151
        if ($this->__isset($name)) {
152
            $retval = $this->aConfig[$name];
153
        }
154
        return $retval;
155
    }
156

    
157
    // Authenticate the user (check if they exist in the database)
158
    public function authenticate()
159
    {
160
        // Get user information
161
        $loginname = ( preg_match('/^'.self::USER_CHARS.'+$/s',$this->username) ? $this->username : '0');
162
        $aSettings = array();
163
        $aSettings['SYSTEM_PERMISSIONS']   = array();
164
        $aSettings['MODULE_PERMISSIONS']   = array();
165
        $aSettings['TEMPLATE_PERMISSIONS'] = array();
166
        $bRetval = false;
167

    
168
        $sql = 'SELECT * FROM `'.TABLE_PREFIX.'users` '
169
             . 'WHERE `username`=\''.$this->oDb->escapeString($loginname).'\'';
170
        if (($oUser = $this->oDb->query($sql))) {
171
            if (($aUser = $oUser->fetchRow(MYSQLI_ASSOC))) {
172
                if (
173
                    $aUser['password'] == $this->password &&
174
                    $aUser['active'] == 1
175
                ) {
176
                // valide authentcation !!
177
                    $user_id                   = $aUser['user_id'];
178
                    $this->user_id             = $user_id;
179
                    $aSettings['USER_ID']      = $user_id;
180
                    $aSettings['GROUP_ID']     = $aUser['group_id'];
181
                    $aSettings['GROUPS_ID']    = $aUser['groups_id'];
182
                    $aSettings['USERNAME']     = $aUser['username'];
183
                    $aSettings['DISPLAY_NAME'] = $aUser['display_name'];
184
                    $aSettings['EMAIL']        = $aUser['email'];
185
                    $aSettings['HOME_FOLDER']  = $aUser['home_folder'];
186
                    // Run remember function if needed
187
                    if($this->remember == true) { $this->remember($this->user_id); }
188
                    // Set language
189
                    if($aUser['language'] != '') {
190
                        $aSettings['LANGUAGE'] = $aUser['language'];
191
                    }
192
                    // Set timezone
193
                    if($aUser['timezone'] != '-72000') {
194
                        $aSettings['TIMEZONE'] = $aUser['timezone'];
195
                    } else {
196
                        // Set a session var so apps can tell user is using default tz
197
                        $aSettings['USE_DEFAULT_TIMEZONE'] = true;
198
                    }
199
                    // Set date format
200
                    if($aUser['date_format'] != '') {
201
                        $aSettings['DATE_FORMAT'] = $aUser['date_format'];
202
                    } else {
203
                        // Set a session var so apps can tell user is using default date format
204
                        $aSettings['USE_DEFAULT_DATE_FORMAT'] = true;
205
                    }
206
                    // Set time format
207
                    if($aUser['time_format'] != '') {
208
                        $aSettings['TIME_FORMAT'] = $aUser['time_format'];
209
                    } else {
210
                        // Set a session var so apps can tell user is using default time format
211
                        $aSettings['USE_DEFAULT_TIME_FORMAT'] = true;
212
                    }
213
                    // Get group information
214
                    $aSettings['GROUP_NAME'] = array();
215
                    $bOnlyAdminGroup = $this->ami_group_member('1') && (sizeof($aGroupsIds) == 1);
216
                    $sql = 'SELECT * FROM `'.TABLE_PREFIX.'groups` '
217
                         . 'WHERE `group_id` IN ('.$aUser['groups_id'].',0) '
218
                         . 'ORDER BY `group_id`';
219

    
220
                    if (($oGroups = $this->oDb->query($sql))) {
221
                        while (($aGroup = $oGroups->fetchRow( MYSQLI_ASSOC ))) {
222
                            $aSettings['GROUP_NAME'][$aGroup['group_id']] = $aGroup['name'];
223
                        // collect system_permissions (additively)
224
                            $aSettings['SYSTEM_PERMISSIONS'] = array_merge(
225
                                $aSettings['SYSTEM_PERMISSIONS'],
226
                                explode(',', $aGroup['system_permissions'])
227
                            );
228
                        // collect module_permission (subtractive)
229
                            if (!sizeof($aSettings['MODULE_PERMISSIONS'])) {
230
                                $aSettings['MODULE_PERMISSIONS'] = explode(',', $aGroup['module_permissions']);
231
                            } else {
232
                                $aSettings['MODULE_PERMISSIONS'] = array_intersect(
233
                                    $aSettings['MODULE_PERMISSIONS'],
234
                                    preg_split('/\s*[,;\|\+]/', $aGroup['module_permissions'], -1, PREG_SPLIT_NO_EMPTY)
235
                                );
236
                            }
237
                        // collect template_permission (subtractive)
238
                            if (!sizeof($aSettings['TEMPLATE_PERMISSIONS'])) {
239
                                $aSettings['TEMPLATE_PERMISSIONS'] = explode(',', $aGroup['template_permissions']);
240
                            } else {
241
                                $aSettings['TEMPLATE_PERMISSIONS'] = array_intersect(
242
                                    $aSettings['TEMPLATE_PERMISSIONS'],
243
                                    preg_split('/\s*[,;\|\+]/', $aGroup['template_permissions'], -1, PREG_SPLIT_NO_EMPTY)
244
                                );
245
                            }
246
                        }
247
                    }
248
                    // Update the users table with current ip and timestamp
249
                    $sRemoteAddress = @$_SERVER['REMOTE_ADDR'] ?: 'unknown';
250
                    $sql = 'UPDATE `'.TABLE_PREFIX.'users` '
251
                         . 'SET `login_when`='.time().', '
252
                         .     '`login_ip`=\''.$sRemoteAddress.'\' '
253
                         . 'WHERE `user_id`=\''.$user_id.'\'';
254
                    $this->oDb->query($sql);
255
                    $bRetval = true;
256
                }
257
            }
258
        }
259
        // merge settings into $_SESSION and overwrite older one values
260
        $_SESSION = array_merge($_SESSION, $aSettings);
261
        // Return if the user exists or not
262
        return $bRetval;
263
    }
264

    
265
    // Increase the count for login attemps
266
    protected function increase_attemps()
267
    {
268
        $_SESSION['ATTEMPS'] = (isset($_SESSION['ATTEMPS']) ? $_SESSION['ATTEMPS']++ : 0);
269
        $this->display_login();
270
    }
271

    
272

    
273
    public function getMessage ( ) {
274
      return $this->message;
275
    }
276

    
277
    // Function to set a "remembering" cookie for the user - removed
278
   protected function remember($user_id)
279
    {
280
        return true;
281
    }
282

    
283
    // Function to check if a user has been remembered - removed
284
    protected function is_remembered()
285
    {
286
        return false;
287
    }
288

    
289
    // Display the login screen
290
    protected function display_login() {
291
        // Get language vars
292
        global $MESSAGE;
293
        global $MENU;
294
        global $TEXT;
295

    
296
        $Trans = $GLOBALS['oTrans'];
297
        $ThemeName = (defined('DEFAULT_THEME')?DEFAULT_THEME:'DefaultTheme');
298
        $Trans->enableAddon('templates\\'.$ThemeName);
299
        $aLang = $Trans->getLangArray();
300
        // If attemps more than allowed, warn the user
301
        if($this->get_session('ATTEMPS') > $this->max_attemps) {
302
            $this->warn();
303
        }
304
        // Show the login form
305
        if($this->frontend != true) {
306
//            require_once(WB_PATH.'/include/phplib/template.inc');
307
            $aWebsiteTitle['value'] = WEBSITE_TITLE;
308
            $sql = 'SELECT `value` FROM `'.TABLE_PREFIX.'settings` '
309
                 . 'WHERE `name`=\'website_title\'';
310
            if ($get_title = $this->oDb->query($sql)){
311
                $aWebsiteTitle= $get_title->fetchRow( MYSQLI_ASSOC );
312
            }
313
            // Setup template object, parse vars to it, then parse it
314
            $template = new Template(dirname($this->correct_theme_source($this->template_file)));
315
            $template->set_file('page', $this->template_file);
316
            $template->set_block('page', 'mainBlock', 'main');
317
            $template->set_var('DISPLAY_REMEMBER_ME', ($this->remember_me_option ? '' : 'display: none;'));
318

    
319
            $template->set_var(
320
                array(
321
                    'ACTION_URL' => $this->login_url,
322
                    'ATTEMPS' => $this->get_session('ATTEMPS'),
323
                    'USERNAME' => $this->username,
324
                    'USERNAME_FIELDNAME' => $this->username_fieldname,
325
                    'PASSWORD_FIELDNAME' => $this->password_fieldname,
326
                    'MESSAGE' => $this->message,
327
                    'INTERFACE_DIR_URL' =>  ADMIN_URL.'/interface',
328
                    'MAX_USERNAME_LEN' => $this->max_username_len,
329
                    'MAX_PASSWORD_LEN' => $this->max_password_len,
330
                    'ADMIN_URL' => ADMIN_URL,
331
                    'WB_URL' => WB_URL,
332
                    'URL' => $this->redirect_url,
333
                    'THEME_URL' => THEME_URL,
334
                    'VERSION' => VERSION,
335
                    'REVISION' => REVISION,
336
                    'LANGUAGE' => strtolower(LANGUAGE),
337
                    'FORGOTTEN_DETAILS_APP' => $this->forgotten_details_app,
338
                    'WEBSITE_TITLE'       => ($aWebsiteTitle['value']),
339
                    'TEXT_ADMINISTRATION' => $TEXT['ADMINISTRATION'],
340
//                    'TEXT_FORGOTTEN_DETAILS' => $Trans->TEXT_FORGOTTEN_DETAILS,
341
                    'TEXT_USERNAME' => $TEXT['USERNAME'],
342
                    'TEXT_PASSWORD' => $TEXT['PASSWORD'],
343
                    'TEXT_REMEMBER_ME' => $TEXT['REMEMBER_ME'],
344
                    'TEXT_LOGIN' => $TEXT['LOGIN'],
345
                    'TEXT_SAVE' => $TEXT['SAVE'],
346
                    'TEXT_RESET' => $TEXT['RESET'],
347
                    'TEXT_HOME' => $TEXT['HOME'],
348
                    'PAGES_DIRECTORY' => PAGES_DIRECTORY,
349
                    'SECTION_LOGIN' => $MENU['LOGIN'],
350
                    'LOGIN_DISPLAY_HIDDEN'   => !$this->is_authenticated() ? 'hidden' : '',
351
                    'LOGIN_DISPLAY_NONE'     => !$this->is_authenticated() ? 'none' : '',
352
                    'LOGIN_LINK'             => $_SERVER['SCRIPT_NAME'],
353
                    'LOGIN_ICON'             => 'login',
354
                    'START_ICON'             => 'blank',
355
                    'URL_HELP'               => 'http://wiki.websitebaker.org/',
356
                    )
357
            );
358
            $template->set_var($aLang);
359
            $template->set_var('CHARSET', (defined('DEFAULT_CHARSET') ? DEFAULT_CHARSET : 'utf-8'));
360
            $template->parse('main', 'mainBlock', false);
361
            $template->pparse('output', 'page');
362
        }
363
    }
364

    
365
    // sanities the REMEMBER_KEY cookie to avoid SQL injection
366
    protected function get_safe_remember_key()
367
    {
368
        $iMatches = 0;
369
        if (isset($_COOKIE['REMEMBER_KEY'])) {
370
            $sRetval = preg_replace('/^([0-9]{11})_([0-9a-f]{11})$/i', '\1\2', $_COOKIE['REMEMBER_KEY'], -1, $iMatches);
371
        }
372
        return ($iMatches ? $sRetval : '');
373
    }
374

    
375
    // Warn user that they have had to many login attemps
376
    protected function warn()
377
    {
378
//      header('Location: '.$this->warning_url);
379
        $this->send_header($this->warning_url);
380
        exit;
381
    }
382

    
383
}