Add a per-controller-method check for authorization for private routes
All checks were successful
timw4mail/HummingBirdAnimeClient/PR-21 This commit looks good

This commit is contained in:
Timothy Warren 2019-01-29 15:12:31 -05:00
parent 0348d0db00
commit 28146ad909
6 changed files with 79 additions and 0 deletions

View File

@ -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 <a href="/login">log in</a> to perform this action.'
);
die();
}
}
/**
* Get the string output of a partial template
*

View File

@ -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']);

View File

@ -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))
{

View File

@ -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']);

View File

@ -89,6 +89,7 @@ final class Misc extends BaseController {
*/
public function logout(): void
{
$this->checkAuth();
$auth = $this->container->get('auth');
$auth->logout();

View File

@ -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();
}
/**