inc/users.php - index






















































































































































































































































































































































































































<?php

/* USERS.PHP - handles user login/logout via cookies 

VISITOR code is here too.

Currently there is only one pre-defined user, 'admin', as THIS was designed to 
be a single-user website -- the capability exists for this to be changed.

There is a really simple database (see file DATABASE):

    +-----------------------------+
    | userid                      | VARCHAR UNIQUE
    +-----------------------------+
    | pasword: p6gYt5as1          | TEXT
    | name: Jones!                |
    |                             |
    | I am a great person.        |
    +-----------------------------+

The following functions are defined:

    userstate()
    userlogin($userid, $password)
    usererror($user)
    userlogout()
    thiscrypt()
*/

/* userstate - returns user ID string if user logged in else empty string */

// there are two cookies, userid and userdat; userdat is encoded userid hash
// if hash is wrong nothing happens - use of userdat solely prevents someone 
// creating a cookie by editing a browser cookie file - if we had just that 
// one userid cookie that could let someone in - if our password salt got 
// leaked someone could create a userdat cookie as well - we will add more 
// data to userdat at some point...

function userstate() {

// testing mode code
    
if (config('testing'))
        return 
1;            // note: integer
// end
    
$userid cookie_get('userid');
    
debug("userid '$userid'");

    if (
$userid) {
        
$c cookie_get('userdat');
        
$c cookie_decode($c,$userid,$_SERVER['REMOTE_ADDR']);
        if (
$c != $userid) {
            
debug("userdat '$c' != '$userid'");
            return 
'';
        }
    }
    return (
$userid) ? $userid '';        // NULL, FALSE become ''
}

/* userlogin - check user exists; set cookie if yes, returns user RECORD */

function userlogin($userid$password) {

        
$userid trim($userid);
        
$userid strtolower($userid);

// testing mode code
    
if (config('testing')) {
        if (
$userid != AD_NAME)
            return 
FALSE;
        
$user['userid'] = AD_NAME;
        
$user['password'] = AD_PASS;
    }
    else                    
// note the else!
// end testing mode code

        
$user _userget($userid);

    if (!
$user) {
        
debug(usererror($user,$userid));
        return 
FALSE;
    }

        if (
thiscrypt($password,$user['password']) != $user['password']) {
            
debug("user '$userid' password wrong");
                return 
0;
    }

    
cookie_set('userid',$user['userid']);
    
$c cookie_encode($user['userid'],$_SERVER['REMOTE_ADDR']);
    
cookie_set('userdat',$c);

    
debug("userid '$userid' userdat '$c'");

        return 
$user;
}


/* userlogout - forget user information */

function userlogout() {

        
cookie_unset('userid');
        
cookie_unset('userdat');
    
// maybe more here later
}


/* usererror - return error string */

