egroupware/api/tests/LoggedInTest.php
Ralf Becker 4886583cc1 change sharing to allow mounting shared into existing user sessions
without the need to destroy the session, if the sharee is a different user

This is accomplished by keeping the sharee in the stream context / attribute of the vfs class(es) instead of static Vfs::$user.
Later is still used for the current user - identical to egw_info[user][account_id].

This commit / merge of the vfs-context feature branch also added the abilty to mount WebDAV sources, eg. a sharing link from an other EGroupware instance
or any WebDAV server
2020-10-08 11:24:34 +02:00

257 lines
7.3 KiB
PHP

<?php
/**
* EGroupware Api: Test base class for when you need an Egroupware session for
* the class or test
*
* @link http://www.stylite.de
* @package api
* @subpackage test
* @author Nathan Gray
* @copyright (c) 2016 Nathan Gray
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @version $Id$
*/
namespace EGroupware\Api;
use PHPUnit\Framework\TestCase as TestCase;
use EGroupware\Api;
/**
* Base class for tests, loads the egroupware environment
*
* It's not best practice to require the session for every test, but so much
* is reliant on the session that it's just easier. By "not best practice",
* I mean this is pretty bad, but better than manual testing.
*
* Each test case (extending class) should get its own session, but session is
* shared between tests inside.
*
* The login information is pulled from doc/phpunit.xml. Run tests from the
* command line using 'phpunit -c doc'
*/
abstract class LoggedInTest extends TestCase
{
/**
* Start session once before each test case
*/
public static function setUpBeforeClass() : void
{
try
{
// These globals pulled from the test config (phpunit.xml)
static::load_egw($GLOBALS['EGW_USER'],$GLOBALS['EGW_PASSWORD'], $GLOBALS['EGW_DOMAIN']);
if($GLOBALS['egw']->db)
{
$GLOBALS['egw']->db->connect();
}
else
{
static::markTestSkipped('No $GLOBALS[egw]->db');
die();
}
// Re-init config, since it doesn't get handled by loading Egw
Api\Config::init_static();
Api\Vfs::init_static();
}
catch(Exception $e)
{
static::markTestSkipped('Unable to connect to Egroupware - ' . $e->getMessage());
return;
}
}
protected function assertPreConditions() : void
{
// Do some checks to make sure things we expect are there
$this->assertTrue(static::sanity_check(), 'Unable to connect to Egroupware - failed sanity check');
}
/**
* End session when done - every test class gets its own session
*/
public static function tearDownAfterClass() : void
{
// Clean up VFS
Vfs::clearstatcache();
// Reset stream context, or current user will always be there
stream_context_set_option(stream_context_get_default(),['vfs'=>['user' => null]]);
// Clear some link caching
Link::init_static(true);
if($GLOBALS['egw'])
{
if($GLOBALS['egw']->session)
{
$GLOBALS['egw']->session->destroy(
$GLOBALS['egw']->session->sessionid,
$GLOBALS['egw']->session->kp3
);
}
if($GLOBALS['egw']->acl)
{
$GLOBALS['egw']->acl = null;
}
if($GLOBALS['egw']->accounts)
{
$GLOBALS['egw']->accounts = null;
}
if($GLOBALS['egw']->applications)
{
$GLOBALS['egw']->applications = null;
}
if($GLOBALS['egw']->db)
{
$GLOBALS['egw']->db->disconnect();
}
unset($GLOBALS['egw']);
}
Api\Session::egw_setcookie('sessionid');
Api\Session::egw_setcookie('kp3');
unset($GLOBALS['egw_info']);
unset($GLOBALS['_SESSION']);
$_SESSION = array();
}
/**
* Start the eGW session, skips the test if there are problems connecting
*
* @param string $user
* @param string $passwd
* @param string $domain
*/
public static function load_egw($user,$passwd,$domain='default',$info=array())
{
$_REQUEST['domain'] = $domain;
$GLOBALS['egw_login_data'] = array(
'login' => $user,
'passwd' => $passwd,
'passwd_type' => 'text',
);
if(!$info)
{
$info = array(
'flags' => array(
'currentapp' => 'api',
'noheader' => true,
'autocreate_session_callback' => __CLASS__ .'::create_session',
'no_exception_handler' => 'cli',
'noapi' => false,
)
);
}
$GLOBALS['egw_info'] = $info;
$ob_level = ob_get_level();
try
{
include(realpath(__DIR__ . '/../../header.inc.php'));
}
catch (Exception $e)
{
// Something went wrong setting up egw environment - don't try
// to do the test
static::markTestSkipped($e->getMessage());
return;
}
require_once realpath(__DIR__.'/../src/loader/common.php'); // autoloader & check_load_extension
// egw is normally created when a file is loaded using require_once
if(empty($GLOBALS['egw']) || !is_a($GLOBALS['egw'], 'EGroupware\Api\Egw\Base'))
{
// From Api/src/loader.php
$GLOBALS['egw_info']['user']['domain'] = Api\Session::search_instance(
isset($_POST['login']) ? $_POST['login'] : (isset($_SERVER['PHP_AUTH_USER']) ? $_SERVER['PHP_AUTH_USER'] : $_SERVER['REMOTE_USER']),
Api\Session::get_request('domain'),$GLOBALS['egw_info']['server']['default_domain'],
array($_SERVER['HTTP_HOST'], $_SERVER['SERVER_NAME']),$GLOBALS['egw_domain']);
$GLOBALS['egw_info']['server']['db_host'] = $GLOBALS['egw_domain'][$GLOBALS['egw_info']['user']['domain']]['db_host'];
$GLOBALS['egw_info']['server']['db_port'] = $GLOBALS['egw_domain'][$GLOBALS['egw_info']['user']['domain']]['db_port'];
$GLOBALS['egw_info']['server']['db_name'] = $GLOBALS['egw_domain'][$GLOBALS['egw_info']['user']['domain']]['db_name'];
$GLOBALS['egw_info']['server']['db_user'] = $GLOBALS['egw_domain'][$GLOBALS['egw_info']['user']['domain']]['db_user'];
$GLOBALS['egw_info']['server']['db_pass'] = $GLOBALS['egw_domain'][$GLOBALS['egw_info']['user']['domain']]['db_pass'];
$GLOBALS['egw_info']['server']['db_type'] = $GLOBALS['egw_domain'][$GLOBALS['egw_info']['user']['domain']]['db_type'];
$GLOBALS['egw'] = new Api\Egw(array_keys($GLOBALS['egw_domain']));
}
// load up the $GLOBALS['egw_info']['server'] array
$GLOBALS['egw_info']['server'] += Config::read('phpgwapi');
// Make sure user is properly set
$GLOBALS['egw_info']['user'] = $GLOBALS['egw']->session->read_repositories();
// Disable asyc while we test
$GLOBALS['egw_info']['server']['asyncservice'] = 'off';
// Set up Vfs
Vfs::init_static();
Vfs\StreamWrapper::init_static();
while(ob_get_level() > $ob_level)
{
ob_end_flush();
}
}
/**
* callback to authenticate with the user/pw specified on the commandline
*
* @param array &$account account_info with keys 'login', 'passwd' and optional 'passwd_type'
* @return boolean/string true if we allow the access and account is set, a sessionid or false otherwise
*/
public static function create_session(&$account)
{
if (!($sessionid = $GLOBALS['egw']->session->create($GLOBALS['egw_login_data'])))
{
if(!($reason = $GLOBALS['egw']->session->reason) && $GLOBALS['egw']->session->account_id)
{
$GLOBALS['egw']->session->sessionid = 'CLI';
return 'CLI';
}
die($reason ? $reason : "Wrong account or password - run tests with 'phpunit -c doc/phpunit.xml' or 'phpunit <test_dir> -c doc/phpunit.xml'\n\n");
}
unset($GLOBALS['egw_login_data']);
return $sessionid;
}
/**
* Do some checks to make sure things we expect are there
*/
protected static function sanity_check()
{
// Check that the apps are loaded
if(!array_key_exists('apps', $GLOBALS['egw_info']) || count($GLOBALS['egw_info']['apps']) == 0)
{
return false;
}
// Check that the user is loaded
if(!array_key_exists('user', $GLOBALS['egw_info']) || !$GLOBALS['egw_info']['user']['account_id'])
{
return false;
}
return true;
}
/**
* Log out the current user, log in as the given user
*
* @param $account_lid
* @param $password
*/
protected function switchUser($account_lid, $password)
{
// Log out
self::tearDownAfterClass();
// Log in
static::load_egw($account_lid,$password);
}
}