From 28146ad9092a919984f00c7e779712ad730ecb97 Mon Sep 17 00:00:00 2001 From: Timothy J Warren Date: Tue, 29 Jan 2019 15:12:31 -0500 Subject: [PATCH] Add a per-controller-method check for authorization for private routes --- src/Controller.php | 23 +++++++++++++++++++++++ src/Controller/Anime.php | 28 ++++++++++++++++++++++++++++ src/Controller/AnimeCollection.php | 4 ++++ src/Controller/Manga.php | 20 ++++++++++++++++++++ src/Controller/Misc.php | 1 + src/Controller/Settings.php | 3 +++ 6 files changed, 79 insertions(+) diff --git a/src/Controller.php b/src/Controller.php index 08b117ef..6f0d7b44 100644 --- a/src/Controller.php +++ b/src/Controller.php @@ -33,6 +33,12 @@ class Controller { use ContainerAware; + /** + * The authentication object + * @var \Aviat\AnimeClient\API\Kitsu\Auth $auth ; + */ + protected $auth; + /** * Cache manager * @var \Psr\Cache\CacheItemPoolInterface @@ -96,6 +102,7 @@ class Controller { $session = $container->get('session'); $urlGenerator = $container->get('url-generator'); + $this->auth = $container->get('auth'); $this->cache = $container->get('cache'); $this->config = $container->get('config'); $this->request = $container->get('request'); @@ -172,6 +179,22 @@ class Controller { $this->session->set('redirect_url', NULL); } + /** + * Check if the current user is authenticated, else error and exit + */ + protected function checkAuth(): void + { + if ( ! $this->auth->isAuthenticated()) + { + $this->errorPage( + 403, + 'Forbidden', + 'You must log in to perform this action.' + ); + die(); + } + } + /** * Get the string output of a partial template * diff --git a/src/Controller/Anime.php b/src/Controller/Anime.php index 9bce1426..47be217b 100644 --- a/src/Controller/Anime.php +++ b/src/Controller/Anime.php @@ -67,6 +67,18 @@ final class Anime extends BaseController { */ public function index($type = KitsuWatchingStatus::WATCHING, string $view = NULL): void { + if ( ! in_array($type, [ + 'all', + 'watching', + 'plan_to_watch', + 'on_hold', + 'dropped', + 'completed', + ], TRUE)) + { + $this->errorPage(404, 'Not Found', 'Page not found'); + } + $title = array_key_exists($type, AnimeWatchingStatus::ROUTE_TO_TITLE) ? $this->formatTitle( $this->config->get('whose_list') . "'s Anime List", @@ -100,6 +112,8 @@ final class Anime extends BaseController { */ public function addForm(): void { + $this->checkAuth(); + $this->setSessionRedirect(); $this->outputHTML('anime/add', [ 'title' => $this->formatTitle( @@ -120,6 +134,8 @@ final class Anime extends BaseController { */ public function add(): void { + $this->checkAuth(); + $data = $this->request->getParsedBody(); if (empty($data['mal_id'])) @@ -155,6 +171,7 @@ final class Anime extends BaseController { */ public function edit(string $id, $status = 'all'): void { + $this->checkAuth(); $item = $this->model->getLibraryItem($id); $this->setSessionRedirect(); @@ -192,6 +209,7 @@ final class Anime extends BaseController { */ public function formUpdate(): void { + $this->checkAuth(); $data = $this->request->getParsedBody(); // Do some minor data manipulation for @@ -220,6 +238,8 @@ final class Anime extends BaseController { */ public function increment(): void { + $this->checkAuth(); + if (stripos($this->request->getHeader('content-type')[0], 'application/json') !== FALSE) { $data = Json::decode((string)$this->request->getBody()); @@ -229,6 +249,12 @@ final class Anime extends BaseController { $data = $this->request->getParsedBody(); } + if (empty($data)) + { + $this->errorPage(400, 'Bad Request', ''); + die(); + } + $response = $this->model->incrementLibraryItem(new FormItem($data)); $this->cache->clear(); @@ -242,6 +268,8 @@ final class Anime extends BaseController { */ public function delete(): void { + $this->checkAuth(); + $body = $this->request->getParsedBody(); $response = $this->model->deleteLibraryItem($body['id'], $body['mal_id']); diff --git a/src/Controller/AnimeCollection.php b/src/Controller/AnimeCollection.php index 3510910a..3332bf64 100644 --- a/src/Controller/AnimeCollection.php +++ b/src/Controller/AnimeCollection.php @@ -111,6 +111,7 @@ final class AnimeCollection extends BaseController { */ public function form($id = NULL): void { + $this->checkAuth(); $this->setSessionRedirect(); $action = $id === NULL ? 'Add' : 'Edit'; @@ -138,6 +139,7 @@ final class AnimeCollection extends BaseController { */ public function edit(): void { + $this->checkAuth(); $data = $this->request->getParsedBody(); if (array_key_exists('hummingbird_id', $data)) { @@ -163,6 +165,7 @@ final class AnimeCollection extends BaseController { */ public function add(): void { + $this->checkAuth(); $data = $this->request->getParsedBody(); if (array_key_exists('id', $data)) { @@ -193,6 +196,7 @@ final class AnimeCollection extends BaseController { */ public function delete(): void { + $this->checkAuth(); $data = $this->request->getParsedBody(); if ( ! array_key_exists('hummingbird_id', $data)) { diff --git a/src/Controller/Manga.php b/src/Controller/Manga.php index 8d1b81be..ed269482 100644 --- a/src/Controller/Manga.php +++ b/src/Controller/Manga.php @@ -66,6 +66,18 @@ final class Manga extends Controller { */ public function index($status = 'all', $view = ''): void { + if ( ! in_array($type, [ + 'all', + 'reading', + 'plan_to_read', + 'dropped', + 'on_hold', + 'completed', + ], TRUE)) + { + $this->errorPage(404, 'Not Found', 'Page not found'); + } + $statusTitle = MangaReadingStatus::ROUTE_TO_TITLE[$status]; $title = $this->formatTitle( @@ -99,6 +111,7 @@ final class Manga extends Controller { */ public function addForm(): void { + $this->checkAuth(); $statuses = MangaReadingStatus::KITSU_TO_TITLE; $this->setSessionRedirect(); @@ -121,6 +134,7 @@ final class Manga extends Controller { */ public function add(): void { + $this->checkAuth(); $data = $this->request->getParsedBody(); if ( ! array_key_exists('id', $data)) { @@ -160,6 +174,7 @@ final class Manga extends Controller { */ public function edit($id, $status = 'All'): void { + $this->checkAuth(); $this->setSessionRedirect(); $item = $this->model->getLibraryItem($id); $title = $this->formatTitle( @@ -198,6 +213,7 @@ final class Manga extends Controller { */ public function formUpdate(): void { + $this->checkAuth(); $data = $this->request->getParsedBody(); // Do some minor data manipulation for @@ -225,6 +241,8 @@ final class Manga extends Controller { */ public function increment(): void { + $this->checkAuth(); + if (stripos($this->request->getHeader('content-type')[0], 'application/json') !== FALSE) { $data = Json::decode((string)$this->request->getBody()); @@ -249,6 +267,8 @@ final class Manga extends Controller { */ public function delete(): void { + $this->checkAuth(); + $body = $this->request->getParsedBody(); $response = $this->model->deleteLibraryItem($body['id'], $body['mal_id']); diff --git a/src/Controller/Misc.php b/src/Controller/Misc.php index fdc12f66..a93ace98 100644 --- a/src/Controller/Misc.php +++ b/src/Controller/Misc.php @@ -89,6 +89,7 @@ final class Misc extends BaseController { */ public function logout(): void { + $this->checkAuth(); $auth = $this->container->get('auth'); $auth->logout(); diff --git a/src/Controller/Settings.php b/src/Controller/Settings.php index 729595ac..82a296dd 100644 --- a/src/Controller/Settings.php +++ b/src/Controller/Settings.php @@ -47,6 +47,9 @@ final class Settings extends BaseController { $this->anilistModel = $container->get('anilist-model'); $this->settingsModel = $container->get('settings-model'); + + // This is a rare controller where every route is private + $this->checkAuth(); } /**