1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
//------------------------------------------------------------------------------ |
4
|
|
|
// |
5
|
|
|
// eTraxis - Records tracking web-based system |
6
|
|
|
// Copyright (C) 2005-2013 Artem Rodygin |
7
|
|
|
// |
8
|
|
|
// This program is free software: you can redistribute it and/or modify |
9
|
|
|
// it under the terms of the GNU General Public License as published by |
10
|
|
|
// the Free Software Foundation, either version 3 of the License, or |
11
|
|
|
// (at your option) any later version. |
12
|
|
|
// |
13
|
|
|
// This program is distributed in the hope that it will be useful, |
14
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
15
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16
|
|
|
// GNU General Public License for more details. |
17
|
|
|
// |
18
|
|
|
// You should have received a copy of the GNU General Public License |
19
|
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>. |
20
|
|
|
// |
21
|
|
|
//------------------------------------------------------------------------------ |
22
|
|
|
|
23
|
|
|
/** |
24
|
|
|
* Accounts |
25
|
|
|
* |
26
|
|
|
* This module provides API to work with eTraxis accounts. |
27
|
|
|
* See also {@link https://github.com/etraxis/etraxis-obsolete/wiki/tbl_accounts tbl_accounts} database table. |
28
|
|
|
* |
29
|
|
|
* @package DBO |
30
|
|
|
* @subpackage Accounts |
31
|
|
|
*/ |
32
|
|
|
|
33
|
|
|
/**#@+ |
34
|
|
|
* Dependency. |
35
|
|
|
*/ |
36
|
|
|
require_once('../engine/engine.php'); |
37
|
|
|
require_once('../dbo/filters.php'); |
38
|
|
|
require_once('../dbo/views.php'); |
39
|
|
|
/**#@-*/ |
40
|
|
|
|
41
|
|
|
//------------------------------------------------------------------------------ |
42
|
|
|
// Definitions. |
43
|
|
|
//------------------------------------------------------------------------------ |
44
|
|
|
|
45
|
|
|
/** |
46
|
|
|
* Local accounts suffix. |
47
|
|
|
*/ |
48
|
|
|
define('ACCOUNT_SUFFIX', '@eTraxis'); |
49
|
|
|
|
50
|
|
|
/**#@+ |
51
|
|
|
* Data restriction. |
52
|
|
|
*/ |
53
|
|
|
define('MAX_ACCOUNT_USERNAME', 104); |
54
|
|
|
define('MAX_ACCOUNT_PASSWORD', 104); |
55
|
|
|
define('MAX_ACCOUNT_FULLNAME', 64); |
56
|
|
|
define('MAX_ACCOUNT_EMAIL', 50); |
57
|
|
|
define('MAX_ACCOUNT_DESCRIPTION', 100); |
58
|
|
|
/**#@-*/ |
59
|
|
|
|
60
|
|
|
/** |
61
|
|
|
* Default notifications filter and flags. |
62
|
|
|
*/ |
63
|
|
|
define('DEFAULT_NOTIFY_FLAG', 0x0000FFFF); |
64
|
|
|
|
65
|
|
|
//------------------------------------------------------------------------------ |
66
|
|
|
// Functions. |
67
|
|
|
//------------------------------------------------------------------------------ |
68
|
|
|
|
69
|
|
|
/** |
70
|
|
|
* Checks whether account with specified locking info is still locked. |
71
|
|
|
* |
72
|
|
|
* @param int $locks_count Current value of 'locks_count' DBO field. |
73
|
|
|
* @param int $lock_time Current value of 'lock_time' DBO field. |
74
|
|
|
* @return bool TRUE if account is locked, FALSE otherwise. |
75
|
|
|
*/ |
76
|
|
|
function is_account_locked ($locks_count, $lock_time) |
77
|
|
|
{ |
78
|
|
|
debug_write_log(DEBUG_TRACE, '[is_account_locked]'); |
79
|
|
|
debug_write_log(DEBUG_DUMP, '[is_account_locked] $locks_count = ' . $locks_count); |
80
|
|
|
debug_write_log(DEBUG_DUMP, '[is_account_locked] $lock_time = ' . $lock_time); |
81
|
|
|
|
82
|
|
|
return ($locks_count >= LOCKS_COUNT) && ($lock_time + LOCKS_TIMEOUT * 60 >= time()); |
83
|
|
|
} |
84
|
|
|
|
85
|
|
|
/** |
86
|
|
|
* Increase number of failed attempts to log in ('locks_count' DBO field) for specified account. |
87
|
|
|
* Account is locked when maximum allowed attempts to login is reached ({@link LOCKS_COUNT}). |
88
|
|
|
* |
89
|
|
|
* @param int $id Account ID. |
90
|
|
|
* @return int Always {@link NO_ERROR}. |
91
|
|
|
*/ |
92
|
|
|
function account_lock ($id) |
93
|
|
|
{ |
94
|
|
|
debug_write_log(DEBUG_TRACE, '[account_lock]'); |
95
|
|
|
debug_write_log(DEBUG_DUMP, '[account_lock] $id = ' . $id); |
96
|
|
|
|
97
|
|
|
dal_query('accounts/lock.sql', $id, time()); |
98
|
|
|
|
99
|
|
|
return NO_ERROR; |
100
|
|
|
} |
101
|
|
|
|
102
|
|
|
/** |
103
|
|
|
* Clears number of failed attempts to log in ('locks_count' DBO field) for specified account. |
104
|
|
|
* |
105
|
|
|
* @param int $id Account ID. |
106
|
|
|
* @return int Always {@link NO_ERROR}. |
107
|
|
|
*/ |
108
|
|
|
function account_unlock ($id) |
109
|
|
|
{ |
110
|
|
|
debug_write_log(DEBUG_TRACE, '[account_unlock]'); |
111
|
|
|
debug_write_log(DEBUG_DUMP, '[account_unlock] $id = ' . $id); |
112
|
|
|
|
113
|
|
|
dal_query('accounts/unlock.sql', $id); |
114
|
|
|
|
115
|
|
|
return NO_ERROR; |
116
|
|
|
} |
117
|
|
|
|
118
|
|
|
/** |
119
|
|
|
* Disables specified account. |
120
|
|
|
* |
121
|
|
|
* @param int $id Account ID. |
122
|
|
|
* @return int Always {@link NO_ERROR}. |
123
|
|
|
*/ |
124
|
|
View Code Duplication |
function account_disable ($id) |
|
|
|
|
125
|
|
|
{ |
126
|
|
|
debug_write_log(DEBUG_TRACE, '[account_disable]'); |
127
|
|
|
debug_write_log(DEBUG_DUMP, '[account_disable] $id = ' . $id); |
128
|
|
|
|
129
|
|
|
dal_query('accounts/disable.sql', $id, bool2sql(TRUE)); |
130
|
|
|
|
131
|
|
|
return NO_ERROR; |
132
|
|
|
} |
133
|
|
|
|
134
|
|
|
/** |
135
|
|
|
* Enables specified account. |
136
|
|
|
* |
137
|
|
|
* @param int $id Account ID. |
138
|
|
|
* @return int Always {@link NO_ERROR}. |
139
|
|
|
*/ |
140
|
|
View Code Duplication |
function account_enable ($id) |
|
|
|
|
141
|
|
|
{ |
142
|
|
|
debug_write_log(DEBUG_TRACE, '[account_enable]'); |
143
|
|
|
debug_write_log(DEBUG_DUMP, '[account_enable] $id = ' . $id); |
144
|
|
|
|
145
|
|
|
dal_query('accounts/disable.sql', $id, bool2sql(FALSE)); |
146
|
|
|
|
147
|
|
|
return NO_ERROR; |
148
|
|
|
} |
149
|
|
|
|
150
|
|
|
/** |
151
|
|
|
* Looks for Account ID and token, which are stored in client cookies, |
152
|
|
|
* and checks that token, stored in database for the same user, is equal. |
153
|
|
|
* |
154
|
|
|
* See also {@link account_set_token}. |
155
|
|
|
* |
156
|
|
|
* @return int Account ID if valid equal token is found in database, 0 otherwise. |
157
|
|
|
*/ |
158
|
|
|
function account_get_token () |
159
|
|
|
{ |
160
|
|
|
debug_write_log(DEBUG_TRACE, '[account_get_token]'); |
161
|
|
|
|
162
|
|
|
$id = try_cookie(COOKIE_AUTH_USERID, 0); |
163
|
|
|
$token = try_cookie(COOKIE_AUTH_TOKEN, 0); |
164
|
|
|
|
165
|
|
|
$id = ustr2int($id); |
166
|
|
|
|
167
|
|
|
$rs = dal_query('accounts/gettoken.sql', $id, $token, time()); |
168
|
|
|
|
169
|
|
|
return ($rs->rows == 0 ? 0 : $id); |
170
|
|
|
} |
171
|
|
|
|
172
|
|
|
/** |
173
|
|
|
* Generates a token for specified Account ID, and saves it in the database and client cookies. |
174
|
|
|
* |
175
|
|
|
* <i>Token</i> is a special MD5 hash, specific to Account ID, client IP address, and time of generation. |
176
|
|
|
* Tokens are stored in both database (auth_token, token_expire) and client cookies ({@link COOKIE_AUTH_USERID}, |
177
|
|
|
* {@link COOKIE_AUTH_TOKEN}), and has an expiration specified in {@link SESSION_EXPIRE}. |
178
|
|
|
* When user tries to log in, eTraxis checks for token of this user in database - if it equals to |
179
|
|
|
* token stored in client cookies and is not expired yet, than user is pretended as already logged in, |
180
|
|
|
* and eTraxis does not request for user's credentials. |
181
|
|
|
* |
182
|
|
|
* @param int $id Account ID. |
183
|
|
|
* @return int Always {@link NO_ERROR}. |
184
|
|
|
*/ |
185
|
|
|
function account_set_token ($id) |
186
|
|
|
{ |
187
|
|
|
debug_write_log(DEBUG_TRACE, '[account_set_token]'); |
188
|
|
|
debug_write_log(DEBUG_DUMP, '[account_set_token] $id = ' . $id); |
189
|
|
|
|
190
|
|
|
session_regenerate_id(); |
191
|
|
|
|
192
|
|
|
$token = md5(WEBROOT . $id . $_SERVER['SERVER_ADDR'] . $_SERVER['SERVER_PORT'] . rand()); |
193
|
|
|
|
194
|
|
|
save_cookie(COOKIE_AUTH_USERID, $id); |
195
|
|
|
save_cookie(COOKIE_AUTH_TOKEN, $token); |
196
|
|
|
|
197
|
|
|
dal_query('accounts/settoken.sql', $id, $token, time() + SESSION_EXPIRE * 60); |
198
|
|
|
|
199
|
|
|
return NO_ERROR; |
200
|
|
|
} |
201
|
|
|
|
202
|
|
|
/** |
203
|
|
|
* Finds in database and returns the information about specified Account ID. |
204
|
|
|
* |
205
|
|
|
* @param int $id Account ID. |
206
|
|
|
* @return array Array with data if account is found in database, FALSE otherwise. |
207
|
|
|
*/ |
208
|
|
|
function account_find ($id) |
209
|
|
|
{ |
210
|
|
|
debug_write_log(DEBUG_TRACE, '[account_find]'); |
211
|
|
|
debug_write_log(DEBUG_DUMP, '[account_find] $id = ' . $id); |
212
|
|
|
|
213
|
|
|
$rs = dal_query('accounts/fndid.sql', $id); |
214
|
|
|
|
215
|
|
|
return ($rs->rows == 0 ? FALSE : $rs->fetch()); |
216
|
|
|
} |
217
|
|
|
|
218
|
|
|
/** |
219
|
|
|
* Finds in database and returns the information about account with specified user name. |
220
|
|
|
* To distinguish eTraxis accounts from LDAP ones, user name must be appended with |
221
|
|
|
* {@link ACCOUNT_SUFFIX} to search among eTraxis accounts (LDAP accounts otherwise). |
222
|
|
|
* |
223
|
|
|
* @param string $username User name of account. |
224
|
|
|
* @return array Array with data if account is found in database, FALSE otherwise. |
225
|
|
|
*/ |
226
|
|
|
function account_find_username ($username) |
227
|
|
|
{ |
228
|
|
|
debug_write_log(DEBUG_TRACE, '[account_find_username]'); |
229
|
|
|
debug_write_log(DEBUG_DUMP, '[account_find_username] $username = ' . $username); |
230
|
|
|
|
231
|
|
|
$rs = dal_query('accounts/fndk.sql', ustrtolower($username)); |
232
|
|
|
|
233
|
|
|
return ($rs->rows == 0 ? FALSE : $rs->fetch()); |
234
|
|
|
} |
235
|
|
|
|
236
|
|
|
/** |
237
|
|
|
* Removes {@link ACCOUNT_SUFFIX} from specified user name if it presents and LDAP support is enabled. |
238
|
|
|
* |
239
|
|
|
* @param string $username User name. |
240
|
|
|
* @param bool $ldap_enabled Whether LDAP support is enabled (current value of {@link LDAP_ENABLED} by default). |
241
|
|
|
* @return string Clear user name. |
242
|
|
|
*/ |
243
|
|
|
function account_get_username ($username, $ldap_enabled = LDAP_ENABLED) |
244
|
|
|
{ |
245
|
|
|
debug_write_log(DEBUG_TRACE, '[account_get_username]'); |
246
|
|
|
debug_write_log(DEBUG_DUMP, '[account_get_username] $username = ' . $username); |
247
|
|
|
debug_write_log(DEBUG_DUMP, '[account_get_username] $ldap_enabled = ' . $ldap_enabled); |
248
|
|
|
|
249
|
|
|
return ($ldap_enabled ? $username : ustr_replace(ACCOUNT_SUFFIX, NULL, $username)); |
250
|
|
|
} |
251
|
|
|
|
252
|
|
|
/** |
253
|
|
|
* Returns {@link CRecordset DAL recordset} which contains all existing accounts and sorted in |
254
|
|
|
* accordance with current sort mode. |
255
|
|
|
* |
256
|
|
|
* @param int &$sort Sort mode (used as output only). The function retrieves current sort mode from |
257
|
|
|
* client cookie ({@link COOKIE_ACCOUNTS_SORT}) and updates it, if it's out of valid range. |
258
|
|
|
* @param int &$page Number of current page tab (used as output only). The function retrieves current |
259
|
|
|
* page from client cookie ({@link COOKIE_ACCOUNTS_PAGE}) and updates it, if it's out of valid range. |
260
|
|
|
* @return CRecordset Recordset with list of accounts. |
261
|
|
|
*/ |
262
|
|
|
function accounts_list (&$sort, &$page) |
263
|
|
|
{ |
264
|
|
|
debug_write_log(DEBUG_TRACE, '[accounts_list]'); |
265
|
|
|
|
266
|
|
|
$sort_modes = array |
267
|
|
|
( |
268
|
|
|
1 => 'username asc', |
269
|
|
|
2 => 'fullname asc, username asc', |
270
|
|
|
3 => 'email asc, username asc', |
271
|
|
|
4 => 'is_admin asc, username asc', |
272
|
|
|
5 => 'description asc, username asc', |
273
|
|
|
6 => 'username desc', |
274
|
|
|
7 => 'fullname desc, username desc', |
275
|
|
|
8 => 'email desc, username desc', |
276
|
|
|
9 => 'is_admin desc, username desc', |
277
|
|
|
10 => 'description desc, username desc', |
278
|
|
|
); |
279
|
|
|
|
280
|
|
|
$sort = try_request('sort', try_cookie(COOKIE_ACCOUNTS_SORT)); |
281
|
|
|
$sort = ustr2int($sort, 1, count($sort_modes)); |
282
|
|
|
|
283
|
|
|
$page = try_request('page', try_cookie(COOKIE_ACCOUNTS_PAGE)); |
284
|
|
|
$page = ustr2int($page, 1, MAXINT); |
285
|
|
|
|
286
|
|
|
save_cookie(COOKIE_ACCOUNTS_SORT, $sort); |
287
|
|
|
save_cookie(COOKIE_ACCOUNTS_PAGE, $page); |
288
|
|
|
|
289
|
|
|
return dal_query('accounts/list.sql', $sort_modes[$sort]); |
290
|
|
|
} |
291
|
|
|
|
292
|
|
|
/** |
293
|
|
|
* Validates account information before creation or modification. |
294
|
|
|
* |
295
|
|
|
* @param string $username User name. |
296
|
|
|
* @param string $fullname Full name. |
297
|
|
|
* @param string $email Email address. |
298
|
|
|
* @param string $passwd1 First password entry. |
299
|
|
|
* @param string $passwd2 Second password entry. |
300
|
|
|
* @return int Error code: |
301
|
|
|
* <ul> |
302
|
|
|
* <li>{@link NO_ERROR} - data are valid</li> |
303
|
|
|
* <li>{@link ERROR_INCOMPLETE_FORM} - at least one of required field is empty</li> |
304
|
|
|
* <li>{@link ERROR_INVALID_USERNAME} - user name contains invalid characters</li> |
305
|
|
|
* <li>{@link ERROR_INVALID_EMAIL} - email address contains invalid characters</li> |
306
|
|
|
* <li>{@link ERROR_PASSWORDS_DO_NOT_MATCH} - entered password entries are not equal</li> |
307
|
|
|
* <li>{@link ERROR_PASSWORD_TOO_SHORT} - entered password is too short (see {@link MIN_PASSWORD_LENGTH})</li> |
308
|
|
|
* </ul> |
309
|
|
|
*/ |
310
|
|
|
function account_validate ($username, $fullname, $email, $passwd1, $passwd2) |
311
|
|
|
{ |
312
|
|
|
debug_write_log(DEBUG_TRACE, '[account_validate]'); |
313
|
|
|
debug_write_log(DEBUG_DUMP, '[account_validate] $username = ' . $username); |
314
|
|
|
debug_write_log(DEBUG_DUMP, '[account_validate] $fullname = ' . $fullname); |
315
|
|
|
debug_write_log(DEBUG_DUMP, '[account_validate] $email = ' . $email); |
316
|
|
|
|
317
|
|
|
if (ustrlen($username) == 0 || |
318
|
|
|
ustrlen($fullname) == 0 || |
319
|
|
|
ustrlen($email) == 0 || |
320
|
|
|
ustrlen($passwd1) == 0 || |
321
|
|
|
ustrlen($passwd2) == 0) |
322
|
|
|
{ |
323
|
|
|
debug_write_log(DEBUG_NOTICE, '[account_validate] At least one required field is empty.'); |
324
|
|
|
return ERROR_INCOMPLETE_FORM; |
325
|
|
|
} |
326
|
|
|
|
327
|
|
|
if (!is_username($username)) |
328
|
|
|
{ |
329
|
|
|
debug_write_log(DEBUG_NOTICE, '[account_validate] Invalid username.'); |
330
|
|
|
return ERROR_INVALID_USERNAME; |
331
|
|
|
} |
332
|
|
|
|
333
|
|
|
if (!is_email($email)) |
334
|
|
|
{ |
335
|
|
|
debug_write_log(DEBUG_NOTICE, '[account_validate] Invalid email.'); |
336
|
|
|
return ERROR_INVALID_EMAIL; |
337
|
|
|
} |
338
|
|
|
|
339
|
|
|
if ($passwd1 != $passwd2) |
340
|
|
|
{ |
341
|
|
|
debug_write_log(DEBUG_NOTICE, '[account_validate] Passwords do not match.'); |
342
|
|
|
return ERROR_PASSWORDS_DO_NOT_MATCH; |
343
|
|
|
} |
344
|
|
|
|
345
|
|
|
if (ustrlen($passwd1) < MIN_PASSWORD_LENGTH) |
346
|
|
|
{ |
347
|
|
|
debug_write_log(DEBUG_NOTICE, '[account_validate] Password is too short.'); |
348
|
|
|
return ERROR_PASSWORD_TOO_SHORT; |
349
|
|
|
} |
350
|
|
|
|
351
|
|
|
return NO_ERROR; |
352
|
|
|
} |
353
|
|
|
|
354
|
|
|
/** |
355
|
|
|
* Creates new account. |
356
|
|
|
* |
357
|
|
|
* @param string $username User name. |
358
|
|
|
* @param string $fullname Full name. |
359
|
|
|
* @param string $email Email address. |
360
|
|
|
* @param string $passwd Password. |
361
|
|
|
* @param string $description Optional description. |
362
|
|
|
* @param bool $is_admin Whether new account will have administration privileges (see 'is_admin' DBO field). |
363
|
|
|
* @param bool $is_disabled Whether new account should be created in disabled state (see 'is_disabled' DBO field). |
364
|
|
|
* @param int $locale UI language (see 'locale' DBO field). |
365
|
|
|
* @param bool $is_ldapuser Whether new account is LDAP one (FALSE by default, see 'is_ldapuser' DBO field). |
366
|
|
|
* @return int Error code: |
367
|
|
|
* <ul> |
368
|
|
|
* <li>{@link NO_ERROR} - account is successfully created</li> |
369
|
|
|
* <li>{@link ERROR_ALREADY_EXISTS} - account with specified user name already exists</li> |
370
|
|
|
* <li>{@link ERROR_NOT_FOUND} - failure on attempt to create account</li> |
371
|
|
|
* </ul> |
372
|
|
|
*/ |
373
|
|
|
function account_create ($username, $fullname, $email, $passwd, $description, $is_admin, $is_disabled, $locale, $is_ldapuser = FALSE) |
374
|
|
|
{ |
375
|
|
|
debug_write_log(DEBUG_TRACE, '[account_create]'); |
376
|
|
|
debug_write_log(DEBUG_DUMP, '[account_create] $username = ' . $username); |
377
|
|
|
debug_write_log(DEBUG_DUMP, '[account_create] $fullname = ' . $fullname); |
378
|
|
|
debug_write_log(DEBUG_DUMP, '[account_create] $email = ' . $email); |
379
|
|
|
debug_write_log(DEBUG_DUMP, '[account_create] $description = ' . $description); |
380
|
|
|
debug_write_log(DEBUG_DUMP, '[account_create] $is_admin = ' . $is_admin); |
381
|
|
|
debug_write_log(DEBUG_DUMP, '[account_create] $is_disabled = ' . $is_disabled); |
382
|
|
|
debug_write_log(DEBUG_DUMP, '[account_create] $locale = ' . $locale); |
383
|
|
|
debug_write_log(DEBUG_DUMP, '[account_create] $is_ldapuser = ' . $is_ldapuser); |
384
|
|
|
|
385
|
|
|
// Check that there is no account with the same user name. |
386
|
|
|
$rs = dal_query('accounts/fndk.sql', ustrtolower($username . ($is_ldapuser ? NULL : ACCOUNT_SUFFIX))); |
387
|
|
|
|
388
|
|
|
if ($rs->rows != 0) |
389
|
|
|
{ |
390
|
|
|
debug_write_log(DEBUG_NOTICE, '[account_create] Account already exists.'); |
391
|
|
|
return ERROR_ALREADY_EXISTS; |
392
|
|
|
} |
393
|
|
|
|
394
|
|
|
// Create an account. |
395
|
|
|
dal_query('accounts/create.sql', |
396
|
|
|
$username . ($is_ldapuser ? NULL : ACCOUNT_SUFFIX), |
397
|
|
|
$fullname, |
398
|
|
|
$email, |
399
|
|
|
base64_encode(sha1($passwd, TRUE)), |
400
|
|
|
ustrlen($description) == 0 ? NULL : $description, |
401
|
|
|
bool2sql($is_admin), |
402
|
|
|
bool2sql($is_disabled), |
403
|
|
|
bool2sql($is_ldapuser), |
404
|
|
|
$locale, |
405
|
|
|
HTML_TEXTBOX_DEFAULT_HEIGHT, |
406
|
|
|
DEFAULT_PAGE_ROWS, |
407
|
|
|
DEFAULT_PAGE_BKMS, |
408
|
|
|
THEME_DEFAULT); |
409
|
|
|
|
410
|
|
|
// Find newly created account. |
411
|
|
|
$rs = dal_query('accounts/fndk.sql', ustrtolower($username . ($is_ldapuser ? NULL : ACCOUNT_SUFFIX))); |
412
|
|
|
|
413
|
|
|
if ($rs->rows == 0) |
414
|
|
|
{ |
415
|
|
|
debug_write_log(DEBUG_WARNING, '[account_create] Created account not found.'); |
416
|
|
|
return ERROR_NOT_FOUND; |
417
|
|
|
} |
418
|
|
|
|
419
|
|
|
// Get an ID of the created account. |
420
|
|
|
$account_id = $rs->fetch('account_id'); |
421
|
|
|
|
422
|
|
|
// Create default view for new account, which will contain both default filters. |
423
|
|
|
view_create($account_id, get_html_resource(RES_MY_RECORDS_ID, $locale)); |
424
|
|
|
|
425
|
|
|
// Find newly created default view. |
426
|
|
|
$rs = dal_query('views/fndk.sql', $account_id, ustrtolower(get_html_resource(RES_MY_RECORDS_ID, $locale))); |
427
|
|
|
|
428
|
|
|
if ($rs->rows == 0) |
429
|
|
|
{ |
430
|
|
|
debug_write_log(DEBUG_NOTICE, '[account_create] Created view not found.'); |
431
|
|
|
$view_id = NULL; |
432
|
|
|
} |
433
|
|
|
else |
434
|
|
|
{ |
435
|
|
|
$view_id = $rs->fetch('view_id'); |
436
|
|
|
dal_query('accounts/setview.sql', $account_id, $view_id); |
437
|
|
|
} |
438
|
|
|
|
439
|
|
|
// Create 1st default filter for new account, which will show all records assigned to this account. |
440
|
|
|
dal_query('filters/create.sql', |
441
|
|
|
$account_id, |
442
|
|
|
get_html_resource(RES_ALL_ASSIGNED_TO_ME_ID, $locale), |
443
|
|
|
FILTER_TYPE_ALL_PROJECTS, |
444
|
|
|
FILTER_FLAG_ASSIGNED_TO, |
445
|
|
|
NULL); |
446
|
|
|
|
447
|
|
|
// Find 1st newly created default filter. |
448
|
|
|
$rs = dal_query('filters/fndk.sql', |
449
|
|
|
$account_id, |
450
|
|
|
ustrtolower(get_html_resource(RES_ALL_ASSIGNED_TO_ME_ID, $locale))); |
451
|
|
|
|
452
|
|
View Code Duplication |
if ($rs->rows == 0) |
|
|
|
|
453
|
|
|
{ |
454
|
|
|
debug_write_log(DEBUG_WARNING, '[account_create] Created filter #1 not found.'); |
455
|
|
|
} |
456
|
|
|
else |
457
|
|
|
{ |
458
|
|
|
$filter_id = $rs->fetch('filter_id'); |
459
|
|
|
|
460
|
|
|
// Complete filter settings and active the filter. |
461
|
|
|
dal_query('filters/facreate.sql', $filter_id, FILTER_FLAG_ASSIGNED_TO, $account_id); |
462
|
|
|
dal_query('filters/set.sql', $filter_id, $account_id); |
463
|
|
|
|
464
|
|
|
// Add filter into default view. |
465
|
|
|
if (!is_null($view_id)) |
466
|
|
|
{ |
467
|
|
|
dal_query('views/fcreate.sql', $view_id, $filter_id); |
468
|
|
|
} |
469
|
|
|
} |
470
|
|
|
|
471
|
|
|
// Create 2nd default filter for new account, which will show all opened records created by this account. |
472
|
|
|
dal_query('filters/create.sql', |
473
|
|
|
$account_id, |
474
|
|
|
get_html_resource(RES_ALL_CREATED_BY_ME_ID, $locale), |
475
|
|
|
FILTER_TYPE_ALL_PROJECTS, |
476
|
|
|
FILTER_FLAG_CREATED_BY | FILTER_FLAG_UNCLOSED, |
477
|
|
|
NULL); |
478
|
|
|
|
479
|
|
|
// Find 2nd newly created default filter. |
480
|
|
|
$rs = dal_query('filters/fndk.sql', |
481
|
|
|
$account_id, |
482
|
|
|
ustrtolower(get_html_resource(RES_ALL_CREATED_BY_ME_ID, $locale))); |
483
|
|
|
|
484
|
|
View Code Duplication |
if ($rs->rows == 0) |
|
|
|
|
485
|
|
|
{ |
486
|
|
|
debug_write_log(DEBUG_WARNING, '[account_create] Created filter #2 not found.'); |
487
|
|
|
} |
488
|
|
|
else |
489
|
|
|
{ |
490
|
|
|
$filter_id = $rs->fetch('filter_id'); |
491
|
|
|
|
492
|
|
|
// Complete filter settings and active the filter. |
493
|
|
|
dal_query('filters/facreate.sql', $filter_id, FILTER_FLAG_CREATED_BY, $account_id); |
494
|
|
|
dal_query('filters/set.sql', $filter_id, $account_id); |
495
|
|
|
|
496
|
|
|
// Add filter into default view. |
497
|
|
|
if (!is_null($view_id)) |
498
|
|
|
{ |
499
|
|
|
dal_query('views/fcreate.sql', $view_id, $filter_id); |
500
|
|
|
} |
501
|
|
|
} |
502
|
|
|
|
503
|
|
|
return NO_ERROR; |
504
|
|
|
} |
505
|
|
|
|
506
|
|
|
/** |
507
|
|
|
* Modifies specified account. |
508
|
|
|
* |
509
|
|
|
* @param int $id ID of account to be modified. |
510
|
|
|
* @param string $username New user name. |
511
|
|
|
* @param string $fullname New full name. |
512
|
|
|
* @param string $email New email address. |
513
|
|
|
* @param string $description New description. |
514
|
|
|
* @param bool $is_admin Whether the account should have administration privileges (see 'is_admin' DBO field). |
515
|
|
|
* @param bool $is_disabled Whether the account should be disabled (see 'is_disabled' DBO field). |
516
|
|
|
* @param int $locks_count New value of 'locks_count' DBO field. |
517
|
|
|
* @param bool $is_ldapuser Whether the account is LDAP one (FALSE by default, see 'is_ldapuser' DBO field). |
518
|
|
|
* @return int Error code: |
519
|
|
|
* <ul> |
520
|
|
|
* <li>{@link NO_ERROR} - account is successfully modified</li> |
521
|
|
|
* <li>{@link ERROR_ALREADY_EXISTS} - another account with specified user name already exists</li> |
522
|
|
|
* </ul> |
523
|
|
|
*/ |
524
|
|
|
function account_modify ($id, $username, $fullname, $email, $description, $is_admin, $is_disabled, $locks_count, $is_ldapuser = FALSE) |
525
|
|
|
{ |
526
|
|
|
debug_write_log(DEBUG_TRACE, '[account_modify]'); |
527
|
|
|
debug_write_log(DEBUG_DUMP, '[account_modify] $id = ' . $id); |
528
|
|
|
debug_write_log(DEBUG_DUMP, '[account_modify] $username = ' . $username); |
529
|
|
|
debug_write_log(DEBUG_DUMP, '[account_modify] $fullname = ' . $fullname); |
530
|
|
|
debug_write_log(DEBUG_DUMP, '[account_modify] $email = ' . $email); |
531
|
|
|
debug_write_log(DEBUG_DUMP, '[account_modify] $description = ' . $description); |
532
|
|
|
debug_write_log(DEBUG_DUMP, '[account_modify] $is_admin = ' . $is_admin); |
533
|
|
|
debug_write_log(DEBUG_DUMP, '[account_modify] $is_disabled = ' . $is_disabled); |
534
|
|
|
debug_write_log(DEBUG_DUMP, '[account_modify] $locks_count = ' . $locks_count); |
535
|
|
|
debug_write_log(DEBUG_DUMP, '[account_modify] $is_ldapuser = ' . $is_ldapuser); |
536
|
|
|
|
537
|
|
|
// Check that there is no account with the same user name, besides this one. |
538
|
|
|
$rs = dal_query('accounts/fndku.sql', $id, ustrtolower($username . ($is_ldapuser ? NULL : ACCOUNT_SUFFIX))); |
539
|
|
|
|
540
|
|
|
if ($rs->rows != 0) |
541
|
|
|
{ |
542
|
|
|
debug_write_log(DEBUG_NOTICE, '[account_modify] Account already exists.'); |
543
|
|
|
return ERROR_ALREADY_EXISTS; |
544
|
|
|
} |
545
|
|
|
|
546
|
|
|
// Modify the account. |
547
|
|
|
dal_query('accounts/modify.sql', |
548
|
|
|
$id, |
549
|
|
|
$username . ($is_ldapuser ? NULL : ACCOUNT_SUFFIX), |
550
|
|
|
$fullname, |
551
|
|
|
$email, |
552
|
|
|
ustrlen($description) == 0 ? NULL : $description, |
553
|
|
|
bool2sql($is_admin), |
554
|
|
|
bool2sql($is_disabled), |
555
|
|
|
$locks_count); |
556
|
|
|
|
557
|
|
|
return NO_ERROR; |
558
|
|
|
} |
559
|
|
|
|
560
|
|
|
/** |
561
|
|
|
* Creates new LDAP account in eTraxis database. |
562
|
|
|
* |
563
|
|
|
* The function searches on LDAP server for specified <i>username</i>. |
564
|
|
|
* If user is found, then his display name and email address are cached in eTraxis database. |
565
|
|
|
* If <i>password</i> is specified, then function also tries to authorize on LDAP server using specified <i>username</i> and <i>password</i>. |
566
|
|
|
* If authorization is failed, NULL is returned, even when user with specified <i>username</i> was successfully found. |
567
|
|
|
* On success ID of new registered account is returned. |
568
|
|
|
* |
569
|
|
|
* @param string $username User name for new account. |
570
|
|
|
* @param string $password Password of user. |
571
|
|
|
* @return int ID of new account on success, NULL otherwise. |
572
|
|
|
*/ |
573
|
|
|
function account_register_ldapuser ($username, $passwd = NULL) |
574
|
|
|
{ |
575
|
|
|
debug_write_log(DEBUG_TRACE, '[account_register_ldapuser]'); |
576
|
|
|
debug_write_log(DEBUG_DUMP, '[account_register_ldapuser] $username = ' . $username); |
577
|
|
|
|
578
|
|
|
// Set default encoding of multibyte String library to UTF-8. |
579
|
|
|
mb_regex_encoding('UTF-8'); |
580
|
|
|
|
581
|
|
|
// Find a user with specified user name on LDAP server. |
582
|
|
|
$id = NULL; |
583
|
|
|
$userinfo = ldap_finduser($username, $passwd); |
584
|
|
|
|
585
|
|
|
if (!is_null($userinfo)) |
586
|
|
|
{ |
587
|
|
|
debug_write_log(DEBUG_NOTICE, 'Active Directory account is found.'); |
588
|
|
|
|
589
|
|
|
// Prepare list of LDAP admins |
590
|
|
|
$ldap_admins = mb_split(',', ustrtolower(LDAP_ADMINS)); |
591
|
|
|
|
592
|
|
|
foreach ($ldap_admins as $key => $ldap_admin) |
593
|
|
|
{ |
594
|
|
|
$ldap_admins[$key] = trim($ldap_admin); |
595
|
|
|
} |
596
|
|
|
|
597
|
|
|
// Check whether this LDAP user is already registered in eTraxis database. |
598
|
|
|
$rs = dal_query('accounts/fndk.sql', ustrtolower($username)); |
599
|
|
|
|
600
|
|
|
// This LDAP user was never registered in eTraxis database before. |
601
|
|
|
if ($rs->rows == 0) |
602
|
|
|
{ |
603
|
|
|
debug_write_log(DEBUG_NOTICE, 'Register Active Directory account in eTraxis database.'); |
604
|
|
|
|
605
|
|
|
// Create an account in eTraxis database for this LDAP user. |
606
|
|
|
account_create($username, |
607
|
|
|
$userinfo[0], |
608
|
|
|
$userinfo[1], |
609
|
|
|
'', |
610
|
|
|
'Active Directory account', |
611
|
|
|
in_array(ustrtolower($username), $ldap_admins), |
612
|
|
|
0, LANG_DEFAULT, TRUE); |
613
|
|
|
|
614
|
|
|
$rs = dal_query('accounts/fndk.sql', ustrtolower($username)); |
615
|
|
|
$id = $rs->fetch('account_id'); |
616
|
|
|
} |
617
|
|
|
// This LDAP user is already registered in eTraxis database. |
618
|
|
|
else |
619
|
|
|
{ |
620
|
|
|
debug_write_log(DEBUG_NOTICE, 'Update Active Directory account in eTraxis database.'); |
621
|
|
|
|
622
|
|
|
$id = $rs->fetch('account_id'); |
623
|
|
|
|
624
|
|
|
// Update an account of this LDAP user in eTraxis database. |
625
|
|
|
account_modify($id, |
626
|
|
|
$username, |
627
|
|
|
$userinfo[0], |
628
|
|
|
$userinfo[1], |
629
|
|
|
'Active Directory account', |
630
|
|
|
in_array(ustrtolower($username), $ldap_admins), |
631
|
|
|
0, 0, TRUE); |
632
|
|
|
} |
633
|
|
|
} |
634
|
|
|
else |
635
|
|
|
{ |
636
|
|
|
debug_write_log(DEBUG_NOTICE, 'Cannot find Active Directory account.'); |
637
|
|
|
} |
638
|
|
|
|
639
|
|
|
return $id; |
640
|
|
|
} |
641
|
|
|
|
642
|
|
|
/** |
643
|
|
|
* Checks whether account can be deleted. |
644
|
|
|
* |
645
|
|
|
* @param int $id ID of account to be deleted. |
646
|
|
|
* @return bool TRUE if account can be deleted, FALSE otherwise. |
647
|
|
|
*/ |
648
|
|
|
function is_account_removable ($id) |
649
|
|
|
{ |
650
|
|
|
debug_write_log(DEBUG_TRACE, '[is_account_removable]'); |
651
|
|
|
debug_write_log(DEBUG_DUMP, '[is_account_removable] $id = ' . $id); |
652
|
|
|
|
653
|
|
|
// default "root" account must not be deleted |
654
|
|
|
if ($id == 1) return FALSE; |
655
|
|
|
|
656
|
|
|
$rs = dal_query('accounts/efndc.sql', $id); |
657
|
|
|
|
658
|
|
|
return ($rs->fetch(0) == 0); |
659
|
|
|
} |
660
|
|
|
|
661
|
|
|
/** |
662
|
|
|
* Deletes specified account. |
663
|
|
|
* |
664
|
|
|
* @param int $id ID of account to be deleted. |
665
|
|
|
* @return int Always {@link NO_ERROR}. |
666
|
|
|
*/ |
667
|
|
|
function account_delete ($id) |
668
|
|
|
{ |
669
|
|
|
debug_write_log(DEBUG_TRACE, '[account_delete]'); |
670
|
|
|
debug_write_log(DEBUG_DUMP, '[account_delete] $id = ' . $id); |
671
|
|
|
|
672
|
|
|
dal_query('records/unreadall.sql', $id); |
673
|
|
|
dal_query('accounts/rdelall.sql', $id); |
674
|
|
|
dal_query('accounts/rsdelall.sql', $id); |
675
|
|
|
dal_query('accounts/sdelall.sql', $id); |
676
|
|
|
dal_query('accounts/setview.sql', $id, NULL); |
677
|
|
|
dal_query('accounts/vfdelall.sql', $id); |
678
|
|
|
dal_query('accounts/vcdelall.sql', $id); |
679
|
|
|
dal_query('accounts/vdelall.sql', $id); |
680
|
|
|
dal_query('accounts/ffdelall.sql', $id); |
681
|
|
|
dal_query('accounts/ftdelall.sql', $id); |
682
|
|
|
dal_query('accounts/fsdelall.sql', $id); |
683
|
|
|
dal_query('accounts/fadelall.sql', $id); |
684
|
|
|
dal_query('accounts/fa2delall.sql', $id); |
685
|
|
|
dal_query('accounts/fshdelall.sql', $id); |
686
|
|
|
dal_query('accounts/fdelall.sql', $id); |
687
|
|
|
dal_query('accounts/msdelall.sql', $id); |
688
|
|
|
dal_query('accounts/delete.sql', $id); |
689
|
|
|
|
690
|
|
|
return NO_ERROR; |
691
|
|
|
} |
692
|
|
|
|
693
|
|
|
/** |
694
|
|
|
* Validates new password which user has entered to change his current one. |
695
|
|
|
* |
696
|
|
|
* @param string $passwd1 First password entry. |
697
|
|
|
* @param string $passwd2 Second password entry. |
698
|
|
|
* @return int Error code: |
699
|
|
|
* <ul> |
700
|
|
|
* <li>{@link NO_ERROR} - entered password is valid</li> |
701
|
|
|
* <li>{@link ERROR_INCOMPLETE_FORM} - at least one of password entries is empty</li> |
702
|
|
|
* <li>{@link ERROR_PASSWORDS_DO_NOT_MATCH} - entered password entries are not equal</li> |
703
|
|
|
* <li>{@link ERROR_PASSWORD_TOO_SHORT} - entered password is too short (see {@link MIN_PASSWORD_LENGTH})</li> |
704
|
|
|
* </ul> |
705
|
|
|
*/ |
706
|
|
|
function password_validate ($passwd1, $passwd2) |
707
|
|
|
{ |
708
|
|
|
debug_write_log(DEBUG_TRACE, '[password_validate]'); |
709
|
|
|
|
710
|
|
|
if (ustrlen($passwd1) == 0 || |
711
|
|
|
ustrlen($passwd2) == 0) |
712
|
|
|
{ |
713
|
|
|
debug_write_log(DEBUG_NOTICE, '[password_validate] At least one required field is empty.'); |
714
|
|
|
return ERROR_INCOMPLETE_FORM; |
715
|
|
|
} |
716
|
|
|
|
717
|
|
|
if ($passwd1 != $passwd2) |
718
|
|
|
{ |
719
|
|
|
debug_write_log(DEBUG_NOTICE, '[password_validate] Passwords do not match.'); |
720
|
|
|
return ERROR_PASSWORDS_DO_NOT_MATCH; |
721
|
|
|
} |
722
|
|
|
|
723
|
|
|
if (ustrlen($passwd1) < MIN_PASSWORD_LENGTH) |
724
|
|
|
{ |
725
|
|
|
debug_write_log(DEBUG_NOTICE, '[password_validate] Password is too short.'); |
726
|
|
|
return ERROR_PASSWORD_TOO_SHORT; |
727
|
|
|
} |
728
|
|
|
|
729
|
|
|
return NO_ERROR; |
730
|
|
|
} |
731
|
|
|
|
732
|
|
|
/** |
733
|
|
|
* Change password of specified user. |
734
|
|
|
* |
735
|
|
|
* @param int $id ID of user account. |
736
|
|
|
* @param string $passwd New password string. |
737
|
|
|
* @return int Always {@link NO_ERROR}. |
738
|
|
|
*/ |
739
|
|
View Code Duplication |
function password_change ($id, $passwd) |
|
|
|
|
740
|
|
|
{ |
741
|
|
|
debug_write_log(DEBUG_TRACE, '[password_change]'); |
742
|
|
|
debug_write_log(DEBUG_DUMP, '[password_change] $id = ' . $id); |
743
|
|
|
|
744
|
|
|
dal_query('accounts/passwd.sql', |
745
|
|
|
$id, |
746
|
|
|
base64_encode(sha1($passwd, TRUE)), |
747
|
|
|
time()); |
748
|
|
|
|
749
|
|
|
return NO_ERROR; |
750
|
|
|
} |
751
|
|
|
|
752
|
|
|
/** |
753
|
|
|
* Change UI language for specified user. |
754
|
|
|
* |
755
|
|
|
* @param int $id ID of user account. |
756
|
|
|
* @param int $locale New UI language (see 'locale' DBO field). |
757
|
|
|
* @return int Always {@link NO_ERROR}. |
758
|
|
|
*/ |
759
|
|
|
function locale_change ($id, $locale) |
760
|
|
|
{ |
761
|
|
|
debug_write_log(DEBUG_TRACE, '[locale_change]'); |
762
|
|
|
debug_write_log(DEBUG_DUMP, '[locale_change] $id = ' . $id); |
763
|
|
|
debug_write_log(DEBUG_DUMP, '[locale_change] $locale = ' . $locale); |
764
|
|
|
|
765
|
|
|
global $locale_info; |
766
|
|
|
|
767
|
|
|
if (array_key_exists($locale, $locale_info)) |
768
|
|
|
{ |
769
|
|
|
dal_query('accounts/locale.sql', $id, $locale); |
770
|
|
|
} |
771
|
|
|
|
772
|
|
|
return NO_ERROR; |
773
|
|
|
} |
774
|
|
|
|
775
|
|
|
/** |
776
|
|
|
* Set current user's view to specified one, or restore default view if NULL is specified. |
777
|
|
|
* |
778
|
|
|
* @param int $view_id View ID (NULL by default). |
779
|
|
|
* @return int Always {@link NO_ERROR}. |
780
|
|
|
*/ |
781
|
|
|
function account_set_view ($view_id = NULL) |
782
|
|
|
{ |
783
|
|
|
debug_write_log(DEBUG_TRACE, '[account_set_view]'); |
784
|
|
|
debug_write_log(DEBUG_DUMP, '[account_set_view] $view_id = ' . $view_id); |
785
|
|
|
|
786
|
|
|
dal_query('accounts/setview.sql', $_SESSION[VAR_USERID], is_null($view_id) ? NULL : $view_id); |
787
|
|
|
|
788
|
|
|
return NO_ERROR; |
789
|
|
|
} |
790
|
|
|
|
791
|
|
|
/** |
792
|
|
|
* Exports accounts of specified group IDs to XML code (see also {@link template_import}). |
793
|
|
|
* |
794
|
|
|
* @param array Array with Group IDs. |
795
|
|
|
* @return string Generated XML code for accounts found. |
796
|
|
|
*/ |
797
|
|
|
function accounts_export ($groups) |
798
|
|
|
{ |
799
|
|
|
debug_write_log(DEBUG_TRACE, '[accounts_export]'); |
800
|
|
|
|
801
|
|
|
// Remove duplicated group IDs. |
802
|
|
|
$groups = array_unique($groups); |
803
|
|
|
|
804
|
|
|
if (count($groups) == 0) |
805
|
|
|
{ |
806
|
|
|
return NULL; |
807
|
|
|
} |
808
|
|
|
|
809
|
|
|
// List members of all global and local project groups. |
810
|
|
|
$rs = dal_query('groups/mamongs2.sql', implode(',', $groups)); |
811
|
|
|
|
812
|
|
|
$xml_a = NULL; |
813
|
|
|
|
814
|
|
|
if ($rs->rows != 0) |
815
|
|
|
{ |
816
|
|
|
$xml_a = " <accounts>\n"; |
817
|
|
|
|
818
|
|
|
// Add XML code for all enumerated accounts. |
819
|
|
|
while (($account = $rs->fetch())) |
820
|
|
|
{ |
821
|
|
|
// Add XML code for general account information. |
822
|
|
|
$xml_a .= sprintf(" <account username=\"%s\" fullname=\"%s\" email=\"%s\" description=\"%s\" type=\"%s\" admin=\"%s\" disabled=\"%s\" locale=\"%s\"/>\n", |
823
|
|
|
account_get_username($account['username'], FALSE), |
824
|
|
|
ustr2html($account['fullname']), |
825
|
|
|
ustr2html($account['email']), |
826
|
|
|
ustr2html($account['description']), |
827
|
|
|
($account['is_ldapuser'] ? 'ldap' : 'local'), |
828
|
|
|
($account['is_admin'] ? 'yes' : 'no'), |
829
|
|
|
($account['is_disabled'] ? 'yes' : 'no'), |
830
|
|
|
get_html_resource(RES_LOCALE_ID, $account['locale'])); |
831
|
|
|
} |
832
|
|
|
|
833
|
|
|
$xml_a .= " </accounts>\n"; |
834
|
|
|
} |
835
|
|
|
|
836
|
|
|
return $xml_a; |
837
|
|
|
} |
838
|
|
|
|
839
|
|
|
?> |
840
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.