protect config with password

This commit is contained in:
Baptiste Lemoine 2019-11-28 16:48:35 +01:00
parent 6c0ba2ddd6
commit fceb2be35d
5 changed files with 92 additions and 29 deletions

View File

@ -8,19 +8,41 @@ http://127.0.0.1:8000/api/doc.json
``` ```
## create a poll ## create a poll
``` ```http request
POST POST http://127.0.0.1:8000/api/v1/poll/new
http://127.0.0.1:8000/api/v1/poll/new
Content-Type:"application/json" 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 ## add a vote to an existing poll
``` ```http request
POST POST http://127.0.0.1:8000/api/v1/poll/1/vote
http://127.0.0.1:8000/api/v1/poll/98/vote
Content-Type:"application/json" Content-Type:"application/json"
{ {

View File

@ -7,6 +7,8 @@ use App\Entity\Owner;
use App\Entity\Poll; use App\Entity\Poll;
use App\Entity\StackOfVotes; use App\Entity\StackOfVotes;
use App\Entity\Vote; use App\Entity\Vote;
use DateTime;
use DateTimeZone;
use FOS\RestBundle\Controller\Annotations\Delete; use FOS\RestBundle\Controller\Annotations\Delete;
use FOS\RestBundle\Controller\Annotations\Get; use FOS\RestBundle\Controller\Annotations\Get;
use FOS\RestBundle\Controller\Annotations\Post; use FOS\RestBundle\Controller\Annotations\Post;
@ -14,6 +16,7 @@ use FOS\RestBundle\Controller\Annotations\Put;
use FOS\RestBundle\Controller\Annotations\Route; use FOS\RestBundle\Controller\Annotations\Route;
use JMS\Serializer\SerializerBuilder; use JMS\Serializer\SerializerBuilder;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
/** /**
@ -73,7 +76,7 @@ class DefaultController extends AbstractController {
* ) * )
* @param Request $request * @param Request $request
* *
* @return \Symfony\Component\HttpFoundation\JsonResponse * @return JsonResponse
*/ */
public function newPollAction( Request $request ) { public function newPollAction( Request $request ) {
@ -83,11 +86,11 @@ class DefaultController extends AbstractController {
$newpoll = $serializer->deserialize( $data, 'App\Entity\Poll', 'json' ); $newpoll = $serializer->deserialize( $data, 'App\Entity\Poll', 'json' );
$newpoll $newpoll
->setAdminKey( $newpoll->generateAdminKey() ) ->setAdminKey( $newpoll->generateAdminKey() )
->setCreationDate( new \DateTime() ) ->setCreationDate( new DateTime() )
->setModificationPolicy( 'none' ); ->setModificationPolicy( 'nobody' );
$timeStamp = time() + ( 3600 * 24 * 90 ); // 90 days by default $timeStamp = time() + ( 3600 * 24 * 90 ); // 90 days by default
$newpoll->setExpiracyDate( ( new \DateTime() )->setTimestamp( $timeStamp ), $newpoll->setExpiracyDate( ( new DateTime() )->setTimestamp( $timeStamp ),
new \DateTimeZone( 'Europe/Paris' ) ); new DateTimeZone( 'Europe/Paris' ) );
$data = json_decode( $data, true ); $data = json_decode( $data, true );
$em = $this->getDoctrine()->getRepository( Owner::class ); $em = $this->getDoctrine()->getRepository( Owner::class );
$foundOwner = $em->findOneBy( [ 'email' => $data[ 'owner' ][ 'email' ] ] ); $foundOwner = $em->findOneBy( [ 'email' => $data[ 'owner' ][ 'email' ] ] );
@ -113,6 +116,10 @@ class DefaultController extends AbstractController {
$em->persist( $newpoll ); $em->persist( $newpoll );
$em->persist( $foundOwner ); $em->persist( $foundOwner );
// setup the password, converting the raw with md5 hash
if ( $data[ 'password' ] ) {
$newpoll->setPassword( $data[ 'password' ] );
}
// manage choices // manage choices
$choices = $data[ 'choices_to_create' ]; $choices = $data[ 'choices_to_create' ];
foreach ( $choices as $c ) { foreach ( $choices as $c ) {
@ -130,9 +137,10 @@ class DefaultController extends AbstractController {
} }
return $this->json( [ return $this->json( [
'message' => 'you created a poll ' . $precision, 'message' => 'you created a poll ' . $precision,
'data' => $newpoll, 'data' => $newpoll,
'admin_key' => $newpoll->getAdminKey(), 'password_protected' => is_string( $newpoll->getPassword() ),
'admin_key' => $newpoll->getAdminKey(),
], ],
201 ); 201 );
@ -161,12 +169,40 @@ class DefaultController extends AbstractController {
* requirements = {"poll_id"="\d+"} * requirements = {"poll_id"="\d+"}
* ) * )
*/ */
public function getPollConfig( Poll $poll ) { public function getPollConfig( Poll $poll, Request $request ) {
return $this->json( [ $pass = $poll->getPassword();
'message' => 'your poll config', $data = $request->getContent();
'data' => $poll, $data = json_decode( $data, true );
], /**
200 ); * 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(); $foundPolls = $queryFind->getResult();
var_dump( count( $foundPolls ) );
$em->flush(); $em->flush();
@ -228,7 +263,7 @@ class DefaultController extends AbstractController {
/** /**
* add a comment on a poll * add a comment on a poll
* @Post( * @Post(
* path = "poll/{id}/comment", * path = "/poll/{id}/comment",
* name = "new_comment", * name = "new_comment",
* requirements = {"content"="\w+", "poll_id"="\d+"} * requirements = {"content"="\w+", "poll_id"="\d+"}
* ) * )
@ -272,7 +307,7 @@ class DefaultController extends AbstractController {
/** /**
* add a comment on a poll * add a comment on a poll
* @Post( * @Post(
* path = "poll/{id}/vote", * path = "/poll/{id}/vote",
* name = "new_vote_stack", * name = "new_vote_stack",
* requirements = {"content"="\w+", "poll_id"="\d+"} * requirements = {"content"="\w+", "poll_id"="\d+"}
* ) * )
@ -339,7 +374,7 @@ class DefaultController extends AbstractController {
* @param Poll $poll * @param Poll $poll
* @param $accessToken * @param $accessToken
* *
* @return \Symfony\Component\HttpFoundation\JsonResponse * @return JsonResponse
*/ */
public function deletePollAction( Poll $poll, $accessToken ) { public function deletePollAction( Poll $poll, $accessToken ) {
@ -370,7 +405,7 @@ class DefaultController extends AbstractController {
* @param Poll $poll * @param Poll $poll
* @param $accessToken * @param $accessToken
* *
* @return \Symfony\Component\HttpFoundation\JsonResponse * @return JsonResponse
*/ */
public function deletePollCommentsAction( Poll $poll, $accessToken ) { public function deletePollCommentsAction( Poll $poll, $accessToken ) {
if ( $accessToken == $poll->getAdminKey() ) { if ( $accessToken == $poll->getAdminKey() ) {
@ -391,11 +426,11 @@ class DefaultController extends AbstractController {
/** /**
* @Delete( * @Delete(
* path = "/poll/{id}/votes", * path = "/poll/{id}/votes/{accessToken}",
* name = "poll_votes_delete", * name = "poll_votes_delete",
* requirements = {"accessToken"="\w+", "poll_id"="\d+"} * requirements = {"accessToken"="\w+", "poll_id"="\d+"}
* ) * )
* @return \Symfony\Component\HttpFoundation\JsonResponse * @return JsonResponse
*/ */
public function deletePollVotesAction( Poll $poll, $accessToken ) { public function deletePollVotesAction( Poll $poll, $accessToken ) {
if ( $accessToken == $poll->getAdminKey() ) { if ( $accessToken == $poll->getAdminKey() ) {

View File

@ -16,12 +16,14 @@ class Choice {
* @ORM\Id() * @ORM\Id()
* @ORM\GeneratedValue() * @ORM\GeneratedValue()
* @ORM\Column(type="integer") * @ORM\Column(type="integer")
* @Serializer\Expose()
*/ */
private $id; private $id;
/** /**
* @ORM\Column(type="string", length=255, nullable=true) * @ORM\Column(type="string", length=255, nullable=true)
* @Serializer\Type("string") * @Serializer\Type("string")
* @Serializer\Expose()
*/ */
public $name; public $name;

View File

@ -28,7 +28,7 @@ class Owner {
* @Serializer\Type("string") * @Serializer\Type("string")
* @Serializer\Expose() * @Serializer\Expose()
*/ */
private $email; public $email;
/** /**
* @ORM\OneToMany(targetEntity="App\Entity\Poll", mappedBy="owner",cascade={"persist","remove"},orphanRemoval=true) * @ORM\OneToMany(targetEntity="App\Entity\Poll", mappedBy="owner",cascade={"persist","remove"},orphanRemoval=true)
* @Serializer\Type("App\Entity\Poll") * @Serializer\Type("App\Entity\Poll")

View File

@ -10,6 +10,7 @@ use JMS\Serializer\Annotation as Serializer;
/** /**
* @ORM\Entity(repositoryClass="App\Repository\PollRepository") * @ORM\Entity(repositoryClass="App\Repository\PollRepository")
* @Serializer\ExclusionPolicy("ALL")
*/ */
class Poll { class Poll {
/** /**
@ -46,12 +47,14 @@ class Poll {
public $creationDate; public $creationDate;
/** /**
* @ORM\Column(type="datetime") * @ORM\Column(type="datetime")
* @Serializer\Expose()
*/ */
public $expiracyDate; public $expiracyDate;
/** /**
* @ORM\ManyToOne(targetEntity="App\Entity\Owner", inversedBy="polls",cascade={"persist"}) * @ORM\ManyToOne(targetEntity="App\Entity\Owner", inversedBy="polls",cascade={"persist"})
* @ORM\JoinColumn(nullable=false) * @ORM\JoinColumn(nullable=false)
* @Serializer\Type("App\Entity\Owner") * @Serializer\Type("App\Entity\Owner")
* @Serializer\Expose()
*/ */
public $owner; public $owner;
/** /**
@ -76,6 +79,7 @@ class Poll {
* nobody - no one can modify the votes (excepted admin), pray to have it right at first * nobody - no one can modify the votes (excepted admin), pray to have it right at first
* @ORM\Column(type="string", length=255) * @ORM\Column(type="string", length=255)
* @Serializer\Type("string") * @Serializer\Type("string")
* @Serializer\Expose()
*/ */
public $modificationPolicy = 'nobody'; public $modificationPolicy = 'nobody';
/** /**
@ -311,7 +315,7 @@ class Poll {
} }
public function setPassword( string $password ): self { public function setPassword( string $password ): self {
$this->password = $password; $this->password = md5( $password );
return $this; return $this;
} }