mirror of
https://github.com/CachetHQ/Cachet.git
synced 2025-01-17 21:49:01 +01:00
Merge pull request #738 from cachethq/errors
Respond with the correct responses on error
This commit is contained in:
commit
26857597f0
@ -45,5 +45,6 @@ class Kernel extends HttpKernel
|
||||
'app.isSetup' => 'CachetHQ\Cachet\Http\Middleware\AppIsSetup',
|
||||
'app.hasSetting' => 'CachetHQ\Cachet\Http\Middleware\HasSetting',
|
||||
'app.subscribers' => 'CachetHQ\Cachet\Http\Middleware\SubscribersConfigured',
|
||||
'accept' => 'CachetHQ\Cachet\Http\Middleware\Acceptable',
|
||||
];
|
||||
}
|
||||
|
36
app/Http/Middleware/Acceptable.php
Normal file
36
app/Http/Middleware/Acceptable.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Cachet.
|
||||
*
|
||||
* (c) Cachet HQ <support@cachethq.io>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace CachetHQ\Cachet\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Symfony\Component\HttpKernel\Exception\NotAcceptableHttpException;
|
||||
|
||||
class Acceptable
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @param string $type
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next, $type)
|
||||
{
|
||||
if (!$request->accepts($type)) {
|
||||
throw new NotAcceptableHttpException();
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
@ -13,7 +13,7 @@ namespace CachetHQ\Cachet\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Contracts\Auth\Guard;
|
||||
use Illuminate\Support\Facades\Response;
|
||||
use Symfony\Component\HttpKernel\Exception\HttpException;
|
||||
|
||||
class Admin
|
||||
{
|
||||
@ -45,9 +45,7 @@ class Admin
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
if (!$this->auth->check() || ($this->auth->check() && !$this->auth->user()->isAdmin)) {
|
||||
return Response::view('errors.401', [
|
||||
'pageTitle' => trans('errors.unauthorized.title'),
|
||||
], 401);
|
||||
throw new HttpException(401);
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
|
@ -15,6 +15,7 @@ use CachetHQ\Cachet\Models\User;
|
||||
use Closure;
|
||||
use Illuminate\Contracts\Auth\Guard;
|
||||
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
||||
use Symfony\Component\HttpKernel\Exception\HttpException;
|
||||
|
||||
class ApiAuthenticate
|
||||
{
|
||||
@ -48,34 +49,19 @@ class ApiAuthenticate
|
||||
if ($this->auth->guest()) {
|
||||
if ($apiToken = $request->header('X-Cachet-Token')) {
|
||||
try {
|
||||
$user = User::findByApiToken($apiToken);
|
||||
|
||||
$this->auth->onceUsingId($user->id);
|
||||
$this->auth->onceUsingId(User::findByApiToken($apiToken)->id);
|
||||
} catch (ModelNotFoundException $e) {
|
||||
return $this->handleError();
|
||||
throw new HttpException(401);
|
||||
}
|
||||
} elseif ($user = $request->getUser()) {
|
||||
} elseif ($request->getUser()) {
|
||||
if ($this->auth->onceBasic() !== null) {
|
||||
return $this->handleError();
|
||||
throw new HttpException(401);
|
||||
}
|
||||
} else {
|
||||
return $this->handleError();
|
||||
throw new HttpException(401);
|
||||
}
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Common method for returning an unauthorized error.
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
protected function handleError()
|
||||
{
|
||||
return response()->json([
|
||||
'message' => 'You are not authorized to view this content.',
|
||||
'status_code' => 401,
|
||||
], 401);
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ namespace CachetHQ\Cachet\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Contracts\Auth\Guard;
|
||||
use Symfony\Component\HttpKernel\Exception\HttpException;
|
||||
|
||||
class Authenticate
|
||||
{
|
||||
@ -44,11 +45,7 @@ class Authenticate
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
if ($this->auth->guest()) {
|
||||
if ($request->ajax()) {
|
||||
return response('Unauthorized.', 401);
|
||||
} else {
|
||||
return redirect()->guest('auth/login');
|
||||
}
|
||||
throw new HttpException(401);
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
|
@ -23,8 +23,9 @@ class ApiRoutes
|
||||
public function map(Registrar $router)
|
||||
{
|
||||
$router->group([
|
||||
'namespace' => 'Api',
|
||||
'prefix' => 'api/v1',
|
||||
'namespace' => 'Api',
|
||||
'prefix' => 'api/v1',
|
||||
'middleware' => 'accept:application/json',
|
||||
], function ($router) {
|
||||
// General
|
||||
$router->get('ping', 'GeneralController@ping');
|
||||
|
@ -1,25 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Cachet.
|
||||
*
|
||||
* (c) Cachet HQ <support@cachethq.io>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
return [
|
||||
'not-found' => [
|
||||
'code' => '404',
|
||||
'title' => 'Die Seite konnte nicht gefunden werden!',
|
||||
'message' => 'Entschuldigung, aber die Seite konnte nicht gefunden werden. Überprüfen Sie die URL und versuchen Sie es erneut.',
|
||||
'link' => 'Zurück zur Startseite',
|
||||
],
|
||||
'unauthorized' => [
|
||||
'code' => '401',
|
||||
'title' => 'Unauthorized',
|
||||
'message' => 'Sorry, you need admin privileges to see this page.',
|
||||
'link' => 'Return to homepage',
|
||||
],
|
||||
];
|
@ -1,25 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Cachet.
|
||||
*
|
||||
* (c) Cachet HQ <support@cachethq.io>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
return [
|
||||
'not-found' => [
|
||||
'code' => 'crwdns208:0crwdne208:0',
|
||||
'title' => 'crwdns367:0crwdne367:0',
|
||||
'message' => 'crwdns368:0crwdne368:0',
|
||||
'link' => 'crwdns369:0crwdne369:0',
|
||||
],
|
||||
'unauthorized' => [
|
||||
'code' => 'crwdns370:0crwdne370:0',
|
||||
'title' => 'crwdns371:0crwdne371:0',
|
||||
'message' => 'crwdns372:0crwdne372:0',
|
||||
'link' => 'crwdns373:0crwdne373:0',
|
||||
],
|
||||
];
|
@ -1,25 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Cachet.
|
||||
*
|
||||
* (c) Cachet HQ <support@cachethq.io>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
return [
|
||||
'not-found' => [
|
||||
'code' => '404',
|
||||
'title' => 'That page went missing!',
|
||||
'message' => 'Sorry, but the page you are looking for has not been found. Check the URL for errors and try again.',
|
||||
'link' => 'Return to homepage',
|
||||
],
|
||||
'unauthorized' => [
|
||||
'code' => '401',
|
||||
'title' => 'Unauthorized',
|
||||
'message' => 'Sorry, you need admin privileges to see this page.',
|
||||
'link' => 'Return to homepage',
|
||||
],
|
||||
];
|
@ -1,25 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Cachet.
|
||||
*
|
||||
* (c) Cachet HQ <support@cachethq.io>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
return [
|
||||
'not-found' => [
|
||||
'code' => '404',
|
||||
'title' => '¡Esta página se perdió!',
|
||||
'message' => 'Lo sentimos, no se ha encontrado la página que estás buscando. Comprueba que la dirección URL no contenga errores y vuelve a intentarlo.',
|
||||
'link' => 'Regresar a la página de inicio',
|
||||
],
|
||||
'unauthorized' => [
|
||||
'code' => '401',
|
||||
'title' => 'No autorizado',
|
||||
'message' => 'Lo sentimos, necesitas privilegios de administrador para ver esta página.',
|
||||
'link' => 'Regresar a la página de inicio',
|
||||
],
|
||||
];
|
@ -1,25 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Cachet.
|
||||
*
|
||||
* (c) Cachet HQ <support@cachethq.io>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
return [
|
||||
'not-found' => [
|
||||
'code' => '404',
|
||||
'title' => 'Cette page est manquante !',
|
||||
'message' => 'Désolé, mais la page que vous recherchez est introuvable. Vérifier l\'URL et essayez à nouveau.',
|
||||
'link' => 'Retour à l\'accueil',
|
||||
],
|
||||
'unauthorized' => [
|
||||
'code' => '401',
|
||||
'title' => 'Unauthorized',
|
||||
'message' => 'Sorry, you need admin privileges to see this page.',
|
||||
'link' => 'Return to homepage',
|
||||
],
|
||||
];
|
@ -1,25 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Cachet.
|
||||
*
|
||||
* (c) Cachet HQ <support@cachethq.io>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
return [
|
||||
'not-found' => [
|
||||
'code' => '404',
|
||||
'title' => 'Halaman ini hilang!',
|
||||
'message' => 'Maaf, halaman yang diinginkan tidak ditemukan. Periksa apakah ada kesalahan URL lalu coba lagi.',
|
||||
'link' => 'Kembali ke depan',
|
||||
],
|
||||
'unauthorized' => [
|
||||
'code' => '401',
|
||||
'title' => 'Tidak dibolehkan',
|
||||
'message' => 'Maaf, anda perlu kewenangan admin untuk melihat halaman ini.',
|
||||
'link' => 'Kembali ke depan',
|
||||
],
|
||||
];
|
@ -1,25 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Cachet.
|
||||
*
|
||||
* (c) Cachet HQ <support@cachethq.io>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
return [
|
||||
'not-found' => [
|
||||
'code' => '404',
|
||||
'title' => 'Die pagina is vermist geraakt!',
|
||||
'message' => 'Sorry, maar de pagina die je zoekt is niet gevonden. Controleer de URL op fouten en probeer het nogmaals.',
|
||||
'link' => 'Terug naar homepagina',
|
||||
],
|
||||
'unauthorized' => [
|
||||
'code' => '401',
|
||||
'title' => 'Ongeautoriseerd',
|
||||
'message' => 'Sorry, maar je moet beheerdersrechten hebben om deze pagina te bekijken.',
|
||||
'link' => 'Terug naar homepagina',
|
||||
],
|
||||
];
|
@ -1,25 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Cachet.
|
||||
*
|
||||
* (c) Cachet HQ <support@cachethq.io>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
return [
|
||||
'not-found' => [
|
||||
'code' => '404',
|
||||
'title' => 'That page went missing!',
|
||||
'message' => 'Sorry, but the page you are looking for has not been found. Check the URL for errors and try again.',
|
||||
'link' => 'Return to homepage',
|
||||
],
|
||||
'unauthorized' => [
|
||||
'code' => '401',
|
||||
'title' => 'Unauthorized',
|
||||
'message' => 'Sorry, you need admin privileges to see this page.',
|
||||
'link' => 'Return to homepage',
|
||||
],
|
||||
];
|
@ -1,25 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Cachet.
|
||||
*
|
||||
* (c) Cachet HQ <support@cachethq.io>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
return [
|
||||
'not-found' => [
|
||||
'code' => '404',
|
||||
'title' => 'Essa página desapareceu!',
|
||||
'message' => 'Desculpe, mas a página que você está procurando não foi encontrada. Verifique a URL por erros e tente novamente.',
|
||||
'link' => 'Voltar para a página inicial',
|
||||
],
|
||||
'unauthorized' => [
|
||||
'code' => '401',
|
||||
'title' => 'Não autorizado',
|
||||
'message' => 'Desculpe, que você precisa de privilégios de administrador para ver esta página.',
|
||||
'link' => 'Voltar para a página inicial',
|
||||
],
|
||||
];
|
@ -1,25 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Cachet.
|
||||
*
|
||||
* (c) Cachet HQ <support@cachethq.io>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
return [
|
||||
'not-found' => [
|
||||
'code' => '404',
|
||||
'title' => '这个页面失踪了!',
|
||||
'message' => '抱歉,但我们无法找到您要访问的的页面。请检查你的 URL,然后重试。',
|
||||
'link' => '返回主页',
|
||||
],
|
||||
'unauthorized' => [
|
||||
'code' => '401',
|
||||
'title' => '未授权',
|
||||
'message' => '很抱歉,您需要管理员权限才能看到此页面。',
|
||||
'link' => '返回主页',
|
||||
],
|
||||
];
|
@ -1,25 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Cachet.
|
||||
*
|
||||
* (c) Cachet HQ <support@cachethq.io>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
return [
|
||||
'not-found' => [
|
||||
'code' => '404',
|
||||
'title' => '找不到頁面',
|
||||
'message' => '抱歉,你所請求的頁面並不存在。請檢查你的 URL 是否正確並再試一次。',
|
||||
'link' => '返回主頁',
|
||||
],
|
||||
'unauthorized' => [
|
||||
'code' => '401',
|
||||
'title' => '未經授權',
|
||||
'message' => '抱歉,你需要管理員權限方可瀏覽本頁面。',
|
||||
'link' => '返回主頁',
|
||||
],
|
||||
];
|
@ -1,19 +0,0 @@
|
||||
@extends('layout.error')
|
||||
|
||||
@section('content')
|
||||
<div class="middle-box text-center">
|
||||
<div>
|
||||
<img class="logo" height="65" src="{{ url('img/cachet-logo.svg') }}" alt="Cachet">
|
||||
</div>
|
||||
<h1>{{ trans('errors.unauthorized.code') }}</h1>
|
||||
<h3>{{ trans('errors.unauthorized.title') }}</h3>
|
||||
|
||||
<div class="error-desc">
|
||||
<p>{{ trans('errors.unauthorized.message') }}</p>
|
||||
<br>
|
||||
<p>
|
||||
<a href="/" class="btn btn-default btn-lg">{{ trans('errors.unauthorized.link') }}</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@stop
|
@ -1,19 +0,0 @@
|
||||
@extends('layout.error')
|
||||
|
||||
@section('content')
|
||||
<div class="middle-box text-center">
|
||||
<div>
|
||||
<img class="logo" height="65" src="{{ url('img/cachet-logo.svg') }}" alt="Cachet">
|
||||
</div>
|
||||
<h1>{{ trans('errors.not-found.code') }}</h1>
|
||||
<h3>{{ trans('errors.not-found.title') }}</h3>
|
||||
|
||||
<div class="error-desc">
|
||||
<p>{{ trans('errors.not-found.message') }}</p>
|
||||
<br>
|
||||
<p>
|
||||
<a href="/" class="btn btn-default btn-lg">{{ trans('errors.not-found.link') }}</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@stop
|
@ -38,8 +38,8 @@ class ComponentTest extends AbstractTestCase
|
||||
public function testPostComponentUnauthorized()
|
||||
{
|
||||
$this->post('/api/v1/components');
|
||||
|
||||
$this->assertResponseStatus(401);
|
||||
$this->seeJson(['message' => 'You are not authorized to view this content.', 'status_code' => 401]);
|
||||
}
|
||||
|
||||
public function testPostComponentNoData()
|
||||
|
@ -20,5 +20,26 @@ class GeneralTest extends AbstractTestCase
|
||||
$this->get('/api/v1/ping');
|
||||
$this->seeJson(['data' => 'Pong!']);
|
||||
$this->assertResponseOk();
|
||||
$this->seeHeader('Content-Type', 'application/json');
|
||||
}
|
||||
|
||||
public function testErrorPage()
|
||||
{
|
||||
$this->get('/api/v1/not-found');
|
||||
|
||||
$this->assertResponseStatus(404);
|
||||
$this->seeHeader('Content-Type', 'application/json');
|
||||
$this->seeJson(['errors' => [[
|
||||
'status' => 404,
|
||||
'title' => 'Not Found',
|
||||
'detail' => 'The requested resource could not be found but may be available again in the future.',
|
||||
]]]);
|
||||
}
|
||||
|
||||
public function testNotAcceptableContentType()
|
||||
{
|
||||
$this->get('/api/v1/ping', ['HTTP_Accept' => 'text/html']);
|
||||
|
||||
$this->assertResponseStatus(406);
|
||||
}
|
||||
}
|
||||
|
@ -39,7 +39,6 @@ class IncidentTest extends AbstractTestCase
|
||||
{
|
||||
$this->post('/api/v1/incidents');
|
||||
$this->assertResponseStatus(401);
|
||||
$this->seeJson(['message' => 'You are not authorized to view this content.', 'status_code' => 401]);
|
||||
}
|
||||
|
||||
public function testPostIncidentNoData()
|
||||
|
@ -40,7 +40,6 @@ class MetricPointTest extends AbstractTestCase
|
||||
$this->post("/api/v1/metrics/{$metric->id}/points");
|
||||
|
||||
$this->assertResponseStatus(401);
|
||||
$this->seeJson(['message' => 'You are not authorized to view this content.', 'status_code' => 401]);
|
||||
}
|
||||
|
||||
public function testPostMetricPoint()
|
||||
|
@ -39,7 +39,6 @@ class MetricTest extends AbstractTestCase
|
||||
{
|
||||
$this->post('/api/v1/metrics');
|
||||
$this->assertResponseStatus(401);
|
||||
$this->seeJson(['message' => 'You are not authorized to view this content.', 'status_code' => 401]);
|
||||
}
|
||||
|
||||
public function testPostMetricNoData()
|
||||
|
Loading…
x
Reference in New Issue
Block a user