User management for the world wide web

Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members

Login.php

00001 <?php
00002 session_start();
00003 
00011 class GenieGate_Api_User {
00012 
00013     //  Holds all the info, to make session serialization easier.
00014     var $FIELDS;
00015 
00016     var $L;
00017 
00018     var $PROPS;
00019 
00027     function GenieGate_Api_User($l,$info) {
00028         $this->FIELDS = $info;
00029         $this->L = $l;
00030     }
00048     function getProperties($section = "genie.form.Public"){
00049         if(! isset($this->PROPS[$section])){
00050             $this->PROPS[$section] = array(); // Force an is_set next time.
00051             $sect = mysql_escape_string($section);
00052             // Get our table names.
00053             $ua_psect = $this->L->_make_table_name("ua_psect");
00054             $ua_prnam = $this->L->_make_table_name("ua_prnam");
00055             $ua_prop = $this->L->_make_table_name("ua_prop");
00056             $uid = mysql_escape_string($this->getUserId());        
00057             $sql = "SELECT n.pkey,p.val FROM $ua_psect AS s, $ua_prnam AS n, $ua_prop AS p ";
00058             $sql .= "WHERE p.uid='$uid' AND skey='$sect' AND s.sid=n.sid AND p.prid=n.prid";
00059             $dbh = $this->L->_get_dbh();
00060             $result = mysql_query($sql,$dbh) or die(mysql_error($dbh));
00061             if($result){
00062                 while($row = mysql_fetch_row($result)){
00063                     $k = $row[0];
00064                     $this->PROPS[$section][$k] = $row[1];
00065                 }
00066             }
00067         }
00068         return($this->PROPS[$section]);
00069     }
00070 
00079     function checkPassword($password){
00080         return(crypt($password,$this->FIELDS[password]) == $this->FIELDS[password]);
00081     }
00090     function checkSessionKey($key){
00091         return(crypt($key,$this->FIELDS[SESSION_KEY]) == $this->FIELDS[SESSION_KEY]);
00092     }
00098     function isActivated() {
00099         return($this->FIELDS[confirm] == "Y");
00100     }
00101 
00108     function getName(){ return($this->FIELDS[name]); }
00109 
00115     function getUserId(){ return($this->FIELDS[uid]); }
00116     
00122     function getEmail(){ return($this->FIELDS[email]); }
00123 
00128     function getGroups() { 
00129         if(is_array($this->FIELDS[GROUPS])){
00130             return($this->FIELDS[GROUPS]); 
00131         }
00132         return(array());
00133     }
00134 
00135     
00136 
00143     function checkGroups(&$groups){
00144         $member = $this->FIELDS[GROUPS];
00145         if(! $member){
00146             $member = array();
00147         }
00148         foreach($groups as $gid){
00149             if(! in_array($gid,$member)){
00150                 return(FALSE);
00151             }
00152         }
00153         return(TRUE);
00154     }
00155 }
00156 
00194 class GenieGate_Api_Login {
00198     var $DBH;
00199 
00203     var $DBN;
00204 
00218     var $FORM_USERID   = "GG_USERID";
00226     var $FORM_PASSWORD = "GG_PASSWORD";
00227 
00235     var $VIEW = FALSE;
00236 
00245     var $SESSION_VARIABLE = "GG_USERACC";
00246     
00252     var $REALM = "Restricted";
00253 
00258     var $USE_HTTP_AUTH = TRUE;
00259 
00269     var $CHECK_IP = FALSE;
00270 
00276     var $DB_PERSISTANT = TRUE;
00277 
00288     var $ALLOW_CACHE = FALSE;
00289 
00298     var $SESSION_KEY_NAME="GGSESKEY";
00299     
00300     // The session key that was either read or generated. Don't use.    
00301     var $SESSION_KEY = FALSE;
00302 
00303 
00317     function GenieGate_Api_Login($DBLink = FALSE, $DBName = FALSE){
00318         $this->_session_key(); // Initialize as soon as possible.
00319         if($DBLink){
00320             $this->DBH = $DBLink;
00321         }
00322         if($DBName){
00323             $this->DBN = $DBName;
00324         }
00325     }
00326 
00327 
00341     function login($groups = array()){        
00342         $user = $this->passiveLogin($groups);
00343         if(! $user){
00344             $this->prompt();
00345             exit();
00346         }
00347         return($user);
00348     }
00349 
00360     function passiveLogin($groups = array()){
00361         // Comming in from a form?        
00362         if(strlen($_REQUEST[$this->FORM_USERID])){
00363             $user = $this->_check_form();            
00364             if($user){
00365                 return($this->_valid_or_false($user,$groups));
00366             }
00367         }        
00368         $user = $this->_check_session();
00369         if($user){         
00370             return($this->_valid_or_false($user,$groups));                     
00371         }
00372         return($this->_valid_or_false($this->_check_auth(),$groups));
00373     }
00374 
00375     // Activated? In all groups?
00376     //\internal
00377     function _valid_or_false($user,$groups){
00378         if(! $user){
00379             $this->_clear_session();  
00380             return(FALSE);
00381         }
00382         if($user->isActivated()){        
00383             if($user->checkGroups($groups)){ 
00384                 return($user);
00385             }
00386         }
00387         $this->_clear_session();  
00388         return(FALSE);
00389     }
00390 
00391 
00392     // Get/Set the session key. (Needed for session based login)
00393     // this will set a cookie.
00394     function _session_key(){
00395         if(! $this->SESSION_KEY) {
00396             $cv = $this->SESSION_KEY_NAME;
00397             if(! $_COOKIE[$cv]){
00398                 $this->SESSION_KEY = md5(uniqid(rand(),1)); 
00399                 setcookie($cv,$this->SESSION_KEY,FALSE,"/");               
00400             }else{
00401                 $this->SESSION_KEY = $_COOKIE[$cv];
00402             }
00403         }
00404         return($this->SESSION_KEY);
00405     }
00406 
00407 
00414     function logout(){
00415         $this->_clear_session();
00416     }
00417 
00429     function setPromptView(&$view){
00430         $this->VIEW = $view;
00431     }
00432 
00443     function prompt(){
00444         $this->_send_authenicate_header();
00445         if(! $this->VIEW){
00446             $this->_default_prompt_html();
00447             exit;
00448         }
00449         if(is_object($this->VIEW)){
00450             $this->VIEW->display();
00451         }else{
00452             include($this->VIEW);
00453         }
00454         exit();
00455     }
00456     
00457     function _send_authenicate_header(){
00458         if($this->USE_HTTP_AUTH){
00459             if(! headers_sent()){
00460                 header('WWW-Authenticate: Basic realm="' . $this->REALM . '"');
00461                 header('HTTP/1.0 401 Unauthorized');
00462             }
00463         }
00464     }
00465 
00466     // Check authentication method.
00467     function _check_auth(){     
00468         if(! $this->USE_HTTP_AUTH){
00469             return(FALSE);
00470         }
00471         $this->_clear_session();                 
00472         $user = $this->lookupUser($_SERVER['PHP_AUTH_USER']);
00473         if($user){                                 
00474             if($user->checkPassword($_SERVER['PHP_AUTH_PW'])){                
00475                 $this->_store_in_session($user);              
00476                 return($user);
00477             }else{
00478                 return(FALSE);
00479             }
00480         }
00481         return(FALSE);
00482     }
00483 
00484     // Look in session.
00485     function _check_session(){                               
00486         $sv = $this->SESSION_VARIABLE;                
00487         if(is_array($_SESSION[$sv])){            
00488             $user = new GenieGate_Api_User($this,$_SESSION[$sv][USER]);                      
00489             if($this->CHECK_IP) {
00490                 if($_SESSION[$sv][LAST_IP] != $_SERVER[REMOTE_ADDR]){                    
00491                     return(FALSE);
00492                 }
00493             }
00494             // Session key correct?
00495             if($user->checkSessionKey($this->_session_key())){ 
00496                 if($this->ALLOW_CACHE){
00497                     return($user);
00498                 }else{
00499                     // refresh.
00500                     $id = $user->getUserId();                   
00501                     $user = $this->lookupUser($id);                  
00502                     $this->_store_in_session($user);
00503                     return($user);
00504                 }
00505             }else{
00506                 return(FALSE); // Would fall through anyway, but we want the logic clearer.
00507             }
00508         }                
00509         return(FALSE); // Not in session.
00510     }
00511 
00512     // Inspect the form, return GenieGate_Api_User on PASS.
00513     function _check_form(){
00514         $uid = $_REQUEST[$this->FORM_USERID];                  
00515         $password = $_REQUEST[$this->FORM_PASSWORD];
00516         $user = $this->lookupUser($uid);
00517         if($user){         
00518             if($user->checkPassword($password)){                                
00519                 $this->_store_in_session($user);
00520                 return($user);
00521             }else{
00522                 return(FALSE);
00523             }                        
00524         }
00525         return(FALSE);
00526     }
00527     // Make a table name, this API uses the fully qualified tablename in it's
00528     // queries, because $DBH may or may not be pointed at the correct database.
00529     function _make_table_name($name){
00530         if($this->DBN){
00531             return($this->DBN . "." . $name);
00532         }
00533         return($name);
00534     }
00535 
00536 
00537     // Store data in the session variable.
00538     function _store_in_session($user){
00539         $sv = $this->SESSION_VARIABLE;
00540         if(! $user->FIELDS[SESSION_KEY]){
00541             $user->FIELDS[SESSION_KEY] = crypt($this->_session_key());
00542         }
00543         $_SESSION[$sv][USER] = $user->FIELDS;
00544         $_SESSION[$sv][LAST_IP] = $_SERVER[REMOTE_ADDR];
00545         
00546     }
00547     function _clear_session(){
00548         $v = $this->SESSION_VARIABLE;
00549         unset($_SESSION[$v]);
00550     }
00551 
00552     function _get_dbh(){
00553         if($this->DBH){
00554             return($this->DBH);
00555         }
00556         if($this->DB_PERSISTANT){
00557             $this->DBH = mysql_pconnect();
00558         }else{
00559             $this->DBH = mysql_connect();
00560         }
00561         if(! $this->DBH){
00562             die(mysql_errno() . " " .  mysql_error());      
00563         } 
00564     }
00565 
00579     function lookupUser($uid){
00580         if(! strlen($uid)){
00581             return(FALSE); // Do a sanity check.
00582         }
00583         $dbh = $this->_get_dbh();
00584         $tbl = $this->_make_table_name("ua_users"); // Fully qualified table.
00585         $fields = array();
00586         $uid = mysql_escape_string($uid);        
00587         $sql = "SELECT uid,password,confirm,name,email FROM $tbl WHERE uid='$uid'";
00588         $result = mysql_query($sql,$dbh) or die(mysql_error($dbh));        
00589         if($result) {
00590             $fields = mysql_fetch_assoc($result);
00591             $fields[password] = crypt($fields[password]); // Don't keep plain-text passwords around.
00592         }else{
00593             return(FALSE);
00594         }
00595         $fields[GROUPS] = array();
00596         $gt = $this->_make_table_name("ua_members");
00597         $result = mysql_query("SELECT gid FROM $gt WHERE uid='$uid'",$dbh) or die(mysql_error($dbh));
00598 
00599         if($result){
00600             while($row = mysql_fetch_row($result)){
00601                 array_push($fields[GROUPS],$row[0]);
00602             }
00603         }
00604         return(new GenieGate_Api_User($this,$fields));
00605     }
00606 
00607     // Builds up all the form variables.
00608     function _build_form_vars(&$req){
00609         $buf = "";      
00610         foreach($req as $k => $v){
00611             if(is_array($v)){
00612                 $nm = $k . "[]"; // Attempt to deal with multiple values.
00613                 foreach($v as $av){
00614                     $buf .= $this->_build_form_var($nm,$av);
00615                 }
00616             }else{
00617                 $buf .= $this->_build_form_var($k,$v);
00618             }
00619         }
00620         return($buf);
00621     }
00622     // Creates a single form variable.
00623     function _build_form_var($name,$val){
00624         $name = htmlentities($name);
00625         $val = htmlentities($val);
00626         $val = str_replace("\n", "&#10;",$val); // Attempt to deal with \r's and \n's.           
00627         $val = str_replace("\r", "&#13;",$val);
00628         return("<INPUT TYPE=\"HIDDEN\" NAME=\"$name\" VALUE=\"$val\">\n");
00629     }
00630 
00631     // NOTE: Don't be tempted to change this HTML, see the documentation for 
00632     // the prompt() method. (this method is called as a last resort to produce 
00633     // the HTML for a login box.)
00634     function _default_prompt_html(){      
00635         if($_SERVER[REQUEST_METHOD] == "GET"){
00636             $hidden = $this->_build_form_vars($_GET);
00637         }else{
00638             $hidden = $this->_build_form_vars($_POST);
00639         }
00640         echo "<FORM ACTION=\"$_SERVER[PHP_SELF]\" METHOD=\"POST\"> ";
00641         echo $hidden;
00642 ?>  
00643       <TABLE COLS="2" ALIGN="CENTER" WIDTH="40%" CLASS="loginBox">      
00644      <TR> 
00645        <TH COLSPAN="2">Login Required</TH>
00646      </TR>
00647       <TR>
00648         <TH>User ID</TH>
00649         <TD><INPUT NAME="<?php echo $this->FORM_USERID; ?>" ></TD>
00650       </TR>
00651       <TR>
00652          <TH>Password</TH>
00653          <TD>
00654            <INPUT TYPE="PASSWORD" NAME="<?php echo $this->FORM_PASSWORD; ?>" >
00655          </TD>
00656       </TR>
00657       <TR>
00658         <TD COLSPAN="2" ALIGN="CENTER"><INPUT TYPE="SUBMIT" VALUE="Login"></TD>
00659       </TR>
00660       </TABLE>
00661 </FORM>
00662 <?php              
00663     }
00664 
00665 
00666 }
00667 ?>

DoxyGen Documentation generated by DoxyGen