Passed
Push — master ( c2d8e3...289151 )
by Jeroen
06:06
created

mod/uservalidationbyemail/start.php (3 issues)

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');
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
	// admin user validation page
33 31
	elgg_register_plugin_hook_handler('register', 'menu:user:unvalidated', '_uservalidationbyemail_user_unvalidated_menu');
34
	elgg_register_plugin_hook_handler('register', 'menu:user:unvalidated:bulk', '_uservalidationbyemail_user_unvalidated_bulk_menu');
35
36 31
	// prevent users from logging in if they aren't validated
37
	register_pam_handler('uservalidationbyemail_check_auth_attempt', "required");
38
39 31
	// prevent the engine from logging in users via login()
40
	elgg_register_event_handler('login:before', 'user', 'uservalidationbyemail_check_manual_login');
41
42 31
	// make admin users always validated
43
	elgg_register_event_handler('make_admin', 'user', 'uservalidationbyemail_validate_new_admin_user');
44
45 31
	// register Walled Garden public pages
46 31
	elgg_register_plugin_hook_handler('public_pages', 'walled_garden', 'uservalidationbyemail_public_pages');
47 31
}
48 31
49 31
/**
50 31
 * Disables a user upon registration
51 31
 *
52
 * @param string $hook   'register'
53
 * @param string $type   'user'
54 31
 * @param bool   $value  current return value
55 31
 * @param array  $params supplied params
56
 *
57
 * @return void
58
 */
59
function uservalidationbyemail_disable_new_user($hook, $type, $value, $params) {
60
	
61
	$user = elgg_extract('user', $params);
62
	// no clue what's going on, so don't react.
63
	if (!$user instanceof ElggUser) {
64
		return;
65
	}
66
67
	// another plugin is requesting that registration be terminated
68
	// no need for uservalidationbyemail
69
	if (!$value) {
70
		return;
71
	}
72
73
	// has the user already been validated?
74
	if ($user->isValidated()) {
75
		return;
76
	}
77
78
	// disable user to prevent showing up on the site
79
	// set context so our canEdit() override works
80
	elgg_push_context('uservalidationbyemail_new_user');
81
	$hidden_entities = access_show_hidden_entities(true);
82
83
	// Don't do a recursive disable.  Any entities owned by the user at this point
84
	// are products of plugins that hook into create user and might need
85
	// access to the entities.
86
	// @todo That ^ sounds like a specific case...would be nice to track it down...
87
	$user->disable('uservalidationbyemail_new_user', false);
88
89
	// set user as unvalidated and send out validation email
90
	$user->setValidationStatus(false);
91
	uservalidationbyemail_request_validation($user->guid);
92
93
	elgg_pop_context();
94
	access_show_hidden_entities($hidden_entities);
95
}
96
97
/**
98
 * Override the URL to be forwarded after registration
99
 *
100
 * @param string                     $hook   'response'
101
 * @param string                     $type   'action:register'
102
 * @param \Elgg\Http\ResponseBuilder $value  Current response
103
 * @param array                      $params Additional params
104
 *
105
 * @return void|\Elgg\Http\ResponseBuilder
106
 */
107
function uservalidationbyemail_after_registration_url($hook, $type, $value, $params) {
3 ignored issues
show
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

107
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...
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

107
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...
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

107
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...
108
	$session = elgg_get_session();
109
	$email = $session->get('emailsent', '');
110
	if ($email) {
111
		$value->setForwardURL(elgg_normalize_url('uservalidationbyemail/emailsent'));
112
		return $value;
113
	}
114
}
115
116
/**
117
 * Override the canEdit() call for if we're in the context of registering a new user.
118
 *
119
 * @param string $hook   'permissions_check'
120
 * @param string $type   'user'
121
 * @param bool   $value  current return value
122
 * @param array  $params supplied params
123
 *
124
 * @return void|true
125
 */
126
function uservalidationbyemail_allow_new_user_can_edit($hook, $type, $value, $params) {
127
	
128
	// $params['user'] is the user to check permissions for.
129
	// we want the entity to check, which is a user.
130
	$user = elgg_extract('entity', $params);
131
	if (!($user instanceof ElggUser)) {
132
		return;
133
	}
134
135
	$context = elgg_get_context();
136
	if ($context == 'uservalidationbyemail_new_user' || $context == 'uservalidationbyemail_validate_user') {
137
		return true;
138 92
	}
139 92
}
140
141
/**
142
 * Checks if an account is validated
143 92
 *
144 92
 * @param array $credentials The username and password
145
 *
146
 * @return void
147 92
 */
148
function uservalidationbyemail_check_auth_attempt($credentials) {
149
150
	if (!isset($credentials['username'])) {
151
		return;
152
	}
153
154
	$username = $credentials['username'];
155
156
	// See if the user exists and isn't validated
157
	$access_status = access_show_hidden_entities(true);
158 9
	
159 2
	// check if logging in with email address
160
	if (strpos($username, '@') !== false) {
161
		$users = get_user_by_email($username);
162 7
		if ($users) {
163
			$username = $users[0]->username;
164
		}
165 7
	}
166
167
	$user = get_user_by_username($username);
168 7
	if ($user && isset($user->validated) && !$user->validated) {
169
		// show an error and resend validation email
170
		uservalidationbyemail_request_validation($user->guid);
171
		access_show_hidden_entities($access_status);
172
		throw new LoginException(elgg_echo('uservalidationbyemail:login:fail'));
173
	}
174
175 7
	access_show_hidden_entities($access_status);
176 7
}
177
178
/**
179
 * Checks sent passed validation code and user guids and validates the user.
180
 *
181
 * @param array $page URL segments
182
 *
183 7
 * @return bool
184 7
 */
