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
|
|
|
elgg_register_event_handler('init', 'system', 'uservalidationbyemail_init'); |
11
|
|
|
|
12
|
|
|
function uservalidationbyemail_init() { |
13
|
|
|
|
14
|
|
|
require_once dirname(__FILE__) . '/lib/functions.php'; |
15
|
|
|
|
16
|
|
|
// Register page handler to validate users |
17
|
|
|
// This doesn't need to be an action because security is handled by the validation codes. |
18
|
|
|
elgg_register_page_handler('uservalidationbyemail', 'uservalidationbyemail_page_handler'); |
19
|
|
|
|
20
|
|
|
// mark users as unvalidated and disable when they register |
21
|
|
|
elgg_register_plugin_hook_handler('register', 'user', 'uservalidationbyemail_disable_new_user'); |
22
|
|
|
|
23
|
|
|
// forward to uservalidationbyemail/emailsent page after register |
24
|
|
|
elgg_register_plugin_hook_handler('forward', 'system', 'uservalidationbyemail_after_registration_url'); |
25
|
|
|
|
26
|
|
|
// canEdit override to allow not logged in code to disable a user |
27
|
|
|
elgg_register_plugin_hook_handler('permissions_check', 'user', 'uservalidationbyemail_allow_new_user_can_edit'); |
28
|
|
|
|
29
|
|
|
// prevent users from logging in if they aren't validated |
30
|
|
|
register_pam_handler('uservalidationbyemail_check_auth_attempt', "required"); |
31
|
|
|
|
32
|
|
|
// prevent the engine from logging in users via login() |
33
|
|
|
elgg_register_event_handler('login:before', 'user', 'uservalidationbyemail_check_manual_login'); |
34
|
|
|
|
35
|
|
|
// make admin users always validated |
36
|
|
|
elgg_register_event_handler('make_admin', 'user', 'uservalidationbyemail_validate_new_admin_user'); |
37
|
|
|
|
38
|
|
|
// register Walled Garden public pages |
39
|
|
|
elgg_register_plugin_hook_handler('public_pages', 'walled_garden', 'uservalidationbyemail_public_pages'); |
40
|
|
|
|
41
|
|
|
// admin interface to manually validate users |
42
|
|
|
elgg_register_admin_menu_item('administer', 'unvalidated', 'users'); |
43
|
|
|
|
44
|
|
|
elgg_extend_view('admin.css', 'uservalidationbyemail/css'); |
45
|
|
|
|
46
|
|
|
// inline module |
47
|
|
|
elgg_extend_view('elgg.js', 'elgg/uservalidationbyemail.js'); |
48
|
|
|
elgg_require_js('elgg/uservalidationbyemail'); |
49
|
|
|
|
50
|
|
|
$action_path = dirname(__FILE__) . '/actions'; |
51
|
|
|
|
52
|
|
|
elgg_register_action('uservalidationbyemail/validate', "$action_path/validate.php", 'admin'); |
53
|
|
|
elgg_register_action('uservalidationbyemail/resend_validation', "$action_path/resend_validation.php", 'admin'); |
54
|
|
|
elgg_register_action('uservalidationbyemail/delete', "$action_path/delete.php", 'admin'); |
55
|
|
|
elgg_register_action('uservalidationbyemail/bulk_action', "$action_path/bulk_action.php", 'admin'); |
56
|
|
|
} |
57
|
|
|
|
58
|
|
|
/** |
59
|
|
|
* Disables a user upon registration. |
60
|
|
|
* |
61
|
|
|
* @param string $hook |
62
|
|
|
* @param string $type |
63
|
|
|
* @param bool $value |
64
|
|
|
* @param array $params |
65
|
|
|
* @return bool |
66
|
|
|
*/ |
67
|
|
|
function uservalidationbyemail_disable_new_user($hook, $type, $value, $params) { |
|
|
|
|
68
|
|
|
$user = elgg_extract('user', $params); |
69
|
|
|
|
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 $value; |
79
|
|
|
} |
80
|
|
|
|
81
|
|
|
// has the user already been validated? |
82
|
|
|
if (elgg_get_user_validation_status($user->guid) == true) { |
83
|
|
|
return $value; |
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_get_show_hidden_status(); |
90
|
|
|
access_show_hidden_entities(TRUE); |
91
|
|
|
|
92
|
|
|
// Don't do a recursive disable. Any entities owned by the user at this point |
93
|
|
|
// are products of plugins that hook into create user and might need |
94
|
|
|
// access to the entities. |
95
|
|
|
// @todo That ^ sounds like a specific case...would be nice to track it down... |
96
|
|
|
$user->disable('uservalidationbyemail_new_user', FALSE); |
97
|
|
|
|
98
|
|
|
// set user as unvalidated and send out validation email |
99
|
|
|
elgg_set_user_validation_status($user->guid, FALSE); |
100
|
|
|
uservalidationbyemail_request_validation($user->guid); |
101
|
|
|
|
102
|
|
|
elgg_pop_context(); |
103
|
|
|
access_show_hidden_entities($hidden_entities); |
104
|
|
|
|
105
|
|
|
return $value; |
106
|
|
|
} |
107
|
|
|
|
108
|
|
|
/** |
109
|
|
|
* Override the URL to be forwarded after registration |
110
|
|
|
* |
111
|
|
|
* @param string $hook |
112
|
|
|
* @param string $type |
113
|
|
|
* @param bool $value |
114
|
|
|
* @param array $params |
115
|
|
|
* @return string |
116
|
|
|
*/ |
117
|
|
|
function uservalidationbyemail_after_registration_url($hook, $type, $value, $params) { |
|
|
|
|
118
|
|
|
$url = elgg_extract('current_url', $params); |
119
|
|
|
if ($url == elgg_get_site_url() . 'action/register') { |
120
|
|
|
$session = elgg_get_session(); |
121
|
|
|
$email = $session->get('emailsent', ''); |
122
|
|
|
if ($email) { |
123
|
|
|
return elgg_get_site_url() . 'uservalidationbyemail/emailsent'; |
124
|
|
|
} |
125
|
|
|
} |
126
|
|
|
} |
127
|
|
|
|
128
|
|
|
/** |
129
|
|
|
* Override the canEdit() call for if we're in the context of registering a new user. |
130
|
|
|
* |
131
|
|
|
* @param string $hook |
132
|
|
|
* @param string $type |
133
|
|
|
* @param bool $value |
134
|
|
|
* @param array $params |
135
|
|
|
* @return bool|null |
136
|
|
|
*/ |
137
|
|
|
function uservalidationbyemail_allow_new_user_can_edit($hook, $type, $value, $params) { |
|
|
|
|
138
|
|
|
// $params['user'] is the user to check permissions for. |
139
|
|
|
// we want the entity to check, which is a user. |
140
|
|
|
$user = elgg_extract('entity', $params); |
141
|
|
|
|
142
|
|
|
if (!($user instanceof ElggUser)) { |
143
|
|
|
return; |
144
|
|
|
} |
145
|
|
|
|
146
|
|
|
$context = elgg_get_context(); |
147
|
|
|
if ($context == 'uservalidationbyemail_new_user' || $context == 'uservalidationbyemail_validate_user') { |
148
|
|
|
return TRUE; |
149
|
|
|
} |
150
|
|
|
|
151
|
|
|
return; |
152
|
|
|
} |
153
|
|
|
|
154
|
|
|
/** |
155
|
|
|
* Checks if an account is validated |
156
|
|
|
* |
157
|
|
|
* @params array $credentials The username and password |
158
|
|
|
* @return bool |
159
|
|
|
*/ |
160
|
|
|
function uservalidationbyemail_check_auth_attempt($credentials) { |
161
|
|
|
|
162
|
|
|
if (!isset($credentials['username'])) { |
163
|
|
|
return; |
164
|
|
|
} |
165
|
|
|
|
166
|
|
|
$username = $credentials['username']; |
167
|
|
|
|
168
|
|
|
// See if the user exists and isn't validated |
169
|
|
|
$access_status = access_get_show_hidden_status(); |
170
|
|
|
access_show_hidden_entities(TRUE); |
171
|
|
|
|
172
|
|
|
// check if logging in with email address |
173
|
|
|
if (strpos($username, '@') !== false) { |
174
|
|
|
$users = get_user_by_email($username); |
175
|
|
|
if ($users) { |
176
|
|
|
$username = $users[0]->username; |
177
|
|
|
} |
178
|
|
|
} |
179
|
|
|
|
180
|
|
|
$user = get_user_by_username($username); |
181
|
|
|
if ($user && isset($user->validated) && !$user->validated) { |
182
|
|
|
// show an error and resend validation email |
183
|
|
|
uservalidationbyemail_request_validation($user->guid); |
184
|
|
|
access_show_hidden_entities($access_status); |
185
|
|
|
throw new LoginException(elgg_echo('uservalidationbyemail:login:fail')); |
186
|
|
|
} |
187
|
|
|
|
188
|
|
|
access_show_hidden_entities($access_status); |
189
|
|
|
} |
190
|
|
|
|
191
|
|
|
/** |
192
|
|
|
* Checks sent passed validation code and user guids and validates the user. |
193
|
|
|
* |
194
|
|
|
* @param array $page |
195
|
|
|
* @return bool |
196
|
|
|
*/ |
197
|
|
|
function uservalidationbyemail_page_handler($page) { |
198
|
|
|
switch ($page[0]) { |
199
|
|
|
case 'confirm': |
200
|
|
|
echo elgg_view_resource("uservalidationbyemail/confirm"); |
201
|
|
|
break; |
202
|
|
|
case 'emailsent': |
203
|
|
|
echo elgg_view_resource("uservalidationbyemail/emailsent"); |
204
|
|
|
break; |
205
|
|
|
default: |
206
|
|
|
forward('', '404'); |
207
|
|
|
return false; |
208
|
|
|
} |
209
|
|
|
|
210
|
|
|
// note, safe to include based on input because we validated above. |
211
|
|
|
return true; |
212
|
|
|
} |
213
|
|
|
|
214
|
|
|
/** |
215
|
|
|
* Make sure any admin users are automatically validated |
216
|
|
|
* |
217
|
|
|
* @param string $event |
218
|
|
|
* @param string $type |
219
|
|
|
* @param ElggUser $user |
220
|
|
|
*/ |
221
|
|
|
function uservalidationbyemail_validate_new_admin_user($event, $type, $user) { |
|
|
|
|
222
|
|
|
if ($user instanceof ElggUser && !$user->validated) { |
223
|
|
|
elgg_set_user_validation_status($user->guid, TRUE, 'admin_user'); |
224
|
|
|
} |
225
|
|
|
} |
226
|
|
|
|
227
|
|
|
/** |
228
|
|
|
* Registers public pages to allow in the case walled garden has been enabled. |
229
|
|
|
*/ |
230
|
|
|
function uservalidationbyemail_public_pages($hook, $type, $return_value, $params) { |
|
|
|
|
231
|
|
|
$return_value[] = 'uservalidationbyemail/confirm'; |
232
|
|
|
$return_value[] = 'uservalidationbyemail/emailsent'; |
233
|
|
|
return $return_value; |
234
|
|
|
} |
235
|
|
|
|
236
|
|
|
/** |
237
|
|
|
* Prevent a manual code login with login(). |
238
|
|
|
* |
239
|
|
|
* @param string $event |
240
|
|
|
* @param string $type |
241
|
|
|
* @param ElggUser $user |
242
|
|
|
* @return bool |
243
|
|
|
* |
244
|
|
|
* @throws LoginException |
245
|
|
|
*/ |
246
|
|
|
function uservalidationbyemail_check_manual_login($event, $type, $user) { |
|
|
|
|
247
|
|
|
$access_status = access_get_show_hidden_status(); |
248
|
|
|
access_show_hidden_entities(TRUE); |
249
|
|
|
|
250
|
|
|
if (($user instanceof ElggUser) && !$user->isEnabled() && !$user->validated) { |
251
|
|
|
// send new validation email |
252
|
|
|
uservalidationbyemail_request_validation($user->getGUID()); |
253
|
|
|
|
254
|
|
|
// restore hidden entities settings |
255
|
|
|
access_show_hidden_entities($access_status); |
256
|
|
|
|
257
|
|
|
// throw error so we get a nice error message |
258
|
|
|
throw new LoginException(elgg_echo('uservalidationbyemail:login:fail')); |
259
|
|
|
} |
260
|
|
|
|
261
|
|
|
access_show_hidden_entities($access_status); |
262
|
|
|
} |
263
|
|
|
|
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.