mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
Dav: implements JWT extraction from the URL, and add the access_token in dav urls
This commit is contained in:
parent
146e0090fb
commit
6f6683f549
@ -15,6 +15,7 @@ use Chill\DocStoreBundle\Dav\Request\PropfindRequestAnalyzer;
|
|||||||
use Chill\DocStoreBundle\Dav\Response\DavResponse;
|
use Chill\DocStoreBundle\Dav\Response\DavResponse;
|
||||||
use Chill\DocStoreBundle\Entity\StoredObject;
|
use Chill\DocStoreBundle\Entity\StoredObject;
|
||||||
use Chill\DocStoreBundle\Service\StoredObjectManagerInterface;
|
use Chill\DocStoreBundle\Service\StoredObjectManagerInterface;
|
||||||
|
use DateTimeInterface;
|
||||||
use Lexik\Bundle\JWTAuthenticationBundle\Services\JWTTokenManagerInterface;
|
use Lexik\Bundle\JWTAuthenticationBundle\Services\JWTTokenManagerInterface;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
@ -30,41 +31,44 @@ final readonly class WebdavController
|
|||||||
public function __construct(
|
public function __construct(
|
||||||
private \Twig\Environment $engine,
|
private \Twig\Environment $engine,
|
||||||
private StoredObjectManagerInterface $storedObjectManager,
|
private StoredObjectManagerInterface $storedObjectManager,
|
||||||
|
private Security $security,
|
||||||
|
private ?JWTTokenManagerInterface $JWTTokenManager = null,
|
||||||
) {
|
) {
|
||||||
$this->requestAnalyzer = new PropfindRequestAnalyzer();
|
$this->requestAnalyzer = new PropfindRequestAnalyzer();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Route("/dav/open/{uuid}")
|
* @Route("/chdoc/open/{uuid}")
|
||||||
*/
|
*/
|
||||||
public function open(StoredObject $storedObject): Response
|
public function open(StoredObject $storedObject): Response
|
||||||
{
|
{
|
||||||
/*$accessToken = $this->JWTTokenManager->createFromPayload($this->security->getUser(), [
|
$accessToken = $this->JWTTokenManager?->createFromPayload($this->security->getUser(), [
|
||||||
'UserCanWrite' => true,
|
'UserCanWrite' => true,
|
||||||
'UserCanAttend' => true,
|
'UserCanAttend' => true,
|
||||||
'UserCanPresent' => true,
|
'UserCanPresent' => true,
|
||||||
'fileId' => $storedObject->getUuid(),
|
'fileId' => $storedObject->getUuid(),
|
||||||
]);*/
|
]);
|
||||||
|
|
||||||
return new DavResponse($this->engine->render('@ChillDocStore/Webdav/open_in_browser.html.twig', [
|
return new DavResponse($this->engine->render('@ChillDocStore/Webdav/open_in_browser.html.twig', [
|
||||||
'stored_object' => $storedObject, 'access_token' => '',
|
'stored_object' => $storedObject, 'access_token' => $accessToken,
|
||||||
]));
|
]));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Route("/dav/get/{uuid}/", methods={"GET", "HEAD"}, name="chill_docstore_dav_directory_get")
|
* @Route("/dav/{access_token}/get/{uuid}/", methods={"GET", "HEAD"}, name="chill_docstore_dav_directory_get")
|
||||||
*/
|
*/
|
||||||
public function getDirectory(StoredObject $storedObject): Response
|
public function getDirectory(StoredObject $storedObject, string $access_token): Response
|
||||||
{
|
{
|
||||||
return new DavResponse(
|
return new DavResponse(
|
||||||
$this->engine->render('@ChillDocStore/Webdav/directory.html.twig', [
|
$this->engine->render('@ChillDocStore/Webdav/directory.html.twig', [
|
||||||
'stored_object' => $storedObject
|
'stored_object' => $storedObject,
|
||||||
|
'access_token' => $access_token,
|
||||||
])
|
])
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Route("/dav/get/{uuid}/", methods={"OPTIONS"})
|
* @Route("/dav/{access_token}/get/{uuid}/", methods={"OPTIONS"})
|
||||||
*/
|
*/
|
||||||
public function optionsDirectory(StoredObject $storedObject): Response
|
public function optionsDirectory(StoredObject $storedObject): Response
|
||||||
{
|
{
|
||||||
@ -78,9 +82,9 @@ final readonly class WebdavController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Route("/dav/get/{uuid}/", methods={"PROPFIND"})
|
* @Route("/dav/{access_token}/get/{uuid}/", methods={"PROPFIND"})
|
||||||
*/
|
*/
|
||||||
public function propfindDirectory(StoredObject $storedObject, Request $request): Response
|
public function propfindDirectory(StoredObject $storedObject, string $access_token, Request $request): Response
|
||||||
{
|
{
|
||||||
$depth = $request->headers->get('depth');
|
$depth = $request->headers->get('depth');
|
||||||
|
|
||||||
@ -111,10 +115,11 @@ final readonly class WebdavController
|
|||||||
$this->engine->render('@ChillDocStore/Webdav/directory_propfind.xml.twig', [
|
$this->engine->render('@ChillDocStore/Webdav/directory_propfind.xml.twig', [
|
||||||
'stored_object' => $storedObject,
|
'stored_object' => $storedObject,
|
||||||
'properties' => $properties,
|
'properties' => $properties,
|
||||||
'last_modified' => $lastModified ?? null,
|
'last_modified' => $lastModified ,
|
||||||
'etag' => $etag ?? null,
|
'etag' => $etag,
|
||||||
'content_length' => $length ?? null,
|
'content_length' => $length,
|
||||||
'depth' => (int) $depth
|
'depth' => (int) $depth,
|
||||||
|
'access_token' => $access_token,
|
||||||
]),
|
]),
|
||||||
207
|
207
|
||||||
);
|
);
|
||||||
@ -127,7 +132,7 @@ final readonly class WebdavController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Route("/dav/get/{uuid}/d", name="chill_docstore_dav_document_get", methods={"GET"})
|
* @Route("/dav/{access_token}/get/{uuid}/d", name="chill_docstore_dav_document_get", methods={"GET"})
|
||||||
*/
|
*/
|
||||||
public function getDocument(StoredObject $storedObject): Response
|
public function getDocument(StoredObject $storedObject): Response
|
||||||
{
|
{
|
||||||
@ -136,7 +141,7 @@ final readonly class WebdavController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Route("/dav/get/{uuid}/d", methods={"HEAD"})
|
* @Route("/dav/{access_token}/get/{uuid}/d", methods={"HEAD"})
|
||||||
*/
|
*/
|
||||||
public function headDocument(StoredObject $storedObject): Response
|
public function headDocument(StoredObject $storedObject): Response
|
||||||
{
|
{
|
||||||
@ -154,7 +159,7 @@ final readonly class WebdavController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Route("/dav/get/{uuid}/d", methods={"OPTIONS"})
|
* @Route("/dav/{access_token}/get/{uuid}/d", methods={"OPTIONS"})
|
||||||
*/
|
*/
|
||||||
public function optionsDocument(StoredObject $storedObject): Response
|
public function optionsDocument(StoredObject $storedObject): Response
|
||||||
{
|
{
|
||||||
@ -176,9 +181,9 @@ final readonly class WebdavController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Route("/dav/get/{uuid}/d", methods={"PROPFIND"})
|
* @Route("/dav/{access_token}/get/{uuid}/d", methods={"PROPFIND"})
|
||||||
*/
|
*/
|
||||||
public function propfindDocument(StoredObject $storedObject, Request $request): Response
|
public function propfindDocument(StoredObject $storedObject, string $access_token, Request $request): Response
|
||||||
{
|
{
|
||||||
$content = $request->getContent();
|
$content = $request->getContent();
|
||||||
$xml = new \DOMDocument();
|
$xml = new \DOMDocument();
|
||||||
@ -204,9 +209,10 @@ final readonly class WebdavController
|
|||||||
[
|
[
|
||||||
'stored_object' => $storedObject,
|
'stored_object' => $storedObject,
|
||||||
'properties' => $properties,
|
'properties' => $properties,
|
||||||
'etag' => $etag ?? null,
|
'etag' => $etag,
|
||||||
'last_modified' => $lastModified ?? null,
|
'last_modified' => $lastModified,
|
||||||
'content_length' => $length ?? null,
|
'content_length' => $length,
|
||||||
|
'access_token' => $access_token,
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
207
|
207
|
||||||
@ -221,7 +227,7 @@ final readonly class WebdavController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Route("/dav/get/{uuid}/d", methods={"PUT"})
|
* @Route("/dav/{access_token}/get/{uuid}/d", methods={"PUT"})
|
||||||
*/
|
*/
|
||||||
public function putDocument(StoredObject $storedObject, Request $request): Response
|
public function putDocument(StoredObject $storedObject, Request $request): Response
|
||||||
{
|
{
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="{{ absolute_url(path('chill_docstore_dav_document_get', {'uuid': stored_object.uuid })) }}">d</a></li>
|
<li><a href="{{ absolute_url(path('chill_docstore_dav_document_get', {'uuid': stored_object.uuid, 'access_token': access_token })) }}">d</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" ?>
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
<d:multistatus xmlns:d="DAV:">
|
<d:multistatus xmlns:d="DAV:">
|
||||||
<d:response>
|
<d:response>
|
||||||
<d:href>{{ path('chill_docstore_dav_directory_get', { 'uuid': stored_object.uuid } ) }}</d:href>
|
<d:href>{{ path('chill_docstore_dav_directory_get', { 'uuid': stored_object.uuid, 'access_token': access_token } ) }}</d:href>
|
||||||
{% if properties.resourceType or properties.contentType %}
|
{% if properties.resourceType or properties.contentType %}
|
||||||
<d:propstat>
|
<d:propstat>
|
||||||
<d:prop>
|
<d:prop>
|
||||||
@ -28,7 +28,7 @@
|
|||||||
</d:response>
|
</d:response>
|
||||||
{% if depth == 1 %}
|
{% if depth == 1 %}
|
||||||
<d:response>
|
<d:response>
|
||||||
<d:href>{{ path('chill_docstore_dav_document_get', {'uuid': stored_object.uuid}) }}</d:href>
|
<d:href>{{ path('chill_docstore_dav_document_get', {'uuid': stored_object.uuid, 'access_token':access_token}) }}</d:href>
|
||||||
{% if properties.lastModified or properties.contentLength or properties.resourceType or properties.etag or properties.contentType or properties.creationDate %}
|
{% if properties.lastModified or properties.contentLength or properties.resourceType or properties.etag or properties.contentType or properties.creationDate %}
|
||||||
<d:propstat>
|
<d:propstat>
|
||||||
<d:prop>
|
<d:prop>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" ?>
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
<d:multistatus xmlns:d="DAV:">
|
<d:multistatus xmlns:d="DAV:">
|
||||||
<d:response>
|
<d:response>
|
||||||
<d:href>{{ path('chill_docstore_dav_document_get', {'uuid': stored_object.uuid}) }}</d:href>
|
<d:href>{{ path('chill_docstore_dav_document_get', {'uuid': stored_object.uuid, 'access_token': access_token}) }}</d:href>
|
||||||
{% if properties.lastModified or properties.contentLength or properties.resourceType or properties.etag or properties.contentType or properties.creationDate %}
|
{% if properties.lastModified or properties.contentLength or properties.resourceType or properties.etag or properties.contentType or properties.creationDate %}
|
||||||
<d:propstat>
|
<d:propstat>
|
||||||
<d:prop>
|
<d:prop>
|
||||||
|
@ -2,6 +2,6 @@
|
|||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<p>document uuid: {{ stored_object.uuid }}</p>
|
<p>document uuid: {{ stored_object.uuid }}</p>
|
||||||
<p>{{ absolute_url(path('chill_docstore_dav_document_get', {'uuid': stored_object.uuid })) }}</p>
|
<p>{{ absolute_url(path('chill_docstore_dav_document_get', {'uuid': stored_object.uuid, 'access_token': access_token })) }}</p>
|
||||||
<a href="vnd.libreoffice.command:ofe|u|{{ absolute_url(path('chill_docstore_dav_document_get', {'uuid': stored_object.uuid })) }}">Open document</a>
|
<a href="vnd.libreoffice.command:ofe|u|{{ absolute_url(path('chill_docstore_dav_document_get', {'uuid': stored_object.uuid, 'access_token': access_token })) }}">Open document</a>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -0,0 +1,49 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Chill is a software for social workers
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view
|
||||||
|
* the LICENSE file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Chill\DocStoreBundle\Security\Guard;
|
||||||
|
|
||||||
|
use Lexik\Bundle\JWTAuthenticationBundle\TokenExtractor\TokenExtractorInterface;
|
||||||
|
use Psr\Log\LoggerInterface;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
|
||||||
|
final readonly class DavOnUrlTokenExtractor implements TokenExtractorInterface
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
private LoggerInterface $logger,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
public function extract(Request $request): string|false
|
||||||
|
{
|
||||||
|
$uri = $request->getRequestUri();
|
||||||
|
|
||||||
|
$segments = array_values(
|
||||||
|
array_filter(
|
||||||
|
explode('/', $uri),
|
||||||
|
fn ($item) => '' !== trim($item)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (2 > count($segments)) {
|
||||||
|
$this->logger->info("not enough segment for parsing URL");
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('dav' !== $segments[0]) {
|
||||||
|
$this->logger->info("the first segment of the url must be DAV");
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $segments[1];
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Chill is a software for social workers
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view
|
||||||
|
* the LICENSE file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Chill\DocStoreBundle\Security\Guard;
|
||||||
|
|
||||||
|
use Lexik\Bundle\JWTAuthenticationBundle\Security\Guard\JWTTokenAuthenticator;
|
||||||
|
use Lexik\Bundle\JWTAuthenticationBundle\Services\JWTTokenManagerInterface;
|
||||||
|
use Lexik\Bundle\JWTAuthenticationBundle\TokenExtractor\TokenExtractorInterface;
|
||||||
|
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
|
||||||
|
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
|
||||||
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
|
|
||||||
|
class JWTOnDavUrlAuthenticator extends JWTTokenAuthenticator
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
JWTTokenManagerInterface $jwtManager,
|
||||||
|
EventDispatcherInterface $dispatcher,
|
||||||
|
TokenExtractorInterface $tokenExtractor,
|
||||||
|
TokenStorageInterface $preAuthenticationTokenStorage,
|
||||||
|
TranslatorInterface $translator = null,
|
||||||
|
private readonly DavOnUrlTokenExtractor $davOnUrlTokenExtractor,
|
||||||
|
) {
|
||||||
|
parent::__construct($jwtManager, $dispatcher, $tokenExtractor, $preAuthenticationTokenStorage, $translator);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getTokenExtractor()
|
||||||
|
{
|
||||||
|
return $this->davOnUrlTokenExtractor;
|
||||||
|
}
|
||||||
|
}
|
@ -21,6 +21,7 @@ use Prophecy\PhpUnit\ProphecyTrait;
|
|||||||
use Ramsey\Uuid\Uuid;
|
use Ramsey\Uuid\Uuid;
|
||||||
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
|
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Symfony\Component\Security\Core\Security;
|
||||||
use Symfony\Component\Templating\EngineInterface;
|
use Symfony\Component\Templating\EngineInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -43,8 +44,9 @@ class WebdavControllerTest extends KernelTestCase
|
|||||||
private function buildController(): WebdavController
|
private function buildController(): WebdavController
|
||||||
{
|
{
|
||||||
$storedObjectManager = new MockedStoredObjectManager();
|
$storedObjectManager = new MockedStoredObjectManager();
|
||||||
|
$security = $this->prophesize(Security::class);
|
||||||
|
|
||||||
return new WebdavController($this->engine, $storedObjectManager);
|
return new WebdavController($this->engine, $storedObjectManager, $security->reveal());
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildDocument(): StoredObject
|
private function buildDocument(): StoredObject
|
||||||
@ -115,7 +117,7 @@ class WebdavControllerTest extends KernelTestCase
|
|||||||
|
|
||||||
$request = new Request([], [], [], [], [], [], $requestContent);
|
$request = new Request([], [], [], [], [], [], $requestContent);
|
||||||
$request->setMethod('PROPFIND');
|
$request->setMethod('PROPFIND');
|
||||||
$response = $controller->propfindDocument($this->buildDocument(), $request);
|
$response = $controller->propfindDocument($this->buildDocument(), '1234', $request);
|
||||||
|
|
||||||
self::assertEquals($expectedStatusCode, $response->getStatusCode());
|
self::assertEquals($expectedStatusCode, $response->getStatusCode());
|
||||||
self::assertContains('content-type', $response->headers->keys());
|
self::assertContains('content-type', $response->headers->keys());
|
||||||
@ -134,7 +136,7 @@ class WebdavControllerTest extends KernelTestCase
|
|||||||
$request = new Request([], [], [], [], [], [], $requestContent);
|
$request = new Request([], [], [], [], [], [], $requestContent);
|
||||||
$request->setMethod('PROPFIND');
|
$request->setMethod('PROPFIND');
|
||||||
$request->headers->add(["Depth" => "0"]);
|
$request->headers->add(["Depth" => "0"]);
|
||||||
$response = $controller->propfindDirectory($this->buildDocument(), $request);
|
$response = $controller->propfindDirectory($this->buildDocument(), '1234', $request);
|
||||||
|
|
||||||
self::assertEquals($expectedStatusCode, $response->getStatusCode());
|
self::assertEquals($expectedStatusCode, $response->getStatusCode());
|
||||||
self::assertContains('content-type', $response->headers->keys());
|
self::assertContains('content-type', $response->headers->keys());
|
||||||
@ -170,7 +172,7 @@ class WebdavControllerTest extends KernelTestCase
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<d:multistatus xmlns:d="DAV:" >
|
<d:multistatus xmlns:d="DAV:" >
|
||||||
<d:response>
|
<d:response>
|
||||||
<d:href>/dav/get/716e6688-4579-4938-acf3-c4ab5856803b/d</d:href>
|
<d:href>/dav/1234/get/716e6688-4579-4938-acf3-c4ab5856803b/d</d:href>
|
||||||
<d:propstat>
|
<d:propstat>
|
||||||
<d:prop>
|
<d:prop>
|
||||||
<d:resourcetype/>
|
<d:resourcetype/>
|
||||||
@ -205,7 +207,7 @@ class WebdavControllerTest extends KernelTestCase
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<d:multistatus xmlns:d="DAV:">
|
<d:multistatus xmlns:d="DAV:">
|
||||||
<d:response>
|
<d:response>
|
||||||
<d:href>/dav/get/716e6688-4579-4938-acf3-c4ab5856803b/d</d:href>
|
<d:href>/dav/1234/get/716e6688-4579-4938-acf3-c4ab5856803b/d</d:href>
|
||||||
<d:propstat>
|
<d:propstat>
|
||||||
<d:prop xmlns:ns0="http://ucb.openoffice.org/dav/props/">
|
<d:prop xmlns:ns0="http://ucb.openoffice.org/dav/props/">
|
||||||
<ns0:IsReadOnly/>
|
<ns0:IsReadOnly/>
|
||||||
@ -232,7 +234,7 @@ class WebdavControllerTest extends KernelTestCase
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<d:multistatus xmlns:d="DAV:">
|
<d:multistatus xmlns:d="DAV:">
|
||||||
<d:response>
|
<d:response>
|
||||||
<d:href>/dav/get/716e6688-4579-4938-acf3-c4ab5856803b/d</d:href>
|
<d:href>/dav/1234/get/716e6688-4579-4938-acf3-c4ab5856803b/d</d:href>
|
||||||
<d:propstat>
|
<d:propstat>
|
||||||
<d:prop xmlns:ns0="http://ucb.openoffice.org/dav/props/">
|
<d:prop xmlns:ns0="http://ucb.openoffice.org/dav/props/">
|
||||||
<ns0:BaseURI/>
|
<ns0:BaseURI/>
|
||||||
@ -259,7 +261,7 @@ class WebdavControllerTest extends KernelTestCase
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<d:multistatus xmlns:d="DAV:">
|
<d:multistatus xmlns:d="DAV:">
|
||||||
<d:response>
|
<d:response>
|
||||||
<d:href>/dav/get/716e6688-4579-4938-acf3-c4ab5856803b/d</d:href>
|
<d:href>/dav/1234/get/716e6688-4579-4938-acf3-c4ab5856803b/d</d:href>
|
||||||
<d:propstat>
|
<d:propstat>
|
||||||
<d:prop>
|
<d:prop>
|
||||||
<!-- the date scraped from a webserver is >Sun, 10 Sep 2023 14:10:23 GMT -->
|
<!-- the date scraped from a webserver is >Sun, 10 Sep 2023 14:10:23 GMT -->
|
||||||
@ -285,7 +287,7 @@ class WebdavControllerTest extends KernelTestCase
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<d:multistatus xmlns:d="DAV:">
|
<d:multistatus xmlns:d="DAV:">
|
||||||
<d:response>
|
<d:response>
|
||||||
<d:href>/dav/get/716e6688-4579-4938-acf3-c4ab5856803b/d</d:href>
|
<d:href>/dav/1234/get/716e6688-4579-4938-acf3-c4ab5856803b/d</d:href>
|
||||||
<d:propstat>
|
<d:propstat>
|
||||||
<d:prop>
|
<d:prop>
|
||||||
<d:resourcetype/>
|
<d:resourcetype/>
|
||||||
@ -323,7 +325,7 @@ class WebdavControllerTest extends KernelTestCase
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<d:multistatus xmlns:d="DAV:">
|
<d:multistatus xmlns:d="DAV:">
|
||||||
<d:response>
|
<d:response>
|
||||||
<d:href>/dav/get/716e6688-4579-4938-acf3-c4ab5856803b/</d:href>
|
<d:href>/dav/1234/get/716e6688-4579-4938-acf3-c4ab5856803b/</d:href>
|
||||||
<d:propstat>
|
<d:propstat>
|
||||||
<d:prop>
|
<d:prop>
|
||||||
<d:resourcetype><d:collection/></d:resourcetype>
|
<d:resourcetype><d:collection/></d:resourcetype>
|
||||||
@ -365,7 +367,7 @@ class WebdavControllerTest extends KernelTestCase
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<d:multistatus xmlns:d="DAV:">
|
<d:multistatus xmlns:d="DAV:">
|
||||||
<d:response>
|
<d:response>
|
||||||
<d:href>/dav/get/716e6688-4579-4938-acf3-c4ab5856803b/</d:href>
|
<d:href>/dav/1234/get/716e6688-4579-4938-acf3-c4ab5856803b/</d:href>
|
||||||
<d:propstat>
|
<d:propstat>
|
||||||
<d:prop xmlns:ns0="http://ucb.openoffice.org/dav/props/" >
|
<d:prop xmlns:ns0="http://ucb.openoffice.org/dav/props/" >
|
||||||
<ns0:CreatableContentsInfo/>
|
<ns0:CreatableContentsInfo/>
|
||||||
|
@ -0,0 +1,54 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Chill is a software for social workers
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view
|
||||||
|
* the LICENSE file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Chill\DocStoreBundle\Tests\Security\Guard;
|
||||||
|
|
||||||
|
use Chill\DocStoreBundle\Security\Guard\DavOnUrlTokenExtractor;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Prophecy\PhpUnit\ProphecyTrait;
|
||||||
|
use Psr\Log\NullLogger;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
* @coversNothing
|
||||||
|
*/
|
||||||
|
class DavOnUrlTokenExtractorTest extends TestCase
|
||||||
|
{
|
||||||
|
use ProphecyTrait;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider provideDataUri
|
||||||
|
*/
|
||||||
|
public function testExtract(string $uri, string|false $expected): void
|
||||||
|
{
|
||||||
|
$request = $this->prophesize(Request::class);
|
||||||
|
$request->getRequestUri()->willReturn($uri);
|
||||||
|
|
||||||
|
$extractor = new DavOnUrlTokenExtractor(new NullLogger());
|
||||||
|
|
||||||
|
$actual = $extractor->extract($request->reveal());
|
||||||
|
|
||||||
|
self::assertEquals($expected, $actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @phpstan-pure
|
||||||
|
*/
|
||||||
|
public static function provideDataUri(): iterable
|
||||||
|
{
|
||||||
|
yield ['/dav/123456789/get/d07d2230-5326-11ee-8fd4-93696acf5ea1/d', '123456789'];
|
||||||
|
yield ['/dav/123456789', '123456789'];
|
||||||
|
yield ['/not-dav/123456978', false];
|
||||||
|
yield ['/dav', false];
|
||||||
|
yield ['/', false];
|
||||||
|
}
|
||||||
|
}
|
@ -34,6 +34,11 @@ services:
|
|||||||
autoconfigure: true
|
autoconfigure: true
|
||||||
autowire: true
|
autowire: true
|
||||||
|
|
||||||
|
Chill\DocStoreBundle\Security\:
|
||||||
|
resource: './../Security'
|
||||||
|
autoconfigure: true
|
||||||
|
autowire: true
|
||||||
|
|
||||||
Chill\DocStoreBundle\Serializer\Normalizer\:
|
Chill\DocStoreBundle\Serializer\Normalizer\:
|
||||||
autowire: true
|
autowire: true
|
||||||
resource: '../Serializer/Normalizer/'
|
resource: '../Serializer/Normalizer/'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user