From d0f1ffc4563d338e134bd105ef736e9901db14b1 Mon Sep 17 00:00:00 2001
From: Tagadda <36127788+Tagadda@users.noreply.github.com>
Date: Mon, 13 Aug 2018 13:50:31 +0200
Subject: [PATCH 1/5] Some more documentaion
---
API.md | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
README.md | 4 +++-
2 files changed, 71 insertions(+), 1 deletion(-)
create mode 100644 API.md
diff --git a/API.md b/API.md
new file mode 100644
index 0000000..1f597f7
--- /dev/null
+++ b/API.md
@@ -0,0 +1,68 @@
+# VerlainePoll's API
+
+## Methods
+
+### Create a poll
+```
+POST /polls
+```
+
+| Field | Description | Optional |
+| -------------- | ------------------------------------ | ---------- |
+| `title` | The question. | no |
+| `options` | All the options. Array of strings. | no |
+| `settings` | A Settings object. | yes |
+
+Return a Poll.
+
+### Retrieve a poll
+
+```
+GET /polls/:id
+```
+
+Return a Poll.
+
+### Vote
+
+```
+POST /polls/:id/vote
+```
+| Field | Description | Optional |
+| -------------- | -------------------------------------------- | ---------- |
+| `options` | Options you want to vote for. Array of ids. | no |
+
+Return a Poll.
+
+### Delete a poll
+
+```
+DELETE /polls/:id
+```
+
+Return a Poll.
+
+## Entities
+
+### Poll
+
+| Attribute | Description | Nullable |
+| --------------- | ------------------------------------ | ---------- |
+| `id` | | no |
+| `title` | The question. | no |
+| `options` | All the options. Array of Options. | no |
+| `settings` | A Settings object. | no |
+| `creation_date` | Creation date. | no |
+
+### Options
+
+| Attribute | Description | Nullable |
+| --------------- | ------------------------------------ | ---------- |
+| `id` | | no |
+| `label` | The option. | no |
+
+### Settings
+
+| Attribute | Description | Nullable |
+| --------------- | ------------------------------------ | ---------- |
+| `unique_ip` | One vote per IP address. Boolean. | yes |
diff --git a/README.md b/README.md
index f32fa59..300c44c 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@ Clone the repository :
mkdir db && touch db/polls.db && composer install
```
-Uncomment the dba extention in `php.ini` :
+Uncomment the `dba` extention in `php.ini` :
```
extension=dba
```
@@ -25,3 +25,5 @@ location /
```
## API
+
+See [API.md](API.md).
\ No newline at end of file
From d5ab16135db21cbc3174c0f06f2fdb7ed55ded81 Mon Sep 17 00:00:00 2001
From: Tagadda <36127788+Tagadda@users.noreply.github.com>
Date: Mon, 13 Aug 2018 14:29:55 +0200
Subject: [PATCH 2/5] Remove id from Option
---
API.md | 1 -
1 file changed, 1 deletion(-)
diff --git a/API.md b/API.md
index 1f597f7..a20505c 100644
--- a/API.md
+++ b/API.md
@@ -58,7 +58,6 @@ Return a Poll.
| Attribute | Description | Nullable |
| --------------- | ------------------------------------ | ---------- |
-| `id` | | no |
| `label` | The option. | no |
### Settings
From 7a29c6265b2af2891c0b6685137f566625e6c776 Mon Sep 17 00:00:00 2001
From: Tagadda <36127788+Tagadda@users.noreply.github.com>
Date: Mon, 13 Aug 2018 15:20:06 +0200
Subject: [PATCH 3/5] Delete a Poll
---
index.php | 31 ++++++++++++++++++++++++++++---
models/Poll.php | 13 ++++++++++++-
static/js/new.js | 1 +
views/home.php | 1 +
4 files changed, 42 insertions(+), 4 deletions(-)
diff --git a/index.php b/index.php
index 2d86700..b9c1038 100644
--- a/index.php
+++ b/index.php
@@ -3,14 +3,19 @@ require __DIR__ . "/vendor/autoload.php";
require __DIR__ . "/models/Poll.php";
require __DIR__ . "/config/app.php";
-function format_poll($poll)
+function format_poll($poll, $with_delete_token = false)
{
- return [
+ $array = [
"id" => $poll->id,
"title" => $poll->title,
"creation_date" => $poll->creation_date,
"options" => $poll->options,
];
+
+ if ($with_delete_token === true)
+ $array['delete_token'] = $poll->delete_token;
+
+ return $array;
}
Flight::route("POST /polls", function () {
@@ -20,7 +25,7 @@ Flight::route("POST /polls", function () {
$request_json = $request->data;
$poll = Poll::create_poll($request_json);
if ($poll)
- Flight::json(format_poll($poll), 201);
+ Flight::json(format_poll($poll, true), 201);
else
Flight::halt(403, "
403 Forbidden
Invalid data.
");
}
@@ -86,6 +91,26 @@ Flight::route("POST /polls/@id:[a-fA-F0-9]+/vote", function ($id) {
Flight::notFound();
});
+Flight::route("GET|DELETE /polls/@id:[a-fA-F0-9]+/@token:[a-fA-F0-9]+", function ($id, $token) {
+ $poll = Poll::load_poll($id);
+ if ($poll)
+ {
+ if ($poll->delete_token !== $token)
+ Flight::halt(401, "401 Unauthorized
Invalid token.
");
+
+ $poll->delete();
+
+ if (Flight::request()->type === "application/json")
+ Flight::json(format_poll($poll), 204);
+ else
+ {
+ Flight::redirect('/');
+ }
+ }
+ else
+ Flight::notFound();
+});
+
Flight::route("/", function () {
global $VERLAINE;
Flight::render("home", ["app_url" => $VERLAINE["app_url"]], "body_content");
diff --git a/models/Poll.php b/models/Poll.php
index 5dd8112..7d56e7b 100644
--- a/models/Poll.php
+++ b/models/Poll.php
@@ -22,6 +22,7 @@ class Poll
];
}
$poll->gen_new_id();
+ $poll->delete_token = bin2hex(openssl_random_pseudo_bytes(16));
$poll->save();
return $poll;
}
@@ -46,6 +47,7 @@ class Poll
$poll->title = $saved_poll_data->title;
$poll->creation_date = $saved_poll_data->creation_date;
$poll->options = $saved_poll_data->options;
+ $poll->delete_token = $saved_poll_data->delete_token;
dba_close($db);
return $poll;
@@ -61,8 +63,9 @@ class Poll
public $title;
public $creation_date;
public $options = [];
+ public $delete_token;
- public function gen_new_id()
+ private function gen_new_id()
{
$db = dba_open(SAVE_PATH . "/polls.db", "rd");
@@ -97,7 +100,15 @@ class Poll
"title" => $this->title,
"creation_date" => $this->creation_date,
"options" => $this->options,
+ "delete_token" => $this->delete_token
]), $db);
dba_close($db);
}
+
+ public function delete()
+ {
+ $db = dba_open(SAVE_PATH . "/polls.db", "wd");
+ dba_delete($this->id, $db);
+ dba_close($db);
+ }
}
diff --git a/static/js/new.js b/static/js/new.js
index a1d0012..5f3d533 100644
--- a/static/js/new.js
+++ b/static/js/new.js
@@ -48,6 +48,7 @@ document.addEventListener("DOMContentLoaded", () => {
let result_el = document.getElementById("result");
result_el.innerHTML = result_el.innerHTML.replace(/:poll_title/g, json.title);
result_el.innerHTML = result_el.innerHTML.replace(/:poll_url/g, `/polls/${json.id}`);
+ result_el.innerHTML = result_el.innerHTML.replace(/:delete_url/g, `/polls/${json.id}/${json.delete_token}`);
result_el.removeAttribute("hidden");
});
});
diff --git a/views/home.php b/views/home.php
index f541cf5..658e008 100644
--- a/views/home.php
+++ b/views/home.php
@@ -14,6 +14,7 @@
From 9469ffb88b5d2bea3c90e0cdde626f45e423d72b Mon Sep 17 00:00:00 2001
From: Tagadda <36127788+Tagadda@users.noreply.github.com>
Date: Mon, 13 Aug 2018 15:23:26 +0200
Subject: [PATCH 4/5] DELETE: Change HTTP Status Code to 204
---
index.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/index.php b/index.php
index b9c1038..0916b61 100644
--- a/index.php
+++ b/index.php
@@ -104,7 +104,7 @@ Flight::route("GET|DELETE /polls/@id:[a-fA-F0-9]+/@token:[a-fA-F0-9]+", function
Flight::json(format_poll($poll), 204);
else
{
- Flight::redirect('/');
+ Flight::redirect('/', 204);
}
}
else
From a0333c7065746e00e38762afab41b8721aba7c9c Mon Sep 17 00:00:00 2001
From: Tagadda <36127788+Tagadda@users.noreply.github.com>
Date: Mon, 13 Aug 2018 16:22:24 +0200
Subject: [PATCH 5/5] WIP: DELETE Redirect on error
---
index.php | 25 ++++++++++++++++++-------
1 file changed, 18 insertions(+), 7 deletions(-)
diff --git a/index.php b/index.php
index 0916b61..fb57ece 100644
--- a/index.php
+++ b/index.php
@@ -95,16 +95,27 @@ Flight::route("GET|DELETE /polls/@id:[a-fA-F0-9]+/@token:[a-fA-F0-9]+", function
$poll = Poll::load_poll($id);
if ($poll)
{
- if ($poll->delete_token !== $token)
- Flight::halt(401, "401 Unauthorized
Invalid token.
");
-
- $poll->delete();
-
if (Flight::request()->type === "application/json")
- Flight::json(format_poll($poll), 204);
+ {
+ if ($poll->delete_token === $token)
+ {
+ $poll->delete();
+
+ Flight::json(format_poll($poll), 204);
+ }
+ else
+ Flight::halt(401, "401 Unauthorized
Invalid token.
");
+ }
else
{
- Flight::redirect('/', 204);
+ if ($poll->delete_token === $token)
+ {
+ $poll->delete();
+
+ Flight::redirect('/', 204);
+ }
+ else
+ Flight::redirect('/', 401);
}
}
else