mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-09-17 02:05:34 +00:00
Fix issues with API authentication.
This commit is contained in:
@@ -25,12 +25,14 @@ namespace FireflyIII\Api\V1\Controllers;
|
|||||||
use Auth;
|
use Auth;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use FireflyIII\Models\Bill;
|
use FireflyIII\Models\Bill;
|
||||||
|
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
||||||
use FireflyIII\Transformers\BillTransformer;
|
use FireflyIII\Transformers\BillTransformer;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
use League\Fractal\Manager;
|
use League\Fractal\Manager;
|
||||||
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
||||||
use League\Fractal\Resource\Collection as FractalCollection;
|
use League\Fractal\Resource\Collection as FractalCollection;
|
||||||
|
use League\Fractal\Resource\Item;
|
||||||
use League\Fractal\Serializer\JsonApiSerializer;
|
use League\Fractal\Serializer\JsonApiSerializer;
|
||||||
use Preferences;
|
use Preferences;
|
||||||
use Response;
|
use Response;
|
||||||
@@ -40,6 +42,28 @@ use Response;
|
|||||||
*/
|
*/
|
||||||
class BillController extends Controller
|
class BillController extends Controller
|
||||||
{
|
{
|
||||||
|
/** @var BillRepositoryInterface */
|
||||||
|
private $repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BillController constructor.
|
||||||
|
*
|
||||||
|
* @throws \FireflyIII\Exceptions\FireflyException
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
$this->middleware(
|
||||||
|
function ($request, $next) {
|
||||||
|
/** @var BillRepositoryInterface repository */
|
||||||
|
$this->repository = app(BillRepositoryInterface::class);
|
||||||
|
$this->repository->setUser(auth()->user());
|
||||||
|
|
||||||
|
return $next($request);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove the specified resource from storage.
|
* Remove the specified resource from storage.
|
||||||
*
|
*
|
||||||
@@ -49,7 +73,9 @@ class BillController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function destroy(Bill $bill)
|
public function destroy(Bill $bill)
|
||||||
{
|
{
|
||||||
//
|
$this->repository->destroy($bill);
|
||||||
|
return response()->json(null, 204);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -69,7 +95,7 @@ class BillController extends Controller
|
|||||||
if (null !== $request->get('end')) {
|
if (null !== $request->get('end')) {
|
||||||
$end = new Carbon($request->get('end'));
|
$end = new Carbon($request->get('end'));
|
||||||
}
|
}
|
||||||
$paginator = $user->bills()->paginate($pageSize);
|
$paginator = $this->repository->getPaginator($pageSize);
|
||||||
/** @var Collection $bills */
|
/** @var Collection $bills */
|
||||||
$bills = $paginator->getCollection();
|
$bills = $paginator->getCollection();
|
||||||
|
|
||||||
@@ -84,16 +110,34 @@ class BillController extends Controller
|
|||||||
return Response::json($manager->createData($resource)->toArray());
|
return Response::json($manager->createData($resource)->toArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display the specified resource.
|
* @param Request $request
|
||||||
|
* @param Bill $bill
|
||||||
*
|
*
|
||||||
* @param \FireflyIII\Models\Bill $bill
|
* @return \Illuminate\Http\JsonResponse
|
||||||
*
|
|
||||||
* @return \Illuminate\Http\Response
|
|
||||||
*/
|
*/
|
||||||
public function show(Bill $bill)
|
public function show(Request $request, Bill $bill)
|
||||||
{
|
{
|
||||||
//
|
$start = null;
|
||||||
|
$end = null;
|
||||||
|
if (null !== $request->get('start')) {
|
||||||
|
$start = new Carbon($request->get('start'));
|
||||||
|
}
|
||||||
|
if (null !== $request->get('end')) {
|
||||||
|
$end = new Carbon($request->get('end'));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$manager = new Manager();
|
||||||
|
$manager->parseIncludes(['attachments']);
|
||||||
|
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||||
|
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||||
|
|
||||||
|
$resource = new Item($bill, new BillTransformer($start, $end), 'bill');
|
||||||
|
|
||||||
|
return Response::json($manager->createData($resource)->toArray());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* Authenticate.php
|
* Authenticate.php
|
||||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||||
*
|
*
|
||||||
* This file is part of Firefly III.
|
* This file is part of Firefly III.
|
||||||
*
|
*
|
||||||
@@ -18,50 +18,93 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace FireflyIII\Http\Middleware;
|
namespace FireflyIII\Http\Middleware;
|
||||||
|
|
||||||
use Closure;
|
use Closure;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Auth\AuthenticationException;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Contracts\Auth\Factory as Auth;
|
||||||
use Session;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class Authenticate.
|
* Class Authenticate
|
||||||
*/
|
*/
|
||||||
class Authenticate
|
class Authenticate
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* The authentication factory instance.
|
||||||
|
*
|
||||||
|
* @var \Illuminate\Contracts\Auth\Factory
|
||||||
|
*/
|
||||||
|
protected $auth;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new middleware instance.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Contracts\Auth\Factory $auth
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct(Auth $auth)
|
||||||
|
{
|
||||||
|
$this->auth = $auth;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle an incoming request.
|
* Handle an incoming request.
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Http\Request $request
|
* @param \Illuminate\Http\Request $request
|
||||||
* @param \Closure $next
|
* @param \Closure $next
|
||||||
* @param string|null $guard
|
* @param string[] ...$guards
|
||||||
*
|
*
|
||||||
* @return mixed
|
* @return mixed
|
||||||
|
*
|
||||||
|
* @throws \Illuminate\Auth\AuthenticationException
|
||||||
*/
|
*/
|
||||||
public function handle(Request $request, Closure $next, $guard = null)
|
public function handle($request, Closure $next, ...$guards)
|
||||||
{
|
{
|
||||||
if (Auth::guard($guard)->guest()) {
|
$this->authenticate($guards);
|
||||||
if ($request->ajax()) {
|
|
||||||
return response('Unauthorized.', 401);
|
|
||||||
}
|
|
||||||
|
|
||||||
return redirect()->guest('login');
|
|
||||||
}
|
|
||||||
if (1 === intval(Auth::guard($guard)->user()->blocked)) {
|
|
||||||
$message = strval(trans('firefly.block_account_logout'));
|
|
||||||
if ('email_changed' === Auth::guard($guard)->user()->blocked_code) {
|
|
||||||
$message = strval(trans('firefly.email_changed_logout'));
|
|
||||||
}
|
|
||||||
|
|
||||||
Session::flash('logoutMessage', $message);
|
|
||||||
Auth::guard($guard)->logout();
|
|
||||||
|
|
||||||
return redirect()->guest('login');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $next($request);
|
return $next($request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if the user is logged in to any of the given guards.
|
||||||
|
*
|
||||||
|
* @param array $guards
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
* @throws \Illuminate\Auth\AuthenticationException
|
||||||
|
*/
|
||||||
|
protected function authenticate(array $guards)
|
||||||
|
{
|
||||||
|
if (empty($guards)) {
|
||||||
|
// go for default guard:
|
||||||
|
if ($this->auth->check()) {
|
||||||
|
// do an extra check on user object.
|
||||||
|
$user = $this->auth->authenticate();
|
||||||
|
if (1 === intval($user->blocked)) {
|
||||||
|
$message = strval(trans('firefly.block_account_logout'));
|
||||||
|
if ('email_changed' === $user->blocked_code) {
|
||||||
|
$message = strval(trans('firefly.email_changed_logout'));
|
||||||
|
}
|
||||||
|
|
||||||
|
app('session')->flash('logoutMessage', $message);
|
||||||
|
$this->auth->logout();
|
||||||
|
|
||||||
|
return redirect()->guest('login');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->auth->authenticate();
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($guards as $guard) {
|
||||||
|
if ($this->auth->guard($guard)->check()) {
|
||||||
|
return $this->auth->shouldUse($guard);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new AuthenticationException('Unauthenticated.', $guards);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -24,6 +24,7 @@ namespace FireflyIII\Http\Middleware;
|
|||||||
|
|
||||||
use Closure;
|
use Closure;
|
||||||
use FireflyIII\Support\Domain;
|
use FireflyIII\Support\Domain;
|
||||||
|
use Illuminate\Contracts\Auth\Factory as Auth;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -31,6 +32,12 @@ use Illuminate\Http\Request;
|
|||||||
*/
|
*/
|
||||||
class Binder
|
class Binder
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* The authentication factory instance.
|
||||||
|
*
|
||||||
|
* @var \Illuminate\Contracts\Auth\Factory
|
||||||
|
*/
|
||||||
|
protected $auth;
|
||||||
/**
|
/**
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
@@ -38,21 +45,27 @@ class Binder
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Binder constructor.
|
* Binder constructor.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Contracts\Auth\Factory $auth
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct(Auth $auth)
|
||||||
{
|
{
|
||||||
$this->binders = Domain::getBindables();
|
$this->binders = Domain::getBindables();
|
||||||
|
$this->auth = $auth;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle an incoming request.
|
* Handle an incoming request.
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Http\Request $request
|
* @param \Illuminate\Http\Request $request
|
||||||
* @param \Closure $next
|
* @param \Closure $next
|
||||||
|
* @param string[] ...$guards
|
||||||
*
|
*
|
||||||
* @return mixed
|
* @return mixed
|
||||||
|
*
|
||||||
|
* @throws \Illuminate\Auth\AuthenticationException
|
||||||
*/
|
*/
|
||||||
public function handle(Request $request, Closure $next)
|
public function handle($request, Closure $next, ...$guards)
|
||||||
{
|
{
|
||||||
foreach ($request->route()->parameters() as $key => $value) {
|
foreach ($request->route()->parameters() as $key => $value) {
|
||||||
if (isset($this->binders[$key])) {
|
if (isset($this->binders[$key])) {
|
||||||
|
@@ -29,7 +29,7 @@ use Illuminate\Database\Eloquent\Relations\HasMany;
|
|||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||||
use Watson\Validating\ValidatingTrait;
|
use Watson\Validating\ValidatingTrait;
|
||||||
|
use Illuminate\Contracts\Auth\Factory as Auth;
|
||||||
/**
|
/**
|
||||||
* Class Bill.
|
* Class Bill.
|
||||||
*/
|
*/
|
||||||
|
@@ -49,6 +49,13 @@ class AttachmentTransformer extends TransformerAbstract
|
|||||||
'notes' => $attachment->notes,
|
'notes' => $attachment->notes,
|
||||||
'mime' => $attachment->mime,
|
'mime' => $attachment->mime,
|
||||||
'size' => $attachment->size,
|
'size' => $attachment->size,
|
||||||
|
'links' => [
|
||||||
|
[
|
||||||
|
'rel' => 'self',
|
||||||
|
'uri' => '/attachment/' . $attachment->id,
|
||||||
|
],
|
||||||
|
]
|
||||||
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -72,7 +72,8 @@ class BillTransformer extends TransformerAbstract
|
|||||||
{
|
{
|
||||||
$attachments = $bill->attachments()->get();
|
$attachments = $bill->attachments()->get();
|
||||||
|
|
||||||
return $this->collection($attachments, new AttachmentTransformer);
|
return $this->collection($attachments, new AttachmentTransformer,'attachment');
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -84,7 +85,8 @@ class BillTransformer extends TransformerAbstract
|
|||||||
{
|
{
|
||||||
$notes = $bill->notes()->get();
|
$notes = $bill->notes()->get();
|
||||||
|
|
||||||
return $this->collection($notes, new NoteTransformer);
|
return $this->collection($notes, new NoteTransformer,'note');
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -95,7 +97,9 @@ class BillTransformer extends TransformerAbstract
|
|||||||
public function transform(Bill $bill): array
|
public function transform(Bill $bill): array
|
||||||
{
|
{
|
||||||
$paidData = $this->paidData($bill);
|
$paidData = $this->paidData($bill);
|
||||||
$data = [
|
$payDates = $this->payDates($bill);
|
||||||
|
|
||||||
|
$data = [
|
||||||
'id' => (int)$bill->id,
|
'id' => (int)$bill->id,
|
||||||
'name' => $bill->name,
|
'name' => $bill->name,
|
||||||
'match' => explode(',', $bill->match),
|
'match' => explode(',', $bill->match),
|
||||||
@@ -107,13 +111,13 @@ class BillTransformer extends TransformerAbstract
|
|||||||
'automatch' => intval($bill->automatch) === 1,
|
'automatch' => intval($bill->automatch) === 1,
|
||||||
'active' => intval($bill->active) === 1,
|
'active' => intval($bill->active) === 1,
|
||||||
'attachments_count' => $bill->attachments()->count(),
|
'attachments_count' => $bill->attachments()->count(),
|
||||||
'pay_dates' => $this->payDates($bill),
|
'pay_dates' => $payDates,
|
||||||
'paid_dates' => $paidData['paid_dates'],
|
'paid_dates' => $paidData['paid_dates'],
|
||||||
'next_expected_match' => $paidData['next_expected_match'],
|
'next_expected_match' => $paidData['next_expected_match'],
|
||||||
'links' => [
|
'links' => [
|
||||||
[
|
[
|
||||||
'rel' => 'self',
|
'rel' => 'self',
|
||||||
'uri' => '/bills/' . $bill->id,
|
'uri' => '/bill/' . $bill->id,
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
@@ -217,6 +221,9 @@ class BillTransformer extends TransformerAbstract
|
|||||||
*/
|
*/
|
||||||
protected function payDates(Bill $bill): array
|
protected function payDates(Bill $bill): array
|
||||||
{
|
{
|
||||||
|
if (is_null($this->start) || is_null($this->end)) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
$set = new Collection;
|
$set = new Collection;
|
||||||
$currentStart = clone $this->start;
|
$currentStart = clone $this->start;
|
||||||
while ($currentStart <= $this->end) {
|
while ($currentStart <= $this->end) {
|
||||||
|
@@ -48,6 +48,13 @@ class NoteTransformer extends TransformerAbstract
|
|||||||
'title' => $note->title,
|
'title' => $note->title,
|
||||||
'text' => $note->text,
|
'text' => $note->text,
|
||||||
'markdown' => $converter->convertToHtml($note->text),
|
'markdown' => $converter->convertToHtml($note->text),
|
||||||
|
'links' => [
|
||||||
|
[
|
||||||
|
'rel' => 'self',
|
||||||
|
'uri' => '/note/' . $note->id,
|
||||||
|
],
|
||||||
|
]
|
||||||
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -20,7 +20,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
Route::group(
|
Route::group(
|
||||||
['middleware' => 'auth:api', 'namespace' => 'FireflyIII\Api\V1\Controllers', 'prefix' => 'bill', 'as' => 'api.v1.bills.'], function () {
|
['middleware' => ['auth:api','bindings'], 'namespace' => 'FireflyIII\Api\V1\Controllers', 'prefix' => 'bill', 'as' => 'api.v1.bills.'], function () {
|
||||||
|
|
||||||
// Bills API routes:
|
// Bills API routes:
|
||||||
Route::get('', ['uses' => 'BillController@index', 'as' => 'index']);
|
Route::get('', ['uses' => 'BillController@index', 'as' => 'index']);
|
||||||
|
Reference in New Issue
Block a user