Skip to content

Commit

Permalink
Allow user to edit packages (#299)
Browse files Browse the repository at this point in the history
* Allow user to edit packages

* Add validation for API request

* Add restrictions for package update
  • Loading branch information
karniv00l authored Oct 15, 2020
1 parent efe2fcf commit 1b26aad
Show file tree
Hide file tree
Showing 23 changed files with 457 additions and 58 deletions.
10 changes: 4 additions & 6 deletions src/Controller/Api/ApiController.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ protected function parseJson(Request $request): array
return [];
}

$data = json_decode($request->getContent(), true);

if (json_last_error() !== JSON_ERROR_NONE) {
try {
$data = json_decode($request->getContent(), true, 512, JSON_THROW_ON_ERROR);
} catch (\JsonException $th) {
throw new BadRequestHttpException();
}

Expand All @@ -60,11 +60,9 @@ protected function getErrors(FormInterface $form): Errors
}

/**
* @param callable $listFunction
*
* @return array<mixed>
*/
protected function paginate($listFunction, int $total, int $perPage, int $page, string $baseUrl): array
protected function paginate(callable $listFunction, int $total, int $perPage, int $page, string $baseUrl): array
{
$pages = (int) ceil($total / $perPage);
if ($pages === 0) {
Expand Down
68 changes: 66 additions & 2 deletions src/Controller/Api/PackageController.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@
use Buddy\Repman\Entity\Organization\Package\Metadata;
use Buddy\Repman\Entity\User\OAuthToken;
use Buddy\Repman\Form\Type\Api\AddPackageType;
use Buddy\Repman\Form\Type\Api\EditPackageType;
use Buddy\Repman\Message\Organization\AddPackage;
use Buddy\Repman\Message\Organization\Package\AddBitbucketHook;
use Buddy\Repman\Message\Organization\Package\AddGitHubHook;
use Buddy\Repman\Message\Organization\Package\AddGitLabHook;
use Buddy\Repman\Message\Organization\Package\Update;
use Buddy\Repman\Message\Organization\RemovePackage;
use Buddy\Repman\Message\Organization\SynchronizePackage;
use Buddy\Repman\Query\Api\Model\Errors;
Expand Down Expand Up @@ -174,12 +176,48 @@ public function removePackage(Organization $organization, Package $package): Jso
return new JsonResponse();
}

/**
* Synchronize package.
*
* @Route("/api/organization/{organization}/package/{package}",
* name="api_synchronize_update",
* methods={"PUT"},
* requirements={"organization"="%organization_pattern%","package"="%uuid_pattern%"}
* )
*
* @Oa\Parameter(
* name="package",
* in="path",
* description="UUID"
* )
*
* @OA\Response(
* response=200,
* description="Package updated"
* )
*
* @OA\Response(
* response=404,
* description="Package not found"
* )
*
* @OA\Tag(name="Package")
*/
public function synchronizePackage(Organization $organization, Package $package): JsonResponse
{
$this->dispatchMessage(new SynchronizePackage($package->getId()));

return new JsonResponse();
}

/**
* Update and synchronize package.
*
* @IsGranted("ROLE_ORGANIZATION_OWNER", subject="organization")
*
* @Route("/api/organization/{organization}/package/{package}",
* name="api_package_update",
* methods={"PUT"},
* methods={"PATCH"},
* requirements={"organization"="%organization_pattern%","package"="%uuid_pattern%"}
* )
*
Expand All @@ -189,6 +227,10 @@ public function removePackage(Organization $organization, Package $package): Jso
* description="UUID"
* )
*
* @OA\RequestBody(
* @Model(type=EditPackageType::class)
* )
*
* @OA\Response(
* response=200,
* description="Package updated"
Expand All @@ -204,10 +246,32 @@ public function removePackage(Organization $organization, Package $package): Jso
* description="Forbidden"
* )
*
* @OA\Response(
* response=400,
* description="Bad request"
* )
*
* @OA\Tag(name="Package")
*/
public function updatePackage(Organization $organization, Package $package): JsonResponse
public function updatePackage(Organization $organization, Package $package, Request $request): JsonResponse
{
$form = $this->createApiForm(EditPackageType::class);

$form->submit(array_merge([
'url' => $package->getUrl(),
'keepLastReleases' => $package->getKeepLastReleases(),
], $this->parseJson($request)));

if (!$form->isValid()) {
return $this->badRequest($this->getErrors($form));
}

$this->dispatchMessage(new Update(
$package->getId(),
$form->get('url')->getData(),
$form->get('keepLastReleases')->getData(),
));

$this->dispatchMessage(new SynchronizePackage($package->getId()));

return new JsonResponse();
Expand Down
50 changes: 50 additions & 0 deletions src/Controller/Organization/PackageController.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,15 @@
use Buddy\Repman\Entity\Organization\Package\Metadata;
use Buddy\Repman\Entity\User\OAuthToken;
use Buddy\Repman\Form\Type\Organization\AddPackageType;
use Buddy\Repman\Form\Type\Organization\EditPackageType;
use Buddy\Repman\Message\Organization\AddPackage;
use Buddy\Repman\Message\Organization\Package\AddBitbucketHook;
use Buddy\Repman\Message\Organization\Package\AddGitHubHook;
use Buddy\Repman\Message\Organization\Package\AddGitLabHook;
use Buddy\Repman\Message\Organization\Package\Update;
use Buddy\Repman\Message\Organization\SynchronizePackage;
use Buddy\Repman\Query\User\Model\Organization;
use Buddy\Repman\Query\User\Model\Package;
use Buddy\Repman\Query\User\UserQuery;
use Buddy\Repman\Security\Model\User;
use Buddy\Repman\Service\BitbucketApi;
Expand Down Expand Up @@ -110,6 +113,53 @@ public function packageNew(Organization $organization, Request $request, ?string
]);
}

