Skip to content
This repository has been archived by the owner on Dec 27, 2023. It is now read-only.

Commit

Permalink
feature(Tinebase Webfinger) add /.well-known/webfinger partial suppor…
Browse files Browse the repository at this point in the history
…t (rfc 7033)
  • Loading branch information
paulmhh committed Aug 5, 2021
1 parent ac76c90 commit 5e67fa6
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 1 deletion.
59 changes: 58 additions & 1 deletion tests/tine20/Tinebase/ControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* @package Tinebase
* @subpackage Account
* @license http://www.gnu.org/licenses/agpl.html
* @copyright Copyright (c) 2010-2011 Metaways Infosystems GmbH (http://www.metaways.de)
* @copyright Copyright (c) 2010-2021 Metaways Infosystems GmbH (http://www.metaways.de)
* @author Philipp Schüle <p.schuele@metaways.de>
*
* @todo make testLoginAndLogout work (needs to run in separate process)
Expand Down Expand Up @@ -271,6 +271,63 @@ public function testGetStatusNoApiKey()
Tinebase_Controller::getInstance()->getStatus();
}

public function testWebfinger()
{
$relHandler = Tinebase_Config::getInstance()->{Tinebase_Config::WEBFINGER_REL_HANDLER};
$relHandler['b'] = [self::class, 'webfingerHandlerMock'];
Tinebase_Config::getInstance()->{Tinebase_Config::WEBFINGER_REL_HANDLER} = $relHandler;

$emitter = new Tinebase_Server_UnittestEmitter();
$server = new Tinebase_Server_Expressive($emitter);

$request = \Zend\Psr7Bridge\Psr7ServerRequest::fromZend(Tinebase_Http_Request::fromString(
'GET /.well-known/webfinger?resource=a&rel=b HTTP/1.1' . "\r\n"
. 'Host: localhost' . "\r\n"
. 'User-Agent: Mozilla/5.0 (X11; Linux i686; rv:15.0) Gecko/20120824 Thunderbird/15.0 Lightning/1.7' . "\r\n"
. 'Accept: */*' . "\r\n"
. 'Referer: http://tine20.vagrant/' . "\r\n"
. 'Accept-Encoding: gzip, deflate' . "\r\n"
. 'Accept-Language: en-US,en;q=0.8,de-DE;q=0.6,de;q=0.4' . "\r\n\r\n"
));

/** @var \Symfony\Component\DependencyInjection\Container $container */
$container = Tinebase_Core::getPreCompiledContainer();
$container->set(\Psr\Http\Message\RequestInterface::class, $request);
Tinebase_Core::setContainer($container);

$server->handle();

$this->assertSame('application/jrd+json', $emitter->response->getHeader('Content-Type')[0]);

$this->assertIsArray($jsonResponse = json_decode((string)$emitter->response->getBody(), true));
$this->assertArrayHasKey('subject', $jsonResponse);
$this->assertSame('a', $jsonResponse['subject']);

$this->assertArrayHasKey('aliases', $jsonResponse);
$this->assertEmpty($jsonResponse['aliases']);

$this->assertArrayHasKey('properties', $jsonResponse);
$this->assertEmpty($jsonResponse['properties']);

$this->assertArrayHasKey('links', $jsonResponse);
$this->assertArrayHasKey(0, $jsonResponse['links']);
$this->assertSame([
'rel' => 'b',
'href' => 'c'
], $jsonResponse['links'][0]);
$this->assertCount(1, $jsonResponse['links']);

$this->assertCount(4, $jsonResponse);
}

public static function webfingerHandlerMock(&$result)
{
$result['links'][] = [
'rel' => 'b',
'href' => 'c'
];
}

public function testGetFaviconLegacy()
{
$icon = './images/favicon.png';
Expand Down
10 changes: 10 additions & 0 deletions tine20/Tinebase/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -688,6 +688,8 @@ class Tinebase_Config extends Tinebase_Config_Abstract
*/
const WEBDAV_SYNCTOKEN_ENABLED = 'webdavSynctokenEnabled';

const WEBFINGER_REL_HANDLER = 'webfingerRelHandler';

/**
* @var string
*/
Expand Down Expand Up @@ -1925,6 +1927,14 @@ class Tinebase_Config extends Tinebase_Config_Abstract
),
],
),
self::WEBFINGER_REL_HANDLER => [
self::LABEL => 'Webfinder Rel Handler',
self::TYPE => self::TYPE_ARRAY,
self::CLIENTREGISTRYINCLUDE => false,
self::SETBYADMINMODULE => false,
self::SETBYSETUPMODULE => false,
self::DEFAULT_STR => [],
],
self::DOWNLOAD_PASSWORD_POLICY => array(
//_('Download password policy')
'label' => 'Download password policy',
Expand Down
6 changes: 6 additions & 0 deletions tine20/Tinebase/Controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -1081,6 +1081,12 @@ public static function addFastRoutes(
Tinebase_Expressive_RouteHandler::IS_PUBLIC => true
]))->toArray());
});
$r->addGroup('/.well-known', function (\FastRoute\RouteCollector $routeCollector) {
$routeCollector->get('/webfinger', (new Tinebase_Expressive_RouteHandler(
Tinebase_Webfinger::class, 'handlePublicGet', [
Tinebase_Expressive_RouteHandler::IS_PUBLIC => true
]))->toArray());
});
}

/**
Expand Down
47 changes: 47 additions & 0 deletions tine20/Tinebase/Webfinger.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php declare(strict_types=1);

class Tinebase_Webfinger
{
/**
* Tinebase_Expressive_RoutHandler function
*
* @return \Zend\Diactoros\Response
*/
public static function handlePublicGet(): \Zend\Diactoros\Response
{
/** @var \Zend\Diactoros\ServerRequest $request */
$request = Tinebase_Core::getContainer()->get(\Psr\Http\Message\RequestInterface::class);
$params = $request->getQueryParams();
if (!isset($params['resource']) || !isset($params['rel'])) {
return static::badRequest();
}
$resource = $params['resource'];
$rel = $params['rel'];

$response = new \Zend\Diactoros\Response('php://memory', 200, [
'Access-Control-Allow-Origin' => '*',
'Content-Type' => 'application/jrd+json'
]);

$result = [
'subject' => $resource,
'aliases' => [],
'properties' => [],
'links' => []
];

$relHandler = Tinebase_Config::getInstance()->{Tinebase_Config::WEBFINGER_REL_HANDLER};
if (isset($relHandler[$rel])) {
call_user_func_array($relHandler[$rel], [&$result]);
}

$response->getBody()->write(json_encode($result));

return $response;
}

protected static function badRequest(): \Zend\Diactoros\Response
{
return new \Zend\Diactoros\Response('php://memory', 400);
}
}

0 comments on commit 5e67fa6

Please sign in to comment.