185
function uservalidationbyemail_page_handler($page) {
186
	
187
	switch ($page[0]) {
188
		case 'confirm':
189
			echo elgg_view_resource("uservalidationbyemail/confirm");
190
			return true;
191
		case 'emailsent':
192
			echo elgg_view_resource("uservalidationbyemail/emailsent");
193
			return true;
194
		default:
195
			forward('', '404');
196
			return false;
197
	}
198
}
199
200
/**
201
 * Make sure any admin users are automatically validated
202
 *
203
 * @param string   $event 'make_admin'
204
 * @param string   $type  'user'
205
 * @param ElggUser $user  the user
206
 *
207
 * @return void
208
 */
209
function uservalidationbyemail_validate_new_admin_user($event, $type, $user) {
210
	if ($user instanceof ElggUser && !$user->isValidated()) {
211
		$user->setValidationStatus(true, 'admin_user');
212
	}
213
}
214
215
/**
216
 * Registers public pages to allow in the case walled garden has been enabled
217
 *
218 6
 * @param string $hook         'public_pages'
219 6
 * @param string $type         'walled_garden'
220
 * @param array  $return_value current return value
221 6
 * @param mixed  $params       supplied params
222
 *
223
 * @return array
224
 */
225
function uservalidationbyemail_public_pages($hook, $type, $return_value, $params) {
226
	$return_value[] = 'uservalidationbyemail/confirm';
227
	$return_value[] = 'uservalidationbyemail/emailsent';
228
	return $return_value;
229
}
230
231
/**
232
 * Prevent a manual code login with login()
233
 *
234
 * @param string   $event 'login:before'
235
 * @param string   $type  'user'
236
 * @param ElggUser $user  the user
237
 *
238
 * @return void
239
 *
240
 * @throws LoginException
241
 */
242
function uservalidationbyemail_check_manual_login($event, $type, $user) {
243
	
244
	$access_status = access_show_hidden_entities(true);
245
	
246
	if (($user instanceof ElggUser) && !$user->isEnabled() && !$user->validated) {
247
		// send new validation email
248
		uservalidationbyemail_request_validation($user->getGUID());
249
		
250
		// restore hidden entities settings
251
		access_show_hidden_entities($access_status);
252 5
		
253
		// throw error so we get a nice error message
254 5
		throw new LoginException(elgg_echo('uservalidationbyemail:login:fail'));
255
	}
256
257
	access_show_hidden_entities($access_status);
258
}
259
260
/**
261
 * Add a menu item to an unvalidated user
262
 *
263
 * @elgg_plugin_hook register menu:user:unvalidated
264
 *
265 5
 * @param \Elgg\Hook $hook the plugin hook 'register' 'menu:user:unvalidated'
266 5
 *
267
 * @return void|ElggMenuItem[]
268
 *
269 18
 * @since 3.0
270 18
 * @internal
271
 */
272
function _uservalidationbyemail_user_unvalidated_menu(\Elgg\Hook $hook) {
273
	
274
	if (!elgg_is_admin_logged_in()) {
275
		return;
276
	}
277
	
278
	$entity = $hook->getEntityParam();
279
	if (!$entity instanceof ElggUser) {
280
		return;
281
	}
282
	
283
	$return = $hook->getValue();
284
	
285
	$return[] = ElggMenuItem::factory([
286
		'name' => 'uservalidationbyemail:resend',
287
		'text' => elgg_echo('uservalidationbyemail:admin:resend_validation'),
288
		'href' => elgg_http_add_url_query_elements('action/uservalidationbyemail/resend_validation', [
289
			'user_guids[]' => $entity->guid,
290
		]),
291
		'confirm' => elgg_echo('uservalidationbyemail:confirm_resend_validation', [$entity->getDisplayName()]),
292
		'priority' => 100,
293
	]);
294
	
295
	return $return;
296
}
297
298
/**
299
 * Add a menu item to the buld actions for unvalidated users
300
 *
301
 * @elgg_plugin_hook register menu:user:unvalidated:bulk
302
 *
303
 * @param \Elgg\Hook $hook the plugin hook 'register' 'menu:user:unvalidated:bulk'
304
 *
305
 * @return void|ElggMenuItem[]
306
 *
307
 * @since 3.0
308
 * @internal
309
 */
310
function _uservalidationbyemail_user_unvalidated_bulk_menu(\Elgg\Hook $hook) {
311
	
312
	if (!elgg_is_admin_logged_in()) {
313
		return;
314
	}
315
	
316
	$return = $hook->getValue();
317
	
318
	$return[] = ElggMenuItem::factory([
319
		'id' => 'uservalidationbyemail-bulk-resend',
320
		'name' => 'uservalidationbyemail:resend:bulk',
321
		'text' => elgg_echo('uservalidationbyemail:admin:resend_validation'),
322
		'href' => 'action/uservalidationbyemail/resend_validation',
323
		'confirm' => elgg_echo('uservalidationbyemail:confirm_resend_validation_checked'),
324
		'priority' => 100,
325
		'section' => 'right',
326
		'deps' => 'elgg/uservalidationbyemail',
327
	]);
328
	
329
	return $return;
330
}
331
332
return function() {
333
	elgg_register_event_handler('init', 'system', 'uservalidationbyemail_init');
334
};
335