diff options
-rw-r--r-- | Zotlabs/Module/Magic.php | 8 | ||||
-rw-r--r-- | tests/unit/Module/MagicTest.php | 109 |
2 files changed, 115 insertions, 2 deletions
diff --git a/Zotlabs/Module/Magic.php b/Zotlabs/Module/Magic.php index 8259f7d39..deda4255d 100644 --- a/Zotlabs/Module/Magic.php +++ b/Zotlabs/Module/Magic.php @@ -40,7 +40,11 @@ class Magic extends Controller { goaway($dest); } - $basepath = $parsed['scheme'] . '://' . $parsed['host'] . (isset($parsed['port']) ? ':' . $parsed['port'] : ''); + $basepath = unparse_url(array_filter( + $parsed, + fn (string $key) => in_array($key, ['scheme', 'host', 'port']), + ARRAY_FILTER_USE_KEY + )); $owapath = SConfig::get($basepath,'system','openwebauth', $basepath . '/owa'); // This is ready-made for a plugin that provides a blacklist or "ask me" before blindly authenticating. @@ -106,7 +110,7 @@ class Magic extends Controller { $headers['Content-Type'] = 'application/x-zot+json' ; $headers['X-Open-Web-Auth'] = random_string(); $headers['Host'] = $parsed['host']; - $headers['(request-target)'] = 'get ' . '/owa'; + $headers['(request-target)'] = 'get /owa'; $headers = HTTPSig::create_sig($headers,$channel['channel_prvkey'], channel_url($channel),true,'sha512'); $redirects = 0; diff --git a/tests/unit/Module/MagicTest.php b/tests/unit/Module/MagicTest.php new file mode 100644 index 000000000..4d50412ee --- /dev/null +++ b/tests/unit/Module/MagicTest.php @@ -0,0 +1,109 @@ +<?php +/** + * Tests for the Magic module + * + * SPDX-FileCopyrightText: 2024 Hubzilla Community + * SPDX-FileContributor: Harald Eilertsen + * + * SPDX-License-Identifier: MIT + */ + +namespace Zotlabs\Tests\Unit\Module; + +use PHPUnit\Framework\Attributes\BackupStaticProperties; +use Zotlabs\Module\Magic; +use App; + +class MagicTest extends TestCase { + + public function test_init_with_no_args(): void { + // Since no parameters are passed, nothing will really be done. + // Neither the delegate nor the owa functionality will be invoked, + // but at the end the code will try to redirect to an empty + // URL. + // + // This should probably return a 400 Invalid Request instead. + $this->expectRedirectTo(''); + + $this->get('magic'); + } + + #[BackupStaticProperties(App::class)] + public function test_local_request_without_delegate(): void { + $baseurl = 'https://hubzilla.test'; + $dest_url = $baseurl . '/channel/testuser'; + + App::set_baseurl($baseurl); + + App::$observer = [ + 'xchan_hash' => 'the hash', + ]; + + // We pass a local URL, and have a valid observer, but as the + // delegate param is not passed, nothing will be done except + // redirecting to the passed dest url. + // + // This should probably return a 400 Invalid Request instead. + $this->expectRedirectTo($dest_url); + + $this->get('magic', [ 'bdest' => bin2hex($dest_url) ]); + } + + #[BackupStaticProperties(App::class)] + public function test_delegate_request_switches_channel_when_allowed(): void { + $baseurl = 'https://hubzilla.test'; + $dest_url = $baseurl . '/channel/testuser'; + + // Set the stage: + // Populate the global static App class with necessary values for the + // code under test + App::set_baseurl($baseurl); + App::$timezone = 'UTC'; + + // Simulate a foreign (to this hub) observer, + App::$observer = [ + 'xchan_hash' => 'foreign hash', + ]; + + // Create the channel the foreign observer wants to access + $result = create_identity([ + 'account_id' => $this->fixtures['account'][0]['account_id'], + 'nickname' => 'testuser', + 'name' => 'Trish Testuser', + ]); + + // Shortcut the permission checks, by saying this observer is allowed + // the delegate privilege over the target channel + insert_hook('perm_is_allowed', function (array &$perm) { + $perm['result'] = true; + }); + + // Add some dummy session data, so we can check that it's being + // pushed to the delegate session. + $original_session = [ + 'data' => 'Just some test session data', + ]; + + $_SESSION = $original_session; + + // Handle redirects manually, since we want to be able to check some + // assertions after the redirect is thrown. + $this->stub_goaway(); + + try { + // Send a request to get delegate privileges for the `testuser` channel + // on the local hub. + $this->get('magic', [ + 'bdest' => bin2hex($dest_url), + 'delegate' => 'testuser@hubzilla.test'] + ); + } catch (RedirectException $e) { + $this->assertEquals($dest_url, $e->getMessage()); + $this->assertEquals($result['channel']['channel_id'], App::$channel['channel_id']); + $this->assertEquals($original_session, $_SESSION['delegate_push']); + $this->assertEquals($result['channel']['channel_id'], $_SESSION['delegate_channel']); + $this->assertEquals('foreign hash', $_SESSION['delegate']); + $this->assertEquals($this->fixtures['account'][0]['account_id'], $_SESSION['account_id']); + } + } +} |