Skip to content

Commit

Permalink
Merge branch 'master' into III-6494/rdf-convert-blank-nodes-to-named-…
Browse files Browse the repository at this point in the history
…hashes
  • Loading branch information
grubolsch authored Jan 24, 2025
2 parents 996269f + 41e818b commit f618a24
Show file tree
Hide file tree
Showing 33 changed files with 512 additions and 615 deletions.
2 changes: 2 additions & 0 deletions app/Event/EventRdfServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use CultuurNet\UDB3\Error\LoggerName;
use CultuurNet\UDB3\Event\ReadModel\RDF\EventJsonToTurtleConverter;
use CultuurNet\UDB3\Model\Serializer\Event\EventDenormalizer;
use CultuurNet\UDB3\Model\Serializer\ValueObject\MediaObject\ImageNormalizer;
use CultuurNet\UDB3\RDF\RdfServiceProvider;

final class EventRdfServiceProvider extends AbstractServiceProvider
Expand All @@ -33,6 +34,7 @@ public function register(): void
$this->container->get('event_jsonld_repository'),
(new EventDenormalizer())->handlesDummyOrganizers(),
$this->container->get(AddressParser::class),
$this->container->get(ImageNormalizer::class),
LoggerFactory::create($this->getContainer(), LoggerName::forService('rdf'))
)
);
Expand Down
15 changes: 8 additions & 7 deletions app/Media/MediaServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@

use Broadway\EventHandling\EventBus;
use Broadway\UuidGenerator\Rfc4122\Version4Generator;
use CultuurNet\UDB3\AggregateType;
use CultuurNet\UDB3\Container\AbstractServiceProvider;
use CultuurNet\UDB3\Error\LoggerFactory;
use CultuurNet\UDB3\Error\LoggerName;
use CultuurNet\UDB3\Http\Media\GetMediaRequestHandler;
use CultuurNet\UDB3\Http\Media\UploadMediaRequestHandler;
use CultuurNet\UDB3\Iri\CallableIriGenerator;
use CultuurNet\UDB3\Media\Serialization\MediaObjectSerializer;
use CultuurNet\UDB3\AggregateType;
use CultuurNet\UDB3\Error\LoggerFactory;
use CultuurNet\UDB3\Error\LoggerName;
use CultuurNet\UDB3\Model\ValueObject\MediaObject\ImagesToMediaObjectReferencesConvertor;
use CultuurNet\UDB3\Model\Serializer\ValueObject\MediaObject\ImageNormalizer;

final class MediaServiceProvider extends AbstractServiceProvider
{
Expand All @@ -31,7 +31,7 @@ protected function getProvidedServiceNames(): array
'media_url_mapping',
GetMediaRequestHandler::class,
UploadMediaRequestHandler::class,
ImagesToMediaObjectReferencesConvertor::class,
ImageNormalizer::class,
];
}

Expand Down Expand Up @@ -150,10 +150,11 @@ function () use ($container) {
);

