GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Pull Request — develop (#155)
by
unknown
08:46
created
myth/Api/Auth/APIAuthentication.php 2 patches
Indentation   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -74,7 +74,7 @@  discard block
 block discarded – undo
74 74
 	 */
75 75
 	public function setRealm($realm)
76 76
 	{
77
-	    $this->realm = $realm;
77
+		$this->realm = $realm;
78 78
 		return $this;
79 79
 	}
80 80
 
@@ -116,7 +116,7 @@  discard block
 block discarded – undo
116 116
 			'password'  => $password
117 117
 		];
118 118
 
119
-	    $user = $this->validate($data, true);
119
+		$user = $this->validate($data, true);
120 120
 
121 121
 		$this->user = $user;
122 122
 
@@ -272,7 +272,7 @@  discard block
 block discarded – undo
272 272
 	 */
273 273
 	public function checkIPBlacklist()
274 274
 	{
275
-	    $blacklist = explode(',', config_item('api.ip_blacklist'));
275
+		$blacklist = explode(',', config_item('api.ip_blacklist'));
276 276
 
277 277
 		array_walk($blacklist, function (&$item, $key) {
278 278
 			$item = trim($item);
Please login to merge, or discard this patch.
Spacing   +22 added lines, -22 removed lines patch added patch discarded remove patch
@@ -46,7 +46,7 @@  discard block
 block discarded – undo
46 46
 
47 47
 	//--------------------------------------------------------------------
48 48
 
49
-	public function __construct($ci=null)
49
+	public function __construct($ci = null)
50 50
 	{
51 51
 		parent::__construct($ci);
52 52
 
@@ -112,7 +112,7 @@  discard block
 block discarded – undo
112 112
 		// so request authorization by the client.
113 113
 		if (empty($username) || empty($password))
114 114
 		{
115
-			$this->ci->output->set_header('WWW-Authenticate: Basic realm="'. config_item('api.realm') .'"');
115
+			$this->ci->output->set_header('WWW-Authenticate: Basic realm="'.config_item('api.realm').'"');
116 116
 			return false;
117 117
 		}
118 118
 
@@ -162,7 +162,7 @@  discard block
 block discarded – undo
162 162
 		// No digest string? Then you're done. Go home.
163 163
 		if (empty($digest_string))
164 164
 		{
165
-			$this->ci->output->set_header( sprintf('WWW-Authenticate: Digest realm="%s", nonce="%s", opaque="%s"', config_item('api.realm'), $nonce, $opaque) );
165
+			$this->ci->output->set_header(sprintf('WWW-Authenticate: Digest realm="%s", nonce="%s", opaque="%s"', config_item('api.realm'), $nonce, $opaque));
166 166
 			return false;
167 167
 		}
168 168
 
@@ -172,30 +172,30 @@  discard block
 block discarded – undo
172 172
 		preg_match_all('@(username|nonce|uri|nc|cnonce|qop|response)=[\'"]?([^\'",]+)@', $digest_string, $matches);
173 173
 		$digest = (empty($matches[1]) || empty($matches[2])) ? array() : array_combine($matches[1], $matches[2]);
174 174
 
175
-		if (! array_key_exists('username', $digest))
175
+		if ( ! array_key_exists('username', $digest))
176 176
 		{
177
-			$this->ci->output->set_header( sprintf('WWW-Authenticate: Digest realm="%s", nonce="%s", opaque="%s"', config_item('api.realm'), $nonce, $opaque) );
177
+			$this->ci->output->set_header(sprintf('WWW-Authenticate: Digest realm="%s", nonce="%s", opaque="%s"', config_item('api.realm'), $nonce, $opaque));
178 178
 			return false;
179 179
 		}
180 180
 
181 181
 		// Grab the user that corresponds to that "username"
182 182
 		// exact field determined in the api config file - api.auth_field setting.
183
-		$user = $this->user_model->as_array()->find_by( config_item('api.auth_field'), $digest['username'] );
183
+		$user = $this->user_model->as_array()->find_by(config_item('api.auth_field'), $digest['username']);
184 184
 
185 185
 		// If the user is throttled due to too many invalid logins
186 186
 		// or the system is under attack, kick them back.
187 187
 
188 188
 		// If throttling time is above zero, we can't allow
189 189
 		// logins now.
190
-		if ($time = (int)$this->isThrottled($user) > 0)
190
+		if ($time = (int) $this->isThrottled($user) > 0)
191 191
 		{
192 192
 			$this->error = sprintf(lang('api.throttled'), $time);
193 193
 			return false;
194 194
 		}
195 195
 
196
-		if (!  $user)
196
+		if ( ! $user)
197 197
 		{
198
-			$this->ci->output->set_header( sprintf('WWW-Authenticate: Digest realm="%s", nonce="%s", opaque="%s"', config_item('api.realm'), $nonce, $opaque) );          
198
+			$this->ci->output->set_header(sprintf('WWW-Authenticate: Digest realm="%s", nonce="%s", opaque="%s"', config_item('api.realm'), $nonce, $opaque));          
199 199
 			$this->ci->login_model->recordLoginAttempt($this->ci->input->ip_address());
200 200
 			return false;
201 201
 		}
@@ -205,16 +205,16 @@  discard block
 block discarded – undo
205 205
 
206 206
 		if ($digest['qop'] == 'auth')
207 207
 		{
208
-			$A2 = md5( strtoupper( $_SERVER['REQUEST_METHOD'] ) .':'. $digest['uri'] );
208
+			$A2 = md5(strtoupper($_SERVER['REQUEST_METHOD']).':'.$digest['uri']);
209 209
 		} else {
210 210
 			$body = file_get_contents('php://input');
211
-			$A2 = md5( strtoupper( $_SERVER['REQUEST_METHOD'] ) .':'. $digest['uri'] .':'. md5($body) );
211
+			$A2 = md5(strtoupper($_SERVER['REQUEST_METHOD']).':'.$digest['uri'].':'.md5($body));
212 212
 		}
213
-		$valid_response = md5($A1 .':'. $digest['nonce'].':'. $digest['nc'] .':'. $digest['cnonce'] .':'. $digest['qop'] .':'. $A2);
213
+		$valid_response = md5($A1.':'.$digest['nonce'].':'.$digest['nc'].':'.$digest['cnonce'].':'.$digest['qop'].':'.$A2);
214 214
 
215 215
 		if ($digest['response'] != $valid_response)
216 216
 		{
217
-			$this->ci->output->set_header( sprintf('WWW-Authenticate: Digest realm="%s", nonce="%s", opaque="%s"', config_item('api.realm'), $nonce, $opaque) );
217
+			$this->ci->output->set_header(sprintf('WWW-Authenticate: Digest realm="%s", nonce="%s", opaque="%s"', config_item('api.realm'), $nonce, $opaque));
218 218
 			$this->ci->login_model->recordLoginAttempt($this->ci->input->ip_address(), $user['id']);
219 219
 			return false;
220 220
 		}
@@ -252,7 +252,7 @@  discard block
 block discarded – undo
252 252
 				break;
253 253
 		}
254 254
 
255
-		if (! $user)
255
+		if ( ! $user)
256 256
 		{
257 257
 			$this->user = null;
258 258
 			return $user;
@@ -280,13 +280,13 @@  discard block
 block discarded – undo
280 280
 	{
281 281
 	    $blacklist = explode(',', config_item('api.ip_blacklist'));
282 282
 
283
-		array_walk($blacklist, function (&$item, $key) {
283
+		array_walk($blacklist, function(&$item, $key) {
284 284
 			$item = trim($item);
285 285
 		});
286 286
 
287 287
 		if (in_array($this->ci->input->ip_address(), $blacklist))
288 288
 		{
289
-			throw new \Exception( lang('api.ip_denied'), 401);
289
+			throw new \Exception(lang('api.ip_denied'), 401);
290 290
 		}
291 291
 
292 292
 		return true;
@@ -305,13 +305,13 @@  discard block
 block discarded – undo
305 305
 
306 306
 		array_push($whitelist, '127.0.0.1', '0.0.0.0');
307 307
 
308
-		array_walk($whitelist, function (&$item, $key) {
308
+		array_walk($whitelist, function(&$item, $key) {
309 309
 			$item = trim($item);
310 310
 		});
311 311
 
312
-		if (! in_array($this->ci->input->ip_address(), $whitelist))
312
+		if ( ! in_array($this->ci->input->ip_address(), $whitelist))
313 313
 		{
314
-			throw new \Exception( lang('api.ip_denied'), 401);
314
+			throw new \Exception(lang('api.ip_denied'), 401);
315 315
 		}
316 316
 
317 317
 		return true;
@@ -368,9 +368,9 @@  discard block
 block discarded – undo
368 368
 	 *
369 369
 	 * @return bool|mixed|void
370 370
 	 */
371
-	public function login($credentials, $remember=false)
371
+	public function login($credentials, $remember = false)
372 372
 	{
373
-		throw new \BadMethodCallException( lang('api.unused_method') );
373
+		throw new \BadMethodCallException(lang('api.unused_method'));
374 374
 	}
375 375
 
376 376
 	//--------------------------------------------------------------------
@@ -385,7 +385,7 @@  discard block
 block discarded – undo
385 385
 	 */
386 386
 	public function logout()
387 387
 	{
388
-		throw new \BadMethodCallException( lang('api.unused_method') );
388
+		throw new \BadMethodCallException(lang('api.unused_method'));
389 389
 	}
390 390
 
391 391
 	//--------------------------------------------------------------------
Please login to merge, or discard this patch.
myth/Auth/LocalAuthentication.php 2 patches
Indentation   +908 added lines, -908 removed lines patch added patch discarded remove patch
@@ -52,915 +52,915 @@
 block discarded – undo
52 52
  */
53 53
 class LocalAuthentication implements AuthenticateInterface {
54 54
 
55
-    protected $ci;
56
-
57
-    protected $user = null;
58
-
59
-    public $user_model = null;
60
-
61
-    public $error = null;
62
-
63
-    //--------------------------------------------------------------------
64
-
65
-    public function __construct( $ci=null )
66
-    {
67
-        if ($ci)
68
-        {
69
-            $this->ci= $ci;
70
-        }
71
-        else
72
-        {
73
-            $this->ci =& get_instance();
74
-        }
75
-
76
-        // Get our compatibility password file loaded up.
77
-        if (! function_exists('password_hash'))
78
-        {
79
-            require_once dirname(__FILE__) .'password.php';
80
-        }
81
-
82
-        if (empty($this->ci->session))
83
-        {
84
-            $this->ci->load->library('session');
85
-        }
86
-
87
-        $this->ci->config->load('auth');
88
-        $this->ci->load->model('auth/login_model');
89
-        $this->ci->load->language('auth/auth');
90
-    }
91
-
92
-    //--------------------------------------------------------------------
93
-
94
-    /**
95
-     * Attempt to log a user into the system.
96
-     *
97
-     * $credentials is an array of key/value pairs needed to log the user in.
98
-     * This is often email/password, or username/password.
99
-     *
100
-     * @param array $credentials
101
-     * @param bool  $remember
102
-     * @return bool|mixed
103
-     */
104
-    public function login($credentials, $remember=false)
105
-    {
106
-        $user = $this->validate($credentials, true);
107
-
108
-        if (! $user)
109
-        {
110
-            $this->user = null;
111
-            return $user;
112
-        }       
113
-
114
-        $this->loginUser($user);
115
-
116
-        if ($remember)
117
-        {
118
-            $this->rememberUser($user);
119
-        }
120
-
121
-        Events::trigger('didLogin', [$user]);
122
-
123
-        return true;
124
-    }
125
-
126
-    //--------------------------------------------------------------------
127
-
128
-    /**
129
-     * Validates user login information without logging them in.
130
-     *
131
-     * $credentials is an array of key/value pairs needed to log the user in.
132
-     * This is often email/password, or username/password.
133
-     *
134
-     * @param $credentials
135
-     * @param bool $return_user
136
-     * @return mixed
137
-     */
138
-    public function validate($credentials, $return_user=false)
139
-    {
140
-        // Can't validate without a password.
141
-        if (empty($credentials['password']) || count($credentials) < 2)
142
-        {
143
-            return null;
144
-        }
145
-
146
-        $password = $credentials['password'];
147
-        unset($credentials['password']);
148
-
149
-        // We should only be allowed 1 single other credential to
150
-        // test against.
151
-        if (count($credentials) > 1)
152
-        {
153
-            $this->error = lang('auth.too_many_credentials');
154
-            return false;
155
-        }
156
-
157
-        // Ensure that the fields are allowed validation fields
158
-        if (! in_array(key($credentials), config_item('auth.valid_fields')) )
159
-        {
160
-            $this->error = lang('auth.invalid_credentials');
161
-            return false;
162
-        }
163
-
164
-        // We do not want to force case-sensitivity on things
165
-        // like username and email for usability sake.
166
-        if (! empty($credentials['email']))
167
-        {
168
-            $credentials['email'] = strtolower($credentials['email']);
169
-        }
170
-
171
-        // Can we find a user with those credentials?
172
-        $user = $this->user_model->as_array()
173
-                                 ->where($credentials)
174
-                                 ->first();
175
-
176
-        // If the user is throttled due to too many invalid logins
177
-        // or the system is under attack, kick them back.
178
-
179
-        // If throttling time is above zero, we can't allow
180
-        // logins now.
181
-        $time = (int)$this->isThrottled($user);
182
-        if ($time > 0)
183
-        {
184
-            $this->error = sprintf(lang('auth.throttled'), $time);
185
-            return false;
186
-        }
187
-
188
-        // Get ip address
189
-        $ip_address = $this->ci->input->ip_address();
190
-
191
-        if (! $user)
192
-        {
193
-            $this->error = lang('auth.invalid_user');
194
-            $this->ci->login_model->recordLoginAttempt($ip_address);
195
-            return false;
196
-        }
197
-
198
-        // Now, try matching the passwords.
199
-        $result =  password_verify($password, $user['password_hash']);
200
-
201
-        if (! $result)
202
-        {
203
-            $this->error = lang('auth.invalid_password');
204
-            $this->ci->login_model->recordLoginAttempt($ip_address, $user['id']);
205
-            return false;
206
-        }
207
-
208
-        // Check to see if the password needs to be rehashed.
209
-        // This would be due to the hash algorithm or hash
210
-        // cost changing since the last time that a user
211
-        // logged in.
212
-        if (password_needs_rehash($user['password_hash'], PASSWORD_DEFAULT, ['cost' => config_item('auth.hash_cost')] ))
213
-        {
214
-            $new_hash = Password::hashPassword($password);
215
-            $this->user_model->skip_validation()
216
-                             ->update($user['id'], ['password_hash' => $new_hash]);
217
-            unset($new_hash);
218
-        }
219
-
220
-        // Is the user active?
221
-        if (! $user['active'])
222
-        {
223
-            $this->error = lang('auth.inactive_account');
224
-            return false;
225
-        }
226
-
227
-        return $return_user ? $user : true;
228
-    }
229
-
230
-    //--------------------------------------------------------------------
231
-
232
-    /**
233
-     * Logs a user out and removes all session information.
234
-     *
235
-     * @return mixed
236
-     */
237
-    public function logout()
238
-    {
239
-        $this->ci->load->helper('cookie');
240
-
241
-        if (! Events::trigger('beforeLogout', [$this->user]))
242
-        {
243
-            return false;
244
-        }
245
-
246
-        // Destroy the session data - but ensure a session is still
247
-        // available for flash messages, etc.
248
-        if (isset($_SESSION))
249
-        {
250
-            foreach ( $_SESSION as $key => $value )
251
-            {
252
-                $_SESSION[ $key ] = NULL;
253
-                unset( $_SESSION[ $key ] );
254
-            }
255
-        }
256
-        // Also, regenerate the session ID for a touch of added safety.
257
-        $this->ci->session->sess_regenerate(true);
258
-
259
-        // Take care of any rememberme functionality.
260
-        if (config_item('auth.allow_remembering'))
261
-        {
262
-            $token = get_cookie('remember');
263
-
264
-            $this->invalidateRememberCookie($this->user['email'], $token);
265
-        }
266
-    }
267
-
268
-    //--------------------------------------------------------------------
269
-
270
-    /**
271
-     * Checks whether a user is logged in or not.
272
-     *
273
-     * @return bool
274
-     */
275
-    public function isLoggedIn()
276
-    {
277
-        $id = $this->ci->session->userdata('logged_in');
278
-
279
-        if (! $id)
280
-        {
281
-            return false;
282
-        }
283
-
284
-        // If the user var hasn't been filled in, we need to fill it in,
285
-        // since this method will typically be used as the only method
286
-        // to determine whether a user is logged in or not.
287
-        if (! $this->user)
288
-        {
289
-            $this->user = $this->user_model->as_array()
290
-                                           ->find_by('id', (int)$id);
291
-
292
-            if (empty($this->user))
293
-            {
294
-                return false;
295
-            }
296
-        }
297
-
298
-        // If logged in, ensure cache control
299
-        // headers are in place
300
-        $this->setHeaders();
301
-
302
-        return true;
303
-    }
304
-
305
-    //--------------------------------------------------------------------
306
-
307
-    /**
308
-     * Attempts to log a user in based on the "remember me" cookie.
309
-     *
310
-     * @return bool
311
-     */
312
-    public function viaRemember()
313
-    {
314
-        if (! config_item('auth.allow_remembering'))
315
-        {
316
-            return false;
317
-        }
318
-
319
-        $this->ci->load->helper('cookie');
320
-
321
-        if (! $token = get_cookie('remember'))
322
-        {
323
-            return false;
324
-        }
325
-
326
-        // Attempt to match the token against our auth_tokens table.
327
-        $query = $this->ci->db->where('hash', $this->ci->login_model->hashRememberToken($token))
328
-                              ->get('auth_tokens');
329
-
330
-        if (! $query->num_rows())
331
-        {
332
-            return false;
333
-        }
334
-
335
-        // Grab the user
336
-        $email = $query->row()->email;
337
-
338
-        $user = $this->user_model->as_array()
339
-                                 ->find_by('email', $email);
340
-
341
-        $this->loginUser($user);
342
-
343
-        // We only want our remember me tokens to be valid
344
-        // for a single use.
345
-        $this->refreshRememberCookie($user, $token);
346
-
347
-        return true;
348
-    }
349
-
350
-    //--------------------------------------------------------------------
351
-
352
-    /**
353
-     * Registers a new user and handles activation method.
354
-     *
355
-     * @param $user_data
356
-     * @return bool
357
-     */
358
-    public function registerUser($user_data)
359
-    {
360
-        // Anything special needed for Activation?
361
-        $method = config_item('auth.activation_method');
362
-
363
-        $user_data['active'] = $method == 'auto' ? 1 : 0;
364
-
365
-        // If via email, we need to generate a hash
366
-        $this->ci->load->helper('string');
367
-        $token = random_string('alnum', 24);
368
-        $user_data['activate_hash'] = hash('sha1', config_item('auth.salt') . $token);
369
-
370
-        // Email should NOT be case sensitive.
371
-        if (! empty($user_data['email']))
372
-        {
373
-            $user_data['email'] = strtolower($user_data['email']);
374
-        }
375
-
376
-        // Save the user
377
-        if (! $id = $this->user_model->insert($user_data))
378
-        {
379
-            $this->error = $this->user_model->error();
380
-            return false;
381
-        }
382
-
383
-        $data = [
384
-            'user_id' => $id,
385
-            'email'   => $user_data['email'],
386
-            'token'   => $token,
387
-            'method'  => $method
388
-        ];
389
-
390
-        Events::trigger('didRegisterUser', [$data]);
391
-
392
-        return true;
393
-    }
394
-
395
-    //--------------------------------------------------------------------
396
-
397
-    /**
398
-     * Used to verify the user values and activate a user so they can
399
-     * visit the site.
400
-     *
401
-     * @param $data
402
-     * @return bool
403
-     */
404
-    public function activateUser($data)
405
-    {
406
-        $post = [
407
-            'email'         => $data['email'],
408
-            'activate_hash' => hash('sha1', config_item('auth.salt') . $data['code'])
409
-        ];
410
-
411
-        $user = $this->user_model->where($post)
412
-                                 ->first();
413
-
414
-        if (! $user) {
415
-            $this->error = $this->user_model->error() ? $this->user_model->error() : lang('auth.activate_no_user');
416
-
417
-            return false;
418
-        }
419
-
420
-        if (! $this->user_model->update($user->id, ['active' => 1, 'activate_hash' => null]))
421
-        {
422
-            $this->error = $this->user_model->error();
423
-            return false;
424
-        }
425
-
426
-        Events::trigger('didActivate', [(array)$user]);
427
-
428
-        return true;
429
-    }
430
-
431
-    //--------------------------------------------------------------------
432
-
433
-    /**
434
-     * Used to allow manual activation of a user with a known ID.
435
-     *
436
-     * @param $id
437
-     * @return bool
438
-     */
439
-    public function activateUserById($id)
440
-    {
441
-        if (! $this->user_model->update($id, ['active' => 1, 'activate_hash' => null]))
442
-        {
443
-            $this->error = $this->user_model->error();
444
-            return false;
445
-        }
446
-
447
-        Events::trigger('didActivate', [$this->user_model->as_array()->find($id)]);
448
-
449
-        return true;
450
-    }
451
-
452
-    //--------------------------------------------------------------------
453
-
454
-    /**
455
-     * Grabs the current user object. Returns NULL if nothing found.
456
-     *
457
-     * @return array|null
458
-     */
459
-    public function user()
460
-    {
461
-        return $this->user;
462
-    }
463
-
464
-    //--------------------------------------------------------------------
465
-
466
-    /**
467
-     * A convenience method to grab the current user's ID.
468
-     *
469
-     * @return int|null
470
-     */
471
-    public function id()
472
-    {
473
-        if (! is_array($this->user) || empty($this->user['id']))
474
-        {
475
-            return null;
476
-        }
477
-
478
-        return (int)$this->user['id'];
479
-    }
480
-
481
-    //--------------------------------------------------------------------
482
-
483
-    /**
484
-     * Checks to see if the user is currently being throttled.
485
-     *
486
-     *  - If they are NOT, will return FALSE.
487
-     *  - If they ARE, will return the number of seconds until they can try again.
488
-     *
489
-     * @param $user
490
-     * @return mixed
491
-     */
492
-    public function isThrottled($user)
493
-    {
494
-        // Not throttling? Get outta here!
495
-        if (! config_item('auth.allow_throttling'))
496
-        {
497
-            return false;
498
-        }
499
-
500
-        // Get user_id
501
-        $user_id = $user ? $user['id'] : null;
55
+	protected $ci;
56
+
57
+	protected $user = null;
58
+
59
+	public $user_model = null;
60
+
61
+	public $error = null;
62
+
63
+	//--------------------------------------------------------------------
64
+
65
+	public function __construct( $ci=null )
66
+	{
67
+		if ($ci)
68
+		{
69
+			$this->ci= $ci;
70
+		}
71
+		else
72
+		{
73
+			$this->ci =& get_instance();
74
+		}
75
+
76
+		// Get our compatibility password file loaded up.
77
+		if (! function_exists('password_hash'))
78
+		{
79
+			require_once dirname(__FILE__) .'password.php';
80
+		}
81
+
82
+		if (empty($this->ci->session))
83
+		{
84
+			$this->ci->load->library('session');
85
+		}
86
+
87
+		$this->ci->config->load('auth');
88
+		$this->ci->load->model('auth/login_model');
89
+		$this->ci->load->language('auth/auth');
90
+	}
91
+
92
+	//--------------------------------------------------------------------
93
+
94
+	/**
95
+	 * Attempt to log a user into the system.
96
+	 *
97
+	 * $credentials is an array of key/value pairs needed to log the user in.
98
+	 * This is often email/password, or username/password.
99
+	 *
100
+	 * @param array $credentials
101
+	 * @param bool  $remember
102
+	 * @return bool|mixed
103
+	 */
104
+	public function login($credentials, $remember=false)
105
+	{
106
+		$user = $this->validate($credentials, true);
107
+
108
+		if (! $user)
109
+		{
110
+			$this->user = null;
111
+			return $user;
112
+		}       
113
+
114
+		$this->loginUser($user);
115
+
116
+		if ($remember)
117
+		{
118
+			$this->rememberUser($user);
119
+		}
120
+
121
+		Events::trigger('didLogin', [$user]);
122
+
123
+		return true;
124
+	}
125
+
126
+	//--------------------------------------------------------------------
127
+
128
+	/**
129
+	 * Validates user login information without logging them in.
130
+	 *
131
+	 * $credentials is an array of key/value pairs needed to log the user in.
132
+	 * This is often email/password, or username/password.
133
+	 *
134
+	 * @param $credentials
135
+	 * @param bool $return_user
136
+	 * @return mixed
137
+	 */
138
+	public function validate($credentials, $return_user=false)
139
+	{
140
+		// Can't validate without a password.
141
+		if (empty($credentials['password']) || count($credentials) < 2)
142
+		{
143
+			return null;
144
+		}
145
+
146
+		$password = $credentials['password'];
147
+		unset($credentials['password']);
148
+
149
+		// We should only be allowed 1 single other credential to
150
+		// test against.
151
+		if (count($credentials) > 1)
152
+		{
153
+			$this->error = lang('auth.too_many_credentials');
154
+			return false;
155
+		}
156
+
157
+		// Ensure that the fields are allowed validation fields
158
+		if (! in_array(key($credentials), config_item('auth.valid_fields')) )
159
+		{
160
+			$this->error = lang('auth.invalid_credentials');
161
+			return false;
162
+		}
163
+
164
+		// We do not want to force case-sensitivity on things
165
+		// like username and email for usability sake.
166
+		if (! empty($credentials['email']))
167
+		{
168
+			$credentials['email'] = strtolower($credentials['email']);
169
+		}
170
+
171
+		// Can we find a user with those credentials?
172
+		$user = $this->user_model->as_array()
173
+								 ->where($credentials)
174
+								 ->first();
175
+
176
+		// If the user is throttled due to too many invalid logins
177
+		// or the system is under attack, kick them back.
178
+
179
+		// If throttling time is above zero, we can't allow
180
+		// logins now.
181
+		$time = (int)$this->isThrottled($user);
182
+		if ($time > 0)
183
+		{
184
+			$this->error = sprintf(lang('auth.throttled'), $time);
185
+			return false;
186
+		}
187
+
188
+		// Get ip address
189
+		$ip_address = $this->ci->input->ip_address();
190
+
191
+		if (! $user)
192
+		{
193
+			$this->error = lang('auth.invalid_user');
194
+			$this->ci->login_model->recordLoginAttempt($ip_address);
195
+			return false;
196
+		}
197
+
198
+		// Now, try matching the passwords.
199
+		$result =  password_verify($password, $user['password_hash']);
200
+
201
+		if (! $result)
202
+		{
203
+			$this->error = lang('auth.invalid_password');
204
+			$this->ci->login_model->recordLoginAttempt($ip_address, $user['id']);
205
+			return false;
206
+		}
207
+
208
+		// Check to see if the password needs to be rehashed.
209
+		// This would be due to the hash algorithm or hash
210
+		// cost changing since the last time that a user
211
+		// logged in.
212
+		if (password_needs_rehash($user['password_hash'], PASSWORD_DEFAULT, ['cost' => config_item('auth.hash_cost')] ))
213
+		{
214
+			$new_hash = Password::hashPassword($password);
215
+			$this->user_model->skip_validation()
216
+							 ->update($user['id'], ['password_hash' => $new_hash]);
217
+			unset($new_hash);
218
+		}
219
+
220
+		// Is the user active?
221
+		if (! $user['active'])
222
+		{
223
+			$this->error = lang('auth.inactive_account');
224
+			return false;
225
+		}
226
+
227
+		return $return_user ? $user : true;
228
+	}
229
+
230
+	//--------------------------------------------------------------------
231
+
232
+	/**
233
+	 * Logs a user out and removes all session information.
234
+	 *
235
+	 * @return mixed
236
+	 */
237
+	public function logout()
238
+	{
239
+		$this->ci->load->helper('cookie');
240
+
241
+		if (! Events::trigger('beforeLogout', [$this->user]))
242
+		{
243
+			return false;
244
+		}
245
+
246
+		// Destroy the session data - but ensure a session is still
247
+		// available for flash messages, etc.
248
+		if (isset($_SESSION))
249
+		{
250
+			foreach ( $_SESSION as $key => $value )
251
+			{
252
+				$_SESSION[ $key ] = NULL;
253
+				unset( $_SESSION[ $key ] );
254
+			}
255
+		}
256
+		// Also, regenerate the session ID for a touch of added safety.
257
+		$this->ci->session->sess_regenerate(true);
258
+
259
+		// Take care of any rememberme functionality.
260
+		if (config_item('auth.allow_remembering'))
261
+		{
262
+			$token = get_cookie('remember');
263
+
264
+			$this->invalidateRememberCookie($this->user['email'], $token);
265
+		}
266
+	}
267
+
268
+	//--------------------------------------------------------------------
269
+
270
+	/**
271
+	 * Checks whether a user is logged in or not.
272
+	 *
273
+	 * @return bool
274
+	 */
275
+	public function isLoggedIn()
276
+	{
277
+		$id = $this->ci->session->userdata('logged_in');
278
+
279
+		if (! $id)
280
+		{
281
+			return false;
282
+		}
283
+
284
+		// If the user var hasn't been filled in, we need to fill it in,
285
+		// since this method will typically be used as the only method
286
+		// to determine whether a user is logged in or not.
287
+		if (! $this->user)
288
+		{
289
+			$this->user = $this->user_model->as_array()
290
+										   ->find_by('id', (int)$id);
291
+
292
+			if (empty($this->user))
293
+			{
294
+				return false;
295
+			}
296
+		}
297
+
298
+		// If logged in, ensure cache control
299
+		// headers are in place
300
+		$this->setHeaders();
301
+
302
+		return true;
303
+	}
304
+
305
+	//--------------------------------------------------------------------
306
+
307
+	/**
308
+	 * Attempts to log a user in based on the "remember me" cookie.
309
+	 *
310
+	 * @return bool
311
+	 */
312
+	public function viaRemember()
313
+	{
314
+		if (! config_item('auth.allow_remembering'))
315
+		{
316
+			return false;
317
+		}
318
+
319
+		$this->ci->load->helper('cookie');
320
+
321
+		if (! $token = get_cookie('remember'))
322
+		{
323
+			return false;
324
+		}
325
+
326
+		// Attempt to match the token against our auth_tokens table.
327
+		$query = $this->ci->db->where('hash', $this->ci->login_model->hashRememberToken($token))
328
+							  ->get('auth_tokens');
329
+
330
+		if (! $query->num_rows())
331
+		{
332
+			return false;
333
+		}
334
+
335
+		// Grab the user
336
+		$email = $query->row()->email;
337
+
338
+		$user = $this->user_model->as_array()
339
+								 ->find_by('email', $email);
340
+
341
+		$this->loginUser($user);
342
+
343
+		// We only want our remember me tokens to be valid
344
+		// for a single use.
345
+		$this->refreshRememberCookie($user, $token);
346
+
347
+		return true;
348
+	}
349
+
350
+	//--------------------------------------------------------------------
351
+
352
+	/**
353
+	 * Registers a new user and handles activation method.
354
+	 *
355
+	 * @param $user_data
356
+	 * @return bool
357
+	 */
358
+	public function registerUser($user_data)
359
+	{
360
+		// Anything special needed for Activation?
361
+		$method = config_item('auth.activation_method');
362
+
363
+		$user_data['active'] = $method == 'auto' ? 1 : 0;
364
+
365
+		// If via email, we need to generate a hash
366
+		$this->ci->load->helper('string');
367
+		$token = random_string('alnum', 24);
368
+		$user_data['activate_hash'] = hash('sha1', config_item('auth.salt') . $token);
369
+
370
+		// Email should NOT be case sensitive.
371
+		if (! empty($user_data['email']))
372
+		{
373
+			$user_data['email'] = strtolower($user_data['email']);
374
+		}
375
+
376
+		// Save the user
377
+		if (! $id = $this->user_model->insert($user_data))
378
+		{
379
+			$this->error = $this->user_model->error();
380
+			return false;
381
+		}
382
+
383
+		$data = [
384
+			'user_id' => $id,
385
+			'email'   => $user_data['email'],
386
+			'token'   => $token,
387
+			'method'  => $method
388
+		];
389
+
390
+		Events::trigger('didRegisterUser', [$data]);
391
+
392
+		return true;
393
+	}
394
+
395
+	//--------------------------------------------------------------------
396
+
397
+	/**
398
+	 * Used to verify the user values and activate a user so they can
399
+	 * visit the site.
400
+	 *
401
+	 * @param $data
402
+	 * @return bool
403
+	 */
404
+	public function activateUser($data)
405
+	{
406
+		$post = [
407
+			'email'         => $data['email'],
408
+			'activate_hash' => hash('sha1', config_item('auth.salt') . $data['code'])
409
+		];
410
+
411
+		$user = $this->user_model->where($post)
412
+								 ->first();
413
+
414
+		if (! $user) {
415
+			$this->error = $this->user_model->error() ? $this->user_model->error() : lang('auth.activate_no_user');
416
+
417
+			return false;
418
+		}
419
+
420
+		if (! $this->user_model->update($user->id, ['active' => 1, 'activate_hash' => null]))
421
+		{
422
+			$this->error = $this->user_model->error();
423
+			return false;
424
+		}
425
+
426
+		Events::trigger('didActivate', [(array)$user]);
427
+
428
+		return true;
429
+	}
430
+
431
+	//--------------------------------------------------------------------
432
+
433
+	/**
434
+	 * Used to allow manual activation of a user with a known ID.
435
+	 *
436
+	 * @param $id
437
+	 * @return bool
438
+	 */
439
+	public function activateUserById($id)
440
+	{
441
+		if (! $this->user_model->update($id, ['active' => 1, 'activate_hash' => null]))
442
+		{
443
+			$this->error = $this->user_model->error();
444
+			return false;
445
+		}
446
+
447
+		Events::trigger('didActivate', [$this->user_model->as_array()->find($id)]);
448
+
449
+		return true;
450
+	}
451
+
452
+	//--------------------------------------------------------------------
453
+
454
+	/**
455
+	 * Grabs the current user object. Returns NULL if nothing found.
456
+	 *
457
+	 * @return array|null
458
+	 */
459
+	public function user()
460
+	{
461
+		return $this->user;
462
+	}
463
+
464
+	//--------------------------------------------------------------------
465
+
466
+	/**
467
+	 * A convenience method to grab the current user's ID.
468
+	 *
469
+	 * @return int|null
470
+	 */
471
+	public function id()
472
+	{
473
+		if (! is_array($this->user) || empty($this->user['id']))
474
+		{
475
+			return null;
476
+		}
477
+
478
+		return (int)$this->user['id'];
479
+	}
480
+
481
+	//--------------------------------------------------------------------
482
+
483
+	/**
484
+	 * Checks to see if the user is currently being throttled.
485
+	 *
486
+	 *  - If they are NOT, will return FALSE.
487
+	 *  - If they ARE, will return the number of seconds until they can try again.
488
+	 *
489
+	 * @param $user
490
+	 * @return mixed
491
+	 */
492
+	public function isThrottled($user)
493
+	{
494
+		// Not throttling? Get outta here!
495
+		if (! config_item('auth.allow_throttling'))
496
+		{
497
+			return false;
498
+		}
499
+
500
+		// Get user_id
501
+		$user_id = $user ? $user['id'] : null;
502 502
         
503
-        // Get ip address
504
-        $ip_address = $this->ci->input->ip_address();
505
-
506
-        // Have any attempts been made?
507
-        $attempts = $this->ci->login_model->countLoginAttempts($ip_address, $user_id);
508
-
509
-        // Grab the amount of time to add if the system thinks we're
510
-        // under a distributed brute force attack.
511
-        // Affect users that have at least 1 failure login attempt
512
-        $dbrute_time = ($attempts === 0) ? 0 : $this->ci->login_model->distributedBruteForceTime();
513
-
514
-        // If this user was found to possibly be under a brute
515
-        // force attack, their account would have been banned
516
-        // for 15 minutes.
517
-        if ($time = isset($_SESSION['bruteBan']) ? $_SESSION['bruteBan'] : false)
518
-        {
519
-            // If the current time is less than the
520
-            // the ban expiration, plus any distributed time
521
-            // then the user can't login just yet.
522
-            if ($time + $dbrute_time > time())
523
-            {
524
-                // The user is banned still...
525
-                $this->error = lang('auth.bruteBan_notice');
526
-                return ($time + $dbrute_time) - time();
527
-            }
528
-
529
-            // Still here? The the ban time is over...
530
-            unset($_SESSION['bruteBan']);
531
-        }
532
-
533
-        // Grab the time of last attempt and
534
-        // determine if we're throttled by amount of time passed.
535
-        $last_time = $this->ci->login_model->lastLoginAttemptTime($ip_address, $user_id);
536
-
537
-        $allowed = config_item('auth.allowed_login_attempts');
538
-
539
-        // We're not throttling if there are 0 attempts or
540
-        // the number is less than or equal to the allowed free attempts
541
-        if ($attempts === 0 || $attempts < $allowed)
542
-        {
543
-            // Before we can say there's nothing up here,
544
-            // we need to check dbrute time.
545
-            $time_left = $last_time + $dbrute_time - time();
546
-
547
-            if ($time_left > 0)
548
-            {
549
-                return $time_left;
550
-            }
551
-
552
-            return false;
553
-        }
554
-
555
-        // If the number of attempts is excessive (above 100) we need
556
-        // to check the elapsed time of all of these attacks. If they are
557
-        // less than 1 minute it's obvious this is a brute force attack,
558
-        // so we'll set a session flag and block that user for 15 minutes.
559
-        if ($attempts > 100 && $this->ci->login_model->isBruteForced($ip_address, $user_id))
560
-        {
561
-            $this->error = lang('auth.bruteBan_notice');
562
-
563
-            $ban_time = 60 * 15;    // 15 minutes
564
-            $_SESSION['bruteBan'] = time() + $ban_time;
565
-            return $ban_time;
566
-        }
567
-
568
-        // Get our allowed attempts out of the picture.
569
-        $attempts = $attempts - $allowed;
570
-
571
-        $max_time = config_item('auth.max_throttle_time');
572
-
573
-        $add_time = 5 * pow(2, $attempts);
574
-
575
-        if ($add_time > $max_time)
576
-        {
577
-            $add_time = $max_time;
578
-        }
579
-
580
-        $next_time = $last_time + $add_time + $dbrute_time;
581
-
582
-        $current = time();
583
-
584
-        // We are NOT throttled if we are already
585
-        // past the allowed time.
586
-        if ($current > $next_time)
587
-        {
588
-            return false;
589
-        }
590
-
591
-        return $next_time - $current;
592
-    }
593
-
594
-    //--------------------------------------------------------------------
595
-
596
-    /**
597
-     * Sends a password reset link email to the user associated with
598
-     * the passed in $email.
599
-     *
600
-     * @param $email
601
-     * @return mixed
602
-     */
603
-    public function remindUser($email)
604
-    {
605
-        // Emails should NOT be case sensitive.
606
-        $email = strtolower($email);
607
-
608
-        // Is it a valid user?
609
-        $user = $this->user_model->find_by('email', $email);
610
-
611
-        if (! $user)
612
-        {
613
-            $this->error = lang('auth.invalid_email');
614
-            return false;
615
-        }
616
-
617
-        // Generate/store our codes
618
-        $this->ci->load->helper('string');
619
-        $token = random_string('alnum', 24);
620
-        $hash = hash('sha1', config_item('auth.salt') .$token);
621
-
622
-        $result = $this->user_model->update($user->id, ['reset_hash' => $hash]);
623
-
624
-        if (! $result)
625
-        {
626
-            $this->error = $this->user_model->error();
627
-            return false;
628
-        }
629
-
630
-        Events::trigger('didRemindUser', [(array)$user, $token]);
631
-
632
-        return true;
633
-    }
634
-
635
-    //--------------------------------------------------------------------
636
-
637
-    /**
638
-     * Validates the credentials provided and, if valid, resets the password.
639
-     *
640
-     * The $credentials array MUST contain a 'code' key with the string to
641
-     * hash and check against the reset_hash.
642
-     *
643
-     * @param $credentials
644
-     * @param $password
645
-     * @param $passConfirm
646
-     * @return mixed
647
-     */
648
-    public function resetPassword($credentials, $password, $passConfirm)
649
-    {
650
-        if (empty($credentials['code']))
651
-        {
652
-            $this->error = lang('auth.need_reset_code');
653
-            return false;
654
-        }
655
-
656
-        // Generate a hash to match against the table.
657
-        $reset_hash = hash('sha1', config_item('auth.salt') .$credentials['code']);
658
-        unset($credentials['code']);
659
-
660
-        if (! empty($credentials['email']))
661
-        {
662
-            $credentials['email'] = strtolower($credentials['email']);
663
-        }
664
-
665
-        // Is there a matching user?
666
-        $user = $this->user_model->as_array()
667
-                                 ->where($credentials)
668
-                                 ->first();
669
-
670
-        // If throttling time is above zero, we can't allow
671
-        // logins now.
672
-        $time = (int)$this->isThrottled($user);
673
-        if ($time > 0)
674
-        {
675
-            $this->error = sprintf(lang('auth.throttled'), $time);
676
-            return false;
677
-        }
678
-
679
-        // Get ip address
680
-        $ip_address = $this->ci->input->ip_address();
681
-
682
-        if (! $user)
683
-        {
684
-            $this->error = lang('auth.reset_no_user');
685
-            $this->ci->login_model->recordLoginAttempt($ip_address);
686
-            return false;
687
-        }
688
-
689
-        // Is generated reset_hash string matches one from the table?
690
-        if ($reset_hash !== $user['reset_hash'])
691
-        {
692
-            $this->error = lang('auth.reset_no_user');
693
-            $this->ci->login_model->recordLoginAttempt($ip_address, $user['id']);
694
-            return false;
695
-        }
696
-
697
-        // Update their password and reset their reset_hash
698
-        $data = [
699
-            'password'     => $password,
700
-            'pass_confirm' => $passConfirm,
701
-            'reset_hash'   => null
702
-        ];
703
-
704
-        if (! $this->user_model->update($user['id'], $data))
705
-        {
706
-            $this->error = $this->user_model->error();
707
-            return false;
708
-        }
709
-
710
-        // Clear our login attempts
711
-        $this->ci->login_model->purgeLoginAttempts($ip_address, $user['id']);
712
-
713
-        Events::trigger('didResetPassword', [$user]);
714
-
715
-        return true;
716
-    }
717
-
718
-    //--------------------------------------------------------------------
719
-
720
-    /**
721
-     * Provides a way for implementations to allow new statuses to be set
722
-     * on the user. The details will vary based upon implementation, but
723
-     * will often allow for banning or suspending users.
724
-     *
725
-     * @param $newStatus
726
-     * @param null $message
727
-     * @return mixed
728
-     */
729
-    public function changeStatus($newStatus, $message=null)
730
-    {
731
-        // todo actually record new users status!
732
-    }
733
-
734
-    //--------------------------------------------------------------------
735
-
736
-    /**
737
-     * Allows the consuming application to pass in a reference to the
738
-     * model that should be used.
739
-     *
740
-     * The model MUST extend Myth\Models\CIDbModel.
741
-     *
742
-     * @param $model
743
-     * @param bool $allow_any_parent
744
-     * @return mixed
745
-     */
746
-    public function useModel($model, $allow_any_parent=false)
747
-    {
748
-        if (! $allow_any_parent && get_parent_class($model) != 'Myth\Models\CIDbModel')
749
-        {
750
-            throw new \RuntimeException('Models passed into LocalAuthenticate MUST extend Myth\Models\CIDbModel');
751
-        }
752
-
753
-        $this->user_model =& $model;
754
-
755
-        return $this;
756
-    }
757
-
758
-    //--------------------------------------------------------------------
759
-
760
-    public function error()
761
-    {
762
-        if (validation_errors())
763
-        {
764
-            return validation_errors();
765
-        }
766
-
767
-        return $this->error;
768
-    }
769
-
770
-    //--------------------------------------------------------------------
771
-
772
-    //--------------------------------------------------------------------
773
-    // Login Records
774
-    //--------------------------------------------------------------------
775
-
776
-    /**
777
-     * Purges all login attempt records from the database.
778
-     *
779
-     * @param null $ip_address
780
-     * @param null $user_id
781
-     */
782
-    public function purgeLoginAttempts($ip_address = null, $user_id = null)
783
-    {
784
-        $this->ci->login_model->purgeLoginAttempts($ip_address, $user_id);
785
-
786
-        // @todo record activity of login attempts purge.
787
-        Events::trigger('didPurgeLoginAttempts', [$email]);
788
-    }
789
-
790
-    //--------------------------------------------------------------------
791
-
792
-    /**
793
-     * Purges all remember tokens for a single user. Effectively logs
794
-     * a user out of all devices. Intended to allow users to log themselves
795
-     * out of all devices as a security measure.
796
-     *
797
-     * @param $email
798
-     */
799
-    public function purgeRememberTokens($email)
800
-    {
801
-        // Emails should NOT be case sensitive.
802
-        $email = strtolower($email);
803
-
804
-        $this->ci->login_model->purgeRememberTokens($email);
805
-
806
-        // todo record activity of remember me purges.
807
-        Events::trigger('didPurgeRememberTokens', [$email]);
808
-    }
809
-
810
-    //--------------------------------------------------------------------
811
-
812
-    //--------------------------------------------------------------------
813
-    // Protected Methods
814
-    //--------------------------------------------------------------------
815
-
816
-    /**
817
-     * Check if Allow Persistent Login Cookies is enable
818
-     *
819
-     * @param $user
820
-     */
821
-    protected function rememberUser($user)
822
-    {
823
-        if (! config_item('auth.allow_remembering'))
824
-        {
825
-            log_message('debug', 'Auth library set to refuse "Remember Me" functionality.');
826
-            return false;
827
-        }
828
-
829
-        $this->refreshRememberCookie($user);
830
-    }
831
-
832
-    //--------------------------------------------------------------------
833
-
834
-    /**
835
-     * Invalidates the current rememberme cookie/database entry, creates
836
-     * a new one, stores it and returns the new value.
837
-     *
838
-     * @param $user
839
-     * @param null $token
840
-     * @return mixed
841
-     */
842
-    protected function refreshRememberCookie($user, $token=null)
843
-    {
844
-        $this->ci->load->helper('cookie');
845
-
846
-        // If a token is passed in, we know we're removing the
847
-        // old one.
848
-        if (! empty($token))
849
-        {
850
-            $this->invalidateRememberCookie($user['email'], $token);
851
-        }
852
-
853
-        $new_token = $this->ci->login_model->generateRememberToken($user);
854
-
855
-        // Save the token to the database.
856
-        $data = [
857
-            'email'   => $user['email'],
858
-            'hash'    => sha1(config_item('auth.salt') . $new_token),
859
-            'created' => date('Y-m-d H:i:s')
860
-        ];
861
-
862
-        $this->ci->db->insert('auth_tokens', $data);
863
-
864
-        // Create the cookie
865
-        set_cookie(
866
-            'remember',                             // Cookie Name
867
-            $new_token,                             // Value
868
-            config_item('auth.remember_length'),    // # Seconds until it expires
869
-            config_item('cookie_domain'),
870
-            config_item('cookie_path'),
871
-            config_item('cookie_prefix'),
872
-            false,                                  // Only send over HTTPS?
873
-            true                                    // Hide from Javascript?
874
-        );
875
-
876
-        return $new_token;
877
-    }
878
-
879
-    //--------------------------------------------------------------------
880
-
881
-    /**
882
-     * Deletes any current remember me cookies and database entries.
883
-     *
884
-     * @param $email
885
-     * @param $token
886
-     * @return string The new token (not the hash).
887
-     */
888
-    protected function invalidateRememberCookie($email, $token)
889
-    {
890
-        // Emails should NOT be case sensitive.
891
-        $email = strtolower($email);
892
-
893
-        // Remove from the database
894
-        $this->ci->login_model->deleteRememberToken($email, $token);
895
-
896
-        // Remove the cookie
897
-        delete_cookie(
898
-            'remember',
899
-            config_item('cookie_domain'),
900
-            config_item('cookie_path'),
901
-            config_item('cookie_prefix')
902
-        );
903
-    }
904
-
905
-    //--------------------------------------------------------------------
906
-
907
-    /**
908
-     * Handles the nitty gritty of actually logging our user into the system.
909
-     * Does NOT perform the authentication, just sets the system up so that
910
-     * it knows we're here.
911
-     *
912
-     * @param $user
913
-     */
914
-    protected function loginUser($user)
915
-    {
916
-        // Save the user for later access
917
-        $this->user = $user;
918
-
919
-        // Get ip address
920
-        $ip_address = $this->ci->input->ip_address();
921
-
922
-        // Regenerate the session ID to help protect
923
-        // against session fixation
924
-        $this->ci->session->sess_regenerate();
925
-
926
-        // Let the session know that we're logged in.
927
-        $this->ci->session->set_userdata('logged_in', $user['id']);
928
-
929
-        // Clear our login attempts
930
-        $this->ci->login_model->purgeLoginAttempts($ip_address, $user['id']);
931
-
932
-        // Record a new Login
933
-        $this->ci->login_model->recordLogin($user);
934
-
935
-        // If logged in, ensure cache control
936
-        // headers are in place
937
-        $this->setHeaders();
938
-
939
-        // We'll give a 20% chance to need to do a purge since we
940
-        // don't need to purge THAT often, it's just a maintenance issue.
941
-        // to keep the table from getting out of control.
942
-        if (mt_rand(1, 100) < 20)
943
-        {
944
-            $this->ci->login_model->purgeOldRememberTokens();
945
-        }
946
-    }
947
-
948
-    //--------------------------------------------------------------------
949
-
950
-    /**
951
-     * Sets the headers to ensure that pages are not cached when a user
952
-     * is logged in, helping to protect against logging out and then
953
-     * simply hitting the Back button on the browser and getting private
954
-     * information because the page was loaded from cache.
955
-     */
956
-    protected function setHeaders()
957
-    {
958
-        $this->ci->output->set_header('Cache-Control: no-store, no-cache, must-revalidate');
959
-        $this->ci->output->set_header('Cache-Control: post-check=0, pre-check=0');
960
-        $this->ci->output->set_header('Pragma: no-cache');
961
-    }
962
-
963
-    //--------------------------------------------------------------------
503
+		// Get ip address
504
+		$ip_address = $this->ci->input->ip_address();
505
+
506
+		// Have any attempts been made?
507
+		$attempts = $this->ci->login_model->countLoginAttempts($ip_address, $user_id);
508
+
509
+		// Grab the amount of time to add if the system thinks we're
510
+		// under a distributed brute force attack.
511
+		// Affect users that have at least 1 failure login attempt
512
+		$dbrute_time = ($attempts === 0) ? 0 : $this->ci->login_model->distributedBruteForceTime();
513
+
514
+		// If this user was found to possibly be under a brute
515
+		// force attack, their account would have been banned
516
+		// for 15 minutes.
517
+		if ($time = isset($_SESSION['bruteBan']) ? $_SESSION['bruteBan'] : false)
518
+		{
519
+			// If the current time is less than the
520
+			// the ban expiration, plus any distributed time
521
+			// then the user can't login just yet.
522
+			if ($time + $dbrute_time > time())
523
+			{
524
+				// The user is banned still...
525
+				$this->error = lang('auth.bruteBan_notice');
526
+				return ($time + $dbrute_time) - time();
527
+			}
528
+
529
+			// Still here? The the ban time is over...
530
+			unset($_SESSION['bruteBan']);
531
+		}
532
+
533
+		// Grab the time of last attempt and
534
+		// determine if we're throttled by amount of time passed.
535
+		$last_time = $this->ci->login_model->lastLoginAttemptTime($ip_address, $user_id);
536
+
537
+		$allowed = config_item('auth.allowed_login_attempts');
538
+
539
+		// We're not throttling if there are 0 attempts or
540
+		// the number is less than or equal to the allowed free attempts
541
+		if ($attempts === 0 || $attempts < $allowed)
542
+		{
543
+			// Before we can say there's nothing up here,
544
+			// we need to check dbrute time.
545
+			$time_left = $last_time + $dbrute_time - time();
546
+
547
+			if ($time_left > 0)
548
+			{
549
+				return $time_left;
550
+			}
551
+
552
+			return false;
553
+		}
554
+
555
+		// If the number of attempts is excessive (above 100) we need
556
+		// to check the elapsed time of all of these attacks. If they are
557
+		// less than 1 minute it's obvious this is a brute force attack,
558
+		// so we'll set a session flag and block that user for 15 minutes.
559
+		if ($attempts > 100 && $this->ci->login_model->isBruteForced($ip_address, $user_id))
560
+		{
561
+			$this->error = lang('auth.bruteBan_notice');
562
+
563
+			$ban_time = 60 * 15;    // 15 minutes
564
+			$_SESSION['bruteBan'] = time() + $ban_time;
565
+			return $ban_time;
566
+		}
567
+
568
+		// Get our allowed attempts out of the picture.
569
+		$attempts = $attempts - $allowed;
570
+
571
+		$max_time = config_item('auth.max_throttle_time');
572
+
573
+		$add_time = 5 * pow(2, $attempts);
574
+
575
+		if ($add_time > $max_time)
576
+		{
577
+			$add_time = $max_time;
578
+		}
579
+
580
+		$next_time = $last_time + $add_time + $dbrute_time;
581
+
582
+		$current = time();
583
+
584
+		// We are NOT throttled if we are already
585
+		// past the allowed time.
586
+		if ($current > $next_time)
587
+		{
588
+			return false;
589
+		}
590
+
591
+		return $next_time - $current;
592
+	}
593
+
594
+	//--------------------------------------------------------------------
595
+
596
+	/**
597
+	 * Sends a password reset link email to the user associated with
598
+	 * the passed in $email.
599
+	 *
600
+	 * @param $email
601
+	 * @return mixed
602
+	 */
603
+	public function remindUser($email)
604
+	{
605
+		// Emails should NOT be case sensitive.
606
+		$email = strtolower($email);
607
+
608
+		// Is it a valid user?
609
+		$user = $this->user_model->find_by('email', $email);
610
+
611
+		if (! $user)
612
+		{
613
+			$this->error = lang('auth.invalid_email');
614
+			return false;
615
+		}
616
+
617
+		// Generate/store our codes
618
+		$this->ci->load->helper('string');
619
+		$token = random_string('alnum', 24);
620
+		$hash = hash('sha1', config_item('auth.salt') .$token);
621
+
622
+		$result = $this->user_model->update($user->id, ['reset_hash' => $hash]);
623
+
624
+		if (! $result)
625
+		{
626
+			$this->error = $this->user_model->error();
627
+			return false;
628
+		}
629
+
630
+		Events::trigger('didRemindUser', [(array)$user, $token]);
631
+
632
+		return true;
633
+	}
634
+
635
+	//--------------------------------------------------------------------
636
+
637
+	/**
638
+	 * Validates the credentials provided and, if valid, resets the password.
639
+	 *
640
+	 * The $credentials array MUST contain a 'code' key with the string to
641
+	 * hash and check against the reset_hash.
642
+	 *
643
+	 * @param $credentials
644
+	 * @param $password
645
+	 * @param $passConfirm
646
+	 * @return mixed
647
+	 */
648
+	public function resetPassword($credentials, $password, $passConfirm)
649
+	{
650
+		if (empty($credentials['code']))
651
+		{
652
+			$this->error = lang('auth.need_reset_code');
653
+			return false;
654
+		}
655
+
656
+		// Generate a hash to match against the table.
657
+		$reset_hash = hash('sha1', config_item('auth.salt') .$credentials['code']);
658
+		unset($credentials['code']);
659
+
660
+		if (! empty($credentials['email']))
661
+		{
662
+			$credentials['email'] = strtolower($credentials['email']);
663
+		}
664
+
665
+		// Is there a matching user?
666
+		$user = $this->user_model->as_array()
667
+								 ->where($credentials)
668
+								 ->first();
669
+
670
+		// If throttling time is above zero, we can't allow
671
+		// logins now.
672
+		$time = (int)$this->isThrottled($user);
673
+		if ($time > 0)
674
+		{
675
+			$this->error = sprintf(lang('auth.throttled'), $time);
676
+			return false;
677
+		}
678
+
679
+		// Get ip address
680
+		$ip_address = $this->ci->input->ip_address();
681
+
682
+		if (! $user)
683
+		{
684
+			$this->error = lang('auth.reset_no_user');
685
+			$this->ci->login_model->recordLoginAttempt($ip_address);
686
+			return false;
687
+		}
688
+
689
+		// Is generated reset_hash string matches one from the table?
690
+		if ($reset_hash !== $user['reset_hash'])
691
+		{
692
+			$this->error = lang('auth.reset_no_user');
693
+			$this->ci->login_model->recordLoginAttempt($ip_address, $user['id']);
694
+			return false;
695
+		}
696
+
697
+		// Update their password and reset their reset_hash
698
+		$data = [
699
+			'password'     => $password,
700
+			'pass_confirm' => $passConfirm,
701
+			'reset_hash'   => null
702
+		];
703
+
704
+		if (! $this->user_model->update($user['id'], $data))
705
+		{
706
+			$this->error = $this->user_model->error();
707
+			return false;
708
+		}
709
+
710
+		// Clear our login attempts
711
+		$this->ci->login_model->purgeLoginAttempts($ip_address, $user['id']);
712
+
713
+		Events::trigger('didResetPassword', [$user]);
714
+
715
+		return true;
716
+	}
717
+
718
+	//--------------------------------------------------------------------
719
+
720
+	/**
721
+	 * Provides a way for implementations to allow new statuses to be set
722
+	 * on the user. The details will vary based upon implementation, but
723
+	 * will often allow for banning or suspending users.
724
+	 *
725
+	 * @param $newStatus
726
+	 * @param null $message
727
+	 * @return mixed
728
+	 */
729
+	public function changeStatus($newStatus, $message=null)
730
+	{
731
+		// todo actually record new users status!
732
+	}
733
+
734
+	//--------------------------------------------------------------------
735
+
736
+	/**
737
+	 * Allows the consuming application to pass in a reference to the
738
+	 * model that should be used.
739
+	 *
740
+	 * The model MUST extend Myth\Models\CIDbModel.
741
+	 *
742
+	 * @param $model
743
+	 * @param bool $allow_any_parent
744
+	 * @return mixed
745
+	 */
746
+	public function useModel($model, $allow_any_parent=false)
747
+	{
748
+		if (! $allow_any_parent && get_parent_class($model) != 'Myth\Models\CIDbModel')
749
+		{
750
+			throw new \RuntimeException('Models passed into LocalAuthenticate MUST extend Myth\Models\CIDbModel');
751
+		}
752
+
753
+		$this->user_model =& $model;
754
+
755
+		return $this;
756
+	}
757
+
758
+	//--------------------------------------------------------------------
759
+
760
+	public function error()
761
+	{
762
+		if (validation_errors())
763
+		{
764
+			return validation_errors();
765
+		}
766
+
767
+		return $this->error;
768
+	}
769
+
770
+	//--------------------------------------------------------------------
771
+
772
+	//--------------------------------------------------------------------
773
+	// Login Records
774
+	//--------------------------------------------------------------------
775
+
776
+	/**
777
+	 * Purges all login attempt records from the database.
778
+	 *
779
+	 * @param null $ip_address
780
+	 * @param null $user_id
781
+	 */
782
+	public function purgeLoginAttempts($ip_address = null, $user_id = null)
783
+	{
784
+		$this->ci->login_model->purgeLoginAttempts($ip_address, $user_id);
785
+
786
+		// @todo record activity of login attempts purge.
787
+		Events::trigger('didPurgeLoginAttempts', [$email]);
788
+	}
789
+
790
+	//--------------------------------------------------------------------
791
+
792
+	/**
793
+	 * Purges all remember tokens for a single user. Effectively logs
794
+	 * a user out of all devices. Intended to allow users to log themselves
795
+	 * out of all devices as a security measure.
796
+	 *
797
+	 * @param $email
798
+	 */
799
+	public function purgeRememberTokens($email)
800
+	{
801
+		// Emails should NOT be case sensitive.
802
+		$email = strtolower($email);
803
+
804
+		$this->ci->login_model->purgeRememberTokens($email);
805
+
806
+		// todo record activity of remember me purges.
807
+		Events::trigger('didPurgeRememberTokens', [$email]);
808
+	}
809
+
810
+	//--------------------------------------------------------------------
811
+
812
+	//--------------------------------------------------------------------
813
+	// Protected Methods
814
+	//--------------------------------------------------------------------
815
+
816
+	/**
817
+	 * Check if Allow Persistent Login Cookies is enable
818
+	 *
819
+	 * @param $user
820
+	 */
821
+	protected function rememberUser($user)
822
+	{
823
+		if (! config_item('auth.allow_remembering'))
824
+		{
825
+			log_message('debug', 'Auth library set to refuse "Remember Me" functionality.');
826
+			return false;
827
+		}
828
+
829
+		$this->refreshRememberCookie($user);
830
+	}
831
+
832
+	//--------------------------------------------------------------------
833
+
834
+	/**
835
+	 * Invalidates the current rememberme cookie/database entry, creates
836
+	 * a new one, stores it and returns the new value.
837
+	 *
838
+	 * @param $user
839
+	 * @param null $token
840
+	 * @return mixed
841
+	 */
842
+	protected function refreshRememberCookie($user, $token=null)
843
+	{
844
+		$this->ci->load->helper('cookie');
845
+
846
+		// If a token is passed in, we know we're removing the
847
+		// old one.
848
+		if (! empty($token))
849
+		{
850
+			$this->invalidateRememberCookie($user['email'], $token);
851
+		}
852
+
853
+		$new_token = $this->ci->login_model->generateRememberToken($user);
854
+
855
+		// Save the token to the database.
856
+		$data = [
857
+			'email'   => $user['email'],
858
+			'hash'    => sha1(config_item('auth.salt') . $new_token),
859
+			'created' => date('Y-m-d H:i:s')
860
+		];
861
+
862
+		$this->ci->db->insert('auth_tokens', $data);
863
+
864
+		// Create the cookie
865
+		set_cookie(
866
+			'remember',                             // Cookie Name
867
+			$new_token,                             // Value
868
+			config_item('auth.remember_length'),    // # Seconds until it expires
869
+			config_item('cookie_domain'),
870
+			config_item('cookie_path'),
871
+			config_item('cookie_prefix'),
872
+			false,                                  // Only send over HTTPS?
873
+			true                                    // Hide from Javascript?
874
+		);
875
+
876
+		return $new_token;
877
+	}
878
+
879
+	//--------------------------------------------------------------------
880
+
881
+	/**
882
+	 * Deletes any current remember me cookies and database entries.
883
+	 *
884
+	 * @param $email
885
+	 * @param $token
886
+	 * @return string The new token (not the hash).
887
+	 */
888
+	protected function invalidateRememberCookie($email, $token)
889
+	{
890
+		// Emails should NOT be case sensitive.
891
+		$email = strtolower($email);
892
+
893
+		// Remove from the database
894
+		$this->ci->login_model->deleteRememberToken($email, $token);
895
+
896
+		// Remove the cookie
897
+		delete_cookie(
898
+			'remember',
899
+			config_item('cookie_domain'),
900
+			config_item('cookie_path'),
901
+			config_item('cookie_prefix')
902
+		);
903
+	}
904
+
905
+	//--------------------------------------------------------------------
906
+
907
+	/**
908
+	 * Handles the nitty gritty of actually logging our user into the system.
909
+	 * Does NOT perform the authentication, just sets the system up so that
910
+	 * it knows we're here.
911
+	 *
912
+	 * @param $user
913
+	 */
914
+	protected function loginUser($user)
915
+	{
916
+		// Save the user for later access
917
+		$this->user = $user;
918
+
919
+		// Get ip address
920
+		$ip_address = $this->ci->input->ip_address();
921
+
922
+		// Regenerate the session ID to help protect
923
+		// against session fixation
924
+		$this->ci->session->sess_regenerate();
925
+
926
+		// Let the session know that we're logged in.
927
+		$this->ci->session->set_userdata('logged_in', $user['id']);
928
+
929
+		// Clear our login attempts
930
+		$this->ci->login_model->purgeLoginAttempts($ip_address, $user['id']);
931
+
932
+		// Record a new Login
933
+		$this->ci->login_model->recordLogin($user);
934
+
935
+		// If logged in, ensure cache control
936
+		// headers are in place
937
+		$this->setHeaders();
938
+
939
+		// We'll give a 20% chance to need to do a purge since we
940
+		// don't need to purge THAT often, it's just a maintenance issue.
941
+		// to keep the table from getting out of control.
942
+		if (mt_rand(1, 100) < 20)
943
+		{
944
+			$this->ci->login_model->purgeOldRememberTokens();
945
+		}
946
+	}
947
+
948
+	//--------------------------------------------------------------------
949
+
950
+	/**
951
+	 * Sets the headers to ensure that pages are not cached when a user
952
+	 * is logged in, helping to protect against logging out and then
953
+	 * simply hitting the Back button on the browser and getting private
954
+	 * information because the page was loaded from cache.
955
+	 */
956
+	protected function setHeaders()
957
+	{
958
+		$this->ci->output->set_header('Cache-Control: no-store, no-cache, must-revalidate');
959
+		$this->ci->output->set_header('Cache-Control: post-check=0, pre-check=0');
960
+		$this->ci->output->set_header('Pragma: no-cache');
961
+	}
962
+
963
+	//--------------------------------------------------------------------
964 964
 
965 965
 
966 966
 }
Please login to merge, or discard this patch.
Spacing   +59 added lines, -59 removed lines patch added patch discarded remove patch
@@ -62,21 +62,21 @@  discard block
 block discarded – undo
62 62
 
63 63
     //--------------------------------------------------------------------
64 64
 
65
-    public function __construct( $ci=null )
65
+    public function __construct($ci = null)
66 66
     {
67 67
         if ($ci)
68 68
         {
69
-            $this->ci= $ci;
69
+            $this->ci = $ci;
70 70
         }
71 71
         else
72 72
         {
73
-            $this->ci =& get_instance();
73
+            $this->ci = & get_instance();
74 74
         }
75 75
 
76 76
         // Get our compatibility password file loaded up.
77
-        if (! function_exists('password_hash'))
77
+        if ( ! function_exists('password_hash'))
78 78
         {
79
-            require_once dirname(__FILE__) .'password.php';
79
+            require_once dirname(__FILE__).'password.php';
80 80
         }
81 81
 
82 82
         if (empty($this->ci->session))
@@ -101,11 +101,11 @@  discard block
 block discarded – undo
101 101
      * @param bool  $remember
102 102
      * @return bool|mixed
103 103
      */
104
-    public function login($credentials, $remember=false)
104
+    public function login($credentials, $remember = false)
105 105
     {
106 106
         $user = $this->validate($credentials, true);
107 107
 
108
-        if (! $user)
108
+        if ( ! $user)
109 109
         {
110 110
             $this->user = null;
111 111
             return $user;
@@ -135,7 +135,7 @@  discard block
 block discarded – undo
135 135
      * @param bool $return_user
136 136
      * @return mixed
137 137
      */
138
-    public function validate($credentials, $return_user=false)
138
+    public function validate($credentials, $return_user = false)
139 139
     {
140 140
         // Can't validate without a password.
141 141
         if (empty($credentials['password']) || count($credentials) < 2)
@@ -155,7 +155,7 @@  discard block
 block discarded – undo
155 155
         }
156 156
 
157 157
         // Ensure that the fields are allowed validation fields
158
-        if (! in_array(key($credentials), config_item('auth.valid_fields')) )
158
+        if ( ! in_array(key($credentials), config_item('auth.valid_fields')))
159 159
         {
160 160
             $this->error = lang('auth.invalid_credentials');
161 161
             return false;
@@ -163,7 +163,7 @@  discard block
 block discarded – undo
163 163
 
164 164
         // We do not want to force case-sensitivity on things
165 165
         // like username and email for usability sake.
166
-        if (! empty($credentials['email']))
166
+        if ( ! empty($credentials['email']))
167 167
         {
168 168
             $credentials['email'] = strtolower($credentials['email']);
169 169
         }
@@ -178,7 +178,7 @@  discard block
 block discarded – undo
178 178
 
179 179
         // If throttling time is above zero, we can't allow
180 180
         // logins now.
181
-        $time = (int)$this->isThrottled($user);
181
+        $time = (int) $this->isThrottled($user);
182 182
         if ($time > 0)
183 183
         {
184 184
             $this->error = sprintf(lang('auth.throttled'), $time);
@@ -188,7 +188,7 @@  discard block
 block discarded – undo
188 188
         // Get ip address
189 189
         $ip_address = $this->ci->input->ip_address();
190 190
 
191
-        if (! $user)
191
+        if ( ! $user)
192 192
         {
193 193
             $this->error = lang('auth.invalid_user');
194 194
             $this->ci->login_model->recordLoginAttempt($ip_address);
@@ -196,9 +196,9 @@  discard block
 block discarded – undo
196 196
         }
197 197
 
198 198
         // Now, try matching the passwords.
199
-        $result =  password_verify($password, $user['password_hash']);
199
+        $result = password_verify($password, $user['password_hash']);
200 200
 
201
-        if (! $result)
201
+        if ( ! $result)
202 202
         {
203 203
             $this->error = lang('auth.invalid_password');
204 204
             $this->ci->login_model->recordLoginAttempt($ip_address, $user['id']);
@@ -209,7 +209,7 @@  discard block
 block discarded – undo
209 209
         // This would be due to the hash algorithm or hash
210 210
         // cost changing since the last time that a user
211 211
         // logged in.
212
-        if (password_needs_rehash($user['password_hash'], PASSWORD_DEFAULT, ['cost' => config_item('auth.hash_cost')] ))
212
+        if (password_needs_rehash($user['password_hash'], PASSWORD_DEFAULT, ['cost' => config_item('auth.hash_cost')]))
213 213
         {
214 214
             $new_hash = Password::hashPassword($password);
215 215
             $this->user_model->skip_validation()
@@ -218,7 +218,7 @@  discard block
 block discarded – undo
218 218
         }
219 219
 
220 220
         // Is the user active?
221
-        if (! $user['active'])
221
+        if ( ! $user['active'])
222 222
         {
223 223
             $this->error = lang('auth.inactive_account');
224 224
             return false;
@@ -238,7 +238,7 @@  discard block
 block discarded – undo
238 238
     {
239 239
         $this->ci->load->helper('cookie');
240 240
 
241
-        if (! Events::trigger('beforeLogout', [$this->user]))
241
+        if ( ! Events::trigger('beforeLogout', [$this->user]))
242 242
         {
243 243
             return false;
244 244
         }
@@ -247,10 +247,10 @@  discard block
 block discarded – undo
247 247
         // available for flash messages, etc.
248 248
         if (isset($_SESSION))
249 249
         {
250
-            foreach ( $_SESSION as $key => $value )
250
+            foreach ($_SESSION as $key => $value)
251 251
             {
252
-                $_SESSION[ $key ] = NULL;
253
-                unset( $_SESSION[ $key ] );
252
+                $_SESSION[$key] = NULL;
253
+                unset($_SESSION[$key]);
254 254
             }
255 255
         }
256 256
         // Also, regenerate the session ID for a touch of added safety.
@@ -276,7 +276,7 @@  discard block
 block discarded – undo
276 276
     {
277 277
         $id = $this->ci->session->userdata('logged_in');
278 278
 
279
-        if (! $id)
279
+        if ( ! $id)
280 280
         {
281 281
             return false;
282 282
         }
@@ -284,10 +284,10 @@  discard block
 block discarded – undo
284 284
         // If the user var hasn't been filled in, we need to fill it in,
285 285
         // since this method will typically be used as the only method
286 286
         // to determine whether a user is logged in or not.
287
-        if (! $this->user)
287
+        if ( ! $this->user)
288 288
         {
289 289
             $this->user = $this->user_model->as_array()
290
-                                           ->find_by('id', (int)$id);
290
+                                           ->find_by('id', (int) $id);
291 291
 
292 292
             if (empty($this->user))
293 293
             {
@@ -311,14 +311,14 @@  discard block
 block discarded – undo
311 311
      */
312 312
     public function viaRemember()
313 313
     {
314
-        if (! config_item('auth.allow_remembering'))
314
+        if ( ! config_item('auth.allow_remembering'))
315 315
         {
316 316
             return false;
317 317
         }
318 318
 
319 319
         $this->ci->load->helper('cookie');
320 320
 
321
-        if (! $token = get_cookie('remember'))
321
+        if ( ! $token = get_cookie('remember'))
322 322
         {
323 323
             return false;
324 324
         }
@@ -327,7 +327,7 @@  discard block
 block discarded – undo
327 327
         $query = $this->ci->db->where('hash', $this->ci->login_model->hashRememberToken($token))
328 328
                               ->get('auth_tokens');
329 329
 
330
-        if (! $query->num_rows())
330
+        if ( ! $query->num_rows())
331 331
         {
332 332
             return false;
333 333
         }
@@ -365,16 +365,16 @@  discard block
 block discarded – undo
365 365
         // If via email, we need to generate a hash
366 366
         $this->ci->load->helper('string');
367 367
         $token = random_string('alnum', 24);
368
-        $user_data['activate_hash'] = hash('sha1', config_item('auth.salt') . $token);
368
+        $user_data['activate_hash'] = hash('sha1', config_item('auth.salt').$token);
369 369
 
370 370
         // Email should NOT be case sensitive.
371
-        if (! empty($user_data['email']))
371
+        if ( ! empty($user_data['email']))
372 372
         {
373 373
             $user_data['email'] = strtolower($user_data['email']);
374 374
         }
375 375
 
376 376
         // Save the user
377
-        if (! $id = $this->user_model->insert($user_data))
377
+        if ( ! $id = $this->user_model->insert($user_data))
378 378
         {
379 379
             $this->error = $this->user_model->error();
380 380
             return false;
@@ -405,25 +405,25 @@  discard block
 block discarded – undo
405 405
     {
406 406
         $post = [
407 407
             'email'         => $data['email'],
408
-            'activate_hash' => hash('sha1', config_item('auth.salt') . $data['code'])
408
+            'activate_hash' => hash('sha1', config_item('auth.salt').$data['code'])
409 409
         ];
410 410
 
411 411
         $user = $this->user_model->where($post)
412 412
                                  ->first();
413 413
 
414
-        if (! $user) {
414
+        if ( ! $user) {
415 415
             $this->error = $this->user_model->error() ? $this->user_model->error() : lang('auth.activate_no_user');
416 416
 
417 417
             return false;
418 418
         }
419 419
 
420
-        if (! $this->user_model->update($user->id, ['active' => 1, 'activate_hash' => null]))
420
+        if ( ! $this->user_model->update($user->id, ['active' => 1, 'activate_hash' => null]))
421 421
         {
422 422
             $this->error = $this->user_model->error();
423 423
             return false;
424 424
         }
425 425
 
426
-        Events::trigger('didActivate', [(array)$user]);
426
+        Events::trigger('didActivate', [(array) $user]);
427 427
 
428 428
         return true;
429 429
     }
@@ -438,7 +438,7 @@  discard block
 block discarded – undo
438 438
      */
439 439
     public function activateUserById($id)
440 440
     {
441
-        if (! $this->user_model->update($id, ['active' => 1, 'activate_hash' => null]))
441
+        if ( ! $this->user_model->update($id, ['active' => 1, 'activate_hash' => null]))
442 442
         {
443 443
             $this->error = $this->user_model->error();
444 444
             return false;
@@ -470,12 +470,12 @@  discard block
 block discarded – undo
470 470
      */
471 471
     public function id()
472 472
     {
473
-        if (! is_array($this->user) || empty($this->user['id']))
473
+        if ( ! is_array($this->user) || empty($this->user['id']))
474 474
         {
475 475
             return null;
476 476
         }
477 477
 
478
-        return (int)$this->user['id'];
478
+        return (int) $this->user['id'];
479 479
     }
480 480
 
481 481
     //--------------------------------------------------------------------
@@ -492,7 +492,7 @@  discard block
 block discarded – undo
492 492
     public function isThrottled($user)
493 493
     {
494 494
         // Not throttling? Get outta here!
495
-        if (! config_item('auth.allow_throttling'))
495
+        if ( ! config_item('auth.allow_throttling'))
496 496
         {
497 497
             return false;
498 498
         }
@@ -560,7 +560,7 @@  discard block
 block discarded – undo
560 560
         {
561 561
             $this->error = lang('auth.bruteBan_notice');
562 562
 
563
-            $ban_time = 60 * 15;    // 15 minutes
563
+            $ban_time = 60 * 15; // 15 minutes
564 564
             $_SESSION['bruteBan'] = time() + $ban_time;
565 565
             return $ban_time;
566 566
         }
@@ -608,7 +608,7 @@  discard block
 block discarded – undo
608 608
         // Is it a valid user?
609 609
         $user = $this->user_model->find_by('email', $email);
610 610
 
611
-        if (! $user)
611
+        if ( ! $user)
612 612
         {
613 613
             $this->error = lang('auth.invalid_email');
614 614
             return false;
@@ -617,17 +617,17 @@  discard block
 block discarded – undo
617 617
         // Generate/store our codes
618 618
         $this->ci->load->helper('string');
619 619
         $token = random_string('alnum', 24);
620
-        $hash = hash('sha1', config_item('auth.salt') .$token);
620
+        $hash = hash('sha1', config_item('auth.salt').$token);
621 621
 
622 622
         $result = $this->user_model->update($user->id, ['reset_hash' => $hash]);
623 623
 
624
-        if (! $result)
624
+        if ( ! $result)
625 625
         {
626 626
             $this->error = $this->user_model->error();
627 627
             return false;
628 628
         }
629 629
 
630
-        Events::trigger('didRemindUser', [(array)$user, $token]);
630
+        Events::trigger('didRemindUser', [(array) $user, $token]);
631 631
 
632 632
         return true;
633 633
     }
@@ -654,10 +654,10 @@  discard block
 block discarded – undo
654 654
         }
655 655
 
656 656
         // Generate a hash to match against the table.
657
-        $reset_hash = hash('sha1', config_item('auth.salt') .$credentials['code']);
657
+        $reset_hash = hash('sha1', config_item('auth.salt').$credentials['code']);
658 658
         unset($credentials['code']);
659 659
 
660
-        if (! empty($credentials['email']))
660
+        if ( ! empty($credentials['email']))
661 661
         {
662 662
             $credentials['email'] = strtolower($credentials['email']);
663 663
         }
@@ -669,7 +669,7 @@  discard block
 block discarded – undo
669 669
 
670 670
         // If throttling time is above zero, we can't allow
671 671
         // logins now.
672
-        $time = (int)$this->isThrottled($user);
672
+        $time = (int) $this->isThrottled($user);
673 673
         if ($time > 0)
674 674
         {
675 675
             $this->error = sprintf(lang('auth.throttled'), $time);
@@ -679,7 +679,7 @@  discard block
 block discarded – undo
679 679
         // Get ip address
680 680
         $ip_address = $this->ci->input->ip_address();
681 681
 
682
-        if (! $user)
682
+        if ( ! $user)
683 683
         {
684 684
             $this->error = lang('auth.reset_no_user');
685 685
             $this->ci->login_model->recordLoginAttempt($ip_address);
@@ -701,7 +701,7 @@  discard block
 block discarded – undo
701 701
             'reset_hash'   => null
702 702
         ];
703 703
 
704
-        if (! $this->user_model->update($user['id'], $data))
704
+        if ( ! $this->user_model->update($user['id'], $data))
705 705
         {
706 706
             $this->error = $this->user_model->error();
707 707
             return false;
@@ -726,7 +726,7 @@  discard block
 block discarded – undo
726 726
      * @param null $message
727 727
      * @return mixed
728 728
      */
729
-    public function changeStatus($newStatus, $message=null)
729
+    public function changeStatus($newStatus, $message = null)
730 730
     {
731 731
         // todo actually record new users status!
732 732
     }
@@ -743,14 +743,14 @@  discard block
 block discarded – undo
743 743
      * @param bool $allow_any_parent
744 744
      * @return mixed
745 745
      */
746
-    public function useModel($model, $allow_any_parent=false)
746
+    public function useModel($model, $allow_any_parent = false)
747 747
     {
748
-        if (! $allow_any_parent && get_parent_class($model) != 'Myth\Models\CIDbModel')
748
+        if ( ! $allow_any_parent && get_parent_class($model) != 'Myth\Models\CIDbModel')
749 749
         {
750 750
             throw new \RuntimeException('Models passed into LocalAuthenticate MUST extend Myth\Models\CIDbModel');
751 751
         }
752 752
 
753
-        $this->user_model =& $model;
753
+        $this->user_model = & $model;
754 754
 
755 755
         return $this;
756 756
     }
@@ -820,7 +820,7 @@  discard block
 block discarded – undo
820 820
      */
821 821
     protected function rememberUser($user)
822 822
     {
823
-        if (! config_item('auth.allow_remembering'))
823
+        if ( ! config_item('auth.allow_remembering'))
824 824
         {
825 825
             log_message('debug', 'Auth library set to refuse "Remember Me" functionality.');
826 826
             return false;
@@ -839,13 +839,13 @@  discard block
 block discarded – undo
839 839
      * @param null $token
840 840
      * @return mixed
841 841
      */
842
-    protected function refreshRememberCookie($user, $token=null)
842
+    protected function refreshRememberCookie($user, $token = null)
843 843
     {
844 844
         $this->ci->load->helper('cookie');
845 845
 
846 846
         // If a token is passed in, we know we're removing the
847 847
         // old one.
848
-        if (! empty($token))
848
+        if ( ! empty($token))
849 849
         {
850 850
             $this->invalidateRememberCookie($user['email'], $token);
851 851
         }
@@ -855,7 +855,7 @@  discard block
 block discarded – undo
855 855
         // Save the token to the database.
856 856
         $data = [
857 857
             'email'   => $user['email'],
858
-            'hash'    => sha1(config_item('auth.salt') . $new_token),
858
+            'hash'    => sha1(config_item('auth.salt').$new_token),
859 859
             'created' => date('Y-m-d H:i:s')
860 860
         ];
861 861
 
@@ -863,13 +863,13 @@  discard block
 block discarded – undo
863 863
 
864 864
         // Create the cookie
865 865
         set_cookie(
866
-            'remember',                             // Cookie Name
867
-            $new_token,                             // Value
868
-            config_item('auth.remember_length'),    // # Seconds until it expires
866
+            'remember', // Cookie Name
867
+            $new_token, // Value
868
+            config_item('auth.remember_length'), // # Seconds until it expires
869 869
             config_item('cookie_domain'),
870 870
             config_item('cookie_path'),
871 871
             config_item('cookie_prefix'),
872
-            false,                                  // Only send over HTTPS?
872
+            false, // Only send over HTTPS?
873 873
             true                                    // Hide from Javascript?
874 874
         );
875 875
 
Please login to merge, or discard this patch.