3 * FusionForge user management
5 * Copyright 1999-2001, VA Linux Systems, Inc.
6 * Copyright 2009-2010, Roland Mas
7 * Copyright 2011, Franck Villaume - Capgemini
8 * Copyright 2012, Franck Villaume - TrivialDev
9 * Copyright (C) 2012 Alain Peyrat - Alcatel-Lucent
10 * http://fusionforge.org
12 * This file is part of FusionForge. FusionForge is free software;
13 * you can redistribute it and/or modify it under the terms of the
14 * GNU General Public License as published by the Free Software
15 * Foundation; either version 2 of the Licence, or (at your option)
18 * FusionForge is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License along
24 * with FusionForge; if not, write to the Free Software Foundation, Inc.,
25 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
31 * user_get_object_by_name() - Get User object by username.
32 * user_get_object is useful so you can pool user objects/save database queries
33 * You should always use this instead of instantiating the object directly
35 * @param string The unix username - required
36 * @param int The result set handle ("SELECT * FROM USERS WHERE user_id=xx")
37 * @return a user object or false on failure
39 function &user_get_object_by_name($user_name, $res = false) {
40 $user_name = strtolower($user_name);
42 $res = db_query_params('SELECT * FROM users WHERE user_name=$1',
45 return user_get_object(db_result($res, 0, 'user_id'), $res);
49 * user_get_object_by_email() - Get User object by email address
50 * Only works if sys_require_unique_email is true
52 * @param string The unix username - required
53 * @param int The result set handle ("SELECT * FROM USERS WHERE user_id=xx")
54 * @return a user object or false on failure
57 function user_get_object_by_email($email ,$res = false) {
58 if (!validate_email($email)
59 || !forge_get_config('require_unique_email')) {
63 $res=db_query_params('SELECT * FROM users WHERE email=$1',
66 return user_get_object(db_result($res, 0, 'user_id'), $res);
70 * user_get_object() - Get User object by user ID.
71 * user_get_object is useful so you can pool user objects/save database queries
72 * You should always use this instead of instantiating the object directly
74 * @param int The ID of the user - required
75 * @param int The result set handle ("SELECT * FROM USERS WHERE user_id=xx")
76 * @return object a user object or false on failure
78 function &user_get_object($user_id, $res = false) {
79 //create a common set of group objects
80 //saves a little wear on the database
82 //automatically checks group_type and
83 //returns appropriate object
86 if (!isset($USER_OBJ["_".$user_id."_"])) {
88 //the db result handle was passed in
90 $res = db_query_params('SELECT * FROM users WHERE user_id=$1',
93 if (!$res || db_numrows($res) < 1) {
94 $USER_OBJ["_".$user_id."_"]=false;
96 $USER_OBJ["_".$user_id."_"]= new GFUser($user_id,$res);
99 return $USER_OBJ["_".$user_id."_"];
102 function &user_get_objects($id_arr) {
107 foreach ($id_arr as $id) {
109 // See if this ID already has been fetched in the cache
111 if (!isset($USER_OBJ["_".$id."_"])) {
115 if (count($fetch) > 0) {
116 $res = db_query_params('SELECT * FROM users WHERE user_id = ANY ($1)',
117 array(db_int_array_to_any_clause ($fetch)));
118 while ($arr = db_fetch_array($res)) {
119 $USER_OBJ["_".$arr['user_id']."_"] = new GFUser($arr['user_id'],$arr);
122 foreach ($id_arr as $id) {
123 $return[] =& $USER_OBJ["_".$id."_"];
128 function &user_get_objects_by_name($username_arr) {
129 $res = db_query_params('SELECT user_id FROM users WHERE lower(user_name) = ANY ($1)',
130 array(db_string_array_to_any_clause ($username_arr)));
131 $arr =& util_result_column_to_array($res, 0);
132 return user_get_objects($arr);
135 function &user_get_objects_by_email($email_arr) {
136 $res=db_query_params('SELECT user_id FROM users WHERE lower(email) = ANY ($1)',
137 array(db_string_array_to_any_clause ($email_arr)));
138 $arr =& util_result_column_to_array($res, 0);
139 return user_get_objects($arr);
142 function &user_get_active_users() {
143 $res=db_query_params('SELECT user_id FROM users WHERE status=$1',
145 return user_get_objects(util_result_column_to_array($res, 0));
148 function &user_get_all_users() {
149 $res=db_query_params ('SELECT user_id FROM users',
151 return user_get_objects (util_result_column_to_array($res,0)) ;
154 class GFUser extends Error {
156 * Associative array of data from db.
158 * @var array $data_array.
163 * Is this person a site super-admin?
165 * @var bool $is_super_user
170 * Is this person the logged in user?
172 * @var bool $is_logged_in
177 * Array of preferences
179 * @var array $user_pref
187 * GFUser($id,$res) - CONSTRUCTOR - GENERALLY DON'T USE THIS
189 * instead use the user_get_object() function call
191 * @param int The user_id
192 * @param int The database result set OR array of data
194 function __construct($id = false, $res = false) {
197 //setting up an empty object
198 //probably going to call create()
202 $this->fetchData($id);
204 if (is_array($res)) {
205 $this->data_array =& $res;
206 } elseif (db_numrows($res) < 1) {
207 //function in class we extended
208 $this->setError(_('User Not Found'));
209 $this->data_array=array();
212 //set up an associative array for use by other functions
213 $this->data_array = db_fetch_array_by_row($res, 0);
214 if (($this->getUnixStatus() == 'A') && (forge_get_config('use_shell'))) {
215 $this->data_array['authorized_keys'] = array();
216 $res = db_query_params('select * from sshkeys where userid = $1 and deleted = 0', array($this->getID()));
217 while ($arr = db_fetch_array($res)) {
218 $this->data_array['authorized_keys'][$arr['id_sshkeys']]['upload'] = $arr['upload'];
219 $this->data_array['authorized_keys'][$arr['id_sshkeys']]['name'] = $arr['name'];
220 $this->data_array['authorized_keys'][$arr['id_sshkeys']]['fingerprint'] = $arr['fingerprint'];
221 $this->data_array['authorized_keys'][$arr['id_sshkeys']]['algorithm'] = $arr['algorithm'];
222 $this->data_array['authorized_keys'][$arr['id_sshkeys']]['deploy'] = $arr['deploy'];
223 $this->data_array['authorized_keys'][$arr['id_sshkeys']]['key'] = $arr['sshkey'];
224 $this->data_array['authorized_keys'][$arr['id_sshkeys']]['keyid'] = $arr['id_sshkeys'];
229 $this->is_super_user = false;
230 $this->is_logged_in = false;
235 * create() - Create a new user.
237 * @param string The unix username.
238 * @param string The real firstname.
239 * @param string The real lastname.
240 * @param string The first password.
241 * @param string The confirmation password.
242 * @param string The users email address.
243 * @param string The users preferred default language.
244 * @param string The users preferred default timezone.
245 * @param string The users preference for receiving site updates by email.
246 * @param string The users preference for receiving community updates by email.
247 * @param int The ID of the language preference.
248 * @param string The users preferred timezone.
249 * @param string The users Jabber address.
250 * @param int The users Jabber preference.
251 * @param int The users theme_id.
252 * @param string The users unix_box.
253 * @param string The users address.
254 * @param string The users address part 2.
255 * @param string The users phone.
256 * @param string The users fax.
257 * @param string The users title.
258 * @param char(2) The users ISO country_code.
259 * @param bool Whether to send an email or not
260 * @param int The users preference for tooltips
261 * @returns The newly created user ID
264 function create($unix_name, $firstname, $lastname, $password1, $password2, $email,
265 $mail_site, $mail_va, $language_id, $timezone, $jabber_address, $jabber_only, $theme_id,
266 $unix_box = 'shell', $address = '', $address2 = '', $phone = '', $fax = '', $title = '', $ccode = 'US', $send_mail = true, $tooltips = true) {
269 $this->setError(_('You must supply a theme'));
272 if (! forge_get_config('require_unique_email')) {
274 $this->setError(_('You must supply a username'));
279 $this->setError(_('You must supply a first name'));
283 $this->setError(_('You must supply a last name'));
287 $this->setError(_('You must supply a password'));
290 if ($password1 != $password2) {
291 $this->setError(_('Passwords do not match'));
294 if (!account_pwvalid($password1)) {
295 $this->setError(_('Invalid Password:'));
298 //testing if there is at least one capital letter in the unix name
299 if (preg_match('/[A-Z]/', $unix_name)) {
300 $this->setError(_('Invalid Unix Name (must not contain uppercase characters)'));
303 $unix_name=strtolower($unix_name);
304 if (!account_namevalid($unix_name)) {
305 $this->setError(_('Invalid Unix Name.'));
308 if (!$SYS->sysUseUnixName($unix_name)) {
309 $this->setError(_('Unix name already taken'));
312 if (!validate_email($email)) {
313 $this->setError(_('Invalid Email Address:') .' '. $email);
316 if ($jabber_address && !validate_email($jabber_address)) {
317 $this->setError(_('Invalid Jabber Address'));
325 if ($unix_name && db_numrows(db_query_params('SELECT user_id FROM users WHERE user_name LIKE $1',
326 array($unix_name))) > 0) {
327 $this->setError(_('That username already exists.'));
330 if (forge_get_config('require_unique_email')) {
331 if (user_get_object_by_email('$email')) {
332 $this->setError(_('User with this email already exists - use people search to recover your login.'));
336 if (forge_get_config('require_unique_email') && !$unix_name) {
337 // Let's generate a loginname for the user
338 // ...based on the email address:
339 $email_array = explode ('@', $email, 2) ;
340 $email_u = $email_array [0];
341 $l = preg_replace('/[^a-z0-9]/', '', $email_u);
342 $l = substr ($l, 0, 15);
343 // Is the user part of the email address okay?
344 if (account_namevalid($l)
345 && db_numrows(db_query_params('SELECT user_id FROM users WHERE user_name = $1',
349 // No? What if we add a number at the end?
352 $c = substr ($l, 0, 15-strlen ("$i")) . "$i" ;
353 if (account_namevalid($c)
354 && db_numrows(db_query_params('SELECT user_id FROM users WHERE user_name = $1',
362 // If we're really unlucky, then let's go brute-force
363 while (!$unix_name) {
364 $c = substr (md5($email . util_randbytes()), 0, 15);
365 if (account_namevalid($c)
366 && db_numrows(db_query_params('SELECT user_id FROM users WHERE user_name = $1',
372 $unix_name = strtolower($unix_name);
373 if (!account_namevalid($unix_name)) {
374 $this->setError(_('Invalid Unix Name.'));
377 $shell = account_get_user_default_shell();
378 // if we got this far, it must be good
379 $confirm_hash = substr(md5($password1 . util_randbytes() . microtime()),0,16);
381 $result = db_query_params('INSERT INTO users (user_name,user_pw,unix_pw,realname,firstname,lastname,email,add_date,status,confirm_hash,mail_siteupdates,mail_va,language,timezone,jabber_address,jabber_only,unix_box,address,address2,phone,fax,title,ccode,theme_id,tooltips,shell)
382 VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22,$23,$24,$25,$26)',
385 account_genunixpw($password1),
386 htmlspecialchars($firstname.' '.$lastname),
387 htmlspecialchars($firstname),
388 htmlspecialchars($lastname),
393 (($mail_site)?"1":"0"),
394 (($mail_va)?"1":"0"),
400 htmlspecialchars($address),
401 htmlspecialchars($address2),
402 htmlspecialchars($phone),
403 htmlspecialchars($fax),
404 htmlspecialchars($title),
410 $this->setError(_('Insert Failed: ') . db_error());
415 $id = db_insertid($result, 'users', 'user_id');
417 $this->setError('Could Not Get USERID: ' .db_error());
422 if (!$this->fetchData($id)) {
427 $hook_params = array();
428 $hook_params['user'] = $this;
429 $hook_params['user_id'] = $this->getID();
430 $hook_params['user_name'] = $unix_name;
431 $hook_params['user_password'] = $password1;
432 plugin_hook("user_create", $hook_params);
435 setup_gettext_from_lang_id($language_id);
436 $this->sendRegistrationEmail();
437 setup_gettext_from_context();
446 * sendRegistrationEmail() - Send email for registration verification
448 * @return bool success or not
450 function sendRegistrationEmail() {
451 $message=stripcslashes(sprintf(_('Thank you for registering on the %3$s web site. You have
452 account with username %1$s created for you. In order
453 to complete your registration, visit the following url:
457 You have 1 week to confirm your account. After this time, your account will be deleted.
459 (If you don\'t see any URL above, it is likely due to a bug in your mail client.
460 Use one below, but make sure it is entered as the single line.)
468 $this->getUnixName(),
469 util_make_url('/account/verify.php?confirm_hash=_'.$this->getConfirmHash()),
470 forge_get_config('forge_name')));
473 sprintf(_('%1$s Account Registration'), forge_get_config('forge_name')),
479 * delete() - remove the User from all his groups.
481 * Remove the User from all his groups and set his status to D.
483 * @param boolean Confirmation of deletion.
484 * @return boolean success or not
486 function delete($sure) {
490 $groups = &$this->getGroups();
491 if (is_array($groups)) {
492 foreach ($groups as $group) {
493 $group->removeUser($this->getID());
498 $res = db_query_params('DELETE FROM artifact_monitor WHERE user_id=$1',
499 array($this->getID()));
501 $this->setError('ERROR - ' . _('Could Not Delete From artifact_monitor:') . ' '.db_error());
505 $res = db_query_params('DELETE FROM artifact_type_monitor WHERE user_id=$1',
506 array($this->getID()));
508 $this->setError('ERROR - ' . _('Could Not Delete From artifact_type_monitor:') . ' ' .db_error());
512 $res = db_query_params('DELETE FROM forum_monitored_forums WHERE user_id=$1',
513 array($this->getID()));
515 $this->setError('ERROR - ' . _('Could Not Delete From forum_monitored_forums:') . ' '.db_error());
519 $res = db_query_params('DELETE FROM filemodule_monitor WHERE user_id=$1',
520 array($this->getID()));
522 $this->setError('ERROR - ' . _('Could Not Delete From filemodule_monitor:') . ' '.db_error());
527 $hook_params = array ();
528 $hook_params['user'] = $this;
529 $hook_params['user_id'] = $this->getID();
530 plugin_hook("user_delete", $hook_params);
532 $this->setStatus('D');
533 $this->setUnixStatus('D');
540 * update() - update *common* properties of GFUser object.
542 * Use specific setter to change other properties.
544 * @param string The users first name.
545 * @param string The users last name.
546 * @param int The ID of the users language preference.
547 * @param string The useres timezone preference.
548 * @param string The users preference for receiving site updates by email.
549 * @param string The users preference for receiving community updates by email.
550 * @param string The users preference for being participating in "peer ratings".
551 * @param string The users Jabber account address.
552 * @param int The users Jabber preference.
553 * @param int The users theme_id preference.
554 * @param string The users address.
555 * @param string The users address2.
556 * @param string The users phone.
557 * @param string The users fax.
558 * @param string The users title.
559 * @param string The users ccode.
560 * @param int The users preference for tooltips.
561 * @param string The users email.
563 function update($firstname, $lastname, $language_id, $timezone, $mail_site, $mail_va, $use_ratings,
564 $jabber_address, $jabber_only, $theme_id, $address, $address2, $phone, $fax, $title, $ccode, $tooltips, $email='') {
565 $mail_site = $mail_site ? 1 : 0;
566 $mail_va = $mail_va ? 1 : 0;
567 $block_ratings = $use_ratings ? 0 : 1;
569 if ($jabber_address && !validate_email($jabber_address)) {
570 $this->setError(_('Invalid Jabber Address'));
581 $res = db_query_params('
604 htmlspecialchars($firstname . ' ' .$lastname),
605 htmlspecialchars($firstname),
606 htmlspecialchars($lastname),
614 htmlspecialchars($address),
615 htmlspecialchars($address2),
616 htmlspecialchars($phone),
617 htmlspecialchars($fax),
618 htmlspecialchars($title),
625 $this->setError(_('ERROR - Could Not Update User Object:'). ' ' .db_error());
630 if ($email && $email != $this->getEmail()
631 && !$this->setEmail($email)) {
635 // If there's a transaction from using to not
636 // using ratings, remove all rating made by the
637 // user (ratings by others should not be removed,
638 // as it opens possibility to abuse rate system)
639 if (!$use_ratings && $this->usesRatings()) {
640 db_query_params('DELETE FROM user_ratings WHERE rated_by=$1',
641 array($this->getID()));
643 if (!$this->fetchData($this->getID())) {
648 $hook_params = array ();
649 $hook_params['user'] = $this;
650 $hook_params['user_id'] = $this->getID();
651 plugin_hook ("user_update", $hook_params);
658 * fetchData - May need to refresh database fields.
660 * If an update occurred and you need to access the updated info.
662 * @param int $user_id the User ID data to be fetched
663 * @return boolean success;
665 function fetchData($user_id) {
666 $res = db_query_params ('SELECT * FROM users WHERE user_id=$1',
668 if (!$res || db_numrows($res) < 1) {
669 $this->setError('GFUser::fetchData():: '.db_error());
672 $this->data_array = db_fetch_array($res);
673 if (($this->getUnixStatus() == 'A') && (forge_get_config('use_shell'))) {
674 $this->data_array['authorized_keys'] = array();
675 $res = db_query_params('select * from sshkeys where userid = $1 and deleted = 0', array($this->getID()));
676 while ($arr = db_fetch_array($res)) {
677 $this->data_array['authorized_keys'][$arr['id_sshkeys']]['upload'] = $arr['upload'];
678 $this->data_array['authorized_keys'][$arr['id_sshkeys']]['name'] = $arr['name'];
679 $this->data_array['authorized_keys'][$arr['id_sshkeys']]['fingerprint'] = $arr['fingerprint'];
680 $this->data_array['authorized_keys'][$arr['id_sshkeys']]['algorithm'] = $arr['algorithm'];
681 $this->data_array['authorized_keys'][$arr['id_sshkeys']]['deploy'] = $arr['deploy'];
682 $this->data_array['authorized_keys'][$arr['id_sshkeys']]['key'] = $arr['sshkey'];
683 $this->data_array['authorized_keys'][$arr['id_sshkeys']]['keyid'] = $arr['id_sshkeys'];
690 * getID - Simply return the user_id for this object.
692 * @return int This user's user_id number.
695 return $this->data_array['user_id'];
699 * getStatus - get the status of this user.
701 * Statuses include (A)ctive, (P)ending, (S)uspended ,(D)eleted.
703 * @return char This user's status flag.
705 function getStatus() {
706 return $this->data_array['status'];
710 * setStatus - set this user's status.
712 * @param string $status Status - P, A, S, or D.
713 * @return boolean success.
715 function setStatus($status) {
717 if ($status != 'P' && $status != 'A'
718 && $status != 'S' && $status != 'D') {
719 $this->setError(_('ERROR: Invalid status value'));
722 if ($this->getStatus() != 'P' && $status == 'P') {
723 $this->setError('ERROR: You can\'t set pending status if user is suspend or active');
728 $res = db_query_params ('UPDATE users SET status=$1 WHERE user_id=$2',
733 $this->setError(_('ERROR - Could Not Update User Status:') . ' ' .db_error());
737 $this->data_array['status']=$status;
738 if ($status == 'D') {
739 $projects = $this->getGroups() ;
740 foreach ($projects as $p) {
741 $p->removeUser ($this->getID()) ;
745 $hook_params = array ();
746 $hook_params['user'] = $this;
747 $hook_params['user_id'] = $this->getID();
748 $hook_params['status'] = $status;
749 plugin_hook ("user_setstatus", $hook_params);
758 * isActive - whether this user is confirmed and active.
760 * Database field status of 'A' returns true.
761 * @return boolean is_active.
763 function isActive() {
764 if ($this->getStatus()=='A') {
772 * getUnixStatus - Status of activation of unix account.
774 * @return char (N)one, (A)ctive, (S)uspended or (D)eleted
776 function getUnixStatus() {
777 return $this->data_array['unix_status'];
781 * setUnixStatus - Sets status of activation of unix account.
783 * @param string The unix status.
789 * @return boolean success.
791 function setUnixStatus($status) {
794 $res = db_query_params ('UPDATE users SET unix_status=$1 WHERE user_id=$2',
799 $this->setError('ERROR - Could Not Update User Unix Status: '.db_error());
803 if ($status == 'A') {
804 if (!$SYS->sysCheckCreateUser($this->getID())) {
805 $this->setError($SYS->getErrorMessage());
810 if ($SYS->sysCheckUser($this->getID())) {
811 if (!$SYS->sysRemoveUser($this->getID())) {
812 $this->setError($SYS->getErrorMessage());
819 $this->data_array['unix_status']=$status;
826 * getUnixName - the user's unix_name.
828 * @return string This user's unix/login name.
830 function getUnixName() {
831 return strtolower($this->data_array['user_name']);
835 * getUnixPasswd - get the user's password.
837 * @return string This user's unix crypted passwd.
839 function getUnixPasswd() {
840 return $this->data_array['unix_pw'];
844 * getUnixBox - the hostname of the unix box this user has an account on.
846 * @return string This user's shell login machine.
848 function getUnixBox() {
849 return $this->data_array['unix_box'];
853 * getMD5Passwd - the password.
855 * @return string This user's MD5-crypted passwd.
857 function getMD5Passwd() {
858 return $this->data_array['user_pw'];
861 //Added to be compatible with codendi getUserPw function
862 function getUserPw() {
863 return $this->data_array['user_pw'];
867 * getConfirmHash - the confirm hash in the db.
869 * @return string This user's confirmation hash.
871 function getConfirmHash() {
872 return $this->data_array['confirm_hash'];
876 * getEmail - the user's email address.
878 * @return string This user's email address.
880 function getEmail() {
881 return str_replace("\n", "", $this->data_array['email']);
885 * getSha1Email - a SHA1 encoded hash of the email URI (including mailto: prefix)
887 * @return string The SHA1 encoded value for the email
889 function getSha1Email() {
890 return sha1('mailto:'.$this->getEmail());
894 * getNewEmail - while changing an email address, it is stored here until confirmation.
896 * getNewEmail is a private operation for email change.
898 * @return string This user's new (not yet confirmed) email address.
901 function getNewEmail() {
902 return $this->data_array['email_new'];
906 * setEmail - set a new email address, which must be confirmed.
908 * @param string The email address.
909 * @return boolean success.
911 function setEmail($email) {
913 if (!strcasecmp($this->getEmail(), $email)) {
917 if (!$email || !validate_email($email)) {
918 $this->setError('ERROR: Invalid Email');
922 if (forge_get_config('require_unique_email')) {
923 if (db_numrows(db_query_params('SELECT user_id FROM users WHERE user_id!=$1 AND (lower(email) LIKE $2 OR lower(email_new) LIKE $2)',
924 array ($this->getID(),
925 strtolower($email)))) > 0) {
926 $this->setError(_('User with this email already exists.'));
932 $res = db_query_params ('UPDATE users SET email=$1 WHERE user_id=$2',
937 $this->setError('ERROR - Could Not Update User Email: '.db_error());
941 $hook_params = array ();
942 $hook_params['user'] = $this;
943 $hook_params['user_id'] = $this->getID();
944 $hook_params['user_email'] = $email;
945 plugin_hook("user_setemail", $hook_params);
947 if (!$this->fetchData($this->getId())) {
958 * setNewEmailAndHash - setNewEmailAndHash is a private operation for email change.
960 * @param string The email address.
961 * @param string The email hash.
962 * @return boolean success.
964 function setNewEmailAndHash($email, $hash='') {
967 $hash = substr(md5(strval(time()) . strval(util_randbytes())), 0, 16);
970 if (!$email || !validate_email($email)) {
971 $this->setError('ERROR - Invalid Email');
975 if (forge_get_config('require_unique_email')) {
976 if (db_numrows(db_query_params('SELECT user_id FROM users WHERE user_id!=$1 AND (lower(email) LIKE $2 OR lower(email_new) LIKE $2)',
977 array ($this->getID(),
978 strtolower($email)))) > 0) {
979 $this->setError(_('User with this email already exists.'));
983 $res = db_query_params ('UPDATE users SET confirm_hash=$1, email_new=$2 WHERE user_id=$3',
988 $this->setError('ERROR - Could Not Update User Email And Hash: '.db_error());
991 $this->data_array['email_new'] = $email;
992 $this->data_array['confirm_hash'] = $hash;
998 * getRealName - get the user's real name.
1000 * @return string This user's real name.
1002 function getRealName() {
1003 return $this->data_array['realname'];
1007 * setRealName - set the user's real name.
1009 * @return string boolean.
1011 function setRealName($realname) {
1012 $res=db_query_params('UPDATE users SET realname=$1 WHERE user_id=$2',
1013 array($realname, $this->getID()));
1014 if (!$res || db_affected_rows($res) < 1) {
1015 $this->setError('ERROR - Could Not Update real name of user : '.db_error());
1018 $this->data_array['realname'] = $realname;
1023 * getFirstName - get the user's first name.
1025 * @return string This user's first name.
1027 function getFirstName() {
1028 return $this->data_array['firstname'];
1032 * getLastName - get the user's last name.
1034 * @return string This user's last name.
1036 function getLastName() {
1037 return $this->data_array['lastname'];
1041 * getAddDate - this user's unix time when account was opened.
1043 * @return int This user's unix time when account was opened.
1045 function getAddDate() {
1046 return $this->data_array['add_date'];
1050 * getTimeZone - this user's timezone setting.
1052 * @return string This user's timezone setting.
1054 function getTimeZone() {
1055 return $this->data_array['timezone'];
1059 * getCountryCode - this user's ccode setting.
1061 * @return string This user's ccode setting.
1063 function getCountryCode() {
1064 return $this->data_array['ccode'];
1068 * getShell - this user's preferred shell.
1070 * @return string This user's preferred shell.
1072 function getShell() {
1073 return $this->data_array['shell'];
1077 * setShell - sets user's preferred shell.
1079 * @param string The users preferred shell.
1080 * @return boolean success.
1082 function setShell($shell) {
1085 $shells = account_getavailableshells();
1087 if (!in_array($shell, $shells)) {
1088 $this->setError( sprintf(_('ERROR: Invalid Shell %s'), $shell) );
1093 $res = db_query_params ('UPDATE users SET shell=$1 WHERE user_id=$2',
1097 $this->setError(_('ERROR - Could Not Update User Unix Shell:') . ' ' .db_error());
1101 // Now change LDAP attribute, but only if corresponding
1102 // entry exists (i.e. if user have shell access)
1103 if ($SYS->sysCheckUser($this->getID()))
1105 if (!$SYS->sysUserSetAttribute($this->getID(),"loginShell",$shell)) {
1106 $this->setError($SYS->getErrorMessage());
1111 $this->data_array['shell']=$shell;
1118 * getUnixUID() - Get the unix UID of the user
1120 * @return int This user's UID.
1122 function getUnixUID() {
1123 return $this->data_array['unix_uid'];
1127 * getUnixGID() - Get the unix GID of the user
1129 * @return int This user's GID.
1131 function getUnixGID() {
1132 return $this->data_array['unix_gid'];
1136 * getLanguage - this user's language_id from supported_languages table.
1138 * @return int This user's language_id.
1140 function getLanguage() {
1141 return $this->data_array['language'];
1145 * getJabberAddress - this user's optional jabber address.
1147 * @return string This user's jabber address.
1149 function getJabberAddress() {
1150 return $this->data_array['jabber_address'];
1154 * getJabberOnly - whether this person wants updates sent ONLY to jabber.
1156 * @return boolean This user's jabber preference.
1158 function getJabberOnly() {
1159 return $this->data_array['jabber_only'];
1163 * getAddress - get this user's address.
1165 * @return text This user's address.
1167 function getAddress() {
1168 return $this->data_array['address'];
1172 * getAddress2 - get this user's address2.
1174 * @return text This user's address2.
1176 function getAddress2() {
1177 return $this->data_array['address2'];
1181 * getPhone - get this person's phone number.
1183 * @return text This user's phone number.
1185 function getPhone() {
1186 return $this->data_array['phone'];
1190 * getFax - get this person's fax number.
1192 * @return text This user's fax.
1195 return $this->data_array['fax'];
1199 * getTitle - get this person's title.
1201 * @return text This user's title.
1203 function getTitle() {
1204 return $this->data_array['title'];
1208 * getGroups - get an array of groups this user is a member of.
1210 * @return array Array of groups.
1212 function &getGroups($onlylocal = true) {
1214 foreach ($this->getRoles() as $r) {
1216 if ($r instanceof RoleExplicit
1217 && $r->getHomeProject() != NULL) {
1218 $ids[] = $r->getHomeProject()->getID();
1221 foreach ($r->getLinkedProjects() as $p) {
1222 $ids[] = $p->getID();
1226 return group_get_objects(array_values(array_unique($ids))) ;
1230 * getAuthorizedKeys - the SSH authorized keys set by the user.
1232 * @return string This user's SSH authorized (public) keys.
1234 function getAuthorizedKeys() {
1235 return $this->data_array['authorized_keys'];
1239 * addAuthorizedKey - add the SSH authorized key for the user.
1241 * @param string The user public key.
1242 * @return boolean success.
1244 function addAuthorizedKey($key) {
1246 $key = preg_replace("/\r\n/", "\n", $key); // Convert to Unix EOL
1247 $key = preg_replace("/\n+/", "\n", $key); // Remove empty lines
1248 $tempfile = tempnam("/tmp", "authkey");
1249 $ft = fopen($tempfile, 'w');
1252 $returnExec = array();
1253 exec("/usr/bin/ssh-keygen -lf ".$tempfile, $returnExec);
1255 $returnExecExploded = explode(' ', $returnExec[0]);
1256 $fingerprint = $returnExecExploded[1];
1258 $explodedKey = explode(' ', $key);
1259 $existingKeys = $this->getAuthorizedKeys();
1260 foreach ($existingKeys as $existingKey) {
1261 if ($existingKey['fingerprint'] == $fingerprint) {
1262 $this->setError(_('SSH Key already in use'));
1266 $res = db_query_params('insert into sshkeys (userid, fingerprint, upload, sshkey, name, algorithm)
1267 values ($1, $2, $3, $4, $5, $6)',
1268 array($this->getID(), $fingerprint, $now, $key, $explodedKey[2], $explodedKey[0]));
1270 $this->setError(_('ERROR - Could Not Add User SSH Key:').db_error());
1273 $keyid = db_insertid($res, 'sshkeys', 'id_sshkeys');
1274 $this->data_array['authorized_keys'][$keyid]['fingerprint'] = $fingerprint;
1275 $this->data_array['authorized_keys'][$keyid]['upload'] = $now;
1276 $this->data_array['authorized_keys'][$keyid]['sshkey'] = $key;
1277 $this->data_array['authorized_keys'][$keyid]['deploy'] = 0;
1278 $this->data_array['authorized_keys'][$keyid]['keyid'] = $keyid;
1283 function deleteAuthorizedKey($keyid) {
1284 $res = db_query_params('update sshkeys set deleted = 1 where id_sshkeys =$1 and userid = $2',
1285 array($keyid, $this->getID()));
1287 $this->setError(_('ERROR - Could Not Delete User SSH Key:').db_error());
1290 unset($this->data_array['authorized_keys'][$keyid]);
1296 * setLoggedIn($val) - Really only used by session code.
1298 * @param boolean The session value.
1300 function setLoggedIn($val=true) {
1301 $this->is_logged_in = $val;
1304 $this->is_super_user = forge_check_global_perm_for_user($this, 'forge_admin') ;
1309 * isLoggedIn - only used by session code.
1311 * @return boolean is_logged_in.
1313 function isLoggedIn() {
1314 return $this->is_logged_in;
1318 * deletePreference - delete a preference for this user.
1320 * @param string The unique field name for this preference.
1321 * @return boolean success.
1323 function deletePreference($preference_name) {
1324 $preference_name=strtolower(trim($preference_name));
1325 unset($this->user_pref["$preference_name"]);
1326 $res = db_query_params('DELETE FROM user_preferences WHERE user_id=$1 AND preference_name=$2',
1327 array ($this->getID(),
1329 return ((!$res || db_affected_rows($res) < 1) ? false : true);
1333 * setPreference - set a new preference for this user.
1335 * @param string The unique field name for this preference.
1336 * @param string The value you are setting this preference to.
1337 * @return boolean success.
1339 function setPreference($preference_name,$value) {
1340 $preference_name=strtolower(trim($preference_name));
1341 //delete pref if not value passed in
1342 unset($this->user_pref);
1343 if (!isset($value)) {
1344 $result = db_query_params ('DELETE FROM user_preferences WHERE user_id=$1 AND preference_name=$2',
1345 array ($this->getID(),
1346 $preference_name)) ;
1348 $result = db_query_params ('UPDATE user_preferences SET preference_value=$1,set_date=$2 WHERE user_id=$3 AND preference_name=$4',
1352 $preference_name)) ;
1353 if (db_affected_rows($result) < 1) {
1355 $result = db_query_params ('INSERT INTO user_preferences (user_id,preference_name,preference_value,set_date) VALUES ($1,$2,$3,$4)',
1356 array ($this->getID(),
1362 return ((!$result || db_affected_rows($result) < 1) ? false : true);
1366 * getPreference - get a specific preference.
1368 * @param string The unique field name for this preference.
1369 * @return string|bool the preference string or false on failure.
1371 function getPreference($preference_name) {
1372 $preference_name=strtolower(trim($preference_name));
1374 First check to see if we have already fetched the preferences
1376 if (isset($this->user_pref)) {
1377 //echo "\n\nPrefs were fetched already";
1378 if (isset($this->user_pref["$preference_name"])) {
1379 //we have fetched prefs - return part of array
1380 return $this->user_pref["$preference_name"];
1382 //we have fetched prefs, but this pref hasn't been set
1386 //we haven't returned prefs - go to the db
1387 $result = db_query_params ('SELECT preference_name,preference_value FROM user_preferences WHERE user_id=$1',
1388 array ($this->getID())) ;
1389 if (db_numrows($result) < 1) {
1390 //echo "\n\nNo Prefs Found";
1394 //iterate and put the results into an array
1395 for ($i=0; $i<db_numrows($result); $i++) {
1396 $pref["".db_result($result,$i,'preference_name').""]=db_result($result,$i,'preference_value');
1398 $this->user_pref = $pref;
1400 if (array_key_exists($preference_name,$this->user_pref)) {
1401 //we have fetched prefs - return part of array
1402 return $this->user_pref["$preference_name"];
1404 //we have fetched prefs, but this pref hasn't been set
1412 * setPasswd - Changes user's password.
1414 * @param string The plaintext password.
1415 * @return boolean success.
1417 function setPasswd($passwd) {
1419 if (!account_pwvalid($passwd)) {
1420 $this->setError('Error: '.$GLOBALS['register_error']);
1425 $md5_pw = md5 ($passwd) ;
1426 $unix_pw = account_genunixpw ($passwd) ;
1428 $res = db_query_params ('UPDATE users SET user_pw=$1, unix_pw=$2 WHERE user_id=$3',
1433 if (!$res || db_affected_rows($res) < 1) {
1434 $this->setError(_('ERROR - Could Not Change User Password:') . ' ' .db_error());
1438 // Now change LDAP password, but only if corresponding
1439 // entry exists (i.e. if user have shell access)
1440 if ($SYS->sysCheckUser($this->getID())) {
1441 if (!$SYS->sysUserSetAttribute($this->getID(),"userPassword",'{crypt}'.$unix_pw)) {
1442 $this->setError($SYS->getErrorMessage());
1448 $hook_params = array ();
1449 $hook_params['user'] = $this;
1450 $hook_params['user_id'] = $this->getID();
1451 $hook_params['user_password'] = $passwd;
1452 plugin_hook ("user_setpasswd", $hook_params);
1458 * setMD5Passwd - Changes user's MD5 password.
1460 * @param string $md5 The MD5-hashed password.
1461 * @return boolean success.
1463 function setMD5Passwd($md5) {
1466 $res = db_query_params('UPDATE users SET user_pw=$1 WHERE user_id=$2',
1467 array($md5, $this->getID()));
1469 if (!$res || db_affected_rows($res) < 1) {
1470 $this->setError(_('ERROR - Could Not Change User Password:') . ' ' .db_error());
1480 * setUnixPasswd - Changes user's Unix-hashed password.
1482 * @param string $unix The Unix-hashed password.
1483 * @return boolean success.
1485 function setUnixPasswd($unix) {
1490 $res = db_query_params('UPDATE users SET unix_pw=$1 WHERE user_id=$1',
1494 if (!$res || db_affected_rows($res) < 1) {
1495 $this->setError(_('ERROR - Could Not Change User Password:') . ' ' .db_error());
1500 // Now change system password, but only if corresponding
1501 // entry exists (i.e. if user have shell access)
1502 if ($SYS->sysCheckUser($this->getID())) {
1503 if (!$SYS->sysUserSetAttribute($this->getID(),"userPassword",'{crypt}'.$unix)) {
1504 $this->setError($SYS->getErrorMessage());
1515 * usesRatings - whether user participates in rating system.
1517 * @return boolean success.
1519 function usesRatings() {
1520 return !$this->data_array['block_ratings'];
1524 * usesTooltips - whether user enables or not tooltips.
1526 * @return boolean success.
1528 function usesTooltips() {
1529 return $this->data_array['tooltips'];
1533 * getPlugins - get a list of all available user plugins
1535 * @return array array containing plugin_id => plugin_name
1537 function getPlugins() {
1538 if (!isset($this->plugins_data)) {
1539 $this->plugins_data = array () ;
1540 $res = db_query_params ('SELECT user_plugin.plugin_id, plugins.plugin_name
1541 FROM user_plugin, plugins
1542 WHERE user_plugin.user_id=$1
1543 AND user_plugin.plugin_id=plugins.plugin_id',
1544 array ($this->getID())) ;
1545 $rows = db_numrows($res);
1547 for ($i=0; $i<$rows; $i++) {
1548 $plugin_id = db_result($res,$i,'plugin_id');
1549 $this->plugins_data[$plugin_id] = db_result($res,$i,'plugin_name');
1552 return $this->plugins_data ;
1556 * usesPlugin - returns true if the user uses a particular plugin
1558 * @param string name of the plugin
1559 * @return boolean whether plugin is being used or not
1561 function usesPlugin($pluginname) {
1562 $plugins_data = $this->getPlugins() ;
1563 foreach ($plugins_data as $p_name) {
1564 if ($p_name == $pluginname) {
1572 * setPluginUse - enables/disables plugins for the user
1574 * @param string name of the plugin
1575 * @param boolean the new state
1576 * @return string database result
1578 function setPluginUse($pluginname, $val=true) {
1579 if ($val == $this->usesPlugin($pluginname)) {
1580 // State is already good, returning
1583 $res = db_query_params('SELECT plugin_id FROM plugins WHERE plugin_name=$1',
1584 array($pluginname));
1585 $rows = db_numrows($res);
1587 // Error: no plugin by that name
1590 $plugin_id = db_result($res,0,'plugin_id');
1592 unset ($this->plugins_data);
1594 return db_query_params('INSERT INTO user_plugin (user_id,plugin_id) VALUES ($1,$2)',
1595 array($this->getID(),
1598 return db_query_params('DELETE FROM user_plugin WHERE user_id=$1 AND plugin_id=$2',
1599 array($this->getID(),
1605 * getMailingsPrefs - Get activity status for one of the site mailings.
1607 * @param string The id of mailing ('mail_va' for community mailings, 'mail_siteupdates' for site mailings)
1608 * @return boolean success.
1610 function getMailingsPrefs($mailing_id) {
1611 if ($mailing_id == 'va') {
1612 return $this->data_array['mail_va'];
1613 } elseif ($mailing_id == 'site') {
1614 return $this->data_array['mail_siteupdates'];
1621 * unsubscribeFromMailings - Disable email notifications for user.
1623 * @param boolean If false, disable general site mailings, else - all.
1624 * @return boolean success.
1626 function unsubscribeFromMailings($all = false) {
1627 $res1 = $res2 = $res3 = true;
1628 $res1 = db_query_params ('UPDATE users SET mail_siteupdates=0, mail_va=0 WHERE user_id=$1',
1629 array ($this->getID())) ;
1631 $res2 = db_query_params('DELETE FROM forum_monitored_forums WHERE user_id=$1',
1632 array ($this->getID())) ;
1633 $res3 = db_query_params('DELETE FROM filemodule_monitor WHERE user_id=$1',
1634 array ($this->getID())) ;
1637 return $res1 && $res2 && $res3;
1641 * getThemeID - get the theme_id for this user.
1643 * @return int The theme_id.
1645 function getThemeID() {
1646 return $this->data_array['theme_id'];
1650 * setUpTheme - get the theme path
1652 * @return string The theme path.
1654 function setUpTheme() {
1656 // An optimization in session_getdata lets us pre-fetch this in most cases.....
1658 if (!isset($this->data_array['dirname']) || !$this->data_array['dirname']) {
1659 $res = db_query_params ('SELECT dirname FROM themes WHERE theme_id=$1',
1660 array ($this->getThemeID())) ;
1661 $this->theme=db_result($res,0,'dirname');
1663 $this->theme=$this->data_array['dirname'];
1665 if (is_file(forge_get_config('themes_root').'/'.$this->theme.'/Theme.class.php')) {
1666 $GLOBALS['sys_theme']=$this->theme;
1668 $this->theme=forge_get_config('default_theme');
1670 return $this->theme;
1674 * getRole() - Get user Role object.
1676 * @param object group object
1677 * @return object Role object
1679 function getRole(&$g) {
1680 if (is_int ($g) || is_string($g)) {
1683 $group_id = $g->getID();
1685 foreach ($this->getRoles () as $r) {
1686 if ($r instanceof RoleExplicit ) {
1687 $homeproj = $r->getHomeProject();
1689 if ($homeproj->getID() == $group_id) {
1698 function getRoles() {
1699 return RBACEngine::getInstance()->getAvailableRolesForUser($this);
1703 function isMember($g, $type = 0){
1704 if (is_int ($g) || is_string($g)) {
1705 $group = group_get_object ($g) ;
1709 $group_id = $group->getID() ;
1715 foreach ($this->getGroups() as $p) {
1716 if ($p->getID() == $group_id) {
1724 return forge_check_perm_for_user($this, 'pm_admin', $group_id);
1728 return forge_check_perm_for_user($this, 'forum_admin', $group_id);
1731 //admin for this group
1732 return forge_check_perm_for_user($this, 'project_admin', $group_id);
1736 return forge_check_perm_for_user($this, 'docman', $group_id, 'admin');
1742 * setAdminNotification - send an email to all admins (used in verify.php)
1744 * @return boolean True
1746 function setAdminNotification() {
1747 $admins = RBACEngine::getInstance()->getUsersByAllowedAction('forge_admin', -1);
1748 foreach ($admins as $admin) {
1749 $admin_email = $admin->getEmail();
1750 setup_gettext_for_user($admin);
1751 $message = sprintf(_('New User %1$s registered and validated
1755 $this->getUnixName() , $this->getRealName(), $this->getEmail());
1756 util_send_message($admin_email, sprintf(_('New %1$s User'), forge_get_config ('forge_name')), $message);
1757 setup_gettext_from_context();
1768 EVERYTHING BELOW HERE IS DEPRECATED
1771 DO NOT USE FOR ANY NEW CODE
1780 * user_ismember() - DEPRECATED; DO NOT USE! (TODO: document what should be used instead)
1781 * Replace user_ismember(1[, 'A']) with forge_check_global_perm('forge_admin')
1782 * Replace user_ismember($group_id, 'A') with forge_check_perm('project_admin', $group_id)
1783 * For now, keep user_ismember($group_id) alone
1784 * @param int The Group ID
1785 * @param int The Type
1789 function user_ismember($group_id,$type=0) {
1790 if (!session_loggedin()) {
1794 return session_get_user()->isMember($group_id, $type) ;
1798 * user_getname() - DEPRECATED; DO NOT USE! (TODO: document what should be used instead)
1800 * @param int The User ID
1804 function user_getname($user_id = false) {
1805 // use current user if one is not passed in
1807 if (session_loggedin()) {
1808 $user=&user_get_object(user_getid());
1810 return $user->getUnixName();
1812 return 'Error getting user';
1815 return 'No User Id';
1818 $user=&user_get_object($user_id);
1820 return $user->getUnixName();
1822 return 'Invalid User';
1827 class UserComparator {
1828 var $criterion = 'name' ;
1830 function Compare ($a, $b) {
1831 switch ($this->criterion) {
1834 $namecmp = strcoll ($a->getRealName(), $b->getRealName()) ;
1835 if ($namecmp != 0) {
1838 /* If several projects share a same real name */
1839 return strcoll ($a->getUnixName(), $b->getUnixName()) ;
1842 return strcmp ($a->getUnixName(), $b->getUnixName()) ;
1845 $aid = $a->getID() ;
1846 $bid = $b->getID() ;
1850 return ($a < $b) ? -1 : 1;
1856 function sortUserList (&$list, $criterion='name') {
1857 $cmp = new UserComparator () ;
1858 $cmp->criterion = $criterion ;
1860 return usort ($list, array ($cmp, 'Compare')) ;
1865 // c-file-style: "bsd"