/**
* @Route("/organization/{organization}/package/{package}", name="organization_package_update", methods={"POST"}, requirements={"organization"="%organization_pattern%","package"="%uuid_pattern%"})
*/
public function updatePackage(Organization $organization, Package $package): Response
{
$this->dispatchMessage(new SynchronizePackage($package->id()));

$this->addFlash('success', 'Package will be synchronized in the background');

return $this->redirectToRoute('organization_packages', ['organization' => $organization->alias()]);
}

/**
* @IsGranted("ROLE_ORGANIZATION_OWNER", subject="organization")
* @Route("/organization/{organization}/package/{package}/edit", name="organization_package_edit", methods={"GET","POST"}, requirements={"organization"="%organization_pattern%","package"="%uuid_pattern%"})
*/
public function editPackage(Organization $organization, Package $package, Request $request): Response
{
$form = $this->createForm(EditPackageType::class, [
'url' => $package->url(),
'keepLastReleases' => $package->keepLastReleases(),
]);

$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$data = $form->getData();

$this->dispatchMessage(new Update(
$package->id(),
$data['url'],
$data['keepLastReleases'],
));

$this->dispatchMessage(new SynchronizePackage($package->id()));

$this->addFlash('success', 'Package will be synchronized in the background');

return $this->redirectToRoute('organization_packages', ['organization' => $organization->alias()]);
}

return $this->render('organization/package/edit.html.twig', [
'organization' => $organization,
'package' => $package,
'form' => $form->createView(),
]);
}

/**
* @param string[] $choices
*/
Expand Down
13 changes: 0 additions & 13 deletions src/Controller/OrganizationController.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
use Buddy\Repman\Message\Organization\RemoveOrganization;
use Buddy\Repman\Message\Organization\RemovePackage;
use Buddy\Repman\Message\Organization\RemoveToken;
use Buddy\Repman\Message\Organization\SynchronizePackage;
use Buddy\Repman\Message\Security\ScanPackage;
use Buddy\Repman\Query\Filter;
use Buddy\Repman\Query\User\Model\Installs\Day;
Expand Down Expand Up @@ -88,18 +87,6 @@ public function packages(Organization $organization, Request $request): Response
]);
}

