CWIS Developer Documentation
User.php
Go to the documentation of this file.
1 <?PHP
2 #
3 # User.php
4 # An Object for Handling User Information
5 #
6 # Copyright 1999-2001 Axis Data
7 # This code is free software that can be used or redistributed under the
8 # terms of Version 2 of the GNU General Public License, as published by the
9 # Free Software Foundation (http://www.fsf.org).
10 #
11 # Author: Edward Almasy (almasy@axisdata.com)
12 #
13 # Part of the AxisPHP library v1.2.4
14 # For more information see http://www.axisdata.com/AxisPHP/
15 #
16 
17 # status values (error codes)
18 define("U_OKAY", 0);
19 define("U_ERROR", 1);
20 define("U_BADPASSWORD", 2);
21 define("U_NOSUCHUSER", 3);
22 define("U_PASSWORDSDONTMATCH", 4);
23 define("U_EMAILSDONTMATCH", 5);
24 define("U_DUPLICATEUSERNAME", 6);
25 define("U_ILLEGALUSERNAME", 7);
26 define("U_EMPTYUSERNAME", 8);
27 define("U_ILLEGALPASSWORD", 9);
28 define("U_ILLEGALPASSWORDAGAIN", 10);
29 define("U_EMPTYPASSWORD", 11);
30 define("U_EMPTYPASSWORDAGAIN", 12);
31 define("U_ILLEGALEMAIL", 13);
32 define("U_ILLEGALEMAILAGAIN", 14);
33 define("U_EMPTYEMAIL", 15);
34 define("U_EMPTYEMAILAGAIN", 16);
35 define("U_NOTLOGGEDIN", 17);
36 define("U_MAILINGERROR", 18);
37 define("U_TEMPLATENOTFOUND", 19);
38 define("U_DUPLICATEEMAIL", 20);
39 define("U_NOTACTIVATED", 21);
40 
41 class User
42 {
43  # ---- PUBLIC INTERFACE --------------------------------------------------
44 
45  public function __construct($UserInfoOne = NULL, $UserInfoTwo = NULL)
46  {
47  # assume constructor will succeed and user is not logged in
48  $this->Result = U_OKAY;
49  $this->LoggedIn = FALSE;
50 
51  # create database connection
52  $this->DB = new Database();
53 
54  # if user info passed in
55  if (is_int($UserInfoOne) || is_string($UserInfoOne)
56  || is_int($UserInfoTwo) || is_string($UserInfoTwo))
57  {
58  # if user ID was passed in
59  if (is_int($UserInfoOne) || is_int($UserInfoTwo))
60  {
61  # save user ID
62  $this->UserId = is_int($UserInfoOne) ? $UserInfoOne : $UserInfoTwo;
63 
64  # get whether the user is logged in
65  $this->LoggedIn = (bool)$this->DB->Query("
66  SELECT LoggedIn FROM APUsers
67  WHERE UserId='".addslashes($this->UserId)."'",
68  "LoggedIn");
69  }
70  else
71  {
72  # look up user ID in database
73  $UserInfoTwo = is_string($UserInfoOne) ? $UserInfoOne : $UserInfoTwo;
74  $this->DB->Query("SELECT UserId, LoggedIn FROM APUsers"
75  ." WHERE UserName='".addslashes($UserInfoTwo)."'");
76  $Record = $this->DB->FetchRow();
77  if ($Record)
78  {
79  $this->UserId = $Record["UserId"];
80  $this->LoggedIn = $Record["LoggedIn"];
81  }
82 
83  # if user ID was not found
84  if ($Record === FALSE)
85  {
86  # if name looks like it could actually be a user ID
87  if (preg_match("/^[-]*[0-9]+$/", $UserInfoTwo))
88  {
89  # assume name was user ID
90  $this->UserId = intval($UserInfoTwo);
91  }
92  else
93  {
94  # set code indicating no user found
95  $this->Result = U_NOSUCHUSER;
96  unset($this->UserId);
97  }
98  }
99  }
100  }
101  else
102  {
103  # if user ID is available from session
104  if (isset($_SESSION["APUserId"]))
105  {
106  # save user ID
107  $this->UserId = $_SESSION["APUserId"];
108 
109  # set flag indicating user is currently logged in
110  $this->LoggedIn = TRUE;
111  }
112  }
113  }
114 
115  public function Status()
116  {
117  return $this->Result;
118  }
119 
120  # return text message corresponding to current (or specified) status code
121  public function StatusMessage($StatusCode = NULL)
122  {
123  $APUserStatusMessages = array(
124  U_OKAY => "The operation was successful.",
125  U_ERROR => "There has been an error.",
126  U_BADPASSWORD => "The password you entered was"
127  ." incorrect.",
128  U_NOSUCHUSER => "No such user name was found.",
129  U_PASSWORDSDONTMATCH => "The new passwords you entered do"
130  ." not match.",
131  U_EMAILSDONTMATCH => "The e-mail addresses you entered"
132  ." do not match.",
133  U_DUPLICATEUSERNAME => "The user name you requested is"
134  ." already in use.",
135  U_ILLEGALUSERNAME => "The user name you requested is too"
136  ." short, too long, or contains"
137  ." illegal characters.",
138  U_ILLEGALPASSWORD => "The new password you requested is"
139  ." too short, too long, or"
140  ." contains illegal characters.",
141  U_ILLEGALEMAIL => "The e-mail address you entered"
142  ." appears to be invalid.",
143  U_NOTLOGGEDIN => "The user is not logged in.",
144  U_MAILINGERROR => "An error occurred while attempting"
145  ." to send e-mail. Please notify"
146  ." the system administrator.",
147  U_TEMPLATENOTFOUND => "An error occurred while attempting"
148  ." to generate e-mail. Please"
149  ." notify the system administrator.",
150  U_DUPLICATEEMAIL => "The e-mail address you supplied already"
151  ." has an account associated with it.",
152  );
153 
154  return ($StatusCode === NULL) ? $APUserStatusMessages[$this->Result]
155  : $APUserStatusMessages[$StatusCode];
156  }
157 
158  public function Delete()
159  {
160  # clear priv list values
161  $this->DB->Query("DELETE FROM APUserPrivileges WHERE UserId = '"
162  .$this->UserId."'");
163 
164  # delete user record from database
165  $this->DB->Query("DELETE FROM APUsers WHERE UserId = '".$this->UserId."'");
166 
167  # report to caller that everything succeeded
168  $this->Result = U_OKAY;
169  return $this->Result;
170  }
171 
177  public static function SetEmailFunction($NewValue)
178  {
179  if (is_callable($NewValue))
180  {
181  self::$EmailFunc = $NewValue;
182  }
183  }
184 
185 
186  # ---- Getting/Setting Values --------------------------------------------
187 
188  public function Id()
189  {
190  return $this->UserId;
191  }
192  public function Name()
193  {
194  return $this->Get("UserName");
195  }
196 
202  public function GetBestName()
203  {
204  $RealName = $this->Get("RealName");
205 
206  # the real name is available, so use it
207  if (strlen(trim($RealName)))
208  {
209  return $RealName;
210  }
211 
212  # the real name isn't available, so use the user name
213  return $this->Get("UserName");
214  }
215 
216  public function LastLocation($NewLocation = NULL)
217  {
218  # return NULL if not associated with a particular user
219  if ($this->UserId === NULL) { return NULL; }
220 
221  if ($NewLocation)
222  {
223  $this->DB->Query("UPDATE APUsers SET"
224  ." LastLocation = '".addslashes($NewLocation)."',"
225  ." LastActiveDate = NOW(),"
226  ." LastIPAddress = '".$_SERVER["REMOTE_ADDR"]."'"
227  ." WHERE UserId = '".addslashes($this->UserId)."'");
228  if (isset($this->DBFields))
229  {
230  $this->DBFields["LastLocation"] = $NewLocation;
231  $this->DBFields["LastActiveDate"] = date("Y-m-d H:i:s");
232  }
233  }
234  return $this->Get("LastLocation");
235  }
236  public function LastActiveDate()
237  {
238  return $this->Get("LastActiveDate");
239  }
240  public function LastIPAddress()
241  {
242  return $this->Get("LastIPAddress");
243  }
244 
245  # get value from specified field
246  public function Get($FieldName)
247  {
248  # return NULL if not associated with a particular user
249  if ($this->UserId === NULL) { return NULL; }
250 
251  return $this->UpdateValue($FieldName);
252  }
253 
254  # get value (formatted as a date) from specified field
255  public function GetDate($FieldName, $Format = "")
256  {
257  # return NULL if not associated with a particular user
258  if ($this->UserId === NULL) { return NULL; }
259 
260  # retrieve specified value from database
261  if (strlen($Format) > 0)
262  {
263  $this->DB->Query("SELECT DATE_FORMAT(`".addslashes($FieldName)
264  ."`, '".addslashes($Format)."') AS `".addslashes($FieldName)
265  ."` FROM APUsers WHERE UserId='".$this->UserId."'");
266  }
267  else
268  {
269  $this->DB->Query("SELECT `".addslashes($FieldName)."` FROM APUsers WHERE UserId='".$this->UserId."'");
270  }
271  $Record = $this->DB->FetchRow();
272 
273  # return value to caller
274  return $Record[$FieldName];
275  }
276 
277  # set value in specified field
278  public function Set($FieldName, $NewValue)
279  {
280  # return error if not associated with a particular user
281  if ($this->UserId === NULL) { return U_NOTLOGGEDIN; }
282 
283  $this->UpdateValue($FieldName, $NewValue);
284  $this->Result = U_OKAY;
285  return $this->Result;
286  }
287 
288 
289  # ---- Login Functions ---------------------------------------------------
290 
291  public function Login($UserName, $Password, $IgnorePassword = FALSE)
292  {
293  # if user not found in DB
294  $this->DB->Query("SELECT * FROM APUsers"
295  ." WHERE UserName = '"
296  .addslashes(self::NormalizeUserName($UserName))."'");
297  if ($this->DB->NumRowsSelected() < 1)
298  {
299  # result is no user by that name
300  $this->Result = U_NOSUCHUSER;
301  }
302  else
303  {
304  # if user account not yet activated
305  $Record = $this->DB->FetchRow();
306  if (!$Record["RegistrationConfirmed"])
307  {
308  # result is user registration not confirmed
309  $this->Result = U_NOTACTIVATED;
310  }
311  else
312  {
313  # grab password from DB
314  $StoredPassword = $Record["UserPassword"];
315 
316  if (isset($Password[0]) && $Password[0] == " ")
317  {
318  $Challenge = md5(date("Ymd").$_SERVER["REMOTE_ADDR"]);
319  $StoredPassword = md5( $Challenge . $StoredPassword );
320 
321  $EncryptedPassword = trim($Password);
322  }
323  else
324  {
325  # if supplied password matches encrypted password
326  $EncryptedPassword = crypt($Password, $StoredPassword);
327  }
328 
329  if (($EncryptedPassword == $StoredPassword) || $IgnorePassword)
330  {
331  # result is success
332  $this->Result = U_OKAY;
333 
334  # store user ID for session
335  $this->UserId = $Record["UserId"];
336  $_SESSION["APUserId"] = $this->UserId;
337 
338  # update last login date
339  $this->DB->Query("UPDATE APUsers SET LastLoginDate = NOW(),"
340  ." LoggedIn = '1'"
341  ." WHERE UserId = '".$this->UserId."'");
342 
343  # Check for old format hashes, and rehash if possible
344  if ($EncryptedPassword === $StoredPassword &&
345  substr($StoredPassword, 0, 3) !== "$1$" &&
346  $Password[0] !== " " &&
347  CRYPT_MD5 )
348  {
349  $NewPassword = crypt($Password);
350  $this->DB->Query(
351  "UPDATE APUsers SET UserPassword='"
352  .addslashes($NewPassword)."' "
353  ."WHERE UserId='".$this->UserId."'");
354  }
355 
356  # since self::DBFields might already have been set to false if
357  # the user wasn't logged in when this is called, populate it
358  # with user data so that a call to self::UpdateValue will be
359  # able to properly fetch the data associated with the user
360  $this->DBFields = $Record;
361 
362  # set flag to indicate we are logged in
363  $this->LoggedIn = TRUE;
364  }
365  else
366  {
367  # result is bad password
368  $this->Result = U_BADPASSWORD;
369  }
370  }
371  }
372 
373  # return result to caller
374  return $this->Result;
375  }
376 
377  # log this user out
378  public function Logout()
379  {
380  # clear user ID (if any) for session
381  unset($_SESSION["APUserId"]);
382 
383  # if user is marked as logged in
384  if ($this->LoggedIn)
385  {
386  # set flag to indicate user is no longer logged in
387  $this->LoggedIn = FALSE;
388 
389  # clear login flag in database
390  $this->DB->Query(
391  "UPDATE APUsers SET LoggedIn = '0' "
392  ."WHERE UserId='".$this->UserId."'");
393  }
394  }
395 
396  public function GetPasswordSalt($UserName)
397  {
398  $this->DB->Query(
399  "SELECT * FROM APUsers WHERE UserName = '"
400  .addslashes(self::NormalizeUserName($UserName))."'");
401 
402  if ($this->DB->NumRowsSelected() < 1)
403  {
404  # result is no user by that name, generate a fake salt
405  # to discourage user enumeration. Make it be an old-format
406  # crypt() salt so that it's harder.
407  $SaltString = $_SERVER["SERVER_ADDR"].$UserName;
408  $Result = substr(base64_encode(md5($SaltString)), 0, 2);
409  }
410  else
411  {
412  # grab password from DB
413  # Assumes that we used php's crypt() for the passowrd
414  # management stuff, and will need to be changed if we
415  # go to something else.
416  $Record = $this->DB->FetchRow();
417  $StoredPassword = $Record["UserPassword"];
418 
419  if (substr($StoredPassword, 0, 3) === "$1$")
420  {
421  $Result = substr($StoredPassword, 0, 12);
422  }
423  else
424  {
425  $Result = substr($StoredPassword, 0, 2);
426  }
427  }
428 
429  return $Result;
430  }
431 
432  # report whether this user is or is not currently logged in
433  public function IsLoggedIn()
434  {
435  return $this->LoggedIn;
436  }
437  public function IsNotLoggedIn()
438  {
439  return !$this->LoggedIn;
440  }
441 
442 
443  # ---- Password Functions ------------------------------------------------
444 
445  # set new password (with checks against old password)
446  public function ChangePassword($OldPassword, $NewPassword, $NewPasswordAgain)
447  {
448  # return error if not associated with a particular user
449  if ($this->UserId === NULL) { return U_NOTLOGGEDIN; }
450 
451  # if old password is not correct
452  $StoredPassword = $this->DB->Query("SELECT UserPassword FROM APUsers"
453  ." WHERE UserId='".$this->UserId."'", "UserPassword");
454  $EncryptedPassword = crypt($OldPassword, $StoredPassword);
455  if ($EncryptedPassword != $StoredPassword)
456  {
457  # set status to indicate error
458  $this->Result = U_BADPASSWORD;
459  }
460  # else if new password is not legal
461  elseif (!$this->IsValidPassword($NewPassword))
462  {
463  # set status to indicate error
464  $this->Result = U_ILLEGALPASSWORD;
465  }
466  # else if both instances of new password do not match
467  elseif (self::NormalizePassword($NewPassword)
468  != self::NormalizePassword($NewPasswordAgain))
469  {
470  # set status to indicate error
471  $this->Result = U_PASSWORDSDONTMATCH;
472  }
473  else
474  {
475  # set new password
476  $this->SetPassword($NewPassword);
477 
478  # set status to indicate password successfully changed
479  $this->Result = U_OKAY;
480  }
481 
482  # report to caller that everything succeeded
483  return $this->Result;
484  }
485 
486  # set new password
487  public function SetPassword($NewPassword)
488  {
489  # generate encrypted password
490  $EncryptedPassword = crypt(self::NormalizePassword($NewPassword));
491 
492  # save encrypted password
493  $this->UpdateValue("UserPassword", $EncryptedPassword);
494  }
495 
496  public function SetEncryptedPassword($NewEncryptedPassword)
497  {
498  # save encrypted password
499  $this->UpdateValue("UserPassword", $NewEncryptedPassword);
500  }
501 
503  $UserName, $EMail, $EMailAgain,
504  $TemplateFile = "Axis--User--EMailTemplate.txt")
505  {
507  $UserName, $EMail, $EMailAgain, $TemplateFile);
508  }
509 
511  $UserName, $EMail, $EMailAgain,
512  $TemplateFile = "Axis--User--EMailTemplate.txt")
513  {
514  # load e-mail template from file (first line is subject)
515  $Template = file($TemplateFile, 1);
516  $EMailSubject = array_shift($Template);
517  $EMailBody = join("", $Template);
518 
520  $UserName, $EMail, $EMailAgain, $EMailSubject, $EMailBody);
521  }
522 
524  $UserName, $EMail, $EMailAgain, $EMailSubject, $EMailBody)
525  {
526  # make sure e-mail addresses match
527  if ($EMail != $EMailAgain)
528  {
529  $this->Result = U_EMAILSDONTMATCH;
530  return $this->Result;
531  }
532 
533  # make sure e-mail address looks valid
534  if ($this->IsValidLookingEMailAddress($EMail) == FALSE)
535  {
536  $this->Result = U_ILLEGALEMAIL;
537  return $this->Result;
538  }
539 
540  # generate random password
541  $Password = $this->GetRandomPassword();
542 
543  # attempt to create new user with password
544  $Result = $this->CreateNewUser($UserName, $Password, $Password);
545 
546  # if user creation failed
547  if ($Result != U_OKAY)
548  {
549  # report error result to caller
550  return $Result;
551  }
552  # else
553  else
554  {
555  # set e-mail address in user record
556  $this->Set("EMail", $EMail);
557 
558  # plug appropriate values into subject and body of e-mail message
559  $EMailSubject = str_replace("X-USERNAME-X", $UserName, $EMailSubject);
560  $EMailBody = str_replace("X-USERNAME-X", $UserName, $EMailBody);
561  $EMailBody = str_replace("X-PASSWORD-X", $Password, $EMailBody);
562 
563  # send out e-mail message with new account info
564  if (is_Callable(self::$EmailFunc))
565  {
566  $Result = call_user_func(self::$EmailFunc,
567  $EMail, $EMailSubject, $EMailBody,
568  "Auto-Submitted: auto-generated");
569  }
570  else
571  {
572  $Result = mail($EMail, $EMailSubject, $EMailBody,
573  "Auto-Submitted: auto-generated");
574  }
575 
576  # if mailing attempt failed
577  if ($Result != TRUE)
578  {
579  # report error to caller
580  $this->Result = U_MAILINGERROR;
581  return $this->Result;
582  }
583  # else
584  else
585  {
586  # report success to caller
587  $this->Result = U_OKAY;
588  return $this->Result;
589  }
590  }
591  }
592 
593  # get code for user to submit to confirm registration
594  public function GetActivationCode()
595  {
596  # code is MD5 sum based on user name and encrypted password
597  $ActivationCodeLength = 6;
598  return $this->GetUniqueCode("Activation", $ActivationCodeLength);
599  }
600 
601  # check whether confirmation code is valid
602  public function IsActivationCodeGood($Code)
603  {
604  return (strtoupper(trim($Code)) == $this->GetActivationCode())
605  ? TRUE : FALSE;
606  }
607 
608  # get/set whether user registration has been confirmed
609  public function IsActivated($NewValue = DB_NOVALUE)
610  {
611  return $this->UpdateValue("RegistrationConfirmed", $NewValue);
612  }
613 
614  # get code for user to submit to confirm password reset
615  public function GetResetCode()
616  {
617  # code is MD5 sum based on user name and encrypted password
618  $ResetCodeLength = 10;
619  return $this->GetUniqueCode("Reset", $ResetCodeLength);
620  }
621 
622  # check whether password reset code is valid
623  public function IsResetCodeGood($Code)
624  {
625  return (strtoupper(trim($Code)) == $this->GetResetCode())
626  ? TRUE : FALSE;
627  }
628 
629  # get code for user to submit to confirm mail change request
630  public function GetMailChangeCode()
631  {
632  $ResetCodeLength = 10;
633  return $this->GetUniqueCode("MailChange".$this->Get("EMail")
634  .$this->Get("NewEMail"),
635  $ResetCodeLength);
636  }
637 
638  public function IsMailChangeCodeGood($Code)
639  {
640  return (strtoupper(trim($Code)) == $this->GetMailChangeCode())
641  ? TRUE : FALSE;
642  }
643 
644  # send e-mail to user (returns TRUE on success)
645  public function SendEMail(
646  $TemplateTextOrFileName, $FromAddress = NULL, $MoreSubstitutions = NULL,
647  $ToAddress = NULL)
648  {
649  # if template is file name
650  if (@is_file($TemplateTextOrFileName))
651  {
652  # load in template from file
653  $Template = file($TemplateTextOrFileName, 1);
654 
655  # report error to caller if template load failed
656  if ($Template == FALSE)
657  {
658  $this->Status = U_TEMPLATENOTFOUND;
659  return $this->Status;
660  }
661 
662  # join into one text block
663  $TemplateTextOrFileName = join("", $Template);
664  }
665 
666  # split template into lines
667  $Template = explode("\n", $TemplateTextOrFileName);
668 
669  # strip any comments out of template
670  $FilteredTemplate = array();
671  foreach ($Template as $Line)
672  {
673  if (!preg_match("/^[\\s]*#/", $Line))
674  {
675  $FilteredTemplate[] = $Line;
676  }
677  }
678 
679  # split subject line out of template (first non-comment line in file)
680  $EMailSubject = array_shift($FilteredTemplate);
681  $EMailBody = join("\n", $FilteredTemplate);
682 
683  # set up our substitutions
684  $Substitutions = array(
685  "X-USERNAME-X" => $this->Get("UserName"),
686  "X-EMAILADDRESS-X" => $this->Get("EMail"),
687  "X-ACTIVATIONCODE-X" => $this->GetActivationCode(),
688  "X-RESETCODE-X" => $this->GetResetCode(),
689  "X-CHANGECODE-X" => $this->GetMailChangeCode(),
690  "X-IPADDRESS-X" => @$_SERVER["REMOTE_ADDR"],
691  );
692 
693  # if caller provided additional substitutions
694  if (is_array($MoreSubstitutions))
695  {
696  # add in entries from caller to substitution list
697  $Substitutions = array_merge(
698  $Substitutions, $MoreSubstitutions);
699  }
700 
701  # perform substitutions on subject and body of message
702  $EMailSubject = str_replace(array_keys($Substitutions),
703  array_values($Substitutions), $EMailSubject);
704  $EMailBody = str_replace(array_keys($Substitutions),
705  array_values($Substitutions), $EMailBody);
706 
707  $AdditionalHeaders = "Auto-Submitted: auto-generated";
708 
709  # if caller provided "From" address
710  if ($FromAddress)
711  {
712  # prepend "From" address onto message
713  $AdditionalHeaders .= "\r\nFrom: ".$FromAddress;
714  }
715 
716  # send out mail message
717  if (is_Callable(self::$EmailFunc))
718  {
719  $Result = call_user_func(self::$EmailFunc,
720  is_null($ToAddress)?$this->Get("EMail"):$ToAddress,
721  $EMailSubject, $EMailBody, $AdditionalHeaders);
722  }
723  else
724  {
725  $Result = mail(is_null($ToAddress)?$this->Get("EMail"):$ToAddress,
726  $EMailSubject,
727  $EMailBody, $AdditionalHeaders);
728  }
729 
730  # report result of mailing attempt to caller
731  $this->Status = ($Result == TRUE) ? U_OKAY : U_MAILINGERROR;
732  return ($this->Status == U_OKAY);
733  }
734 
735 
736  # ---- Privilege Functions -----------------------------------------------
737 
746  public function HasPriv($Privilege, $Privileges = NULL)
747  {
748  # return FALSE if not associated with a particular user
749  if ($this->UserId === NULL) { return FALSE; }
750 
751  # bail out if empty array of privileges passed in
752  if (is_array($Privilege) && !count($Privilege) && (func_num_args() < 2))
753  { return FALSE; }
754 
755  # set up beginning of database query
756  $Query = "SELECT COUNT(*) AS PrivCount FROM APUserPrivileges "
757  ."WHERE UserId='".$this->UserId."' AND (";
758 
759  # add first privilege(s) to query (first arg may be single value or array)
760  if (is_array($Privilege))
761  {
762  $Sep = "";
763  foreach ($Privilege as $Priv)
764  {
765  $Query .= $Sep."Privilege='".addslashes($Priv)."'";
766  $Sep = " OR ";
767  }
768  }
769  else
770  {
771  $Query .= "Privilege='".$Privilege."'";
772  $Sep = " OR ";
773  }
774 
775  # add any privileges from additional args to query
776  $Args = func_get_args();
777  array_shift($Args);
778  foreach ($Args as $Arg)
779  {
780  $Query .= $Sep."Privilege='".$Arg."'";
781  $Sep = " OR ";
782  }
783 
784  # close out query
785  $Query .= ")";
786 
787  # look for privilege in database
788  $PrivCount = $this->DB->Query($Query, "PrivCount");
789 
790  # return value to caller
791  return ($PrivCount > 0) ? TRUE : FALSE;
792  }
793 
802  public static function GetSqlQueryForUsersWithPriv($Privilege, $Privileges = NULL)
803  {
804  # set up beginning of database query
805  $Query = "SELECT DISTINCT UserId FROM APUserPrivileges "
806  ."WHERE ";
807 
808  # add first privilege(s) to query (first arg may be single value or array)
809  if (is_array($Privilege))
810  {
811  $Sep = "";
812  foreach ($Privilege as $Priv)
813  {
814  $Query .= $Sep."Privilege='".addslashes($Priv)."'";
815  $Sep = " OR ";
816  }
817  }
818  else
819  {
820  $Query .= "Privilege='".$Privilege."'";
821  $Sep = " OR ";
822  }
823 
824  # add any privileges from additional args to query
825  $Args = func_get_args();
826  array_shift($Args);
827  foreach ($Args as $Arg)
828  {
829  $Query .= $Sep."Privilege='".$Arg."'";
830  $Sep = " OR ";
831  }
832 
833  # return query to caller
834  return $Query;
835  }
836 
845  public static function GetSqlQueryForUsersWithoutPriv($Privilege, $Privileges = NULL)
846  {
847  # set up beginning of database query
848  $Query = "SELECT DISTINCT UserId FROM APUserPrivileges "
849  ."WHERE ";
850 
851  # add first privilege(s) to query (first arg may be single value or array)
852  if (is_array($Privilege))
853  {
854  $Sep = "";
855  foreach ($Privilege as $Priv)
856  {
857  $Query .= $Sep."Privilege != '".addslashes($Priv)."'";
858  $Sep = " AND ";
859  }
860  }
861  else
862  {
863  $Query .= "Privilege != '".$Privilege."'";
864  $Sep = " AND ";
865  }
866 
867  # add any privileges from additional args to query
868  $Args = func_get_args();
869  array_shift($Args);
870  foreach ($Args as $Arg)
871  {
872  $Query .= $Sep."Privilege != '".$Arg."'";
873  $Sep = " AND ";
874  }
875 
876  # return query to caller
877  return $Query;
878  }
879 
880  public function GrantPriv($Privilege)
881  {
882  # return error if not associated with a particular user
883  if ($this->UserId === NULL) { return U_NOTLOGGEDIN; }
884 
885  # if privilege value is invalid
886  if (intval($Privilege) != trim($Privilege))
887  {
888  # set code to indicate error
889  $this->Result = U_ERROR;
890  }
891  else
892  {
893  # if user does not already have privilege
894  $PrivCount = $this->DB->Query("SELECT COUNT(*) AS PrivCount"
895  ." FROM APUserPrivileges"
896  ." WHERE UserId='".$this->UserId."'"
897  ." AND Privilege='".$Privilege."'",
898  "PrivCount");
899  if ($PrivCount == 0)
900  {
901  # add privilege for this user to database
902  $this->DB->Query("INSERT INTO APUserPrivileges"
903  ." (UserId, Privilege) VALUES"
904  ." ('".$this->UserId."', ".$Privilege.")");
905  }
906 
907  # set code to indicate success
908  $this->Result = U_OKAY;
909  }
910 
911  # report result to caller
912  return $this->Result;
913  }
914 
915  public function RevokePriv($Privilege)
916  {
917  # return error if not associated with a particular user
918  if ($this->UserId === NULL) { return U_NOTLOGGEDIN; }
919 
920  # remove privilege from database (if present)
921  $this->DB->Query("DELETE FROM APUserPrivileges"
922  ." WHERE UserId = '".$this->UserId."'"
923  ." AND Privilege = '".$Privilege."'");
924 
925  # report success to caller
926  $this->Result = U_OKAY;
927  return $this->Result;
928  }
929 
930  public function GetPrivList()
931  {
932  # return empty list if not associated with a particular user
933  if ($this->UserId === NULL) { return array(); }
934 
935  # read privileges from database and return array to caller
936  $this->DB->Query("SELECT Privilege FROM APUserPrivileges"
937  ." WHERE UserId='".$this->UserId."'");
938  return $this->DB->FetchColumn("Privilege");
939  }
940 
941  public function SetPrivList($NewPrivileges)
942  {
943  # return error if not associated with a particular user
944  if ($this->UserId === NULL) { return U_NOTLOGGEDIN; }
945 
946  # clear old priv list values
947  $this->DB->Query("DELETE FROM APUserPrivileges"
948  ." WHERE UserId='".$this->UserId."'");
949 
950  # for each priv value passed in
951  foreach ($NewPrivileges as $Privilege)
952  {
953  # set priv for user
954  $this->GrantPriv($Privilege);
955  }
956  }
957 
958 
959  # ---- Miscellaneous Functions -------------------------------------------
960 
961  # get unique alphanumeric code for user
962  public function GetUniqueCode($SeedString, $CodeLength)
963  {
964  # return NULL if not associated with a particular user
965  if ($this->UserId === NULL) { return NULL; }
966 
967  return substr(strtoupper(md5(
968  $this->Get("UserName").$this->Get("UserPassword").$SeedString)),
969  0, $CodeLength);
970  }
971 
972 
973  # ---- PRIVATE INTERFACE -------------------------------------------------
974 
975  protected $DB; # handle to SQL database we use to store user information
976  protected $UserId = NULL; # user ID number for reference into database
977  protected $Result; # result of last operation
978  protected $LoggedIn; # flag indicating whether user is logged in
979  private $DBFields; # used for caching user values
980 
981  # optional mail function to use instead of mail()
982  private static $EmailFunc = NULL;
983 
984  # check whether a user name is valid (alphanumeric string of 2-24 chars)
985  public static function IsValidUserName($UserName)
986  {
987  if (preg_match("/^[a-zA-Z0-9]{2,24}$/", $UserName))
988  {
989  return TRUE;
990  }
991  else
992  {
993  return FALSE;
994  }
995  }
996 
997  # check whether a password is valid (at least 6 characters)
998  public static function IsValidPassword($Password)
999  {
1000  if (strlen(self::NormalizePassword($Password)) < 6)
1001  {
1002  return FALSE;
1003  }
1004  else
1005  {
1006  return TRUE;
1007  }
1008  }
1009 
1010  # check whether an e-mail address looks valid
1011  public static function IsValidLookingEMailAddress($EMail)
1012  {
1013  if (preg_match("/^[a-zA-Z0-9._\-]+@[a-zA-Z0-9._\-]+\.[a-zA-Z]{2,3}$/",
1014  $EMail))
1015  {
1016  return TRUE;
1017  }
1018  else
1019  {
1020  return FALSE;
1021  }
1022  }
1023 
1024  # get normalized version of e-mail address
1025  public static function NormalizeEMailAddress($EMailAddress)
1026  {
1027  return strtolower(trim($EMailAddress));
1028  }
1029 
1030  # get normalized version of user name
1031  public static function NormalizeUserName($UserName)
1032  {
1033  return trim($UserName);
1034  }
1035 
1036  # get normalized version of password
1037  public static function NormalizePassword($Password)
1038  {
1039  return trim($Password);
1040  }
1041 
1042  # generate random password
1043  public function GetRandomPassword($PasswordMinLength = 6, $PasswordMaxLength = 8)
1044  {
1045  # seed random number generator
1046  mt_srand((double)microtime() * 1000000);
1047 
1048  # generate password of requested length
1049  return sprintf("%06d", mt_rand(pow(10, ($PasswordMinLength - 1)),
1050  (pow(10, $PasswordMaxLength) - 1)));
1051  }
1052 
1053  # convenience function to supply parameters to Database->UpdateValue()
1054  public function UpdateValue($FieldName, $NewValue = DB_NOVALUE)
1055  {
1056  return $this->DB->UpdateValue("APUsers", $FieldName, $NewValue,
1057  "UserId = '".$this->UserId."'", $this->DBFields);
1058  }
1059 
1060  # methods for backward compatibility with earlier versions of User
1061  public function GivePriv($Privilege)
1062  {
1063  $this->GrantPriv($Privilege);
1064  }
1065 }
Get($FieldName)
Definition: User.php:246
$DB
Definition: User.php:975
GetRandomPassword($PasswordMinLength=6, $PasswordMaxLength=8)
Definition: User.php:1043
static NormalizeUserName($UserName)
Definition: User.php:1031
const U_TEMPLATENOTFOUND
Definition: User.php:37
IsLoggedIn()
Definition: User.php:433
static IsValidLookingEMailAddress($EMail)
Definition: User.php:1011
GetMailChangeCode()
Definition: User.php:630
GetUniqueCode($SeedString, $CodeLength)
Definition: User.php:962
GivePriv($Privilege)
Definition: User.php:1061
__construct($UserInfoOne=NULL, $UserInfoTwo=NULL)
Definition: User.php:45
GrantPriv($Privilege)
Definition: User.php:880
SQL database abstraction object with smart query caching.
Definition: Database.php:22
IsMailChangeCodeGood($Code)
Definition: User.php:638
const U_EMAILSDONTMATCH
Definition: User.php:23
GetResetCode()
Definition: User.php:615
UpdateValue($FieldName, $NewValue=DB_NOVALUE)
Definition: User.php:1054
static NormalizePassword($Password)
Definition: User.php:1037
CreateNewUserAndMailPassword($UserName, $EMail, $EMailAgain, $EMailSubject, $EMailBody)
Definition: User.php:523
GetActivationCode()
Definition: User.php:594
const U_ERROR
Definition: User.php:19
static IsValidPassword($Password)
Definition: User.php:998
const U_NOTLOGGEDIN
Definition: User.php:35
const U_BADPASSWORD
Definition: User.php:20
const U_ILLEGALEMAIL
Definition: User.php:31
Login($UserName, $Password, $IgnorePassword=FALSE)
Definition: User.php:291
Definition: User.php:41
SetEncryptedPassword($NewEncryptedPassword)
Definition: User.php:496
StatusMessage($StatusCode=NULL)
Definition: User.php:121
Delete()
Definition: User.php:158
IsResetCodeGood($Code)
Definition: User.php:623
static IsValidUserName($UserName)
Definition: User.php:985
static GetSqlQueryForUsersWithPriv($Privilege, $Privileges=NULL)
Get an SQL query that will return IDs of all users that have the specified privilege flags...
Definition: User.php:802
GetPasswordSalt($UserName)
Definition: User.php:396
LastLocation($NewLocation=NULL)
Definition: User.php:216
GetPrivList()
Definition: User.php:930
IsActivated($NewValue=DB_NOVALUE)
Definition: User.php:609
HasPriv($Privilege, $Privileges=NULL)
Check whether user has specified privilege(s).
Definition: User.php:746
$LoggedIn
Definition: User.php:978
GetBestName()
Get the best available name associated with a user, i.e., the real name or, if it isn&#39;t available...
Definition: User.php:202
SendEMail($TemplateTextOrFileName, $FromAddress=NULL, $MoreSubstitutions=NULL, $ToAddress=NULL)
Definition: User.php:645
Set($FieldName, $NewValue)
Definition: User.php:278
const DB_NOVALUE
Definition: Database.php:1396
const U_MAILINGERROR
Definition: User.php:36
const U_DUPLICATEUSERNAME
Definition: User.php:24
static SetEmailFunction($NewValue)
Set email function to use instead of mail().
Definition: User.php:177
const U_OKAY
Definition: User.php:18
static NormalizeEMailAddress($EMailAddress)
Definition: User.php:1025
GetDate($FieldName, $Format="")
Definition: User.php:255
const U_DUPLICATEEMAIL
Definition: User.php:38
CreateNewUserWithEMailedPassword($UserName, $EMail, $EMailAgain, $TemplateFile="Axis--User--EMailTemplate.txt")
Definition: User.php:502
Status()
Definition: User.php:115
IsNotLoggedIn()
Definition: User.php:437
Logout()
Definition: User.php:378
LastActiveDate()
Definition: User.php:236
$Result
Definition: User.php:977
CreateNewUserAndMailPasswordFromFile($UserName, $EMail, $EMailAgain, $TemplateFile="Axis--User--EMailTemplate.txt")
Definition: User.php:510
LastIPAddress()
Definition: User.php:240
const U_NOSUCHUSER
Definition: User.php:21
Id()
Definition: User.php:188
SetPassword($NewPassword)
Definition: User.php:487
const U_NOTACTIVATED
Definition: User.php:39
$UserId
Definition: User.php:976
SetPrivList($NewPrivileges)
Definition: User.php:941
ChangePassword($OldPassword, $NewPassword, $NewPasswordAgain)
Definition: User.php:446
IsActivationCodeGood($Code)
Definition: User.php:602
const U_ILLEGALUSERNAME
Definition: User.php:25
RevokePriv($Privilege)
Definition: User.php:915
Name()
Definition: User.php:192
const U_ILLEGALPASSWORD
Definition: User.php:27
static GetSqlQueryForUsersWithoutPriv($Privilege, $Privileges=NULL)
Get an SQL query that will return IDs of all users that do not have the specified privilege flags...
Definition: User.php:845
const U_PASSWORDSDONTMATCH
Definition: User.php:22