Passed
Branch development (176841)
by Elk
15:26
created

UserSettings   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 145
Duplicated Lines 0 %

Test Coverage

Coverage 7.89%

Importance

Changes 3
Bugs 0 Features 0
Metric Value
eloc 30
dl 0
loc 145
ccs 3
cts 38
cp 0.0789
rs 10
c 3
b 0
f 0
wmc 15

8 Methods

Rating   Name   Duplication   Size   Complexity  
A updateLastLogin() 0 3 1
A validatePassword() 0 11 2
A updateTotalTimeLoggedIn() 0 3 1
A rehashPassword() 0 21 3
A getActivationStatus() 0 3 2
A initHasher() 0 16 2
A updatePassword() 0 6 1
A fixSalt() 0 11 3
1
<?php
2
3
/**
4
 * @package   ElkArte Forum
5
 * @copyright ElkArte Forum contributors
6
 * @license   BSD http://opensource.org/licenses/BSD-3-Clause (see accompanying LICENSE.txt file)
7
 *
8
 * This file contains code covered by:
9
 * copyright:	2011 Simple Machines (http://www.simplemachines.org)
10
 *
11
 * @version 2.0 dev
12
 *
13
 */
14
15
namespace ElkArte;
16
17
/**
18
 * This class holds all the data belonging to a certain member.
19
 */
20
class UserSettings extends \ElkArte\ValuesContainerReadOnly
21
{
22
	/**
23
	 * The object used to create hashes
24
	 *
25
	 * @var \PasswordHash
0 ignored issues
show
Bug introduced by
The type PasswordHash was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
26
	 */
27
	protected $hasher = null;
28
29
	/**
30
	 * Sets last_login to the current time
31
	 */
32
	public function updateLastLogin()
33
	{
34
		$this->data['last_login'] = time();
35
	}
36
37
	/**
38
	 * Changes the password to the provided one in $this->settings
39
	 * Doesn't actually change the database.
40
	 *
41
	 * @param string $password The hashed password
42 2
	 */
43
	public function updatePassword($password)
44 2
	{
45 2
		$this->data['passwd'] = $password;
46
47
		$tokenizer = new \ElkArte\TokenHash();
48
		$this->data['password_salt'] = $tokenizer->generate_hash(UserSettingsLoader::HASH_LENGTH);
49
	}
50
51
	/**
52
	 * Updates total_time_logged_in
53
	 *
54
	 * @param int $increment_offset
55
	 */
56
	public function updateTotalTimeLoggedIn($increment_offset)
57
	{
58
		$this->data['total_time_logged_in'] += time() - $increment_offset;
59
	}
60
61
	/**
62
	 * Fixes the password salt if not present or if it needs to be changed
63
	 *
64
	 * @param bool $force - If true the salt is changed no matter what
65
	 */
66
	public function fixSalt($force = false)
67
	{
68
		// Correct password, but they've got no salt; fix it!
69
		if ($this->data['password_salt'] === '' || $force === true)
70
		{
71
			$tokenizer = new \ElkArte\TokenHash();
72
73
			$this->data['password_salt'] = $tokenizer->generate_hash(UserSettingsLoader::HASH_LENGTH);
74
			return true;
75
		}
76
		return false;
77
	}
78
79
	/**
80
	 * Updates total_time_logged_in
81
	 *
82
	 * @param int $increment_offset
83
	 */
84
	public function getActivationStatus($strip_ban = true)
0 ignored issues
show
Unused Code introduced by
The parameter $strip_ban is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

84
	public function getActivationStatus(/** @scrutinizer ignore-unused */ $strip_ban = true)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
85
	{
86
		return $this->is_activated > UserSettingsLoader::BAN_OFFSET ? $this->is_activated - UserSettingsLoader::BAN_OFFSET : $this->is_activated;
0 ignored issues
show
Bug Best Practice introduced by
The property is_activated does not exist on ElkArte\UserSettings. Since you implemented __get, consider adding a @property annotation.
Loading history...
87
	}
88
89
	/**
90
	 * Repeat the hashing of the password
91
	 *
92
	 * @param string $password The plain text (or sha256 hashed) password
93
	 * @return bool|null Returns false if something fails
94
	 */
95
	public function rehashPassword($password)
96
	{
97
		$this->initHasher();
98
99
		// If the password is not 64 characters, lets make it a (SHA-256)
100
		if (strlen($password) !== 64)
101
		{
102
			$password = hash('sha256', \ElkArte\Util::strtolower($this->member_name) . un_htmlspecialchars($password));
0 ignored issues
show
Bug Best Practice introduced by
The property member_name does not exist on ElkArte\UserSettings. Since you implemented __get, consider adding a @property annotation.
Loading history...
103
		}
104
105
		$passhash = $this->hasher->HashPassword($password);
106
107
		// Something is not right, we can not generate a valid hash that's <20 characters
108
		if (strlen($passhash) < 20)
109
		{
110
			// @todo here we should throw an exception
111
			return false;
112
		}
113
		else
114
		{
115
			$this->settings->updatePassword($passhash);
0 ignored issues
show
Bug introduced by
The method updatePassword() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

115
			$this->settings->/** @scrutinizer ignore-call */ 
116
                    updatePassword($passhash);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
Bug Best Practice introduced by
The property settings does not exist on ElkArte\UserSettings. Since you implemented __get, consider adding a @property annotation.
Loading history...
116
		}
117
	}
118
119
	/**
120
	 * Initialize the password hashing object
121
	 */
122
	protected function initHasher()
123
	{
124
		if ($this->hasher === null)
125
		{
126
			// Our hashing controller
127
			require_once(EXTDIR . '/PasswordHash.php');
128
129
			// Base-2 logarithm of the iteration count used for password stretching, the
130
			// higher the number the more secure and CPU time consuming
131
			$hash_cost_log2 = 10;
132
133
			// Do we require the hashes to be portable to older systems (less secure)?
134
			$hash_portable = false;
135
136
			// Get an instance of the hasher
137
			$this->hasher = new \PasswordHash($hash_cost_log2, $hash_portable);
138
		}
139
	}
140
141
	/**
142
	 * Checks whether a password meets the current forum rules
143
	 *
144
	 * What it does:
145
	 *
146
	 * - called when registering/choosing a password.
147
	 * - checks the password obeys the current forum settings for password strength.
148
	 * - if password checking is enabled, will check that none of the words in restrict_in appear in the password.
149
	 * - returns an error identifier if the password is invalid.
150
	 *
151
	 * @param string $password
152
	 * @return bool true or false
153
	 */
154
	public function validatePassword($password)
155
	{
156
		$this->initHasher();
157
158
		// If the password is not 64 characters, lets make it a (SHA-256)
159
		if (strlen($password) !== 64)
160
		{
161
			$password = hash('sha256', \ElkArte\Util::strtolower($this->member_name) . un_htmlspecialchars($password));
0 ignored issues
show
Bug Best Practice introduced by
The property member_name does not exist on ElkArte\UserSettings. Since you implemented __get, consider adding a @property annotation.
Loading history...
162
		}
163
164
		return (bool) $this->hasher->CheckPassword($password, $this->passwd);
0 ignored issues
show
Bug Best Practice introduced by
The property passwd does not exist on ElkArte\UserSettings. Since you implemented __get, consider adding a @property annotation.
Loading history...
165
	}
166
}
167