00001 <?PHP
00002
00003 #
00004 # Axis--User.php
00005 # An Object for Handling User Information
00006 #
00007 # Copyright 1999-2001 Axis Data
00008 # This code is free software that can be used or redistributed under the
00009 # terms of Version 2 of the GNU General Public License, as published by the
00010 # Free Software Foundation (http://www.fsf.org).
00011 #
00012 # Author: Edward Almasy (almasy@axisdata.com)
00013 #
00014 # Part of the AxisPHP library v1.2.4
00015 # For more information see http://www.axisdata.com/AxisPHP/
00016 #
00017
00018 # status values (error codes)
00019 define("U_OKAY", 0);
00020 define("U_ERROR", 1);
00021 define("U_BADPASSWORD", 2);
00022 define("U_NOSUCHUSER", 3);
00023 define("U_PASSWORDSDONTMATCH", 4);
00024 define("U_EMAILSDONTMATCH", 5);
00025 define("U_DUPLICATEUSERNAME", 6);
00026 define("U_ILLEGALUSERNAME", 7);
00027 define("U_EMPTYUSERNAME", 8);
00028 define("U_ILLEGALPASSWORD", 9);
00029 define("U_ILLEGALPASSWORDAGAIN",10);
00030 define("U_EMPTYPASSWORD", 11);
00031 define("U_EMPTYPASSWORDAGAIN", 12);
00032 define("U_ILLEGALEMAIL", 13);
00033 define("U_ILLEGALEMAILAGAIN", 14);
00034 define("U_EMPTYEMAIL", 15);
00035 define("U_EMPTYEMAILAGAIN", 16);
00036 define("U_NOTLOGGEDIN", 17);
00037 define("U_MAILINGERROR", 18);
00038 define("U_TEMPLATENOTFOUND", 19);
00039 define("U_DUPLICATEEMAIL", 20);
00040
00041
00042 class User {
00043
00044 # ---- PUBLIC INTERFACE --------------------------------------------------
00045
00046 function User(&$SessionOrDb, $UserInfo=NULL)
00047 {
00048 # assume constructor will succeed and user is not logged in
00049 $this->Result = U_OKAY;
00050 $this->LoggedIn = FALSE;
00051
00052 # if a session was passed in
00053 if (is_object($SessionOrDb) && method_exists($SessionOrDb, "Session"))
00054 {
00055 # save pointer to session
00056 $this->Session =& $SessionOrDb;
00057
00058 # swipe database handle from session
00059 $this->DB =& $this->Session->DB;
00060
00061 # if user ID is available from session
00062 if ($this->Session->Get("APUserId") !== NULL)
00063 {
00064 # save user ID
00065 $this->UserId = $this->Session->Get("APUserId");
00066
00067 # set flag indicating user is currently logged in
00068 $this->LoggedIn = TRUE;
00069 }
00070 }
00071 # else if database handle was passed in
00072 elseif (is_object($SessionOrDb)
00073 && method_exists($SessionOrDb, "Database"))
00074 {
00075 # save database handle
00076 $this->DB =& $SessionOrDb;
00077
00078 # if user ID was passed in
00079 if (is_int($UserInfo))
00080 {
00081 # save user ID
00082 $this->UserId = $UserInfo;
00083 }
00084 # else if user name was passed in
00085 elseif (is_string($UserInfo))
00086 {
00087 # look up user ID in database
00088 $this->DB->Query("SELECT UserId FROM APUsers"
00089 ." WHERE UserName='".addslashes($UserInfo)."'");
00090
00091 # if user ID was found
00092 if ($this->DB->NumRowsSelected() > 0)
00093 {
00094 $this->UserId = $this->DB->FetchField("UserId");
00095 }
00096 else
00097 {
00098 # if name looks like it could actually be a user ID
00099 if (preg_match("/^[-]*[0-9]+$/", $UserInfo))
00100 {
00101 # assume name was user ID
00102 $this->UserId = $UserInfo;
00103 }
00104 else
00105 {
00106 # set code indicating no user found
00107 $this->Result = U_NOSUCHUSER;
00108 }
00109 }
00110 }
00111 }
00112 else
00113 {
00114 # error out
00115 $this->Result = U_ERROR;
00116 exit("ERROR: User object creation attempted without DB or session");
00117 }
00118 }
00119
00120 function Status()
00121 {
00122 return $this->Result;
00123 }
00124
00125 # return text message corresponding to current (or specified) status code
00126 function StatusMessage($StatusCode = NULL)
00127 {
00128 $APUserStatusMessages = array(
00129 U_OKAY => "The operation was successful.",
00130 U_ERROR => "There has been an error.",
00131 U_BADPASSWORD => "The password you entered was"
00132 ." incorrect.",
00133 U_NOSUCHUSER => "No such user name was found.",
00134 U_PASSWORDSDONTMATCH => "The new passwords you entered do"
00135 ." not match.",
00136 U_EMAILSDONTMATCH => "The e-mail addresses you entered"
00137 ." do not match.",
00138 U_DUPLICATEUSERNAME => "The user name you requested is"
00139 ." already in use.",
00140 U_ILLEGALUSERNAME => "The user name you requested is too"
00141 ." short, too long, or contains"
00142 ." illegal characters.",
00143 U_ILLEGALPASSWORD => "The new password you requested is"
00144 ." too short, too long, or"
00145 ." contains illegal characters.",
00146 U_ILLEGALEMAIL => "The e-mail address you entered"
00147 ." appears to be invalid.",
00148 U_NOTLOGGEDIN => "The user is not logged in.",
00149 U_MAILINGERROR => "An error occurred while attempting"
00150 ." to send e-mail. Please notify"
00151 ." the system administrator.",
00152 U_TEMPLATENOTFOUND => "An error occurred while attempting"
00153 ." to generate e-mail. Please"
00154 ." notify the system administrator.",
00155 U_DUPLICATEEMAIL => "The e-mail address you supplied already"
00156 ." has an account associated with it.",
00157 );
00158
00159 return ($StatusCode === NULL) ? $APUserStatusMessages[$this->Result]
00160 : $APUserStatusMessages[$StatusCode];
00161 }
00162
00163 function Delete()
00164 {
00165 # clear priv list values
00166 $this->DB->Query("DELETE FROM APUserPrivileges WHERE UserId = '".$this->UserId."'");
00167
00168 # delete user record from database
00169 $this->DB->Query("DELETE FROM APUsers WHERE UserId = '".$this->UserId."'");
00170
00171 # report to caller that everything succeeded
00172 $this->Result = U_OKAY;
00173 return $this->Result;
00174 }
00175
00176
00177 # ---- Getting/Setting Values --------------------------------------------
00178
00179 function Id()
00180 {
00181 return $this->UserId;
00182 }
00183 function Name()
00184 {
00185 return $this->Get("UserName");
00186 }
00187 function LastLocation($NewLocation = NULL)
00188 {
00189 if ($NewLocation)
00190 {
00191 $this->DB->Query("UPDATE APUsers SET"
00192 ." LastLocation = '".addslashes($NewLocation)."',"
00193 ." LastActiveDate = NOW(),"
00194 ." LastIPAddress = '".$_SERVER["REMOTE_ADDR"]."'"
00195 ." WHERE UserId = '".addslashes($this->UserId)."'");
00196 if (isset($this->DBFields))
00197 {
00198 $this->DBFields["LastLocation"] = $NewLocation;
00199 $this->DBFields["LastActiveDate"] = date("Y-m-d H:i:s");
00200 }
00201 }
00202 return $this->Get("LastLocation");
00203 }
00204 function LastActiveDate()
00205 {
00206 return $this->Get("LastActiveDate");
00207 }
00208 function LastIPAddress()
00209 {
00210 return $this->Get("LastIPAddress");
00211 }
00212
00213 # get value from specified field
00214 function Get($FieldName)
00215 {
00216 return $this->UpdateValue($FieldName);
00217 }
00218
00219 # get value (formatted as a date) from specified field
00220 function GetDate($FieldName, $Format = "")
00221 {
00222 # retrieve specified value from database
00223 if (strlen($Format) > 0)
00224 {
00225 $this->DB->Query("SELECT DATE_FORMAT(`".addslashes($FieldName)."`, '".addslashes($Format)."') AS `".addslashes($FieldName)."` FROM APUsers WHERE UserId='".$this->UserId."'");
00226 }
00227 else
00228 {
00229 $this->DB->Query("SELECT `".addslashes($FieldName)."` FROM APUsers WHERE UserId='".$this->UserId."'");
00230 }
00231 $Record = $this->DB->FetchRow();
00232
00233 # return value to caller
00234 return $Record[$FieldName];
00235 }
00236
00237 # set value in specified field
00238 function Set($FieldName, $NewValue)
00239 {
00240 $this->UpdateValue($FieldName, $NewValue);
00241 $this->Result = U_OKAY;
00242 return $this->Result;
00243 }
00244
00245
00246 # ---- Login Functions ---------------------------------------------------
00247
00248 function Login($UserName, $Password, $IgnorePassword = FALSE)
00249 {
00250 global $APUserId;
00251
00252 # error out if we are not part of a session
00253 if (!isset($this->Session))
00254 {
00255 exit("ERROR: User->Login() called on object without session");
00256 }
00257
00258 # if user not found in DB
00259 $this->DB->Query("SELECT * FROM APUsers"
00260 ." WHERE UserName = '"
00261 .addslashes(self::NormalizeUserName($UserName))."'");
00262 if ($this->DB->NumRowsSelected() < 1)
00263 {
00264 # result is no user by that name
00265 $this->Result = U_NOSUCHUSER;
00266 }
00267 else
00268 {
00269 # grab password from DB
00270 $Record = $this->DB->FetchRow();
00271 $StoredPassword = $Record["UserPassword"];
00272
00273 if (isset($Password[0]) && $Password[0] == " ")
00274 {
00275 $Challenge = md5(date("Ymd").$_SERVER["REMOTE_ADDR"]);
00276 $StoredPassword = md5( $Challenge . $StoredPassword );
00277
00278 $EncryptedPassword = trim($Password);
00279 }
00280 else
00281 {
00282 # if supplied password matches encrypted password
00283 $EncryptedPassword = crypt($Password, $StoredPassword);
00284 }
00285
00286 if (($EncryptedPassword == $StoredPassword) || $IgnorePassword)
00287 {
00288 # result is success
00289 $this->Result = U_OKAY;
00290
00291 # store user ID for session
00292 $this->UserId = $Record["UserId"];
00293 $APUserId = $this->UserId;
00294 $this->Session->RegisterVariable("APUserId");
00295
00296 # update last login date
00297 $this->DB->Query("UPDATE APUsers SET LastLoginDate = NOW() "
00298 ."WHERE UserId = '".$this->UserId."'");
00299
00300 # Check for old format hashes, and rehash if possible
00301 if ($EncryptedPassword === $StoredPassword &&
00302 substr($StoredPassword,0,3) !== "$1$" &&
00303 $Password[0] !== " " &&
00304 CRYPT_MD5 )
00305 {
00306 $NewPassword = crypt($Password);
00307 $this->DB->Query(
00308 "UPDATE APUsers SET UserPassword='".addslashes($NewPassword)."' "
00309 ."WHERE UserId='".$this->UserId."'");
00310 }
00311
00312 # since self::DBFields might already have been set to false if
00313 # the user wasn't logged in when this is called, populate it
00314 # with user data so that a call to self::UpdateValue will be
00315 # able to properly fetch the data associated with the user
00316 $this->DBFields = $Record;
00317
00318 # set flag to indicate we are logged in
00319 $this->LoggedIn = TRUE;
00320 }
00321 else
00322 {
00323 # result is bad password
00324 $this->Result = U_BADPASSWORD;
00325 }
00326 }
00327
00328 # return result to caller
00329 return $this->Result;
00330 }
00331
00332 # log this user out
00333 function Logout()
00334 {
00335 # if we are part of a session
00336 if (isset($this->Session))
00337 {
00338 # clear user ID for session
00339 $this->Session->UnregisterVariable("APUserId");
00340 }
00341
00342 # set flag to indicate user is no longer logged in
00343 $this->LoggedIn = FALSE;
00344 }
00345
00346 function GetPasswordSalt($UserName)
00347 {
00348 $this->DB->Query(
00349 "SELECT * FROM APUsers WHERE UserName = '"
00350 .addslashes(self::NormalizeUserName($UserName))."'");
00351
00352 if ($this->DB->NumRowsSelected() < 1)
00353 {
00354 # result is no user by that name, generate a fake salt
00355 # to discourage user enumeration. Make it be an old-format
00356 # crypt() salt so that it's harder.
00357 $SaltString = $_SERVER["SERVER_ADDR"].$UserName;
00358 $Result = substr(base64_encode(md5($SaltString)),0,2);
00359 }
00360 else
00361 {
00362 # grab password from DB
00363 # Assumes that we used php's crypt() for the passowrd
00364 # management stuff, and will need to be changed if we
00365 # go to something else.
00366 $Record = $this->DB->FetchRow();
00367 $StoredPassword = $Record["UserPassword"];
00368
00369 if (substr($StoredPassword,0,3)==="$1$")
00370 {
00371 $Result = substr($StoredPassword, 0,12);
00372 }
00373 else
00374 {
00375 $Result = substr($StoredPassword, 0,2);
00376 }
00377 }
00378
00379 return $Result;
00380 }
00381
00382 # report whether this user is or is not currently logged in
00383 function IsLoggedIn() { return $this->LoggedIn; }
00384 function IsNotLoggedIn() { return !$this->LoggedIn; }
00385
00386
00387 # ---- Password Functions ------------------------------------------------
00388
00389 # set new password (with checks against old password)
00390 function ChangePassword($OldPassword, $NewPassword, $NewPasswordAgain)
00391 {
00392 # if we are part of a session make sure a user is logged in
00393 if (isset($this->Session) && ($this->IsLoggedIn() == FALSE))
00394 {
00395 $this->Result = U_NOTLOGGEDIN;
00396 return $this->Result;
00397 }
00398
00399 # if old password is not correct
00400 $StoredPassword = $this->DB->Query("SELECT UserPassword FROM APUsers"
00401 ." WHERE UserId='".$this->UserId."'", "UserPassword");
00402 $EncryptedPassword = crypt($OldPassword, $StoredPassword);
00403 if ($EncryptedPassword != $StoredPassword)
00404 {
00405 # set status to indicate error
00406 $this->Result = U_BADPASSWORD;
00407 }
00408 # else if new password is not legal
00409 elseif (!$this->IsValidPassword($NewPassword))
00410 {
00411 # set status to indicate error
00412 $this->Result = U_ILLEGALPASSWORD;
00413 }
00414 # else if both instances of new password do not match
00415 elseif (self::NormalizePassword($NewPassword)
00416 != self::NormalizePassword($NewPasswordAgain))
00417 {
00418 # set status to indicate error
00419 $this->Result = U_PASSWORDSDONTMATCH;
00420 }
00421 else
00422 {
00423 # set new password
00424 $this->SetPassword($NewPassword);
00425
00426 # set status to indicate password successfully changed
00427 $this->Result = U_OKAY;
00428 }
00429
00430 # report to caller that everything succeeded
00431 return $this->Result;
00432 }
00433
00434 # set new password
00435 function SetPassword($NewPassword)
00436 {
00437 # generate encrypted password
00438 $EncryptedPassword = crypt(self::NormalizePassword($NewPassword));
00439
00440 # save encrypted password
00441 $this->UpdateValue("UserPassword", $EncryptedPassword);
00442 }
00443
00444 function CreateNewUserWithEMailedPassword(
00445 $UserName, $EMail, $EMailAgain,
00446 $TemplateFile = "Axis--User--EMailTemplate.txt")
00447 {
00448 return CreateNewUserAndMailPasswordFromFile(
00449 $UserName, $EMail, $EMailAgain, $TemplateFile);
00450 }
00451
00452 function CreateNewUserAndMailPasswordFromFile(
00453 $UserName, $EMail, $EMailAgain,
00454 $TemplateFile = "Axis--User--EMailTemplate.txt")
00455 {
00456 # load e-mail template from file (first line is subject)
00457 $Template = file($TemplateFile, 1);
00458 $EMailSubject = array_shift($Template);
00459 $EMailBody = join("", $Template);
00460
00461 return CreateNewUserAndMailPassword(
00462 $UserName, $EMail, $EMailAgain, $EMailSubject, $EMailBody);
00463 }
00464
00465 function CreateNewUserAndMailPassword(
00466 $UserName, $EMail, $EMailAgain, $EMailSubject, $EMailBody)
00467 {
00468 # make sure e-mail addresses match
00469 if ($EMail != $EMailAgain)
00470 {
00471 $this->Result = U_EMAILSDONTMATCH;
00472 return $this->Result;
00473 }
00474
00475 # make sure e-mail address looks valid
00476 if ($this->IsValidLookingEMailAddress($EMail) == FALSE)
00477 {
00478 $this->Result = U_ILLEGALEMAIL;
00479 return $this->Result;
00480 }
00481
00482 # generate random password
00483 $Password = $this->GetRandomPassword();
00484
00485 # attempt to create new user with password
00486 $Result = $this->CreateNewUser($UserName, $Password, $Password);
00487
00488 # if user creation failed
00489 if ($Result != U_OKAY)
00490 {
00491 # report error result to caller
00492 return $Result;
00493 }
00494 # else
00495 else
00496 {
00497 # set e-mail address in user record
00498 $this->Set("EMail", $EMail);
00499
00500 # plug appropriate values into subject and body of e-mail message
00501 $EMailSubject = str_replace("X-USERNAME-X", $UserName, $EMailSubject);
00502 $EMailBody = str_replace("X-USERNAME-X", $UserName, $EMailBody);
00503 $EMailBody = str_replace("X-PASSWORD-X", $Password, $EMailBody);
00504
00505 # send out e-mail message with new account info
00506 $Result = mail($EMail, $EMailSubject, $EMailBody,
00507 "Auto-Submitted: auto-generated");
00508
00509 # if mailing attempt failed
00510 if ($Result != TRUE)
00511 {
00512 # report error to caller
00513 $this->Result = U_MAILINGERROR;
00514 return $this->Result;
00515 }
00516 # else
00517 else
00518 {
00519 # report success to caller
00520 $this->Result = U_OKAY;
00521 return $this->Result;
00522 }
00523 }
00524 }
00525
00526 # get code for user to submit to confirm registration
00527 function GetActivationCode()
00528 {
00529 # code is MD5 sum based on user name and encrypted password
00530 $ActivationCodeLength = 6;
00531 return $this->GetUniqueCode("Activation", $ActivationCodeLength);
00532 }
00533
00534 # check whether confirmation code is valid
00535 function IsActivationCodeGood($Code)
00536 {
00537 return (strtoupper(trim($Code)) == $this->GetActivationCode())
00538 ? TRUE : FALSE;
00539 }
00540
00541 # get/set whether user registration has been confirmed
00542 function IsActivated($NewValue = DB_NOVALUE)
00543 {
00544 return $this->UpdateValue("RegistrationConfirmed", $NewValue);
00545 }
00546
00547 # get code for user to submit to confirm password reset
00548 function GetResetCode()
00549 {
00550 # code is MD5 sum based on user name and encrypted password
00551 $ResetCodeLength = 10;
00552 return $this->GetUniqueCode("Reset", $ResetCodeLength);
00553 }
00554
00555 # check whether password reset code is valid
00556 function IsResetCodeGood($Code)
00557 {
00558 return (strtoupper(trim($Code)) == $this->GetResetCode())
00559 ? TRUE : FALSE;
00560 }
00561
00562 # get code for user to submit to confirm mail change request
00563 function GetMailChangeCode()
00564 {
00565 $ResetCodeLength = 10;
00566
00567 return $this->GetUniqueCode("MailChange".$this->Get("EMail").$this->Get("NewEMail"),
00568 $ResetCodeLength);
00569 }
00570
00571 function IsMailChangeCodeGood($Code)
00572 {
00573 return (strtoupper(trim($Code)) == $this->GetMailChangeCode())
00574 ? TRUE : FALSE;
00575 }
00576
00577 # send e-mail to user (returns TRUE on success)
00578 function SendEMail(
00579 $TemplateTextOrFileName, $FromAddress = NULL, $MoreSubstitutions = NULL,
00580 $ToAddress = NULL)
00581 {
00582 # if template is file name
00583 if (@is_file($TemplateTextOrFileName))
00584 {
00585 # load in template from file
00586 $Template = file($TemplateTextOrFileName, 1);
00587
00588 # report error to caller if template load failed
00589 if ($Template == FALSE)
00590 {
00591 $this->Status = U_TEMPLATENOTFOUND;
00592 return $this->Status;
00593 }
00594
00595 # join into one text block
00596 $TemplateTextOrFileName = join("", $Template);
00597 }
00598
00599 # split template into lines
00600 $Template = explode("\n", $TemplateTextOrFileName);
00601
00602 # strip any comments out of template
00603 $FilteredTemplate = array();
00604 foreach ($Template as $Line)
00605 {
00606 if (!preg_match("/^[\\s]*#/", $Line))
00607 {
00608 $FilteredTemplate[] = $Line;
00609 }
00610 }
00611
00612 # split subject line out of template (first non-comment line in file)
00613 $EMailSubject = array_shift($FilteredTemplate);
00614 $EMailBody = join("\n", $FilteredTemplate);
00615
00616 # set up our substitutions
00617 $Substitutions = array(
00618 "X-USERNAME-X" => $this->Get("UserName"),
00619 "X-EMAILADDRESS-X" => $this->Get("EMail"),
00620 "X-ACTIVATIONCODE-X" => $this->GetActivationCode(),
00621 "X-RESETCODE-X" => $this->GetResetCode(),
00622 "X-CHANGECODE-X" => $this->GetMailChangeCode(),
00623 "X-IPADDRESS-X" => @$_SERVER["REMOTE_ADDR"],
00624 );
00625
00626 # if caller provided additional substitutions
00627 if (is_array($MoreSubstitutions))
00628 {
00629 # add in entries from caller to substitution list
00630 $Substitutions = array_merge(
00631 $Substitutions, $MoreSubstitutions);
00632 }
00633
00634 # perform substitutions on subject and body of message
00635 $EMailSubject = str_replace(array_keys($Substitutions),
00636 array_values($Substitutions), $EMailSubject);
00637 $EMailBody = str_replace(array_keys($Substitutions),
00638 array_values($Substitutions), $EMailBody);
00639
00640 $AdditionalHeaders = "Auto-Submitted: auto-generated";
00641
00642 # if caller provided "From" address
00643 if ($FromAddress)
00644 {
00645 # prepend "From" address onto message
00646 $AdditionalHeaders .= "\r\nFrom: ".$FromAddress;
00647 }
00648
00649 # send out mail message
00650 $Result = mail(is_null($ToAddress)?$this->Get("EMail"):$ToAddress,
00651 $EMailSubject,
00652 $EMailBody, $AdditionalHeaders);
00653
00654 # report result of mailing attempt to caller
00655 $this->Status = ($Result == TRUE) ? U_OKAY : U_MAILINGERROR;
00656 return ($this->Status == U_OKAY);
00657 }
00658
00659
00660 # ---- Privilege Functions -----------------------------------------------
00661
00670 function HasPriv($Privilege)
00671 {
00672 # make sure a user is logged in (no privileges if not logged in)
00673 if ($this->IsLoggedIn() == FALSE) { return FALSE; }
00674
00675 # set up beginning of database query
00676 $Query = "SELECT COUNT(*) AS PrivCount FROM APUserPrivileges "
00677 ."WHERE UserId='".$this->UserId."' AND (";
00678
00679 # add first privilege(s) to query (first arg may be single value or array)
00680 if (is_array($Privilege))
00681 {
00682 $Sep = "";
00683 foreach ($Privilege as $Priv)
00684 {
00685 $Query .= $Sep."Privilege='".addslashes($Priv)."'";
00686 $Sep = " OR ";
00687 }
00688 }
00689 else
00690 {
00691 $Query .= "Privilege='".$Privilege."'";
00692 $Sep = " OR ";
00693 }
00694
00695 # add any privileges from additional args to query
00696 $Args = func_get_args();
00697 array_shift($Args);
00698 foreach ($Args as $Arg)
00699 {
00700 $Query .= $Sep."Privilege='".$Arg."'";
00701 $Sep = " OR ";
00702 }
00703
00704 # close out query
00705 $Query .= ")";
00706
00707 # look for privilege in database
00708 $PrivCount = $this->DB->Query($Query, "PrivCount");
00709
00710 # return value to caller
00711 return ($PrivCount > 0) ? TRUE : FALSE;
00712 }
00713
00722 static function GetSqlQueryForUsersWithPriv($Privilege)
00723 {
00724 # set up beginning of database query
00725 $Query = "SELECT UserId FROM APUserPrivileges "
00726 ."WHERE ";
00727
00728 # add first privilege(s) to query (first arg may be single value or array)
00729 if (is_array($Privilege))
00730 {
00731 $Sep = "";
00732 foreach ($Privilege as $Priv)
00733 {
00734 $Query .= $Sep."Privilege='".addslashes($Priv)."'";
00735 $Sep = " OR ";
00736 }
00737 }
00738 else
00739 {
00740 $Query .= "Privilege='".$Privilege."'";
00741 $Sep = " OR ";
00742 }
00743
00744 # add any privileges from additional args to query
00745 $Args = func_get_args();
00746 array_shift($Args);
00747 foreach ($Args as $Arg)
00748 {
00749 $Query .= $Sep."Privilege='".$Arg."'";
00750 $Sep = " OR ";
00751 }
00752
00753 # return query to caller
00754 return $Query;
00755 }
00756
00757 function GrantPriv($Privilege)
00758 {
00759 # if privilege value is invalid
00760 if (intval($Privilege) != trim($Privilege))
00761 {
00762 # set code to indicate error
00763 $this->Result = U_ERROR;
00764 }
00765 else
00766 {
00767 # if user does not already have privilege
00768 $PrivCount = $this->DB->Query("SELECT COUNT(*) AS PrivCount"
00769 ." FROM APUserPrivileges"
00770 ." WHERE UserId='".$this->UserId."'"
00771 ." AND Privilege='".$Privilege."'",
00772 "PrivCount");
00773 if ($PrivCount == 0)
00774 {
00775 # add privilege for this user to database
00776 $this->DB->Query("INSERT INTO APUserPrivileges"
00777 ." (UserId, Privilege) VALUES"
00778 ." ('".$this->UserId."', ".$Privilege.")");
00779 }
00780
00781 # set code to indicate success
00782 $this->Result = U_OKAY;
00783 }
00784
00785 # report result to caller
00786 return $this->Result;
00787 }
00788
00789 function RevokePriv($Privilege)
00790 {
00791 # remove privilege from database (if present)
00792 $this->DB->Query("DELETE FROM APUserPrivileges"
00793 ." WHERE UserId = '".$this->UserId."'"
00794 ." AND Privilege = '".$Privilege."'");
00795
00796 # report success to caller
00797 $this->Result = U_OKAY;
00798 return $this->Result;
00799 }
00800
00801 function GetPrivList()
00802 {
00803 # read privileges from database and return array to caller
00804 $this->DB->Query("SELECT Privilege FROM APUserPrivileges"
00805 ." WHERE UserId='".$this->UserId."'");
00806 return $this->DB->FetchColumn("Privilege");
00807 }
00808
00809 function SetPrivList($NewPrivileges)
00810 {
00811 # clear old priv list values
00812 $this->DB->Query("DELETE FROM APUserPrivileges"
00813 ." WHERE UserId='".$this->UserId."'");
00814
00815 # for each priv value passed in
00816 foreach ($NewPrivileges as $Privilege)
00817 {
00818 # set priv for user
00819 $this->GrantPriv($Privilege);
00820 }
00821 }
00822
00823
00824 # ---- Miscellaneous Functions -------------------------------------------
00825
00826 # get unique alphanumeric code for user
00827 function GetUniqueCode($SeedString, $CodeLength)
00828 {
00829 return substr(strtoupper(md5(
00830 $this->Get("UserName").$this->Get("UserPassword").$SeedString)),
00831 0, $CodeLength);
00832 }
00833
00834
00835 # ---- PRIVATE INTERFACE -------------------------------------------------
00836
00837 var $DB; # handle to SQL database we use to store user information
00838 var $Session; # session to use in storing persistent information
00839 var $UserId; # user ID number for reference into database
00840 var $Result; # result of last operation
00841 var $LoggedIn; # flag indicating whether user is logged in
00842 var $DBFields; # used for caching user values
00843
00844 # check whether a user name is valid (alphanumeric string of 2-24 chars)
00845 static function IsValidUserName($UserName)
00846 {
00847 if (preg_match("/^[a-zA-Z0-9]{2,24}$/", $UserName)) { return TRUE; } else { return FALSE; }
00848 }
00849
00850 # check whether a password is valid (at least 6 characters)
00851 static function IsValidPassword($Password)
00852 {
00853 if (strlen(self::NormalizePassword($Password)) < 6)
00854 { return FALSE; } else { return TRUE; }
00855 }
00856
00857 # check whether an e-mail address looks valid
00858 static function IsValidLookingEMailAddress($EMail)
00859 {
00860 if (preg_match("/^[a-zA-Z0-9._\-]+@[a-zA-Z0-9._\-]+\.[a-zA-Z]{2,3}$/", $EMail)) { return TRUE; } else { return FALSE; }
00861 }
00862
00863 # get normalized version of e-mail address
00864 static function NormalizeEMailAddress($EMailAddress)
00865 {
00866 return strtolower(trim($EMailAddress));
00867 }
00868
00869 # get normalized version of user name
00870 static function NormalizeUserName($UserName)
00871 {
00872 return trim($UserName);
00873 }
00874
00875 # get normalized version of password
00876 static function NormalizePassword($Password)
00877 {
00878 return trim($Password);
00879 }
00880
00881 # generate random password
00882 function GetRandomPassword($PasswordMinLength = 6, $PasswordMaxLength = 8)
00883 {
00884 # seed random number generator
00885 mt_srand((double)microtime() * 1000000);
00886
00887 # generate password of requested length
00888 return sprintf("%06d", mt_rand(pow(10, ($PasswordMinLength - 1)),
00889 (pow(10, $PasswordMaxLength) - 1)));
00890 }
00891
00892 # convenience function to supply parameters to Database->UpdateValue()
00893 function UpdateValue($FieldName, $NewValue = DB_NOVALUE)
00894 {
00895 return $this->DB->UpdateValue("APUsers", $FieldName, $NewValue,
00896 "UserId = '".$this->UserId."'", $this->DBFields);
00897 }
00898
00899 # methods for backward compatibility with earlier versions of User
00900 function GivePriv($Privilege) { $this->GrantPriv($Privilege); }
00901
00902 }