Axis--User.php
Go to the documentation of this file.
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 }