"Fossies" - the Fresh Open Source Software Archive

Member "Open-Web-Analytics-1.7.0/owa_auth.php" (16 Sep 2020, 13803 Bytes) of package /linux/www/Open-Web-Analytics-1.7.0.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) PHP source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "owa_auth.php" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 1.6.9_vs_1.7.0.

    1 <?php
    2 
    3 //
    4 // Open Web Analytics - An Open Source Web Analytics Framework
    5 //
    6 // Copyright 2006 Peter Adams. All rights reserved.
    7 //
    8 // Licensed under GPL v2.0 http://www.gnu.org/copyleft/gpl.html
    9 //
   10 // Unless required by applicable law or agreed to in writing, software
   11 // distributed under the License is distributed on an "AS IS" BASIS,
   12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   13 // See the License for the specific language governing permissions and
   14 // limitations under the License.
   15 //
   16 // $Id$
   17 //
   18 
   19 require_once(OWA_BASE_CLASS_DIR.'sanitize.php');
   20 
   21 /**
   22  * User Authentication Object
   23  * 
   24  * @author      Peter Adams <peter@openwebanalytics.com>
   25  * @copyright   Copyright &copy; 2006 Peter Adams <peter@openwebanalytics.com>
   26  * @license     http://www.gnu.org/copyleft/gpl.html GPL v2.0
   27  * @category    owa
   28  * @package     owa
   29  * @version        $Revision$
   30  * @since        owa 1.0.0
   31  */
   32 class owa_auth extends owa_base {
   33 
   34     /**
   35      * User object
   36      *
   37      * @var unknown_type
   38      */
   39     var $u;
   40 
   41     /**
   42      * Array of permission roles that users can have
   43      *
   44      * @var array
   45      */
   46     var $roles;
   47 
   48     var $status_msg;
   49 
   50     /**
   51      * Login credentials
   52      *
   53      * @var array
   54      */
   55     var $credentials = array();
   56 
   57     /**
   58      * Status of Authentication
   59      *
   60      * @var boolean
   61      */
   62     var $auth_status = false;
   63 
   64     var $_is_user = false;
   65 
   66     var $_priviledge_level;
   67 
   68     var $_is_priviledged = false;
   69 
   70     var $params;
   71 
   72     var $check_for_credentials = false;
   73 
   74     /**
   75      * Auth class Singleton
   76      *
   77      * @return owa_auth
   78      */
   79     public static function get_instance($plugin = '') {
   80 
   81         static $auth;
   82 
   83         if (!$auth) {
   84 
   85             $auth = new owa_auth();
   86 
   87         }
   88 
   89         return $auth;
   90     }
   91 
   92 
   93     /**
   94      * Class Constructor
   95      *
   96      * @return owa_auth
   97      */
   98     function __construct() {
   99 
  100         // register auth cookies
  101         owa_coreAPI::registerStateStore('u', time()+3600*24*365*10, '', '', 'cookie');
  102         owa_coreAPI::registerStateStore('p', time()+3600*2, '', '', 'cookie');
  103 
  104         parent::__construct();
  105         $this->eq = owa_coreAPI::getEventDispatch();
  106     }
  107 
  108     /**
  109      * Used by controllers to check if the user exists and if they are priviledged.
  110      *
  111      * @param string $necessary_role
  112      */
  113     function authenticateUser() {
  114         
  115         $apiKey = owa_coreAPI::getRequestParam('apiKey') ?: owa_coreAPI::getServerParam( 'HTTP_X_API_KEY' );
  116         // check existing auth status first in case someone else took care of this already.
  117         if (owa_coreAPI::getCurrentUser()->isAuthenticated()) {
  118             owa_coreAPI::debug('User is already authenticated.');
  119             $ret = true;
  120         } elseif ( $apiKey ) {
  121             // auth user by api key
  122             $ret = $this->authByApiKey( $apiKey );
  123             owa_coreAPI::debug('User authenticated via api key.');
  124         } elseif (owa_coreAPI::getRequestParam('pk') && owa_coreAPI::getStateParam('u')) {
  125             // auth user by temporary passkey. used in forgot password situations
  126             $ret = $this->authenticateUserByUrlPasskey(owa_coreAPI::getRequestParam('pk'));
  127              owa_coreAPI::debug('User authenticated via temporary passkey.');
  128         } elseif (owa_coreAPI::getRequestParam('user_id') && owa_coreAPI::getRequestParam('password')) {
  129             // auth user by login form input
  130             $ret = $this->authByInput(owa_coreAPI::getRequestParam('user_id'), owa_coreAPI::getRequestParam('password'));
  131              owa_coreAPI::debug('User authenticated via form input.');
  132         } elseif (owa_coreAPI::getStateParam('u') && owa_coreAPI::getStateParam('p')) {
  133             // auth user by cookies
  134             $ret = $this->authByCookies(owa_coreAPI::getStateParam('u'), owa_coreAPI::getStateParam('p'));
  135              owa_coreAPI::debug('User authenticated via cookies.');
  136             // bump expiration time
  137             //owa_coreAPI::setState('p', '', owa_coreAPI::getStateParam('p'));
  138         } else {
  139             $ret = false;
  140             owa_coreAPI::debug("Could not find any credentials to authenticate with.");
  141         }
  142 
  143         // filter results for modules can add their own auth logic.
  144         $ret = $this->eq->filter('auth_status', $ret);
  145 
  146         return array('auth_status' => $ret);
  147 
  148     }
  149 
  150     function authByApiKey( $key ) {
  151 
  152         $key = owa_sanitize::cleanMd5( $key );
  153 
  154         if ( $key ) {
  155 
  156             // fetch user object from the db
  157             $this->u = owa_coreAPI::entityFactory('base.user');
  158             $this->u->load($key, 'api_key');
  159 
  160             if ($this->u->get('user_id')) {
  161                 // get current user
  162                 $cu = owa_coreAPI::getCurrentUser();
  163                 // set as new current user in service layer
  164                 $cu->loadNewUserByObject($this->u);
  165                 $cu->setAuthStatus(true);
  166                 $this->_is_user = true;
  167                 return true;
  168             } else {
  169                 return false;
  170             }
  171 
  172         } else {
  173 
  174             return false;
  175         }
  176 
  177     }
  178 
  179     function authByCookies($user_id, $password) {
  180 
  181         // set credentials
  182         $this->credentials['user_id'] = owa_sanitize::cleanUserId( $user_id );
  183         $this->credentials['password'] = $password;
  184 
  185         // lookup user if not already done.
  186         if ($this->_is_user == false) {
  187 
  188             // check to see if the current user has already been authenticated by something upstream
  189             $cu = owa_coreAPI::getCurrentUser();
  190             if (!$cu->isAuthenticated()) {
  191                 // check to see if they are a user.
  192                 $val = $this->isUser();
  193                 //print ("val: ". $val);
  194                 return $val;
  195             }
  196         } else {
  197             return true;
  198         }
  199     }
  200 
  201     function authByInput($user_id, $password) {
  202 
  203         // set credentials
  204         $this->credentials['user_id'] = owa_sanitize::cleanUserId( $user_id );
  205         // must encrypt password to see if it matches whats in the db
  206         $this->credentials['password'] = $this->generateAuthCredential( $this->credentials['user_id'], $this->encryptOldPassword( $password ) );
  207         // pass plain text password to test with password_verify
  208         $this->credentials['new_password'] = $password;
  209         //owa_coreAPI::debug(print_r($this->credentials, true));
  210         $ret = $this->isUser();
  211 
  212         if ($ret === true) {
  213             $this->saveCredentials();
  214         }
  215 
  216         return $ret;
  217     }
  218 
  219     /**
  220      * Looks up user by temporary Passkey Column in db
  221      *
  222      * @param unknown_type $key
  223      * @return unknown
  224      */
  225     function authenticateUserTempPasskey( $key ) {
  226 
  227         $key = owa_sanitize::cleanMd5( $key );
  228 
  229         if ( $key ) {
  230 
  231             $this->u = owa_coreAPI::entityFactory('base.user');
  232             $this->u->getByColumn('temp_passkey', $key);
  233 
  234             $id = $this->u->get('id');
  235 
  236             if (!empty($id)) {
  237 
  238                 return true;
  239 
  240             } else {
  241 
  242                 return false;
  243             }
  244 
  245         } else {
  246 
  247             return false;
  248         }
  249     }
  250 
  251     /**
  252      * Authenticates user by a passkey
  253      *
  254      * @param unknown_type $key
  255      * @return unknown
  256      */
  257     function authenticateUserByUrlPasskey($user_id, $passkey) {
  258 
  259         $passkey = owa_sanitize::cleanMd5( $passkey );
  260 
  261         if ( $passkey ) {
  262 
  263             // set credentials
  264             $this->credentials['user_id'] = $user_id;
  265             $this->credentials['passkey'] = $passkey;
  266 
  267             // fetch user obj
  268             $this->getUser();
  269 
  270             // generate a new passkey from its components in the db
  271             $key = $this->generateUrlPasskey($this->u->get('user_id'), $this->u->get('password'));
  272 
  273             // see if it matches the key on the url
  274             if ($key == $passkey) {
  275 
  276                 return true;
  277 
  278             } else {
  279                 return false;
  280             }
  281 
  282         } else {
  283 
  284             return false;
  285         }
  286     }
  287 
  288     /**
  289      * Sets a temporary Passkey for a user
  290      *
  291      * @param string $email_address
  292      * @return boolean
  293      */
  294     function setTempPasskey($email_address) {
  295 
  296         $this->u = owa_coreAPI::entityFactory('base.user');
  297         $this->u->getByColumn('email_address', $email_address);
  298 
  299         $id = $u->get('id');
  300 
  301         if (!empty($id)):
  302 
  303             $this->eq->log(array('email_address' => $this->u->email_address), 'user.set_temp_passkey');
  304             return true;
  305         else:
  306             return false;
  307         endif;
  308 
  309     }
  310 
  311     function generateTempPasskey($seed) {
  312 
  313         return md5($seed.time().rand());
  314     }
  315 
  316     function generateUrlPasskey($user_name, $password) {
  317 
  318         return md5($user_name . $password);
  319 
  320     }
  321 
  322     /**
  323      * Sets the initial Passkey for a new user
  324      *
  325      * @param string $user_id
  326      * @return boolean
  327      * @deprecated
  328      */
  329     function setInitialPasskey($user_id) {
  330 
  331         return $this->eq->log(array('user_id' => $user_id), 'user.set_initial_passkey');
  332 
  333     }
  334 
  335     /**
  336      * Saves login credentails to persistant browser cookies
  337      * TODO: refactor to use state facility
  338      */
  339     function saveCredentials() {
  340 
  341         $this->e->debug('saving user credentials to cookies');
  342 
  343         if (PHP_VERSION_ID < 70300) {
  344             setcookie($this->config['ns'].'u', $this->u->get('user_id'), time()+3600*24*365*10, '/; samesite=Lax', $this->config['cookie_domain']);
  345             setcookie($this->config['ns'].'p', $this->generateAuthCredential( $this->credentials['user_id'], $this->u->get('password') ), time()+3600*24*2, '/; samesite=Lax', $this->config['cookie_domain']);
  346         } else {
  347             setcookie($this->config['ns'].'u', $this->u->get('user_id'), [
  348                 'expires' => time()+3600*24*365*10,
  349                 'path' => '/',
  350                 'samesite' => 'Lax',
  351                 'domain' => $this->config['cookie_domain'],
  352             ]);
  353             setcookie($this->config['ns'].'p', $this->generateAuthCredential( $this->credentials['user_id'], $this->u->get('password') ), [
  354                 'expires' => time()+3600*24*365*10,
  355                 'path' => '/',
  356                 'samesite' => 'Lax',
  357                 'domain' => $this->config['cookie_domain'],
  358             ]);
  359         }
  360     }
  361 
  362     /**
  363      * Removes credentials
  364      * @return boolean
  365      */
  366     function deleteCredentials() {
  367 
  368         return owa_coreAPI::clearState('p');
  369     }
  370 
  371     /**
  372      * Simple Password Encryption Scheme
  373      *
  374      * @param string $password
  375      * @return string
  376      */
  377     function encryptPassword($password) {
  378 
  379         return owa_lib::encryptPassword($password);
  380 
  381     }
  382     function encryptOldPassword($password) {
  383 
  384         return owa_lib::encryptOldPassword($password);
  385 
  386     }
  387 
  388     function getUser() {
  389 
  390         // fetch user object from the db
  391         $this->u = owa_coreAPI::entityFactory('base.user');
  392         $this->u->getByColumn('user_id', $this->credentials['user_id']);
  393     }
  394 
  395     /**
  396      * Checks to see if the user credentials match a real user object in the DB
  397      *
  398      * @return boolean
  399      */
  400     function isUser() {
  401 
  402         // get current user
  403         $cu = owa_coreAPI::getCurrentUser();
  404 
  405         // fetches user object from DB
  406         $this->getUser();
  407 
  408         if ( $this->credentials['user_id'] === $this->u->get('user_id') ) {
  409 
  410             // new_password will only be set when using authByInput
  411             if ( isset($this->credentials['new_password']) ) {
  412                 // plain text password matches DB password we can authorize
  413                 if ( password_verify( $this->credentials['new_password'], $this->u->get('password') ) ) {
  414                 $this->_is_user = true;
  415 
  416                 // set as new current user in service layer
  417                 $cu->loadNewUserByObject( $this->u );
  418                 $cu->setAuthStatus(true);
  419 
  420                 return true;
  421                 }
  422             }
  423 
  424             //if ($this->credentials['password'] === $this->u->get('password')):
  425             if ( $this->isValidAuthCredential( $this->credentials['user_id'], $this->credentials['password'] ) ) {
  426                 $this->_is_user = true;
  427 
  428                 // set as new current user in service layer
  429                 $cu->loadNewUserByObject( $this->u );
  430                 $cu->setAuthStatus(true);
  431 
  432                 return true;
  433             } else {
  434                 $this->_is_user = false;
  435                 return false;
  436             }
  437         } else {
  438             $this->_is_user = false;
  439             return false;
  440         }
  441     }
  442 
  443     function isValidAuthCredential( $user_id, $passed_credential ) {
  444 
  445         $hash = '';
  446         $hash = $this->reconstructAuthCredential( $user_id );
  447         //print "hash: $hash ";
  448         //print "passed credential: $passed_credential ";
  449         if ( function_exists('hash_equals') ) {
  450 
  451             return hash_equals( $hash, $passed_credential );
  452 
  453         } else {
  454 
  455             if ( $hash === $passed_credential ) {
  456 
  457                 return true;
  458             }
  459         }
  460     }
  461 
  462     function reconstructAuthCredential( $user_id ) {
  463 
  464         $u = owa_coreAPI::entityFactory('base.user');
  465 
  466         $u->getByColumn( 'user_id', $user_id );
  467 
  468         $password = $u->get('password');
  469         //print "password $password";
  470         return $this->generateAuthCredential( $user_id, $password );
  471     }
  472 
  473     function generateAuthCredential($user_id, $password, $expiration = '', $scheme = 'auth') {
  474 
  475         $frag = substr($password, 8, 4);
  476 
  477         $key = owa_coreAPI::saltedHash( $user_id . $frag . $expiration, $scheme );
  478 
  479         $algo = 'sha1';
  480 
  481         if ( function_exists( 'hash' ) ) {
  482 
  483             $algo = 'sha256';
  484 
  485         }
  486 
  487         $hash = owa_lib::hash( $algo, $user_id . $expiration, $key );
  488 
  489         $credential = $hash; // could add other elements here.
  490 
  491         return $credential;
  492     }
  493 
  494 }
  495 
  496 ?>