Passed
Push — master ( c0a3a7...3b84a4 )
by Jeroen
58:51
created

uservalidationbyemail_init()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 40
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 17
nc 1
nop 0
dl 0
loc 40
ccs 17
cts 17
cp 1
crap 1
rs 8.8571
c 0
b 0
f 0
1
<?php
2
/**
3
 * Email user validation plugin.
4
 * Non-admin accounts are invalid until their email address is confirmed.
5
 *
6
 * @package Elgg.Core.Plugin
7
 * @subpackage UserValidationByEmail
8
 */
9
10
/**
11
 * User validation by email init
12
 *
13
 * @return void
14
 */
15
function uservalidationbyemail_init() {
16
17 31
	require_once dirname(__FILE__) . '/lib/functions.php';
18
19
	// Register page handler to validate users
20
	// This doesn't need to be an action because security is handled by the validation codes.
21 31
	elgg_register_page_handler('uservalidationbyemail', 'uservalidationbyemail_page_handler');
0 ignored issues
show
Deprecated Code introduced by
The function elgg_register_page_handler() has been deprecated: 3.0 ( Ignorable by Annotation )

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

21
	/** @scrutinizer ignore-deprecated */ elgg_register_page_handler('uservalidationbyemail', 'uservalidationbyemail_page_handler');

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
22
23
	// mark users as unvalidated and disable when they register
24 31
	elgg_register_plugin_hook_handler('register', 'user', 'uservalidationbyemail_disable_new_user');
25
26
	// forward to uservalidationbyemail/emailsent page after register
27 31
	elgg_register_plugin_hook_handler('response', 'action:register', 'uservalidationbyemail_after_registration_url');
28
29
	// canEdit override to allow not logged in code to disable a user
30 31
	elgg_register_plugin_hook_handler('permissions_check', 'user', 'uservalidationbyemail_allow_new_user_can_edit');
31
32
	// prevent users from logging in if they aren't validated
33 31
	register_pam_handler('uservalidationbyemail_check_auth_attempt', "required");
34
35
	// prevent the engine from logging in users via login()
36 31
	elgg_register_event_handler('login:before', 'user', 'uservalidationbyemail_check_manual_login');
37
38
	// make admin users always validated
39 31
	elgg_register_event_handler('make_admin', 'user', 'uservalidationbyemail_validate_new_admin_user');
40
41
	// register Walled Garden public pages
42 31
	elgg_register_plugin_hook_handler('public_pages', 'walled_garden', 'uservalidationbyemail_public_pages');
43
44
	// admin interface to manually validate users
45 31
	elgg_register_menu_item('page', [
46 31
		'name' => 'users:unvalidated',
47 31
		'text' => elgg_echo('admin:users:unvalidated'),
48 31
		'href' => 'admin/users/unvalidated',
49 31
		'section' => 'administer',
50 31
		'parent_name' => 'users',
51 31
		'context' => 'admin',
52
	]);
53
	
54 31
	elgg_extend_view('admin.css', 'uservalidationbyemail/css');
55 31
}
56
57
/**
58
 * Disables a user upon registration
59
 *
60
 * @param string $hook   'register'
61
 * @param string $type   'user'
62
 * @param bool   $value  current return value
63
 * @param array  $params supplied params
64
 *
65
 * @return void
66
 */
