summaryrefslogtreecommitdiff
path: root/includes
diff options
context:
space:
mode:
authorLester Caine <lester@lsces.co.uk>2026-05-15 15:42:51 +0100
committerLester Caine <lester@lsces.co.uk>2026-05-15 15:42:51 +0100
commit02a3c1e025dfcac83f04a4d08599e3e361b94997 (patch)
treea8c41f2fc8476881b3f7bf2ddb402baa2da17142 /includes
parent513bc9e03522f0bfc0e307a8e40a517e746de2bc (diff)
downloadusers-02a3c1e025dfcac83f04a4d08599e3e361b94997.tar.gz
users-02a3c1e025dfcac83f04a4d08599e3e361b94997.tar.bz2
users-02a3c1e025dfcac83f04a4d08599e3e361b94997.zip
To simplyfy maintenence BitUser classes have been retired and active code base defaulted to ROLE_MODEL
Diffstat (limited to 'includes')
-rwxr-xr-xincludes/bit_setup_inc.php3
-rwxr-xr-xincludes/classes/BitAuth.php111
-rwxr-xr-xincludes/classes/BitPermUser.php980
-rwxr-xr-xincludes/classes/BitUser.php2817
-rwxr-xr-xincludes/classes/RoleUser.php4
-rwxr-xr-xincludes/lookup_user_inc.php1
-rwxr-xr-xincludes/register_inc.php34
7 files changed, 10 insertions, 3940 deletions
diff --git a/includes/bit_setup_inc.php b/includes/bit_setup_inc.php
index 979ac5b..17bf54e 100755
--- a/includes/bit_setup_inc.php
+++ b/includes/bit_setup_inc.php
@@ -48,9 +48,6 @@ if( !defined( 'LOGO_MAX_DIM' )) {
define( 'LOGO_MAX_DIM', 600 );
}
-// a package can decide to override the default user class
-$userClass = $gBitSystem->getConfig( 'user_class', (defined('ROLE_MODEL') ) ? '\Bitweaver\Users\RolePermUser' : '\Bitweaver\Users\BitPermUser' );
-
// set session lifetime
if( $gBitSystem->isFeatureActive( 'site_session_lifetime' )) {
ini_set( 'session.gc_maxlifetime', $gBitSystem->isFeatureActive( 'site_session_lifetime' ));
diff --git a/includes/classes/BitAuth.php b/includes/classes/BitAuth.php
deleted file mode 100755
index 9ef9678..0000000
--- a/includes/classes/BitAuth.php
+++ /dev/null
@@ -1,111 +0,0 @@
-<?php
-/**
- * $Header$
- *
- * @package users
- */
-
-/**
- * Class that manages the bitweaver autentication method
- *
- * @package users
- * @subpackage auth
- */
-
-namespace Bitweaver\Users;
-
-class BitAuth extends BaseAuth {
-
- public function __construct() {
- parent::__construct('bit');
- }
-
- public function validate($user,$pass,$challenge,$response) {
- parent::validate($user,$pass,$challenge,$response);
- global $gBitSystem;
- global $gBitDb;
- $ret = SERVER_ERROR;
- if( empty( $user ) ) {
- $this->mErrors['login'] = 'User not found';
- } elseif( empty( $pass ) ) {
- $this->mErrors['login'] = 'Password incorrect';
- } else {
- $loginVal = strtoupper( $user ); // case insensitive login
- $loginCol = ' UPPER(`'.(strpos( $user, '@' ) ? 'email' : 'login').'`)';
- // first verify that the user exists
- $query = "select `email`, `login`, `user_id`, `user_password` from `".BIT_DB_PREFIX."users_users` where " . $gBitDb->convertBinary(). " $loginCol = ?";
- $result = $gBitDb->query( $query, [ $loginVal ] );
- if( !$result->numRows() ) {
- $this->mErrors['login'] = 'User not found';
- } else {
- $res = $result->fetchRow();
- $userId = $res['user_id'];
- $user = $res['login'];
- // TikiWiki 1.8+ uses this bizarro conglomeration of fields to get the hash. this sucks for many reasons
- $hash = md5( strtolower($user) . $pass . $res['email']);
- $hash2 = md5($pass);
- // next verify the password with 2 hashes methods, the old one (pass)) and the new one (login.pass;email)
- // TODO - this needs cleaning up - wolff_borg
- if( !$gBitSystem->isFeatureActive( 'feature_challenge' ) || empty($response) ) {
- $query = "select `user_id`, `hash` from `".BIT_DB_PREFIX."users_users` where " . $gBitDb->convertBinary(). " $loginCol = ? and (`hash`=? or `hash`=?)";
- if ( $row = $gBitDb->getRow( $query, [ $loginVal, $hash, $hash2 ] ) ) {
- // auto-update old hashes with simple and standard md5( password )
- $hashUpdate = '';
- if( $row['hash'] == $hash ) {
- $hashUpdate = 'hash=?, ';
- $bindVars[] = $hash2;
- }
- $bindVars[] = $gBitSystem->getUTCTime();
- $bindVars[] = $userId;
- $query = "update `".BIT_DB_PREFIX."users_users` set $hashUpdate `last_login`=`current_login`, `current_login`=? where `user_id`=?";
- $result = $gBitDb->query($query, $bindVars );
- $ret=USER_VALID;
- } else {
- $ret=PASSWORD_INCORRECT;
- $this->mErrors[] = 'Password incorrect';
- }
- } else {
- // Use challenge-reponse method
- // Compare pass against md5(user,challenge,hash)
- $hash = $gBitDb->getOne("select `hash` from `".BIT_DB_PREFIX."users_users` where " . $gBitDb->convertBinary(). " $loginCol = ?", [ $user ] );
- if (!isset($_SESSION["challenge"])) {
- $this->mErrors[] = 'Invalid challenge';
- $ret=PASSWORD_INCORRECT;
- }
- //print("pass: $pass user: $user hash: $hash <br/>");
- //print("challenge: ".$_SESSION["challenge"]." challenge: $challenge<br/>");
- //print("response : $response<br/>");
- if ($response == md5( strtolower($user) . $hash . $_SESSION["challenge"]) ) {
- $ret = USER_VALID;
- RoleUser::updateLastLogin( $userId );
- } else {
- $this->mErrors[] = 'Invalid challenge';
- $ret=PASSWORD_INCORRECT;
- }
- }
- }
- if (!empty($userId)) {
- $this->mInfo['user_id']=$userId;
- }
- }
- return $ret;
- }
-
- public function canManageAuth() {
- return true;
- }
-
- public function isSupported() {
- return true;
- }
-
- public function createUser( &$pUserHash ) {
- //$authUserInfo = array( 'login' => $instance->mInfo['login'], 'password' => $instance->mInfo['password'], 'real_name' => $instance->mInfo['real_name'], 'email' => $instance->mInfo['email'] );
- $u = new RolePermUser();
-
- if( !$u->store( $pUserHash ) ) {
- $this->mErrors = array_merge($this->mErrors,$u->mErrors);
- }
- return $u->mUserId;
- }
-}
diff --git a/includes/classes/BitPermUser.php b/includes/classes/BitPermUser.php
deleted file mode 100755
index 61738cb..0000000
--- a/includes/classes/BitPermUser.php
+++ /dev/null
@@ -1,980 +0,0 @@
-<?php
-/**
- * $Header$
- *
- * Lib for user administration, groups and permissions
- * This lib uses pear so the constructor requieres
-
- * Copyright (c) 2004 bitweaver.org
- * Copyright (c) 2003 tikwiki.org
- * Copyright (c) 2002-2003, Luis Argerich, Garland Foster, Eduardo Polidor, et. al.
- * All Rights Reserved. See below for details and a complete list of authors.
- * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See http://www.gnu.org/copyleft/lesser.html for details
- *
- * $Id$
- * @package users
- */
-
-/**
- * required setup
- */
-namespace Bitweaver\Users;
-
-use ADORecordSet;
-use Bitweaver\KernelTools;
-
-/**
- * Class that holds all information for a given user
- *
- * @author spider <spider@steelsun.com>
- * @version $Revision$
- * @package users
- * @subpackage BitPermUser
- */
-class BitPermUser extends BitUser {
-
- public $mPerms;
-
- /**
- * BitPermUser Initialise class
- *
- * @param numeric $pUserId User ID of the user we wish to load
- * @param numeric $pContentId Content ID of the user we wish to load
- * @access public
- * @return void
- */
- function __construct( $pUserId=null, $pContentId=null ) {
- parent::__construct( $pUserId, $pContentId );
-
- // Permission setup
- $this->mAdminContentPerm = 'p_users_admin';
- }
-
- public function __sleep() {
- return array_merge( parent::__sleep(), [ 'mPerms' ] );
- }
-
- public function __wakeup() {
- parent::__wakeup();
- if( empty( $this->mPerms ) ) {
- $this->loadPermissions();
- }
- }
-
- /**
- * assumeUser Assume the identity of anothre user - Only admins may do this
- *
- * @param numeric $pUserId User ID of the user you want to hijack
- * @access public
- * @return bool true on success, false on failure - mErrors will contain reason for failure
- */
- function assumeUser( $pUserId ) {
- global $gBitUser;
- $ret = false;
-
- // make double sure the current logged in user has permission, check for p_users_admin, not admin, as that is all you need for assuming another user.
- // this enables creating of a non technical site adminstrators group, eg customer support representatives.
- if( $gBitUser->hasPermission( 'p_users_admin' ) ) {
- $assumeUser = new BitPermUser( $pUserId );
- $assumeUser->loadPermissions();
- if( $assumeUser->isAdmin() ) {
- $this->mErrors['assume_user'] = KernelTools::tra( "User administrators cannot be assumed." );
- } else {
- $this->mDb->query( "UPDATE `".BIT_DB_PREFIX."users_cnxn` SET `user_id`=?, `assume_user_id`=? WHERE `cookie`=?", [ $pUserId, $gBitUser->mUserId, $_COOKIE[$this->getSiteCookieName()] ] );
- $ret = true;
- }
- }
-
- return $ret;
- }
-
- /**
- * load
- *
- * @param bool $pFull Load all permissions
- * @param string $pUserName User login name
- * @return bool true on success, false on failure - mErrors will contain reason for failure
- */
- public function load( ...$extraParams ): bool {
- if( BitUser::load( $extraParams[0], $extraParams[1] ) ) {
- if( !empty($extraParams[0]) && $extraParams[0] ) {
- unset( $this->mPerms );
- $this->loadGroups();
- $this->loadPermissions();
- }
- }
- return $this->mUserId != null;
- }
-
- /**
- * sanitizeUserInfo Used to remove sensitive information from $this->mInfo when it is unneccessary (i.e. $gQueryUser)
- *
- * @access public
- * @return void
- */
- function sanitizeUserInfo()
- {
- if (!empty( $this->mInfo )) {
- $unsanitary = [ 'provpass', 'hash', 'challenge', 'user_password' ];
- foreach ( array_keys( $this->mInfo ) as $key ) {
- if (in_array( $key, $unsanitary )) {
- unset( $this->mInfo[$key] );
- }
- }
- }
- }
-
- /**
- * store
- *
- * @param array $pParamHash
- * @return bool true on success, false on failure - mErrors will contain reason for failure
- */
- public function store( array &$pParamHash ) : bool
- {
- global $gBitSystem;
- // keep track of newUser before calling base class
- $newUser = !$this->isRegistered();
- $this->StartTrans();
- if (BitUser::store( $pParamHash ) && $newUser) {
- $defaultGroups = $this->getDefaultGroup();
- $this->addUserToGroup( $this->mUserId, $defaultGroups );
- if ($gBitSystem->isFeatureActive( 'users_eponymous_groups' )) {
- // Create a group just for this user, for permissions assignment.
- $groupParams = [
- 'user_id' => $this->mUserId,
- 'name' => $pParamHash['user_store']['login'],
- 'desc' => "Personal group for " . ( !empty( $pParamHash['user_store']['real_name'] ) ? $pParamHash['user_store']['real_name'] : $pParamHash['user_store']['login'] ),
- ];
- if ($this->storeGroup( $groupParams )) {
- $this->addUserToGroup( $this->mUserId, $groupParams['group_id'] );
- }
- }
- $this->load( true );
-
- // store any uploaded images, this can stuff mErrors, so we want to do this as the very last thing.
- $pParamHash['upload']['thumbnail'] = false; // i don't think this does anything - perhaps replace it by setting thumbnail_sizes
- $this->storeImages( $pParamHash );
- }
- $this->CompleteTrans();
- return count( $this->mErrors ) == 0;
- }
-
- /**
- * groupExists work out if a given group exists
- *
- * @param string $pGroupName
- * @param numeric $pUserId
- * @access public
- * @return bool true on success, false on failure - mErrors will contain reason for failure
- */
- function groupExists( $pGroupName, $pUserId = ROOT_USER_ID )
- {
- static $sGroups = [];
- if (!isset( $sGroups[$pUserId][$pGroupName] )) {
- $bindVars = [ $pGroupName ];
- $whereSql = '';
- if ($pUserId != '*') {
- $whereSql = 'AND `user_id`=?';
- $bindVars[] = $pUserId;
- }
- $query = "
- SELECT ug.`group_name`, ug.`group_id`, ug.`user_id`
- FROM `" . BIT_DB_PREFIX . "users_groups` ug
- WHERE `group_name`=? $whereSql";
- if ($result = $this->mDb->getAssoc( $query, $bindVars )) {
- if (empty( $sGroups[$pUserId] )) {
- $sGroups[$pUserId] = [];
- }
- $sGroups[$pUserId][$pGroupName] = $result[$pGroupName];
- }
- else {
- $sGroups[$pUserId][$pGroupName]['group_id'] = null;
- }
- }
- return $sGroups[$pUserId][$pGroupName]['group_id'];
- }
-
- /**
- * removes user and associated private data
- *
- * @access public
- * @return bool
- */
- public function expunge() : bool
- {
- global $gBitSystem, $gBitUser;
- $this->clearFromCache();
- if ($this->isValid()) {
- $this->StartTrans();
- if ($this->mUserId == $gBitUser->mUserId) {
- $this->mDb->RollbackTrans();
- $gBitSystem->fatalError( KernelTools::tra( 'You cannot delete yourself' ) );
- }
- elseif ($this->mUserId != ANONYMOUS_USER_ID) {
- $userTables = [
- 'users_groups_map',
- ];
-
- foreach ( $userTables as $table ) {
- $query = "DELETE FROM `" . BIT_DB_PREFIX . $table . "` WHERE `user_id` = ?";
- $result = $this->mDb->query( $query, [ $this->mUserId ] );
- }
-
- if ( parent::expunge() ) {
- $this->CompleteTrans();
- return true;
- }
-
- $this->mDb->RollbackTrans();
-
- }
- else {
- $this->mDb->RollbackTrans();
- $gBitSystem->fatalError( KernelTools::tra( 'The anonymous user cannot be deleted' ) );
- }
- }
- return true;
- }
-
- // =-=-=-=-=-=-=-=-=-=-=-= Group Functions =-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- /**
- * loadGroups load groups into $this->mGroups
- *
- * @param boolean $pForceRefresh
- * @access public
- * @return void
- */
- public function loadGroups( $pForceRefresh = false )
- {
- if ($this->isValid()) {
- $this->mGroups = $this->getGroups( null, $pForceRefresh );
- }
- }
-
- /**
- * isInGroup work out if a given user is in a group
- *
- * @param mixed $pGroupMixed Group ID or Group Name (deprecated)
- * @access public
- * @return bool true on success, false on failure - mErrors will contain reason for failure
- */
- public function isInGroup( $pGroupMixed )
- {
- $ret = false;
- if ($this->isAdmin()) {
- $ret = true;
- }
- if ($this->isValid()) {
- if (empty( $this->mGroups )) {
- $this->loadGroups();
- }
- if (preg_match( '/A-Za-z/', $pGroupMixed )) {
- // Old style group name passed in
- deprecated( "Please use the Group ID instead of the Group name." );
- $ret = in_array( $pGroupMixed, $this->mGroups );
- }
- else {
- $ret = isset( $this->mGroups[$pGroupMixed] );
- }
- }
- return $ret;
- }
-
- /**
- * getAllGroups Get a list of all Groups
- *
- * @param array $pListHash List Hash
- * @access public
- * @return array of groups
- */
- function getAllGroups( &$pListHash )
- {
- if (empty( $pListHash['sort_mode'] ) || $pListHash['sort_mode'] == 'name_asc') {
- $pListHash['sort_mode'] = 'group_name_asc';
- }
- LibertyContent::prepGetList( $pListHash );
- $sortMode = $this->mDb->convertSortmode( $pListHash['sort_mode'] );
- if (!empty( $pListHash['find_groups'] )) {
- $mid = " AND UPPER(`group_name`) like ?";
- $bindvars[] = "%" . strtoupper( $pListHash['find_groups'] ) . "%";
- }
- elseif (!empty( $pListHash['find'] )) {
- $mid = " AND UPPER(`group_name`) like ?";
- $bindvars[] = "%" . strtoupper( $pListHash['find'] ) . "%";
- }
- else {
- $mid = '';
- $bindvars = [];
- }
-
- if (!empty( $pListHash['hide_root_groups'] )) {
- $mid .= ' AND `user_id` <> ' . ROOT_USER_ID;
- }
- elseif (!empty( $pListHash['only_root_groups'] )) {
- $mid .= ' AND `user_id` = ' . ROOT_USER_ID;
- }
-
- if (!empty( $pListHash['user_id'] )) {
- $mid .= ' AND `user_id` = ? ';
- $bindvars[] = $pListHash['user_id'];
- }
- if (!empty( $pListHash['is_public'] )) {
- $mid .= ' AND `is_public` = ?';
- $bindvars[] = $pListHash['is_public'];
- }
- if (!empty( $pListHash['visible'] ) && !$this->isAdmin()) {
- global $gBitUser;
- $mid .= ' AND `user_id` = ? OR `is_public` = ? ';
- $bindvars[] = $gBitUser->mUserId;
- $bindvars[] = 'y';
-
- }
-
- $mid = preg_replace( '/^ AND */', ' WHERE ', $mid );
-
- $query = "
- SELECT `user_id`, `group_id`, `group_name` , `group_desc`, `group_home`, `is_default`, `is_public`
- FROM `" . BIT_DB_PREFIX . "users_groups` $mid
- ORDER BY $sortMode";
- $ret = [];
- if ($rs = $this->mDb->query( $query, $bindvars )) {
- while ( $row = $rs->fetchRow() ) {
- $groupId = $row['group_id'];
- $ret[$groupId] = $row;
- $ret[$groupId]['perms'] = $this->getGroupPermissions( [ 'group_id' => $groupId ] );
- }
- }
-
- $pListHash['cant'] = $this->mDb->getOne( "SELECT COUNT(*) FROM `" . BIT_DB_PREFIX . "users_groups` $mid", $bindvars );
-
- return $ret;
- }
-
- /**
- * getAllUserGroups
- *
- * @param numeric $pUserId
- * @access public
- * @return array of groups a user belongs to
- */
- function getAllUserGroups( $pUserId = null )
- {
- if (empty( $pUserId )) {
- $pUserId = $this->mUserId;
- }
-
- $sql = "
- SELECT ug.`group_id` AS `hash_key`, ug.* FROM `" . BIT_DB_PREFIX . "users_groups` ug
- WHERE `user_id`=?
- ORDER BY ug.`group_name` ASC";
- return $this->mDb->getAssoc( $sql, [ $pUserId ] );
- }
-
- /**
- * expungeGroup remove a group
- *
- * @param numeric $pGroupId
- * @access public
- * @return bool true on success, false on failure
- */
- function expungeGroup( $pGroupId )
- {
- // we cannot remove the anonymous group
- if ($pGroupId != ANONYMOUS_GROUP_ID) {
- $query = "DELETE FROM `" . BIT_DB_PREFIX . "users_groups_map` WHERE `group_id` = ?";
- $result = $this->mDb->query( $query, [ $pGroupId ] );
- $query = "DELETE FROM `" . BIT_DB_PREFIX . "users_group_permissions` WHERE `group_id` = ?";
- $result = $this->mDb->query( $query, [ $pGroupId ] );
- $query = "DELETE FROM `" . BIT_DB_PREFIX . "users_groups` WHERE `group_id` = ?";
- $result = $this->mDb->query( $query, [ $pGroupId ] );
- return true;
- }
- }
-
- /**
- * getDefaultGroup get the default group of a given user
- *
- * @param array $pGroupId pass in a Group ID to make conditional function
- * @access public
- * @return Default Group ID if one is set
- */
- function getDefaultGroup( $pGroupId = null )
- {
- $bindvars = false;
- $whereSql = '';
- if (\Bitweaver\BitBase::verifyId( $pGroupId )) {
- $whereSql = "AND `group_id`=? ";
- $bindvars = [ $pGroupId ];
- }
- return $this->mDb->getAssoc( "SELECT `group_id`, `group_name` FROM `" . BIT_DB_PREFIX . "users_groups` WHERE `is_default` = 'y' $whereSql ", $bindvars );
- }
-
- /**
- * getGroupUsers Get a list of users who share a given group id
- *
- * @param array $pGroupId
- * @access public
- * @return list of users who are in the group id
- */
- function getGroupUsers( $pGroupId )
- {
- $ret = [];
- if (\Bitweaver\BitBase::verifyId( $pGroupId )) {
- $query = "
- SELECT uu.`user_id` AS hash_key, uu.`login`, uu.`real_name`, uu.`user_id`
- FROM `" . BIT_DB_PREFIX . "users_users` uu
- INNER JOIN `" . BIT_DB_PREFIX . "users_groups_map` ug ON (uu.`user_id`=ug.`user_id`)
- WHERE `group_id`=?";
- $ret = $this->mDb->getAssoc( $query, [ $pGroupId ] );
- }
- return $ret;
- }
-
- /**
- * getGroupHome get the URL where a user of that group should be sent
- *
- * @param array $pGroupId
- * @access public
- * @return bool true on success, false on failure - mErrors will contain reason for failure
- */
- function getGroupHome( $pGroupId )
- {
- $ret = false;
- if (\Bitweaver\BitBase::verifyId( $pGroupId )) {
- $query = "SELECT `group_home` FROM `" . BIT_DB_PREFIX . "users_groups` WHERE `group_id`=?";
- $ret = $this->mDb->getOne( $query, [ $pGroupId ] );
- }
- return $ret;
- }
-
- /**
- * storeUserDefaultGroup
- *
- * @param integer $pUserId
- * @param integer $pGroupId
- * @access public
- * @return bool true on success, false on failure
- */
- function storeUserDefaultGroup( $pUserId, $pGroupId )
- {
- if (\Bitweaver\BitBase::verifyId( $pUserId ) && \Bitweaver\BitBase::verifyId( $pGroupId )) {
- $query = "UPDATE `" . BIT_DB_PREFIX . "users_users` SET `default_group_id` = ? WHERE `user_id` = ?";
- return $this->mDb->query( $query, [ $pGroupId, $pUserId ] );
- }
- return false;
- }
-
- /**
- * batchAssignUsersToGroup assign all users to a given group
- *
- * @param array $pGroupId
- * @access public
- * @return void
- */
- function batchAssignUsersToGroup( $pGroupId )
- {
- if (\Bitweaver\BitBase::verifyId( $pGroupId )) {
- $users = $this->getGroupUsers( $pGroupId );
- $result = $this->mDb->getCol( "SELECT uu.`user_id` FROM `" . BIT_DB_PREFIX . "users_users` uu" );
- foreach ( $result as $userId ) {
- if (empty( $users[$userId] ) && $userId != ANONYMOUS_USER_ID) {
- $this->addUserToGroup( $userId, $pGroupId );
- }
- }
- }
- }
-
- /**
- * batchSetUserDefaultGroup
- *
- * @param array $pGroupId
- * @access public
- * @return bool true on success, false on failure - mErrors will contain reason for failure
- */
- function batchSetUserDefaultGroup( $pGroupId )
- {
- if (\Bitweaver\BitBase::verifyId( $pGroupId )) {
- $users = $this->getGroupUsers( $pGroupId );
- foreach ( array_keys( $users ) as $userId ) {
- $this->storeUserDefaultGroup( $userId, $pGroupId );
- }
- }
- }
-
- /**
- * getGroupInfo
- *
- * @param array $pGroupId
- * @access public
- * @return array group information
- */
- public function getGroupInfo( $pGroupId ) :array
- {
- if (\Bitweaver\BitBase::verifyId( $pGroupId )) {
- $sql = "SELECT * FROM `" . BIT_DB_PREFIX . "users_groups` WHERE `group_id` = ?";
- $ret = $this->mDb->getRow( $sql, [ $pGroupId ] );
-
- $listHash = [
- 'group_id' => $pGroupId,
- 'sort_mode' => 'up.perm_name_asc',
- ];
- $ret["perms"] = $this->getGroupPermissions( $listHash );
-
- $sql = "SELECT COUNT(*) FROM `" . BIT_DB_PREFIX . "users_groups_map` WHERE `group_id` = ?";
- $ret['num_members'] = $this->mDb->getOne( $sql, [ $pGroupId ] );
-
- return $ret;
- }
- return [];
- }
-
- /**
- * addUserToGroup Adds user pUserId to group(s) pGroupMixed.
- *
- * @param numeric $pUserId User ID
- * @param mixed $pGroupMixed A single group ID or an array of group IDs
- * @access public
- * @return ADORecordSet|bool an ADO RecordSet (success) or false (failure).
- */
- function addUserToGroup( $pUserId, $pGroupMixed )
- {
- $result = false;
- if (\Bitweaver\BitBase::verifyId( $pUserId ) && !empty( $pGroupMixed )) {
- $result = true;
- $addGroups = [];
- if (is_array( $pGroupMixed )) {
- $addGroups = array_keys( $pGroupMixed );
- }
- elseif (\Bitweaver\BitBase::verifyId( $pGroupMixed )) {
- $addGroups = [ $pGroupMixed ];
- }
- $currentUserGroups = $this->getGroups( $pUserId );
- foreach ( $addGroups as $groupId ) {
- if (!$this->mDb->getOne( "SELECT group_id FROM `" . BIT_DB_PREFIX . "users_groups_map` WHERE `user_id` = ? AND `group_id` = ?", [ $pUserId, $groupId ] )) {
- $query = "INSERT INTO `" . BIT_DB_PREFIX . "users_groups_map` (`user_id`,`group_id`) VALUES(?,?)";
- $result = $this->mDb->query( $query, [ $pUserId, $groupId ] );
- }
- }
- }
- $this->clearFromCache();
- return $result;
- }
-
- /**
- * removeUserFromGroup
- *
- * @param integer $pUserId
- * @param integer $pGroupId
- * @access public
- * @return void
- */
- function removeUserFromGroup( $pUserId, $pGroupId )
- {
- if (\Bitweaver\BitBase::verifyId( $pUserId ) && \Bitweaver\BitBase::verifyId( $pGroupId )) {
- $query = "DELETE FROM `" . BIT_DB_PREFIX . "users_groups_map` WHERE `user_id` = ? AND `group_id` = ?";
- $result = $this->mDb->query( $query, [ $pUserId, $pGroupId ] );
- $default = $this->getDefaultGroup();
- if ($pGroupId == key( $default )) {
- $query = "UPDATE `" . BIT_DB_PREFIX . "users_users` SET `default_group_id` = null WHERE `user_id` = ?";
- $this->mDb->query( $query, [ $pUserId ] );
- }
- }
- $this->clearFromCache();
- }
-
- /**
- * verifyGroup
- *
- * @param array $pParamHash
- * @access public
- * @return bool true on success, false on failure - mErrors will contain reason for failure
- */
- function verifyGroup( &$pParamHash )
- {
- if (!empty( $pParamHash['group_id'] )) {
- if (@$this->verifyId( $pParamHash['group_id'] )) {
- $pParamHash['group_store']['group_id'] = $pParamHash['group_id'];
- }
- else {
- $this->mErrors['groups'] = 'Unknown Group';
- }
- }
-
- if (!empty( $pParamHash["name"] )) {
- $pParamHash['group_store']['group_name'] = substr( $pParamHash["name"], 0, 30 );
- }
- if (!empty( $pParamHash["desc"] )) {
- $pParamHash['group_store']['group_desc'] = substr( $pParamHash["desc"], 0, 255 );
- ;
- }
- $pParamHash['group_store']['group_home'] = !empty( $pParamHash["home"] ) ? $pParamHash["home"] : '';
- $pParamHash['group_store']['is_default'] = !empty( $pParamHash["is_default"] ) ? $pParamHash["is_default"] : null;
- $pParamHash['group_store']['user_id'] = @$this->verifyId( $pParamHash["user_id"] ) ? $pParamHash["user_id"] : $this->mUserId;
- $pParamHash['group_store']['is_public'] = !empty( $pParamHash['is_public'] ) ? $pParamHash['is_public'] : null;
- $pParamHash['group_store']['after_registration_page'] = !empty( $pParamHash['after_registration_page'] ) ? $pParamHash['after_registration_page'] : '';
- return count( $this->mErrors ) == 0;
- }
-
- /**
- * storeGroup
- *
- * @param array $pParamHash
- * @access public
- * @return bool true on success, false on failure - mErrors will contain reason for failure
- */
- function storeGroup( &$pParamHash )
- {
- global $gBitSystem, $gBitUser;
- if ($this->verifyGroup( $pParamHash )) {
- $this->StartTrans();
- if (empty( $pParamHash['group_id'] )) {
- $pParamHash['group_id'] = $this->mDb->GenID( 'users_groups_id_seq' );
- $pParamHash['group_store']['group_id'] = $pParamHash['group_id'];
- $result = $this->mDb->associateInsert( BIT_DB_PREFIX . 'users_groups', $pParamHash['group_store'] );
- }
- else {
- $sql = "SELECT COUNT(*) FROM `" . BIT_DB_PREFIX . "users_groups` WHERE `group_id` = ?";
- $groupExists = $this->mDb->getOne( $sql, [ $pParamHash['group_id'] ] );
- if ($groupExists) {
- $result = $this->mDb->associateUpdate( BIT_DB_PREFIX . 'users_groups', $pParamHash['group_store'], [ "group_id" => $pParamHash['group_id'] ] );
- }
- else {
- // A group_id was specified but that group does not exist yet
- $pParamHash['group_store']['group_id'] = $pParamHash['group_id'];
- $result = $this->mDb->associateInsert( BIT_DB_PREFIX . 'users_groups', $pParamHash['group_store'] );
- }
- }
-
- if (isset( $_REQUEST['batch_set_default'] ) and $_REQUEST['batch_set_default'] == 'on') {
- $gBitUser->batchSetUserDefaultGroup( $pParamHash['group_id'] );
- }
- $this->CompleteTrans();
- }
- return count( $this->mErrors ) == 0;
- }
-
- /**
- * getGroupNameFromId
- *
- * @param array $pGroupId
- * @param array $pColumns
- * @access public
- * @return array of group data
- */
- public static function getGroupNameFromId( $pGroupId )
- {
- $ret = '';
- if (static::verifyId( $pGroupId )) {
- global $gBitDb;
- $ret = $gBitDb->getOne( "SELECT `group_name` FROM `" . BIT_DB_PREFIX . "users_groups` WHERE `group_id`=?", [ $pGroupId ] );
- }
- return $ret;
- }
-
- /**
- * getGroupUserData
- *
- * @param array $pGroupId
- * @param array $pColumns
- * @access public
- * @return array of group data
- */
- function getGroupUserData( $pGroupId, $pColumns )
- {
- $ret = [];
- if (@$this->verifyId( $pGroupId ) && !empty( $pColumns )) {
- if (is_array( $pColumns )) {
- $col = implode( $pColumns, ',' );
- $exec = 'getAssoc';
- }
- else {
- $col = '`' . $pColumns . '`';
- $exec = 'getArray';
- }
- $query = "
- SELECT $col
- FROM `" . BIT_DB_PREFIX . "users_users` uu
- INNER JOIN `" . BIT_DB_PREFIX . "users_groups_map` ugm ON (uu.`user_id`=ugm.`user_id`)
- WHERE ugm.`group_id` = ?";
- $ret = $this->mDb->$exec( $query, [ $pGroupId ] );
- }
- return $ret;
- }
-
- // =-=-=-=-=-=-=-=-=-=-=-= PERMISSION FUNCTIONS =-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- /**
- * loadPermissions
- *
- * @access public
- * @return bool true on success, false if no perms were loaded
- */
- function loadPermissions( $pForceReload = false )
- {
- if ($this->isValid() && ( empty( $this->mPerms ) || $pForceReload )) {
- $this->mPerms = [];
- // the double up.`perm_name` is intentional - the first is for hash key, the second is for hash value
- $query = "
- SELECT up.`perm_name` AS `hash_key`, up.`perm_name`, up.`perm_desc`, up.`perm_level`, up.`package`
- FROM `" . BIT_DB_PREFIX . "users_permissions` up
- INNER JOIN `" . BIT_DB_PREFIX . "users_group_permissions` ugp ON ( ugp.`perm_name`=up.`perm_name` )
- INNER JOIN `" . BIT_DB_PREFIX . "users_groups` ug ON ( ug.`group_id`=ugp.`group_id` )
- LEFT OUTER JOIN `" . BIT_DB_PREFIX . "users_groups_map` ugm ON ( ugm.`group_id`=ugp.`group_id` AND ugm.`user_id` = ? )
- WHERE ug.`group_id`= " . ANONYMOUS_GROUP_ID . " OR ugm.`group_id`=ug.`group_id`";
- $this->mPerms = $this->mDb->getAssoc( $query, [ $this->mUserId ] );
- // Add in override permissions
- if (!empty( $this->mPermsOverride )) {
- foreach ( $this->mPermsOverride as $key => $val ) {
- $this->mPerms[$key] = $val;
- }
- }
- }
- return !empty( $this->mPerms );
- }
-
- /**
- * getUnassignedPerms
- *
- * @access public
- * @return array of permissions that have not been assigned to any group yet
- */
- function getUnassignedPerms()
- {
- $query = "SELECT up.`perm_name` AS `hash_key`, up.*
- FROM `" . BIT_DB_PREFIX . "users_permissions` up
- LEFT OUTER JOIN `" . BIT_DB_PREFIX . "users_group_permissions` ugp ON( up.`perm_name` = ugp.`perm_name` )
- WHERE ugp.`group_id` IS null AND up.`perm_name` <> ?
- ORDER BY `package`, up.`perm_name` ASC";
- return $this->mDb->getAssoc( $query, [ '' ] );
- }
-
- /**
- * isAdmin
- *
- * @param array $pCheckTicket
- * @access public
- * @return bool true on success, false on failure - mErrors will contain reason for failure
- */
- function isAdmin()
- {
- // we can't use hasPermission here since it turn into an endless loop
- return !empty( $this->mPerms['p_admin'] );
- }
-
- /**
- * hasPermission check to see if a user has a given permission
- *
- * @param array $pPerm Perm name
- * @access public
- * @return bool true if the user has a permission, false if they don't
- */
- function hasPermission( $pPerm )
- {
- $ret = false;
- if ($this->isAdmin()) {
- $ret = true;
- }
- elseif ($this->isValid()) {
- $ret = isset( $this->mPerms[$pPerm] );
- }
- return $ret;
- }
-
- /**
- * verifyPermission check if a user has a given permission and if not
- * it will display the error template and die()
- * @param $pPermission value of a given permission
- * @return void
- * @access public
- */
- function verifyPermission( $pPermission, $pMsg = null )
- {
- global $gBitSmarty, $gBitSystem, ${$pPermission};
- if (empty( $pPermission ) || $this->hasPermission( $pPermission )) {
- return;
- }
-
- $gBitSystem->fatalPermission( $pPermission, $pMsg );
-
- }
-
- /**
- * getGroupPermissions
- *
- * @param array $pGroupId Group id, if unset, all groups are returned
- * @param string $pPackage permissions to give group, if unset, all permissions are returned
- * @param string $find search for a particular permission
- * @param array $pSortMode sort mode of return hash
- * @access public
- * @return array true on success, false on failure
- */
- public function getGroupPermissions( $pParamHash = null )
- {
- global $gBitSystem;
- $ret = $bindVars = [];
- $whereSql = $selectSql = $fromSql = '';
-
- $sortMode = ( !empty( $pParamHash['sort_mode'] ) ) ? $this->mDb->convertSortmode( $pParamHash['sort_mode'] ) : 'up.`package`, up.`perm_name` ASC';
-
- if (!empty( $pParamHash['package'] )) {
- $whereSql = ' WHERE `package`= ? ';
- $bindVars[] = $pParamHash['package'];
- }
-
- if (\Bitweaver\BitBase::verifyId( $pParamHash['group_id'] )) {
- $selectSql = ', ugp.`perm_value` AS `hasPerm` ';
- $fromSql = ' INNER JOIN `' . BIT_DB_PREFIX . 'users_group_permissions` ugp ON ( ugp.`perm_name`=up.`perm_name` ) ';
- if ($whereSql) {
- $whereSql .= " AND ugp.`group_id`=?";
- }
- else {
- $whereSql .= " WHERE ugp.`group_id`=?";
- }
-
- $bindVars[] = $pParamHash['group_id'];
- }
-
- if (!empty( $pParamHash['find'] )) {
- if ($whereSql) {
- $whereSql .= " AND `perm_name` like ?";
- }
- else {
- $whereSql .= " WHERE `perm_name` like ?";
- }
- $bindVars[] = '%' . $pParamHash['find'] . '%';
- }
-
- // the double up.`perm_name` is intentional - the first is for hash key, the second is for hash value
- $query = "
- SELECT up.`perm_name` AS `hash_key`, up.`perm_name`, up.`perm_desc`, up.`perm_level`, up.`package` $selectSql
- FROM `" . BIT_DB_PREFIX . "users_permissions` up $fromSql $whereSql
- ORDER BY $sortMode";
- $perms = $this->mDb->getAssoc( $query, $bindVars );
-
- // weed out permissions of inactive packages
- $ret = [];
- foreach ( $perms as $key => $perm ) {
- if ($gBitSystem->isPackageActive( $perm['package'] )) {
- $ret[$key] = $perm;
- }
- }
-
- return $ret;
- }
-
- /**
- * assignLevelPermissions Assign the permissions of a given level to a given group
- *
- * @param array $pGroupId Group we want to assign permissions to
- * @param array $pLevel permission level we wish to assign from
- * @param array $pPackage limit set of permissions to a given package
- * @access public
- * @return void
- */
- function assignLevelPermissions( $pGroupId, $pLevel, $pPackage = null )
- {
- if (\Bitweaver\BitBase::verifyId( $pGroupId ) && !empty( $pLevel )) {
- $bindvars = [ $pLevel ];
- $whereSql = '';
- if (!empty( $pPackage )) {
- $whereSql = ' AND `package`=?';
- array_push( $bindvars, $pPackage );
- }
- $query = "SELECT `perm_name` FROM `" . BIT_DB_PREFIX . "users_permissions` WHERE `perm_level` = ? $whereSql";
- if ($result = $this->mDb->query( $query, $bindvars )) {
- while ( $row = $result->fetchRow() ) {
- $this->assignPermissionToGroup( $row['perm_name'], $pGroupId );
- }
- }
- }
- }
-
- /**
- * getPermissionPackages Get a list of packages that have their own set of permissions
- *
- * @access public
- * @return array of packages
- */
- function getPermissionPackages()
- {
- return $this->mDb->getCol( "SELECT DISTINCT(`package`) FROM `" . BIT_DB_PREFIX . "users_permissions` ORDER BY `package`" );
- }
-
- /**
- * assignPermissionToGroup
- *
- * @param array $perm
- * @param array $pGroupId
- * @access public
- * @return bool true on success
- */
- function assignPermissionToGroup( $pPerm, $pGroupId ) {
- if( \Bitweaver\BitBase::verifyId( $pGroupId ) && !empty( $pPerm )) {
- $query = "DELETE FROM `".BIT_DB_PREFIX."users_group_permissions` WHERE `group_id` = ? AND `perm_name` = ?";
- $result = $this->mDb->query( $query, [ $pGroupId, $pPerm ]);
- $query = "INSERT INTO `".BIT_DB_PREFIX."users_group_permissions`(`group_id`, `perm_name`) VALUES(?, ?)";
- $result = $this->mDb->query( $query, [ $pGroupId, $pPerm ]);
- return true;
- }
- }
-
- /**
- * removePermissionFromGroup
- *
- * @param string $pPerm Perm name
- * @param numeric $pGroupId Group ID
- * @access public
- * @return bool true on success
- */
- function removePermissionFromGroup( $pPerm, $pGroupId ) {
- if( \Bitweaver\BitBase::verifyId( $pGroupId ) && !empty( $pPerm )) {
- $query = "DELETE FROM `".BIT_DB_PREFIX."users_group_permissions` WHERE `perm_name` = ? AND `group_id` = ?";
- $result = $this->mDb->query($query, [$pPerm, $pGroupId]);
- return true;
- }
- }
-
- /**
- * storeRegistrationChoice
- *
- * @param mixed $pGroupMixed A single group ID or an array of group IDs
- * @param array $pValue Value you wish to store - use null to delete a value
- * @access public
- * @return ADO record set on success, false on failure
- */
- function storeRegistrationChoice( $pGroupMixed, $pValue = null ) {
- if( !empty( $pGroupMixed )) {
- $this->clearFromCache();
- $bindVars[] = $pValue;
- if( is_array( $pGroupMixed )) {
- $mid = implode( ',', array_fill( 0, count( $pGroupMixed ),'?' ));
- $bindVars = array_merge( $bindVars, $pGroupMixed );
- } else {
- $bindVars[] = $pGroupMixed;
- $mid = 'LIKE ?';
- }
- $query = "UPDATE `".BIT_DB_PREFIX."users_groups` SET `is_public`= ? where `group_id` IN ($mid)";
- return $this->mDb->query( $query, $bindVars );
- }
- }
-
- /**
- * Grant a single permission to a given value
- */
- function setPermissionOverride( $pPerm, $pValue = null ) {
- if( $this->isAdmin() ) {
- $this->mPerms[$pPerm] = true;
- $this->mPermsOverride[$pPerm] = true;
- } elseif( $this->isValid() ) {
- if( $pValue == 'y' || $pValue == true ) {
- $this->mPermsOverride[$pPerm] = true;
- $this->mPerms[$pPerm] = true;
- } else {
- unset( $this->mPermsOverride[$pPerm] );
- unset( $this->mPerms[$pPerm] );
- }
- }
- }
-}
-
-/* vim: :set fdm=marker : */
diff --git a/includes/classes/BitUser.php b/includes/classes/BitUser.php
deleted file mode 100755
index 7b5d021..0000000
--- a/includes/classes/BitUser.php
+++ /dev/null
@@ -1,2817 +0,0 @@
-<?php
-/**
- * Lib for user administration, groups and permissions
- * This lib uses pear so the constructor requieres
- * a pear DB object
-
- * Copyright (c) 2004 bitweaver.org
- * Copyright (c) 2003 tikwiki.org
- * Copyright (c) 2002-2003, Luis Argerich, Garland Foster, Eduardo Polidor, et. al.
- * All Rights Reserved. See below for details and a complete list of authors.
- * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See http://www.gnu.org/copyleft/lesser.html for details
- *
- * @package users
- */
-
-/**
- * required setup
- */
-namespace Bitweaver\Users;
-
-use Bitweaver\KernelTools;
-use Bitweaver\Liberty\LibertyContent;
-
-define( 'AVATAR_TYPE_CENTRALIZED', 'c' );
-define( 'AVATAR_TYPE_USER_DB', 'u' );
-define( 'AVATAR_TYPE_LIBRARY', 'l' );
-
-// Column sizes for users_users table
-define( 'REAL_NAME_COL_SIZE', 64 );
-
-define( 'BITUSER_CONTENT_TYPE_GUID', 'bituser' );
-
-// some definitions for helping with authentication
-define( "USER_VALID", 2 );
-define( "SERVER_ERROR", -1 );
-define( "PASSWORD_INCORRECT", -3 );
-define( "USER_NOT_FOUND", -5 );
-define( "ACCOUNT_DISABLED", -6 );
-
-/**
- * Class that holds all information for a given user
- *
- * @author spider <spider@steelsun.com>
- * @package users
- * @subpackage BitUser
- */
-#[\AllowDynamicProperties]
-class BitUser extends \Bitweaver\Liberty\LibertyMime {
- public $mUserId;
- public $mUsername;
- public $mGroups;
- public $mTicket;
- public $mAuth;
- public $pExpungeContent = false;
-
- /**
- * Constructor - will automatically load all relevant data if passed a user string
- *
- * @access public
- * @author Christian Fowler <spider@viovio.com>
- * @return void
- */
- function __construct( $pUserId=null, $pContentId=null ) {
- parent::__construct();
- $this->mContentTypeGuid = BITUSER_CONTENT_TYPE_GUID;
- $this->registerContentType(
- BITUSER_CONTENT_TYPE_GUID, [
- 'content_type_guid' => BITUSER_CONTENT_TYPE_GUID,
- 'content_name' => 'User Information',
- 'content_name_plural' => 'User Information',
- 'handler_class' => 'BitUser',
- 'handler_package' => 'users',
- 'handler_file' => 'BitUser.php',
- 'maintainer_url' => 'https://www.bitweaver.org',
- ],
- );
- $this->mUserId = ( @$this->verifyId( $pUserId ) ? $pUserId : null);
- $this->mContentId = $pContentId;
- }
-
- public function __sleep() {
- return array_merge( parent::__sleep(), [ 'mUserId', 'mUsername', 'mGroups', 'mTicket', 'mAuth' ] );
- }
-
- public function getCacheKey() {
- $ret = $this->mUserId;
- $siteCookie = static::getSiteCookieName();
- if( $this->isRegistered() && !empty( $_COOKIE[$siteCookie] ) ) {
- $ret .= $_COOKIE[$siteCookie];
- }
- return $ret;
- }
-
- public static function isCacheableClass() {
- global $gBitSystem;
- return !$gBitSystem->isLive(); // only cache user objects in test mode for now
- }
-
- /**
- * Determines if a user object is cacheable. Out of paranoia, admin's are never cached.
- * @return bool if object can be cached
- */
- public function isCacheableObject() {
- global $gBitSystem;
- return parent::isCacheableObject() && (!$this->isAdmin() || ($gBitSystem && $gBitSystem->isLive())); // Do not cache admin object for live sites per paranoia
- }
-
- /**
- * Validate inbound sort_mode parameter
- * @return array of fields which are valid sorts
- */
- public static function getSortModeFields(): array {
- $fields = parent::getSortModeFields();
- $fields[] = 'map_position';
- return $fields;
- }
-
- /**
- * load - loads all settings & preferences for this user
- *
- * - bool $pFull Load additional user data like
- * - string $pUserName User login name
- * @author Chrstian Fowler <spider@steelsun.com>
- * @return bool true if valid object
- */
- public function load( ...$extraParams ): bool {
- global $gBitSystem;
- $this->mInfo = null;
- if( isset( $this->mUserId ) ) {
- $whereSql = "WHERE uu.`user_id`=?";
- $bindVars = [ $this->mUserId ];
- } elseif( isset( $this->mContentId ) ) {
- $whereSql = "WHERE uu.`content_id`=?";
- $bindVars = [ $this->mContentId ];
- } elseif( !empty( $extraParams[1] ) ) {
- $whereSql = "WHERE uu.`login`=?";
- $bindVars = [ $extraParams[1] ];
- }
- if( isset( $whereSql ) ) {
- $fullSelect = '';
- $fullJoin = '';
- if( !empty($extraParams[0]) && $extraParams[0] ) {
- $fullSelect = ' , lc.* ';
- $fullJoin = " LEFT OUTER JOIN `".BIT_DB_PREFIX."liberty_content` lc ON ( uu.`content_id`=lc.`content_id` )";
- $this->getServicesSql( 'content_load_sql_function', $fullSelect, $fullJoin, $whereSql, $bindVars );
- }
- // uu.`user_id` AS `uu_user_id` is last and aliases to avoid possible column name collisions
- $query = "
- SELECT uu.*,
- lf_ava.`file_name` AS `avatar_file_name`, la_ava.`attachment_id` AS `avatar_attachment_id`, lf_ava.`mime_type` AS `avatar_mime_type`,
- lf_por.`file_name` AS `portrait_file_name`, ta_por.`attachment_id` AS `portrait_attachment_id`, lf_por.`mime_type` AS `portrait_mime_type`,
- lf_logo.`file_name` AS `logo_file_name`, ta_logo.`attachment_id` AS `logo_attachment_id`, lf_logo.`mime_type` AS `logo_mime_type`
- $fullSelect, uu.`user_id` AS `uu_user_id`
- FROM `".BIT_DB_PREFIX."users_users` uu
- LEFT OUTER JOIN `".BIT_DB_PREFIX."liberty_attachments` la_ava ON ( uu.`avatar_attachment_id`=la_ava.`attachment_id` )
- LEFT OUTER JOIN `".BIT_DB_PREFIX."liberty_files` lf_ava ON ( lf_ava.`file_id`=la_ava.`foreign_id` )
- LEFT OUTER JOIN `".BIT_DB_PREFIX."liberty_attachments` ta_por ON ( uu.`portrait_attachment_id`=ta_por.`attachment_id` )
- LEFT OUTER JOIN `".BIT_DB_PREFIX."liberty_files` lf_por ON ( lf_por.`file_id`=ta_por.`foreign_id` )
- LEFT OUTER JOIN `".BIT_DB_PREFIX."liberty_attachments` ta_logo ON ( uu.`logo_attachment_id`=ta_logo.`attachment_id` )
- LEFT OUTER JOIN `".BIT_DB_PREFIX."liberty_files` lf_logo ON ( lf_logo.`file_id`=ta_logo.`foreign_id` )
- $fullJoin
- $whereSql";
- if(( $result = $this->mDb->query( $query, $bindVars )) && $result->numRows() ) {
- $this->mInfo = $result->fetchRow();
- $this->mInfo['user'] = $this->mInfo['login'];
- $this->mInfo['valid'] = @$this->verifyId( $this->mInfo['uu_user_id'] );
- $this->mInfo['user_id'] = $this->mInfo['uu_user_id'];
- $this->mInfo['is_registered'] = $this->isRegistered();
- foreach( [ 'portrait', 'avatar', 'logo' ] as $img ) {
- $this->mInfo[$img.'_path'] = $this->getSourceFile( [ 'user_id'=>$this->getField( 'user_id' ), 'package'=>\Bitweaver\Liberty\liberty_mime_get_storage_sub_dir_name( [ 'mime_type' => $this->getField( $img.'_mime_type' ), 'name' => $this->getField( $img.'_file_name' ) ] ), 'file_name' => basename( $this->mInfo[$img.'_file_name'] ?? '' ), 'sub_dir' => $this->getField( $img.'_attachment_id' ), 'mime_type' => $this->getField( $img.'_mime_type' ) ] );
- $this->mInfo[$img.'_url'] = \Bitweaver\Liberty\liberty_fetch_thumbnail_url( [ 'source_file'=>$this->mInfo[$img.'_path'], 'size' => 'small', 'mime_image' => false ]);
- }
-
- // break the real name into first and last name using the last space as the beginning of the last name
- // for people who really want to use first and last name fields
- if( preg_match( '/ /', $this->mInfo['real_name'] ) ) {
- $this->mInfo['first_name'] = substr( $this->mInfo['real_name'], 0, strrpos($this->mInfo['real_name'], ' ') );
- $this->mInfo['last_name'] = substr( $this->mInfo['real_name'], strrpos($this->mInfo['real_name'], ' ')+1 );
- }else{
- // no spaces assign the real name to the first name
- $this->mInfo['first_name'] = $this->mInfo['real_name'];
- }
-
- $this->mUserId = $this->mInfo['uu_user_id'];
- $this->mContentId = $this->mInfo['content_id'];
- $this->mUsername = $this->mInfo['login'];
- // a few random security conscious unset's - SPIDER
- unset( $this->mInfo['user_password'] );
- unset( $this->mInfo['hash'] );
-
- $this->loadPreferences();
- // Load attachments
- \Bitweaver\Liberty\LibertyMime::load();
- if( $this->getPreference( 'users_country' ) ) {
- $this->setPreference( 'flag', $this->getPreference( 'users_country' ) );
- $this->setPreference( 'users_country', str_replace( '_', ' ', $this->getPreference( 'users_country' ) ) );
- }
- if( !empty($extraParams[0]) && $extraParams[0] ) {
- $this->mInfo['real_name'] = trim( $this->mInfo['real_name'] );
- $this->mInfo['display_name'] = (
- ( !empty( $this->mInfo['real_name'] ) ? $this->mInfo['real_name'] :
- ( !empty( $this->mUsername) ? $this->mUsername :
- ( !empty( $this->mInfo['email'] ) ? substr( $this->mInfo['email'], 0, strpos( $this->mInfo['email'],'@' )) :
- $this->mUserId )))
- );
- //print("displayName: ".$this->mInfo['display_name']);
- $this->defaults();
- $this->mInfo['publicEmail'] = scramble_email( $this->mInfo['email'], ( $this->getPreference( 'users_email_display' ) ? $this->getPreference( 'users_email_display' ) : null ) );
- }
- $this->mTicket = substr( md5( session_id() . $this->mUserId ), 0, 20 );
- } else {
- $this->mUserId = null;
- }
- }
- if( !$gBitSystem->isFeatureActive( 'i18n_browser_languages' ) ) {
- global $gBitLanguage, $gBitUser;
- //change language only if if logged user is this user
- //otherwise it's just logged user (lang A) watching other user's page (lang B) and don't change
- if( $this->mUserId && $this->mUserId != ANONYMOUS_USER_ID && $gBitUser === $this) {
- $gBitLanguage->mLanguage = $this->getPreference( 'bitlanguage', $gBitLanguage->mLanguage );
- } elseif( isset( $_SESSION['bitlanguage'] )) {
- // users not logged that change the preference
- $gBitLanguage->mLanguage = $_SESSION['bitlanguage'];
- }
- }
- return $this->isValid();
- }
-
- /**
- * defaults set a default set of preferences in mPrefs for new users
- *
- * @access public
- * @return void
- */
- function defaults() {
- global $gBitSystem, $gBitThemes, $gBitLanguage;
- if( !$this->getPreference( 'users_information' ) ) {
- $this->setPreference( 'users_information', 'public' );
- }
- if( !$this->getPreference( 'messages_allow_messages' ) ) {
- $this->setPreference( 'messages_allow_messages', 'y' );
- }
- if( !$this->getPreference( 'site_display_utc' ) ) {
- $this->setPreference( 'site_display_utc', 'Local' );
- }
-/*
- * site_display_timezone is not used for 'Local' time display so daylight saving offset is not available
- * both of these should pick up the 'site default' values
- if( !$this->getPreference( 'site_display_timezone' ) ) {
- $this->setPreference( 'site_display_timezone', 'UTC' );
- }
- */
- if( !$this->getPreference( 'bitlanguage' ) ) {
- $this->setPreference( 'bitlanguage', $gBitLanguage->mLanguage );
- }
- if( !$this->getPreference( 'theme' ) ) {
- $this->setPreference( 'theme', $gBitThemes->getStyle() );
- }
- }
-
- /**
- * verify store hash
- *
- * @param array $pParamHash Data to be verified
- * @return bool true on success, false on failure - mErrors will contain reason for failure
- */
- public function verify( array &$pParamHash ): bool {
- global $gBitSystem;
-
- KernelTools::trim_array( $pParamHash );
-
- // DO NOT REMOVE - to allow specific setting of the user_id during the first store.
- // used by ROOT_USER_ID or ANONYMOUS_USER_ID during install.
- if( @$this->verifyId( $pParamHash['user_id'] ) ) {
- $pParamHash['user_store']['user_id'] = $pParamHash['user_id'];
- }
- // require login
- if( !empty( $pParamHash['login'] ) && $pParamHash['login'] != $this->getField( 'login' ) ) {
- $pParamHash['login'] = strip_tags($pParamHash['login']);
- if( strlen( $pParamHash['login'] ) > 40 ) {
- $pParamHash['login'] = substr( $pParamHash['login'], 0, 40 );
- }
- if( $this->userExists( [ 'login' => $pParamHash['login'] ] ) ) {
- $this->mErrors['login'] = 'The username "'.$pParamHash['login'].'" is already in use';
- } elseif( preg_match( '/[^A-Za-z0-9_.-]/', $pParamHash["login"] ) ) {
- $this->mErrors['login'] = KernelTools::tra( "Your username can only contain numbers, characters, underscores and hyphens." );
- } else {
- // LOWER CASE all logins
- $pParamHash['login'] = strtolower( $pParamHash['login'] );
- $pParamHash['user_store']['login'] = $pParamHash['login'];
- }
- }
- // some people really like using first and last names
- // push them into real_name
- if( !empty( $pParamHash['first_name'] ) ) {
- $pParamHash['real_name'] = $pParamHash['first_name'];
- }
- if( !empty( $pParamHash['last_name'] ) ) {
- $pParamHash['real_name'] = !empty( $pParamHash['real_name'] )?$pParamHash['real_name']." ":'';
- $pParamHash['real_name'] .= $pParamHash['last_name'];
- }
- // real_name
- if( !empty( $pParamHash['real_name'] ) ) {
- $pParamHash['user_store']['real_name'] = substr( strip_tags($pParamHash['real_name']), 0, 64 );
- }
- // require email
- if( !empty( $pParamHash['email'] ) ) {
- // LOWER CASE all emails
- $pParamHash['email'] = strtolower( $pParamHash['email'] );
- if( $emailResult = $this->verifyEmail( $pParamHash['email'] , $this->mErrors) ) {
- $pParamHash['verified_email'] = ($emailResult === true);
- }
- }
- // check some new user requirements
- if( !$this->isRegistered() ) {
- if( empty( $pParamHash['login'] ) ) {
- // choose a login based on the username in the email
- if( empty($pParamHash['email']) ){
- // obviously if they didnt enter an email address we cant help them out
- $this->mErrors['email'] = KernelTools::tra( 'You must enter your email address' );
- }else{
- $loginBase = preg_replace( '/[^A-Za-z0-9_]/', '', substr( $pParamHash['email'], 0, strpos( $pParamHash['email'], '@' ) ) );
- $login = $loginBase;
- do {
- if( $loginTaken = $this->userExists( [ 'login' => $login ] ) ) {
- $login = $loginBase.rand(100,999);
- }
- } while( $loginTaken );
- $pParamHash['login'] = $login;
- }
- }
- if( empty( $pParamHash['registration_date'] ) ) {
- $pParamHash['registration_date'] = date( "U" );
- }
- $pParamHash['user_store']['registration_date'] = $pParamHash['registration_date'];
-
- if( !empty( $pParamHash['email'] ) && empty($this->mErrors['email']) ) {
- $pParamHash['user_store']['email'] = substr( $pParamHash['email'], 0, 200 ) ;
- }elseif( empty($pParamHash['email']) ){
- $this->mErrors['email'] = KernelTools::tra( 'You must enter your email address' );
- }
-
- if( $gBitSystem->isFeatureActive( 'users_validate_user' ) ) {
- $pParamHash['user_store']['provpass'] = md5(\Bitweaver\BitSystem::genPass());
- $pParamHash['pass_due'] = 0;
- } elseif( empty( $pParamHash['password'] ) ) {
- $this->mErrors['password'] = KernelTools::tra( 'Your password should be at least '.$gBitSystem->getConfig( 'users_min_pass_length', 4 ).' characters long' );
- }
- } elseif( $this->isValid() ) {
- // Prevent losing user info on save
- if( empty( $pParamHash['edit'] ) ) {
- $pParamHash['edit'] = $this->mInfo['data'];
- }
- }
-
- if( isset( $pParamHash['password'] ) ) {
- if( isset( $pParamHash["password2"] ) && $pParamHash["password"] != $pParamHash["password2"] ) {
- $passwordErrors['password2'] = KernelTools::tra("The passwords didn't match");
- }
- if( ( !$this->isValid() || isset( $pParamHash['password'] ) ) && $error = $this->verifyPasswordFormat( $pParamHash['password'] ) ) {
- $passwordErrors['password'] = $error;
- }
- if( !empty( $passwordErrors ) ) {
- $this->mErrors = array_merge( $this->mErrors,$passwordErrors );
- } else {
- // Generate a unique hash
- //$pParamHash['user_store']['hash'] = md5( strtolower( (!empty($pParamHash['login'])?$pParamHash['login']:'') ).$pPassword.$pParamHash['email'] );
- $pParamHash['user_store']['hash'] = md5( $pParamHash['password'] );
- $now = $gBitSystem->getUTCTime();
- // set password due date
- // if no pass_due and no user_pass_due value user will never have to update the password
- if( empty( $pParamHash['pass_due'] ) && $gBitSystem->getConfig('users_pass_due') ) {
- // renew password according to config value
- $pParamHash['user_store']['pass_due'] = $now + (60 * 60 * 24 * $gBitSystem->getConfig('users_pass_due') );
- } elseif( !empty( $pParamHash['pass_due'] ) ) {
- // renew password only next half year ;)
- $pParamHash['user_store']['pass_due'] = $now + (60 * 60 * 24 * $pParamHash['pass_due']);
- }
- if( $gBitSystem->isFeatureActive( 'users_clear_passwords' ) || !empty( $pParamHash['user_store']['provpass'] ) ) {
- $pParamHash['user_store']['user_password'] = $pParamHash['password'];
- }
- }
- }
-
- // if we have an error we get them all by checking parent classes for additional errors
- if( count( $this->mErrors ) > 0 ){
- parent::verify( $pParamHash );
- }
-
- return ( count($this->mErrors) == 0 );
- }
-
- /**
- * answerCaptcha
- *
- * Determine if the submitted answer for the captcha is valid
- */
- function answerCaptcha( $pParamHash ) {
- global $gBitSystem;
- // require catpcha
- // novalidation is set to yes if a user confirms his email is correct after tiki fails to validate it
- if( $gBitSystem->isFeatureActive( 'users_random_number_reg' ) ) {
- if( ( empty( $pParamHash['novalidation'] ) || $pParamHash['novalidation'] != 'yes' )
- &&( !isset( $_SESSION['captcha'] ) || $_SESSION['captcha'] != md5( $pParamHash['captcha'] ) ) )
- {
- $this->mErrors['captcha'] = "Wrong Answer";
- }
- }
-
- if( $gBitSystem->isFeatureActive( 'users_register_recaptcha' ) && (empty( $pParamHash['novalidation'] ) || $pParamHash['novalidation'] != 'yes') ) {
- if( !empty( $pParamHash['g-recaptcha-response'] ) ) {
- require_once USERS_PKG_INCLUDE_PATH.'recaptcha/autoload.php';
-
- $recaptcha = new \ReCaptcha\ReCaptcha( $gBitSystem->getConfig( 'users_register_recaptcha_secret_key' ) );
- $resp = $recaptcha->setExpectedHostname( $_SERVER['HTTP_HOST'] )
- ->verify( $pParamHash['g-recaptcha-response'], $_SERVER['REMOTE_ADDR'] );
- if( !$resp->isSuccess() ) {
- foreach( $resp->getErrorCodes() as $errorCode ) {
- $this->mErrors['recaptcha'][] = ucwords( str_replace( '-', ' ', $errorCode ) );
- }
- }
- } else {
- $this->mErrors['recaptcha'] = 'No reCAPTCHA Response';
- }
- }
-
- if( $gBitSystem->isFeatureActive( 'users_register_smcaptcha' ) && (empty( $pParamHash['novalidation'] ) || $pParamHash['novalidation'] != 'yes') ) {
- require_once( USERS_PKG_INCLUDE_PATH.'solvemedialib.php' );
- if( !empty( $pParamHash['adcopy_challenge'] ) && !empty( $pParamHash['adcopy_response'] ) ) {
- $solvemediaResponse = solvemedia_check_answer($gBitSystem->getConfig( 'users_register_smcaptcha_v_key' ), $_SERVER["REMOTE_ADDR"], $pParamHash["adcopy_challenge"], $pParamHash["adcopy_response"], $gBitSystem->getConfig( 'users_register_smcaptcha_h_key' ) );
- if( !$solvemediaResponse->is_valid ) {
- $this->mErrors['smcaptcha'] = $solvemediaResponse->error;
- }
- } else {
- $this->mErrors['smcaptcha'] = 'Wrong Answer';
- }
- }
-
- return ( count($this->mErrors) == 0 );
- }
-
- /**
- * preRegisterVerify
- *
- * A collection of values to verify before a user can register
- * Separated from BitUser::verify so that import verification can
- * be processed with less rigor than user submitted requests
- */
- function preRegisterVerify( &$pParamHash ) {
- global $gBitSystem;
-
- $this->answerCaptcha( $pParamHash );
-
- // require passcode
- if( $gBitSystem->isFeatureActive( 'users_register_require_passcode' ) ) {
- if( $pParamHash["passcode"] != $gBitSystem->getConfig( "users_register_passcode",md5( $this->genPass() ) ) ) {
- $this->mErrors['passcode'] = 'Wrong passcode! You need to know the passcode to register at this site';
- }
- }
- return count($this->mErrors) == 0;
- }
-
- /**
- * verifyPasswordFormat
- *
- * @param array $pPassword
- * @param array $pPassword2
- * @access public
- * @return false on success, Error string on failure
- */
- function verifyPasswordFormat( $pPassword, $pPassword2=null ) {
- global $gBitSystem;
-
- $minPassword = $gBitSystem->getConfig( 'users_min_pass_length', 4 );
- if( strlen( $pPassword ) < $minPassword ) {
- return ( KernelTools::tra( 'Your password should be at least '.$minPassword.' characters long' ));
- }
- if( !empty( $pPassword2 ) && $pPassword != $pPassword2 ) {
- return( KernelTools::tra( 'The passwords do not match' ));
- }
- if( $gBitSystem->isFeatureActive( 'users_pass_chr_num' ) && ( !preg_match_all( "/[0-9]+/",$pPassword,$foo ) || !preg_match_all( "/[A-Za-z]+/",$pPassword,$foo ))) {
- return ( KernelTools::tra( 'Password must contain both letters and numbers' ));
- }
-
- return false;
- }
-
- /**
- * getSmtpResponse
- *
- * @param array $pConnect
- * @access public
- * @return bool true on success, false on failure - mErrors will contain reason for failure
- */
- function getSmtpResponse( &$pConnect ) {
- $out = "";
- while( 1 ) {
- $work = fgets( $pConnect, 1024 );
- $out .= $work;
- if( !preg_match( '/^\d\d\d-/',$work )) {
- break;
- }
- }
- return $out;
- }
-
- /**
- * verifyEmail
- *
- * @param array $pEmail
- * @return bool true on success, false on failure, or -1 if verifyMX had a connection failure - mErrors will contain reason for failure
- */
- public function verifyEmail( $pEmail , &$pErrors ) {
- global $gBitSystem;
-
- // check for existing user first, so root@localhost doesn't get attempted to re-register
- if( !empty( $this ) && is_object( $this ) && $this->userExists( [ 'email' => $pEmail ] ) ) {
- $pErrors['email'] = 'The email address "'.$pEmail.'" has already been registered.';
- // during install we have some <user>@localhost as email address. we won't cause problems on those
- } elseif( $pEmail == 'root@localhost' || $pEmail == 'guest@localhost' ) {
- // nothing to do
- } elseif( !validate_email_syntax( $pEmail ) ) {
- $pErrors['email'] = 'The email address '.$pEmail.' is invalid.';
- } elseif( $gBitSystem->isFeatureActive( 'users_validate_email' ) ) {
- $mxErrors = [];
- $ret = $this->verifyMX( $pEmail, $mxErrors ) ;
- if ($ret === false) {
- bit_error_log('INVALID EMAIL : '.$pEmail.' by '. $_SERVER['REMOTE_ADDR'] .' for '. $mxErrors['email']);
- $pErrors = array_merge( $pErrors, $mxErrors );
- }
- }
-
- if( !isset( $ret ) ) {
- $ret = ( count( $pErrors ) == 0 ) ;
- }
-
- return $ret;
- }
-
- /**
- * verifyAnonEmail
- *
- * @param array $pEmail
- * @return bool true on success, false on failure, or -1 if verifyMX had a connection failure - mErrors will contain reason for failure
- */
- public static function verifyAnonEmail( $pEmail , &$pErrors ) {
- global $gBitSystem;
-
- // check for existing user first, so root@localhost doesn't get attempted to re-register
- if( $pEmail == 'root@localhost' || $pEmail == 'guest@localhost' ) {
- // nothing to do
- } elseif( !validate_email_syntax( $pEmail ) ) {
- $pErrors['email'] = 'The email address "'.$pEmail.'" is invalid.';
- }
-
- if( !isset( $ret ) ) {
- $ret = ( count( $pErrors ) == 0 ) ;
- }
-
- return $ret;
- }
-
- /**
- * verifyMX
- *
- * @param array $pEmail
- * @param array $pValidate
- * @access public
- * @return bool true on success, false on failure - mErrors will contain reason for failure
- */
- function verifyMX( $pEmail, &$pErrors ) {
-
- global $gBitSystem, $gDebug;
-
- $HTTP_HOST=$_SERVER['SERVER_NAME'];
- $ret = false;
-
- if( validate_email_syntax( $pEmail ) ){
- list ( $Username, $domain ) = preg_split ("/@/",$pEmail);
- //checkdnsrr will check to see if there are any MX records for the domain
- if( !\KernelTools::is_windows() and checkdnsrr ( $domain, "MX" ) ) {
- \Bitweaver\bitdebug( "Confirmation : MX record for {$domain} exists." );
-
- $MXWeights = [];
-
- getmxrr ( $domain, $MXHost, $MXWeights );
- $hosts = [];
-
- //create an array that combines the MXWeights with their associated hosts
- for( $i = 0; $i < count( $MXHost ); $i++ ) {
- $hosts[$MXHost[$i]] = $MXWeights[$i];
- }
-
- //sorts the hosts by weight
- asort($hosts);
-
- if( !empty($hosts)) { //hosts shouldn't be empty here, since we passed the checkdnsrr check, but the server COULD have died between the first and second check.
- $Connect = '' ;
- foreach ($hosts as $host=>$priority){
-
- $Connect = @fsockopen ( $host, 25, $errNo, $errStr, 10 ); // 10 second timeout to open each MX server, seems adequate to me, increase as necessary
- // Success in fsockopen
-
- if( $Connect ) {
- bitdebug( "Connection succeeded to {$host} SMTP." );
-
- stream_set_timeout( $Connect, 30 );
- $out = $this->getSmtpResponse( $Connect );
-
- // Judgment is that a service preparing to begin a transaction will send a 220 string after a succesful handshake
- if( preg_match ( "/^220/", $out ) ) {
- // Inform client's reaching to server who connect.
- if( $gBitSystem->hasValidSenderEmail() ) {
- $senderEmail = $gBitSystem->getConfig( 'site_sender_email' );
- fputs( $Connect, "HELO $HTTP_HOST\r\n" );
- bitdebug( "Run : HELO $HTTP_HOST" );
- // Receive server's answering cord.
- $out = $this->getSmtpResponse( $Connect );
-
- // Inform sender's address to server.
- fputs ( $Connect, "MAIL FROM: <{$senderEmail}>\r\n" );
- bitdebug( "Run : MAIL FROM: &lt;{$senderEmail}&gt;" );
- // Receive server's answering cord.
- $from = $this->getSmtpResponse( $Connect );
-
- // Inform listener's address to server.
- fputs ( $Connect, "RCPT TO: <{$pEmail}>\r\n" );
- bitdebug( "Run : RCPT TO: &lt;{$pEmail}&gt;" );
- // Receive server's answering cord.
- $to = $this->getSmtpResponse( $Connect );
-
- // Finish connection.
- fputs( $Connect, "QUIT\r\n" );
- bitdebug( "Run : QUIT" );
- fclose( $Connect );
-
- //Checks if we received a 250 OK from the server. If we did not, the server is telling us that this address is not a valid mailbox.
- if( !preg_match ( "/^250/", $from ) || ( !preg_match ( "/^250/", $to ) && !preg_match( "/Please use your ISP relay/", $to ))) {
- $pErrors['email'] = $pEmail." is not recognized by the mail server. Try double checking the address for typos." ;
- bit_error_log("INVALID EMAIL : ".$pEmail." SMTP FROM : ".$from." SMTP TO: ".$to);
- $ret = false;
- break; //break out of foreach and fall through to the end of function
- }
- $ret = true;//address has been verified by the server, no more checking necessary
- break;
-
- }
- } elseif( preg_match ( "/^420/", $out ) ) {
- // Yahoo has a bad, bad habit of issuing 420's
- bit_error_log("UNKNOWN EMAIL : ".$pEmail." SMTP response: ".$out);
- $ret = true;
- } else {
- $pErrors['email'] = 'Connection rejected by MX server';
- bit_error_log("INVALID EMAIL : ".$pEmail." SMTP response: ".$out);
- $ret = false;
- }
- } else {
- //fsockopen failed
- if(!$gBitSystem->getConfig('users_validate_email_group')){ //will ONLY stuff mErrors if you have not set a default group for verifiable emails, otherwise this is not a game breaking case
- $pErrors['email'] = "One or more mail servers not responding";
- }
- $ret = -1; //-1 implies ambiguity, MX servers found, but unable to be reached.
- }
- }
- }else{
- $pErrors['email'] = "Mail server not found";
- $ret = false;
- }
- } else {
- $pErrors['email'] = "Mail server not found";
- $ret = false;
- }
- } else {
- $pErrors['email'] = "Invalid email syntax";
- $ret = false;
- }
- return $ret;
- }
-
- /**
- * register - will handle everything necessary for registering a user and sending appropriate emails, etc.
- *
- * @access public
- * @author Christian Fowler<spider@viovio.com>
- * @return bool true on success, false on failure
- */
- function register( &$pParamHash, $pNotifyRegistrant=true ) {
- global $notificationlib, $gBitSmarty, $gBitSystem;
- $ret = false;
- if( !empty( $_FILES['user_portrait_file'] ) && empty( $_FILES['user_avatar_file'] ) ) {
- $pParamHash['user_auto_avatar'] = true;
- }
- if( $this->verify( $pParamHash )) {
- for( $i = 0; $i < BaseAuth::getAuthMethodCount(); $i++ ) {
- $instance = BaseAuth::init( $i );
- if( $instance && $instance->canManageAuth() ) {
- if( $userId = $instance->createUser( $pParamHash )) {
- $this->mUserId = $userId;
- break;
- }
- $this->mErrors = array_merge( $this->mErrors, $instance->mErrors );
- return false;
-
- }
- }
-
- if( !empty( $pParamHash['verified_email'] ) && $pParamHash['verified_email'] && $gBitSystem->getConfig('users_validate_email_group') ) {
- $this->addUserToGroup( $this->mUserId, $gBitSystem->getConfig('users_validate_email_group') );
- }
-
- $this->mLogs['register'] = 'New user registered.';
- $ret = true;
-
- $this->load( false, $pParamHash['login'] );
-
- require_once( KERNEL_PKG_INCLUDE_PATH.'notification_lib.php' );
- $notificationlib->post_new_user_event( $pParamHash['login'] );
-
- // set local time zone as default when registering
- $this->storePreference( 'site_display_utc', 'Local' );
-
- if( !empty( $_REQUEST['CUSTOM'] ) ) {
- foreach( $_REQUEST['CUSTOM'] as $field=>$value ) {
- $this->storePreference( $field, $value );
- }
- }
-
- // Handle optional user preferences that may be collected during registration
- if( !empty( $pParamHash['prefs'] ) ) {
- foreach( array_keys( $pParamHash['prefs'] ) as $key ) {
- $this->storePreference( $key, $pParamHash['prefs'][$key] );
- }
- }
-
- // Send notification
- if( $pNotifyRegistrant ) {
- $siteName = $gBitSystem->getConfig('site_title', $_SERVER['HTTP_HOST'] );
- $gBitSmarty->assign( 'siteName',$_SERVER["SERVER_NAME"] );
- $gBitSmarty->assign( 'mail_site',$_SERVER["SERVER_NAME"] );
- $gBitSmarty->assign( 'mail_user',$pParamHash['login'] );
- if( $gBitSystem->isFeatureActive( 'users_validate_user' ) ) {
- // $apass = addslashes(substr(md5($gBitSystem->genPass()),0,25));
- $apass = $pParamHash['user_store']['provpass'];
- $foo = parse_url( $_SERVER["REQUEST_URI"] );
- $foo1 = str_replace( "register", "confirm", $foo["path"] );
- $machine = httpPrefix().$foo1;
-
- // Send the mail
- $gBitSmarty->assign( 'msg',KernelTools::tra( 'You will receive an email with information to login for the first time into this site' ));
- $gBitSmarty->assign( 'mail_machine',$machine );
- $gBitSmarty->assign( 'mailUserId',$this->mUserId );
- $gBitSmarty->assign( 'mailProvPass',$apass );
- $mail_data = $gBitSmarty->fetch( 'bitpackage:users/user_validation_mail.tpl' );
- mail( $pParamHash["email"], $siteName.' - '.KernelTools::tra( 'Your registration information' ), $mail_data, "From: ".$gBitSystem->getConfig('site_sender_email')."\nContent-type: text/plain;charset=utf-8\n" );
- $gBitSmarty->assign( 'showmsg', 'y' );
-
- $this->mLogs['confirm'] = 'Validation email sent.';
- } elseif( $gBitSystem->isFeatureActive( 'send_welcome_email' ) ) {
- // Send the welcome mail
- $gBitSmarty->assign( 'mailPassword',$pParamHash['password'] );
- $gBitSmarty->assign( 'mailEmail',$pParamHash['email'] );
- $mail_data = $gBitSmarty->fetch( 'bitpackage:users/welcome_mail.tpl' );
- mail( $pParamHash["email"], KernelTools::tra( 'Welcome to' ).' '.$siteName, $mail_data, "From: ".$gBitSystem->getConfig( 'site_sender_email' )."\nContent-type: text/plain;charset=utf-8\n" );
-
- $this->mLogs['welcome'] = 'Welcome email sent.';
- }
- }
- $logHash['action_log']['title'] = $pParamHash['login'];
- $this->storeActionLog( $logHash );
- }
- return( $ret );
- }
-
- /**
- * verifyCaptcha
- *
- * @param array $pCaptcha
- * @access public
- * @return bool true on success, false on failure
- */
- function verifyCaptcha( $pCaptcha = null ) {
- if( $this->hasPermission( 'p_users_bypass_captcha' ) || ( !empty( $_SESSION['captcha_verified'] ) && $_SESSION['captcha_verified'] === true ) ) {
- return true;
- }
- if( empty( $pCaptcha ) || empty( $_SESSION['captcha'] ) || $_SESSION['captcha'] != md5( $pCaptcha ) ) {
- return false;
- }
- $_SESSION['captcha_verified'] = true;
- return true;
-
- }
-
- /**
- * store
- *
- * @param array $pParamHash
- * @return bool true on success, false on failure - mErrors will contain reason for failure
- */
- public function store( array &$pParamHash): bool {
- if( $this->verify( $pParamHash ) ) {
- $this->StartTrans();
- $pParamHash['content_type_guid'] = BITUSER_CONTENT_TYPE_GUID;
-
- if( !empty( $pParamHash['user_store'] ) && count( $pParamHash['user_store'] ) ) {
- if( $this->isValid() ) {
- $userId = [ "user_id" => $this->mUserId ];
- $result = $this->mDb->associateUpdate( BIT_DB_PREFIX.'users_users', $pParamHash['user_store'], $userId );
- } else {
- if( empty( $pParamHash['user_store']['user_id'] ) ) {
- $pParamHash['user_store']['user_id'] = $this->mDb->GenID( 'users_users_user_id_seq' );
- }
- $this->mUserId = $pParamHash['user_store']['user_id'];
- $result = $this->mDb->associateInsert( BIT_DB_PREFIX.'users_users', $pParamHash['user_store'] );
- }
- }
-
- // Prevent liberty from assuming ANONYMOUS_USER_ID while storing
- $pParamHash['user_id'] = $this->mUserId;
- // Don't let LA snarf these now so we can do extra things.
- $pParamHash['_files_override'] = [];
- if( \Bitweaver\LibertyMime::store( $pParamHash ) ) {
-
- if( empty( $this->mInfo['content_id'] ) || ($pParamHash['content_id'] != $this->mInfo['content_id']) ) {
- $query = "UPDATE `".BIT_DB_PREFIX."users_users` SET `content_id`=? WHERE `user_id`=?";
- $result = $this->mDb->query( $query, [ $pParamHash['content_id'], $this->mUserId ] );
- $this->mInfo['content_id'] = $pParamHash['content_id'];
- }
- }
-
- $this->CompleteTrans();
-
- $this->load( true );
- }
- return( count( $this->mErrors ) == 0 );
- }
-
- /**
- * Imports a user record from csv file
- * This is a admin specific function
- *
- * @param $pParamHash an array with user data
- * @return bool true if import succeed
- **/
- function importUser( &$pParamHash ) {
- global $gBitUser;
-
- if( ! $gBitUser->hasPermission( 'p_users_admin' ) ) {
- return false;
- }
- if( $this->verifyUserImport( $pParamHash ) ) {
- $this->StartTrans();
- $pParamHash['content_type_guid'] = BITUSER_CONTENT_TYPE_GUID;
- if( !empty( $pParamHash['user_store'] ) && count( $pParamHash['user_store'] ) ) {
- // lookup and asign the default group for user
- $defaultGroups = $this->getDefaultGroup();
- if( !empty( $defaultGroups ) ) {
- $pParamHash['user_store']['default_group_id'] = key( $defaultGroups );
- }
- if( $this->isValid() ) {
- $userId = [ "user_id" => $this->mUserId ];
- $result = $this->mDb->associateUpdate( BIT_DB_PREFIX.'users_users', $pParamHash['user_store'], $userId );
- } else {
- if( empty( $pParamHash['user_store']['user_id'] ) ) {
- $pParamHash['user_store']['user_id'] = $this->mDb->GenID( 'users_users_user_id_seq' );
- }
- $this->mUserId = $pParamHash['user_store']['user_id'];
- $result = $this->mDb->associateInsert( BIT_DB_PREFIX.'users_users', $pParamHash['user_store'] );
- }
- // make sure user is added into the default group map
- if( !empty( $pParamHash['user_store']['default_group_id'] ) ) {
- $this->addUserToGroup( $pParamHash['user_store']['user_id'],$pParamHash['user_store']['default_group_id'] );
- }
-
- }
- // Prevent liberty from assuming ANONYMOUS_USER_ID while storing
- $pParamHash['user_id'] = $this->mUserId;
- if( parent::store( $pParamHash )) {
- if( empty( $this->mInfo['content_id'] ) || $pParamHash['content_id'] != $this->mInfo['content_id'] ) {
- $query = "UPDATE `".BIT_DB_PREFIX."users_users` SET `content_id`=? WHERE `user_id`=?";
- $result = $this->mDb->query( $query, [ $pParamHash['content_id'], $this->mUserId ] );
- $this->mInfo['content_id'] = $pParamHash['content_id'];
- }
- }
-
- $this->CompleteTrans();
-
- // store any uploaded images
- $this->storeImages( $pParamHash );
-
- $this->load( true );
- }
- return( count( $this->mErrors ) == 0 );
- }
-
- /**
- * Verify and validate the data when
- * importing a user record from csv file
- * This is a admin specific function
- *
- * @param $pParamHash an array with user data
- * @return bool true on success, false on failure - mErrors will contain reason for failure
- **/
- function verifyUserImport( &$pParamHash ) {
- global $gBitSystem, $gBitUser;
-
- if( ! $gBitUser->hasPermission( 'p_users_admin' ) ) {
- return false;
- }
-
- trim_array( $pParamHash );
-
- // perhaps someone is importing users and *knows* what they are doing
- if( $this->verifyIdParameter( $pParamHash, 'user_id' ) ) {
- // only import user_id if it doesn't exist or overwrite is set.
- if( !$this->userExists( [ 'user_id' => $pParamHash['user_id'] ] ) || !empty( $_REQUEST['overwrite'] ) ) {
- $pParamHash['user_store']['user_id'] = $pParamHash['user_id'];
- } else {
- unset( $pParamHash['user_id'] );
- }
- }
- if( !empty( $pParamHash['login'] ) ) {
- $ret = $this->userExists( [ 'login' => $pParamHash['login'] ] );
- if( !empty( $ret ) ) {
- // On batch import admin can overwrite existing user, so don't error if set
- // however, prevent overwrite of a mix of user records
- if( !empty( $_REQUEST['overwrite'] ) && (!isset($pParamHash['user_store']['user_id']) || $pParamHash['user_store']['user_id'] == $ret ) ) {
- $pParamHash['user_id'] = $ret;
- $pParamHash['user_store']['user_id'] = $pParamHash['user_id'];
- } else {
- $this->mErrors['login'] = 'The username "'.$pParamHash['login'].'" is already in use';
- }
- } elseif( preg_match( '/[^A-Za-z0-9_.-]/', $pParamHash["login"] ) ) {
- $this->mErrors['login'] = KernelTools::tra( "Your username can only contain numbers, characters, underscores and hyphens." );
- }
-
- if( !isset($this->mErrors['login']) ) {
- // LOWER CASE all logins
- $pParamHash['login'] = strtolower($pParamHash['login']);
- $pParamHash['user_store']['login'] = $pParamHash['login'];
- }
- } else {
- $this->mErrors['login'] = 'Value for username is missing';
- }
- if( !empty( $pParamHash['real_name'] ) ) {
- $pParamHash['user_store']['real_name'] = substr( $pParamHash['real_name'], 0, 64 );
- }
- if( !empty( $pParamHash['email'] ) ) {
- // LOWER CASE all emails admin_verify_email
- $pParamHash['email'] = strtolower( $pParamHash['email'] );
- if( validate_email_syntax( $pParamHash['email'] ) ) {
- $ret = $this->userExists( [ 'email' => $pParamHash['email'] ] );
- if( !empty($ret) ) {
- if( !empty( $_REQUEST['overwrite'] ) && (!isset($pParamHash['user_store']['user_id']) || $pParamHash['user_store']['user_id'] == $ret ) ) {
- $pParamHash['user_id'] = $ret;
- $pParamHash['user_store']['user_id'] = $pParamHash['user_id'];
- } else {
- $this->mErrors['email'] = 'The email address "'.$pParamHash['email'].'" has already been registered.';
- }
- }
- if( !empty( $_REQUEST['admin_verify_email'] ) ) {
- if( !$this->verifyMX( $pParamHash['email'] ) ) {
- $this->mErrors['email'] = 'Cannot find a valid mail server';
- }
- }
- if( !isset($this->mErrors['email']) ) {
- $pParamHash['user_store']['email'] = strtolower( substr( $pParamHash['email'], 0, 200 ) );
- }
- } else {
- $this->mErrors['email'] = 'The email address "'.$pParamHash['email'].'" has an invalid syntax.';
- }
- } else {
- $this->mErrors['email'] = KernelTools::tra( 'You must enter your email address' );
- }
-
- // check some new user requirements
- if( !$this->isRegistered() ) {
- if( isset($pParamHash['user_store']['user_id']) && !empty( $_REQUEST['overwrite'] ) ) {
- $this->mUserId = $this->userExists( [ 'user_id' => $pParamHash['user_store']['user_id'] ] );
- }
- if( empty( $pParamHash['registration_date'] ) ) {
- $pParamHash['registration_date'] = date( "U" );
- }
- $pParamHash['user_store']['registration_date'] = $pParamHash['registration_date'];
-
- if( !empty($pParamHash['hash'] ) ) {
- unset( $pParamHash['password'] );
- if( strlen( $pParamHash['hash'] ) <> 32 ) {
- $this->mErrors['password'] = KernelTools::tra( 'When importing a MD5 password hash it needto have a length of 32 bytes.' );
- }
- } else {
- if( !empty( $_REQUEST['admin_verify_user'] ) ) {
- $pParamHash['user_store']['provpass'] = md5(BitSystem::genPass());
- $pParamHash['user_store']['hash'] = '';
- $pParamHash['pass_due'] = 0;
- unset( $pParamHash['password'] );
- } elseif( empty($pParamHash['password'] ) ) {
- $pParamHash['password'] = $gBitSystem->genPass();
- }
- }
- } elseif( $this->isValid() ) {
- // Prevent loosing user info on save
- if( empty( $pParamHash['edit'] ) ) {
- $pParamHash['edit'] = $this->mInfo['data'];
- }
- }
-
- if( isset( $pParamHash['password'] ) ) {
- if (!$this->isValid() || isset($pParamHash['password']) ) {
- $passswordError = $this->verifyPasswordFormat( $pParamHash['password'] );
- }
- if( !empty( $passswordError ) ) {
- $this->mErrors['password'] = $passswordError;
- } else {
- // Generate a unique hash
- //$pParamHash['user_store']['hash'] = md5( strtolower( (!empty($pParamHash['login'])?$pParamHash['login']:'') ).$pPassword.$pParamHash['email'] );
- $pParamHash['user_store']['hash'] = md5( $pParamHash['password'] );
- $now = $gBitSystem->getUTCTime();
- if( !isset( $pParamHash['pass_due'] ) && $gBitSystem->getConfig('users_pass_due') ) {
- $pParamHash['user_store']['pass_due'] = $now + (60 * 60 * 24 * $gBitSystem->getConfig('users_pass_due') );
- } elseif( isset( $pParamHash['pass_due'] ) ) {
- // renew password only next half year ;)
- $pParamHash['user_store']['pass_due'] = $now + (60 * 60 * 24 * $pParamHash['pass_due']);
- }
- $pParamHash['user_store']['user_password'] = '';
- }
- } elseif( !empty( $pParamHash['hash'] )) {
- $pParamHash['user_store']['hash'] = $pParamHash['hash'];
- $now = $gBitSystem->getUTCTime();
- if( !isset( $pParamHash['pass_due'] ) && $gBitSystem->getConfig( 'users_pass_due' )) {
- $pParamHash['user_store']['pass_due'] = $now + ( 60 * 60 * 24 * $gBitSystem->getConfig( 'users_pass_due' ));
- } elseif( isset( $pParamHash['pass_due'] ) ) {
- // renew password only next half year ;)
- $pParamHash['user_store']['pass_due'] = $now + ( 60 * 60 * 24 * $pParamHash['pass_due'] );
- }
- }
- return ( count( $this->mErrors ) == 0 );
- }
-
- /**
- * expunge removes user and associated private data
- *
- * @access public
- * @return bool
- */
- public function expunge(): bool {
- global $gBitSystem;
- $this->invokeServices( 'users_expunge_check_function' );
- if( !empty( $this->mErrors['expunge_check'] ) ) {
- $this->mDb->RollbackTrans();
- } else {
- $this->StartTrans();
-
- if( !empty( $this->pExpungeContent ) ) {
- if( $this->pExpungeContent == 'all' ) {
- if( $userContent = $this->mDb->getAssoc( "SELECT content_id, content_type_guid FROM `".BIT_DB_PREFIX."liberty_content` WHERE `user_id`=? AND `content_type_guid` != 'bituser'", [ $this->mUserId ] ) ) {
- foreach( $userContent as $contentId=>$contentTypeGuid ) {
- if( $delContent = static::getLibertyObject( $contentId, $contentTypeGuid ) ) {
- $delContent->expunge();
- }
- }
- }
- }
- }
-
- if( $this->mUserId != ANONYMOUS_USER_ID ) {
- $this->purgeImage( 'avatar' );
- $this->purgeImage( 'portrait' );
- $this->purgeImage( 'logo' );
- $this->invokeServices( 'users_expunge_function' );
- $userTables = [
- 'users_cnxn',
- 'users_watches',
- 'users_favorites_map',
- 'users_auth_map',
- 'users_users',
- ];
- foreach( $userTables as $table ) {
- $query = "DELETE FROM `".BIT_DB_PREFIX.$table."` WHERE `user_id` = ?";
- $result = $this->mDb->query( $query, [ $this->mUserId ] );
- }
-
- parent::expunge();
-
- $logHash['action_log']['title'] = $this->mInfo['login'];
- $this->mLogs['user_del'] = 'User deleted';
- $this->storeActionLog( $logHash );
- $this->CompleteTrans();
- $this->clearFromCache();
-
- return true;
- }
- $this->mDb->RollbackTrans();
- $gBitSystem->fatalError( KernelTools::tra( 'The anonymous user cannot be deleted' ) );
-
- }
- return count( $this->mErrors ) === 0;
- }
-
- // {{{ ==================== Sessions and logging in and out methods ====================
- /**
- * updateSession
- *
- * @param array $pSessionId
- * @access public
- * @return bool true on success, false on failure - mErrors will contain reason for failure
- */
- protected function updateSession( $pSessionId ) {
- global $gLightWeightScan;
- if ( !$this->isDatabaseValid() ) return true;
- global $gBitSystem, $gBitUser;
- $update['last_get'] = $gBitSystem->getUTCTime();
- $update['current_view'] = $_SERVER['SCRIPT_NAME'];
-
- if( empty( $gLightWeightScan ) ) {
- $row = $this->mDb->getRow( "SELECT `last_get`, `connect_time`, `get_count`, `user_agent`, `current_view` FROM `".BIT_DB_PREFIX."users_cnxn` WHERE `cookie`=? ", [ $pSessionId ] );
- if( $gBitUser->isRegistered() ) {
- $update['user_id'] = $gBitUser->mUserId;
- }
- if( $row ) {
- if( empty( $row['ip'] ) || $row['ip'] != $_SERVER['REMOTE_ADDR'] ) {
- $update['ip'] = $_SERVER['REMOTE_ADDR'];
- }
- if( !empty( $_SERVER['HTTP_USER_AGENT'] ) && (empty( $row['user_agent'] ) || $row['user_agent'] != $_SERVER['HTTP_USER_AGENT']) ) {
- $update['user_agent'] = (string)substr( $_SERVER['HTTP_USER_AGENT'], 0, 128 );
- }
- $update['get_count'] = $row['get_count'] + 1;
- $ret = $this->mDb->associateUpdate( BIT_DB_PREFIX.'users_cnxn', $update, [ 'cookie' => $pSessionId ] );
- } else {
- if( $this->isRegistered() ) {
- $update['user_id'] = $this->mUserId;
- $update['ip'] = $_SERVER['REMOTE_ADDR'];
- // truncate length & cast substr to (string) to prevent insert fatals if substr returns false
- $update['user_agent'] = (string)substr( $_SERVER['HTTP_USER_AGENT'], 0, 128 );
- $update['get_count'] = 1;
- $update['connect_time'] = $update['last_get'];
- $update['cookie'] = $pSessionId;
- $result = $this->mDb->associateInsert( BIT_DB_PREFIX.'users_cnxn', $update );
- }
- }
- // Delete old connections nightly during the hour of 3 am
- // This needs moving to an event that is known to happen
- if( date( 'H' ) == '03' && date( 'i' ) > 0 && date( 'i' ) < 2 ) {
- // Default to 30 days history
- $oldy = $update['last_get'] - ($gBitSystem->getConfig( 'users_cnxn_history_days', 30 ) * 24 * 60 * 60);
- $query = "DELETE from `".BIT_DB_PREFIX."users_cnxn` where `connect_time` < ?";
- $result = $this->mDb->query($query, [$oldy]);
- }
- }
- return true;
- }
-
- /**
- * countSessions
- *
- * @param array $pActive
- * @access public
- * @return count of sessions
- */
- function countSessions( $pActive = false ) {
- $query = "SELECT COUNT(*) FROM `".BIT_DB_PREFIX."users_cnxn`";
- if( $pActive ) {
- $query .=" WHERE `cookie` IS NOT null";
- }
- return $this->mDb->getOne( $query,[] );
- }
-
- /**
- * logout
- *
- * @access public
- * @return void
- */
- function logout() {
- // This must come first
- $this->clearFromCache();
-
- $this->sendSessionCookie( false );
-
- session_destroy();
- $this->mUserId = null;
- // ensure Guest default page is loaded if required
- $this->mInfo['default_group_id'] = -1;
- }
-
- protected function sendSessionCookie( $pCookie=true ) {
- global $gBitSystem;
-
- $siteCookie = static::getSiteCookieName();
- $cookieTime = 0;
- $cookiePath = BIT_ROOT_URL;
- $cookieDomain = '';
-
- if( $pCookie === true ) {
- $pCookie = session_id();
- } elseif( $pCookie==false ) {
- $pCookie = ''; // unset the cookie, eg logout
- if( !empty( $_COOKIE[$siteCookie] ) ) {
- $this->mDb->query( "UPDATE `".BIT_DB_PREFIX."users_cnxn` SET `cookie`=null WHERE `cookie`=?", [ $_COOKIE[$siteCookie] ] );
- unset( $_COOKIE[$siteCookie] );
- }
- }
-
- if( !empty( $pCookie ) ) {
- // Now if the remember me feature is on and the user checked the user_remember_me checkbox then ...
- if( $gBitSystem->isFeatureActive( 'users_remember_me' ) && isset( $_REQUEST['rme'] ) && $_REQUEST['rme'] == 'on' ) {
- $cookieTime = (int)( time() + (int)$gBitSystem->getConfig( 'users_remember_time', 86400 ));
- $cookiePath = $gBitSystem->getConfig( 'cookie_path', $cookiePath );
- $cookieDomain = $gBitSystem->getConfig( 'cookie_domain', $cookieDomain );
- }
- }
- setcookie( $siteCookie, $pCookie, $cookieTime , $cookiePath, $cookieDomain );
- $_COOKIE[$siteCookie] = $pCookie;
- }
-
- public static function getSiteCookieName() {
- global $gBitSystem;
-
- $cookieName = (is_object( $gBitSystem ) ? $gBitSystem->getConfig( 'site_title', 'bitweaver' ) : 'bitweaver');
- $cookie_site = strtolower( preg_replace( "/[^a-zA-Z0-9]/", "", $cookieName) );
- return( 'bit-user-'.$cookie_site );
- }
-
- /**
- * verifyTicket
- *
- * @param array $pFatalOnError
- * @param array $pForceCheck
- * @access public
- * @return bool true on success, false on failure - mErrors will contain reason for failure
- */
- function verifyTicket( $pFatalOnError=true, $pForceCheck=true ) {
- global $gBitSystem, $gBitUser;
- $ret = false;
- if( $pForceCheck == true || !empty( $_REQUEST['tk'] ) ) {
- if( empty( $_REQUEST['tk'] ) || (!($ret = $_REQUEST['tk'] == $this->mTicket ) && $pFatalOnError) ) {
- $userString = $gBitUser->isRegistered() ? "\nUSER ID: ".$gBitUser->mUserId.' ( '.$gBitUser->getField( 'email' ).' ) ' : '';
- error_log( KernelTools::tra( "Security Violation" )."$userString ".$_SERVER['REMOTE_ADDR']."\nURI: $_SERVER[REQUEST_URI] \nREFERER: $_SERVER[HTTP_REFERER] " );
- $gBitSystem->fatalError( KernelTools::tra( "Security Violation" ));
- }
- }
- return $ret;
- }
- // }}}
-
- // {{{ ==================== Banning ====================
- /**
- * ban sets the user account status to -201 suspended
- *
- * @access public
- * @return bool true on success, Display error message on failure
- */
- function ban(){
- global $gBitSystem;
- if( $this->mUserId == ANONYMOUS_USER_ID || $this->mUserId == ROOT_USER_ID || $this->isAdmin()) {
- $gBitSystem->fatalError( KernelTools::tra( 'You cannot ban the user' )." ".$this->mInfo['login'] );
- } else {
- $this->storeStatus( -201 );
- return true;
- }
- }
-
- /**
- * ban unban the user
- *
- * @access public
- * @return bool true on success
- */
- function unban(){
- global $gBitSystem;
- $this->storeStatus( 50 );
- return true;
- }
- // }}}
-
- /**
- * genPass generate random password
- *
- * @param array $pLength Length of final password
- * @access public
- * @return password
- */
- public static function genPass( $pLength=null ) {
- global $gBitSystem;
- $vocales = "AaEeIiOoUu13580";
- $consonantes = "BbCcDdFfGgHhJjKkLlMmNnPpQqRrSsTtVvWwXxYyZz24679";
- $ret = '';
- if( empty( $pLength ) || !is_numeric( $pLength ) ) {
- $pLength = $gBitSystem->getConfig( 'users_min_pass_length', 16 );
- }
- for( $i = 0; $i < $pLength; $i++ ) {
- if( $i % 2 ) {
- $ret .= $vocales[rand( 0, strlen( $vocales ) - 1 )];
- } else {
- $ret .= $consonantes[rand( 0, strlen( $consonantes ) - 1 )];
- }
- }
- return $ret;
- }
-
- /**
- * generateChallenge
- *
- * @access public
- * @return md5 string
- */
- function generateChallenge() {
- return( md5( \Bitweaver\BitSystem::genPass() ));
- }
-
- /**
- * login
- *
- * @param array $pLogin
- * @param array $pPassword
- * @param array $pChallenge
- * @param array $pResponse
- * @access public
- * @return URL the user should be sent to after login
- */
- function login( $pLogin, $pPassword, $pChallenge=null, $pResponse=null ) {
- global $gBitSystem;
- $isvalid = false;
-
- $loginCol = strpos( $pLogin, '@' ) ? 'email' : 'login';
-
- $this->StartTrans();
- // Verify user is valid
- if( $this->validate( $pLogin, $pPassword, $pChallenge, $pResponse )) {
- $userInfo = $this->getUserInfo( [ $loginCol => $pLogin ]);
-
- // If the password is valid but it is due then force the user to change the password by
- // sending the user to the new password change screen without letting him use
- // The user must re-nter the old password so no secutiry risk here
- if( $this->isPasswordDue() ) {
- // Redirect the user to the screen where he must change his password.
- // Note that the user is not logged in he's just validated to change his password
- // The user must re-enter his old password so no secutiry risk involved
- $url = USERS_PKG_URL.'change_password.php?user_id='.$userInfo['user_id'];
-
- } elseif( $userInfo['user_id'] != ANONYMOUS_USER_ID ) {
- // User is valid and not due to change pass..
- $this->mUserId = $userInfo['user_id'];
- $this->load();
- $this->loadPermissions( true );
-
- $url = $this->getPostLoginUrl();
-
- $this->setUserSession();
- }
- } else {
- // before we give up lets see if the user exists and if the password is expired
- $query = "select `email`, `user_id`, `user_password` from `".BIT_DB_PREFIX."users_users` where " . $this->mDb->convertBinary(). " $loginCol = ?";
- $result = $this->mDb->getRow( $query, [ $pLogin ] );
- if( !empty( $result['user_id'] ) && $this->isPasswordDue( $result['user_id'] ) ) {
- // user needs email password reset so send it and let them know
- $url = USERS_PKG_URL.'remind_password.php?remind=y&required=y&username='.$pLogin;
- }else{
- $this->mUserId = ANONYMOUS_USER_ID;
- $this->mInfo = [];
- $this->clearFromCache();
- $this->mErrors['login'] = KernelTools::tra( 'Invalid username or password' );
- $url = USERS_PKG_URL.'signin.php?error=' . urlencode( $this->mErrors['login'] );
- }
- }
- $this->CompleteTrans();
-
- // check for HTTPS mode and redirect back to non-ssl when not requested, or a SSL login was forced
- if( isset( $_SERVER['HTTPS'] ) && strtolower( $_SERVER['HTTPS'] ) == 'on' ) {
- $refererSsl = isset( $_SERVER['HTTP_REFERER'] ) && substr( $_SERVER['HTTP_REFERER'], 0, 5 ) == 'https';
- if( ($gBitSystem->getConfig( 'site_https_login_required' ) && !$refererSsl) ) {
- // start setting up the URL redirect without SSL
- $prefix = 'http://' . $gBitSystem->getConfig( 'site_http_domain', $_SERVER['HTTP_HOST'] );
-
- // add port to prefix if needed
- $port = $gBitSystem->getConfig( 'site_http_port', 80 );
- if( $port != 80 ) {
- $prefix .= ':'.$port;
- }
- $prefix .= $gBitSystem->getConfig( 'site_http_prefix', BIT_ROOT_URL );
- if( strrpos( $prefix, '/' ) == (strlen( $prefix ) - 1) ) {
- $prefix = substr( $prefix, 0, strlen( $prefix ) - 1 );
- }
- // join prefix and URL
- $url = $prefix.$url;
- }
- }
- return( $url );
- }
-
- public function getPostLoginUrl() {
- global $gBitSystem;
- $url = BIT_ROOT_URL;
- if( $this->isRegistered() ) {
- // set post-login url
- // if group home is set for this user we get that
- // default to general post-login
- // @see \Bitweaver\BitSystem::getIndexPage
- $indexType = 'my_page';
- // getGroupHome is BitPermUser method
- if( method_exists( $this, 'getGroupHome' ) &&
- (( @$this->verifyId( $this->mInfo['default_group_id'] ) && ( $group_home = $this->getGroupHome( $this->mInfo['default_group_id'] ) ) ) ||
- ( $gBitSystem->getConfig( 'default_home_group' ) && ( $group_home = $this->getGroupHome( $gBitSystem->getConfig( 'default_home_group' ) ) ) )) ){
- $indexType = 'group_home';
- }
-
- $url = $_SESSION['loginfrom'] ?? $gBitSystem->getIndexPage( $indexType );
- unset( $_SESSION['loginfrom'] );
- }
- return $url;
- }
- public function setUserSession() {
- if( $this->isRegistered() ) {
- $sessionId = session_id();
- $this->sendSessionCookie( $sessionId );
- $this->updateSession( $sessionId );
- }
- }
-
- /**
- * validate
- *
- * @param array $pUser
- * @param array $pPass
- * @param array $pChallenge
- * @param array $pResponse
- * @access public
- * @return bool true on success, false on failure - mErrors will contain reason for failure
- * @todo rewrite this mess. this is horrible stuff. - xing - Thursday Oct 16, 2008 09:47:20 CEST
- */
- function validate( $pUser, $pPass, $pChallenge, $pResponse ) {
- global $gBitSystem;
- // these will help us keep tabs of what is going on
- $authValid = $authPresent = false;
- $createAuth = ( $gBitSystem->getConfig( "users_create_user_auth", "n" ) == "y" );
-
- for( $i = 0; $i < BaseAuth::getAuthMethodCount(); $i++ ) {
- $instance = BaseAuth::init( $i );
- if( $instance ) {
- $result = $instance->validate( $pUser, $pPass, $pChallenge, $pResponse );
- switch( $result ) {
- case USER_VALID:
- unset($this->mErrors['login']);
- $authPresent = true;
- $authValid = true;
- break;
- case PASSWORD_INCORRECT:
- // this mErrors assignment is CRUCIAL so that bit auth fails properly. DO NOT FUCK WITH THIS unless you know what you are doing and have checked with me first. XOXOX - spiderr
- // This might have broken other auth, but at this point, bw auth was TOTALLY busted. If you need to fix, please come find me.
- $this->mErrors['login'] = 'Password incorrect';
- $authPresent = true;
- break;
- case USER_NOT_FOUND:
- break;
- }
-
- if( $authValid ) {
- if( empty( $instance->mInfo['email'] )) {
- $instance->mInfo['email'] = $pUser;
- }
-
- //If we're given a user_id then the user is already in the database:
- if( !empty( $instance->mInfo['user_id'] )) {
- $this->mUserId = $instance->mInfo['user_id'];
-
- //Is the user already in the database:
- } elseif( $this->mDb->getOne( "SELECT COUNT(*) FROM `".BIT_DB_PREFIX."users_users` WHERE `login` = ?", [ $instance->mLogin ]) > 0 ) {
- // Update Details
- $authUserInfo = [
- 'login' => $instance->mInfo['login'],
- 'password' => $instance->mInfo['password'],
- 'real_name' => $instance->mInfo['real_name'],
- 'email' => $instance->mInfo['email'],
- ];
- $userInfo = $this->getUserInfo( [ 'login' => $pUser ]);
- $this->mUserId = $userInfo['user_id'];
- $this->store( $authUserInfo );
- $this->mErrors = [];
-
- } else {
- $authUserInfo = [
- 'login' => $instance->mInfo['login'],
- 'password' => $instance->mInfo['password'],
- 'real_name' => $instance->mInfo['real_name'],
- 'email' => $instance->mInfo['email'],
- ];
- // TODO somehow, mUserId gets set to -1 at this point - no idea how
- // set to null to prevent overwriting Guest user - wolff_borg
- $this->mUserId = null;
- $this->store( $authUserInfo );
- }
-
- if( $createAuth && $i > 0 ) {
- // if the user was logged into this system and we should progate users down other auth methods
- for( $j = $i; $i >= 0; $j-- ) {
- $probMethodName = $gBitSystem->getConfig( "users_auth_method_$j", $default ?? false );
- if( !empty( $probMethodName )) {
- $probInstance = BaseAuth::init( $probMethodName );
- if( $probInstance && $probInstance->canManageAuth() ) {
- $result = $probInstance->validate( $pUser, $pPass, $pChallenge, $pResponse );
- if( $result == USER_VALID || $result == PASSWORD_INCORRECT ) {
- // see if we can create a new account
- $userattr = $instance->getUserData();
- if( empty( $userattr['login'] )) {
- $userattr['login'] = $pUser;
- }
- if( empty( $userattr['password'] )) {
- $userattr['password'] = $pPass;
- }
- $probInstance->createUser( $userattr );
- }
- }
- $this->mErrors = array_merge( $this->mErrors, $probInstance->mErrors );
- }
- }
- }
- $this->mAuth = $instance;
- break;
- }
- $this->mErrors = array_merge( $this->mErrors,$instance->mErrors );
- }
- }
- if( $this->mUserId != ANONYMOUS_USER_ID ) {
- $this->load();
- //on first time login we run the users registation service
- if( empty( $this->mInfo['last_login'] ) ) {
- $this->invokeServices( 'users_register_function' );
- }
- $this->updateLastLogin( $this->mUserId );
- }
- return( count( $this->mErrors ) == 0 );
- }
-
- /**
- * updateLastLogin
- *
- * @param array $pUserId
- * @access public
- * @return bool true on success, false on failure - mErrors will contain reason for failure
- */
- function updateLastLogin( $pUserId ) {
- $ret = false;
- if( @$this->verifyId( $pUserId ) ) {
- global $gBitSystem;
- $query = "UPDATE `".BIT_DB_PREFIX."users_users` SET `last_login` = `current_login`, `current_login` = ? WHERE `user_id` = ?";
- $result = $this->mDb->query( $query, [ $gBitSystem->getUTCTime(), $pUserId ]);
- $ret = true;
- }
- return $ret;
- }
-
- /**
- * confirmRegistration
- *
- * @param array $pUserId
- * @param array $pProvpass
- * @access public
- * @return registered user, empty array on failure
- */
- function confirmRegistration( $pUserId, $pProvpass ) {
- global $gBitSystem;
- $query = "
- SELECT `user_id`, `provpass`, `user_password`, `login`, `email` FROM `".BIT_DB_PREFIX."users_users`
- WHERE `user_id`=? AND `provpass`=? AND ( `provpass_expires` IS null OR `provpass_expires` > ?)";
- return( $this->mDb->getRow( $query, [ (int)$pUserId, $pProvpass, $gBitSystem->getUTCTime() ]));
- }
-
- /**
- * changeUserEmail
- *
- * @param array $pUserId
- * @param array $pEmail
- * @access public
- * @return bool true on success, false on failure - mErrors will contain reason for failure
- */
- function changeUserEmail( $pUserId, $pEmail ) {
- if( !validate_email_syntax( $pEmail ) ) {
- $this->mErrors['bad_mail'] = KernelTools::tra( "The email address provided does not have recognised valid syntax." );
- } elseif( $this->userExists( [ 'email' => $pEmail ])) {
- $this->mErrors['duplicate_mail'] = KernelTools::tra( "The email address you selected already exists." );
- } else {
- $query = "UPDATE `".BIT_DB_PREFIX."users_users` SET `email`=? WHERE `user_id`=?";
- $result = $this->mDb->query( $query, [ $pEmail, $pUserId ] );
- $query = "UPDATE `".BIT_DB_PREFIX."users_watches` SET `email`=? WHERE `user_id`=?";
- $result = $this->mDb->query( $query, [ $pEmail, $pUserId ] );
-
- // update value in hash
- $this->mInfo['email'] = $pEmail;
- }
- return( count( $this->mErrors ) == 0 );
- }
-
- /**
- * lookupHomepage
- *
- * @param array $iHomepage
- * @access public
- * @return user_id that can be used to point to users homepage
- */
- function lookupHomepage( $iHomepage ) {
- $ret = null;
- if( @$this->verifyId( $iHomepage )) {
- // iHomepage is the user_id for the user...
- $key = 'user_id';
- // force to proper integer to get things like "007." to properly query
- $iHomepage = (int)$iHomepage;
- } elseif( substr( $iHomepage, 0, 7 ) == 'mailto:' ) {
- // iHomepage is the email address of the user...
- $key = 'email';
- } else {
- // iHomepage is the 'login' of the user...
- $key = 'login';
- }
- $tmpUser = $this->getUserInfo( [ $key => $iHomepage ]);
- if( @$this->verifyId( $tmpUser['user_id'] )) {
- $ret = $tmpUser['user_id'];
- }
- return $ret;
- }
-
- /**
- * getUserPreference
- *
- * @param string $pPrefName
- * @param string $pPrefDefault
- * @param int $pUserId
- * @return string|null
- */
- public static function getUserPreference( string $pPrefName, string $pPrefDefault, int $pUserId ) {
- // Alternate to LibertyContent::getPreference when all you have is a user_id and a pref_name, and you need a value...
- global $gBitDb;
- $ret = null;
-
- if( \Bitweaver\BitBase::verifyId( $pUserId ) ) {
- $query = "
- SELECT lcp.`pref_value` FROM `".BIT_DB_PREFIX."liberty_content_prefs` lcp INNER JOIN `".BIT_DB_PREFIX."users_users` uu ON (lcp.`content_id`=uu.`content_id`)
- WHERE uu.`user_id` = ? AND lcp.`pref_name` = ?";
- if( !$ret = $gBitDb->getOne( $query, [ $pUserId, $pPrefName ])) {
- $ret = $pPrefDefault;
- }
- }
- return $ret;
- }
-
- /**
- * getUserInfo will fetch the user info of a given user
- *
- * @param array $pUserMixed hash key can be any column in users_users table e.g.: 'login', 'user_id', 'email', 'content_id'
- * @access public
- * @return user info on success, null on failure
- */
- public static function getUserInfo( $pUserMixed ) {
- global $gBitDb;
- $ret = null;
- if( is_array( $pUserMixed ) ) {
- if( $val = current( $pUserMixed ) ) {
- $key = $gBitDb->sanitizeColumnString( key( $pUserMixed ) );
- if( preg_match( '/_id$/', $key ) ) {
- $col = " uu.`".$key."` ";
- $val = (int)$val;
- if( $val > 0x1FFFFFFF ) {
- // 32 bit overflow, set to zero to avoid fatal error in databases with 32 bit signed integer columns
- $val = 0;
- }
- } elseif( is_numeric( $val ) ) {
- $col = " uu.`".$key."` ";
- $val = $val;
- } else {
- $col = "UPPER( uu.`".$key."` ) ";
- $val = strtoupper( $val );
- }
- if( !empty( $col ) ) {
- $query = "SELECT uu.* FROM `".BIT_DB_PREFIX."users_users` uu LEFT OUTER JOIN `".BIT_DB_PREFIX."liberty_content` lc ON (lc.`content_id`=uu.`content_id`) WHERE $col = ?";
- $ret = $gBitDb->getRow( $query, [ $val ], 600 );
- }
- }
- }
- return $ret;
- }
-
- /**
- * isUserPublic Determine if an arbitrary user can be viewed by non-permissioned users.
- *
- * @param array $pUserId user_id of user to query visibility, if null will use this object
- * @access public
- * @return bool if user is publically visible
- */
- function isUserPrivate( $pUserId=null ) {
- $infoPref = null;
- if( \Bitweaver\BitBase::verifyId( $pUserId ) ) {
- $infoPref = BitUser::getUserPreference( 'users_information', null, $pUserId );
- } elseif( isset( $this ) && $this->isValid() ) {
- $infoPref = $this->getPreference( 'users_information' );
- }
-
- return $infoPref == 'private';
- }
-
- /**
- * getByHash get user from cookie hash
- *
- * @param array $pParamHash
- * @access public
- * @return user info
- */
- function getUserIdFromCookieHash( $pParamHash ) {
- $query = "SELECT `user_id` FROM `".BIT_DB_PREFIX."users_cnxn` WHERE `cookie` = ?";
- return $this->mDb->getOne( $query, [ $pParamHash ]);
- }
-
- /**
- * isPasswordDue work out if a user has to change their password
- *
- * @access public
- * @return bool true when the password is due, false if it isn't, null when no due time is set
- * @note null password due means *no* expiration
- */
- function isPasswordDue( $pUserId = null ) {
- global $gBitSystem;
- $ret = false;
- if( empty( $pUserId) && $this->isRegistered() ) {
- $pUserId = $this->mUserId;
- }
- if( !empty( $pUserId ) ){
- // get user_id to avoid null and zero confusion
- $query = "
- SELECT `user_id`, `pass_due`
- FROM `".BIT_DB_PREFIX."users_users`
- WHERE `pass_due` IS NOT null AND `user_id`=? ";
- $due = $this->mDb->getRow( $query, [ $pUserId ] );
- if( @$this->verifyId( $due['user_id'] ) && !empty( $due['pass_due'] ) ) {
- $ret = $due['pass_due'] <= $gBitSystem->getUTCTime();
- }
- }
- return $ret;
- }
-
- /**
- * createTempPassword
- *
- * @param array $pLogin
- * @param array $pPass
- * @access public
- * @return bool true on success, false on failure - mErrors will contain reason for failure
- */
- function createTempPassword( $pLogin, $pPass ) {
- global $gBitSystem;
- $ret = [ '', '' ];
-
- if( empty( $pLogin ) ) {
- $pLogin = $this->getField( 'email' );
- }
-
- if( !empty( $pLogin )) {
- $pass = \Bitweaver\BitSystem::genPass();
- $provpass = md5( $pass );
- $loginCol = strpos( $pLogin, '@' ) ? 'email' : 'login';
-
- #temp passwords good for 3 days -- prob should be an config option
- $passDue = $gBitSystem->getUTCTime() + ( 60 * 60 * 24 * 3 );
- $query = "UPDATE `".BIT_DB_PREFIX."users_users` SET `provpass` = ?, `provpass_expires` = ? WHERE `".$loginCol."` = ?";
- $result = $this->mDb->query( $query, [ $provpass, $passDue, $pLogin ]);
- $ret = [ $pass, $provpass ];
- }
- return $ret;
- }
-
- /**
- * storePassword
- *
- * @param array $pPass
- * @param array $pLogin
- * @access public
- * @return bool true on success, false on failure - mErrors will contain reason for failure
- */
- function storePassword( $pPass, $pLogin=null ) {
- global $gBitSystem;
- $ret = false;
-
- if( empty( $pLogin ) ) {
- $pLogin = $this->getField( 'email' );
- }
-
- if( !empty( $pLogin )) {
- $ret = true;
- $hash = md5( $pPass );
- // if renew password config is set then set - otherwise set null to respect no pass due
- $passDue = null;
- if( $gBitSystem->getConfig('users_pass_due') ) {
- $now = $gBitSystem->getUTCTime();;
- // renew password according to config value
- $passDue = $now + ( 60 * 60 * 24 * $gBitSystem->getConfig( 'users_pass_due' ));
- }
- $pPass = null;
- $loginCol = strpos( $pLogin, '@' ) ? 'email' : 'login';
- $query = "UPDATE `".BIT_DB_PREFIX."users_users` SET `provpass`= null, `provpass_expires` = null,`hash`=? ,`user_password`=? ,`pass_due`=? WHERE `".$loginCol."`=?";
- $result = $this->mDb->query( $query, [ $hash, $pPass, $passDue, $pLogin ]);
- }
- return $ret;
- }
-
- /**
- * getUserActivity
- *
- * @param array $pListHash
- * @access public
- * @return array of users and what they have been up to
- */
- function getUserActivity( &$pListHash ) {
- $bindVars = [];
- if( empty( $pListHash['sort_mode'] ) ) {
- $pListHash['sort_mode'] = 'last_get_desc';
- }
- LibertyContent::prepGetList( $pListHash );
-
- $whereSql = '';
- if( !empty( $pListHash['last_get'] ) ) {
- $whereSql .= ' AND uc.`last_get` > ? ';
- $bindVars[] = time() - $pListHash['last_get'];
- }
-
- if( \Bitweaver\BitBase::verifyId( $pListHash['user_id'] ?? 0 ) ) {
- $whereSql .= ' AND uc.`user_id` = ? ';
- $bindVars[] = $pListHash['user_id'];
- }
-
- if( !empty( $pListHash['ip'] ) ) {
- $ips = mb_split( ',', $pListHash['ip'] );
- $ipList = '';
- do {
- $ip = array_pop( $ips );
- if( !empty( $ipList ) ) {
- $ipList .= ", ";
- }
- $ipList .= "'$ip'";
- } while( $ips );
- $whereSql .= ' AND (uc.`ip` IN ('.$ipList.') OR lc.`ip` IN ('.$ipList.'))';
- }
-
- if( !empty( $pListHash['online'] ) ) {
- $whereSql .= ' AND uc.`cookie` IS NOT null ';
- }
-
- $query = "
- SELECT DISTINCT uc.`user_id`, `login`, `real_name`, `connect_time`, uc.`ip`, `user_agent`, `last_get`, uu.`content_id`
- FROM `".BIT_DB_PREFIX."users_users` uu
- INNER JOIN `".BIT_DB_PREFIX."liberty_content` lc ON (uu.`content_id` = lc.`content_id`)
- LEFT JOIN `".BIT_DB_PREFIX."users_cnxn` uc ON (uc.`user_id` = uu.`user_id`)
- WHERE uu.`user_id` IS NOT null $whereSql
- ORDER BY ".$this->mDb->convertSortmode( $pListHash['sort_mode'] );
- $result = $this->mDb->query( $query, $bindVars, $pListHash['max_records'], $pListHash['offset'] );
- $ret = [];
- while( $res = $result->fetchRow() ) {
- $res['users_information'] = $this->getPreference( 'users_information', 'public', $res['content_id'] );
- $ret[] = $res;
- }
-
- $countSql = "
- SELECT COUNT( uc.`user_id` )
- FROM `".BIT_DB_PREFIX."users_users` uu
- INNER JOIN `".BIT_DB_PREFIX."liberty_content` lc ON (uu.`content_id` = lc.`content_id`)
- LEFT JOIN `".BIT_DB_PREFIX."users_cnxn` uc ON (uc.`user_id` = uu.`user_id`)
- WHERE uc.`user_id` IS NOT null $whereSql";
- $pListHash['cant'] = $this->mDb->GetOne( $countSql, $bindVars );
- $this->postGetList( $pListHash );
- return $ret;
- }
-
- /**
- * getUserDomain
- *
- * @param array $pLogin
- * @access public
- * @return bool true on success, false on failure - mErrors will contain reason for failure
- */
- function getUserDomain( $pLogin ) {
- $ret = [];
- if( $pLogin == $this->getField( 'login' ) && $this->getPreference( 'domain_style' ) ) {
- $ret = $this->mInfo;
- $ret['style'] = $this->getPreference( 'domain_style' );
- } else {
- $sql = "
- SELECT uu.*, lcp.`pref_value` AS `style`
- FROM `".BIT_DB_PREFIX."users_users` uu
- INNER JOIN `".BIT_DB_PREFIX."liberty_content_prefs` lcp ON( uu.`content_id` = lcp.`content_id` )
- WHERE uu.`login` = ? AND lcp.`pref_name` = ?";
- $ret = $this->mDb->getRow( $sql, [ $pLogin, 'domain_style' ] );
- }
- return( $ret );
- }
-
- /**
- * getDomain
- *
- * @param array $pContentId
- * @access public
- * @return bool true on success, false on failure - mErrors will contain reason for failure
- */
- function getDomain( $pContentId ) {
- $ret = [];
- if( $this->verifyId( $pContentId ) ) {
- $ret['content_id'] = $pContentId;
- $ret['style'] = $this->mDb->getOne( "SELECT `pref_value` FROM `".BIT_DB_PREFIX."liberty_content_prefs` WHERE `content_id`=? AND `pref_name`=?", [ $pContentId, 'domain_style' ]);
- }
- return( $ret );
- }
-
- /**
- * canCustomizeTheme check if a user can customise their theme
- *
- * @access public
- * @return bool true on success, false on failure
- */
- function canCustomizeTheme() {
- global $gBitSystem;
- return( $this->hasPermission( 'p_tidbits_custom_home_theme' ) || $gBitSystem->getConfig( 'users_themes' ) == 'y' || $gBitSystem->getConfig( 'users_themes' ) == 'h' || $gBitSystem->getConfig( 'users_themes' ) == 'u' );
- }
-
- /**
- * canCustomizeLayout check if a user can customise their layout
- *
- * @access public
- * @return bool true on success, false on failure
- */
- function canCustomizeLayout() {
- global $gBitSystem;
- return( $this->hasPermission( 'p_tidbits_custom_home_layout' ) || $gBitSystem->getConfig( 'users_layouts' ) == 'y' || $gBitSystem->getConfig( 'users_layouts' ) == 'h' || $gBitSystem->getConfig( 'users_layouts' ) == 'u' );
- }
-
- // {{{ ==================== image and file functions ====================
- /**
- * getThumbnailUrl
- *
- * @param string $pSize
- * @param array $pInfoHash
- * @access public
- * @return bool true on success, false on failure - mErrors will contain reason for failure
- */
- function getThumbnailUrl( string $pSize = 'small', ?array $pInfoHash = null, ?int $pSecondaryId = null, ?int $pDefault = null ): string|null {
- $ret = '';
- if( $pInfoHash ) {
- // do some stuff if we are passed a hash-o-crap, not implemented currently
- } elseif( $this->isValid() ) {
- $ret = $this->getField( 'avatar_url' );
- }
- return $ret;
- }
-
- /**
- * storeImages will store any user images - please note that uploaded files have to be in predefined keys in $_FILES
- * $_FILES['user_portrait_file']
- * $_FILES['user_auto_avatar']
- * $_FILES['user_logo_file']
- *
- * @param array $pParamHash array of options
- * @param boolean $pParamHash['user_auto_avatar'] automatically create avatar from portrait
- * @access public
- * @return bool true on success, false on failure - mErrors will contain reason for failure
- */
- function storeImages( $pParamHash ) {
- if( isset( $_FILES['user_portrait_file'] ) && is_uploaded_file( $_FILES['user_portrait_file']['tmp_name'] ) && $_FILES['user_portrait_file']['size'] > 0 ) {
- $portraitHash = $pParamHash;
- $portraitHash['user_id'] = $this->mUserId;
- $portraitHash['content_id'] = $this->mContentId;
- $portraitHash['upload'] = $_FILES['user_portrait_file'];
- $portraitHash['upload']['source_file'] = $_FILES['user_portrait_file']['tmp_name'];
- $this->storePortrait( $portraitHash, !empty( $portraitHash['user_auto_avatar'] ));
- }
-
- if( isset( $_FILES['user_avatar_file'] ) && is_uploaded_file( $_FILES['user_avatar_file']['tmp_name'] ) && $_FILES['user_avatar_file']['size'] > 0 ) {
- $avatarHash = $pParamHash;
- $avatarHash['user_id'] = $this->mUserId;
- $avatarHash['content_id'] = $this->mContentId;
- $avatarHash['upload'] = $_FILES['user_avatar_file'];
- $avatarHash['upload']['source_file'] = $_FILES['user_avatar_file']['tmp_name'];
- $this->storeAvatar( $avatarHash );
- }
-
- if( isset( $_FILES['user_logo_file'] ) && is_uploaded_file( $_FILES['user_logo_file']['tmp_name'] ) && $_FILES['user_logo_file']['size'] > 0 ) {
- $logoHash = $pParamHash;
- $logoHash['user_id'] = $this->mUserId;
- $logoHash['content_id'] = $this->mContentId;
- $logoHash['upload'] = $_FILES['user_logo_file'];
- $logoHash['upload']['source_file'] = $_FILES['user_logo_file']['tmp_name'];
- $this->storeLogo( $logoHash );
- }
- }
-
- /**
- * storePortrait
- *
- * @param array $pStorageHash
- * @param array $pGenerateAvatar
- * @access public
- * @return bool true on success, false on failure - mErrors will contain reason for failure
- */
- function storePortrait( &$pStorageHash, $pGenerateAvatar = false ) {
- if( $this->isValid() && count( $pStorageHash )) {
- // make a copy before the uploaded file disappears
- if( $pGenerateAvatar ) {
- $avatarHash = $pStorageHash;
- $avatarHash['upload']['tmp_name'] = $pStorageHash['upload']['tmp_name'].'.av';
- copy( $pStorageHash['upload']['tmp_name'], $pStorageHash['upload']['tmp_name'].'.av' );
- }
-
- if( $this->storeUserImage( $pStorageHash, 'portrait' ) && $pGenerateAvatar ) {
- $this->storeAvatar( $avatarHash );
- // nuke copy of image
- @unlink( $pStorageHash['upload']['tmp_name'].'.av' );
- }
- }
-
- return( count( $this->mErrors ) == 0 );
- }
-
- /**
- * storeAvatar
- *
- * @param array $pStorageHash
- * @access public
- * @return bool true on success, false on failure - mErrors will contain reason for failure
- */
- function storeAvatar( &$pStorageHash ) {
- return( $this->storeUserImage( $pStorageHash, 'avatar' ));
- }
-
- /**
- * storeLogo
- *
- * @param array $pStorageHash
- * @access public
- * @return bool true on success, false on failure - mErrors will contain reason for failure
- */
- function storeLogo( &$pStorageHash ) {
- return( $this->storeUserImage( $pStorageHash, 'logo' ));
- }
-
- /**
- * storeUserImage
- *
- * @param array $pStorageHash
- * @param string $pType
- * @access public
- * @return bool true on success, false on failure - mErrors will contain reason for failure
- */
- function storeUserImage( &$pStorageHash, $pType = 'portrait' ) {
- if( $this->isValid() && count( $pStorageHash ) ) {
- // don't do the content thing
- $pStorageHash['skip_content_store'] = true;
-
- // setup the hash for central storage functions
- $pStorageHash['no_perm_check'] = true;
- $pStorageHash['_files_override'][$pType] = $pStorageHash['upload'];
- $pStorageHash['_files_override'][$pType]['max_width'] = constant( strtoupper( $pType )."_MAX_DIM" );
- $pStorageHash['_files_override'][$pType]['max_height'] = constant( strtoupper( $pType )."_MAX_DIM" );
- $pStorageHash['_files_override'][$pType]['attachment_id'] = !empty( $this->mInfo["{$pType}_attachment_id"] ) ? $this->mInfo["{$pType}_attachment_id"] : null;
- $pStorageHash['_files_override'][$pType]['user_id'] = $this->mUserId;
- if( \Bitweaver\LibertyMime::store( $pStorageHash )) {
- $file = $pStorageHash['upload_store']['files'][$pType];
- if( empty( $this->mInfo["{$pType}_attachment_id"] ) || $this->mInfo["{$pType}_attachment_id"] != $file['attachment_id'] ) {
- $query = "UPDATE `".BIT_DB_PREFIX."users_users` SET `{$pType}_attachment_id` = ? WHERE `user_id`=?";
- $result = $this->mDb->query( $query, [ $file['attachment_id'], $this->mUserId ] );
- $this->mInfo["{$pType}_attachment_id"] = $file['attachment_id'];
- $pStorageHash["{$pType}_file_name"] = $file['upload']['dest_branch'];
- }
- } else {
- $this->mErrors["{$pType}_file"] = 'File '.$pStorageHash['upload_store']['files'][$pType]['name'].' could not be stored.';
- }
- }
- return( count( $this->mErrors ) == 0 );
- }
-
- /**
- * purgeImage
- *
- * @param string $pType
- * @access public
- * @return bool true on success, false on failure - mErrors will contain reason for failure
- */
- function purgeImage( $pType ) {
- if( $this->isValid() && @$this->verifyId( $this->mInfo[$pType.'_attachment_id'] ) ) {
- $this->StartTrans();
- $query = "UPDATE `".BIT_DB_PREFIX."users_users` SET `".$pType."_attachment_id` = null WHERE `user_id`=?";
- $result = $this->mDb->query( $query, [ $this->mUserId ] );
- if( $this->expungeAttachment( $this->getField( $pType.'_attachment_id' ) ) ) {
- unset( $this->mInfo[$pType.'_file_name'] );
- unset( $this->mInfo[$pType.'_attachment_id'] );
- unset( $this->mInfo[$pType.'_url'] );
- }
- $this->CompleteTrans();
- return true;
- }
- }
-
- /**
- * purgePortrait
- *
- * @access public
- * @return bool true on success, false on failure
- */
- function purgePortrait() {
- return $this->purgeImage( 'portrait' );
- }
-
- /**
- * purgeAvatar
- *
- * @access public
- * @return bool true on success, false on failure
- */
- function purgeAvatar() {
- return $this->purgeImage( 'avatar' );
- }
-
- /**
- * purgeLogo
- *
- * @access public
- * @return bool true on success, false on failure
- */
- function purgeLogo() {
- return $this->purgeImage( 'logo' );
- }
- // }}}
-
- // {{{ ==================== Watches ====================
- // TODO: clean up all watch functions. these are old and messy. - xing - Thursday Oct 16, 2008 11:07:55 CEST
- /**
- * storeWatch
- *
- * @param array $pEvent
- * @param array $pObject
- * @param array $pType
- * @param array $pTitle
- * @param array $pUrl
- * @access public
- * @return bool true on success, false on failure
- */
- function storeWatch( $pEvent, $pObject, $pType, $pTitle, $pUrl ) {
- global $userlib;
- if( $this->isValid() ) {
- $hash = md5( uniqid( '.' ));
- $query = "DELETE FROM `".BIT_DB_PREFIX."users_watches` WHERE `user_id`=? AND `event`=? AND `object`=?";
- $this->mDb->query($query,[ $this->mUserId, $pEvent, $pObject ] );
- $query = "INSERT INTO `".BIT_DB_PREFIX."users_watches`(`user_id` ,`event` ,`object` , `email`, `hash`, `watch_type`, `title`, `url`) VALUES(?,?,?,?,?,?,?,?)";
- $this->mDb->query( $query, [ $this->mUserId, $pEvent, $pObject, $this->mInfo['email'], $hash, $pType, $pTitle, $pUrl ] );
- return true;
- }
- }
-
- /**
- * getWatches
- *
- * @param string $pEvent
- * @access public
- * @return bool true on success, false on failure
- */
- function getWatches( $pEvent = '' ) {
- $ret = null;
- if( $this->isValid() ) {
- $mid = '';
- $bindvars=[ $this->mUserId ];
- if ($pEvent) {
- $mid = " and `event`=? ";
- $bindvars[]=$pEvent;
- }
-
- $query = "select * from `".BIT_DB_PREFIX."users_watches` where `user_id`=? $mid";
- $result = $this->mDb->query($query,$bindvars);
- $ret = [];
-
- while ($res = $result->fetchRow()) {
- $ret[] = $res;
- }
- }
- return $ret;
- }
-
- /**
- * getEventWatches
- *
- * @param array $pEvent
- * @param array $object
- * @access public
- * @return bool true on success, false on failure
- */
- function getEventWatches( $pEvent, $pObject ) {
- $ret = null;
- if( $this->isValid() ) {
- $query = "SELECT * FROM `".BIT_DB_PREFIX."users_watches` WHERE `user_id`=? AND `event`=? AND `object`=?";
- $result = $this->mDb->query($query,[ $this->mUserId, $pEvent, $pObject ] );
- if ( $result->numRows() ) {
- $ret = $result->fetchRow();
- }
- }
- return $ret;
- }
-
- /**
- * get_event_watches
- *
- * @param array $pEvent
- * @param array $pObject
- * @access public
- * @return bool true on success, false on failure
- */
- function get_event_watches( $pEvent, $pObject ) {
- $ret = [];
-
- $query = "select * from `".BIT_DB_PREFIX."users_watches` tw INNER JOIN `".BIT_DB_PREFIX."users_users` uu ON ( tw.`user_id`=uu.`user_id` ) where `event`=? and `object`=?";
- $result = $this->mDb->query( $query,[ $pEvent,$pObject ]);
-
- if( !$result->numRows() ) {
- return $ret;
- }
-
- while ($res = $result->fetchRow()) {
- $ret[] = $res;
- }
-
- return $ret;
- }
-
- /**
- * remove_user_watch_by_hash
- *
- * @param array $pParamHash
- * @access public
- * @return bool true on success, false on failure
- */
- function remove_user_watch_by_hash( $pParamHash ) {
- $query = "DELETE FROM `".BIT_DB_PREFIX."users_watches` WHERE `hash`=?";
- $this->mDb->query( $query,[ $pParamHash ]);
- }
-
- /**
- * expungeWatch
- *
- * @param array $pEvent
- * @param array $pObject
- * @access public
- * @return bool true on success, false on failure
- */
- function expungeWatch( $pEvent, $pObject ) {
- if( $this->isValid() ) {
- $query = "DELETE FROM `".BIT_DB_PREFIX."users_watches` WHERE `user_id`=? AND `event`=? AND `object`=?";
- $this->mDb->query( $query, [ $this->mUserId, $pEvent, $pObject ]);
- }
- }
-
- /**
- * get_watches_events
- *
- * @access public
- * @return bool true on success, false on failure
- */
- function get_watches_events() {
- $query = "select distinct `event` from `".BIT_DB_PREFIX."users_watches`";
- $result = $this->mDb->query($query,[]);
- $ret = [];
- while ($res = $result->fetchRow()) {
- $ret[] = $res['event'];
- }
- return $ret;
- }
- // }}}
-
- /**
- * getUserAttachments
- *
- * @param array $pListHash
- * @access public
- * @return list of attachments
- */
- function getUserAttachments( &$pListHash ) {
- $pListHash['user_id'] = $this->mUserId;
- $mime = new LibertyMime();
- return $mime->getAttachmentList( $pListHash );
- }
-
- // {{{ ==================== Favorites ====================
- /**
- * storeFavorite
- *
- * @param array $pContentId
- * @access public
- * @return bool true on success, false on failure
- */
- function storeFavorite( $pContentId ) {
- $ret = false;
- if( $this->isValid() && $this->verifyId( $pContentId )) {
- if( !$this->hasFavorite( $pContentId ) ){
- $this->mDb->query( "INSERT INTO `".BIT_DB_PREFIX."users_favorites_map` ( `user_id`, `favorite_content_id` ) VALUES (?,?)", [ $this->mUserId, $pContentId ] );
- }
- $ret = true;
- }
- return( $ret );
- }
-
- function expungeFavorite( $pContentId ) {
- $ret = false;
- if( $this->isValid() && $this->verifyId( $pContentId ) ) {
- $this->mDb->query( "DELETE FROM `".BIT_DB_PREFIX."users_favorites_map` WHERE `user_id`=? AND `favorite_content_id`=?", [ $this->mUserId, $pContentId ] );
- $ret = true;
- }
- return( $ret );
- }
-
- function hasFavorite( $pContentId ) {
- $ret = false;
- $rslt = $this->mDb->getOne( "SELECT `favorite_content_id` FROM `".BIT_DB_PREFIX."users_favorites_map` WHERE `user_id`=? AND `favorite_content_id`=?", [ $this->mUserId, $pContentId ] );
- if( !is_null( $rslt ) ){
- $ret = true;
- }
- return $ret;
- }
-
- /**
- * getFavorites
- *
- * @see LibertyContent::getContentList
- * @return Array of content data
- */
- function getFavorites(){
- $ret = null;
- if( $this->isRegistered() ){
- $listHash['join_sql'] = " INNER JOIN `".BIT_DB_PREFIX."users_favorites_map` ufm ON (ufm.favorite_content_id=lc.content_id AND ufm.user_id=".$this->mUserId.") ";
- $listHash['user_favs'] = true;
- $listHash['order_table'] = 'ufm.';
- $listHash['sort_mode'] = 'map_position_desc';
- $ret = $this->getContentList( $listHash );
- }
- return $ret;
- }
- // }}}
-
- /**
- * getUserId
- *
- * @access public
- * @return user id of currently loaded user
- */
- function getUserId() {
- return $this->isValid() ? $this->mUserId : ANONYMOUS_USER_ID;
- }
-
- /**
- * getDisplayUrlFromHash
- *
- * @param array $pUserName
- * @param array $pParamHash
- * @access public
- * @return URL to users homepage
- */
- public static function getDisplayUrlFromHash( &$pParamHash ) {
- if( function_exists( 'override_user_url' ) ) {
- $ret = override_user_url( $pParamHash );
- } else {
- global $gBitSystem;
-
- $rewrite_tag = $gBitSystem->isFeatureActive( 'pretty_urls_extended' ) ? 'view/':'';
-
- if ($gBitSystem->isFeatureActive( 'pretty_urls' )
- || $gBitSystem->isFeatureActive( 'pretty_urls_extended' ) ) {
- $ret = USERS_PKG_URL . $rewrite_tag;
- $ret .= urlencode( $pParamHash['login'] );
- } else {
- $ret = USERS_PKG_URL . 'index.php?home=';
- $ret .= urlencode( $pParamHash['login'] );
- }
- }
- return $ret;
- }
-
- /**
- * getDisplayLink
- *
- * @param array $pUserName
- * @param array $pDisplayHash
- * @access public
- * @return get a link to the the users homepage
- */
- public static function getDisplayLinkFromHash( &$pParamHash, $pLinkText=null, $pAnchor=null ) {
- return BitUser::getDisplayNameFromHash( $pParamHash, true );
- }
-
- /**
- * getTitle
- *
- * @param array $pParamHash
- * @access public
- * @return string get the users display name
- */
- public static function getTitleFromHash( &$pParamHash, $pDefault=true ) {
- return BitUser::getDisplayNameFromHash( $pParamHash );
- }
-
- /**
- * Get user information for a particular user
- *
- * @param array pParamHash todo - need explanation on how to use this...
- * @param bool pUseLink return the information in the form of a url that links to the users information page
- * @return string display name or link to user information page
- **/
- public static function getDisplayNameFromHash( $pParamHash, $pUseLink=false ) {
- global $gBitSystem, $gBitUser;
- if( !empty( $pParamHash )) {
- if( !empty( $pParamHash['real_name'] ) && $gBitSystem->getConfig( 'users_display_name', 'real_name' ) == 'real_name' ) {
- $displayName = $pParamHash['real_name'];
- } elseif( !empty( $pParamHash['user'] )) {
- $displayName = $pParamHash['user'];
- } elseif( !empty( $pParamHash['login'] )) {
- $displayName = $pParamHash['login'];
- } elseif( !empty( $pParamHash['email'] )) {
- $displayName = substr( $pParamHash['email'], 0, strpos( $pParamHash['email'], '@' ));
- } else {
- $displayName = $pParamHash['user_id'];
- }
-
- if( !empty( $pParamHash['user'] )) {
- $iHomepage = $pParamHash['user'];
- } elseif( !empty( $pParamHash['login'] )) {
- // user of 'login' is deprecated and eventually should go away!
- $iHomepage = $pParamHash['login'];
- } elseif( \Bitweaver\BitBase::verifyId( $pParamHash['user_id'] )) {
- $iHomepage = $pParamHash['user_id'];
- } elseif( !empty( $pParamHash['email'] )) {
- $iHomepage = $pParamHash['email'];
- } else {
- // this won't work right now, we need to alter userslib::interpret_home() to interpret a real name
- $iHomepage = $pParamHash['real_name'];
- }
-
- if( empty( $pParamHash['users_information'] ) && !empty( $pParamHash['login'] ) ) {
- $pParamHash['users_information'] = $gBitSystem->mDb->getOne( "SELECT pref_value FROM liberty_content_prefs lcp INNER JOIN users_users uu ON (lcp.content_id=uu.content_id) WHERE uu.login=? AND pref_name='users_information'", [ $pParamHash['login'] ], 1, null, 86400 );
- }
-
- $ret = ( $pUseLink && ( $gBitUser->hasPermission( 'p_users_view_user_homepage' ) || $pParamHash['users_information'] == 'public' ) ) ? '<a class="username" title="' . ( !empty( $pParamHash['link_title'] ) ? $pParamHash['link_title'] : KernelTools::tra( 'Profile for' ) . ' ' . htmlspecialchars( $displayName ) )
- . '" href="' . BitUser::getDisplayUrlFromHash( $pParamHash ) . '">'
- . htmlspecialchars( $pParamHash['link_label'] ?? $displayName )
- . '</a>' : htmlspecialchars( $displayName );
- }
- else {
- $ret = KernelTools::tra( "Anonymous" );
- }
-
- return $ret;
- }
-
- /**
- * Get user information for a particular user
- *
- * @param pUseLink return the information in the form of a url that links to the users information page
- * @param pParamHash todo - need explanation on how to use this...
- * @return display name or link to user information page
- **/
- function getDisplayName( $pUseLink=false ) {
- return static::getDisplayNameFromHash( $this->mInfo, $pUseLink );
- }
-
- /**
- * getRenderFile Returns include file that will
- *
- * @access public
- * @return the fully specified path to file to be included
- */
- function getRenderFile() {
- return USERS_PKG_INCLUDE_PATH.'display_bituser_inc.php';
- }
-
- /**
- * getSelectionList get a list of users that can be used in dropdown lists in forms to choose from
- *
- * @access public
- * @return bool true on success, false on failure - mErrors will contain reason for failure
- */
- function getSelectionList() {
- $query = "
- SELECT uu.`user_id`, uu.`login`, uu.`real_name`
- FROM `".BIT_DB_PREFIX."users_users` uu
- ORDER BY uu.`login`";
- $result = $this->mDb->query( $query );
- $ret = [];
- while( $res = $result->fetchRow()) {
- $ret[$res['user_id']] = $res['login'].(( !empty( $res['real_name'] ) && $res['real_name'] != $res['login'] ) ? ' - '.$res['real_name'] : '' );
- }
-
- return $ret;
- }
-
- /**
- * getList get a list of users
- *
- * @param array $pParamHash
- * @access public
- * @return array of users
- */
- function getList( &$pParamHash ) {
- global $gBitSystem, $gBitUser;
- if( empty( $pParamHash['sort_mode'] )) {
- $pParamHash['sort_mode'] = 'registration_date_desc';
- }
-
- LibertyContent::prepGetList( $pParamHash );
-
- $selectSql = $joinSql = $whereSql = '';
- $bindVars = [ 'bituser' ];
- $this->getServicesSql( 'content_list_sql_function', $selectSql, $joinSql, $whereSql, $bindVars, null, $pParamHash );
-
- // limit search to users with a specific language
- if( !empty( $pParamHash['lang_code'] ) ) {
- $joinSql .= " INNER JOIN `".BIT_DB_PREFIX."liberty_content_prefs` lcp ON ( lcp.`content_id`=uu.`content_id` AND lcp.`pref_name`='bitlanguage' )";
- $whereSql .= " AND lcp.`pref_value`=? ";
- $bindVars[] = $pParamHash['lang_code'];
- }
-
- if( !$gBitUser->hasPermission( 'p_users_admin' ) ) {
- $joinSql .= " LEFT OUTER JOIN `".BIT_DB_PREFIX."liberty_content_prefs` lcp2 ON ( lcp2.`content_id`=uu.`content_id` AND lcp2.`pref_name`='users_information' )";
- $whereSql .= " AND (lcp2.`pref_value` IS null OR lcp2.`pref_value`='public')";
- }
-
- // limit search to users with a specific IP
- if( !empty( $pParamHash['ip'] ) ) {
- $joinSql .= " LEFT OUTER JOIN `".BIT_DB_PREFIX."users_cnxn` uc ON ( uu.`user_id`=uc.`user_id`) ";
- $ips = mb_split( ',', $pParamHash['ip'] );
- $ipList = '';
- do {
- $ip = array_pop( $ips );
- if( !empty( $ipList ) ) {
- $ipList .= ", ";
- }
- $ipList .= "'$ip'";
- } while( $ips );
- $whereSql .= ' AND (uc.`ip` IN ('.$ipList.') OR lc.`ip` IN ('.$ipList.'))';
- }
-
- // limit to registrations over a time period like 'YYYY-MM-DD' or 'Y \Week W' or anything convertible by SQLDate
- if( !empty( $pParamHash['period'] ) ) {
- $sqlPeriod = $this->mDb->SQLDate( $this->mDb->getPeriodFormat( $pParamHash['period'] ), $this->mDb->SQLIntToTimestamp( 'registration_date' ));
- $whereSql .= ' AND '.$sqlPeriod.'=?';
- $bindVars[] = $pParamHash['timeframe'];
- }
-
- // lets search for a user
- if ( $pParamHash['find'] ) {
- $whereSql .= " AND ( UPPER( uu.`login` ) LIKE ? OR UPPER( uu.`real_name` ) LIKE ? OR UPPER( uu.`email` ) LIKE ? ) ";
- $bindVars[] = '%'.strtoupper( $pParamHash['find'] ).'%';
- $bindVars[] = '%'.strtoupper( $pParamHash['find'] ).'%';
- $bindVars[] = '%'.strtoupper( $pParamHash['find'] ).'%';
- }
-
- if( $gBitSystem->isPackageActive( 'stats' ) ) {
- $joinSql .= " LEFT OUTER JOIN `".BIT_DB_PREFIX."stats_referer_users_map` srum ON (srum.`user_id`=uu.`user_id`)
- LEFT OUTER JOIN `".BIT_DB_PREFIX."stats_referer_urls` sru ON (srum.`referer_url_id`=sru.`referer_url_id`)";
- $selectSql .= ", sru.`referer_url`";
- if( !empty( $pParamHash['referer'] ) ) {
- if( $pParamHash['referer'] == 'none' ) {
- $whereSql .= " AND `referer_url` IS null";
- } else {
- $whereSql .= " AND `referer_url` LIKE ?";
- $bindVars[] = '%'.strtolower( $pParamHash['find'] ).'%';
- }
- }
- }
-
- // Return an array of users indicating name, email, last changed pages, versions, last_login
- $query = "
- SELECT uu.*, lc.`content_status_id`, lf_ava.`file_name` AS `avatar_file_name`, lf_ava.`mime_type` AS `avatar_mime_type`, la_ava.`attachment_id` AS `avatar_attachment_id` $selectSql
- FROM `".BIT_DB_PREFIX."users_users` uu
- INNER JOIN `".BIT_DB_PREFIX."liberty_content` lc ON (uu.`content_id`=lc.`content_id`)
- $joinSql
- LEFT OUTER JOIN `".BIT_DB_PREFIX."liberty_content_hits` lch ON ( lc.`content_id` = lch.`content_id` )
- LEFT OUTER JOIN `".BIT_DB_PREFIX."liberty_attachments` la_ava ON ( uu.`avatar_attachment_id`=la_ava.`attachment_id` )
- LEFT OUTER JOIN `".BIT_DB_PREFIX."liberty_files` lf_ava ON ( lf_ava.`file_id`=la_ava.`foreign_id` )
- WHERE lc.`content_type_guid` = ? $whereSql ORDER BY ".$this->mDb->convertSortmode( $pParamHash['sort_mode'] );
- $result = $this->mDb->query( $query, $bindVars, $pParamHash['max_records'], $pParamHash['offset'] );
-
- $ret = [];
- while( $res = $result->fetchRow() ) {
- // Used for pulling out dead/empty/spam accounts
- if( isset( $pParamHash['max_content_count'] ) && is_numeric( $pParamHash['max_content_count'] ) ) {
- $contentCount = $this->mDb->getOne( "SELECT COUNT(*) FROM `".BIT_DB_PREFIX."liberty_content` lc INNER JOIN `".BIT_DB_PREFIX."users_users` uu ON ( lc.`user_id`=uu.`user_id` ) WHERE uu.`user_id`=? AND `content_type_guid` != 'bituser'", [ $res['user_id'] ] );
- if( $contentCount > $pParamHash['max_content_count'] ) {
- continue;
- }
- }
-
- // Used for pulling out non-idle accounts or pigs
- if( isset( $pParamHash['min_content_count'] ) && is_numeric( $pParamHash['min_content_count'] ) ) {
- $contentCount = $this->mDb->getOne( "SELECT COUNT(*) FROM `".BIT_DB_PREFIX."liberty_content` lc INNER JOIN `".BIT_DB_PREFIX."users_users` uu ON ( lc.`user_id`=uu.`user_id` ) WHERE uu.`user_id`=? AND `content_type_guid` != 'bituser'", [ $res['user_id'] ] );
- if( $contentCount < $pParamHash['min_content_count'] ) {
- continue;
- }
- }
-
- if( !empty( $res['referer_url'] )) {
- if ( $gBitSystem->isPackageActive('stats') ) {
- $res['short_referer_url'] = \Bitweaver\Stats\stats_referer_display_short($res['referer_url']);
- }
- }
- if( !empty( $res['avatar_file_name'] )) {
- $res['avatar_url'] = $this->getSourceUrl( [ 'attachment_id'=>$res['avatar_attachment_id'], 'mime_type'=>$res['avatar_mime_type'], 'file_name'=>$res['avatar_file_name'] ] );
- $res['thumbnail_url'] = \Bitweaver\Liberty\liberty_fetch_thumbnail_url( [
- 'source_file' => $this->getSourceFile( [ 'sub_dir'=>$res['avatar_attachment_id'], 'user_id' => $res['user_id'], 'file_name'=>$res['avatar_file_name'], 'mime_type'=>$res['avatar_mime_type'], 'package'=>\Bitweaver\Liberty\liberty_mime_get_storage_sub_dir_name( [ 'mime_type'=>$res['avatar_mime_type'], 'name'=>$res['avatar_file_name'] ] ) ] ),
- 'file_name' => $res['avatar_url'],
- // TODO: Make this a preference
- 'size' => 'avatar',
- ] );
- }
- $res["groups"] = $this->getGroups( $res['user_id'] );
- $ret[$res['user_id']] = $res;
- }
- $retval = [];
-
- $query = "
- SELECT COUNT(*) FROM `".BIT_DB_PREFIX."users_users` uu
- INNER JOIN `".BIT_DB_PREFIX."liberty_content` lc ON (uu.`content_id`=lc.`content_id`) $joinSql
- WHERE lc.`content_type_guid` = ? $whereSql";
- $pParamHash["cant"] = $this->mDb->getOne( $query, $bindVars );
-
- LibertyContent::postGetList( $pParamHash );
-
- return $ret;
- }
-
- /**
- * getGroups
- *
- * @param array $pUserId
- * @param array $pForceRefresh
- * @access public
- * @return bool true on success, false on failure - mErrors will contain reason for failure
- */
- function getGroups( $pUserId=null, $pForceRefresh = false ) {
- $pUserId = !empty( $pUserId ) ? $pUserId : $this->mUserId;
- if( !isset( $this->cUserGroups[$pUserId] ) || $pForceRefresh ) {
- $query = "
- SELECT ug.`group_id`, ug.`group_name`, ug.`user_id` as group_owner_user_id
- FROM `".BIT_DB_PREFIX."users_groups_map` ugm INNER JOIN `".BIT_DB_PREFIX."users_groups` ug ON (ug.`group_id`=ugm.`group_id`)
- WHERE ugm.`user_id`=? OR ugm.`group_id`=".ANONYMOUS_GROUP_ID;
- $ret = $this->mDb->getAssoc( $query, [( int )$pUserId ]);
- if( $ret ) {
- foreach( array_keys( $ret ) as $groupId ) {
- $res = [];
- foreach( $res as $key=>$val) {
- $ret[$key] = [ 'group_name' => $val ];
- }
- }
- }
- // cache it
- $this->cUserGroups[$pUserId] = $ret;
- return $ret;
- }
- return $this->cUserGroups[$pUserId];
-
- }
-
- /**
- * isValid
- *
- * @access public
- * @return bool true if user is loaded
- */
- function isValid() {
- return ( $this->verifyId( $this->mUserId ) );
- }
-
- /**
- * isAdmin "PURE VIRTUAL BASE FUNCTION";
- *
- * @access public
- * @return false
- */
- function isAdmin() {
- return false;
- }
-
- /**
- * isRegistered
- *
- * @access public
- * @return bool true if user is registered, false otherwise
- */
- function isRegistered() {
- return ( $this->mUserId > ANONYMOUS_USER_ID );
- }
-
- /**
- * verifyRegistered
- *
- * @access public
- * @return bool true if user is registered, otherwise a login dialog is displayed
- */
- function verifyRegistered( $pMsg = "" ) {
- global $gBitSystem;
- if( !$this->isRegistered() ) {
- $gBitSystem->fatalPermission( "", $pMsg );
- }
- return true;
- }
-
- /**
- * userExists
- *
- * @param array $pUserMixed
- * @access public
- * @return bool true on success, false on failure
- */
- function userExists( $pUserMixed ) {
- $ret = false;
- if (is_array( $pUserMixed )) {
- if ($cur = current( $pUserMixed )) {
- $conditionSql = ( is_numeric( $cur ) ) ? " `" . key( $pUserMixed ) . "` " : " UPPER(`" . key( $pUserMixed ) . "`)";
- $query = "SELECT `user_id` FROM `".BIT_DB_PREFIX."users_users` WHERE $conditionSql = ?";
- $ret = $this->mDb->getOne( $query, [ strtoupper( $cur ) ] );
- }
- }
- return $ret;
- }
-
- /**
- * Create an export hash from the data
- *
- * @access public
- * @return export data
- */
- function exportHash() {
- global $gBitSystem;
- $ret = [];
-
- if( $this->isValid() ) {
- $ret = parent::exportHash();
- $ret['login'] = $this->getField( 'login' );
- $ret['user_id'] = $this->mUserId;
- $ret['content_id'] = $this->mContentId;
- $ret['real_name'] = $this->getField( 'real_name' );
- $ret['email'] = $this->getField( 'email' );
- $ret['display_uri'] = $this->getDisplayUri();
- $ret['registration_date'] = date( DateTime::W3C, $this->getField('registration_date') );
- $ret['last_login'] = date( DateTime::W3C, $this->getField('last_login') );
- $ret['content_count'] = get_user_content_count( $this->mUserId );
- $ret['avatar_uri'] = BIT_BASE_URI.$this->getField( 'avatar_url' );
- $ret['avatar_url'] = $this->getField( 'avatar_url' );
- if( $gBitSystem->isPackageActive( 'stats' ) ) {
- $ret['referer'] = $this->mDb->getOne( "SELECT sru.`referer_url` FROM `".BIT_DB_PREFIX."stats_referer_urls` sru INNER JOIN `".BIT_DB_PREFIX."stats_referer_users_map` srum ON (srum.`referer_url_id`=sru.`referer_url_id`) WHERE `user_id`=?", $this->mUserId );
- }
- $ret['ips'] = implode( ',', $this->mDb->getCol( "SELECT DISTINCT(`ip`) FROM `".BIT_DB_PREFIX."users_cnxn` uc WHERE `user_id`=?", $this->mUserId ) );
- }
-
- return $ret;
- }
-
- /**
- * userCollection
- *
- * @param array $pInput
- * @param array $pReturn
- * @access public
- * @return $pReturn
- */
- public static function userCollection( $pInput, &$pReturn ) {
- global $gQueryUserId;
-
- if( empty( $pReturn['user_id'] )) {
- if( !empty( $gQueryUserId )) {
- $pReturn['user_id'] = $gQueryUserId;
- } elseif( isset( $pInput['user_id'] ) ) {
- $pReturn['user_id'] = $pInput['user_id'];
- }
- }
- if( \Bitweaver\BitBase::verifyId( $pInput['group_id'] ) ) {
- $pReturn['group_id'] = $pInput['group_id'];
- }
-
- }
-
- public static function getUserObject( $pUserId ) {
- global $gBitSystem;
- $userClass = $gBitSystem->getConfig( 'user_class', 'BitPermUser' );
- if( $ret = new $userClass( $pUserId ) ) {
- $ret->load();
- }
- return $ret;
- }
-}
-
-function get_user_content_count( $pUserId ) {
- global $gBitDb;
- if( \Bitweaver\BitBase::verifyId( $pUserId ) ) {
- return $gBitDb->getOne( "SELECT COUNT(`content_id`) FROM `".BIT_DB_PREFIX."liberty_content` lc WHERE lc.`content_type_guid`!='bituser' AND lc.`user_id`=?", [ $pUserId ] );
- }
-}
-
-// {{{ ==================== Services ====================
-function users_favs_content_list_sql( $pObject, $pParamHash=null ){
- $ret = [];
- if( is_object( $pObject ) && !empty( $pParamHash['user_favs'] ) ){
- // $ret['select_sql'] = "";
- $ret['join_sql'] = " INNER JOIN `".BIT_DB_PREFIX."users_favorites_map` ufm ON ( ufm.`favorite_content_id`=lc.`content_id` )";
- $ret['where_sql'] = " AND ufm.`user_id` = ?";
- $ret['bind_vars'][] = $pObject->mUserId;
- }
- return $ret;
-}
-
-function users_collection_sql( &$pObject, $pParamHash=null ){
- $ret = [];
- if( !empty( $pParamHash['group_id'] ) and \Bitweaver\BitBase::verifyId( $pParamHash['group_id'] ) ){
- // $ret['select_sql'] = "";
- $ret['join_sql'] = " INNER JOIN `".BIT_DB_PREFIX."users_groups_map` ugm ON (ugm.`user_id`=uu.`user_id`)";
- $ret['where_sql'] = ' AND ugm.`group_id` = ? ';
- $ret['bind_vars'][] = $pParamHash['group_id'];
- }
- return $ret;
-}
-// }}}
-
-/* vim: :set fdm=marker : */
diff --git a/includes/classes/RoleUser.php b/includes/classes/RoleUser.php
index c627409..b190311 100755
--- a/includes/classes/RoleUser.php
+++ b/includes/classes/RoleUser.php
@@ -2821,9 +2821,7 @@ class RoleUser extends \Bitweaver\Liberty\LibertyMime {
}
public static function getUserObject( $pUserId ) {
- global $gBitSystem;
- $userClass = $gBitSystem->getConfig( 'user_class', 'BitPermUser' );
- if( $ret = new $userClass( $pUserId ) ) {
+ if( $ret = new RolePermUser( $pUserId ) ) {
$ret->load();
}
return $ret;
diff --git a/includes/lookup_user_inc.php b/includes/lookup_user_inc.php
index 727dfa1..79b58b0 100755
--- a/includes/lookup_user_inc.php
+++ b/includes/lookup_user_inc.php
@@ -32,7 +32,6 @@ if( isset( $_REQUEST['fHomepage'] )) {
if( isset( $_REQUEST['home'] )) {
// this allows for a numeric user_id or alpha_numeric user_id
$queryUserId = $gBitUser->lookupHomepage( $_REQUEST['home'] ); //, $gBitSystem->getConfig( 'users_case_sensitive_login' ) == 'y' );
- $userClass = $gBitSystem->getConfig( 'user_class', (defined('ROLE_MODEL') ) ? '\Bitweaver\Users\RolePermUser' : '\Bitweaver\Users\BitPermUser' );
$gQueryUser = new RolePermUser( $queryUserId );
$gQueryUser->load( true );
$gQueryUser->setCacheableObject( false );
diff --git a/includes/register_inc.php b/includes/register_inc.php
index 89f8324..d24a8c5 100755
--- a/includes/register_inc.php
+++ b/includes/register_inc.php
@@ -12,31 +12,15 @@ use Bitweaver\Wiki\BitPage;
if( $newUser->preRegisterVerify( $pRegisterHash ) && $newUser->register( $pRegisterHash ) ) {
$gBitUser->mUserId = $newUser->mUserId;
- if( defined(ROLE_MODEL) ) {
- // add user to user-selected role
- if ( !empty( $_REQUEST['role'] ) ) {
- $roleInfo = $gBitUser->getRoleInfo( $_REQUEST['group'] );
- if ( empty($roleInfo) || $roleInfo['is_public'] != 'y' ) {
- $errors[] = "You can't use this group";
- $gBitSmarty->assign( 'errors', $errors );
- } else {
- $userId = $newUser->getUserId();
- $gBitUser->addUserToRole( $userId, $_REQUEST['group'] );
- $gBitUser->storeUserDefaultRole( $userId, $_REQUEST['group'] );
- }
- }
- } else {
- // add user to user-selected group
- if ( !empty( $_REQUEST['group'] ) ) {
- $groupInfo = $gBitUser->getGroupInfo( $_REQUEST['group'] );
- if ( empty($groupInfo) || $groupInfo['is_public'] != 'y' ) {
- $errors[] = "You can't use this group";
- $gBitSmarty->assign( 'errors', $errors );
- } else {
- $userId = $newUser->getUserId();
- $gBitUser->addUserToGroup( $userId, $_REQUEST['group'] );
- $gBitUser->storeUserDefaultGroup( $userId, $_REQUEST['group'] );
- }
+ if ( !empty( $_REQUEST['role'] ) ) {
+ $roleInfo = $gBitUser->getRoleInfo( $_REQUEST['group'] );
+ if ( empty($roleInfo) || $roleInfo['is_public'] != 'y' ) {
+ $errors[] = "You can't use this group";
+ $gBitSmarty->assign( 'errors', $errors );
+ } else {
+ $userId = $newUser->getUserId();
+ $gBitUser->addUserToRole( $userId, $_REQUEST['group'] );
+ $gBitUser->storeUserDefaultRole( $userId, $_REQUEST['group'] );
}
}