2008-06-13 20:20:23 +00:00
< ? php
/*
2008-12-21 11:07:58 +00:00
* e107 website system
*
2016-06-06 19:54:48 -07:00
* Copyright ( C ) 2008 - 2016 e107 Inc ( e107 . org )
2008-12-21 11:07:58 +00:00
* Released under the terms and conditions of the
* GNU General Public License ( http :// www . gnu . org / licenses / gpl . txt )
*
* Handler - user - related functions
*
2008-06-13 20:20:23 +00:00
*/
2010-01-31 22:21:11 +00:00
/**
2010-05-13 15:47:31 +00:00
*
2010-01-31 22:21:11 +00:00
* @ package e107
* @ subpackage e107_handlers
*
* USER HANDLER CLASS - manages login and various user functions
*
*/
2008-06-13 20:20:23 +00:00
if ( ! defined ( 'e107_INIT' )) { exit ; }
2008-12-21 11:07:58 +00:00
// Codes for `user_ban` field (not all used ATM)
2008-06-13 20:20:23 +00:00
define ( 'USER_VALIDATED' , 0 );
define ( 'USER_BANNED' , 1 );
define ( 'USER_REGISTERED_NOT_VALIDATED' , 2 );
define ( 'USER_EMAIL_BOUNCED' , 3 );
define ( 'USER_BOUNCED_RESET' , 4 );
define ( 'USER_TEMPORARY_ACCOUNT' , 5 );
define ( 'PASSWORD_E107_MD5' , 0 );
define ( 'PASSWORD_E107_SALT' , 1 );
2016-06-06 19:54:48 -07:00
define ( 'PASSWORD_E107_PHP' , 3 ); // PHP Default - Using the bcrypt algorithm (default as of PHP 5.5.0).
2008-06-13 20:20:23 +00:00
define ( 'PASSWORD_E107_ID' , '$E$' ); // E107 salted
2016-06-06 19:54:48 -07:00
define ( 'PASSWORD_INVALID' , false );
2008-06-13 20:20:23 +00:00
define ( 'PASSWORD_VALID' , TRUE );
define ( 'PASSWORD_DEFAULT_TYPE' , PASSWORD_E107_MD5 );
//define ('PASSWORD_DEFAULT_TYPE',PASSWORD_E107_SALT);
2008-12-21 11:07:58 +00:00
// Required language file - if not loaded elsewhere, uncomment next line
2017-01-23 09:41:23 -08:00
e107 :: includeLan ( e_LANGUAGEDIR . e_LANGUAGE . '/lan_user.php' );
2008-06-13 20:20:23 +00:00
2022-04-04 10:54:24 -07:00
/**
*
*/
2008-06-13 20:20:23 +00:00
class UserHandler
{
2008-12-21 11:07:58 +00:00
var $userVettingInfo = array ();
2008-06-13 20:20:23 +00:00
var $preferred = PASSWORD_DEFAULT_TYPE ; // Preferred password format
var $passwordOpts = 0 ; // Copy of pref
2016-06-06 19:54:48 -07:00
var $passwordEmail = false ; // True if can use email address to log in
2016-06-28 09:25:30 -07:00
private $otherFields = array ();
2016-06-06 19:54:48 -07:00
private $passwordAPI = false ;
2008-06-13 20:20:23 +00:00
// Constructor
2010-01-31 22:21:11 +00:00
public function __construct ()
2008-06-13 20:20:23 +00:00
{
2011-09-14 11:09:05 +00:00
$pref = e107 :: getPref ();
2016-03-22 11:42:05 -07:00
e107 :: lan ( 'core' , 'user' );
2016-06-06 19:54:48 -07:00
if ( function_exists ( 'password_verify' ))
{
$this -> passwordAPI = true ;
}
2010-01-31 22:21:11 +00:00
/**
2008-12-21 11:07:58 +00:00
Table of vetting methods for user data - lists every field whose value could be set manually .
Valid 'vetMethod' values ( use comma separated list for multiple vetting ) :
0 - Null method
1 - Check for duplicates
2 - Check against $pref [ 'signup_disallow_text' ]
2009-11-30 20:40:03 +00:00
3 - Check email address against remote server , only if option enabled
2008-12-30 14:05:44 +00:00
2008-12-21 11:07:58 +00:00
Index is the destination field name . If the source index name is different , specify 'srcName' in the array .
2008-12-30 14:05:44 +00:00
2008-12-21 11:07:58 +00:00
Possible processing options :
2008-12-28 22:37:43 +00:00
'dbClean' - 'sanitising' method for final value :
- 'toDB' - passes final value through $tp -> toDB ()
- 'intval' - converts to an integer
- 'image' - checks image for size
- 'avatar' - checks an image in the avatars directory
2008-12-21 11:07:58 +00:00
'stripTags' - strips HTML tags from the value ( not an error if there are some )
'minLength' - minimum length ( in utf - 8 characters ) for the string
'maxLength' - minimum length ( in utf - 8 characters ) for the string
'longTrim' - if set , and the string exceeds maxLength , its trimmed
'enablePref' - value is processed only if the named $pref evaluates to true ; otherwise any input is discarded without error
*/
$this -> userVettingInfo = array (
2016-03-22 11:42:05 -07:00
'user_name' => array ( 'niceName' => LAN_USER_01 , 'fieldType' => 'string' , 'vetMethod' => '1,2' , 'vetParam' => 'signup_disallow_text' , 'srcName' => 'username' , 'stripTags' => TRUE , 'stripChars' => '/ |\#|\=|\$/' , 'fixedBlock' => 'anonymous' , 'minLength' => 2 , 'maxLength' => varset ( $pref [ 'displayname_maxlength' ], 15 )), // Display name
2018-07-30 22:42:55 +02:00
//'user_loginname' => array('niceName'=> LAN_USER_02, 'fieldType' => 'string', 'vetMethod' => '1', 'vetParam' => '', 'srcName' => 'loginname', 'stripTags' => TRUE, 'stripChars' => '#[^a-z0-9_\.]#i', 'minLength' => 2, 'maxLength' => varset($pref['loginname_maxlength'],30)), // User name
'user_loginname' => array ( 'niceName' => LAN_USER_02 , 'fieldType' => 'string' , 'vetMethod' => '1' , 'vetParam' => '' , 'srcName' => 'loginname' , 'stripTags' => TRUE , 'stripChars' => '#[^\p{L}\p{M}a-z0-9_\.]#ui' , 'minLength' => 2 , 'maxLength' => varset ( $pref [ 'loginname_maxlength' ], 30 )), // User name
2016-04-23 00:29:14 +03:00
'user_login' => array ( 'niceName' => LAN_USER_03 , 'fieldType' => 'string' , 'vetMethod' => '0' , 'vetParam' => '' , 'srcName' => 'realname' , 'dbClean' => 'toDB' , 'stripTags' => TRUE , 'stripChars' => '#<|>#i' ), // Real name (no real vetting)
'user_customtitle' => array ( 'niceName' => LAN_USER_04 , 'fieldType' => 'string' , 'vetMethod' => '0' , 'vetParam' => '' , 'srcName' => 'customtitle' , 'dbClean' => 'toDB' , 'enablePref' => 'signup_option_customtitle' , 'stripTags' => TRUE , 'stripChars' => '#<|>#i' ), // No real vetting
2015-09-01 15:52:22 -07:00
'user_password' => array ( 'niceName' => LAN_PASSWORD , 'fieldType' => 'string' , 'vetMethod' => '0' , 'vetParam' => '' , 'srcName' => 'password1' , 'dataType' => 2 , 'minLength' => varset ( $pref [ 'signup_pass_len' ], 1 )),
2013-04-19 22:50:41 -07:00
'user_sess' => array ( 'niceName' => LAN_USER_06 , 'fieldType' => 'string' , 'vetMethod' => '0' , 'vetParam' => '' , 'stripChars' => " # \" |'|(|)# " , 'dbClean' => 'image' , 'imagePath' => e_AVATAR_UPLOAD , 'maxHeight' => varset ( $pref [ 'im_height' ], 100 ), 'maxWidth' => varset ( $pref [ 'im_width' ], 120 )), // Photo
2012-06-18 09:06:20 +00:00
'user_image' => array ( 'niceName' => LAN_USER_07 , 'fieldType' => 'string' , 'vetMethod' => '0' , 'vetParam' => '' , 'srcName' => 'image' , 'stripChars' => " # \" |'|(|)# " , 'dbClean' => 'avatar' ), //, 'maxHeight' => varset($pref['im_height'], 100), 'maxWidth' => varset($pref['im_width'], 120) resized on-the-fly // Avatar
2015-09-01 15:52:22 -07:00
'user_email' => array ( 'niceName' => LAN_EMAIL , 'fieldType' => 'string' , 'vetMethod' => '1,3' , 'vetParam' => '' , 'fieldOptional' => varset ( $pref [ 'disable_emailcheck' ], 0 ), 'srcName' => 'email' , 'dbClean' => 'toDB' ),
2009-01-11 21:06:52 +00:00
'user_signature' => array ( 'niceName' => LAN_USER_09 , 'fieldType' => 'string' , 'vetMethod' => '0' , 'vetParam' => '' , 'srcName' => 'signature' , 'dbClean' => 'toDB' ),
'user_hideemail' => array ( 'niceName' => LAN_USER_10 , 'fieldType' => 'int' , 'vetMethod' => '0' , 'vetParam' => '' , 'srcName' => 'hideemail' , 'dbClean' => 'intval' ),
2015-09-01 15:52:22 -07:00
'user_xup' => array ( 'niceName' => " XUP File " , 'fieldType' => 'string' , 'vetMethod' => '0' , 'vetParam' => '' , 'srcName' => 'user_xup' , 'dbClean' => 'toDB' ),
2009-01-11 21:06:52 +00:00
'user_class' => array ( 'niceName' => LAN_USER_12 , 'fieldType' => 'string' , 'vetMethod' => '0' , 'vetParam' => '' , 'srcName' => 'class' , 'dataType' => '1' )
2008-12-21 11:07:58 +00:00
);
2016-06-06 19:54:48 -07:00
$this -> otherFields = array (
2008-12-21 11:07:58 +00:00
'user_join' => LAN_USER_14 ,
'user_lastvisit' => LAN_USER_15 ,
'user_currentvisit' => LAN_USER_16 ,
2015-07-07 18:02:16 -07:00
'user_comments' => LAN_COMMENTS ,
2008-12-21 11:07:58 +00:00
'user_ip' => LAN_USER_18 ,
'user_ban' => LAN_USER_19 ,
'user_prefs' => LAN_USER_20 ,
'user_visits' => LAN_USER_21 ,
'user_admin' => LAN_USER_22 ,
'user_perms' => LAN_USER_23 ,
'user_pwchange' => LAN_USER_24
// user_chats int(10) unsigned NOT NULL default '0',
);
2016-06-06 19:54:48 -07:00
$this -> otherFieldTypes = array (
2009-01-11 22:11:19 +00:00
'user_join' => 'int' ,
'user_lastvisit' => 'int' ,
'user_currentvisit' => 'int' ,
'user_comments' => 'int' ,
'user_ip' => 'string' ,
'user_ban' => 'int' ,
'user_prefs' => 'string' ,
'user_visits' => 'int' ,
'user_admin' => 'int' ,
'user_perms' => 'string' ,
'user_pwchange' => 'int'
);
2008-12-21 11:07:58 +00:00
2016-06-06 19:54:48 -07:00
$this -> passwordOpts = varset ( $pref [ 'passwordEncoding' ], 0 );
$this -> passwordEmail = varset ( $pref [ 'allowEmailLogin' ], false );
switch ( $this -> passwordOpts )
{
case 3 :
$this -> preferred = PASSWORD_E107_PHP ;
break ;
case 1 :
case 2 :
$this -> preferred = PASSWORD_E107_SALT ;
break ;
case 0 :
default :
$this -> preferred = PASSWORD_E107_MD5 ;
$this -> passwordOpts = 0 ; // In case it got set to some stupid value
break ;
}
return false ;
2008-06-13 20:20:23 +00:00
}
2016-06-16 12:23:20 -07:00
/**
* Return the code for the current default password hash - type
* @ return int
*/
public function getDefaultHashType ()
{
return $this -> preferred ;
}
/**
* Returns true if PHP5 . 5 + password API is found , otherwise return false .
* @ return bool
*/
public function passwordAPIExists ()
{
return $this -> passwordAPI ;
}
2016-06-28 09:25:30 -07:00
/**
* Check if a user posted field is readonly ( should not be user - editable ) - used in usersettings . php
* @ param array $posted
* @ return bool
*/
public function hasReadonlyField ( $posted )
{
$restricted = array_keys ( $this -> otherFields );
$pref = e107 :: getPref ();
if ( empty ( $pref [ 'signup_option_class' ]))
{
$restricted [] = 'user_class' ;
}
foreach ( $posted as $k => $v )
{
if ( in_array ( $k , $restricted ))
{
return true ;
}
}
return false ;
}
2010-01-31 22:21:11 +00:00
/**
* Given plaintext password and login name , generate password string to store in DB
*
* @ param string $password - plaintext password as entered by user
* @ param string $login_name - string used to log in ( could actually be email address )
2016-06-06 19:54:48 -07:00
* @ param string $force empty | PASSWORD_E107_MD 5 | PASSWORD_E107_SALT | PASSWORD_E107_PHP $force - if non - empty , forces a particular type of password
2010-01-31 22:21:11 +00:00
*
2016-06-06 19:54:48 -07:00
* @ return string | boolean - false if invalid emcoding method , else encoded password to store in DB
2010-01-31 22:21:11 +00:00
*/
2016-06-06 19:54:48 -07:00
public function HashPassword ( $password , $login_name = '' , $force = false )
2008-06-13 20:20:23 +00:00
{
2016-06-06 19:54:48 -07:00
if ( $force === false )
{
$force = $this -> preferred ;
}
2016-06-07 17:18:18 -07:00
if (( $force == PASSWORD_E107_PHP ) && $this -> passwordAPI === false )
{
$force = PASSWORD_E107_SALT ; // fallback.
}
2016-06-06 19:54:48 -07:00
switch ( $force )
{
case PASSWORD_E107_MD5 :
return md5 ( $password );
case PASSWORD_E107_SALT :
return PASSWORD_E107_ID . md5 ( md5 ( $password ) . $login_name );
break ;
case PASSWORD_E107_PHP :
2016-06-07 17:18:18 -07:00
return password_hash ( $password , PASSWORD_DEFAULT );
2016-06-06 19:54:48 -07:00
break ;
}
return false ;
2008-06-13 20:20:23 +00:00
}
2010-01-31 22:21:11 +00:00
/**
* Verify existing plaintext password against a stored hash value ( which defines the encoding format and any 'salt' )
*
* @ param string $password - plaintext password as entered by user
* @ param string $login_name - string used to log in ( could actually be email address )
* @ param string $stored_hash - required value for password to match
2010-05-13 15:47:31 +00:00
*
2016-06-06 12:48:26 -07:00
* @ return string PASSWORD_INVALID | PASSWORD_VALID | string
2010-01-31 22:21:11 +00:00
* PASSWORD_INVALID if no match
* PASSWORD_VALID if valid password
* Return a new hash to store if valid password but non - preferred encoding
*/
public function CheckPassword ( $password , $login_name , $stored_hash )
2008-06-13 20:20:23 +00:00
{
2016-06-10 13:08:08 -07:00
$password = trim ( $password );
2016-06-06 19:54:48 -07:00
2016-06-10 13:08:08 -07:00
if ( empty ( $password ))
2016-06-06 19:54:48 -07:00
{
return PASSWORD_INVALID ;
2010-01-31 22:21:11 +00:00
}
2008-06-13 20:20:23 +00:00
2016-06-06 19:54:48 -07:00
$type = $this -> getHashType ( $stored_hash );
switch ( $type )
{
2016-06-10 16:37:36 -07:00
case PASSWORD_E107_MD5 :// &&
2016-06-06 19:54:48 -07:00
if ( md5 ( $password ) !== $stored_hash ) return PASSWORD_INVALID ;
2016-06-10 16:37:36 -07:00
if ( $this -> preferred == PASSWORD_E107_MD5 && ( $this -> passwordOpts <= 1 )) return PASSWORD_VALID ;
2016-06-06 19:54:48 -07:00
return $this -> HashPassword ( $password ); // Valid password, but non-preferred encoding; return the new hash
break ;
case PASSWORD_E107_SALT :
$hash = $this -> HashPassword ( $password , $login_name , PASSWORD_E107_SALT );
if ( $hash === false ) return PASSWORD_INVALID ;
return ( $hash == $stored_hash ) ? PASSWORD_VALID : PASSWORD_INVALID ;
break ;
case PASSWORD_E107_PHP : // PHP 5.5+ Blowfish+
if ( $this -> passwordAPI === true && password_verify ( $password , $stored_hash ))
{
return PASSWORD_VALID ;
}
break ;
2010-01-31 22:21:11 +00:00
}
2016-06-06 19:54:48 -07:00
2010-01-31 22:21:11 +00:00
return PASSWORD_INVALID ;
2008-06-13 20:20:23 +00:00
}
2016-06-06 19:54:48 -07:00
/**
2016-06-16 12:23:20 -07:00
* If necessary , rehash the user password to the currently set algorythm and updated database . .
2016-06-06 19:54:48 -07:00
* @ param array $user - user fields . required : user_id , user_loginname , user_password
* @ param string $password - plain text password .
2020-02-22 11:45:35 -08:00
* @ return bool | string returns new password hash on success or false .
2016-06-06 19:54:48 -07:00
*/
public function rehashPassword ( $user , $password )
{
$type = $this -> getHashType ( $user [ 'user_password' ]);
2016-06-10 13:10:45 -07:00
if ( $type == $this -> preferred || empty ( $user [ 'user_id' ]) || empty ( $user [ 'user_password' ]) || empty ( $user [ 'user_loginname' ]))
2016-06-06 19:54:48 -07:00
{
return false ;
}
$sql = e107 :: getDb ();
2016-06-16 12:23:20 -07:00
$newPasswordHash = $this -> HashPassword ( $password , $user [ 'user_loginname' ]);
2016-06-06 19:54:48 -07:00
$update = array (
'data' => array (
2016-06-16 12:23:20 -07:00
'user_password' => $newPasswordHash ,
2016-06-06 19:54:48 -07:00
),
'WHERE' => " user_id = " . intval ( $user [ 'user_id' ]) . " LIMIT 1 " ,
'_FIELD_TYPES' => array ( 'user_password' => 'safestr' ),
);
2016-06-16 12:23:20 -07:00
if ( $sql -> update ( 'user' , $update ) !== false )
{
return $newPasswordHash ;
}
2016-06-06 19:54:48 -07:00
2016-06-16 12:23:20 -07:00
return false ;
2016-06-06 19:54:48 -07:00
}
2021-01-16 08:43:51 -08:00
2016-06-06 19:54:48 -07:00
/**
* Detect Password Hash Algorythm type
* @ param string $hash - Password hash to analyse
2016-06-10 16:37:36 -07:00
* @ param string $mode - ( optional ) set to 'text' for a plain - text description .
2019-02-21 12:05:54 -08:00
* @ return bool | int | array
2016-06-06 19:54:48 -07:00
*/
2016-06-10 16:37:36 -07:00
public function getHashType ( $hash , $mode = 'constant' )
2016-06-06 19:54:48 -07:00
{
if ( empty ( $hash ))
{
return false ;
}
2016-06-10 16:37:36 -07:00
$num = false ;
$name = '' ;
if (( strlen ( $hash ) === 32 ))
2016-06-06 19:54:48 -07:00
{
2016-06-10 16:37:36 -07:00
$num = PASSWORD_E107_MD5 ;
$name = 'md5' ;
2016-06-06 19:54:48 -07:00
}
2021-01-24 17:00:02 -08:00
elseif (( strlen ( $hash ) === 35 ) && ( strpos ( $hash , PASSWORD_E107_ID ) === 0 ))
2016-06-06 19:54:48 -07:00
{
2016-06-10 16:37:36 -07:00
$num = PASSWORD_E107_SALT ;
$name = 'md5-salt' ;
2016-06-06 19:54:48 -07:00
}
2016-06-10 16:37:36 -07:00
elseif ( $this -> passwordAPI )
2016-06-06 19:54:48 -07:00
{
$info = password_get_info ( $hash );
if ( ! empty ( $info [ 'algo' ]))
{
2016-06-10 16:37:36 -07:00
$num = PASSWORD_E107_PHP ;
$name = $info [ 'algoName' ];
2016-06-06 19:54:48 -07:00
}
}
2016-06-10 16:37:36 -07:00
if ( $mode == 'array' && ! empty ( $name ))
{
return array ( $num , $name );
}
return $num ;
2016-06-06 19:54:48 -07:00
}
2015-05-18 11:49:32 -07:00
/**
* Reset the user ' s password with an auto - generated string .
* @ param $uid
* @ param string $loginName ( optional )
2021-12-03 14:58:33 -08:00
* @ param array $options
2015-05-18 11:49:32 -07:00
* @ return bool | string rawPassword
*/
2016-06-07 08:37:19 -07:00
public function resetPassword ( $uid , $loginName = '' , $options = array ())
2015-05-18 11:49:32 -07:00
{
if ( empty ( $uid ))
{
return false ;
}
2016-06-07 08:37:19 -07:00
$rawPassword = $this -> generateRandomString ( str_repeat ( '*' , rand ( 8 , 12 )));
$hash = $this -> HashPassword ( $rawPassword , $loginName );
2015-05-18 11:49:32 -07:00
$updateQry = array (
2016-06-07 08:37:19 -07:00
'data' => array ( 'user_password' => $hash ),
'WHERE' => 'user_id = ' . intval ( $uid ) . " LIMIT 1 " ,
'_FIELD_TYPES' => array ( 'user_password' => 'safestr' )
2015-05-18 11:49:32 -07:00
);
if ( e107 :: getDb () -> update ( 'user' , $updateQry ))
{
2016-06-07 08:37:19 -07:00
if ( ! empty ( $options [ 'return' ]) && $options [ 'return' ] == 'array' )
{
return array ( 'password' => $rawPassword , 'hash' => $hash );
}
2015-05-18 11:49:32 -07:00
return $rawPassword ;
}
2016-06-16 12:23:20 -07:00
return false ;
2015-05-18 11:49:32 -07:00
}
2010-01-31 22:21:11 +00:00
/**
* Verifies a standard response to a CHAP challenge
*
* @ param string $challenge - the string sent to the user
* @ param string $response - the response returned by the user
* @ param string $login_name - user ' s login name
* @ param string $stored_hash - password hash as stored in DB
*
2022-04-04 10:54:24 -07:00
* @ return bool | string
2010-01-31 22:21:11 +00:00
*/
public function CheckCHAP ( $challenge , $response , $login_name , $stored_hash )
2008-06-13 20:20:23 +00:00
{
2010-01-31 22:21:11 +00:00
if ( strlen ( $challenge ) != 40 ) return PASSWORD_INVALID ;
if ( strlen ( $response ) != 32 ) return PASSWORD_INVALID ;
$valid_ret = PASSWORD_VALID ;
if ( strlen ( $stored_hash ) == 32 )
{ // Its simple md5 password storage
$stored_hash = PASSWORD_E107_ID . md5 ( $stored_hash . $login_name ); // Convert to the salted format always used by CHAP
2016-06-06 19:54:48 -07:00
if ( $this -> passwordOpts != PASSWORD_E107_MD5 ) $valid_ret = $stored_hash ;
2010-01-31 22:21:11 +00:00
}
$testval = md5 ( substr ( $stored_hash , strlen ( PASSWORD_E107_ID )) . $challenge );
if ( $testval == $response ) return $valid_ret ;
return PASSWORD_INVALID ;
2008-06-13 20:20:23 +00:00
}
2010-01-31 22:21:11 +00:00
/**
* Checks whether the user has to validate a change of user settings by entering password ( basically , if that field affects the
* stored password value )
*
* @ param string $fieldName - name of field being changed
*
2016-06-06 19:54:48 -07:00
* @ return bool TRUE if change required , false otherwise
2010-01-31 22:21:11 +00:00
*/
public function isPasswordRequired ( $fieldName )
2008-06-13 20:20:23 +00:00
{
2016-06-06 19:54:48 -07:00
if ( $this -> preferred == PASSWORD_E107_MD5 ) return false ;
2008-12-21 11:07:58 +00:00
switch ( $fieldName )
{
case 'user_email' :
return $this -> passwordEmail ;
case 'user_loginname' :
return TRUE ;
}
2016-06-06 19:54:48 -07:00
return false ;
2008-06-13 20:20:23 +00:00
}
2008-12-21 11:07:58 +00:00
2010-01-31 22:21:11 +00:00
/**
* Determines whether its necessary to store a separate password for email address validation
*
* @ return bool TRUE if separate password
*/
public function needEmailPassword ()
2008-12-21 11:07:58 +00:00
{
2016-06-06 19:54:48 -07:00
if ( $this -> preferred == PASSWORD_E107_MD5 ) return false ;
2008-12-21 11:07:58 +00:00
if ( $this -> passwordEmail ) return TRUE ;
2016-06-06 19:54:48 -07:00
return false ;
2008-12-21 11:07:58 +00:00
}
2022-04-04 10:54:24 -07:00
/**
* @ param $userjoined
* @ return bool
*/
2021-01-16 08:43:51 -08:00
public function newUserExpired ( $userjoined )
{
$new_user_period = ( int ) e107 :: getPref ( 'user_new_period' , 0 );
if ( empty ( $new_user_period ))
{
return true ;
}
$userjoined = ( int ) $userjoined ;
return ( time () > ( $userjoined + ( $new_user_period ) * 86400 ));
}
2008-12-30 14:05:44 +00:00
2010-01-31 22:21:11 +00:00
/**
* Checks whether the password value can be converted to the current default
*
* @ param string $password - hashed password
2016-06-06 19:54:48 -07:00
* @ return bool TRUE if conversion possible , false if not possible , or not needed .
2010-01-31 22:21:11 +00:00
*/
public function canConvert ( $password )
2008-06-13 20:20:23 +00:00
{
2016-06-06 19:54:48 -07:00
if ( $this -> preferred == PASSWORD_E107_MD5 ) return false ;
2010-01-31 22:21:11 +00:00
if ( strlen ( $password ) == 32 ) return TRUE ; // Can convert from md5 to salted
2016-06-06 19:54:48 -07:00
return false ;
2008-06-13 20:20:23 +00:00
}
2010-01-31 22:21:11 +00:00
/**
* Given md5 - encoded password and login name , generate password string to store in DB
*
* @ param string $password - MD5 - hashed password
* @ param string $login_name - user ' s login name
*
* @ return string hashed password to store in DB , converted as necessary
*/
public function ConvertPassword ( $password , $login_name )
2008-06-13 20:20:23 +00:00
{
2016-06-06 19:54:48 -07:00
if ( $this -> canConvert ( $password ) === false ) return $password ;
2010-01-31 22:21:11 +00:00
return PASSWORD_E107_ID . md5 ( $password . $login_name );
2008-06-13 20:20:23 +00:00
}
2010-01-31 22:21:11 +00:00
/**
* Generates a random user login name according to some pattern .
* Checked for uniqueness .
*
* @ param string $pattern - defines the format of the username
* @ param int $seed - may be used with the random pattern generator
*
* @ return string a user login name , guaranteed unique in the database .
*/
public function generateUserLogin ( $pattern , $seed = '' )
2008-06-13 20:20:23 +00:00
{
2010-01-31 22:21:11 +00:00
$ul_sql = new db ;
if ( strlen ( $pattern ) < 6 ) $pattern = '##....' ;
do
{
$newname = $this -> generateRandomString ( $pattern , $seed );
2013-02-22 15:45:31 -08:00
} while ( $ul_sql -> select ( 'user' , 'user_id' , " `user_loginname`=' { $newname } ' " ));
2010-01-31 22:21:11 +00:00
return $newname ;
2008-06-13 20:20:23 +00:00
}
2010-01-31 22:21:11 +00:00
/**
* Generates a random string - for user login name , password etc , according to some pattern .
* @ param string $pattern - defines the output format :
* # - an alpha character
* . - a numeric character
* * - an alphanumeric character
2015-05-12 20:15:05 -07:00
* ! - symbol character
* ? - alpha , numeric or symbol character .
2010-01-31 22:21:11 +00:00
* ^ - next character from seed
* alphanumerics are included 'as is'
* @ param int $seed - may be used with the random pattern generator
*
* @ return string - the required random string
*/
2015-05-12 20:15:05 -07:00
public function generateRandomString ( $pattern = '' , $seed = '' )
2008-06-13 20:20:23 +00:00
{
2013-10-16 18:13:21 +03:00
if ( empty ( $pattern ))
2015-05-12 20:15:05 -07:00
{
2009-08-08 23:09:08 +00:00
$pattern = '##....' ;
2015-05-12 20:15:05 -07:00
}
2009-08-08 23:09:08 +00:00
$newname = '' ;
// Create alpha [A-Z][a-z]
2015-05-12 20:15:05 -07:00
$alpha = 'AaBbCcDdEeFfGgHhIiJjKkLMmNnPpQqRrSsTtUuVvWwXxYyZz' ; // O, o and l removed to avoid possible confusion with numbers.
2009-08-08 23:09:08 +00:00
$alphaLength = strlen ( $alpha ) - 1 ;
// Create digit [0-9]
2015-05-12 20:15:05 -07:00
$digit = '0123456789' ;
2009-08-08 23:09:08 +00:00
$digitLength = strlen ( $digit ) - 1 ;
// Create alpha numeric [A-Z][a-z]
2020-02-17 10:36:03 +01:00
$alphaNum = $alpha . $digit . chr ( 45 ) . chr ( 95 ); // add support for - and _
2009-08-08 23:09:08 +00:00
$alphaNumLength = strlen ( $alphaNum ) - 1 ;
2015-05-12 20:15:05 -07:00
$symbols = " ~!@# $ %^*-+?;: " ; // avoid < > and quotes.
$symbolsLength = strlen ( $symbols ) - 1 ;
$alphaNumSymbol = $alphaNum . $symbols ;
$alphaNumSymbolLength = strlen ( $alphaNumSymbol ) - 1 ;
2009-08-08 23:09:08 +00:00
// Next character of seed (if used)
$seed_ptr = 0 ;
for ( $i = 0 , $patternLength = strlen ( $pattern ); $i < $patternLength ; $i ++ )
{
$c = $pattern [ $i ];
switch ( $c )
2008-06-13 20:20:23 +00:00
{
2015-05-12 20:15:05 -07:00
// Symbols only.
case '!' :
$t = rand ( 0 , $symbolsLength );
$newname .= $symbols [ $t ];
break ;
// Alphanumeric + Symbols (most secure)
case '?' :
$t = rand ( 0 , $alphaNumSymbolLength );
$newname .= $alphaNumSymbol [ $t ];
break ;
2009-08-08 23:09:08 +00:00
case '#' :
$t = rand ( 0 , $alphaLength );
$newname .= $alpha [ $t ];
break ;
// Numeric only - [0-9]
case '.' :
$t = rand ( 0 , $digitLength );
$newname .= $digit [ $t ];
break ;
// Alphanumeric
case '*' :
$t = rand ( 0 , $alphaNumLength );
$newname .= $alphaNum [ $t ];
break ;
// Next character from seed
case '^' :
if ( $seed_ptr < strlen ( $seed ))
{
$newname .= $seed [ $seed_ptr ];
$seed_ptr ++ ;
}
break ;
// (else just ignore other characters in pattern)
default :
2016-06-06 19:54:48 -07:00
if ( strrpos ( $alphaNum , $c ) !== false )
2009-08-08 23:09:08 +00:00
{
$newname .= $c ;
}
2008-06-13 20:20:23 +00:00
}
}
2009-08-08 23:09:08 +00:00
return $newname ;
2008-06-13 20:20:23 +00:00
}
2010-01-31 22:21:11 +00:00
/**
* Split up an email address to check for banned domains .
* @ param string $email - email address to process
* @ param string $fieldname - name of field being searched in DB
*
* @ return bool | string false if invalid address . Otherwise returns a set of values to check
2012-01-02 22:06:22 +00:00
* Moved to IPHandler
2010-01-31 22:21:11 +00:00
*/
2012-01-02 22:06:22 +00:00
/*
2010-01-31 22:21:11 +00:00
public function make_email_query ( $email , $fieldname = 'banlist_ip' )
2008-06-13 20:20:23 +00:00
{
2012-01-02 22:06:22 +00:00
return e107 :: getIPHandler () -> makeEmailQuery ( $v , $fieldname ); // Valid 'stub' if required
2010-01-31 22:21:11 +00:00
$tp = e107 :: getParser ();
2009-11-19 20:37:09 +00:00
$tmp = strtolower ( $tp -> toDB ( trim ( substr ( $email , strrpos ( $email , " @ " ) + 1 )))); // Pull out the domain name
2016-06-06 19:54:48 -07:00
if ( $tmp == '' ) return false ;
if ( strpos ( $tmp , '.' ) === false ) return false ;
2009-11-19 20:37:09 +00:00
$em = array_reverse ( explode ( '.' , $tmp ));
$line = '' ;
2010-02-21 16:04:26 +00:00
$out = array ( $fieldname . " ='*@ { $tmp } ' " ); // First element looks for domain as email address
2009-11-19 20:37:09 +00:00
foreach ( $em as $e )
{
$line = '.' . $e . $line ;
$out [] = '`' . $fieldname . " `='* { $line } ' " ;
}
return implode ( ' OR ' , $out );
2008-06-13 20:20:23 +00:00
}
2012-01-02 22:06:22 +00:00
*/
2008-06-13 20:20:23 +00:00
2010-01-31 22:21:11 +00:00
/**
* Create user cookie
*
* @ param array $lode - user information from DB - 'user_id' and 'user_password' required
* @ param bool $autologin - TRUE if the 'Remember Me' box ticked
*
2010-05-13 15:47:31 +00:00
* @ return void
2010-01-31 22:21:11 +00:00
*/
2016-06-06 19:54:48 -07:00
public function makeUserCookie ( $lode , $autologin = false )
2008-08-26 19:45:42 +00:00
{
2021-01-11 15:14:56 -08:00
if ( e107 :: isCli ())
{
return true ;
}
2010-01-31 22:21:11 +00:00
$cookieval = $lode [ 'user_id' ] . '.' . md5 ( $lode [ 'user_password' ]); // (Use extra md5 on cookie value to obscure hashed value for password)
2021-01-27 16:19:37 -08:00
if ( e107 :: getPref ( 'user_tracking' , 'session' ) == 'session' )
2008-08-26 19:45:42 +00:00
{
2010-05-13 15:47:31 +00:00
$_SESSION [ e107 :: getPref ( 'cookie_name' )] = $cookieval ;
2008-12-30 14:05:44 +00:00
}
else
2008-08-26 19:45:42 +00:00
{
2008-12-30 14:05:44 +00:00
if ( $autologin == 1 )
2008-12-28 22:37:43 +00:00
{ // Cookie valid for up to 30 days
2010-05-13 15:47:31 +00:00
cookie ( e107 :: getPref ( 'cookie_name' ), $cookieval , ( time () + 3600 * 24 * 30 ));
$_COOKIE [ e107 :: getPref ( 'cookie_name' )] = $cookieval ; // make it available to the global scope before the page is reloaded
2008-12-30 14:05:44 +00:00
}
else
2008-12-28 22:37:43 +00:00
{
2010-05-13 15:47:31 +00:00
cookie ( e107 :: getPref ( 'cookie_name' ), $cookieval );
$_COOKIE [ e107 :: getPref ( 'cookie_name' )] = $cookieval ; // make it available to the global scope before the page is reloaded
2008-12-28 22:37:43 +00:00
}
2008-08-26 19:45:42 +00:00
}
2016-06-16 12:23:20 -07:00
// echo "Debug: making cookie: ".$cookieval ." from ".print_a($lode,true);
// exit;
2008-08-26 19:45:42 +00:00
}
2008-06-13 20:20:23 +00:00
2008-12-21 11:07:58 +00:00
2010-01-31 22:21:11 +00:00
/**
* Generate an array of all the basic classes a user belongs to
*
* Note that the passed data may relate to the currently logged in user , or if an admin is logged in , to a different user
*
* @ param array $userData - user 's data record - must include the ' user_class ' element
* @ param boolean $asArray if TRUE , returns results in an array ; else as a comma - separated string
* @ param boolean $incInherited if TRUE , includes inherited classes
* @ param boolean $fromAdmin - if TRUE , adds e_UC_ADMIN and e_UC_MAINADMIN in if current user ' s entitlement permits
*
* @ return array | string of userclass information according to $asArray
*/
2016-06-06 19:54:48 -07:00
public function addCommonClasses ( $userData , $asArray = false , $incInherited = false , $fromAdmin = false )
2008-12-21 11:07:58 +00:00
{
if ( $incInherited )
{
2015-05-21 19:19:36 -07:00
$classList = e107 :: getUserClass () -> get_all_user_classes ( $userData [ 'user_class' ]);
2008-12-21 11:07:58 +00:00
}
else
{
2016-10-16 23:45:13 +01:00
if ( ! empty ( $userData [ 'user_class' ])) $classList = explode ( ',' , $userData [ 'user_class' ]);
2008-12-21 11:07:58 +00:00
}
foreach ( array ( e_UC_MEMBER , e_UC_READONLY , e_UC_PUBLIC ) as $c )
{
2018-09-08 10:45:18 -07:00
if ( ! in_array ( $c , vartrue ( $classList , array ())))
2008-12-21 11:07:58 +00:00
{
$classList [] = $c ;
}
}
2010-01-31 22:21:11 +00:00
if ((( varset ( $userData [ 'user_admin' ], 0 ) == 1 ) && strlen ( $userData [ 'user_perms' ])) || ( $fromAdmin && ADMIN ))
2008-12-21 11:07:58 +00:00
{
2010-01-31 22:21:11 +00:00
$classList [] = e_UC_ADMIN ;
if (( strpos ( $userData [ 'user_perms' ], '0' ) === 0 ) || getperms ( '0' ))
{
$classList [] = e_UC_MAINADMIN ;
}
2008-12-21 11:07:58 +00:00
}
if ( $asArray ) return $classList ;
return implode ( ',' , $classList );
}
2010-01-31 22:21:11 +00:00
/**
2015-02-15 02:37:36 -08:00
* Return an array of descriptive names for each field in the user DB .
* @ param bool $all if false , just returns modifiable fields . Else returns all
* @ return array - key is field name , value is 'nice name' ( descriptive name )
2010-01-31 22:21:11 +00:00
*/
2016-06-06 19:54:48 -07:00
public function getNiceNames ( $all = false )
2008-12-21 11:07:58 +00:00
{
// $ret = array('user_id' => LAN_USER_13);
foreach ( $this -> userVettingInfo as $k => $v )
{
$ret [ $k ] = $v [ 'niceName' ];
}
if ( $all )
{
$ret = array_merge ( $ret , $this -> otherFields );
}
return $ret ;
}
//===================================================
// User Field validation
//===================================================
/* $_POST field names :
DB signup usersettings quick add function
------------------------------------------------------------------------------
user_id - user_id - Unique user ID
2008-12-21 22:17:05 +00:00
user_name name $ username username Display name
2008-12-21 11:07:58 +00:00
user_loginname loginname loginname loginname User name ( login name )
user_customtitle - customtitle - Custom title
user_password password1 password1 password1 Password ( prior to encoding )
password2 password2 password1 ( Check password field )
user_sess * - Photo ( file on server )
user_email email email email Email address
email_confirm
user_signature signature signature - User signature
user_image image image * - Avatar ( may be external URL or file on server )
user_hideemail hideemail hideemail - Flag to hide user ' s email address
user_login realname realname realname User Real name
2008-12-21 22:17:05 +00:00
user_xup xupexist $ user_xup - XUP file link
2008-12-21 11:07:58 +00:00
user_class class class userclass User class ( array on form )
2008-12-30 14:05:44 +00:00
2008-12-21 11:07:58 +00:00
user_loginname may be auto - generated
* avatar ( user_image ) and photo ( user_sess ) may be uploaded files
2008-12-21 22:17:05 +00:00
$changed to match the majority vote
2008-12-21 11:07:58 +00:00
Following fields auto - filled in code as required :
user_join
user_lastvisit
user_currentvisit
user_chats
user_comments
user_forums
user_ip
user_ban
user_prefs
user_viewed
user_visits
user_admin
user_perms
user_pwchange
*/
2010-01-31 22:21:11 +00:00
/**
* Function does validation specific to user data . Updates the $targetData array as appropriate .
*
* @ param array $targetData - user data generated from earlier vetting stages - only the data in $targetData [ 'data' ] is checked
*
2016-06-06 19:54:48 -07:00
* @ return bool TRUE if nothing updated ; false if errors found
2010-01-31 22:21:11 +00:00
*/
public function userValidation ( & $targetData )
2008-12-21 11:07:58 +00:00
{
2011-09-14 11:09:05 +00:00
$u_sql = e107 :: getDb ( 'u' );
2008-12-21 11:07:58 +00:00
$ret = TRUE ;
2009-10-06 18:58:08 +00:00
$errMsg = '' ;
2009-01-11 21:06:52 +00:00
if ( isset ( $targetData [ 'data' ][ 'user_email' ]))
2008-12-21 11:07:58 +00:00
{
2009-01-11 21:06:52 +00:00
$v = trim ( $targetData [ 'data' ][ 'user_email' ]); // Always check email address if its entered
2008-12-21 11:07:58 +00:00
if ( $v == '' )
{
2011-09-14 11:09:05 +00:00
if ( ! e107 :: getPref ( 'disable_emailcheck' ))
2009-10-06 18:58:08 +00:00
{
$errMsg = ERR_MISSING_VALUE ;
}
2008-12-21 11:07:58 +00:00
}
elseif ( ! check_email ( $v ))
{
$errMsg = ERR_INVALID_EMAIL ;
}
2017-09-19 16:19:39 -07:00
elseif ( $u_sql -> count ( 'user' , '(*)' , " WHERE `user_email`=' " . filter_var ( $v , FILTER_SANITIZE_EMAIL ) . " ' AND `user_ban`=1 " ))
2008-12-21 11:07:58 +00:00
{
2020-02-19 21:20:48 +01:00
$errMsg = ERR_BANNED_USER ;
2008-12-21 11:07:58 +00:00
}
else
{ // See if email address banned
2012-01-02 22:06:22 +00:00
$wc = e107 :: getIPHandler () -> makeEmailQuery ( $v ); // Generate the query for the ban list
2008-12-21 11:07:58 +00:00
if ( $wc ) { $wc = " `banlist_ip`=' { $v } ' OR " . $wc ; }
2016-06-06 19:54:48 -07:00
if (( $wc === false ) || ! e107 :: getIPHandler () -> checkBan ( $wc , false , TRUE ))
2008-12-21 11:07:58 +00:00
{
2009-10-06 18:58:08 +00:00
// echo "Email banned<br />";
2008-12-21 11:07:58 +00:00
$errMsg = ERR_BANNED_EMAIL ;
}
}
if ( $errMsg )
{
2009-01-11 21:06:52 +00:00
unset ( $targetData [ 'data' ][ 'user_email' ]); // Remove the valid entry
2008-12-21 11:07:58 +00:00
}
}
else
{
2011-09-14 11:09:05 +00:00
if ( ! isset ( $targetData [ 'errors' ][ 'user_email' ]) && ! e107 :: getPref ( 'disable_emailcheck' ))
2008-12-21 11:07:58 +00:00
{ // We may have already picked up an error on the email address - or it may be allowed to be empty
$errMsg = ERR_MISSING_VALUE ;
}
}
if ( $errMsg )
{ // Update the error
$targetData [ 'errors' ][ 'user_email' ] = $errMsg ;
$targetData [ 'failed' ][ 'user_email' ] = $v ;
2016-06-06 19:54:48 -07:00
$ret = false ;
2008-12-21 11:07:58 +00:00
}
return $ret ;
}
2010-01-31 22:21:11 +00:00
/**
* Given an array of user data intended to be written to the DB , adds empty strings ( or other default value ) for any field which doesn ' t have a default in the SQL definition .
* ( Avoids problems with MySQL in STRICT mode . ) .
*
* @ param array $userInfo - user data destined for the database
*
2016-06-06 19:54:48 -07:00
* @ return bool TRUE if additions made , false if no change .
2010-01-31 22:21:11 +00:00
*
* @ todo - may be unnecessary with auto - generation of _NOTNULL array in db handler
*/
public function addNonDefaulted ( & $userInfo )
2008-12-21 11:07:58 +00:00
{
2009-06-12 20:41:35 +00:00
// $nonDefaulted = array('user_signature' => '', 'user_prefs' => '', 'user_class' => '', 'user_perms' => '');
$nonDefaulted = array ( 'user_signature' => '' , 'user_prefs' => '' , 'user_class' => '' , 'user_perms' => '' , 'user_realm' => '' ); // Delete when McFly finished
2016-06-06 19:54:48 -07:00
$ret = false ;
2008-12-21 11:07:58 +00:00
foreach ( $nonDefaulted as $k => $v )
{
if ( ! isset ( $userInfo [ $k ]))
{
$userInfo [ $k ] = $v ;
$ret = TRUE ;
}
}
return $ret ;
}
2008-12-30 14:05:44 +00:00
2010-01-31 22:21:11 +00:00
/**
* Delete time - expired partial registrations from the user DB , clean up user_extended table
*
* @ param bool $force - set TRUE to force check of user_extended table
*
* @ return int number of user records deleted
*/
2016-06-06 19:54:48 -07:00
public function deleteExpired ( $force = false )
2008-12-21 11:07:58 +00:00
{
2011-09-14 11:09:05 +00:00
$pref = e107 :: getPref ();
$sql = e107 :: getDb ();
2020-02-19 21:20:48 +01:00
2009-04-23 19:58:28 +00:00
$temp1 = 0 ;
2015-05-24 12:12:24 -07:00
if ( isset ( $pref [ 'del_unv' ]) && $pref [ 'del_unv' ] && intval ( $pref [ 'user_reg_veri' ]) != 2 )
2008-12-21 11:07:58 +00:00
{
2008-12-28 22:37:43 +00:00
$threshold = intval ( time () - ( $pref [ 'del_unv' ] * 60 ));
2015-05-24 12:12:24 -07:00
if (( $temp1 = $sql -> delete ( 'user' , 'user_ban = 2 AND user_join < ' . $threshold )) > 0 )
{
$force = true ;
}
2008-12-21 11:07:58 +00:00
}
2015-05-24 12:12:24 -07:00
if ( $force ) // Remove 'orphaned' extended user field records
{
2013-02-22 15:45:31 -08:00
$sql -> gen ( " DELETE `#user_extended` FROM `#user_extended` LEFT JOIN `#user` ON `#user_extended`.`user_extended_id` = `#user`.`user_id`
2009-04-23 19:58:28 +00:00
WHERE `#user` . `user_id` IS NULL " );
}
2015-05-24 12:12:24 -07:00
2009-04-23 19:58:28 +00:00
return $temp1 ;
2008-12-21 11:07:58 +00:00
}
2009-04-23 19:58:28 +00:00
2009-06-12 20:41:35 +00:00
2010-01-31 22:21:11 +00:00
/**
* Called to update initial user classes , probationary user class etc after various user events
*
* @ param array $user - user data . 'user_class' must be present
* @ param string $event = userveri | userall | userfull | userpartial - defines event
*
* @ return boolean - true if $user [ 'user_class' ] updated , false otherwise
*/
2014-08-29 14:56:16 +02:00
public function userClassUpdate ( $user , $event = 'userfull' )
2009-06-12 20:41:35 +00:00
{
2011-09-14 11:09:05 +00:00
$pref = e107 :: getPref ();
2010-01-31 22:21:11 +00:00
$tp = e107 :: getParser ();
2009-06-12 20:41:35 +00:00
2020-01-18 00:27:18 +01:00
$initClassStage = isset ( $pref [ 'init_class_stage' ]) ? intval ( $pref [ 'init_class_stage' ]) : 0 ;
2009-06-12 20:41:35 +00:00
$initClasses = array ();
2015-05-21 19:19:36 -07:00
$doClasses = false ;
$doProbation = false ;
$ret = false ;
2014-08-29 14:56:16 +02:00
2015-05-21 19:19:36 -07:00
switch ( $event )
2009-06-12 20:41:35 +00:00
{
2014-08-29 14:56:16 +02:00
case 'userall' :
2015-05-21 19:19:36 -07:00
$doClasses = true ;
$doProbation = true ;
2009-06-12 20:41:35 +00:00
break ;
2015-05-21 19:19:36 -07:00
case 'userfull' :
2020-01-18 00:27:18 +01:00
if ( ! $pref [ 'user_reg_veri' ] || ( $initClassStage == 2 ))
2009-06-12 20:41:35 +00:00
{
2015-05-21 19:19:36 -07:00
$doClasses = true ;
2009-06-12 20:41:35 +00:00
}
2015-05-21 19:19:36 -07:00
$doProbation = true ;
2009-06-12 20:41:35 +00:00
break ;
case 'userpartial' :
2020-01-18 00:27:18 +01:00
if ( $initClassStage === 1 )
2015-05-21 19:19:36 -07:00
{
2014-08-29 14:56:16 +02:00
// Set initial classes if to be done on partial signup, or if selected to add them now
2015-05-21 19:19:36 -07:00
$doClasses = true ;
2009-06-12 20:41:35 +00:00
}
2015-05-21 19:19:36 -07:00
$doProbation = true ;
2009-06-12 20:41:35 +00:00
break ;
}
2015-05-21 19:19:36 -07:00
2014-08-29 14:56:16 +02:00
if ( $doClasses )
2009-06-12 20:41:35 +00:00
{
2015-05-21 19:19:36 -07:00
if ( isset ( $pref [ 'initial_user_classes' ])) // Any initial user classes to be set at some stage
{
$initClasses = explode ( ',' , $pref [ 'initial_user_classes' ]);
}
if ( $doProbation && ( varset ( $pref [ 'user_new_period' ], 0 ) > 0 ))
2009-06-12 20:41:35 +00:00
{
2015-05-21 19:19:36 -07:00
$initClasses [] = e_UC_NEWUSER ; // Probationary user class
2009-06-12 20:41:35 +00:00
}
2015-05-21 19:19:36 -07:00
if ( count ( $initClasses ))
{ // Update the user classes
if ( $user [ 'user_class' ])
2009-06-12 20:41:35 +00:00
{
2015-05-21 19:19:36 -07:00
$initClasses = array_unique ( array_merge ( $initClasses , explode ( ',' , $user [ 'user_class' ])));
2009-06-12 20:41:35 +00:00
}
2015-05-21 19:19:36 -07:00
$user [ 'user_class' ] = $tp -> toDB ( implode ( ',' , $initClasses ));
2014-08-29 14:56:16 +02:00
//$ret = TRUE;
$ret = $user [ 'user_class' ];
2009-06-12 20:41:35 +00:00
}
}
2015-05-21 19:19:36 -07:00
2010-01-31 22:21:11 +00:00
return $ret ;
2009-11-30 20:40:03 +00:00
}
2009-06-12 20:41:35 +00:00
2010-01-31 22:21:11 +00:00
2009-11-30 20:40:03 +00:00
/**
* Updates user status , primarily the user_ban field , to reflect outside events
2010-01-31 22:21:11 +00:00
*
2022-04-04 10:54:24 -07:00
* @ param string $action - 'ban' , 'bounce'
2009-12-16 22:26:27 +00:00
* @ param integer $uid - internal user ID , zero if not known
* @ param string $emailAddress - email address ( optional )
2010-01-31 22:21:11 +00:00
*
2016-06-06 19:54:48 -07:00
* @ return boolean | string - false if user found , error message if not
2009-11-30 20:40:03 +00:00
*/
public function userStatusUpdate ( $action , $uid , $emailAddress = '' )
{
2015-05-25 13:37:17 -07:00
$db = e107 :: getDb ( 'user' );
2009-11-30 20:40:03 +00:00
$qry = '' ;
2016-06-06 19:54:48 -07:00
$error = false ; // Assume no error to start with
2009-11-30 20:40:03 +00:00
$uid = intval ( $uid ); // Precautionary - should have already been done
switch ( $action )
{
case 'ban' :
$newVal = USER_BANNED ;
$logEvent = USER_AUDIT_BANNED ;
break ;
case 'bounce' :
$newVal = USER_EMAIL_BOUNCED ;
$logEvent = USER_AUDIT_MAIL_BOUNCE ;
break ;
case 'reset' :
$newVal = USER_BOUNCED_RESET ;
$logEvent = USER_AUDIT_BOUNCE_RESET ;
break ;
case 'temp' :
$newVal = USER_TEMPORARY_ACCOUNT ;
$logEvent = USER_AUDIT_TEMP_ACCOUNT ;
break ;
default :
return 'Invalid action: ' . $action ;
}
if ( $uid ) { $qry = '`user_id`=' . $uid ; }
if ( $emailAddress ) { if ( $qry ) $qry .= ' OR ' ; $qry .= " `user_email` = ' { $emailAddress } ' " ; }
2016-06-06 19:54:48 -07:00
if ( false === $db -> select ( 'user' , 'user_id, user_email, user_ban, user_loginname' , $qry . ' LIMIT 1' ))
2009-11-30 20:40:03 +00:00
{
$error = 'User not found: ' . $uid . '/' . $emailAddress ;
}
else
{
2020-12-14 16:21:48 -08:00
$row = $db -> fetch ();
2009-11-30 20:40:03 +00:00
if ( $uid && ( $uid != $row [ 'user_id' ]))
{
$error = 'UID mismatch: ' . $uid . '/' . $row [ 'user_id' ];
}
elseif ( $emailAddress && ( $emailAddress != $row [ 'user_email' ]))
{
$error = 'User email mismatch: ' . $emailAddress . '/' . $row [ 'user_email' ];
}
else
{ // Valid user!
if ( $row [ 'user_ban' ] != $newVal ) // We could implement a hierarchy here, so that an important status isn't overridden by a lesser one
{ // Only update if needed
2016-03-16 13:53:57 -07:00
$db -> update ( 'user' , '`user_ban` = ' . $newVal . ', `user_email` = \'\' WHERE `user_id` = ' . $row [ 'user_id' ] . ' LIMIT 1' );
2009-11-30 20:40:03 +00:00
// Add to user audit log TODO: Should we log to admin log as well?
2020-12-22 09:36:02 -08:00
$adminLog = e107 :: getLog ();
2009-11-30 20:40:03 +00:00
$adminLog -> user_audit ( $logEvent , array ( 'user_ban' => $newVal , 'user_email' => $row [ 'user_email' ]), $row [ 'user_id' ], $row [ 'user_loginname' ]);
}
}
}
return $error ;
2009-06-12 20:41:35 +00:00
}
2008-06-13 20:20:23 +00:00
}
2020-02-17 10:36:03 +01:00
/**
* Social login provider
*/
2012-07-31 07:32:00 +00:00
class e_user_provider
{
/**
* @ var string
*/
protected $_provider ;
2020-02-17 10:36:03 +01:00
2012-07-31 07:32:00 +00:00
/**
* Hybridauth adapter
2021-12-28 11:49:58 +01:00
*
* @ var \Hybridauth\Adapter\AdapterInterface | null
2012-07-31 07:32:00 +00:00
*/
public $adapter ;
2020-02-17 10:36:03 +01:00
2012-07-31 07:32:00 +00:00
/**
* Hybridauth object
2021-12-28 11:49:58 +01:00
*
2020-02-14 12:25:15 +01:00
* @ var Hybridauth\Hybridauth
2012-07-31 07:32:00 +00:00
*/
2020-02-17 10:36:03 +01:00
protected $hybridauth ;
2012-07-31 07:32:00 +00:00
protected $_config = array ();
2020-02-17 10:36:03 +01:00
/**
2021-12-28 11:49:58 +01:00
* @ var social_login_config | null
2020-02-17 10:36:03 +01:00
*/
2021-12-28 11:49:58 +01:00
protected $social_login_config_manager = null ;
2020-02-17 10:36:03 +01:00
2021-12-28 11:49:58 +01:00
/**
* Create a new Hybridauth - backed social login provider
*
* This constructor suppresses exceptions due to client usages not handling exceptions and instead sends error
* messages to logged in admins . To check if a Hybridauth configuration is valid , use
* { @ link e107 :: getUserProvider ()} with the provider name while logged in as an admin .
*
* @ param string | null $provider The name of the provider to use
* @ param array $config An override Hybridauth configuration that takes precedence over the
* database Hybridauth configuration for this provider . Leave blank to use
* the database configuration .
* @ param bool $suppress_exceptions Set to false to propagate Hybridauth exceptions
* @ throws \Hybridauth\Exception\UnexpectedValueException if the provider is disabled
* @ throws \Hybridauth\Exception\InvalidArgumentException if the provider configuration validation failed
*/
public function __construct ( $provider = null , $config = array (), $suppress_exceptions = true )
2012-07-31 07:32:00 +00:00
{
2021-12-28 11:49:58 +01:00
@ include_once ( e_PLUGIN . " social/includes/social_login_config.php " );
if ( ! class_exists ( 'social_login_config' )) return ;
2020-02-28 10:33:50 -08:00
$this -> social_login_config_manager = new social_login_config ( e107 :: getConfig ());
2020-02-17 10:36:03 +01:00
if ( ! empty ( $config ))
2012-07-31 07:32:00 +00:00
{
$this -> _config = $config ;
}
2020-02-17 10:36:03 +01:00
else
2012-07-31 07:32:00 +00:00
{
$this -> _config = array (
2021-12-28 11:48:00 +01:00
" callback " => $this -> generateCallbackUrl ( $provider ),
" providers " => $this -> social_login_config_manager -> getSupportedConfiguredProviderConfigs (),
2020-02-17 10:36:03 +01:00
" debug_mode " => 'error' ,
" debug_file " => e_LOG . " hybridAuth.log "
2012-07-31 07:32:00 +00:00
);
2020-02-17 10:36:03 +01:00
2012-07-31 07:32:00 +00:00
}
2020-02-17 10:36:03 +01:00
2021-12-28 11:51:20 +01:00
try
{
$this -> respawnHybridauth ();
$this -> setProvider ( $provider );
2020-02-19 21:20:48 +01:00
2021-12-28 11:51:20 +01:00
$providerId = $this -> getProvider ();
if ( $providerId && $this -> hybridauth -> isConnectedWith ( $providerId ))
{
$this -> adapter = $this -> hybridauth -> getAdapter ( $providerId );
}
}
catch ( \Hybridauth\Exception\InvalidArgumentException $e )
{
if ( ! $suppress_exceptions ) throw $e ;
}
catch ( \Hybridauth\Exception\UnexpectedValueException $e )
2020-02-19 21:20:48 +01:00
{
2021-12-28 11:51:20 +01:00
if ( ! $suppress_exceptions ) throw $e ;
2020-02-19 21:20:48 +01:00
}
2012-07-31 07:32:00 +00:00
}
2020-02-19 21:20:48 +01:00
2021-12-28 11:51:20 +01:00
/**
* @ throws \Hybridauth\Exception\InvalidArgumentException
*/
2020-02-19 21:20:48 +01:00
private function respawnHybridauth ()
2012-07-31 07:32:00 +00:00
{
2020-02-19 21:20:48 +01:00
$this -> hybridauth = new Hybridauth\Hybridauth ( $this -> _config );
2012-07-31 07:32:00 +00:00
}
2016-12-11 20:30:27 +01:00
2022-04-04 10:54:24 -07:00
/**
* @ param $provider
* @ return void
*/
2012-07-31 07:32:00 +00:00
public function setProvider ( $provider )
{
2020-02-17 10:36:03 +01:00
$this -> _provider = $provider ;
2012-07-31 07:32:00 +00:00
}
2016-12-11 20:30:27 +01:00
2022-04-04 10:54:24 -07:00
/**
* @ param $url
* @ return void
* @ throws \Hybridauth\Exception\InvalidArgumentException
*/
2020-02-26 21:22:45 +01:00
public function setBackUrl ( $url )
2012-07-31 07:32:00 +00:00
{
2020-02-14 12:25:15 +01:00
# system/xup/login by default
2020-02-26 21:22:45 +01:00
$this -> _config [ 'callback' ] = $this -> generateCallbackUrl ( $url );
2020-02-19 21:20:48 +01:00
$this -> respawnHybridauth ();
2012-07-31 07:32:00 +00:00
}
2016-12-11 20:30:27 +01:00
2022-04-04 10:54:24 -07:00
/**
* @ return string
*/
2012-07-31 07:32:00 +00:00
public function getProvider ()
{
2016-03-16 12:05:10 -07:00
// $this->log(__CLASS__, __METHOD__, __LINE__);
2012-07-31 07:32:00 +00:00
return $this -> _provider ;
}
2016-12-11 20:30:27 +01:00
2022-04-04 10:54:24 -07:00
/**
* @ return array
*/
2012-07-31 07:32:00 +00:00
public function getConfig ()
{
return $this -> _config ;
}
2016-12-11 20:30:27 +01:00
2022-04-04 10:54:24 -07:00
/**
* @ return \Hybridauth\User\Profile | null
*/
2012-07-31 07:32:00 +00:00
public function getUserProfile ()
{
2020-02-17 10:36:03 +01:00
if ( $this -> adapter )
2012-07-31 07:32:00 +00:00
{
2020-02-17 10:36:03 +01:00
try
{
return $this -> adapter -> getUserProfile ();
}
catch ( \Hybridauth\Exception\Exception $e )
{
return null ;
}
2012-07-31 07:32:00 +00:00
}
return null ;
}
2016-12-11 20:30:27 +01:00
2022-04-04 10:54:24 -07:00
/**
* @ return string | null
*/
2012-07-31 07:32:00 +00:00
public function userId ()
{
2020-02-17 10:36:03 +01:00
if ( $profile = $this -> getUserProfile ())
2012-07-31 07:32:00 +00:00
{
2020-02-17 10:36:03 +01:00
return $this -> getProvider () . '_' . $profile -> identifier ;
2016-12-11 20:30:27 +01:00
}
2012-07-31 07:32:00 +00:00
return null ;
}
2020-02-17 10:36:03 +01:00
2015-01-23 21:10:30 -08:00
/**
2020-02-17 10:36:03 +01:00
* Get the social login providers for which we have adapters
*
2021-12-28 11:51:20 +01:00
* Despite this being a static method , it memoizes ( caches ) the slow reflection code in the { @ link e107 } registry
* after the first run , so subsequent calls to this method are fast .
2020-02-17 10:36:03 +01:00
*
2021-12-28 11:51:20 +01:00
* @ return string [] String list of supported providers . Empty if Hybridauth is broken .
2020-02-17 10:36:03 +01:00
*/
public static function getSupportedProviders ()
{
2020-12-23 12:42:06 -08:00
$regId = 'core/e107/user/provider' ;
if ( $cached = e107 :: getRegistry ( $regId ))
{
return $cached ;
}
2020-02-17 10:36:03 +01:00
$providers = [];
2016-12-11 20:30:27 +01:00
2020-02-17 10:36:03 +01:00
try
{
$reflector = new ReflectionClass ( 'Hybridauth\Hybridauth' );
}
catch ( ReflectionException $e )
{
return $providers ;
}
$hybridauth_path = $reflector -> getFileName ();
$hybridauth_providers_path = dirname ( $hybridauth_path ) . " /Provider/ " ;
$fs_iterator = new FilesystemIterator ( $hybridauth_providers_path );
foreach ( $fs_iterator as $file )
2012-12-20 10:45:22 +02:00
{
2020-02-17 10:36:03 +01:00
if ( ! $file -> isFile ()) continue ;
$provider_source_code = file_get_contents ( $file );
$provider_source_tokens = token_get_all ( $provider_source_code );
for ( $token_index = 0 ; isset ( $provider_source_tokens [ $token_index ]); $token_index ++ )
2012-12-20 10:45:22 +02:00
{
2020-02-17 10:36:03 +01:00
if ( ! isset ( $provider_source_tokens [ $token_index ][ 0 ])) continue ;
if ( T_CLASS === $provider_source_tokens [ $token_index ][ 0 ])
2012-12-20 10:45:22 +02:00
{
2020-02-17 10:36:03 +01:00
$token_index += 2 ;
$providers [] = $provider_source_tokens [ $token_index ][ 1 ];
2012-12-20 10:45:22 +02:00
}
}
}
2020-02-17 10:36:03 +01:00
sort ( $providers );
2020-12-23 12:42:06 -08:00
e107 :: setRegistry ( $regId , $providers );
2020-02-17 10:36:03 +01:00
return $providers ;
2012-07-31 07:32:00 +00:00
}
2016-03-16 12:05:10 -07:00
2020-02-17 10:36:03 +01:00
/**
* Get the type of provider from a provider name
* @ param $providerName string Name of the supported social login provider
* @ return string | bool " OAuth1 " , " OAuth2 " , or " OpenID " . If false , the provider name is invalid .
* Other values are technically possible but not supported .
*/
public static function getTypeOf ( $providerName )
2016-03-16 12:05:10 -07:00
{
2020-02-17 10:36:03 +01:00
$class_name = " Hybridauth \ Provider \\ { $providerName } " ;
2020-11-27 17:00:32 +01:00
$parent_class = eShims :: get_parent_class ( $class_name );
2020-02-17 10:36:03 +01:00
if ( ! $parent_class ) return false ;
2020-11-27 17:00:32 +01:00
$parent_class_split = explode ( " \\ " , eShims :: get_parent_class ( $class_name ));
2020-02-17 10:36:03 +01:00
$type = end ( $parent_class_split );
if ( $type == " AbstractAdapter " ) return $providerName ;
if ( ! in_array ( $type , [ 'OAuth1' , 'OAuth2' , 'OpenID' ])) return self :: getTypeOf ( $type );
return $type ;
2016-03-16 12:05:10 -07:00
}
2020-02-24 22:50:48 +01:00
/**
* Get standard and supplementary fields of the specified provider
* @ param $providerName string Name of the supported social login provider
* @ return array Multidimensional associative array where the keys are the known field names and the values are a
* description of what their key is for . Keys can be nested in parent keys . Parent keys will not
* have a description of the key . All fields take a string value . Return will be empty if the
* specified provider does not have any known fields .
*/
public static function getFieldsOf ( $providerName )
2012-07-31 07:32:00 +00:00
{
2020-02-24 22:50:48 +01:00
$standardFields = self :: getStandardFieldsOf ( $providerName );
$supplementaryFields = self :: getSupplementalFieldsOf ( $providerName );
return self :: array_merge_recursive_distinct ( $standardFields , $supplementaryFields );
2012-07-31 07:32:00 +00:00
}
2020-02-24 22:50:48 +01:00
2020-02-23 21:47:36 +01:00
/**
* Get the standard / common / parent fields of the specified provider
* @ param $providerName string Name of the supported social login provider
* @ return array Multidimensional associative array where the keys are the standard field names and the values are
* a description of what each key is for . Keys can be nested in parent keys . Parent keys will not
* have a description of the key . All fields take a string value . Return will be empty if the
* specified provider does not have any known standard fields .
*/
public static function getStandardFieldsOf ( $providerName )
2012-07-31 07:32:00 +00:00
{
2020-02-23 21:47:36 +01:00
$providerType = self :: getTypeOf ( $providerName );
switch ( $providerType )
{
case 'OAuth2' :
$fieldPart = [
'keys' => [
'id' => " Client ID given to you by $providerName " ,
'secret' => " Client secret given to you by $providerName " ,
],
'scope' => " Permissions to request from $providerName . See the $providerName OAuth2 documentation for details. " ,
];
break ;
case 'OAuth1' :
$fieldPart = [
'keys' => [
'key' => " Consumer key given to you by $providerName " ,
'secret' => " Consumer secret given to you by $providerName " ,
]
];
break ;
case 'OpenID' :
$fieldPart = [
'openid_identifier' => " OpenID endpoint URL "
];
break ;
default :
$fieldPart = [];
}
return $fieldPart ;
2012-07-31 07:32:00 +00:00
}
2020-02-23 21:47:36 +01:00
/**
* Get the supplemental fields specific to the specified provider
* @ param $providerName string Name of the supported social login provider
* @ return array Multidimensional associative array where the keys are the supplemental field names and the values
* are a description of what each key is for . Keys can be nested in parent keys . Parent keys will
* not have a description of the key . All fields take a string value . Return will be empty if the
* specified provider does not have any known supplemental fields .
*/
public static function getSupplementalFieldsOf ( $providerName )
2012-07-31 07:32:00 +00:00
{
2020-02-23 21:47:36 +01:00
$supplementalFields = [];
$className = " Hybridauth \ Provider \\ ${ providerName } " ;
try
{
$reflector = new ReflectionClass ( $className );
}
catch ( ReflectionException $e )
{
return $supplementalFields ;
}
$adapterPath = $reflector -> getFileName ();
$adapterSourceCode = file_get_contents ( $adapterPath );
$adapterTokens = token_get_all ( $adapterSourceCode );
$rawDocumentation = null ;
for ( $index = 0 ; isset ( $adapterTokens [ $index ]); $index ++ )
{
if ( ! isset ( $adapterTokens [ $index ][ 1 ])) continue ;
if ( T_DOC_COMMENT === $adapterTokens [ $index ][ 0 ] &&
FALSE !== strpos ( $adapterTokens [ $index ][ 1 ], '$config' ))
{
$rawDocumentation = $adapterTokens [ $index ][ 1 ];
}
if ( T_VARIABLE == $adapterTokens [ $index ][ 0 ])
{
$supplementalFieldPathSplit = self :: adapterTokenParseConfig ( $adapterTokens , $index , null );
if ( ! is_null ( $supplementalFieldPathSplit ))
{
$value = $rawDocumentation ;
$level = [];
foreach ( array_reverse ( $supplementalFieldPathSplit ) as $supplementalFieldPathItem )
{
$level [ $supplementalFieldPathItem ] = $value ;
$value = $level ;
$level = [];
}
$supplementalFields = self :: array_merge_recursive_distinct ( $supplementalFields , $value );
}
}
}
return $supplementalFields ;
2012-07-31 07:32:00 +00:00
}
2020-02-23 21:47:36 +01:00
2022-04-04 10:54:24 -07:00
/**
* @ param $adapterTokens
* @ param $index
* @ param $carry
* @ return mixed
*/
2020-02-23 21:47:36 +01:00
private static function adapterTokenParseConfig ( $adapterTokens , & $index , $carry )
2012-07-31 07:32:00 +00:00
{
2020-02-23 21:47:36 +01:00
if ( ! isset ( $adapterTokens [ $index ][ 1 ]))
2012-07-31 07:32:00 +00:00
{
2020-02-24 22:50:48 +01:00
if ( in_array ( $adapterTokens [ $index ], [ ';' , '.' , ',' , '?' ])) return $carry ;
2020-02-23 21:47:36 +01:00
++ $index ;
return self :: adapterTokenParseConfig ( $adapterTokens , $index , $carry );
2012-07-31 07:32:00 +00:00
}
2020-02-23 21:47:36 +01:00
$token = $adapterTokens [ $index ];
$tokenType = $token [ 0 ];
$tokenValue = $token [ 1 ];
switch ( $tokenType )
{
case T_VARIABLE :
if ( $tokenValue == '$this' ) break ;
return $carry ;
case T_OBJECT_OPERATOR :
break ;
case T_STRING :
switch ( $tokenValue )
{
case 'config' :
$carry = [];
break ;
case 'filter' :
case 'get' :
break ;
default :
return $carry ;
}
break ;
case T_CONSTANT_ENCAPSED_STRING :
$carry [] = trim ( $tokenValue , '\'"' );
break ;
}
++ $index ;
return self :: adapterTokenParseConfig ( $adapterTokens , $index , $carry );
2012-07-31 07:32:00 +00:00
}
2020-02-23 21:47:36 +01:00
2022-04-04 10:54:24 -07:00
/**
* @ param $array1
* @ param $array2
* @ return mixed
*/
2020-02-23 21:47:36 +01:00
private static function array_merge_recursive_distinct ( & $array1 , & $array2 )
2012-07-31 07:32:00 +00:00
{
2020-02-23 21:47:36 +01:00
$merged = $array1 ;
2016-03-16 12:05:10 -07:00
2020-02-23 21:47:36 +01:00
foreach ( $array2 as $key => & $value )
2012-07-31 07:32:00 +00:00
{
2020-02-23 21:47:36 +01:00
if ( is_array ( $value ) && isset ( $merged [ $key ]) && is_array ( $merged [ $key ]))
{
$merged [ $key ] = self :: array_merge_recursive_distinct ( $merged [ $key ], $value );
}
else
{
$merged [ $key ] = $value ;
}
2012-07-31 07:32:00 +00:00
}
2020-02-23 21:47:36 +01:00
return $merged ;
}
2020-02-22 23:55:20 +01:00
/**
* Check if social logins are enabled site - wide
* @ return bool TRUE if the site has social logins enabled ; FALSE otherwise
*/
public function isSocialLoginEnabled ()
{
2021-12-28 11:49:58 +01:00
if ( $this -> social_login_config_manager === null ) return false ;
2020-02-28 10:33:50 -08:00
return $this -> social_login_config_manager -> isFlagActive ( social_login_config :: ENABLE_BIT_GLOBAL );
2012-07-31 07:32:00 +00:00
}
2020-02-22 23:55:20 +01:00
2015-01-23 21:10:30 -08:00
/**
2020-02-17 10:36:03 +01:00
* XUP Signup Method ( falls - back to XUP login when existing user is detected ) .
* May be used as a simple XUP login link for existing and non - existing users .
2015-01-23 21:10:30 -08:00
*/
2020-02-26 21:22:45 +01:00
public function login ( $redirectUrl = true , $loginAfterSuccess = true , $emailAfterSuccess = true )
2012-07-31 07:32:00 +00:00
{
2020-02-22 23:55:20 +01:00
if ( ! $this -> isSocialLoginEnabled ())
2012-07-31 07:32:00 +00:00
{
2020-02-26 21:22:45 +01:00
throw new Exception ( " Login failed! This feature is disabled. " , 100 ); // TODO lan
2012-07-31 07:32:00 +00:00
}
2020-02-17 10:36:03 +01:00
if ( ! $this -> getProvider ())
2012-07-31 07:32:00 +00:00
{
2020-02-26 21:22:45 +01:00
throw new Exception ( " Login failed! Wrong provider. " , 2 ); // TODO lan
2012-07-31 07:32:00 +00:00
}
2020-02-17 10:36:03 +01:00
if ( $redirectUrl )
2012-07-31 07:32:00 +00:00
{
2020-02-17 10:36:03 +01:00
if ( true === $redirectUrl )
2012-07-31 07:32:00 +00:00
{
$redirectUrl = SITEURL ;
}
2020-02-17 10:36:03 +01:00
elseif ( strpos ( $redirectUrl , 'http://' ) !== 0 && strpos ( $redirectUrl , 'https://' ) !== 0 )
2012-07-31 07:32:00 +00:00
{
$redirectUrl = e107 :: getUrl () -> create ( $redirectUrl );
}
}
2016-03-16 12:05:10 -07:00
2020-02-17 10:36:03 +01:00
if ( e107 :: getUser () -> isUser ())
2012-07-31 07:32:00 +00:00
{
2020-02-17 10:36:03 +01:00
if ( $redirectUrl )
2015-01-23 21:10:30 -08:00
{
2020-02-25 13:10:02 +01:00
$this -> redirectAndForwardMessages ( $redirectUrl );
2015-01-23 21:10:30 -08:00
}
2015-02-15 19:56:58 -08:00
return false ;
2020-02-17 10:36:03 +01:00
// throw new Exception( "Signup failed! User already signed in. ", 1); // TODO lan
2012-07-31 07:32:00 +00:00
}
2020-02-17 10:36:03 +01:00
2020-02-26 21:22:45 +01:00
$this -> setBackUrl ( $redirectUrl );
2020-02-19 21:20:48 +01:00
2012-07-31 07:32:00 +00:00
$this -> adapter = $this -> hybridauth -> authenticate ( $this -> getProvider ());
$profile = $this -> adapter -> getUserProfile ();
2016-03-16 12:05:10 -07:00
2012-07-31 07:32:00 +00:00
// returned back, if success...
2020-02-17 10:36:03 +01:00
if ( $profile -> identifier )
2012-07-31 07:32:00 +00:00
{
2016-03-16 12:05:10 -07:00
2012-07-31 07:32:00 +00:00
$sql = e107 :: getDb ();
$userMethods = e107 :: getUserSession ();
2020-02-17 10:36:03 +01:00
2012-07-31 07:32:00 +00:00
$plainPwd = $userMethods -> generateRandomString ( '************' ); // auto plain passwords
2016-03-16 12:05:10 -07:00
2020-02-17 10:36:03 +01:00
2012-07-31 07:32:00 +00:00
// TODO - auto login name, shouldn't be used if system set to user_email login...
2020-02-17 10:36:03 +01:00
$userdata [ 'user_loginname' ] = $this -> getProvider () . $userMethods -> generateUserLogin ( e107 :: getPref ( 'predefinedLoginName' , '_..#..#..#' ));
2020-02-23 21:57:04 +01:00
$userdata [ 'user_email' ] = $sql -> escape ( $profile -> emailVerified ? $profile -> emailVerified : $profile -> email ) ? : '' ;
2020-02-17 10:36:03 +01:00
$userdata [ 'user_name' ] = $sql -> escape ( $profile -> displayName );
$userdata [ 'user_login' ] = $userdata [ 'user_name' ];
$userdata [ 'user_customtitle' ] = '' ; // not used
$userdata [ 'user_password' ] = $userMethods -> HashPassword ( $plainPwd , $userdata [ 'user_loginname' ]); // pwd
$userdata [ 'user_sess' ] = '' ; //
$userdata [ 'user_image' ] = $profile -> photoURL ; // avatar
$userdata [ 'user_signature' ] = '' ; // not used
$userdata [ 'user_hideemail' ] = 1 ; // hide it by default
$userdata [ 'user_xup' ] = $sql -> escape ( $this -> userId ());
2015-02-15 19:56:58 -08:00
$pref = e107 :: pref ( 'core' );
2020-02-17 10:36:03 +01:00
if ( ! empty ( $pref [ 'initial_user_classes' ]))
2015-02-15 19:56:58 -08:00
{
$userdata [ 'user_class' ] = $pref [ 'initial_user_classes' ];
}
2020-02-17 10:36:03 +01:00
elseif ( ! empty ( $pref [ 'user_new_period' ]))
2015-02-15 19:56:58 -08:00
{
$userdata [ 'user_class' ] = e_UC_NEWUSER ;
}
else
{
$userdata [ 'user_class' ] = '' ;
}
2020-02-17 10:36:03 +01:00
// print_a($userdata);
2012-07-31 07:32:00 +00:00
// user_name, user_xup, user_email and user_loginname shouldn't match
2020-02-17 10:36:03 +01:00
$insert = ( ! empty ( $userdata [ 'user_email' ])) ? " OR user_email=' " . $userdata [ 'user_email' ] . " ' " : " " ;
2016-03-16 12:05:10 -07:00
2020-02-17 10:36:03 +01:00
if ( $uid = $sql -> retrieve ( " user " , " user_id " , " user_xup=' " . $sql -> escape ( $this -> userId ()) . " ' " . $insert . " OR user_loginname=' { $userdata [ 'user_loginname' ] } ' OR user_name=' { $userdata [ 'user_name' ] } ' " ))
2012-07-31 07:32:00 +00:00
{
2015-01-24 11:16:13 -08:00
// $this->login($redirectUrl); // auto-login
2020-02-25 13:10:02 +01:00
$result = e107 :: getUser () -> loginProvider ( $this -> userId ());
2020-05-22 17:13:38 -05:00
$this -> updateXupProfile ();
2016-03-16 12:05:10 -07:00
2020-05-22 17:13:38 -05:00
if ( ! $result )
2015-01-24 11:16:13 -08:00
{
2020-02-26 21:51:22 +01:00
e107 :: getMessage () -> addError ( " User already exists but is not connected through this social login provider " );
2015-01-24 11:16:13 -08:00
}
2016-03-16 12:05:10 -07:00
2020-02-17 10:36:03 +01:00
if ( $redirectUrl )
2015-01-24 11:16:13 -08:00
{
2020-02-25 13:10:02 +01:00
$this -> redirectAndForwardMessages ( $redirectUrl );
2015-01-24 11:16:13 -08:00
}
2020-02-17 10:36:03 +01:00
2015-02-15 19:56:58 -08:00
return false ;
// throw new Exception( "Signup failed! User already exists. Please use 'login' instead.", 3);
2012-07-31 07:32:00 +00:00
}
2020-02-17 10:36:03 +01:00
if ( empty ( $userdata [ 'user_email' ]) && e107 :: getPref ( 'disable_emailcheck' , 0 ) == 0 ) // Allow it if set-up that way.
2012-07-31 07:32:00 +00:00
{
2016-03-16 12:05:10 -07:00
// Twitter will not provide email addresses.
2020-02-17 10:36:03 +01:00
// throw new Exception( "Signup failed! Can't access user email - registration without an email is impossible.".print_a($userdata,true), 4); // TODO lan
2012-07-31 07:32:00 +00:00
}
2020-02-17 10:36:03 +01:00
2012-07-31 07:32:00 +00:00
// other fields
2020-02-17 10:36:03 +01:00
$now = time ();
2012-07-31 07:32:00 +00:00
$userdata [ 'user_id' ] = null ;
2020-02-17 10:36:03 +01:00
$userdata [ 'user_image' ] = '' ;
2012-07-31 07:32:00 +00:00
$userdata [ 'user_join' ] = $now ;
$userdata [ 'user_lastvisit' ] = 0 ;
$userdata [ 'user_currentvisit' ] = 0 ;
$userdata [ 'user_comments' ] = 0 ;
2016-06-06 19:54:48 -07:00
$userdata [ 'user_ip' ] = e107 :: getIPHandler () -> getIP ( false );
2012-07-31 07:32:00 +00:00
$userdata [ 'user_ban' ] = USER_VALIDATED ;
$userdata [ 'user_prefs' ] = '' ;
$userdata [ 'user_visits' ] = 0 ;
$userdata [ 'user_admin' ] = 0 ;
$userdata [ 'user_perms' ] = '' ;
$userdata [ 'user_realm' ] = '' ;
$userdata [ 'user_pwchange' ] = $now ;
2019-02-21 12:05:54 -08:00
/** @var e_system_user' $user */
2012-07-31 07:32:00 +00:00
$user = e107 :: getSystemUser ( 0 , false );
$user -> setData ( $userdata );
$user -> getExtendedModel (); // init
//$user->setEditor(e107::getSystemUser(1, false));
$user -> save ( true );
2020-02-17 10:36:03 +01:00
2012-07-31 07:32:00 +00:00
// user model error
2020-02-17 10:36:03 +01:00
if ( $user -> hasError ())
2012-07-31 07:32:00 +00:00
{
2016-03-16 12:05:10 -07:00
e107 :: getLog () -> add ( 'XUP Signup Failure' , $userdata , E_LOG_WARNING , " XUP_SIGNUP " );
2020-02-17 10:36:03 +01:00
throw new Exception ( $user -> renderMessages (), 5 );
2012-07-31 07:32:00 +00:00
}
2015-01-23 21:10:30 -08:00
2016-03-16 12:05:10 -07:00
2012-07-31 07:32:00 +00:00
### Successful signup!
//$user->set('provider', $this->getProvider());
$userdata = $user -> getData ();
$userdata [ 'provider' ] = $this -> getProvider ();
2019-07-03 13:05:49 +02:00
2020-02-17 10:36:03 +01:00
$userdata [ 'callback_data' ] = $profile ;
// e107::getEvent()->trigger('userveri', $userdata); // Trigger New verified user.
e107 :: getEvent () -> trigger ( 'user_xup_signup' , $userdata );
$ret = e107 :: getEvent () -> trigger ( 'usersupprov' , $userdata ); // XXX - it's time to pass objects instead of array?
if ( true === $ret ) return $this ;
2015-02-15 19:56:58 -08:00
2012-07-31 07:32:00 +00:00
// send email
2020-02-17 10:36:03 +01:00
if ( $emailAfterSuccess && ! empty ( $userdata [ 'user_email' ]))
2012-07-31 07:32:00 +00:00
{
2020-02-17 10:36:03 +01:00
$user -> set ( 'user_password' , $plainPwd ) -> email ( 'signup' );
2012-07-31 07:32:00 +00:00
}
2020-02-17 10:36:03 +01:00
2012-07-31 07:32:00 +00:00
e107 :: getUser () -> setProvider ( $this );
2020-02-17 10:36:03 +01:00
2012-07-31 07:32:00 +00:00
// auto login
2020-02-17 10:36:03 +01:00
if ( $loginAfterSuccess )
2012-07-31 07:32:00 +00:00
{
e107 :: getUser () -> loginProvider ( $this -> userId ()); // if not proper after-login, return true so user can see login screen
}
2020-02-17 10:36:03 +01:00
if ( $redirectUrl )
2012-07-31 07:32:00 +00:00
{
2020-02-19 21:20:48 +01:00
$this -> redirectAndForwardMessages ( $redirectUrl );
2012-07-31 07:32:00 +00:00
}
2020-02-17 10:36:03 +01:00
2012-07-31 07:32:00 +00:00
return true ;
}
return false ;
}
2015-02-15 19:56:58 -08:00
2022-04-04 10:54:24 -07:00
/**
* @ return bool | string
* @ throws \Hybridauth\Exception\InvalidArgumentException
* @ throws \Hybridauth\Exception\UnexpectedValueException
*/
2012-07-31 07:32:00 +00:00
public function logout ()
{
2020-02-14 12:25:15 +01:00
if (
! $this -> adapter ||
! $this -> hybridauth -> isConnectedWith ( $this -> getProvider ())
) return true ;
2012-07-31 07:32:00 +00:00
try
{
2020-02-17 10:36:03 +01:00
$this -> adapter -> disconnect ();
2012-07-31 07:32:00 +00:00
$this -> adapter = null ;
}
2020-02-17 10:36:03 +01:00
catch ( Exception $e )
2012-07-31 07:32:00 +00:00
{
return $e -> getMessage ();
}
return true ;
}
2015-02-15 19:56:58 -08:00
2020-02-19 21:20:48 +01:00
/**
* @ param string $backUrl
* @ return string
*/
2020-02-26 21:22:45 +01:00
public function generateCallbackUrl ( $backUrl = null )
2012-07-31 07:32:00 +00:00
{
2020-02-19 21:20:48 +01:00
return e107 :: getUrl () -> create (
2020-02-26 21:22:45 +01:00
" system/xup/login " ,
2020-02-19 21:20:48 +01:00
array (
2020-02-20 00:03:16 +01:00
'provider' => $this -> getProvider (),
2020-02-19 21:20:48 +01:00
'back' => $backUrl ,
),
array ( 'full' => true , 'encode' => false )
);
2012-07-31 07:32:00 +00:00
}
2020-02-19 21:20:48 +01:00
/**
* @ param $redirectUrl
*/
private function redirectAndForwardMessages ( $redirectUrl )
2012-07-31 07:32:00 +00:00
{
2020-02-19 21:20:48 +01:00
$messages = e107 :: getMessage () -> getAll ( 'default' , true , false );
foreach ( $messages as $type => $message_stack )
2012-07-31 07:32:00 +00:00
{
2020-02-19 21:20:48 +01:00
e107 :: getMessage () -> addSessionStack ( $message_stack , 'default' , $type );
2012-07-31 07:32:00 +00:00
}
2020-02-19 21:20:48 +01:00
e107 :: getRedirect () -> redirect ( $redirectUrl );
2012-07-31 07:32:00 +00:00
}
2020-05-22 17:13:38 -05:00
/**
* Synchronize user profile fields from social login provider
*/
private function updateXupProfile ()
{
try
{
// detect all currently connected providers
$connected = $this -> hybridauth -> getConnectedProviders ();
}
catch ( Exception $e )
{
e107 :: getMessage () -> addError ( '[' . $e -> getCode () . ']' . $e -> getMessage (), 'default' , true );
$session = e107 :: getSession ();
$session -> set ( 'HAuthError' , true );
$connected = false ;
}
// no active session found
if ( ! $connected ) return ;
// query DB
$sql = e107 :: getDb ();
$where = array ();
$userdata = array ();
foreach ( $connected as $providerId )
{
try
{
$adapter = $this -> hybridauth -> getAdapter ( $providerId );
$profile = $adapter -> getUserProfile ();
}
catch ( \Hybridauth\Exception\Exception $e )
{
continue ;
}
if ( ! $profile -> identifier ) continue ;
$userdata [ 'user_name' ] = $sql -> escape ( $profile -> displayName );
$userdata [ 'user_image' ] = $profile -> photoURL ; // avatar
$userdata [ 'user_email' ] = $profile -> email ;
$id = $providerId . '_' . $profile -> identifier ;
$where [] = " user_xup=' " . $sql -> escape ( $id ) . " ' " ;
}
// no active session found
if ( empty ( $where )) return ;
$where = implode ( ' OR ' , $where );
if ( $sql -> select ( 'user' , 'user_id, user_name, user_email, user_image, user_password, user_xup' , $where ))
{
$user = $sql -> fetch ();
e107 :: getUserSession () -> makeUserCookie ( $user );
$spref = e107 :: pref ( 'social' );
// Update display name or avatar image if they have changed.
if (
( empty ( $user [ 'user_email' ]) && ! empty ( $userdata [ 'user_email' ])) ||
( $userdata [ 'user_name' ] != $user [ 'user_name' ]) ||
( $userdata [ 'user_image' ] != $user [ 'user_image' ])
)
{
$updateQry = array ();
if ( ! empty ( $spref [ 'xup_login_update_username' ]))
{
$updateQry [ 'user_name' ] = $userdata [ 'user_name' ];
}
if ( ! empty ( $spref [ 'xup_login_update_avatar' ]))
{
$updateQry [ 'user_image' ] = $userdata [ 'user_image' ];
}
if ( empty ( $user [ 'user_email' ]))
{
$updateQry [ 'user_email' ] = $userdata [ 'user_email' ];
}
$updateQry [ 'WHERE' ] = " user_id= " . $user [ 'user_id' ] . " LIMIT 1 " ;
if ( $sql -> update ( 'user' , $updateQry ) !== false )
{
$updatedProfile = array_replace ( $user , $userdata );
e107 :: getEvent () -> trigger ( 'user_xup_updated' , $updatedProfile );
e107 :: getLog () -> add ( 'User Profile Updated' , $userdata , E_LOG_INFORMATIVE , " XUP_LOGIN " , LOG_TO_ADMIN , array ( 'user_id' => $user [ 'user_id' ], 'user_name' => $user [ 'user_name' ], 'user_email' => $userdata [ 'user_email' ]));
}
else
{
e107 :: getLog () -> add ( 'User Profile Update Failed' , $userdata , E_LOG_WARNING , " XUP_LOGIN " , LOG_TO_ADMIN , $updateQry );
}
}
unset ( $user [ 'user_password' ]);
2020-12-18 19:55:12 -08:00
e107 :: getLog () -> user_audit ( USER_AUDIT_LOGIN , null , $user [ 'user_id' ], $user [ 'user_name' ]);
2020-05-22 17:13:38 -05:00
}
}
2012-07-31 07:32:00 +00:00
}
2009-11-30 20:40:03 +00:00
2012-07-31 07:32:00 +00:00
e107 :: coreLan ( 'administrator' , true );
2008-12-21 11:07:58 +00:00
2022-04-04 10:54:24 -07:00
/**
*
*/
2009-11-12 01:53:16 +00:00
class e_userperms
{
2011-05-11 11:56:42 +00:00
2012-06-04 09:08:54 +00:00
protected $core_perms = array ();
protected $plugin_perms = array ();
protected $language_perms = array ();
protected $main_perms = array ();
2020-02-19 21:20:48 +01:00
2012-06-04 09:08:54 +00:00
protected $full_perms = array ();
protected $permSectionDiz = array (
2015-11-22 10:00:46 -08:00
'core' => LAN_GENERAL ,
2012-06-04 09:08:54 +00:00
'plugin' => ADLAN_CL_7 ,
'language' => ADLAN_132 ,
'main' => ADMSLAN_58
);
2020-02-19 21:20:48 +01:00
2012-06-04 09:08:54 +00:00
function __construct ()
{
2014-01-19 03:55:07 -08:00
2012-06-04 09:08:54 +00:00
$this -> core_perms = array (
2010-05-13 15:47:31 +00:00
2015-07-02 03:54:52 +01:00
// In the same order as admin navigation! Plus same labels.
2020-02-19 21:20:48 +01:00
2011-05-11 11:56:42 +00:00
// Settings
2015-07-02 03:54:52 +01:00
" C " => array ( ADLAN_74 , E_16_CACHE , E_32_CACHE ), // Clear the system cache
" F " => array ( ADLAN_58 , E_16_EMOTE , E_32_EMOTE ), // Emoticons
" G " => array ( ADLAN_60 , E_16_FRONT , E_32_FRONT ), // Front-Page Configuration
" L " => array ( ADLAN_132 , E_16_LANGUAGE , E_32_LANGUAGE ), // Language Packs
" T " => array ( ADLAN_66 , E_16_META , E_32_META ), // Meta tags
2020-02-19 21:20:48 +01:00
2015-07-02 03:54:52 +01:00
" 1 " => array ( LAN_PREFS , E_16_PREFS , E_32_PREFS ), // Alter Site Preferences
" X " => array ( LAN_SEARCH , E_16_SEARCH , E_32_SEARCH ), // Search
2020-12-27 14:28:19 -08:00
" I " => array ( LAN_NAVIGATION , E_16_LINKS , E_32_LINKS ), // Post SiteLinks
2011-05-11 11:56:42 +00:00
" 8 " => array ( ADMSLAN_27 , E_16_LINKS , E_32_LINKS ), // Oversee SiteLink Categories
2015-07-02 03:54:52 +01:00
" K " => array ( ADLAN_159 , E_16_EURL , E_32_EURL ), // Configure URLs
2020-02-19 21:20:48 +01:00
// Users
2015-07-02 03:54:52 +01:00
" 3 " => array ( ADLAN_8 , E_16_ADMIN , E_32_ADMIN ), // Modify Admin perms
2011-05-11 22:25:02 +00:00
" 4 " => array ( LAN_USER_MANAGEALL , E_16_USER , E_32_USER ), // Manage all user access and settings etc
2015-07-02 03:54:52 +01:00
" U0 " => array ( ADLAN_34 , E_16_USER , E_32_USER ), // moderate users/bans but not userclasses or extended fields,
2011-05-11 22:25:02 +00:00
" U1 " => array ( LAN_USER_QUICKADD , E_16_USER , E_32_USER ), // "User: Quick Add User",
" U2 " => array ( LAN_USER_OPTIONS , E_16_USER , E_32_USER ), // Manage only user-options
" U3 " => array ( LAN_USER_RANKS , E_16_USER , E_32_USER ), // Manage only user-ranks
2020-02-19 21:20:48 +01:00
" W " => array ( ADLAN_136 , E_16_MAIL , E_32_MAIL ), // Configure mail settings and mailout
// Content
" 5 " => array ( ADLAN_42 , E_16_CUST , E_32_CUST ), // create/edit custom PAGES
2015-07-02 03:54:52 +01:00
" J " => array ( ADLAN_42 , E_16_CUST , E_32_CUST ), // create/edit custom MENUS
2022-07-21 13:43:29 -07:00
" J1 " => array ( ADLAN_42 . " ( " . LAN_DELETE . " ) " , E_16_CUST , E_32_CUST ), // Delete Pages/Menus.
2015-07-02 03:54:52 +01:00
" H " => array ( ADLAN_0 , E_16_NEWS , E_32_NEWS ), // Post News - All Areas except settings.
" H0 " => array ( ADLAN_0 . " ( " . LAN_CREATE . " ) " , E_16_NEWS , E_32_NEWS ), // Create News Items
" H1 " => array ( ADLAN_0 . " ( " . LAN_EDIT . " ) " , E_16_NEWS , E_32_NEWS ), // Edit News Items
" H2 " => array ( ADLAN_0 . " ( " . LAN_DELETE . " ) " , E_16_NEWS , E_32_NEWS ), // Delete News Items
" H3 " => array ( ADLAN_0 . " ( " . LAN_CATEGORY . " - " . LAN_CREATE . " ) " , E_16_NEWS , E_32_NEWS ), // Create News Category
" H4 " => array ( ADLAN_0 . " ( " . LAN_CATEGORY . " - " . LAN_EDIT . " ) " , E_16_NEWS , E_32_NEWS ), // Edit News Category
" H5 " => array ( ADLAN_0 . " ( " . LAN_CATEGORY . " - " . LAN_DELETE . " ) " , E_16_NEWS , E_32_NEWS ), // Delete News Category
" N " => array ( ADLAN_0 . " ( " . LAN_SUBMITTED . " ) " , E_16_NEWS , E_32_NEWS ), // Moderate submitted news
" V " => array ( ADLAN_31 , E_16_UPLOADS , E_32_UPLOADS ), // Configure public file uploads
" M " => array ( ADLAN_28 , E_16_WELCOME , E_32_WELCOME ), // Welcome Messages
2020-02-19 21:20:48 +01:00
// Tools
2015-07-02 03:54:52 +01:00
" Y " => array ( ADLAN_147 , E_16_INSPECT , E_32_INSPECT ), // File inspector
" 9 " => array ( ADLAN_40 , E_16_MAINTAIN , E_32_MAINTAIN ), // Take Down site for Maintenance
" O " => array ( ADLAN_149 , E_16_NOTIFY , E_32_NOTIFY ), // Notify
" U " => array ( ADLAN_157 , E_16_CRON , E_32_CRON ), // Schedule Tasks
" S " => array ( ADLAN_155 , E_16_ADMINLOG , E_32_ADMINLOG ), // System Logging
2020-02-19 21:20:48 +01:00
2011-05-11 11:56:42 +00:00
// Manage
2015-07-02 03:54:52 +01:00
" B " => array ( LAN_COMMENTMAN , E_16_COMMENT , E_32_COMMENT ), // Moderate Comments
2020-02-19 21:20:48 +01:00
" 6 " => array ( LAN_MEDIAMANAGER , E_16_FILE , E_32_FILE ), // File-Manager - Upload /manage files -
" A " => array ( LAN_MEDIAMANAGER . " ( " . LAN_ALL . " ) " , E_16_IMAGES , E_32_IMAGES ), // Media-Manager All Areas.
2015-11-04 19:35:00 -08:00
" A1 " => array ( LAN_MEDIAMANAGER . " ( " . LAN_UPLOAD . " / " . LAN_IMPORT . " ) " , E_16_IMAGES , E_32_IMAGES ), // Media-Manager (Media Upload/Add/Import)
2015-07-02 03:54:52 +01:00
" A2 " => array ( LAN_MEDIAMANAGER . " ( " . LAN_CATEGORIES . " ) " , E_16_IMAGES , E_32_IMAGES ), // Media-Manager (Media-Categories)
2019-07-29 12:37:08 -07:00
" TMP " => array ( ADLAN_140 . " ( " . LAN_PREFS . " ) " , E_16_THEMEMANAGER , E_32_THEMEMANAGER ),
2020-02-19 21:20:48 +01:00
2015-07-02 03:54:52 +01:00
" 2 " => array ( ADLAN_6 , E_16_MENUS , E_32_MENUS ), // Alter Menus
2020-02-19 21:20:48 +01:00
2012-06-04 09:08:54 +00:00
// "D"=> ADMSLAN_29, // Manage Banners (deprecated - now a plugin)
2020-02-19 21:20:48 +01:00
// "E"=> ADMSLAN_30, // News feed headlines (deprecated - now a plugin)
2012-06-04 09:08:54 +00:00
// "K"=>
2020-02-19 21:20:48 +01:00
2012-06-04 09:08:54 +00:00
// "P" // Reserved for Plugins
2020-02-19 21:20:48 +01:00
2012-06-04 09:08:54 +00:00
// "Q"=> array(ADMSLAN_24), // Manage download categories (deprecated - now a plugin)
2020-02-19 21:20:48 +01:00
// "R"=> ADMSLAN_44, // Post Downloads (deprecated)
// "Z"=> ADMSLAN_62, // Plugin Manager.. included under Plugins category.
2012-06-04 09:08:54 +00:00
);
2020-02-19 21:20:48 +01:00
2010-05-13 15:47:31 +00:00
2017-12-02 11:57:27 -08:00
// $sql = e107::getDb('sql2');
// $tp = e107::getParser();
$pg = e107 :: getPlug ();
$installed = $pg -> getInstalled ();
foreach ( $installed as $plug => $version )
{
$pg -> load ( $plug );
$arr = array (
0 => $pg -> getName (),
1 => $pg -> getIcon ( 16 ),
2 => $pg -> getIcon ( 32 )
);
$key = " P " . $pg -> getId ();
$this -> plugin_perms [ $key ] = $arr ;
}
2010-05-13 15:47:31 +00:00
2017-12-02 11:57:27 -08:00
/*
2011-05-18 08:58:35 +00:00
$plg = e107 :: getPlugin ();
2017-12-02 11:57:27 -08:00
$allPlugins = $plg -> getall ( 1 ); // Needs all for 'reading' and 'installed' for writing.
2013-02-22 15:45:31 -08:00
foreach ( $allPlugins as $k => $row2 )
2011-05-18 08:58:35 +00:00
{
if ( $plg -> parse_plugin ( $row2 [ 'plugin_path' ]))
{
$plug_vars = $plg -> plug_vars ;
2016-06-06 19:54:48 -07:00
$this -> plugin_perms [( " P " . $row2 [ 'plugin_id' ])] = array ( $tp -> toHTML ( $row2 [ 'plugin_name' ], false , 'RAWTEXT,defs' ));
2011-05-18 08:58:35 +00:00
$this -> plugin_perms [( " P " . $row2 [ 'plugin_id' ])][ 1 ] = $plg -> getIcon ( $row2 [ 'plugin_path' ], 16 );
$this -> plugin_perms [( " P " . $row2 [ 'plugin_id' ])][ 2 ] = $plg -> getIcon ( $row2 [ 'plugin_path' ], 32 );
}
}
2017-12-02 11:57:27 -08:00
*/
2010-05-13 15:47:31 +00:00
2009-11-12 01:53:16 +00:00
asort ( $this -> plugin_perms );
2010-05-13 15:47:31 +00:00
2015-07-02 03:54:52 +01:00
$this -> plugin_perms = array ( " Z " => array ( '0' => ADLAN_98 )) + $this -> plugin_perms ;
2010-05-13 15:47:31 +00:00
2009-11-12 01:53:16 +00:00
if ( e107 :: getConfig () -> getPref ( 'multilanguage' ))
{
$lanlist = explode ( " , " , e_LANLIST );
sort ( $lanlist );
foreach ( $lanlist as $langs )
{
2011-07-06 03:17:00 +00:00
$this -> language_perms [ $langs ] = array ( " 0 " => $langs );
2009-11-12 01:53:16 +00:00
}
}
2010-05-13 15:47:31 +00:00
2009-11-12 01:53:16 +00:00
if ( getperms ( '0' ))
{
2011-07-06 03:17:00 +00:00
$this -> main_perms = array ( '0' => array ( '0' => ADMSLAN_58 ));
2009-11-12 01:53:16 +00:00
}
2010-05-13 15:47:31 +00:00
2011-07-06 03:17:00 +00:00
// Note: Using array_merge or array_merge_recursive will corrupt the array.
$this -> full_perms = $this -> core_perms + $this -> plugin_perms + $this -> language_perms + $this -> main_perms ;
2009-11-12 01:53:16 +00:00
}
2010-05-13 15:47:31 +00:00
2022-04-04 10:54:24 -07:00
/**
* @ param $key
* @ return mixed
*/
2009-11-12 01:53:16 +00:00
function renderSectionDiz ( $key )
{
2010-05-13 15:47:31 +00:00
return $this -> permSectionDiz [ $key ];
2009-11-12 01:53:16 +00:00
}
2010-05-13 15:47:31 +00:00
2022-04-04 10:54:24 -07:00
/**
* @ param $type
* @ return array | array []
*/
2009-11-12 01:53:16 +00:00
function getPermList ( $type = 'all' )
{
if ( $type == 'core' )
{
return $this -> core_perms ;
}
if ( $type == 'plugin' )
{
return $this -> plugin_perms ;
}
if ( $type == 'language' )
{
return $this -> language_perms ;
}
if ( $type == 'main' )
{
return $this -> main_perms ;
}
2010-05-13 15:47:31 +00:00
2009-11-12 01:53:16 +00:00
if ( $type == 'grouped' )
{
$ret = array ();
$ret [ 'core' ] = $this -> core_perms ;
$ret [ 'plugin' ] = $this -> plugin_perms ;
2010-05-13 15:47:31 +00:00
2020-12-20 11:50:10 -08:00
if ( ! empty ( $this -> language_perms ))
2009-11-12 01:53:16 +00:00
{
$ret [ 'language' ] = $this -> language_perms ;
}
2010-05-13 15:47:31 +00:00
2020-12-20 11:50:10 -08:00
if ( ! empty ( $this -> main_perms ))
2009-11-12 01:53:16 +00:00
{
$ret [ 'main' ] = $this -> main_perms ;
}
2010-05-13 15:47:31 +00:00
2009-11-12 01:53:16 +00:00
return $ret ;
2010-05-13 15:47:31 +00:00
2009-11-12 01:53:16 +00:00
}
2010-05-13 15:47:31 +00:00
2011-07-06 03:17:00 +00:00
return $this -> full_perms ;
2009-11-12 01:53:16 +00:00
}
2010-05-13 15:47:31 +00:00
2022-04-04 10:54:24 -07:00
/**
* @ param $arg
* @ param $perms
* @ param $info
* @ return string
*/
2011-05-11 11:56:42 +00:00
function checkb ( $arg , $perms , $info = '' )
2009-11-12 01:53:16 +00:00
{
$frm = e107 :: getForm ();
2020-02-19 21:20:48 +01:00
2011-05-11 11:56:42 +00:00
if ( is_array ( $info ))
2009-11-12 01:53:16 +00:00
{
2011-05-11 11:56:42 +00:00
$label = $info [ 0 ];
2020-12-29 09:48:36 -08:00
$icon_16 = varset ( $info [ 1 ]);
$icon_32 = varset ( $info [ 2 ]);
2009-11-12 01:53:16 +00:00
}
2011-05-11 11:56:42 +00:00
elseif ( $info )
{
$label = $info ;
$icon_16 = " " ;
$icon_32 = " " ;
}
2015-11-22 10:00:46 -08:00
$class = getperms ( $arg , $perms ) ? 'active' : '' ;
$par = " <tr class=' { $class } '>
2011-05-11 11:56:42 +00:00
< td style = 'text-align:center' > " . $icon_16 . " </ td >
< td style = 'text-align:center' > " . $frm->checkbox ('perms[]', $arg , getperms( $arg , $perms )). " </ td >
< td > " . $frm->label ( $label ,'perms[]', $arg ). " </ td >
</ tr > " ;
2010-05-13 15:47:31 +00:00
2009-11-12 01:53:16 +00:00
return $par ;
}
2010-05-13 15:47:31 +00:00
2022-04-04 10:54:24 -07:00
/**
* @ param $perms
* @ param $uniqueID
* @ return string
*/
function renderPerms ( $perms , $uniqueID = '' )
2009-11-12 01:53:16 +00:00
{
$tmp = explode ( " . " , $perms );
2013-02-22 15:45:31 -08:00
$tmp = array_filter ( $tmp );
2020-02-19 21:20:48 +01:00
2009-11-12 01:53:16 +00:00
$permdiz = $this -> getPermList ();
2013-02-22 15:45:31 -08:00
2009-11-12 01:53:16 +00:00
$ptext = array ();
2020-02-19 21:20:48 +01:00
2009-11-12 01:53:16 +00:00
foreach ( $tmp as $p )
{
2013-02-22 15:45:31 -08:00
// if(trim($p) == ""){ continue; }
$val = vartrue ( $permdiz [ $p ], 'missing ' . $p );
$ptext [] = is_array ( $permdiz [ $p ]) ? $permdiz [ $p ][ 0 ] : $val ;
2010-05-13 15:47:31 +00:00
}
2009-11-12 01:53:16 +00:00
$id = " id_ " . $uniqueID ;
2010-05-13 15:47:31 +00:00
2012-05-24 07:24:49 +00:00
$text = " <div href='#id_ { $id } ' class='e-pointer e-expandit' title=' " . ADMSLAN_71 . " '> { $perms } </div> \n " ;
2010-05-13 15:47:31 +00:00
2009-11-12 01:53:16 +00:00
if ( varset ( $ptext ))
{
2011-07-06 03:17:00 +00:00
$text .= " <div id='id_ { $id } ' class='e-hideme'><ul><li> " . implode ( " </li> \n <li> " , $ptext ) . " </li></ul></div> \n " ;
2009-11-12 01:53:16 +00:00
}
2010-05-13 15:47:31 +00:00
2009-11-12 01:53:16 +00:00
/*
$text = " <a href='# " . $id . " ' class='e-expandit' title=' " . ADMSLAN_71 . " '> { $perms } </a> " ;
2010-05-13 15:47:31 +00:00
2009-11-12 01:53:16 +00:00
if ( varset ( $ptext ))
{
$text .= " <div class='e-hideme' id=' " . $id . " ' ><ul><li> " . implode ( " </li><li> " , $ptext ) . " </li></ul></div> " ;
}
2010-05-13 15:47:31 +00:00
*/
2009-11-12 01:53:16 +00:00
return $text ;
}
2010-05-13 15:47:31 +00:00
2009-11-12 05:11:47 +00:00
/**
2010-05-13 15:47:31 +00:00
* Render edit admin perms form .
2009-11-17 14:50:37 +00:00
*
2009-11-12 05:11:47 +00:00
* @ param array $row [ optional ] containing $row [ 'user_id' ], $row [ 'user_name' ], $row [ 'user_perms' ];
2009-11-17 14:50:37 +00:00
* @ return void
2009-11-12 05:11:47 +00:00
*/
2009-11-17 14:50:37 +00:00
function edit_administrator ( $row = '' )
2009-11-12 05:11:47 +00:00
{
2009-11-17 14:50:37 +00:00
$pref = e107 :: getPref ();
$lanlist = explode ( " , " , e_LANLIST );
2009-11-12 05:11:47 +00:00
require_once ( e_HANDLER . " user_handler.php " );
$prm = $this ;
$ns = e107 :: getRender ();
$sql = e107 :: getDb ();
$frm = e107 :: getForm ();
2010-05-13 15:47:31 +00:00
2009-11-12 05:11:47 +00:00
$a_id = $row [ 'user_id' ];
$ad_name = $row [ 'user_name' ];
$a_perms = $row [ 'user_perms' ];
2013-02-24 15:46:07 -08:00
/*
2009-11-12 05:11:47 +00:00
$text = "
< form method = 'post' action = '".e_SELF."' id = 'myform' >
< fieldset id = 'core-administrator-edit' >
< legend class = 'e-hideme' > " .ADMSLAN_52. " </ legend >
2012-05-16 06:05:39 +00:00
< table class = 'adminform' >
< colgroup >
2009-11-12 05:11:47 +00:00
< col class = 'col-label' />
< col class = 'col-control' />
</ colgroup >
< tbody >
< tr >
< td class = 'control' >
2020-02-19 21:20:48 +01:00
2010-05-13 15:47:31 +00:00
2009-11-12 05:11:47 +00:00
" ;
2013-02-24 15:46:07 -08:00
*/
2020-02-19 21:20:48 +01:00
2013-02-24 15:46:07 -08:00
$text = " <form method='post' action=' " . e_SELF . " ' id='myform'>
< fieldset id = 'core-administrator-edit' >
< legend class = 'e-hideme' > " .ADMSLAN_52. " </ legend > " ;
2020-02-19 21:20:48 +01:00
//XXX Bootstrap Tabs (as used below) should eventually be the default for all of the admin area.
2013-02-24 15:46:07 -08:00
$text .= '
< ul class = " nav nav-tabs " >
2021-01-26 15:08:58 -08:00
< li class = " active " >< a href = " #tab1 " data - toggle = " tab " data - bs - toggle = " tab " > '.$this->renderSectionDiz(' core ').' </ a ></ li >
< li >< a href = " #tab2 " data - toggle = " tab " data - bs - toggle = " tab " > '.$this->renderSectionDiz(' plugin ').' </ a ></ li >
< li >< a href = " #tab3 " data - toggle = " tab " data - bs - toggle = " tab " > '.$this->renderSectionDiz(' language ').' </ a ></ li >
< li >< a href = " #tab4 " data - toggle = " tab " data - bs - toggle = " tab " > '.$this->renderSectionDiz(' main ').' </ a ></ li >
2013-02-24 15:46:07 -08:00
</ ul >
< div class = " tab-content " >
< div class = " tab-pane active " id = " tab1 " >
< div class = " separator " >
'.$this->renderPermTable(' core ',$a_perms).'
</ div >
</ div >
< div class = " tab-pane " id = " tab2 " >
< div class = " separator " >
'.$this->renderPermTable(' plugin ',$a_perms).'
</ div >
</ div >
< div class = " tab-pane " id = " tab3 " >
< div class = " separator " >
'.$this->renderPermTable(' language ',$a_perms).'
</ div >
</ div >
< div class = " tab-pane " id = " tab4 " >
< div class = " separator " >
'.$this->renderPermTable(' main ',$a_perms).'
</ div >
</ div >
2020-02-19 21:20:48 +01:00
</ div > ' ;
2013-02-24 15:46:07 -08:00
2010-05-13 15:47:31 +00:00
2013-02-24 15:46:07 -08:00
// $text .= $this->renderPermTable('grouped',$a_perms);
2010-05-13 15:47:31 +00:00
2020-02-19 21:20:48 +01:00
$text .= $this -> renderCheckAllButtons ();
2013-02-24 15:46:07 -08:00
// $text .= "</td></tr></tbody></table>";
2020-02-19 21:20:48 +01:00
2013-02-24 15:46:07 -08:00
$text .= "
2012-12-08 21:09:58 +02:00
" . $this->renderSubmitButtons (). "
2013-02-24 15:46:07 -08:00
< input type = 'hidden' name = 'ad_name' value = '{$ad_name}' />
< input type = 'hidden' name = 'a_id' value = '{$a_id}' />
2009-11-12 05:11:47 +00:00
</ fieldset >
</ form >
" ;
2010-05-13 15:47:31 +00:00
2013-02-24 15:46:07 -08:00
// $text .= $this->renderPermTable('core',$a_perms);
$ns -> tablerender ( ADMSLAN_52 . SEP . $ad_name , $text );
2009-11-12 05:11:47 +00:00
}
2010-05-13 15:47:31 +00:00
2022-04-04 10:54:24 -07:00
/**
* @ return string
*/
2012-12-08 21:09:58 +02:00
function renderCheckAllButtons ()
{
$frm = e107 :: getForm ();
return "
< div class = 'field-section' >
" . $frm->admin_button ('check_all', 'jstarget:perms', 'action', LAN_CHECKALL). "
" . $frm->admin_button ('uncheck_all', 'jstarget:perms', 'action', LAN_UNCHECKALL). "
</ div >
" ;
}
2020-02-19 21:20:48 +01:00
2022-04-04 10:54:24 -07:00
/**
* @ return string
*/
2012-12-08 21:09:58 +02:00
function renderSubmitButtons ()
{
$frm = e107 :: getForm ();
return "
< div class = 'buttons-bar center' >
2013-03-21 00:50:16 +01:00
" . $frm->admin_button ('update_admin', LAN_UPDATE, 'update'). "
2013-02-06 12:21:26 -08:00
" . $frm->admin_button ('go_back', LAN_BACK, 'cancel'). "
2012-12-08 21:09:58 +02:00
</ div >
" ;
}
2020-02-19 21:20:48 +01:00
2022-04-04 10:54:24 -07:00
/**
* @ param $type
* @ param $a_perms
* @ return string
*/
function renderPermTable ( $type , $a_perms = '' )
2011-05-11 11:56:42 +00:00
{
2015-11-22 10:00:46 -08:00
if ( $type == 'tabs' )
{
$groupedList = $this -> getPermList ( 'grouped' );
$tab = array ();
foreach ( $groupedList as $section => $list )
{
$text = '' ;
// $text .= "\t\t<div class='field-section'><h4>".$prm->renderSectionDiz($section)."</h4>"; //XXX Lan - General
$text .= " \t \t <table class='table adminlist'>
< colgroup >
< col class = 'center' style = 'width:50px' />
< col style = 'width:50px' />
< col />
</ colgroup >
< tbody > " ;
foreach ( $list as $key => $diz )
{
$text .= $this -> checkb ( $key , $a_perms , $diz );
}
$text .= " </tbody></table> " ;
$tab [] = array ( 'caption' => $this -> renderSectionDiz ( $section ), 'text' => $text );
}
// return print_a($groupedList);
return e107 :: getForm () -> tabs ( $tab );
}
2011-05-11 11:56:42 +00:00
$groupedList = $this -> getPermList ( $type );
2020-02-19 21:20:48 +01:00
2013-02-24 15:46:07 -08:00
if ( $type != 'grouped' )
{
$text = " \t \t <table class='table adminform'>
< colgroup >
< col class = 'center' style = 'width:50px' />
< col style = 'width:50px' />
< col />
</ colgroup >
< tbody > " ;
// $text .= "<tr><td class='field-section' colspan='3'><h4>".$this->renderSectionDiz($type)."</h4></td></tr>"; //XXX Lan - General
// $text .= "\t\t<div class='field-section'><h4>".$prm->renderSectionDiz($section)."</h4>"; //XXX Lan - General
foreach ( $groupedList as $key => $diz )
{
$text .= $this -> checkb ( $key , $a_perms , $diz );
}
$text .= " </tbody>
2020-02-19 21:20:48 +01:00
</ table > " ;
2013-02-24 15:46:07 -08:00
return $text ;
}
2020-02-19 21:20:48 +01:00
2013-02-24 15:46:07 -08:00
$text = " " ;
2011-05-11 11:56:42 +00:00
foreach ( $groupedList as $section => $list )
{
2012-11-26 14:41:32 -08:00
$text .= " \t \t <table class='table adminlist'>
2012-05-16 06:05:39 +00:00
< colgroup >
< col class = 'center' style = 'width:50px' />
< col style = 'width:50px' />
< col />
2011-05-11 11:56:42 +00:00
</ colgroup >
< tbody >< tr >< td class = 'field-section' colspan = '3' >< h4 > " . $this->renderSectionDiz ( $section ). " </ h4 ></ td ></ tr > " ; //XXX Lan - General
// $text .= "\t\t<div class='field-section'><h4>".$prm->renderSectionDiz($section)."</h4>"; //XXX Lan - General
foreach ( $list as $key => $diz )
{
$text .= $this -> checkb ( $key , $a_perms , $diz );
}
$text .= " </tbody>
</ table > " ;
}
2020-02-19 21:20:48 +01:00
return $text ;
2011-05-11 11:56:42 +00:00
}
2020-02-19 21:20:48 +01:00
2009-11-12 05:11:47 +00:00
/**
2009-11-17 14:50:37 +00:00
* Update user ( admin ) permissions .
* NOTE : exit if $uid is not an integer or is 0.
*
* @ param integer $uid
* @ param array $permArray eg . array ( 'A' , 'K' , '1' );
2010-05-13 15:47:31 +00:00
* @ return void
2009-11-12 05:11:47 +00:00
*/
2009-11-17 14:50:37 +00:00
function updatePerms ( $uid , $permArray )
2009-11-12 05:11:47 +00:00
{
global $admin_log ;
2010-05-13 15:47:31 +00:00
2009-11-12 05:11:47 +00:00
$sql = e107 :: getDb ();
$tp = e107 :: getParser ();
2010-05-13 15:47:31 +00:00
2009-11-12 05:11:47 +00:00
$modID = intval ( $uid );
2013-02-06 12:14:40 -08:00
$mes = e107 :: getMessage ();
2009-11-12 05:11:47 +00:00
if ( $modID == 0 )
{
2013-02-06 12:14:40 -08:00
$mes -> addError ( " Malfunction at line " . __LINE__ . " of user_handler.php " );
return ;
2009-11-12 05:11:47 +00:00
}
2010-05-13 15:47:31 +00:00
2012-12-08 21:09:58 +02:00
$sysuser = e107 :: getSystemUser ( $modID , false );
$row = $sysuser -> getData ();
2009-11-12 05:11:47 +00:00
$a_name = $row [ 'user_name' ];
2010-05-13 15:47:31 +00:00
2009-11-12 05:11:47 +00:00
$perm = " " ;
2010-05-13 15:47:31 +00:00
2009-11-12 05:11:47 +00:00
foreach ( $permArray as $value )
{
$value = $tp -> toDB ( $value );
if ( $value == " 0 " )
{
if ( ! getperms ( '0' )) { $value = " " ; break ; }
$perm = " 0 " ; break ;
}
2010-05-13 15:47:31 +00:00
2009-11-12 05:11:47 +00:00
if ( $value )
{
$perm .= $value . " . " ;
}
2012-12-08 21:09:58 +02:00
}
2020-02-19 21:20:48 +01:00
2013-03-21 00:50:16 +01:00
//$sql->db_Update("user", "user_perms='{$perm}' WHERE user_id='{$modID}' ")
2014-12-27 12:02:12 -08:00
if ( ! $sysuser -> isAdmin ())
{
$sysuser -> set ( 'user_admin' , 1 ) -> save ();
2017-11-06 13:24:05 -08:00
$vars = array ( 'x' => $sysuser -> getId (), 'y' => $sysuser -> getName (), 'z' => $sysuser -> getValue ( 'email' ));
$lan = e107 :: getParser () -> lanVars ( USRLAN_164 , $vars );
2014-12-27 12:02:12 -08:00
e107 :: getLog () -> add ( 'USET_08' , $lan , E_LOG_INFORMATIVE );
}
2020-02-19 21:20:48 +01:00
2013-03-21 00:50:16 +01:00
e107 :: getMessage () -> addAuto ( $sysuser -> set ( 'user_perms' , $perm ) -> save (), 'update' , sprintf ( LAN_UPDATED , $tp -> toDB ( $_POST [ 'ad_name' ])), false , false );
2017-11-06 13:48:08 -08:00
$logMsg = str_replace ( array ( '[x]' , '[y]' ), array ( $modID , $a_name ), ADMSLAN_72 ) . $perm ;
2014-10-23 11:12:13 -07:00
e107 :: getLog () -> add ( 'ADMIN_01' , $logMsg , E_LOG_INFORMATIVE , '' );
2009-11-12 05:11:47 +00:00
}
2009-06-12 20:41:35 +00:00
2009-11-17 14:50:37 +00:00
}