From fceb2be35d9ee8bf76c331a5de2eaa857782f5b2 Mon Sep 17 00:00:00 2001 From: Baptiste Lemoine Date: Thu, 28 Nov 2019 16:48:35 +0100 Subject: [PATCH] :zap: protect config with password --- examples.md | 34 +++++++++--- src/Controller/DefaultController.php | 77 ++++++++++++++++++++-------- src/Entity/Choice.php | 2 + src/Entity/Owner.php | 2 +- src/Entity/Poll.php | 6 ++- 5 files changed, 92 insertions(+), 29 deletions(-) diff --git a/examples.md b/examples.md index fb130c2..f1069d5 100644 --- a/examples.md +++ b/examples.md @@ -8,19 +8,41 @@ http://127.0.0.1:8000/api/doc.json ``` ## create a poll -``` -POST -http://127.0.0.1:8000/api/v1/poll/new +```http request +POST http://127.0.0.1:8000/api/v1/poll/new Content-Type:"application/json" +{ + "title": "un coup à boire", + "description": "et on boit quoi?", + "kind": "text", + "custom_url": "this-is-sparta", + "password":"hah", + "owner": { + "email": "contact@cipherbliss.com", + "pseudo": "cipherbliss crée un sondage par postman" + }, + "choices_to_create": [ "cappou" ,"thé", "café", "vodka" ] +} +``` + +## get configuration of existing poll, protected with a password + + + +```http request +GET http://127.0.0.1:8000/api/v1/poll/1 +Content-Type:"application/json" +{ + "password_input": "there_is_my_pass" +} ``` ## add a vote to an existing poll -``` -POST -http://127.0.0.1:8000/api/v1/poll/98/vote +```http request +POST http://127.0.0.1:8000/api/v1/poll/1/vote Content-Type:"application/json" { diff --git a/src/Controller/DefaultController.php b/src/Controller/DefaultController.php index ad6f278..c698d44 100644 --- a/src/Controller/DefaultController.php +++ b/src/Controller/DefaultController.php @@ -7,6 +7,8 @@ use App\Entity\Owner; use App\Entity\Poll; use App\Entity\StackOfVotes; use App\Entity\Vote; +use DateTime; +use DateTimeZone; use FOS\RestBundle\Controller\Annotations\Delete; use FOS\RestBundle\Controller\Annotations\Get; use FOS\RestBundle\Controller\Annotations\Post; @@ -14,6 +16,7 @@ use FOS\RestBundle\Controller\Annotations\Put; use FOS\RestBundle\Controller\Annotations\Route; use JMS\Serializer\SerializerBuilder; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; +use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; /** @@ -73,7 +76,7 @@ class DefaultController extends AbstractController { * ) * @param Request $request * - * @return \Symfony\Component\HttpFoundation\JsonResponse + * @return JsonResponse */ public function newPollAction( Request $request ) { @@ -83,11 +86,11 @@ class DefaultController extends AbstractController { $newpoll = $serializer->deserialize( $data, 'App\Entity\Poll', 'json' ); $newpoll ->setAdminKey( $newpoll->generateAdminKey() ) - ->setCreationDate( new \DateTime() ) - ->setModificationPolicy( 'none' ); + ->setCreationDate( new DateTime() ) + ->setModificationPolicy( 'nobody' ); $timeStamp = time() + ( 3600 * 24 * 90 ); // 90 days by default - $newpoll->setExpiracyDate( ( new \DateTime() )->setTimestamp( $timeStamp ), - new \DateTimeZone( 'Europe/Paris' ) ); + $newpoll->setExpiracyDate( ( new DateTime() )->setTimestamp( $timeStamp ), + new DateTimeZone( 'Europe/Paris' ) ); $data = json_decode( $data, true ); $em = $this->getDoctrine()->getRepository( Owner::class ); $foundOwner = $em->findOneBy( [ 'email' => $data[ 'owner' ][ 'email' ] ] ); @@ -113,6 +116,10 @@ class DefaultController extends AbstractController { $em->persist( $newpoll ); $em->persist( $foundOwner ); + // setup the password, converting the raw with md5 hash + if ( $data[ 'password' ] ) { + $newpoll->setPassword( $data[ 'password' ] ); + } // manage choices $choices = $data[ 'choices_to_create' ]; foreach ( $choices as $c ) { @@ -130,9 +137,10 @@ class DefaultController extends AbstractController { } return $this->json( [ - 'message' => 'you created a poll ' . $precision, - 'data' => $newpoll, - 'admin_key' => $newpoll->getAdminKey(), + 'message' => 'you created a poll ' . $precision, + 'data' => $newpoll, + 'password_protected' => is_string( $newpoll->getPassword() ), + 'admin_key' => $newpoll->getAdminKey(), ], 201 ); @@ -161,12 +169,40 @@ class DefaultController extends AbstractController { * requirements = {"poll_id"="\d+"} * ) */ - public function getPollConfig( Poll $poll ) { - return $this->json( [ - 'message' => 'your poll config', - 'data' => $poll, - ], - 200 ); + public function getPollConfig( Poll $poll, Request $request ) { + $pass = $poll->getPassword(); + $data = $request->getContent(); + $data = json_decode( $data, true ); + /** + * password protected content + */ + if ( $pass ) { + + if ( $pass == md5( $data[ 'password_input' ] ) ) { + return $this->json( [ + 'message' => 'your poll config', + 'data' => $poll, + 'stacks' => $poll->getStacksOfVotes(), + 'comments' => $poll->getComments(), + ], + 200 ); + } else { + return $this->json( [ + 'message' => 'your password ' . $data[ 'password_input' ] . ' is wrong, and you should feel bad', + 'data' => null, + ], + 403 ); + } + } else { + return $this->json( [ + 'message' => 'your poll config', + 'data' => $poll, + 'stacks' => $poll->getStacksOfVotes(), + 'comments' => $poll->getComments(), + ], + 200 ); + } + } /** @@ -192,7 +228,6 @@ class DefaultController extends AbstractController { ); $foundPolls = $queryFind->getResult(); - var_dump( count( $foundPolls ) ); $em->flush(); @@ -228,7 +263,7 @@ class DefaultController extends AbstractController { /** * add a comment on a poll * @Post( - * path = "poll/{id}/comment", + * path = "/poll/{id}/comment", * name = "new_comment", * requirements = {"content"="\w+", "poll_id"="\d+"} * ) @@ -272,7 +307,7 @@ class DefaultController extends AbstractController { /** * add a comment on a poll * @Post( - * path = "poll/{id}/vote", + * path = "/poll/{id}/vote", * name = "new_vote_stack", * requirements = {"content"="\w+", "poll_id"="\d+"} * ) @@ -339,7 +374,7 @@ class DefaultController extends AbstractController { * @param Poll $poll * @param $accessToken * - * @return \Symfony\Component\HttpFoundation\JsonResponse + * @return JsonResponse */ public function deletePollAction( Poll $poll, $accessToken ) { @@ -370,7 +405,7 @@ class DefaultController extends AbstractController { * @param Poll $poll * @param $accessToken * - * @return \Symfony\Component\HttpFoundation\JsonResponse + * @return JsonResponse */ public function deletePollCommentsAction( Poll $poll, $accessToken ) { if ( $accessToken == $poll->getAdminKey() ) { @@ -391,11 +426,11 @@ class DefaultController extends AbstractController { /** * @Delete( - * path = "/poll/{id}/votes", + * path = "/poll/{id}/votes/{accessToken}", * name = "poll_votes_delete", * requirements = {"accessToken"="\w+", "poll_id"="\d+"} * ) - * @return \Symfony\Component\HttpFoundation\JsonResponse + * @return JsonResponse */ public function deletePollVotesAction( Poll $poll, $accessToken ) { if ( $accessToken == $poll->getAdminKey() ) { diff --git a/src/Entity/Choice.php b/src/Entity/Choice.php index fa60343..cd838e4 100644 --- a/src/Entity/Choice.php +++ b/src/Entity/Choice.php @@ -16,12 +16,14 @@ class Choice { * @ORM\Id() * @ORM\GeneratedValue() * @ORM\Column(type="integer") + * @Serializer\Expose() */ private $id; /** * @ORM\Column(type="string", length=255, nullable=true) * @Serializer\Type("string") + * @Serializer\Expose() */ public $name; diff --git a/src/Entity/Owner.php b/src/Entity/Owner.php index 6ecfe6d..64a8d3d 100644 --- a/src/Entity/Owner.php +++ b/src/Entity/Owner.php @@ -28,7 +28,7 @@ class Owner { * @Serializer\Type("string") * @Serializer\Expose() */ - private $email; + public $email; /** * @ORM\OneToMany(targetEntity="App\Entity\Poll", mappedBy="owner",cascade={"persist","remove"},orphanRemoval=true) * @Serializer\Type("App\Entity\Poll") diff --git a/src/Entity/Poll.php b/src/Entity/Poll.php index 1d13ac8..6de0ad6 100644 --- a/src/Entity/Poll.php +++ b/src/Entity/Poll.php @@ -10,6 +10,7 @@ use JMS\Serializer\Annotation as Serializer; /** * @ORM\Entity(repositoryClass="App\Repository\PollRepository") + * @Serializer\ExclusionPolicy("ALL") */ class Poll { /** @@ -46,12 +47,14 @@ class Poll { public $creationDate; /** * @ORM\Column(type="datetime") + * @Serializer\Expose() */ public $expiracyDate; /** * @ORM\ManyToOne(targetEntity="App\Entity\Owner", inversedBy="polls",cascade={"persist"}) * @ORM\JoinColumn(nullable=false) * @Serializer\Type("App\Entity\Owner") + * @Serializer\Expose() */ public $owner; /** @@ -76,6 +79,7 @@ class Poll { * nobody - no one can modify the votes (excepted admin), pray to have it right at first * @ORM\Column(type="string", length=255) * @Serializer\Type("string") + * @Serializer\Expose() */ public $modificationPolicy = 'nobody'; /** @@ -311,7 +315,7 @@ class Poll { } public function setPassword( string $password ): self { - $this->password = $password; + $this->password = md5( $password ); return $this; }