function usererror($user$userid) {

    if (
$user === ""$e "is empty";
        if (
$user === NULL$e "is invalid";
        if (
$user === FALSE$e "not found";
    if (
$user === 0$e "password wrong";

    return 
"user '$userid$e";
}


/* thiscrypt - encrypt a new or check an existing password */

function thiscrypt($string$password '') {

    if (
$password)
        return 
crypt($string,$password);

    return 
crypt($string,SALT1);
}

/* vcrypt - this is for known visitors */

// note that this one's argument is always the encrypted code

function vcrypt($code) {

    return 
crypt($code,SALT2);
}


/* _usernew - add a new user to the database */

function _usernew($userid$passwd) {

        
debug("'$userid','$passwd'");

        if (
_userget($userid))
                return 
NULL;

        
$record['name'] = $userid;
        
$record['password'] = thiscrypt($passwd);    // crypt the password
        
$record['stored'] = _userput($userid,$record);    // write the record

        
return $record;
}


/* _userupdate - update user data (password only for right now) */

function _userupdate($userid$password) {

        
$record _userget($userid);
        
$passwd thiscrypt($password);
        
$record['password'] = $passwd;

        
_userput($userid,$record,TRUE);            // write record 
}


/* _userget - read user as a 'record' */

function _userget($userid) {

    if (!
$userid) return "";
    if (
preg_match("/\W/",$userid)) return NULL;

        return 
dbreaduser($userid);
}


/* _userput - write record as user */

function _userput($userid$record$update FALSE) {

        return 
dbputuser($userid,$record,$update);
}


/* VISITOR Functions */

// These handle the from/code pairs used to validate visitors for commenting
// purposes. See VISITORS for more information. Most functions are called by 
// Admin; the functions with an underscore are called by DISPLAY.PHP.

// NOTE where exactly the 'from' should be "screened" -- caller or callee --
// is still being discussed...

// let's experiment with what characters will be allowed for the from/code 
// pair: alphanumerical, alnum + a few, or... all!


/* visitorget - lookup from visitor store; returns visitor record or 0 */

function visitorget($from) {

    
debug("'$from'");

    if (
$from === "") return "";
    if (
strtolower($from) == 'nobody') return 0;

        
$record dbreadvisitor($from);

    if (
$record) {
        
// need to validate the record; if a future version adds
        // required data, we need to make sure the old records 
        // are updated here -- could use some "upgrade" process as
        // well -- will determine that in this hypothetical future
    
}

    return 
$record;
}

/* visitornew - create a new visitor record */

// called by visitor_store() below; $code is already encrypted

function visitornew($from$code) {

    
debug("'$from','$code'");

    
// caller validates from data

    // the record format is defined here; obviously we will upgrade this
    // to some sort of template...

    
$record['from'] = $from;    // store from in header; important!
    
$record['code'] = $code;
    
$record['ip'] = $_SERVER['REMOTE_ADDR'];
    
$record['meta'] = 'none';
    
$record['body'] = 'time:'.time().THIS_EOL;

// NOTE that if new data needs to go in just add to 'body' - no need to 
// modify the database table

    
return dbnewvisitor($from,$record);
}

/* visitorcreat - create a new database entry */

// called by Admin -- will merge this and the previous function into one
// record is created from an Admin form ($_POST data)

function visitorcreat($record) {

    
debug($record);

    if (
trim($record['from']) === "" || trim($record['code']) === "")
        return 
'';

    
$record['code'] = vcrypt($record['code']);

    return 
dbnewvisitor($record['from'],$record);
}

/* visitorput - update a visitor record */

function visitorput($record) {

    
$from $record['from'];
    
debug("'$from'");

    if (!
dbreadvisitor($from))
        return 
FALSE;

    return 
dbputvisitor($from,$record);
}

/* visitorchksum - validates a record */

// created this due to finding a corrupt record in the database 
// this is not a real "check sum" as is just checks for all fields to exist
// note that we eventually will store the record "definition" somewhere...

function visitorchksum($record$test TRUE) {

    if (
$test) {
        foreach (array(
'from','code','ip','meta','body') as $k)
            if (!isset(
$record[$k])) return FALSE;
        return 
TRUE;
    }

    
// not complete...
    
return TRUE;
}


/* visitorpost - create visitor record from POST data */

// should change this name as "post" implies a verb like the others...
// called by Admin which immediately calls visitorcreat() right after...

function visitorpost() {

    
$def = array('from','code','ip','meta','body');
    
$record postvars($def,TRUE);

    return 
$record;
}


/* visitor_okay - compare from/code pair against store */

// FALSE if from not found
// NULL  if code/vcode mis-match,
// ""    if no from or code

function visitor_okay($from$code) {

    
debug("'$from','$code'");

    if (!
$from || !$code)
        return 
'';

    if (!(
$visitor visitorget($from)))
        return 
FALSE;

    
$vcode $visitor['code'];

    if (
$vcode != vcrypt($code))
        return 
NULL;

    return 
$vcode;
}


/* visitor_validate - compare from/code pair against cookie/store */

// 1     if cookie and from match
// FALSE if from/cookie mis-match, 
// NULL  if code/vcode mis-match,
// ""    if no visitor

function visitor_validate($from$code) {

    
debug("'$from','$code'");

    
$cfrom cookie_get('from');
    if (
$cfrom) {
        if (
$from != $cfrom) {
            
debug("from '$from' != '$cfrom'");
            return 
FALSE;
        }
        
$cdat cookie_get('fromdat');
        
$cdat cookie_decode($cdat,$cfrom);
        if (
$cdat != $cfrom) {
            
debug("fromdat '$cdat' != '$cfrom'");
            return 
FALSE;
        }
        return 
1;
    }

    
// if $code is empty, that's okay
    // if $code and not $visitor, that's okay
    // if $code and $visitor and $code != $vcode that's not okay

    
if ($visitor visitorget($from)) {
        
$vcode $visitor['code'];
        if (
vcrypt($code) != $vcode)
            return 
NULL;
    }

    return 
'';
}

/* visitor_store - updates cookie and/or stores from/code pair */

function visitor_store($from$code) {

    
debug("'$from','$code'");

    
assert($from == trim($from) && $code == trim($code));

    
// special case for us -- add to or remove as wanted

    
if (strtolower($from) == 'nobody')
        return;

    
// if have from/code pair new cookie (or re-set expire time)

    
if ($from !== "" && $code !== "") {
        
cookie_set('from',$from);
        
$c cookie_encode($from);
        
cookie_set('fromdat',$c);

        
debug("fromdat: '$c'");
    }

    
// if have from/code pair and not stored create new stored pair

    
if ($from !== "" && $code !== "" && !visitorget($from))
        
visitornew($from,vcrypt($code));
}

?>