<?php
/**
* Accounts
*
* This module provides API to work with eTraxis accounts.
* See also {@link http://www.etraxis.org/docs-schema.php#tbl_accounts tbl_accounts} database table.
*
* @package DBO
* @subpackage Accounts
*/
//--------------------------------------------------------------------------------------------------
//
// eTraxis - Records tracking web-based system.
// Copyright (C) 2005-2009 by Artem Rodygin
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
//--------------------------------------------------------------------------------------------------
// Author Date Description of modifications
//--------------------------------------------------------------------------------------------------
// Artem Rodygin 2005-02-13 new-001: Records tracking web-based system should be implemented.
// Artem Rodygin 2005-07-24 new-009: Records filter.
// Artem Rodygin 2005-08-03 new-017: Email notifications filter.
// Artem Rodygin 2005-08-15 new-003: Authentication with Active Directory.
// Artem Rodygin 2005-08-18 new-030: UI language should be set for each user separately.
// Artem Rodygin 2005-08-18 new-035: Customizable list size.
// Artem Rodygin 2005-08-22 bug-043: Removable account will not be removed in some cases.
// Artem Rodygin 2005-08-23 new-053: All the calls of DAL API functions should be moved to DBO API.
// Artem Rodygin 2005-09-01 bug-079: String database columns are not enough to store UTF-8 values.
// Artem Rodygin 2005-09-02 bug-083: Allowed length of usernames and passwords should be increased up to 104 characters.
// Artem Rodygin 2005-09-06 new-095: Newly created records should be displayed as unread.
// Artem Rodygin 2005-09-06 bug-097: When registered AD user logged in, all the records become read.
// Artem Rodygin 2005-09-17 new-125: Email notifications advanced filter.
// Artem Rodygin 2005-09-18 new-129: When new account is added, default subscription should be created.
// Artem Rodygin 2005-09-27 new-141: Source code review.
// Artem Rodygin 2005-09-27 new-141: Source code review.
// Artem Rodygin 2005-09-27 bug-142: PHP Notice: Use of undefined constant DEFAULT_NOTIFY_FLAG
// Artem Rodygin 2005-10-15 new-153: Users should *always* receieve notifications about records which are created by them or assigned on.
// Artem Rodygin 2005-10-22 bug-165: PHP Warning: odbc_exec(): SQL error: DELETE statement conflicted with COLUMN REFERENCE constraint.
// Artem Rodygin 2005-11-13 bug-177: Multibyte string functions should be used instead of 'eregi' and 'split'.
// Artem Rodygin 2006-01-24 new-204: Active Directory Support functionality (new-003) should be conditionally "compiled".
// Artem Rodygin 2006-04-09 new-235: Records with new events should be marked as "unread".
// Artem Rodygin 2006-05-07 new-251: Traceability logging review.
// Artem Rodygin 2006-06-19 new-236: Single record subscription.
// Artem Rodygin 2006-06-25 new-222: Email reminders.
// Artem Rodygin 2006-07-14 new-206: User password should not be stored in client cookies.
// Artem Rodygin 2006-08-07 bug-300: Cannot login with Active Directory credentials.
// Artem Rodygin 2006-10-12 new-137: Custom queries.
// Artem Rodygin 2006-10-17 new-361: Extended custom queries.
// Artem Rodygin 2006-11-05 new-365: Filters sharing.
// Artem Rodygin 2006-11-18 bug-389: Motorola LDAP server returns "Insufficient rights" error.
// Artem Rodygin 2006-11-20 new-392: Local users should not be extended with '@eTraxis' when LDAP is disabled.
// Artem Rodygin 2006-11-20 bug-393: PHP Notice: Undefined variable: is_ldapuser// Artem Rodygin 2006-11-20 new-377: Custom views.
// Artem Rodygin 2006-12-04 new-405: Default filter for new user.
// Artem Rodygin 2006-12-06 bug-420: Chosen locale ID is not verified on 'Settings' page.
// Artem Rodygin 2006-12-11 bug-440: Local users should not be extended with '@eTraxis' when being modified.
// Artem Rodygin 2006-12-15 bug-409: User session expires too quick.
// Artem Rodygin 2006-12-17 new-457: Default filter for new user.
// Artem Rodygin 2006-12-20 bug-458: PHP Warning: odbc_exec(): SQL error: Incorrect syntax near ''.
// Artem Rodygin 2006-12-20 new-460: Authentication token should contain client IP.
// Artem Rodygin 2007-05-09 bug-524: Filters, created by default, are not properly set.
// Artem Rodygin 2007-07-01 new-539: Existing records must not be marked as read for newly created user.
// Artem Rodygin 2007-07-12 new-544: The 'ctype' library should not be used.
// Artem Rodygin 2007-07-28 bug-553: Default filter for created records shows all records.
// Artem Rodygin 2007-09-11 new-574: Filter should allow to specify several states.
// Artem Rodygin 2007-09-12 new-576: [SF1788286] Export to CSV
// Artem Rodygin 2007-10-29 new-564: Filters set.
// Artem Rodygin 2007-11-07 new-571: View should show all records of current filters set.
// Artem Rodygin 2007-11-27 new-633: The 'dbx' extension should not be used.
// Dmitry Gorev 2007-12-10 new-414: Passwords expiration.
// Dmitry Gorev 2007-12-18 bug-645: Account is locked for specified amount of seconds, not minutes.
// Artem Rodygin 2008-03-14 new-683: Filters should be sharable with groups, not with accounts.
// Artem Rodygin 2009-04-13 new-814: Password expiration should be turnable off.
// Alexandr Permyakov 2009-05-29 new-821: Remove redundant call of 'ldap_finduser' from 'login_user'.
// Artem Rodygin 2009-06-12 new-824: PHP 4 is discontinued.
// Artem Rodygin 2009-06-17 bug-825: Database gets empty strings instead of NULL values.
// Artem Rodygin 2009-09-09 new-826: Native unicode support for Microsoft SQL Server.
//--------------------------------------------------------------------------------------------------
/**#@+
* Dependency.
*/
require_once('../engine/engine.php');
require_once('../dbo/filters.php');
/**#@-*/
//--------------------------------------------------------------------------------------------------
// Definitions.
//--------------------------------------------------------------------------------------------------
/**
* Local accounts suffix.
*/
define('ACCOUNT_SUFFIX', '@eTraxis');
/**#@+
* Data restriction.
*/
define('MAX_ACCOUNT_USERNAME', 104);
define('MAX_ACCOUNT_PASSWORD', 104);
define('MAX_ACCOUNT_FULLNAME', 64);
define('MAX_ACCOUNT_EMAIL', 50);
define('MAX_ACCOUNT_DESCRIPTION', 100);
/**#@-*/
/**
* Default notifications filter and flags.
*/
define('DEFAULT_NOTIFY_FLAG', 0x0000FFFF);
//--------------------------------------------------------------------------------------------------
// Functions.
//--------------------------------------------------------------------------------------------------
/**
* Checks whether account with specified locking info is still locked.
*
* @param int $locks_count Current value of '{@link http://www.etraxis.org/docs-schema.php#tbl_accounts_locks_count locks_count}' DBO field.
* @param int $lock_time Current value of '{@link http://www.etraxis.org/docs-schema.php#tbl_accounts_lock_time lock_time}' DBO field.
* @return bool TRUE if account is locked, FALSE otherwise.
*/
function is_account_locked ($locks_count, $lock_time)
{
debug_write_log(DEBUG_TRACE, '[is_account_locked]');
debug_write_log(DEBUG_DUMP, '[is_account_locked] $locks_count = ' . $locks_count);
debug_write_log(DEBUG_DUMP, '[is_account_locked] $lock_time = ' . $lock_time);
return ($locks_count >= LOCKS_COUNT) && ($lock_time + LOCKS_TIMEOUT * 60 >= time());
}
/**
* Increase number of failed attempts to log in ('{@link http://www.etraxis.org/docs-schema.php#tbl_accounts_locks_count locks_count}' DBO field) for specified account.
* Account is locked when maximum allowed attempts to login is reached ({@link LOCKS_COUNT}).
*
* @param int $id {@link http://www.etraxis.org/docs-schema.php#tbl_accounts_account_id Account ID}.
* @return int Always {@link NO_ERROR}.
*/
function account_lock ($id)
{
debug_write_log(DEBUG_TRACE, '[account_lock]');
debug_write_log(DEBUG_DUMP, '[account_lock] $id = ' . $id);
dal_query('accounts/lock.sql', $id, time());
return NO_ERROR;
}
/**
* Clears number of failed attempts to log in ('{@link http://www.etraxis.org/docs-schema.php#tbl_accounts_locks_count locks_count}' DBO field) for specified account.
*
* @param int $id {@link http://www.etraxis.org/docs-schema.php#tbl_accounts_account_id Account ID}.
* @return int Always {@link NO_ERROR}.
*/
function account_unlock ($id)
{
debug_write_log(DEBUG_TRACE, '[account_unlock]');
debug_write_log(DEBUG_DUMP, '[account_unlock] $id = ' . $id);
dal_query('accounts/unlock.sql', $id);
return NO_ERROR;
}
/**
* Looks for {@link http://www.etraxis.org/docs-schema.php#tbl_accounts_account_id Account ID} and token,
* which are stored in client cookies, and checks that token, stored in database for the same user, is equal.
*
* See also {@link account_set_token}.
*
* @return int {@link http://www.etraxis.org/docs-schema.php#tbl_accounts_account_id Account ID} if valid equal token is found in database, 0 otherwise.
*/
function account_get_token ()
{
debug_write_log(DEBUG_TRACE, '[account_get_token]');
$id = try_cookie(COOKIE_AUTH_USERID, 0);
$token = try_cookie(COOKIE_AUTH_TOKEN, 0);
$id = ustr2int($id);
$rs = dal_query('accounts/gettoken.sql', $id, $token, time());
return ($rs->rows == 0 ? 0 : $id);
}
/**
* Generates a token for specified {@link http://www.etraxis.org/docs-schema.php#tbl_accounts_account_id Account ID},
* and saves it in the database and client cookies.
*
* <i>Token</i> is a special MD5 hash, specific to {@link http://www.etraxis.org/docs-schema.php#tbl_accounts_account_id Account ID},
* client IP address, and time of generation. Tokens are stored in both database ({@link http://www.etraxis.org/docs-schema.php#tbl_accounts_auth_token auth_token}, {@link http://www.etraxis.org/docs-schema.php#tbl_accounts_token_expire token_expire})
* and client cookies ({@link COOKIE_AUTH_USERID}, {@link COOKIE_AUTH_TOKEN}), and has an expiration specified in {@link SESSION_EXPIRE}.
* When user tries to log in, eTraxis checks for token of this user in database - if it equals to
* token stored in client cookies and is not expired yet, than user is pretended as already logged in,
* and eTraxis does not request for user's credentials.
*
* @param int $id {@link http://www.etraxis.org/docs-schema.php#tbl_accounts_account_id Account ID}.
* @return int Always {@link NO_ERROR}.
*/
function account_set_token ($id)
{
debug_write_log(DEBUG_TRACE, '[account_set_token]');
debug_write_log(DEBUG_DUMP, '[account_set_token] $id = ' . $id);
$token = md5(WEBROOT . $id . $_SERVER['REMOTE_ADDR'] . $_SERVER['REMOTE_PORT'] . rand());
save_cookie(COOKIE_AUTH_USERID, $id);
save_cookie(COOKIE_AUTH_TOKEN, $token);
dal_query('accounts/settoken.sql', $id, $token, time() + SESSION_EXPIRE * 60);
return NO_ERROR;
}
/**
* Finds in database and returns the information about specified {@link http://www.etraxis.org/docs-schema.php#tbl_accounts_account_id Account ID}.
*
* @param int $id {@link http://www.etraxis.org/docs-schema.php#tbl_accounts_account_id Account ID}.
* @return array Array with data if account is found in database, FALSE otherwise.
*/
function account_find ($id)
{
debug_write_log(DEBUG_TRACE, '[account_find]');
debug_write_log(DEBUG_DUMP, '[account_find] $id = ' . $id);
$rs = dal_query('accounts/fndid.sql', $id);
return ($rs->rows == 0 ? FALSE : $rs->fetch());
}
/**
* Finds in database and returns the information about account with specified {@link http://www.etraxis.org/docs-schema.php#tbl_accounts_username user name}.
* To distinguish eTraxis accounts from LDAP ones, user name must be appended with {@link ACCOUNT_SUFFIX} to search among eTraxis accounts
* (LDAP accounts otherwise).
*
* @param string $username {@link http://www.etraxis.org/docs-schema.php#tbl_accounts_username User name} of account.
* @return array Array with data if account is found in database, FALSE otherwise.
*/
function account_find_username ($username)
{
debug_write_log(DEBUG_TRACE, '[account_find_username]');
debug_write_log(DEBUG_DUMP, '[account_find_username] $username = ' . $username);
$rs = dal_query('accounts/fndk.sql', ustrtolower($username));
return ($rs->rows == 0 ? FALSE : $rs->fetch());
}
/**
* Removes {@link ACCOUNT_SUFFIX} from specified {@link http://www.etraxis.org/docs-schema.php#tbl_accounts_username user name}
* if it presents and LDAP support is enabled.
*
* @param string $username {@link http://www.etraxis.org/docs-schema.php#tbl_accounts_username User name}.
* @param bool $ldap_enabled Whether LDAP support is enabled (current value of {@link LDAP_ENABLED} by default).
* @return string Clear {@link http://www.etraxis.org/docs-schema.php#tbl_accounts_username user name}.
*/
function account_get_username ($username, $ldap_enabled = LDAP_ENABLED)
{
debug_write_log(DEBUG_TRACE, '[account_get_username]');
debug_write_log(DEBUG_DUMP, '[account_get_username] $username = ' . $username);
debug_write_log(DEBUG_DUMP, '[account_get_username] $ldap_enabled = ' . $ldap_enabled);
return ($ldap_enabled ? $username : ustr_replace(ACCOUNT_SUFFIX, NULL, $username));
}
/**
* Returns {@link CRecordset DAL recordset} which contains all existing accounts and sorted in
* accordance with current sort mode.
*
* @param int &$sort Sort mode (used as output only). The function retrieves current sort mode from
* client cookie ({@link COOKIE_ACCOUNTS_SORT}) and updates it, if it's out of valid range.
* @param int &$page Number of current page tab (used as output only). The function retrieves current
* page from client cookie ({@link COOKIE_ACCOUNTS_PAGE}) and updates it, if it's out of valid range.
* @return CRecordset Recordset with list of accounts.
*/
function account_list (&$sort, &$page)
{
debug_write_log(DEBUG_TRACE, '[account_list]');
$sort_modes = array
(
1 => 'username asc',
2 => 'fullname asc, username asc',
3 => 'email asc, username asc',
4 => 'is_admin asc, username asc',
5 => 'description asc, username asc',
6 => 'username desc',
7 => 'fullname desc, username desc',
8 => 'email desc, username desc',
9 => 'is_admin desc, username desc',
10 => 'description desc, username desc',
);
$sort = try_request('sort', try_cookie(COOKIE_ACCOUNTS_SORT));
$sort = ustr2int($sort, 1, count($sort_modes));
$page = try_request('page', try_cookie(COOKIE_ACCOUNTS_PAGE));
$page = ustr2int($page, 1, MAXINT);
save_cookie(COOKIE_ACCOUNTS_SORT, $sort);
save_cookie(COOKIE_ACCOUNTS_PAGE, $page);
return dal_query('accounts/list.sql', $sort_modes[$sort]);
}
/**
* Validates account information before creation or modification.
*
* @param string $username {@link http://www.etraxis.org/docs-schema.php#tbl_accounts_username User name}.
* @param string $fullname {@link http://www.etraxis.org/docs-schema.php#tbl_accounts_fullname Full name}.
* @param string $email {@link http://www.etraxis.org/docs-schema.php#tbl_accounts_email Email address}.
* @param string $passwd1 {@link http://www.etraxis.org/docs-schema.php#tbl_accounts_passwd First password entry}.
* @param string $passwd2 {@link http://www.etraxis.org/docs-schema.php#tbl_accounts_passwd Second password entry}.
* @return int Error code:
* <ul>
* <li>{@link NO_ERROR} - data are valid</li>
* <li>{@link ERROR_INCOMPLETE_FORM} - at least one of required field is empty</li>
* <li>{@link ERROR_INVALID_USERNAME} - user name contains invalid characters</li>
* <li>{@link ERROR_INVALID_EMAIL} - email address contains invalid characters</li>
* <li>{@link ERROR_PASSWORDS_DO_NOT_MATCH} - entered password entries are not equal</li>
* <li>{@link ERROR_PASSWORD_TOO_SHORT} - entered password is too short (see {@link MIN_PASSWORD_LENGTH})</li>
* </ul>
*/
function account_validate ($username, $fullname, $email, $passwd1, $passwd2)
{
debug_write_log(DEBUG_TRACE, '[account_validate]');
debug_write_log(DEBUG_DUMP, '[account_validate] $username = ' . $username);
debug_write_log(DEBUG_DUMP, '[account_validate] $fullname = ' . $fullname);
debug_write_log(DEBUG_DUMP, '[account_validate] $email = ' . $email);
if (ustrlen($username) == 0 ||
ustrlen($fullname) == 0 ||
ustrlen($email) == 0 ||
ustrlen($passwd1) == 0 ||
ustrlen($passwd2) == 0)
{
debug_write_log(DEBUG_NOTICE, '[account_validate] At least one required field is empty.');
return ERROR_INCOMPLETE_FORM;
}
if (!is_username($username))
{
debug_write_log(DEBUG_NOTICE, '[account_validate] Invalid username.');
return ERROR_INVALID_USERNAME;
}
if (!is_email($email))
{
debug_write_log(DEBUG_NOTICE, '[account_validate] Invalid email.');
return ERROR_INVALID_EMAIL;
}
if ($passwd1 != $passwd2)
{
debug_write_log(DEBUG_NOTICE, '[account_validate] Passwords do not match.');
return ERROR_PASSWORDS_DO_NOT_MATCH;
}
if (ustrlen($passwd1) < MIN_PASSWORD_LENGTH)
{
debug_write_log(DEBUG_NOTICE, '[account_validate] Password is too short.');
return ERROR_PASSWORD_TOO_SHORT;
}
return NO_ERROR;
}
/**
* Creates new account.
*
* @param string $username {@link http://www.etraxis.org/docs-schema.php#tbl_accounts_username User name}.
* @param string $fullname {@link http://www.etraxis.org/docs-schema.php#tbl_accounts_fullname Full name}.
* @param string $email {@link http://www.etraxis.org/docs-schema.php#tbl_accounts_email Email address}.
* @param string $passwd {@link http://www.etraxis.org/docs-schema.php#tbl_accounts_passwd Password}.
* @param string $description Optional {@link http://www.etraxis.org/docs-schema.php#tbl_accounts_description description}.
* @param bool $is_admin Whether new account will have administration privileges (see '{@link http://www.etraxis.org/docs-schema.php#tbl_accounts_is_admin is_admin}' DBO field).
* @param bool $is_disabled Whether new account should be created in disabled state (see '{@link http://www.etraxis.org/docs-schema.php#tbl_accounts_is_disabled is_disabled}' DBO field).
* @param int $locale UI language (see '{@link http://www.etraxis.org/docs-schema.php#tbl_accounts_locale locale}' DBO field).
* @param bool $is_ldapuser Whether new account is LDAP one (FALSE by default, see '{@link http://www.etraxis.org/docs-schema.php#tbl_accounts_is_ldapuser is_ldapuser}' DBO field).
* @return int Error code:
* <ul>
* <li>{@link NO_ERROR} - account is successfully created</li>
* <li>{@link ERROR_ALREADY_EXISTS} - account with specified {@link http://www.etraxis.org/docs-schema.php#tbl_accounts_username user name} already exists</li>
* <li>{@link ERROR_NOT_FOUND} - failure on attempt to create account</li>
* </ul>
*/
function account_create ($username, $fullname, $email, $passwd, $description, $is_admin, $is_disabled, $locale, $is_ldapuser = FALSE)
{
debug_write_log(DEBUG_TRACE, '[account_create]');
debug_write_log(DEBUG_DUMP, '[account_create] $username = ' . $username);
debug_write_log(DEBUG_DUMP, '[account_create] $fullname = ' . $fullname);
debug_write_log(DEBUG_DUMP, '[account_create] $email = ' . $email);
debug_write_log(DEBUG_DUMP, '[account_create] $description = ' . $description);
debug_write_log(DEBUG_DUMP, '[account_create] $is_admin = ' . $is_admin);
debug_write_log(DEBUG_DUMP, '[account_create] $is_disabled = ' . $is_disabled);
debug_write_log(DEBUG_DUMP, '[account_create] $locale = ' . $locale);
debug_write_log(DEBUG_DUMP, '[account_create] $is_ldapuser = ' . $is_ldapuser);
// Check that there is no account with the same user name.
$rs = dal_query('accounts/fndk.sql', ustrtolower($username . ($is_ldapuser ? NULL : ACCOUNT_SUFFIX)));
if ($rs->rows != 0)
{
debug_write_log(DEBUG_NOTICE, '[account_create] Account already exists.');
return ERROR_ALREADY_EXISTS;
}
// Create an account.
dal_query('accounts/create.sql',
$username . ($is_ldapuser ? NULL : ACCOUNT_SUFFIX),
$fullname,
$email,
md5($passwd),
ustrlen($description) == 0 ? NULL : $description,
bool2sql($is_admin),
bool2sql($is_disabled),
bool2sql($is_ldapuser),
$locale,
DEFAULT_PAGE_ROWS,
DEFAULT_PAGE_BKMS);
// Find newly created account.
$rs = dal_query('accounts/fndk.sql', ustrtolower($username . ($is_ldapuser ? NULL : ACCOUNT_SUFFIX)));
if ($rs->rows == 0)
{
debug_write_log(DEBUG_WARNING, '[account_create] Created account not found.');
return ERROR_NOT_FOUND;
}
// Get an ID of the created account.
$account_id = $rs->fetch('account_id');
// Create 1st default filter for new account, which will show all records assigned to this account.
dal_query('filters/create.sql',
$account_id,
get_html_resource(RES_ALL_ASSIGNED_ON_ME_ID, $locale),
FILTER_TYPE_ALL_PROJECTS,
FILTER_FLAG_ASSIGNED_ON,
NULL);
// Find 1st newly created default filter.
$rs = dal_query('filters/fndk.sql',
$account_id,
ustrtolower(get_html_resource(RES_ALL_ASSIGNED_ON_ME_ID, $locale)));
if ($rs->rows == 0)
{
debug_write_log(DEBUG_WARNING, '[account_create] Created filter #1 not found.');
}
else
{
$filter_id = $rs->fetch('filter_id');
// Complete filter settings and active the filter.
dal_query('filters/facreate.sql', $filter_id, FILTER_FLAG_ASSIGNED_ON, $account_id);
dal_query('filters/set.sql', $filter_id, $account_id);
}
// Create 2nd default filter for new account, which will show all opened records created by this account.
dal_query('filters/create.sql',
$account_id,
get_html_resource(RES_ALL_CREATED_BY_ME_ID, $locale),
FILTER_TYPE_ALL_PROJECTS,
FILTER_FLAG_CREATED_BY | FILTER_FLAG_UNCLOSED,
NULL);
// Find 2nd newly created default filter.
$rs = dal_query('filters/fndk.sql',
$account_id,
ustrtolower(get_html_resource(RES_ALL_CREATED_BY_ME_ID, $locale)));
if ($rs->rows == 0)
{
debug_write_log(DEBUG_WARNING, '[account_create] Created filter #2 not found.');
}
else
{
$filter_id = $rs->fetch('filter_id');
// Complete filter settings and active the filter.
dal_query('filters/facreate.sql', $filter_id, FILTER_FLAG_CREATED_BY, $account_id);
dal_query('filters/set.sql', $filter_id, $account_id);
}
return NO_ERROR;
}
/**
* Modifies specified account.
*
* @param int $id {@link http://www.etraxis.org/docs-schema.php#tbl_accounts_account_id ID} of account to be modified.
* @param string $username New {@link http://www.etraxis.org/docs-schema.php#tbl_accounts_username user name}.
* @param string $fullname New {@link http://www.etraxis.org/docs-schema.php#tbl_accounts_fullname full name}.
* @param string $email New {@link http://www.etraxis.org/docs-schema.php#tbl_accounts_email email address}.
* @param string $description New {@link http://www.etraxis.org/docs-schema.php#tbl_accounts_description description}.
* @param bool $is_admin Whether the account should have administration privileges (see '{@link http://www.etraxis.org/docs-schema.php#tbl_accounts_is_admin is_admin}' DBO field).
* @param bool $is_disabled Whether the account should be disabled (see '{@link http://www.etraxis.org/docs-schema.php#tbl_accounts_is_disabled is_disabled}' DBO field).
* @param int $locks_count New value of '{@link http://www.etraxis.org/docs-schema.php#tbl_accounts_locks_count locks_count}' DBO field.
* @param bool $is_ldapuser Whether the account is LDAP one (FALSE by default, see '{@link http://www.etraxis.org/docs-schema.php#tbl_accounts_is_ldapuser is_ldapuser}' DBO field).
* @return int Error code:
* <ul>
* <li>{@link NO_ERROR} - account is successfully modified</li>
* <li>{@link ERROR_ALREADY_EXISTS} - another account with specified {@link http://www.etraxis.org/docs-schema.php#tbl_accounts_username user name} already exists</li>
* </ul>
*/
function account_modify ($id, $username, $fullname, $email, $description, $is_admin, $is_disabled, $locks_count, $is_ldapuser = FALSE)
{
debug_write_log(DEBUG_TRACE, '[account_modify]');
debug_write_log(DEBUG_DUMP, '[account_modify] $id = ' . $id);
debug_write_log(DEBUG_DUMP, '[account_modify] $username = ' . $username);
debug_write_log(DEBUG_DUMP, '[account_modify] $fullname = ' . $fullname);
debug_write_log(DEBUG_DUMP, '[account_modify] $email = ' . $email);
debug_write_log(DEBUG_DUMP, '[account_modify] $description = ' . $description);
debug_write_log(DEBUG_DUMP, '[account_modify] $is_admin = ' . $is_admin);
debug_write_log(DEBUG_DUMP, '[account_modify] $is_disabled = ' . $is_disabled);
debug_write_log(DEBUG_DUMP, '[account_modify] $locks_count = ' . $locks_count);
// Check that there is no account with the same user name, besides this one.
$rs = dal_query('accounts/fndku.sql', $id, ustrtolower($username . ($is_ldapuser ? NULL : ACCOUNT_SUFFIX)));
if ($rs->rows != 0)
{
debug_write_log(DEBUG_NOTICE, '[account_modify] Account already exists.');
return ERROR_ALREADY_EXISTS;
}
// Modify the account.
dal_query('accounts/modify.sql',
$id,
$username . ($is_ldapuser ? NULL : ACCOUNT_SUFFIX),
$fullname,
$email,
ustrlen($description) == 0 ? NULL : $description,
bool2sql($is_admin),
bool2sql($is_disabled),
$locks_count);
return NO_ERROR;
}
/**
* Creates new LDAP account in eTraxis database.
*
* The function searches on LDAP server for specified <i>username</i>.
* If user is found, then his display name and email address are cached in eTraxis database.
* If <i>password</i> is specified, then function also tries to authorize on LDAP server using specified <i>username</i> and <i>password</i>.
* If authorization is failed, NULL is returned, even when user with specified <i>username</i> was successfully found.
* On success ID of new registered account is returned.
*
* @param string $username {@link http://www.etraxis.org/docs-schema.php#tbl_accounts_username User name} for new account.
* @param string $password Password of user.
* @return int {@link http://www.etraxis.org/docs-schema.php#tbl_accounts_account_id ID} of new account on success, NULL otherwise.
*/
function account_register_ldapuser ($username, $passwd = NULL)
{
debug_write_log(DEBUG_TRACE, '[account_register_ldapuser]');
debug_write_log(DEBUG_DUMP, '[account_register_ldapuser] $username = ' . $username);
// Set default encoding of multibyte String library to UTF-8.
mb_regex_encoding('UTF-8');
// Find a user with specified user name on LDAP server.
$id = NULL;
$userinfo = ldap_finduser($username, $passwd);
if (!is_null($userinfo))
{
debug_write_log(DEBUG_NOTICE, 'Active Directory account is found.');
// Check whether this LDAP user is already registered in eTraxis database.
$rs = dal_query('accounts/fndk.sql', ustrtolower($username));
// This LDAP user was never registered in eTraxis database before.
if ($rs->rows == 0)
{
debug_write_log(DEBUG_NOTICE, 'Register Active Directory account in eTraxis database.');
// Create an account in eTraxis database for this LDAP user.
account_create($username,
$userinfo[0],
$userinfo[1],
'',
'Active Directory account',
in_array(ustrtolower($username), mb_split(',', ustrtolower(LDAP_ADMINS))),
0, LANG_DEFAULT, TRUE);
$rs = dal_query('accounts/fndk.sql', ustrtolower($username));
$id = $rs->fetch('account_id');
}
// This LDAP user is already registered in eTraxis database.
else
{
debug_write_log(DEBUG_NOTICE, 'Update Active Directory account in eTraxis database.');
$id = $rs->fetch('account_id');
// Update an account of this LDAP user in eTraxis database.
account_modify($id,
$username,
$userinfo[0],
$userinfo[1],
'Active Directory account',
in_array(ustrtolower($username), mb_split(',', ustrtolower(LDAP_ADMINS))),
0, 0, TRUE);
}
}
else
{
debug_write_log(DEBUG_NOTICE, 'Cannot find Active Directory account.');
}
return $id;
}
/**
* Checks whether account can be deleted.
*
* @param int $id {@link http://www.etraxis.org/docs-schema.php#tbl_accounts_account_id ID} of account to be deleted.
* @return bool TRUE if account can be deleted, FALSE otherwise.
*/
function is_account_removable ($id)
{
debug_write_log(DEBUG_TRACE, '[is_account_removable]');
debug_write_log(DEBUG_DUMP, '[is_account_removable] $id = ' . $id);
$rs = dal_query('accounts/efndc.sql', $id);
return ($rs->fetch(0) == 0);
}
/**
* Deletes specified account.
*
* @param int $id {@link http://www.etraxis.org/docs-schema.php#tbl_accounts_account_id ID} of account to be deleted.
* @return int Always {@link NO_ERROR}.
*/
function account_delete ($id)
{
debug_write_log(DEBUG_TRACE, '[account_delete]');
debug_write_log(DEBUG_DUMP, '[account_delete] $id = ' . $id);
dal_query('records/unreadall.sql', $id);
dal_query('accounts/rdelall.sql', $id);
dal_query('accounts/rsdelall.sql', $id);
dal_query('accounts/sdelall.sql', $id);
dal_query('accounts/setview.sql', $id, NULL);
dal_query('accounts/cdelall.sql', $id);
dal_query('accounts/vcdelall.sql', $id);
dal_query('accounts/vdelall.sql', $id);
dal_query('accounts/setfset.sql', $id, NULL);
dal_query('accounts/fsfdelall.sql', $id);
dal_query('accounts/fs2delall.sql', $id);
dal_query('accounts/ffdelall.sql', $id);
dal_query('accounts/ftdelall.sql', $id);
dal_query('accounts/fsdelall.sql', $id);
dal_query('accounts/fadelall.sql', $id);
dal_query('accounts/fa2delall.sql', $id);
dal_query('accounts/fshdelall.sql', $id);
dal_query('accounts/fdelall.sql', $id);
dal_query('accounts/msdelall.sql', $id);
dal_query('accounts/delete.sql', $id);
return NO_ERROR;
}
/**
* Validates new password which user has entered to change his current one.
*
* @param string $passwd1 {@link http://www.etraxis.org/docs-schema.php#tbl_accounts_passwd First password entry}.
* @param string $passwd2 {@link http://www.etraxis.org/docs-schema.php#tbl_accounts_passwd Second password entry}.
* @return int Error code:
* <ul>
* <li>{@link NO_ERROR} - entered password is valid</li>
* <li>{@link ERROR_INCOMPLETE_FORM} - at least one of password entries is empty</li>
* <li>{@link ERROR_PASSWORDS_DO_NOT_MATCH} - entered password entries are not equal</li>
* <li>{@link ERROR_PASSWORD_TOO_SHORT} - entered password is too short (see {@link MIN_PASSWORD_LENGTH})</li>
* </ul>
*/
function password_validate ($passwd1, $passwd2)
{
debug_write_log(DEBUG_TRACE, '[password_validate]');
if (ustrlen($passwd1) == 0 ||
ustrlen($passwd2) == 0)
{
debug_write_log(DEBUG_NOTICE, '[password_validate] At least one required field is empty.');
return ERROR_INCOMPLETE_FORM;
}
if ($passwd1 != $passwd2)
{
debug_write_log(DEBUG_NOTICE, '[password_validate] Passwords do not match.');
return ERROR_PASSWORDS_DO_NOT_MATCH;
}
if (ustrlen($passwd1) < MIN_PASSWORD_LENGTH)
{
debug_write_log(DEBUG_NOTICE, '[password_validate] Password is too short.');
return ERROR_PASSWORD_TOO_SHORT;
}
return NO_ERROR;
}
/**
* Change password of specified user.
*
* @param int $id {@link http://www.etraxis.org/docs-schema.php#tbl_accounts_account_id ID} of user account.
* @param string $passwd New {@link http://www.etraxis.org/docs-schema.php#tbl_accounts_passwd password} string.
* @return int Always {@link NO_ERROR}.
*/
function password_change ($id, $passwd)
{
debug_write_log(DEBUG_TRACE, '[password_change]');
debug_write_log(DEBUG_DUMP, '[password_change] $id = ' . $id);
dal_query('accounts/passwd.sql',
$id,
md5($passwd),
time());
return NO_ERROR;
}
/**
* Change UI language for specified user.
*
* @param int $id {@link http://www.etraxis.org/docs-schema.php#tbl_accounts_account_id ID} of user account.
* @param int $locale New UI language (see '{@link http://www.etraxis.org/docs-schema.php#tbl_accounts_locale locale}' DBO field).
* @return int Always {@link NO_ERROR}.
*/
function locale_change ($id, $locale)
{
debug_write_log(DEBUG_TRACE, '[locale_change]');
debug_write_log(DEBUG_DUMP, '[locale_change] $id = ' . $id);
debug_write_log(DEBUG_DUMP, '[locale_change] $locale = ' . $locale);
global $locale_info;
if (array_key_exists($locale, $locale_info))
{
dal_query('accounts/locale.sql', $id, $locale);
}
return NO_ERROR;
}
/**
* Set current user's filters set to specified one, or disable all filters if NULL is specified.
*
* @param int $id {@link http://www.etraxis.org/docs-schema.php#tbl_accounts_account_id ID} of user account.
* @param int $fset_id {@link http://www.etraxis.org/docs-schema.php#tbl_fsets_fset_id Filters set ID} (NULL by default).
* @return int Always {@link NO_ERROR}.
*/
function account_set_fset ($id, $fset_id = NULL)
{
debug_write_log(DEBUG_TRACE, '[account_set_fset]');
debug_write_log(DEBUG_DUMP, '[account_set_fset] $id = ' . $id);
debug_write_log(DEBUG_DUMP, '[account_set_fset] $fset_id = ' . $fset_id);
// Change current user's filters set.
dal_query('accounts/setfset.sql', $id, is_null($fset_id) ? NULL : $fset_id);
// Activate all filters of specified filters set and disable all others.
if (!is_null($fset_id))
{
dal_query('filters/clearall.sql', $_SESSION[VAR_USERID]);
dal_query('filters/fsset.sql', $_SESSION[VAR_USERID], $fset_id);
}
return NO_ERROR;
}
/**
* Set current user's view to specified one, or restore default view if NULL is specified.
*
* @param int $id {@link http://www.etraxis.org/docs-schema.php#tbl_accounts_account_id ID} of user account.
* @param int $view_id {@link http://www.etraxis.org/docs-schema.php#tbl_views_view_id View ID} (NULL by default).
* @return int Always {@link NO_ERROR}.
*/
function account_set_view ($id, $view_id = NULL)
{
debug_write_log(DEBUG_TRACE, '[account_set_view]');
debug_write_log(DEBUG_DUMP, '[account_set_view] $id = ' . $id);
debug_write_log(DEBUG_DUMP, '[account_set_view] $view_id = ' . $view_id);
// Change current user's view.
dal_query('accounts/setview.sql', $id, is_null($view_id) ? NULL : $view_id);
// Add all columns of specified view and remove all others.
if (!is_null($view_id))
{
dal_query('columns/cdelall.sql', $_SESSION[VAR_USERID]);
dal_query('columns/ccreate.sql', $_SESSION[VAR_USERID], $view_id);
}
return NO_ERROR;
}
?>