$container->addShared(
ImagesToMediaObjectReferencesConvertor::class,
ImageNormalizer::class,
function () use ($container) {
return new ImagesToMediaObjectReferencesConvertor(
return new ImageNormalizer(
$container->get('media_object_repository'),
$container->get('media_object_iri_generator')
);
}
);
Expand Down
5 changes: 1 addition & 4 deletions app/Organizer/OrganizerJSONLDServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,7 @@ function () use ($container) {
new JsonDocumentLanguageEnricher(
new OrganizerJsonDocumentLanguageAnalyzer()
),
new ImageNormalizer(
$container->get('media_object_repository'),
$container->get('media_object_iri_generator')
),
$this->container->get(ImageNormalizer::class),
new CdbXMLImporter(
$container->get(CdbXMLToJsonLDLabelImporter::class),
new CultureFeedAddressFactory()
Expand Down
4 changes: 2 additions & 2 deletions app/Organizer/OrganizerRdfServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
use CultuurNet\UDB3\Error\LoggerFactory;
use CultuurNet\UDB3\Error\LoggerName;
use CultuurNet\UDB3\Model\Serializer\Organizer\OrganizerDenormalizer;
use CultuurNet\UDB3\Model\ValueObject\MediaObject\ImagesToMediaObjectReferencesConvertor;
use CultuurNet\UDB3\Model\Serializer\ValueObject\MediaObject\ImageNormalizer;
use CultuurNet\UDB3\Organizer\ReadModel\RDF\OrganizerJsonToTurtleConverter;
use CultuurNet\UDB3\RDF\RdfServiceProvider;

Expand All @@ -31,7 +31,7 @@ public function register(): void
$this->container->get('organizer_jsonld_repository'),
new OrganizerDenormalizer(),
$this->container->get(AddressParser::class),
$this->container->get(ImagesToMediaObjectReferencesConvertor::class),
$this->container->get(ImageNormalizer::class),
LoggerFactory::create($this->getContainer(), LoggerName::forService('rdf'))
)
);
Expand Down
8 changes: 6 additions & 2 deletions app/Ownership/OwnershipRequestHandlerServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,19 @@ public function register(): void
$container->addShared(
GetOwnershipRequestHandler::class,
fn () => new GetOwnershipRequestHandler(
$container->get(OwnershipServiceProvider::OWNERSHIP_JSONLD_REPOSITORY)
$container->get(OwnershipServiceProvider::OWNERSHIP_JSONLD_REPOSITORY),
$container->get(CurrentUser::class),
$container->get(OwnershipStatusGuard::class)
)
);

$container->addShared(
SearchOwnershipRequestHandler::class,
fn () => new SearchOwnershipRequestHandler(
$container->get(OwnershipSearchRepository::class),
$container->get(OwnershipServiceProvider::OWNERSHIP_JSONLD_REPOSITORY)
$container->get(OwnershipServiceProvider::OWNERSHIP_JSONLD_REPOSITORY),
$container->get(CurrentUser::class),
$container->get(OwnershipStatusGuard::class)
)
);

Expand Down
62 changes: 62 additions & 0 deletions features/ownership/get.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
Feature: Test getting a single ownership by ID
Background:
Given I am using the UDB3 base URL
And I am using an UiTID v1 API key of consumer "uitdatabank"
And I am authorized as JWT provider v1 user "centraal_beheerder"
And I send and accept "application/json"

Scenario: Get the ownership as an admin
Given I create a minimal organizer and save the "id" as "organizerId"
And I request ownership for "auth0|64089494e980aedd96740212" on the organizer with organizerId "%{organizerId}" and save the "id" as "ownershipId"
When I send a GET request to '/ownerships/%{ownershipId}'
Then the response status should be 200
And the JSON response at id should be "%{ownershipId}"
And the JSON response at ownerId should be "auth0|64089494e980aedd96740212"
And the JSON response at itemId should be "%{organizerId}"
And the JSON response at state should be "requested"
And the JSON response at itemType should be "organizer"
And the JSON response at requesterId should be "7a583ed3-cbc1-481d-93b1-d80fff0174dd"
And the JSON response at ownerEmail should be "[email protected]"

Scenario: Get the ownership as owner
Given I create a minimal organizer and save the "id" as "organizerId"
And I request ownership for "auth0|64089494e980aedd96740212" on the organizer with organizerId "%{organizerId}" and save the "id" as "ownershipId"
When I am authorized as JWT provider v2 user "dev_e2e_test"
And I send a GET request to '/ownerships/%{ownershipId}'
Then the response status should be 200
And the JSON response at id should be "%{ownershipId}"
And the JSON response at ownerId should be "auth0|64089494e980aedd96740212"
And the JSON response at itemId should be "%{organizerId}"
And the JSON response at state should be "requested"
And the JSON response at itemType should be "organizer"
And the JSON response at requesterId should be "7a583ed3-cbc1-481d-93b1-d80fff0174dd"
And the JSON response at ownerEmail should be "[email protected]"

Scenario: Not allowed to get the ownership as an unrelated user
Given I create a minimal organizer and save the "id" as "organizerId"
And I request ownership for "auth0|64089494e980aedd96740212" on the organizer with organizerId "%{organizerId}" and save the "id" as "ownershipId"
When I am authorized as JWT provider v2 user "invoerder"
And I send a GET request to '/ownerships/%{ownershipId}'
Then the response status should be 403
And the JSON response should be:
"""
{
"type": "https://api.publiq.be/probs/auth/forbidden",
"title": "Forbidden",
"status": 403,
"detail": "You are not allowed to get this ownership"
}
"""

Scenario: Get an unexisting ownership
When I send a GET request to '/ownerships/a0a9f9c0-84b5-471b-869e-c2c692217cc0'
Then the response status should be 404
And the JSON response should be:
"""
{
"type": "https://api.publiq.be/probs/url/not-found",
"title": "Not Found",
"status": 404,
"detail": "The Ownership with id \"a0a9f9c0-84b5-471b-869e-c2c692217cc0\" was not found."
}
"""
49 changes: 43 additions & 6 deletions features/ownership/search.feature
Original file line number Diff line number Diff line change
Expand Up @@ -74,17 +74,54 @@ Feature: Test searching ownerships
And I request ownership for "auth0|631748dba64ea78e3983b203" on the organizer with organizerId "%{organizerId}" and save the "id" as "ownershipId3"
And I request ownership for "auth0|631748dba64ea78e3983b204" on the organizer with organizerId "%{organizerId}" and save the "id" as "ownershipId4"
And I request ownership for "auth0|631748dba64ea78e3983b205" on the organizer with organizerId "%{organizerId}" and save the "id" as "ownershipId5"
When I send a GET request to '/ownerships/?itemId=%{organizerId}&limit=2&start=2'
And I approve the ownership with ownershipId "%{ownershipId1}"
And I approve the ownership with ownershipId "%{ownershipId2}"
When I send a GET request to '/ownerships/?state=requested&itemId=%{organizerId}&imit=2&start=1'
Then the response status should be 200
And the JSON response at "itemsPerPage" should be 2
And the JSON response at "totalItems" should be 5
And the JSON response at "member/0/id" should be "%{ownershipId3}"
And the JSON response at "member/0/ownerId" should be "auth0|631748dba64ea78e3983b203"
And the JSON response at "totalItems" should be 3
And the JSON response at "member/0/id" should be "%{ownershipId4}"
And the JSON response at "member/0/ownerId" should be "auth0|631748dba64ea78e3983b204"
And the JSON response at "member/0/state" should be "requested"
And the JSON response at "member/1/id" should be "%{ownershipId4}"
And the JSON response at "member/1/ownerId" should be "auth0|631748dba64ea78e3983b204"
And the JSON response at "member/1/id" should be "%{ownershipId5}"
And the JSON response at "member/1/ownerId" should be "auth0|631748dba64ea78e3983b205"
And the JSON response at "member/1/state" should be "requested"

Scenario: Searching ownership of an organizer takes into permission organisaties bewerken
Given I create a minimal organizer and save the "id" as "organizerId1"
And I request ownership for "auth0|631748dba64ea78e3983b201" on the organizer with organizerId "%{organizerId1}" and save the "id" as "ownershipId1"
Given I create a minimal organizer and save the "id" as "organizerId2"
And I request ownership for "auth0|631748dba64ea78e3983b202" on the organizer with organizerId "%{organizerId2}" and save the "id" as "ownershipId2"
And I request ownership for "d759fd36-fb28-4fe3-8ec6-b4aaf990371d" on the organizer with organizerId "%{organizerId2}" and save the "id" as "ownershipId3"
And I approve the ownership with ownershipId "%{ownershipId3}"
When I am authorized as JWT provider v2 user "invoerder"
When I send a GET request to '/ownerships/?itemId=%{organizerId2}'
Then the response status should be 200
And the JSON response at "itemsPerPage" should be 2
And the JSON response at "totalItems" should be 2
And the JSON response at "member/0/id" should be "%{ownershipId2}"
And the JSON response at "member/0/ownerId" should be "auth0|631748dba64ea78e3983b202"
And the JSON response at "member/0/state" should be "requested"
And the JSON response at "member/1/id" should be "%{ownershipId3}"
And the JSON response at "member/1/ownerId" should be "d759fd36-fb28-4fe3-8ec6-b4aaf990371d"
And the JSON response at "member/1/state" should be "approved"

Scenario: Searching ownership of an organizer takes into account current owner
Given I create a minimal organizer and save the "id" as "organizerId1"
And I request ownership for "auth0|631748dba64ea78e3983b201" on the organizer with organizerId "%{organizerId1}" and save the "id" as "ownershipId1"
Given I create a minimal organizer and save the "id" as "organizerId2"
And I request ownership for "auth0|631748dba64ea78e3983b202" on the organizer with organizerId "%{organizerId2}" and save the "id" as "ownershipId2"
And I request ownership for "d759fd36-fb28-4fe3-8ec6-b4aaf990371d" on the organizer with organizerId "%{organizerId2}" and save the "id" as "ownershipId3"
When I am authorized as JWT provider v2 user "invoerder"
When I send a GET request to '/ownerships/?itemId=%{organizerId2}'
And show me the unparsed response
Then the response status should be 200
And the JSON response at "itemsPerPage" should be 1
And the JSON response at "totalItems" should be 1
And the JSON response at "member/0/id" should be "%{ownershipId3}"
And the JSON response at "member/0/ownerId" should be "d759fd36-fb28-4fe3-8ec6-b4aaf990371d"
And the JSON response at "member/0/state" should be "requested"

Scenario: No ownerships found
Given I create a minimal organizer and save the "id" as "organizerId"
When I send a GET request to '/ownerships/?itemId=%{organizerId}'
Expand Down
11 changes: 9 additions & 2 deletions src/Event/ReadModel/RDF/EventJsonToTurtleConverter.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
use CultuurNet\UDB3\RDF\Editor\ContactPointEditor;
use CultuurNet\UDB3\RDF\Editor\GraphEditor;
use CultuurNet\UDB3\RDF\Editor\LabelEditor;
use CultuurNet\UDB3\RDF\Editor\MediaObjectEditor;
use CultuurNet\UDB3\RDF\Editor\ImageEditor;
use CultuurNet\UDB3\RDF\Editor\OpeningHoursEditor;
use CultuurNet\UDB3\RDF\Editor\VideoEditor;
use CultuurNet\UDB3\RDF\Editor\WorkflowStatusEditor;
Expand All @@ -50,6 +50,7 @@
use EasyRdf\Serialiser\Turtle;
use Psr\Log\LoggerInterface;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;

final class EventJsonToTurtleConverter implements JsonToTurtleConverter
{
Expand All @@ -61,6 +62,7 @@ final class EventJsonToTurtleConverter implements JsonToTurtleConverter
private DenormalizerInterface $eventDenormalizer;
private AddressParser $addressParser;
private LoggerInterface $logger;
private NormalizerInterface $imageNormalizer;

private const TYPE_ACTIVITEIT = 'cidoc:E7_Activity';
private const TYPE_SPACE_TIME = 'cidoc:E92_Spacetime_Volume';
Expand Down Expand Up @@ -114,6 +116,7 @@ public function __construct(
DocumentRepository $documentRepository,
DenormalizerInterface $eventDenormalizer,
AddressParser $addressParser,
NormalizerInterface $imageNormalizer,
LoggerInterface $logger
) {
$this->eventsIriGenerator = $eventsIriGenerator;
Expand All @@ -124,6 +127,7 @@ public function __construct(
$this->eventDenormalizer = $eventDenormalizer;
$this->addressParser = $addressParser;
$this->logger = $logger;
$this->imageNormalizer = $imageNormalizer;
}

public function convert(string $id): string
Expand Down Expand Up @@ -227,7 +231,10 @@ public function convert(string $id): string
}

if (!$event->getMediaObjectReferences()->isEmpty()) {
(new MediaObjectEditor())->setImages($resource, $event->getMediaObjectReferences());
(new ImageEditor($this->imageNormalizer))->setImages(
$resource,
$event->getMediaObjectReferences()->toImages()
);
}

return trim((new Turtle())->serialise($graph, 'turtle'));
Expand Down
14 changes: 12 additions & 2 deletions src/Http/Ownership/GetOwnershipRequestHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,34 @@
use CultuurNet\UDB3\Http\Response\JsonLdResponse;
use CultuurNet\UDB3\ReadModel\DocumentDoesNotExist;
use CultuurNet\UDB3\ReadModel\DocumentRepository;
use CultuurNet\UDB3\User\CurrentUser;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;

final class GetOwnershipRequestHandler implements RequestHandlerInterface
{
private DocumentRepository $ownershipRepository;
private CurrentUser $currentUser;
private OwnershipStatusGuard $ownershipStatusGuard;

public function __construct(DocumentRepository $ownershipRepository)
{
public function __construct(
DocumentRepository $ownershipRepository,
CurrentUser $currentUser,
OwnershipStatusGuard $ownershipStatusGuard
) {
$this->ownershipRepository = $ownershipRepository;
$this->currentUser = $currentUser;
$this->ownershipStatusGuard = $ownershipStatusGuard;
}

public function handle(ServerRequestInterface $request): ResponseInterface
{
$routeParameters = new RouteParameters($request);
$ownershipId = $routeParameters->getOwnershipId();

$this->ownershipStatusGuard->isAllowedToGet($ownershipId, $this->currentUser);

try {
return new JsonLdResponse(
$this->ownershipRepository->fetch($ownershipId)->getRawBody()
Expand Down
30 changes: 29 additions & 1 deletion src/Http/Ownership/OwnershipStatusGuard.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,34 @@ public function __construct(
$this->permissionVoter = $permissionVoter;
}

public function isAllowedToGet(string $ownershipId, CurrentUser $currentUser): void
{
try {
$ownership = $this->ownershipSearchRepository->getById($ownershipId);
} catch (OwnershipItemNotFound $exception) {
throw ApiProblem::ownershipNotFound($ownershipId);
}

if ($currentUser->isGodUser()) {
return;
}

$isOwner = $this->permissionVoter->isAllowed(
Permission::organisatiesBewerken(),
$ownership->getItemId(),
$currentUser->getId()
);
if ($isOwner) {
return;
}

if ($ownership->getOwnerId() === $currentUser->getId()) {
return;
}

throw ApiProblem::forbidden('You are not allowed to get this ownership');
}

public function isAllowedToRequest(string $itemId, string $requesterId, CurrentUser $currentUser): void
{
$isOwner = $this->permissionVoter->isAllowed(
Expand Down Expand Up @@ -73,7 +101,7 @@ private function isAllowedToUpdateOwnership(OwnershipItem $ownership, CurrentUse
}

return $this->permissionVoter->isAllowed(
Permission::organisatiesBeheren(),
Permission::organisatiesBewerken(),
$ownership->getItemId(),
$currentUser->getId()
);
Expand Down
Loading

0 comments on commit f618a24

Please sign in to comment.