67
function uservalidationbyemail_disable_new_user($hook, $type, $value, $params) {
2 ignored issues
show
Unused Code introduced by
The parameter $hook 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

67
function uservalidationbyemail_disable_new_user(/** @scrutinizer ignore-unused */ $hook, $type, $value, $params) {

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...
Unused Code introduced by
The parameter $type 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

67
function uservalidationbyemail_disable_new_user($hook, /** @scrutinizer ignore-unused */ $type, $value, $params) {

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...
68
	
69
	$user = elgg_extract('user', $params);
70
	// no clue what's going on, so don't react.
71
	if (!$user instanceof ElggUser) {
72
		return;
73
	}
74
75
	// another plugin is requesting that registration be terminated
76
	// no need for uservalidationbyemail
77
	if (!$value) {
78
		return;
79
	}
80
81
	// has the user already been validated?
82
	if ($user->isValidated()) {
83
		return;
84
	}
85
86
	// disable user to prevent showing up on the site
87
	// set context so our canEdit() override works
88
	elgg_push_context('uservalidationbyemail_new_user');
89
	$hidden_entities = access_show_hidden_entities(true);
90
91
	// Don't do a recursive disable.  Any entities owned by the user at this point
92
	// are products of plugins that hook into create user and might need
93
	// access to the entities.
94
	// @todo That ^ sounds like a specific case...would be nice to track it down...
95
	$user->disable('uservalidationbyemail_new_user', false);
96
97
	// set user as unvalidated and send out validation email
98
	$user->setValidationStatus(false);
99
	uservalidationbyemail_request_validation($user->guid);
100
101
	elgg_pop_context();
102
	access_show_hidden_entities($hidden_entities);
103
}
104
105
/**
106
 * Override the URL to be forwarded after registration
107
 *
108
 * @param string                     $hook   'response'
109
 * @param string                     $type   'action:register'
110
 * @param \Elgg\Http\ResponseBuilder $value  Current response
111
 * @param array                      $params Additional params
112
 *
113
 * @return void|\Elgg\Http\ResponseBuilder
114
 */
115
function uservalidationbyemail_after_registration_url($hook, $type, $value, $params) {
3 ignored issues
show
Unused Code introduced by
The parameter $hook 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

115
function uservalidationbyemail_after_registration_url(/** @scrutinizer ignore-unused */ $hook, $type, $value, $params) {

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...
Unused Code introduced by
The parameter $type 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

115
function uservalidationbyemail_after_registration_url($hook, /** @scrutinizer ignore-unused */ $type, $value, $params) {

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...
Unused Code introduced by
The parameter $params 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

115
function uservalidationbyemail_after_registration_url($hook, $type, $value, /** @scrutinizer ignore-unused */ $params) {

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...
116
	$session = elgg_get_session();
117
	$email = $session->get('emailsent', '');
118
	if ($email) {
119
		$value->setForwardURL(elgg_normalize_url('uservalidationbyemail/emailsent'));
120
		return $value;
121
	}
122
}
123
124
/**
125
 * Override the canEdit() call for if we're in the context of registering a new user.
126
 *
127
 * @param string $hook   'permissions_check'
128
 * @param string $type   'user'
129
 * @param bool   $value  current return value
130
 * @param array  $params supplied params
131
 *
132
 * @return void|true
133
 */
134
function uservalidationbyemail_allow_new_user_can_edit($hook, $type, $value, $params) {
3 ignored issues
show
Unused Code introduced by
The parameter $type 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

134
function uservalidationbyemail_allow_new_user_can_edit($hook, /** @scrutinizer ignore-unused */ $type, $value, $params) {

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...
Unused Code introduced by
The parameter $hook 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

134
function uservalidationbyemail_allow_new_user_can_edit(/** @scrutinizer ignore-unused */ $hook, $type, $value, $params) {

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...
Unused Code introduced by
The parameter $value 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

134
function uservalidationbyemail_allow_new_user_can_edit($hook, $type, /** @scrutinizer ignore-unused */ $value, $params) {

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...
135
	
136
	// $params['user'] is the user to check permissions for.
137
	// we want the entity to check, which is a user.
138 92
	$user = elgg_extract('entity', $params);
139 92
	if (!($user instanceof ElggUser)) {
140
		return;
141
	}
142
143 92
	$context = elgg_get_context();
144 92
	if ($context == 'uservalidationbyemail_new_user' || $context == 'uservalidationbyemail_validate_user') {
145
		return true;
146
	}
147 92
}
148
149
/**
150
 * Checks if an account is validated
151
 *
152
 * @param array $credentials The username and password
153
 *
154
 * @return void
155
 */
156
function uservalidationbyemail_check_auth_attempt($credentials) {
157
158 9
	if (!isset($credentials['username'])) {
159 2
		return;
160
	}
161
162 7
	$username = $credentials['username'];
163
164
	// See if the user exists and isn't validated
165 7
	$access_status = access_show_hidden_entities(true);
166
	
167
	// check if logging in with email address
168 7
	if (strpos($username, '@') !== false) {
169
		$users = get_user_by_email($username);
170
		if ($users) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $users of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
171
			$username = $users[0]->username;
172
		}
173
	}
174
175 7
	$user = get_user_by_username($username);
176 7
	if ($user && isset($user->validated) && !$user->validated) {
177
		// show an error and resend validation email
178
		uservalidationbyemail_request_validation($user->guid);
179
		access_show_hidden_entities($access_status);
180
		throw new LoginException(elgg_echo('uservalidationbyemail:login:fail'));
181
	}
182
183 7
	access_show_hidden_entities($access_status);
184 7
}
185
186
/**
187
 * Checks sent passed validation code and user guids and validates the user.
188
 *
189
 * @param array $page URL segments
190
 *
191
 * @return bool
192
 */
193
function uservalidationbyemail_page_handler($page) {
194
	
195
	switch ($page[0]) {
196
		case 'confirm':
197
			echo elgg_view_resource("uservalidationbyemail/confirm");
198
			return true;
199
		case 'emailsent':
200
			echo elgg_view_resource("uservalidationbyemail/emailsent");
201
			return true;
202
		default:
203
			forward('', '404');
204
			return false;
205
	}
206
}
207
208
/**
209
 * Make sure any admin users are automatically validated
210
 *
211
 * @param string   $event 'make_admin'
212
 * @param string   $type  'user'
213
 * @param ElggUser $user  the user
214
 *
215
 * @return void
216
 */
217
function uservalidationbyemail_validate_new_admin_user($event, $type, $user) {
2 ignored issues
show
Unused Code introduced by
The parameter $event 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

217
function uservalidationbyemail_validate_new_admin_user(/** @scrutinizer ignore-unused */ $event, $type, $user) {

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...
Unused Code introduced by
The parameter $type 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

217
function uservalidationbyemail_validate_new_admin_user($event, /** @scrutinizer ignore-unused */ $type, $user) {

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...
218 6
	if ($user instanceof ElggUser && !$user->isValidated()) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $user->isValidated() of type null|boolean is loosely compared to false; this is ambiguous if the boolean can be false. You might want to explicitly use !== null instead.

If an expression can have both false, and null as possible values. It is generally a good practice to always use strict comparison to clearly distinguish between those two values.

$a = canBeFalseAndNull();

// Instead of
if ( ! $a) { }

// Better use one of the explicit versions:
if ($a !== null) { }
if ($a !== false) { }
if ($a !== null && $a !== false) { }
Loading history...
219 6
		$user->setValidationStatus(true, 'admin_user');
220
	}
221 6
}
222
223
/**
224
 * Registers public pages to allow in the case walled garden has been enabled
225
 *
226
 * @param string $hook         'public_pages'
227
 * @param string $type         'walled_garden'
228
 * @param array  $return_value current return value
229
 * @param mixed  $params       supplied params
230
 *
231
 * @return array
232
 */
233
function uservalidationbyemail_public_pages($hook, $type, $return_value, $params) {
3 ignored issues
show
Unused Code introduced by
The parameter $params 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

233
function uservalidationbyemail_public_pages($hook, $type, $return_value, /** @scrutinizer ignore-unused */ $params) {

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...
Unused Code introduced by
The parameter $hook 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

233
function uservalidationbyemail_public_pages(/** @scrutinizer ignore-unused */ $hook, $type, $return_value, $params) {

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...
Unused Code introduced by
The parameter $type 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

233
function uservalidationbyemail_public_pages($hook, /** @scrutinizer ignore-unused */ $type, $return_value, $params) {

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...
234
	$return_value[] = 'uservalidationbyemail/confirm';
235
	$return_value[] = 'uservalidationbyemail/emailsent';
236
	return $return_value;
237
}
238
239
/**
240
 * Prevent a manual code login with login()
241
 *
242
 * @param string   $event 'login:before'
243
 * @param string   $type  'user'
244
 * @param ElggUser $user  the user
245
 *
246
 * @return void
247
 *
248
 * @throws LoginException
249
 */
250
function uservalidationbyemail_check_manual_login($event, $type, $user) {
2 ignored issues
show
Unused Code introduced by
The parameter $event 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

250
function uservalidationbyemail_check_manual_login(/** @scrutinizer ignore-unused */ $event, $type, $user) {

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...
Unused Code introduced by
The parameter $type 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

250
function uservalidationbyemail_check_manual_login($event, /** @scrutinizer ignore-unused */ $type, $user) {

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...
251
	
252 5
	$access_status = access_show_hidden_entities(true);
253
	
254 5
	if (($user instanceof ElggUser) && !$user->isEnabled() && !$user->validated) {
255
		// send new validation email
256
		uservalidationbyemail_request_validation($user->getGUID());
257
		
258
		// restore hidden entities settings
259
		access_show_hidden_entities($access_status);
260
		
261
		// throw error so we get a nice error message
262
		throw new LoginException(elgg_echo('uservalidationbyemail:login:fail'));
263
	}
264
265 5
	access_show_hidden_entities($access_status);
266 5
}
267
268
return function() {
269 18
	elgg_register_event_handler('init', 'system', 'uservalidationbyemail_init');
270
};
271