diff options
| author | Lester Caine <lester@lsces.co.uk> | 2026-05-15 15:42:51 +0100 |
|---|---|---|
| committer | Lester Caine <lester@lsces.co.uk> | 2026-05-15 15:42:51 +0100 |
| commit | 02a3c1e025dfcac83f04a4d08599e3e361b94997 (patch) | |
| tree | a8c41f2fc8476881b3f7bf2ddb402baa2da17142 | |
| parent | 513bc9e03522f0bfc0e307a8e40a517e746de2bc (diff) | |
| download | users-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
| -rw-r--r-- | admin/api_inc.php | 2 | ||||
| -rwxr-xr-x | admin/assign_user.php | 53 | ||||
| -rwxr-xr-x | admin/edit_group.php | 166 | ||||
| -rwxr-xr-x | admin/index.php | 46 | ||||
| -rwxr-xr-x | admin/permissions.php | 48 | ||||
| -rwxr-xr-x | admin/users_import.php | 26 | ||||
| -rw-r--r-- | admin/verify_emails.php | 38 | ||||
| -rwxr-xr-x | auth/imap/auth.php | 113 | ||||
| -rwxr-xr-x | auth/ldap/auth.php | 299 | ||||
| -rwxr-xr-x | auth/locate/auth.php | 143 | ||||
| -rwxr-xr-x | auth/multisites/auth.php | 2 | ||||
| -rwxr-xr-x | includes/bit_setup_inc.php | 3 | ||||
| -rwxr-xr-x | includes/classes/BitAuth.php | 111 | ||||
| -rwxr-xr-x | includes/classes/BitPermUser.php | 980 | ||||
| -rwxr-xr-x | includes/classes/BitUser.php | 2817 | ||||
| -rwxr-xr-x | includes/classes/RoleUser.php | 4 | ||||
| -rwxr-xr-x | includes/lookup_user_inc.php | 1 | ||||
| -rwxr-xr-x | includes/register_inc.php | 34 | ||||
| -rwxr-xr-x | modules/mod_user_profile.php | 5 | ||||
| -rwxr-xr-x | my_groups.php | 212 | ||||
| -rwxr-xr-x | preferences.php | 3 | ||||
| -rwxr-xr-x | role_register.php | 3 |
22 files changed, 32 insertions, 5077 deletions
diff --git a/admin/api_inc.php b/admin/api_inc.php index a0a8a63..006ed2c 100644 --- a/admin/api_inc.php +++ b/admin/api_inc.php @@ -14,7 +14,7 @@ function bituser_api_handler( $pMethod, $pRequest ) { if( $routeAction == 'register' ) { if( $pMethod == 'POST' ) { - $newUser = new BitPermUser(); + $newUser = new RolePermUser(); if( $newUser->register( $pRequest ) ) { $respStatus = HttpStatusCodes::HTTP_OK; $respData = $newUser->exportHash(); diff --git a/admin/assign_user.php b/admin/assign_user.php deleted file mode 100755 index 696a445..0000000 --- a/admin/assign_user.php +++ /dev/null @@ -1,53 +0,0 @@ -<?php -// $Header$ -// 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. -// This script is used to assign groups to a particular user -// ASSIGN USER TO GROUPS -// Initialization -require_once( '../../kernel/includes/setup_inc.php' ); -use Bitweaver\KernelTools; - -$gBitSystem->verifyPermission( 'p_users_admin' ); - -if (!$gBitUser->userExists( [ 'user_id' => $_REQUEST["assign_user"] ] ) ) { - $gBitSystem->fatalError( KernelTools::tra( "User doesnt exist" )); -} - -$assignUser = new BitPermUser( $_REQUEST["assign_user"] ); -$assignUser->setCacheableObject( false ); -$assignUser->load( true ); - -if( $assignUser->isAdmin() && !$gBitUser->isAdmin() ) { - $gBitSystem->fatalError( KernelTools::tra( 'You cannot modify a system administrator.' )); -} - -if( isset( $_REQUEST["action"] ) ) { - $gBitUser->verifyTicket(); - if ($_REQUEST["action"] == 'assign') { - $assignUser->addUserToGroup( $assignUser->mUserId, $_REQUEST["group_id"] ); - } elseif ($_REQUEST["action"] == 'removegroup') { - $assignUser->removeUserFromGroup($_REQUEST["assign_user"], $_REQUEST["group_id"]); - } - header( 'Location: '.$_SERVER['SCRIPT_NAME'].'?assign_user='.$assignUser->mUserId ); - die; -}elseif(isset($_REQUEST['set_default'])) { - $gBitUser->verifyTicket(); - $assignUser->storeUserDefaultGroup( $assignUser->mUserId, $_REQUEST['default_group'] ); - $assignUser->load(); -} -$gBitSmarty->assign( 'assignUser', $assignUser ); - -$listHash = [ 'sort_mode' => 'group_name_asc' ]; -$gBitSmarty->assign('groups', $gBitUser->getAllGroups( $listHash )); - -$gBitSystem->setBrowserTitle( 'Edit User: '.$assignUser->mUsername ); - -if($gBitSystem->isPackageActive("quota")) { - include(QUOTA_PKG_INCLUDE_PATH.'quota_inc.php'); -} - -// Display the template -$gBitSystem->display( 'bitpackage:users/admin_assign_user.tpl', null, [ 'display_mode' => 'admin' ]); -?> diff --git a/admin/edit_group.php b/admin/edit_group.php deleted file mode 100755 index 1c1c0ee..0000000 --- a/admin/edit_group.php +++ /dev/null @@ -1,166 +0,0 @@ -<?php -// $Header$ -// 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. -// Initialization -require_once( '../../kernel/includes/setup_inc.php' ); -use Bitweaver\KernelTools; - -// PERMISSIONS: NEEDS admin -$gBitSystem->verifyPermission( 'p_users_admin' ); - -$successMsg = null; -$errorMsg = null; - -if( count( $_GET ) > 2 || count( $_POST ) > 2 ) { - $gBitUser->verifyTicket(); -} - -if( !empty( $_REQUEST['group_id'] ) ) { - $permListHash = [ - 'sort_mode' => !empty( $_REQUEST['sort_mode'] ) ? $_REQUEST['sort_mode'] : null, - 'package' => !empty( $_REQUEST['package'] ) ? $_REQUEST['package'] : null, - ]; - $allPerms = $gBitUser->getGroupPermissions( $permListHash ); -} - -if( !empty( $_REQUEST["cancel"] ) ) { - bit_redirect( USERS_PKG_URL.'admin/edit_group.php' ); -} elseif( isset( $_REQUEST["batch_assign"] ) ) { - $groupInfo = $gBitUser->getGroupInfo( $_REQUEST['batch_assign'] ); - if( isset( $_REQUEST["confirm"] ) ) { - $gBitUser->batchAssignUsersToGroup( $_REQUEST['batch_assign'] ); - } else { - $gBitSystem->setBrowserTitle( KernelTools::tra( 'Confirm Batch Group Assignment' ) ); - $formHash['batch_assign'] = $_REQUEST["batch_assign"]; - $msgHash = [ - 'label' => KernelTools::tra( 'Batch Assign Users to Group' ), - 'confirm_item' => $groupInfo['group_name'], - 'warning' => KernelTools::tra( 'This will assign every user on the site to the group' ).' <strong>'.$groupInfo['group_name'].'</strong>', - ]; - $gBitSystem->confirmDialog( $formHash,$msgHash ); - } -} elseif( isset($_REQUEST["members"] ) ) { - $groupInfo = $gBitUser->getGroupInfo( $_REQUEST["members"] ); - $gBitSmarty->assign( 'groupInfo', $groupInfo ); - $groupMembers = $gBitUser->getGroupUsers( $_REQUEST["members"] ); - $gBitSmarty->assign( 'groupMembers', $groupMembers ); - $mid = "bitpackage:users/group_list_members.tpl"; - $gBitSystem->setBrowserTitle( KernelTools::tra( 'Group Members' ).': '.$groupInfo['group_name'] ); -} elseif( isset($_REQUEST["save"] ) ) { - if( empty($_REQUEST["name"] ) ) { - $_REQUEST["name"] = $_REQUEST["olgroup"]; - } - // modification - - $_REQUEST['user_id'] = ROOT_USER_ID; - if( $gBitUser->storeGroup( $_REQUEST ) ) { - $successMsg = "Group changes were saved sucessfully."; - } else { - $errorMsg = $gBitUser->mErrors['groups']; - } - if( !empty( $_REQUEST['default_home_group'] ) ) { - $gBitSystem->storeConfig( 'default_home_group', $_REQUEST['group_id'], USERS_PKG_NAME ); - } elseif( $_REQUEST['group_id'] == $gBitSystem->getConfig( 'default_home_group' ) ) { - // the default home group was unchecked. - $gBitSystem->storeConfig( 'default_home_group', null, USERS_PKG_NAME ); - } -} elseif( isset( $_REQUEST['delete'] ) ) { - // Process a form to remove a group - $formHash['group_id'] = $_REQUEST['group_id']; - $formHash['delete'] = 1; - $groupInfo = $gBitUser->getGroupInfo( $_REQUEST['group_id'] ); - if( isset( $_REQUEST["confirm"] ) ) { - $gBitUser->verifyTicket(); - if( $_REQUEST['group_id'] == $gBitSystem->getConfig( 'default_home_group' ) ) { - $gBitSystem->storeConfig( 'default_home_group', null, USERS_PKG_NAME ); - } - $gBitUser->expungeGroup( $_REQUEST['group_id'] ); - $successMsg = "The group ".$groupInfo['group_name']." was deleted."; - unset( $_REQUEST['group_id'] ); - } else { - $gBitSystem->setBrowserTitle( KernelTools::tra( 'Delete group') ); - $msgHash = [ - 'confirm_item' => KernelTools::tra( 'Are you sure you want to permantly remove the group' )." <strong>$groupInfo[group_name]</strong>".'?', - 'warning' => KernelTools::tra( 'This cannot be undone.' ), - ]; - $gBitSystem->confirmDialog( $formHash,$msgHash ); - } -// $mid = 'bitpackage:users/admin_groups_list.tpl'; -} elseif( isset( $_REQUEST['updateperms'] )) { - foreach( array_keys( $allPerms ) as $perm ) { - if( !empty( $_REQUEST['perm'][$perm] )) { - $gBitUser->assignPermissionToGroup( $perm, $_REQUEST['group_id'] ); - } else { - // we have a selected perm that is now UNselected - $gBitUser->removePermissionFromGroup( $perm, $_REQUEST['group_id'] ); - } - } - // let's reload just to be safe. - $allPerms = $gBitUser->getGroupPermissions( $permListHash ); -} elseif( isset( $_REQUEST["action"] )) { - $formHash['action'] = $_REQUEST['action']; - if ($_REQUEST["action"] == 'remove') { - $gBitUser->removePermissionFromGroup( $_REQUEST["permission"], $_REQUEST['group_id'] ); - $successMsg = 'The permission '.$_REQUEST['permission'].' was removed successflly. <a href="'.USERS_PKG_URL.'admin/edit_group.php?action=assign&perm='.$_REQUEST['permission'].'&group_id='.$_REQUEST['group_id'].'&pacakge='.$_REQUEST['package'].'">Undo last action.</a>'; - } elseif( $_REQUEST["action"] == 'create' ) { - $mid = 'bitpackage:users/admin_group_edit.tpl'; - $gBitSystem->setBrowserTitle( KernelTools::tra( 'Create New Group' ) ); - } elseif ($_REQUEST["action"] == 'assign') { - $gBitUser->assignPermissionToGroup($_REQUEST["perm"], $_REQUEST['group_id']); - } -} - -if( !empty( $_REQUEST['group_id'] ) || (!empty( $_REQUEST["action"] ) && $_REQUEST["action"] == 'create' ) ) { - $permPackages = $gBitUser->getPermissionPackages(); - $gBitSmarty->assign( 'permPackages', $permPackages ); - - // get grouplist separately from the $users stuff to avoid splitting of data due to pagination - $listHash = [ 'sort_mode' => 'group_name_asc' ]; - -/* - // get content and pass it on to the template - include_once( LIBERTY_PKG_INCLUDE_PATH.'get_content_list_inc.php' ); - foreach( $contentList as $cItem ) { - $cList[$contentTypes[$cItem['content_type_guid']]][$cItem['content_id']] = $cItem['title'].' [id: '.$cItem['content_id'].']'; - } - $gBitSmarty->assign( 'contentList', $cList ); - $gBitSmarty->assign( 'contentSelect', $contentSelect ); -*/ - $contentTypes = [ '' => KernelTools::tra( 'All Content' ) ]; - foreach( $gLibertySystem->mContentTypes as $cType ) { - $contentTypes[$cType['content_type_guid']] = $gLibertySystem->getContentTypeName( $cType['content_type_guid'] ); - } - $gBitSmarty->assign( 'contentTypes', $contentTypes ); -} else { - // get grouplist separately from the $users stuff to avoid splitting of data due to pagination - $listHash = [ 'sort_mode' => !empty( $_REQUEST['sort_mode'] ) ? $_REQUEST['sort_mode'] : 'group_name_asc' ]; -} -$gBitSmarty->assign('groupList', $gBitUser->getAllGroups( $listHash )); - -$inc = []; -if( empty( $mid ) ) { - if( !empty( $_REQUEST['group_id'] ) ) { - $groupInfo = $gBitUser->getGroupInfo( $_REQUEST['group_id'] ); - - $defaultGroupId = $gBitSystem->getConfig( 'default_home_group' ); - $gBitSmarty->assign( 'defaultGroupId', $defaultGroupId ); - $gBitSmarty->assign( 'groupInfo', $groupInfo ); - $gBitSmarty->assign( 'allPerms', $allPerms ); - - $gBitSystem->setBrowserTitle( KernelTools::tra( 'Admininster Group' ).': '.$groupInfo['group_name'] ); - $mid = 'bitpackage:users/admin_group_edit.tpl'; - } else { - $gBitSystem->setBrowserTitle( KernelTools::tra( 'Admin List Groups' ) ); - $_REQUEST['group_id'] = 0; - $mid = 'bitpackage:users/admin_groups_list.tpl'; - } -} - -$gBitSmarty->assign('successMsg',$successMsg); -$gBitSmarty->assign('errorMsg',$errorMsg); - -// Display the template for group administration -$gBitSystem->display( $mid , null, [ 'display_mode' => 'edit' ]); -?> diff --git a/admin/index.php b/admin/index.php index b2ea0af..2f143a4 100755 --- a/admin/index.php +++ b/admin/index.php @@ -17,7 +17,7 @@ $feedback = []; if( isset($_REQUEST["newuser"] ) ) { $userRecord = $_REQUEST; - $newUser = defined( 'ROLE_MODEL' ) ? new RolePermUser() : new BitPermUser(); + $newUser = new RolePermUser(); if( $newUser->importUser( $userRecord ) ) { $gBitSmarty->assign( 'addSuccess', "User Added Successfully" ); @@ -71,7 +71,7 @@ if( isset( $_REQUEST["action"] ) ) { $fp = fopen($file, 'w'); $printHeader = true; foreach( $_REQUEST['batch_user_ids'] as $uid ) { - $listUser = BitUser::getUserObject( $uid ); + $listUser = RoleUser::getUserObject( $uid ); $hash = $listUser->exportHash(); if( $printHeader ) { fputcsv( $fp, array_keys( $hash ) ); @@ -90,7 +90,7 @@ if( isset( $_REQUEST["action"] ) ) { $gBitUser->verifyTicket(); $delUsers = $errDelUsers = ""; foreach( $_REQUEST['batch_user_ids'] as $uid ) { - $expungeUser = BitUser::getUserObject( $uid ); + $expungeUser = RoleUser::getUserObject( $uid ); $userInfo = $gBitUser->getUserInfo( [ 'user_id' => $uid ] ); if( $expungeUser->load() && $expungeUser->expunge( BitBase::getParameter( $_REQUEST, 'delete_user_content' ) ) ) { $delUsers .= "<li>{$userInfo['real_name']} ({$userInfo['login']})</li>"; @@ -123,8 +123,7 @@ if( isset( $_REQUEST["action"] ) ) { $formHash['user_id'] = $_REQUEST['user_id']; $userInfo = $gBitUser->getUserInfo( [ 'user_id' => $_REQUEST["user_id"] ] ); if( !empty( $userInfo['user_id'] ) ) { - $userClass = $gBitSystem->getConfig( 'user_class', 'BitPermUser' ); - $reqUser = new $userClass( $_REQUEST["user_id"] ); + $reqUser = new RolePermUser( $_REQUEST["user_id"] ); if( isset( $_REQUEST["confirm"] ) ) { $gBitUser->verifyTicket(); switch( $_REQUEST["action"] ){ @@ -191,23 +190,12 @@ if( isset( $_REQUEST["action"] ) ) { if ($_REQUEST["action"] == 'removerole') { $gBitUser->removeUserFromRole($_REQUEST["user"], $_REQUEST["role"]); } - if ($_REQUEST["action"] == 'removegroup') { - $gBitUser->removeUserFromGroup($_REQUEST["user"], $_REQUEST["group"]); - } } -if ( defined( 'ROLE_MODEL' ) ) { - // get default role and pass it to tpl - foreach( $gBitUser->getDefaultRole() as $defaultRoleId => $defaultRoleName ) { - $gBitSmarty->assign('defaultRoleId', $defaultRoleId ); - $gBitSmarty->assign('defaultRoleName', $defaultRoleName ); - } -} else { - // get default group and pass it to tpl - foreach( $gBitUser->getDefaultGroup() as $defaultGroupId => $defaultGroupName ) { - $gBitSmarty->assign('defaultGroupId', $defaultGroupId ); - $gBitSmarty->assign('defaultGroupName', $defaultGroupName ); - } + +foreach( $gBitUser->getDefaultRole() as $defaultRoleId => $defaultRoleName ) { + $gBitSmarty->assign('defaultRoleId', $defaultRoleId ); + $gBitSmarty->assign('defaultRoleName', $defaultRoleName ); } // override default max_records @@ -221,20 +209,10 @@ $listHash['listInfo']["URL"] = USERS_PKG_URL."admin/index.php"; $gBitSmarty->assign('control', $listHash['listInfo']); $gBitSmarty->assign('listInfo', $listHash['listInfo']); -if ( defined( 'ROLE_MODEL' ) ) { - // invoke edit service for the add user feature - $userObj = new RolePermUser(); - $userObj->invokeServices( 'content_edit_function' ); - // Get roles (list of roles) - $rolelist = $gBitUser->getRoles(0, false); - $gBitSmarty->assign( 'rolelist', $rolelist ); -} else { - // invoke edit service for the add user feature - $userObj = new BitPermUser(); - $userObj->invokeServices( 'content_edit_function' ); // Get groups (list of groups) - $grouplist = $gBitUser->getGroups('', '', 'group_name_asc'); - $gBitSmarty->assign( 'grouplist', $grouplist ); -} +$userObj = new RolePermUser(); +$userObj->invokeServices( 'content_edit_function' ); +$rolelist = $gBitUser->getRoles(0, false); +$gBitSmarty->assign( 'rolelist', $rolelist ); $gBitSmarty->assign( 'feedback', $feedback ); $gBitSmarty->assign( (!empty( $_REQUEST['tab'] ) ? $_REQUEST['tab'] : 'userlist').'TabSelect', 'tdefault' ); diff --git a/admin/permissions.php b/admin/permissions.php deleted file mode 100755 index 3f3075d..0000000 --- a/admin/permissions.php +++ /dev/null @@ -1,48 +0,0 @@ -<?php -require_once( '../../kernel/includes/setup_inc.php' ); -use Bitweaver\KernelTools; - -$gBitSystem->verifyPermission( 'p_admin' ); - -$feedback = []; - -// get a list of all groups and their permissions -$listHash = [ - 'only_root_groups' => true, - 'sort_mode' => !empty( $_REQUEST['sort_mode'] ) ? $_REQUEST['sort_mode'] : 'group_name_asc', -]; -$allGroups = $gBitUser->getAllGroups( $listHash ); -$allPerms = $gBitUser->getGroupPermissions( $_REQUEST ); - -// deal with assigning permissions to various groups -if( !empty( $_REQUEST['save'] )) { - $gBitUser->verifyTicket(); - foreach( array_keys( $allGroups ) as $groupId ) { - foreach( array_keys( $allPerms ) as $perm ) { - if( !empty( $_REQUEST['perms'][$groupId][$perm] )) { - $gBitUser->assignPermissionToGroup( $perm, $groupId ); - } else { - $gBitUser->removePermissionFromGroup( $perm, $groupId ); - } - } - } - - $feedback['success'] = KernelTools::tra( "The permissions were successfully added to the requested groups." ); - // we need to update the groups list - $allGroups = $gBitUser->getAllGroups( $listHash ); -} - -// Check to see if we have unassigned permissions -if(( $unassignedPerms = $gBitUser->getUnassignedPerms() )) { - $feedback['warning'] = KernelTools::tra( 'You have some permissions that are not assigned to any group. You need to assign these to at least one group each.' ); - $gBitSmarty->assign( 'unassignedPerms', $unassignedPerms ); -} - -$gBitSmarty->assign( 'allPerms', $allPerms ); -$gBitSmarty->assign( 'allGroups', $allGroups ); -$gBitSmarty->assign( 'permPackages', $gBitUser->getPermissionPackages() ); -$gBitSmarty->assign( 'feedback', $feedback ); -$gBitSmarty->assign( 'contentWithPermissions', LibertyContent::getContentWithPermissionsList() ); - -$gBitSystem->display( 'bitpackage:users/admin_permissions.tpl', KernelTools::tra( 'Permission Maintenance' ), [ 'display_mode' => 'admin' ]); -?> diff --git a/admin/users_import.php b/admin/users_import.php index 0c460be..149b417 100755 --- a/admin/users_import.php +++ b/admin/users_import.php @@ -48,17 +48,8 @@ if( isset( $_REQUEST["batchimport"])) { $added = 0; $i = 1; foreach( $userRecords as $userRecord ) { - $newUser = new BitPermUser(); + $newUser = new RolePermUser(); if( $newUser->importUser( $userRecord ) ) { - if( !empty( $userRecord['groups'] ) ) { - // groups need to be separated by spaces since this is a csv file - $groups = explode( " ", $userRecord['groups'] ); - foreach( $groups as $group ) { - if( $groupId = $gBitUser->groupExists( $group, ROOT_USER_ID ) ) { - $newUser->addUserToGroup( $newUser->mUserId, $groupId ); - } - } - } if( !empty( $userRecord['roles'] ) ) { // roles need to be separated by spaces since this is a csv file $roles = explode( " ", $userRecord['roles'] ); @@ -95,18 +86,9 @@ if( isset( $_REQUEST["batchimport"])) { } } -if ( defined( 'ROLE_MODEL' ) ) { - // get default role and pass it to tpl - foreach( $gBitUser->getDefaultRole() as $defaultRoleId => $defaultRoleName ) { - $gBitSmarty->assign('defaultRoleId', $defaultRoleId ); - $gBitSmarty->assign('defaultRoleName', $defaultRoleName ); - } -} else { - // get default group and pass it to tpl - foreach( $gBitUser->getDefaultGroup() as $defaultGroupId => $defaultGroupName ) { - $gBitSmarty->assign('defaultGroupId', $defaultGroupId ); - $gBitSmarty->assign('defaultGroupName', $defaultGroupName ); - } +foreach( $gBitUser->getDefaultRole() as $defaultRoleId => $defaultRoleName ) { + $gBitSmarty->assign('defaultRoleId', $defaultRoleId ); + $gBitSmarty->assign('defaultRoleName', $defaultRoleName ); } // Display the template diff --git a/admin/verify_emails.php b/admin/verify_emails.php deleted file mode 100644 index 9e614f6..0000000 --- a/admin/verify_emails.php +++ /dev/null @@ -1,38 +0,0 @@ -<?php -// $Header$ -// 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. -// Initialization -require_once( '../../kernel/includes/setup_inc.php' ); - -if( $validatedGroup = $gBitSystem->getConfig( 'users_validate_email_group' ) ) { - $gBitUser->verifyTicket(); - - $whereSql = ''; - $bindVars = [ $gBitSystem->getConfig('users_validate_email_group') ]; - if( !empty( $_REQUEST['start_user_id'] ) ) { - $whereSql = " AND user_id>?"; - $bindVars[] = $_REQUEST['start_user_id']; - } - - $selectSql = "SELECT uu.user_id,uu.email FROM users_users uu WHERE user_id NOT IN (SELECT user_id FROM users_groups_map WHERE group_id = ?) $whereSql ORDER BY uu.user_id"; - $users = $gBitDb->getAssoc($selectSql, $bindVars ); - $errors; - foreach ( $users as $id=>$email ){ - print date( "Y-m-d H:i:s" )." Verifying $email ( $id ) .... "; - flush(); - $emailStatus = $gBitUser->verifyMx($email,$errors); - if( $emailStatus === true){ - $gBitUser->addUserToGroup( $id , $validatedGroup ); - print "valid"; - } elseif( $emailStatus === -1 ) { - print "MX connection failed"; - } else { - print " --INVALID-- "; - } - print "<br/>\n"; - flush(); - } -} - diff --git a/auth/imap/auth.php b/auth/imap/auth.php deleted file mode 100755 index 2887254..0000000 --- a/auth/imap/auth.php +++ /dev/null @@ -1,113 +0,0 @@ -<?php -/** - * $Header$ - * - * @package users - */ - -/** - * Class that manages the imap autentication method - * - * @package users - * @subpackage auth - */ -namespace Bitweaver\Users; - -use Bitweaver\KernelTools; - -class IMAPAuth extends BaseAuth { - - function __construct() { - parent::__construct('imap'); - } - - function validate($user,$pass,$challenge,$response) { - parent::validate($user,$pass,$challenge,$response); - $mailbox = '{' . $this->mConfig['server']; - if ($this->mConfig["ssl"]) { - $mailbox .= "/ssl"; - if ($this->mConfig["sslvalidate"]) { - $mailbox .= "/validate-cert"; - } else { - $mailbox .= "/novalidate-cert"; - } - } - $mailbox .= ':'.$this->mConfig["port"].'}INBOX'; - - $imapauth = @imap_open($mailbox,$user , $pass); - if (!$imapauth) { - $this->mErrors['login']=imap_errors(); - $ret=USER_NOT_FOUND; - } else { - $ret=USER_VALID; - $this->mInfo["real_name"] = $user; - if(empty($this->mConfig["email"])) { - $this->mInfo["email"] = $user; - } else { - $info=['login'=>$user]; - $replace_func = create_function('$matches','$info = '.var_export($info,true).'; - $m = $matches[0]; - $m = substr($m,1,strlen($m)-2); - if(empty($info[$m])) return ""; - return strtolower($info[$m]);'); - $this->mInfo["email"] = preg_replace_callback('/%.*?%/',$replace_func,$this->mConfig["email"]); - } - imap_close($imapauth); - } - return $ret; - } - - function isSupported() { - $ret = true; - if (!function_exists('imap_open')) { - $this->mErrors['support']=KernelTools::tra("IMAP Authentication is not supported as PHP IMAP Extention not loaded."); - $ret = false; - } - return $ret; - } - - function createUser(&$userattr) { - $this->mErrors['create']=KernelTools::tra("Cannot create users in an IMAP Server."); - return false; - } - - function canManageAuth() { - $this->mErrors[]=KernelTools::tra("Cannot create users in an IMAP Server."); - return false; - } - - function getSettings() { - return [ - 'users_imap_server' => [ - 'label' => "IMAP Server", - 'type' => "text", - 'note' => "", - 'default' => '', - ], - 'users_imap_ssl' => [ - 'label' => "Connect Using SSL", - 'type' => "checkbox", - 'note' => "", - 'default' => 'y', - ], - 'users_imap_sslvalidate' => [ - 'label' => "Require SSL Certificate to be valid", - 'type' => "checkbox", - 'note' => "", - 'default' => 'n', - ], - 'users_imap_port' => [ - 'label' => "IMAP Port", - 'type' => "text", - 'note' => "", - 'default' => '993', - ], - 'users_imap_email' => [ - 'label' => "LDAP User E-Mail Address", - 'type' => "text", - 'note' => "If empty the login is used.<br />Otherwise all %login% is replaced with the login name, and the result used as the email address.<br />Please remember to include the @ sign", - 'default' => "%login%@redhat.com", - ], - ]; - } -} diff --git a/auth/ldap/auth.php b/auth/ldap/auth.php deleted file mode 100755 index 709e5e7..0000000 --- a/auth/ldap/auth.php +++ /dev/null @@ -1,299 +0,0 @@ -<?php -/** - * $Header$ - * - * @package users - */ - -/** - * required setup - */ -namespace Bitweaver\Users; - -use Bitweaver\KernelTools; - -if (file_exists(UTIL_PKG_INCLUDE_PATH."pear/Auth/Auth.php")) { - require_once (UTIL_PKG_INCLUDE_PATH."pear/Auth/Auth.php"); -} else { -// THIS may need changing if a different PEAR installation is used - include_once("Auth/Auth.php"); -} - -/** - * Class that manages the PEAR:ldap autentication method - * - * @package users - * @subpackage auth - */ -class LDAPAuth extends BaseAuth { - function __construct() { - parent::__construct('ldap'); - } - - function validate($user,$pass,$challenge,$response) { - parent::validate($user,$pass,$challenge,$response); - global $gBitDb; - - if ( empty($user) or empty($pass) ) { - return USER_NOT_FOUND; - } - - $this->mInfo["real_name"] = ''; // This needs fixing in the base code - real_name will only exist if a user has been identiied - - // Use V3, which requires UTF-8: - $this->mConfig['version'] = 3; - $user_utf8 = utf8_encode( $user ); - - if ( $this->mConfig['reqcert'] ) { - // Skip the SSL certificate check: - // (This assumes PHP is using the OpenLDAP client library.) - putenv('LDAPTLS_REQCERT=never'); - } - - if ( $this->mConfig['activedirectory'] ) { - $this->mConfig['attributes'] = (array) null; - $this->mConfig['userfilter'] = '(objectClass='.$this->mConfig['useroc'].')'; - $this->mConfig['groupfilter'] = '(objectClass='.$this->mConfig['groupoc'].')'; - $this->mConfig['groupscope'] = $this->mConfig['userscope']; - } else { - // Using bitweaver groups with LDAP still needs completing so disable for now - unset($this->mConfig['group']); - } - - $a = new \Auth('LDAP', $this->mConfig, "", false); - $a->_loadStorage(); // set up connection to ldap via user details - - // First, try by username. If that fails, try by email address. - $success = $a->storage->fetchData($user_utf8, $pass, false); - - if ($success == false) { - // The user wasn't found. Try again by email address: - $this->mConfig['userattrsto'] = $this->mConfig['userattr']; // Keep this for later - $this->mConfig['userattr'] = $this->mConfig['email']; // Tell PEAR::Auth() to look at the 'mail' attribute - - // this needs testing better, should be no need to create second instance of Auth! - $a = new \Auth('LDAP', $this->mConfig, "", false); - $a->_loadStorage(); // set up connection to ldap via user details - - $success = $a->storage->fetchData($user_utf8, $pass, false); - if ($success == false) { - $this->mErrors['login'] = $a->storage->options['status'] ?? 'Not authenticated'; - return PASSWORD_INCORRECT; - } - } - - // At this point, there was a successful ldap_bind() using the - // user's Distinguished Name (DN) and password for login. - // The call to ldap_get_attributes() has been saved into $a->getAuthData('attributes') - - if ( $this->mConfig['activedirectory'] ) { - // Active Directory does some things differently - mainly in the returns - $attributes = $a->getAuthData(); - // Warning: ldap_get_attributes() uses case-sensitive array keys - $this->mInfo["login"] = $attributes[ $this->mConfig['userattr'] ]; - $this->mInfo["email"] = $attributes[ $this->mConfig['email'] ]; - $this->mInfo["real_name"] = empty($attributes[$this->mConfig['name']]) ? $this->mInfo["login"] : $attributes[$this->mConfig['name']]; - } - else { - $attributes = $a->getAuthData('attributes'); - // Warning: ldap_get_attributes() uses case-sensitive array keys - $this->mInfo["login"] = $attributes[ $this->mConfig['userattr'] ][0]; - $this->mInfo["email"] = $attributes[ $this->mConfig['email'] ][0]; - $this->mInfo["real_name"] = empty($attributes[$this->mConfig['name']][0]) ? $this->mInfo["login"] : $attributes[$this->mConfig['name']][0]; - } - // Note, the new (or updated) SQL user will be created by the calling BitUser class. - - return USER_VALID; // Success! - - } - - function isSupported() { - $ret = true; - if (!class_exists("Auth")) { - $this->mErrors['support']=KernelTools::tra("LDAP Authentication is not supported as PEAR Package Auth is not availible."); - $ret = false; - } - if (!function_exists('ldap_connect')) { - $this->mErrors['support']=KernelTools::tra("LDAP Authentication is not supported as PHP LDAP Extention not loaded."); - $ret = false; - } - return $ret; - } - - // create a new user in the Auth directory - function createUser(&$userattr) { - global $gBitDb; - // set additional attributes here - if (empty($userattr["email"])) { - $userattr["email"] = $gBitDb->getOne("select `email` from `".BIT_DB_PREFIX."users_users` where `login`=?", [$userattr["login"]]); - } - // set the Auth options - $a = new \Auth("LDAP", $this->mConfig); - // check if the login correct - if ($a->addUser($userattr["login"], $userattr["password"], $userattr) === true) { - return true; - } - // otherwise use the error status given back - $this->mErrors['create'] = $a->getStatus(); - return false; - - } - - function canManageAuth() { - return true; - } - - function getSettings() { - global $gBitUser; - $listHash = []; - - // Roles are not inteneded to match with ldap groups - // This area needs a closer look if it needs to be used - $groups = []; - $groups = $gBitUser->getAllGroups($listHash); - $groupsD = []; - foreach ($groups as $g) { - $groupsD[$g['group_id']]= "{$g['group_name']} ( {$g['group_desc']} )"; - } - $groups = $groupsD; - return [ - 'users_ldap_url' => [ - 'label' => "LDAP Connection URL", - 'type' => "text", - 'note' => "You can specify an LDAP URL, like ldap://localhost/ or ldaps://some-server/.", - 'default' => '', - ], - 'users_ldap_host' => [ - 'label' => "LDAP Host", - 'type' => "text", - 'note' => "Instead of a URL, you can specify a hostname and port explicitly. Give either a URL, or else a hostname/port (but not both).", - 'default' => 'localhost', - ], - 'users_ldap_port' => [ - 'label' => "LDAP Port", - 'type' => "text", - 'note' => "", - 'default' => '389', - ], - 'users_ldap_start_tls' => [ - 'label' => "Use Start-TLS?", - 'type' => "checkbox", - 'note' => "Please note there is a difference between ldaps:// and Start-TLS for ldap. Start-TLS uses port 389, while ldaps:// uses port 636. Both encrypted LDAP (with Start-TLS) and unencrypted LDAP can run on port 389 concurrently.", - 'default' => 'y', - ], - 'users_ldap_reqcert' => [ - 'label' => "Skip the SSL Cert validation?", - 'type' => "checkbox", - 'note' => "If Start-TLS is checked, then your LDAP server needs a trusted SSL cert -- unless you check this option, in which case you can use a self-signed (untrusted) cert.", - 'default' => 'y', - ], - 'users_ldap_referrals' => [ - 'label' => "Use Referrals?", - 'type' => "checkbox", - 'note' => "This should probably be 'yes'. (Only applies to LDAP V3 servers.)", - 'default' => 'y', - ], - 'users_ldap_basedn' => [ - 'label' => "LDAP Base DN", - 'type' => "text", - 'note' => "", - 'default' => '', - ], - 'users_ldap_userdn' => [ - 'label' => "LDAP User DN", - 'type' => "text", - 'note' => "", - 'default' => '', - ], - 'users_ldap_userattr' => [ - 'label' => "LDAP User Attribute", - 'type' => "text", - 'note' => "The LDAP Attribute to use for the user's login in Bitweaver. (This is the first attribute searched when the user logs in.)", - 'default' => 'uid', - ], - 'users_ldap_email' => [ - 'label' => "LDAP User E-Mail Address", - 'type' => "text", - 'note' => "The LDAP Attribute to use for the user's email address in Bitweaver. (This is the second attribute searched when the user logs in.)", - 'default' => 'mail', - ], - 'users_ldap_name' => [ - 'label' => "LDAP User Display Name", - 'type' => "text", - 'note' => "The LDAP Attribute to use for the user's Full Name in Bitweaver.", - 'default' => 'displayName', - ], - 'users_ldap_useroc' => [ - 'label' => "LDAP User OC", - 'type' => "text", - 'note' => "", - 'default' => '(objectClass=inetOrgPerson)', - ], - 'users_ldap_groupdn' => [ - 'label' => "LDAP Group DN", - 'type' => "text", - 'note' => "", - 'default' => '', - ], - 'users_ldap_groupattr' => [ - 'label' => "LDAP Group Atribute", - 'type' => "text", - 'note' => "", - 'default' => 'cn', - ], - 'users_ldap_groupoc' => [ - 'label' => "LDAP Group OC", - 'type' => "text", - 'note' => "", - 'default' => '(objectClass=groupOfUniqueNames)', - ], - 'users_ldap_memberattr' => [ - 'label' => "LDAP Member Attribute", - 'type' => "text", - 'note' => "", - 'default' => 'uniqueMember', - ], - 'users_ldap_memberisdn' => [ - 'label' => "LDAP Member Is DN", - 'type' => "checkbox", - 'note' => "", - 'default' => 'n', - ], - 'users_ldap_binddn' => [ - 'label' => "LDAP Bind DN", - 'type' => "text", - 'note' => "This DN will be used to search the LDAP directory for users. If left blank, 'anonymous bind' is used.", - 'default' => '', - ], - 'users_ldap_bindpw' => [ - 'label' => "LDAP Bind Pwd", - 'type' => "password", - 'note' => "", - 'default' => '', - ], - 'users_ldap_userscope' => [ - 'label' => "LDAP Scope to use when searching for users", - 'type' => "option", - 'note' => "", - 'default' => 'sub', - 'options' => [ - 'sub' => "Sub", - 'one' => "One", - 'base' => "Base", - ], - ], - 'users_ldap_group' => [ - 'label' => "LDAP Group Requirement", - 'type' => "text", - 'note' => "If this is specified, then the LDAP user must also be a member of this LDAP group to connect.", - 'default' => '', - ], - 'users_ldap_activedirectory' => [ - 'label' => "Active Directory?", - 'type' => "checkbox", - 'note' => "", - 'default' => 'n', - ], - ]; - } -}
\ No newline at end of file diff --git a/auth/locate/auth.php b/auth/locate/auth.php deleted file mode 100755 index 77197f5..0000000 --- a/auth/locate/auth.php +++ /dev/null @@ -1,143 +0,0 @@ -<?php -/** - * $Header$ - * - * @package users - */ - -/** - * Class that manages the bitweaver autentication method with additional modifications - * for access managed via machine name - * This is used to idenitfy counter locations in sites where location related activity takes place - * such as anouncment and direction displays - * - * @package users - * @subpackage auth - */ -namespace Bitweaver\Users; - -class LocateAuth extends BaseAuth { - - function __construct() { - parent::__construct('locate'); - } - - function validate($user,$pass,$challenge,$response) { - parent::validate($user,$pass,$challenge,$response); - global $gBitSystem; - global $gBitDb; - global $gMultisites; - - $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`, `content_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 ); -// Modify this to check machine name against managed locations -// $query = "select `multisite_id` from `".BIT_DB_PREFIX."multisite_content` where `content_id` = ?"; -// $sites = $gBitDb->getAll($query, array( $row['content_id'] ) ); -// if ( !$sites ) { - $ret=USER_VALID; -/* } else { - // This will allow for additional by site checking in future - // Currently only a single site per user_id is allowed - $ret=PASSWORD_INCORRECT; - foreach ( $sites as $id ) { - if ( $id['multisite_id'] == $gMultisites->mMultisiteId ) { - $ret=USER_VALID; - } - } - if ( $ret == PASSWORD_INCORRECT ) { - $this->mErrors[] = 'You are not authorized on this area of the site'; - } - } -*/ - } 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; - $this->updateLastLogin( $userId ); - } else { - $this->mErrors[] = 'Invalid challenge'; - $ret=PASSWORD_INCORRECT; - } - } - } - if (!empty($userId)) { - $this->mInfo['user_id']=$userId; - } - } - return( $ret ); - } - - function canManageAuth() { - global $gBitSystem; - if( $gBitSystem->isPackageActive( 'contact' ) ) { - return TRUE; - } - return FALSE; - - } - - function isSupported() { - global $gBitSystem; - if( $gBitSystem->isPackageActive( 'contact' ) ) { - return TRUE; - } - return FALSE; - - } - - 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 BitPermUser(); - - if( !$u->store( $pUserHash ) ) { - $this->mErrors = array_merge($this->mErrors,$u->mErrors); - } - return $u->mUserId; - } -} diff --git a/auth/multisites/auth.php b/auth/multisites/auth.php index cf44c0d..98cb74b 100755 --- a/auth/multisites/auth.php +++ b/auth/multisites/auth.php @@ -128,7 +128,7 @@ class MultisitesAuth extends BaseAuth { 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 BitPermUser(); + $u = new RolePermUser(); if( !$u->store( $pUserHash ) ) { $this->mErrors = array_merge($this->mErrors,$u->mErrors); 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: <{$senderEmail}>" ); - // 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: <{$pEmail}>" ); - // 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'] ); } } diff --git a/modules/mod_user_profile.php b/modules/mod_user_profile.php index 5dfafde..c00fe36 100755 --- a/modules/mod_user_profile.php +++ b/modules/mod_user_profile.php @@ -15,14 +15,13 @@ global $gQueryUser, $gBitUser, $gBitSmarty, $moduleParams; extract( $moduleParams ); -$userClass = $gBitSystem->getConfig( 'user_class', 'BitPermUser' ); if( !empty( $module_params['user_id'] )) { - $user = $userClass( $module_params['user_id'] ); + $user = new RolePermUser( $module_params['user_id'] ); $user->load(); $userInfo = &$user->mInfo; $userPrefs = &$user->mPrefs; } elseif( !empty( $module_params['login'] )) { - $user = $userClass(); + $user = new RolePermUser(); $user->load(null,$module_params['login']); $userInfo = &$user->mInfo; $userPrefs = &$user->mPrefs; diff --git a/my_groups.php b/my_groups.php deleted file mode 100755 index 58ac0be..0000000 --- a/my_groups.php +++ /dev/null @@ -1,212 +0,0 @@ -<?php -/** - * my groups - * - * @copyright (c) 2004-15 bitweaver.org - * - * @package users - * @subpackage functions - */ - -/** - * required setup - */ -require_once '../kernel/includes/setup_inc.php'; -use Bitweaver\KernelTools; - -global $gBitUser, $gBitSystem; - -// PERMISSIONS: registered user required -if ( !$gBitUser->isRegistered() ) { - $gBitSystem->fatalError( KernelTools::tra( "You are not logged in." )); -} - -if( !empty( $_REQUEST["cancel"] ) ) { - bit_redirect( USERS_PKG_URL.'my_groups.php' ); -} - -if ( $gBitUser->hasPermission('p_users_create_personal_groups' ) ) { - if( !empty( $_REQUEST['group_id'] ) ) { - $allPerms = $gBitUser->getGroupPermissions( [ 'sort_mode' => !empty( $_REQUEST['sort_mode'] ) ? $_REQUEST['sort_mode'] : null ]); - // get grouplist separately from the $users stuff to avoid splitting of data due to pagination - $listHash = [ 'sort_mode' => 'group_name_asc' ]; - $groupList = $gBitUser->getAllGroups( $listHash ); - } else { - // get grouplist separately from the $users stuff to avoid splitting of data due to pagination - $listHash = [ 'sort_mode' => !empty( $_REQUEST['sort_mode'] ) ? $_REQUEST['sort_mode'] : 'group_name_asc' ]; - $groupList = $gBitUser->getAllGroups( $listHash ); - } - - // Remember a package limit if it is set. - $gBitSmarty->assign( 'package',$_REQUEST['package'] ?? 'all' ); - - // Save the join - if( isset($_REQUEST["save"] ) ) { - if( empty($_REQUEST["name"] ) ) { - $_REQUEST["name"] = $_REQUEST["olgroup"]; - } - if( $gBitUser->storeGroup( $_REQUEST ) ) { - $successMsg = KernelTools::tra( "Group changes were saved sucessfully." ); - } else { - $errorMsg = $gBitUser->mErrors['groups']; - } - // Update Permissions - } elseif (isset($_REQUEST['updateperms'])) { - $listHash = [ 'group_id' => $_REQUEST['group_id'] ]; - $updatePerms = $gBitUser->getgroupPermissions( $listHash ); - foreach (array_keys($_REQUEST['perm']) as $per) { - if( isset($_REQUEST['perm'][$per]) && !isset($updatePerms[$per]) ) { - // we have an unselected perm that is now selected - $gBitUser->assignPermissionToGroup($per, $_REQUEST['group_id']); - } elseif( empty($_REQUEST['perm'][$per]) && isset($updatePerms[$per]) ) { - // we have a selected perm that is now UNselected - $gBitUser->removePermissionFromGroup($per, $_REQUEST['group_id']); - } - } - // let's reload just to be safe. - $allPerms = $gBitUser->getGroupPermissions(); - // Do some action - } elseif (isset($_REQUEST["action"])) { - // Process a form to remove a group - if( $_REQUEST["action"] == 'delete' ) { - if( $gBitUser->getDefaultGroup( $_REQUEST['group_id'] ) ) { - $errorMsg = KernelTools::tra( "You cannot remove this group, as it is currently set as your 'Default' group" ); - } else { - $gBitUser->expungeGroup( $_REQUEST['group_id'] ); - $successMsg = KernelTools::tra( "The group was deleted."); - unset( $_REQUEST['group_id'] ); - } - // remove a permission from a group - } elseif ($_REQUEST["action"] == 'remove') { - $gBitUser->removePermissionFromGroup( $_REQUEST["permission"], $_REQUEST['group_id'] ); - $successMsg = KernelTools::tra( "Permission Removed"); - $mid = 'bitpackage:users/my_group_edit.tpl'; - // Create a new group - } elseif( $_REQUEST["action"] == 'create' ) { - $gBitSystem->setBrowserTitle( KernelTools::tra( 'Create New Group') ); - $mid = 'bitpackage:users/my_group_edit.tpl'; - // Assign a permission to a group - } elseif ($_REQUEST["action"] == 'assign') { - $gBitUser->assignPermissionToGroup($_REQUEST["perm"], $_REQUEST['group_id']); - $successMsg = KernelTools::tra( "Permission Assigned" ); - $mid = 'bitpackage:users/my_group_edit.tpl'; - } - // Search for users to add - } elseif (!empty($_REQUEST['submitUserSearch'])) { - $searchParams = ['find' => $_REQUEST['find']]; - $gBitUser->getList($searchParams); - $foundUsers = $searchParams['data']; - $mid = 'bitpackage:users/my_group_edit.tpl'; - $gBitSmarty->assign('foundUsers', $foundUsers); - } elseif (!empty($_REQUEST['assignuser'])) { - if( !empty($_REQUEST['group_id'] ) ) { - if ($_REQUEST['group_id'] != -1 && $groupList[$_REQUEST['group_id']]['user_id'] == $gBitUser->mUserId) { - $gBitUser->addUserToGroup( $_REQUEST['assignuser'], $_REQUEST['group_id'] ); - } - else { - $errorMsg = KernelTools::tra( "You can not assign users to this group." ); - } - } - $mid = 'bitpackage:users/my_group_edit.tpl'; - } - - // get pagination url - // get grouplist separately from the $users stuff to avoid splitting of data due to pagination - $listHash = [ 'sort_mode' => 'group_name_asc' ]; - $groupList = $gBitUser->getAllUserGroups(); - - if( !empty( $_REQUEST['group_id'] ) ) { - // we don't want our own group listed when editing - if( !empty( $groupList[$_REQUEST['group_id']] ) ) { - unset( $groupList[$_REQUEST['group_id']] ); - } - $groupInfo = $gBitUser->getGroupInfo( $_REQUEST['group_id'] ); - $groupUsers = $gBitUser->getGroupUsers( $_REQUEST['group_id'] ); - $gBitSmarty->assign('groupUsers', $groupUsers); - $gBitSmarty->assign('groupInfo', $groupInfo); - $gBitSmarty->assign( 'allPerms', $allPerms ); - $gBitSystem->setBrowserTitle( 'Admininster Group: '.$groupInfo['group_name'].' '.($_REQUEST['tab'] ?? '') ); - $mid = 'bitpackage:users/my_group_edit.tpl'; - } - - $gBitSmarty->assign('groups', $groupList); - // $gBitSmarty->assign( (!empty( $_REQUEST['tab'] ) ? $_REQUEST['tab'] : 'edit').'TabSelect', 'tdefault' ); -} - -/* join or leave a public group. */ -if ( ( !empty( $_REQUEST['add_public_group'] ) || !empty( $_REQUEST['remove_public_group'] ) ) && !empty( $_REQUEST['public_group_id'] ) ) { - $groupInfo = $gBitUser->getGroupInfo( $_REQUEST['public_group_id'] ); - if ( empty($groupInfo) || $groupInfo['is_public'] != 'y' ) { - if (empty($_REQUEST['add_public_group'])) { - $errorMsg[] = KernelTools::tra( "You can't join this group." ); - } - else { - $errorMsg[] = KernelTools::tra( "You can't leave this group." ); - } - } elseif ( !empty( $_REQUEST['add_public_group'] ) ) { - $gBitUser->addUserToGroup( $gBitUser->mUserId, $_REQUEST['public_group_id'] ); - } elseif ( !empty( $_REQUEST['remove_public_group'] ) ) { - $gBitUser->removeUserFromGroup( $gBitUser->mUserId, $_REQUEST['public_group_id'] ); - } - $gBitUser->loadPermissions(); - if ( !empty( $_REQUEST['add_public_group'] ) && !empty( $groupInfo['after_registration_page'] ) ) { - if ( $gBitUser->verifyId( $groupInfo['after_registration_page'] ) ) { - $url = BIT_ROOT_URL."index.php?content_id=".$groupInfo['after_registration_page']; - } elseif( strpos( $groupInfo['after_registration_page'], '/' ) === false ) { - $url = BitPage::getDisplayUrlFromHash( $groupInfo['after_registration_page'] ); - } else { - $url = $groupInfo['after_registration_page']; - } - bit_redirect( $url ); - } -} - -/* Load up public groups and check if the user can join or leave them */ -$systemGroups = $gBitUser->getGroups( $gBitUser->mUserId, true ); -$gBitSmarty->assign( 'systemGroups', $systemGroups); -$listHash = [ - 'is_public'=>'y', - 'sort_mode' => [ 'is_default_asc', 'group_desc_asc' ], -]; -$publicGroups = $gBitUser->getAllGroups( $listHash ); -if( count( $publicGroups )) { - foreach ( $systemGroups as $groupId=>$groupInfo ) { - foreach ( $publicGroups as $key=>$publicGroup) { - if ( $publicGroups[$key]['group_id'] == $groupId) { - if ($publicGroups[$key]['is_default'] != 'y' ) { - $systemGroups[$groupId]['public'] = 'y'; - $canRemovePublic = 'y'; - } - $publicGroups[$key]['used'] = 'y'; - break; - } - } - } - foreach ( $publicGroups as $groupInfo) { - if ( empty($groupInfo['used'] ) && $groupInfo['is_default'] != 'y' ) { - $gBitSmarty->assign( 'canAddPublic' , 'y'); - break; - } - } - $gBitSmarty->assign( 'publicGroups', $publicGroups ); - if (isset($canRemovePublic)) { - $gBitSmarty->assign( 'canRemovePublic' , 'y'); - } -} - -// Remember error and success messages. -if (!empty($errorMsg)) { - $gBitSmarty->assign('errorMsg',$errorMsg); -} -if (!empty($successMsg)) { - $gBitSmarty->assign('successMsg',$successMsg); -} - -// Default the template if we aren't doing an edit. -if (empty($mid)) { - $mid = 'bitpackage:users/my_groups_list.tpl'; -} - -// Display the template for group administration -$gBitSystem->display( $mid , null, [ 'display_mode' => 'display' ]); -?> diff --git a/preferences.php b/preferences.php index d4f122c..d9d36b4 100755 --- a/preferences.php +++ b/preferences.php @@ -27,8 +27,7 @@ $feedback = []; // set up the user we're editing if( !empty( $_REQUEST["view_user"] ) && $_REQUEST["view_user"] <> $gBitUser->mUserId ) { $gBitSystem->verifyPermission( 'p_users_admin' ); - $userClass = '\Bitweaver\Users\\'.$gBitSystem->getConfig( 'user_class', (defined('ROLE_MODEL') ) ? 'RolePermUser' : 'BitPermUser' ); - $editUser = new $userClass( $_REQUEST["view_user"] ); + $editUser = new RolePermUser( $_REQUEST["view_user"] ); $editUser->load( true ); $gBitSmarty->assign('view_user', $_REQUEST["view_user"]); $watches = $editUser->getWatches(); diff --git a/role_register.php b/role_register.php index 23af889..1ed995b 100755 --- a/role_register.php +++ b/role_register.php @@ -48,8 +48,7 @@ if( isset( $_REQUEST["register"] ) ) { $reg = $_REQUEST; // Register the new user - $userClass = $gBitSystem->getConfig( 'user_class', 'BitPermUser' ); - $newUser = new $userClass(); + $newUser = new RolePermUser(); if( $newUser->preRegisterVerify( $reg ) && $newUser->register( $reg ) ) { $gBitUser->mUserId = $newUser->mUserId; |
