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

mod/uservalidationbyemail/start.php (1 issue)

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) {
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) {
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) {
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) {
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) {
218 6
	if ($user instanceof ElggUser && !$user->isValidated()) {
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) {
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) {
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