/**
* @Route("/organization/{organization}/package/{package}", name="organization_package_update", methods={"POST"}, requirements={"organization"="%organization_pattern%","package"="%uuid_pattern%"})
*/
public function updatePackage(Organization $organization, Package $package): Response
{
$this->dispatchMessage(new SynchronizePackage($package->id()));

$this->addFlash('success', 'Package will be updated in the background');

return $this->redirectToRoute('organization_packages', ['organization' => $organization->alias()]);
}

/**
* @IsGranted("ROLE_ORGANIZATION_OWNER", subject="organization")
* @Route("/organization/{organization}/package/{package}", name="organization_package_remove", methods={"DELETE"}, requirements={"organization"="%organization_pattern%","package"="%uuid_pattern%"})
Expand Down
6 changes: 6 additions & 0 deletions src/Entity/Organization/Package.php
Original file line number Diff line number Diff line change
Expand Up @@ -310,4 +310,10 @@ public function keepLastReleases(): int
{
return $this->keepLastReleases;
}

public function update(string $url, int $keepLastReleases): void
{
$this->keepLastReleases = $keepLastReleases;
$this->repositoryUrl = $url;
}
}
4 changes: 4 additions & 0 deletions src/Form/Type/Api/AddPackageType.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\PositiveOrZero;

class AddPackageType extends AbstractType
{
Expand Down Expand Up @@ -57,6 +58,9 @@ public function buildForm(FormBuilderInterface $builder, array $options): void
->add('keepLastReleases', IntegerType::class, [
'data' => 0,
'required' => false,
'constraints' => [
new PositiveOrZero(),
],
]);
}
}
43 changes: 43 additions & 0 deletions src/Form/Type/Api/EditPackageType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

declare(strict_types=1);

namespace Buddy\Repman\Form\Type\Api;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\PositiveOrZero;

class EditPackageType extends AbstractType
{
public function getBlockPrefix(): string
{
return '';
}

/**
* @param array<mixed> $options
*/
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('url', TextType::class, [
'required' => false,
'label' => 'Repository URL',
'constraints' => [
new NotBlank(),
],
])
->add('keepLastReleases', IntegerType::class, [
'required' => false,
'label' => 'Keep last releases',
'help' => 'Number of last releases that will be downloaded. Put "0" to download all.',
'constraints' => [
new PositiveOrZero(),
],
]);
}
}
4 changes: 4 additions & 0 deletions src/Form/Type/Organization/AddPackageType.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Validator\Constraints\NotNull;
use Symfony\Component\Validator\Constraints\PositiveOrZero;

class AddPackageType extends AbstractType
{
Expand Down Expand Up @@ -68,6 +69,9 @@ public function buildForm(FormBuilderInterface $builder, array $options): void
'data' => 0,
'help' => 'Number of last releases that will be downloaded. Put "0" to download all.',
'required' => false,
'constraints' => [
new PositiveOrZero(),
],
])
->add('Add', SubmitType::class);
}
Expand Down
43 changes: 43 additions & 0 deletions src/Form/Type/Organization/EditPackageType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

declare(strict_types=1);

namespace Buddy\Repman\Form\Type\Organization;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\PositiveOrZero;

class EditPackageType extends AbstractType
{
public function getBlockPrefix(): string
{
return '';
}

/**
* @param array<mixed> $options
*/
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('url', TextType::class, [
'label' => 'Repository URL',
'constraints' => [
new NotBlank(),
],
])
->add('keepLastReleases', IntegerType::class, [
'label' => 'Keep last releases',
'help' => 'Number of last releases that will be downloaded. Put "0" to download all.',
'constraints' => [
new PositiveOrZero(),
],
])
->add('Update', SubmitType::class);
}
}
Loading

0 comments on commit 1b26aad

Please sign in to comment.