From 370e9b25d138f54fb590618dcb63887044c422c6 Mon Sep 17 00:00:00 2001 From: James Cole Date: Tue, 13 Feb 2018 18:24:06 +0100 Subject: [PATCH] Expand API. --- app/Api/V1/Controllers/AccountController.php | 40 ++++- app/Api/V1/Controllers/BillController.php | 9 +- app/Api/V1/Controllers/Controller.php | 31 ++-- app/Api/V1/Controllers/UserController.php | 149 ++++++++++++++++++ app/Api/V1/Requests/AccountRequest.php | 105 ++++++++++++ app/Exceptions/Handler.php | 6 +- .../Account/AccountRepository.php | 30 +++- app/Transformers/AccountTransformer.php | 25 ++- app/Transformers/UserTransformer.php | 7 + app/Validation/FireflyValidator.php | 25 +-- config/firefly.php | 1 + routes/api.php | 23 +++ 12 files changed, 405 insertions(+), 46 deletions(-) create mode 100644 app/Api/V1/Controllers/UserController.php create mode 100644 app/Api/V1/Requests/AccountRequest.php diff --git a/app/Api/V1/Controllers/AccountController.php b/app/Api/V1/Controllers/AccountController.php index 38729c3caa..3ab23248d0 100644 --- a/app/Api/V1/Controllers/AccountController.php +++ b/app/Api/V1/Controllers/AccountController.php @@ -23,9 +23,11 @@ declare(strict_types=1); namespace FireflyIII\Api\V1\Controllers; +use FireflyIII\Api\V1\Requests\AccountRequest; use FireflyIII\Models\Account; use FireflyIII\Models\AccountType; use FireflyIII\Repositories\Account\AccountRepositoryInterface; +use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; use FireflyIII\Transformers\AccountTransformer; use Illuminate\Http\Request; use Illuminate\Pagination\LengthAwarePaginator; @@ -35,7 +37,6 @@ use League\Fractal\Resource\Collection as FractalCollection; use League\Fractal\Resource\Item; use League\Fractal\Serializer\JsonApiSerializer; use Preferences; -use Response; /** * Class AccountController @@ -43,6 +44,8 @@ use Response; class AccountController extends Controller { + /** @var CurrencyRepositoryInterface */ + private $currencyRepository; /** @var AccountRepositoryInterface */ private $repository; @@ -60,6 +63,9 @@ class AccountController extends Controller $this->repository = app(AccountRepositoryInterface::class); $this->repository->setUser(auth()->user()); + $this->currencyRepository = app(CurrencyRepositoryInterface::class); + $this->currencyRepository->setUser(auth()->user()); + return $next($request); } ); @@ -103,7 +109,7 @@ class AccountController extends Controller $resource = new FractalCollection($accounts, new AccountTransformer($this->parameters), 'accounts'); $resource->setPaginator(new IlluminatePaginatorAdapter($paginator)); - return Response::json($manager->createData($resource)->toArray()); + return response()->json($manager->createData($resource)->toArray()); } /** @@ -121,7 +127,7 @@ class AccountController extends Controller $manager->setSerializer(new JsonApiSerializer($baseUrl)); $resource = new Item($account, new AccountTransformer($this->parameters), 'accounts'); - return Response::json($manager->createData($resource)->toArray()); + return response()->json($manager->createData($resource)->toArray()); } /** @@ -131,6 +137,20 @@ class AccountController extends Controller */ public function store(AccountRequest $request) { + $data = $request->getAll(); + // if currency ID is 0, find the currency by the code: + if ($data['currency_id'] === 0) { + $currency = $this->currencyRepository->findByCode($data['currency_code']); + $data['currency_id'] = $currency->id; + } + $account = $this->repository->store($data); + $manager = new Manager(); + $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; + $manager->setSerializer(new JsonApiSerializer($baseUrl)); + + $resource = new Item($account, new AccountTransformer($this->parameters), 'accounts'); + + return response()->json($manager->createData($resource)->toArray()); } @@ -142,8 +162,22 @@ class AccountController extends Controller */ public function update(AccountRequest $request, Account $account) { + $data = $request->getAll(); + // if currency ID is 0, find the currency by the code: + if ($data['currency_id'] === 0) { + $currency = $this->currencyRepository->findByCode($data['currency_code']); + $data['currency_id'] = $currency->id; + } + // set correct type: + $data['type'] = config('firefly.shortNamesByFullName.' . $account->accountType->type); + $this->repository->update($account, $data); + $manager = new Manager(); + $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; + $manager->setSerializer(new JsonApiSerializer($baseUrl)); + $resource = new Item($account, new AccountTransformer($this->parameters), 'accounts'); + return response()->json($manager->createData($resource)->toArray()); } /** diff --git a/app/Api/V1/Controllers/BillController.php b/app/Api/V1/Controllers/BillController.php index 457f5bf525..c383b31c2e 100644 --- a/app/Api/V1/Controllers/BillController.php +++ b/app/Api/V1/Controllers/BillController.php @@ -34,7 +34,6 @@ use League\Fractal\Resource\Collection as FractalCollection; use League\Fractal\Resource\Item; use League\Fractal\Serializer\JsonApiSerializer; use Preferences; -use Response; /** * Class BillController @@ -98,7 +97,7 @@ class BillController extends Controller $resource = new FractalCollection($bills, new BillTransformer($this->parameters), 'bills'); $resource->setPaginator(new IlluminatePaginatorAdapter($paginator)); - return Response::json($manager->createData($resource)->toArray()); + return response()->json($manager->createData($resource)->toArray()); } @@ -117,7 +116,7 @@ class BillController extends Controller $resource = new Item($bill, new BillTransformer($this->parameters), 'bills'); - return Response::json($manager->createData($resource)->toArray()); + return response()->json($manager->createData($resource)->toArray()); } /** @@ -134,7 +133,7 @@ class BillController extends Controller $resource = new Item($bill, new BillTransformer($this->parameters), 'bills'); - return Response::json($manager->createData($resource)->toArray()); + return response()->json($manager->createData($resource)->toArray()); } @@ -155,7 +154,7 @@ class BillController extends Controller $resource = new Item($bill, new BillTransformer($this->parameters), 'bills'); - return Response::json($manager->createData($resource)->toArray()); + return response()->json($manager->createData($resource)->toArray()); } } diff --git a/app/Api/V1/Controllers/Controller.php b/app/Api/V1/Controllers/Controller.php index 4b7a8ce067..240735d3b5 100644 --- a/app/Api/V1/Controllers/Controller.php +++ b/app/Api/V1/Controllers/Controller.php @@ -73,27 +73,20 @@ class Controller extends BaseController } $bag->set('page', $page); - $start = request()->get('start'); - $startDate = null; - if (!is_null($start)) { - try { - $startDate = new Carbon($start); - } catch (InvalidDateException $e) { - // don't care + // some date fields: + $dates = ['start','end','date']; + foreach($dates as $field) { + $date = request()->get($field); + $obj = null; + if (!is_null($date)) { + try { + $obj= new Carbon($date); + } catch (InvalidDateException $e) { + // don't care + } } + $bag->set($field, $obj); } - $bag->set('start', $startDate); - - $end = request()->get('end'); - $endDate = null; - if (!is_null($end)) { - try { - $endDate = new Carbon($end); - } catch (InvalidDateException $e) { - // don't care - } - } - $bag->set('end', $endDate); $type = request()->get('type') ?? 'all'; $bag->set('type', $type); diff --git a/app/Api/V1/Controllers/UserController.php b/app/Api/V1/Controllers/UserController.php new file mode 100644 index 0000000000..f827ec1e6c --- /dev/null +++ b/app/Api/V1/Controllers/UserController.php @@ -0,0 +1,149 @@ +. + */ + +declare(strict_types=1); + +namespace FireflyIII\Api\V1\Controllers; + +use FireflyIII\Repositories\User\UserRepositoryInterface; +use FireflyIII\Transformers\UserTransformer; +use FireflyIII\User; +use Illuminate\Http\Request; +use Illuminate\Pagination\LengthAwarePaginator; +use League\Fractal\Manager; +use League\Fractal\Pagination\IlluminatePaginatorAdapter; +use League\Fractal\Resource\Collection as FractalCollection; +use League\Fractal\Resource\Item; +use League\Fractal\Serializer\JsonApiSerializer; +use Preferences; +use Symfony\Component\HttpFoundation\File\Exception\AccessDeniedException; + +/** + * Class UserController + */ +class UserController extends Controller +{ + + /** @var UserRepositoryInterface */ + private $repository; + + /** + * UserController constructor. + * + * @throws \FireflyIII\Exceptions\FireflyException + */ + public function __construct() + { + parent::__construct(); + $this->middleware( + function ($request, $next) { + /** @var UserRepositoryInterface repository */ + $this->repository = app(UserRepositoryInterface::class); + + return $next($request); + } + ); + } + + /** + * Remove the specified resource from storage. + * + * @param \FireflyIII\User $user + * + * @return \Illuminate\Http\Response + */ + public function delete(User $user) + { + if (auth()->user()->hasRole('owner')) { + $this->repository->destroy($user); + + return response()->json([], 204); + } + throw new AccessDeniedException(''); + } + + /** + * Display a listing of the resource. + * + * @param Request $request + * + * @return \Illuminate\Http\JsonResponse + */ + public function index(Request $request) + { + $pageSize = intval(Preferences::getForUser(auth()->user(), 'listPageSize', 50)->data); + $collection = $this->repository->all(); + $count = $collection->count(); + $users = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize); + + // make paginator: + $paginator = new LengthAwarePaginator($users, $count, $pageSize, $this->parameters->get('page')); + $manager = new Manager(); + $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; + $manager->setSerializer(new JsonApiSerializer($baseUrl)); + + $resource = new FractalCollection($users, new UserTransformer($this->parameters), 'users'); + $resource->setPaginator(new IlluminatePaginatorAdapter($paginator)); + + return response()->json($manager->createData($resource)->toArray()); + } + + /** + * @param Request $request + * @param User $user + * + * @return \Illuminate\Http\JsonResponse + */ + public function show(Request $request, User $user) + { + + $manager = new Manager(); + //$manager->parseIncludes(['attachments', 'journals', 'user']); + $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; + $manager->setSerializer(new JsonApiSerializer($baseUrl)); + $resource = new Item($user, new UserTransformer($this->parameters), 'users'); + + return response()->json($manager->createData($resource)->toArray()); + } + + /** + * @param AccountRequest $request + * + * @return \Illuminate\Http\JsonResponse + */ + public function store(AccountRequest $request) + { + + } + + /** + * @param AccountRequest $request + * @param Account $account + * + * @return \Illuminate\Http\JsonResponse + */ + public function update(AccountRequest $request, Account $account) + { + + + } + +} \ No newline at end of file diff --git a/app/Api/V1/Requests/AccountRequest.php b/app/Api/V1/Requests/AccountRequest.php new file mode 100644 index 0000000000..826f294922 --- /dev/null +++ b/app/Api/V1/Requests/AccountRequest.php @@ -0,0 +1,105 @@ +. + */ + +declare(strict_types=1); + +namespace FireflyIII\Api\V1\Requests; + +/** + * Class AccountRequest + */ +class AccountRequest extends Request +{ + + /** + * @return bool + */ + public function authorize() + { + // Only allow authenticated users + return auth()->check(); + } + + /** + * @return array + */ + public function getAll(): array + { + $data = [ + 'name' => $this->string('name'), + 'active' => $this->boolean('active'), + 'accountType' => $this->string('type'), + 'currency_id' => $this->integer('currency_id'), + 'currency_code' => $this->string('currency_code'), + 'virtualBalance' => $this->string('virtual_balance'), + 'iban' => $this->string('iban'), + 'BIC' => $this->string('bic'), + 'accountNumber' => $this->string('account_number'), + 'accountRole' => $this->string('account_role'), + 'openingBalance' => $this->string('opening_balance'), + 'openingBalanceDate' => $this->date('opening_balance_date'), + 'ccType' => $this->string('cc_type'), + 'ccMonthlyPaymentDate' => $this->string('cc_monthly_payment_date'), + 'notes' => $this->string('notes'), + ]; + + return $data; + } + + /** + * @return array + */ + public function rules() + { + $accountRoles = join(',', config('firefly.accountRoles')); + $types = join(',', array_keys(config('firefly.subTitlesByIdentifier'))); + $ccPaymentTypes = join(',', array_keys(config('firefly.ccTypes'))); + $rules = [ + 'name' => 'required|min:1|uniqueAccountForUser', + 'opening_balance' => 'numeric|required_with:opening_balance_date|nullable', + 'opening_balance_date' => 'date|required_with:opening_balance|nullable', + 'iban' => 'iban|nullable', + 'bic' => 'bic|nullable', + 'virtual_balance' => 'numeric|nullable', + 'currency_id' => 'numeric|exists:transaction_currencies,id|required_without:currency_code', + 'currency_code' => 'min:3|max:3|exists:transaction_currencies,code|required_without:currency_id', + 'account_number' => 'between:1,255|nullable|uniqueAccountNumberForUser', + 'account_role' => 'in:' . $accountRoles . '|required_if:type,asset', + 'active' => 'required|boolean', + 'cc_type' => 'in:' . $ccPaymentTypes . '|required_if:account_role,ccAsset', + 'cc_monthly_payment_date' => 'date' . '|required_if:account_role,ccAsset|required_if:cc_type,monthlyFull', + 'type' => 'required|in:' . $types, + 'notes' => 'min:0|max:65536', + ]; + switch ($this->method()) { + default: + break; + case 'PUT': + case 'PATCH': + $account = $this->route()->parameter('account'); + $rules['name'] .= ':' . $account->id; + $rules['account_number'] .= ':' . $account->id; + break; + } + + return $rules; + } +} \ No newline at end of file diff --git a/app/Exceptions/Handler.php b/app/Exceptions/Handler.php index 2b3d10aed6..79bd4dceab 100644 --- a/app/Exceptions/Handler.php +++ b/app/Exceptions/Handler.php @@ -28,7 +28,7 @@ use FireflyIII\Jobs\MailError; use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; use Request; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; - +use Illuminate\Validation\ValidationException; /** * Class Handler */ @@ -63,6 +63,10 @@ class Handler extends ExceptionHandler */ public function render($request, Exception $exception) { + if ($exception instanceof ValidationException && $request->expectsJson()) { + // ignore it: controller will handle it. + return parent::render($request, $exception); + } if ($exception instanceof NotFoundHttpException && $request->expectsJson()) { return response()->json(['message' => 'Resource not found', 'exception' => 'NotFoundHttpException'], 404); } diff --git a/app/Repositories/Account/AccountRepository.php b/app/Repositories/Account/AccountRepository.php index 36ca48e872..8e75a1f62a 100644 --- a/app/Repositories/Account/AccountRepository.php +++ b/app/Repositories/Account/AccountRepository.php @@ -49,7 +49,11 @@ class AccountRepository implements AccountRepositoryInterface use FindAccountsTrait; /** @var array */ - private $validFields = ['accountRole', 'ccMonthlyPaymentDate', 'ccType', 'accountNumber', 'currency_id', 'BIC']; + private $validAssetFields = ['accountRole', 'accountNumber', 'currency_id', 'BIC']; + /** @var array */ + private $validCCFields = ['accountRole', 'ccMonthlyPaymentDate', 'ccType', 'accountNumber', 'currency_id', 'BIC']; + /** @var array */ + private $validFields = ['accountNumber', 'currency_id', 'BIC']; /** * Moved here from account CRUD. @@ -195,6 +199,11 @@ class AccountRepository implements AccountRepositoryInterface if ($this->validOpeningBalanceData($data)) { $this->updateInitialBalance($newAccount, $data); + // update note: + if (isset($data['notes'])) { + $this->updateNote($newAccount, $data['notes']); + } + return $newAccount; } $this->deleteInitialBalance($newAccount); @@ -335,7 +344,7 @@ class AccountRepository implements AccountRepositoryInterface // create it: $databaseData - = [ + = [ 'user_id' => $this->user->id, 'account_type_id' => $accountType->id, 'name' => $data['name'], @@ -343,6 +352,12 @@ class AccountRepository implements AccountRepositoryInterface 'active' => true === $data['active'] ? true : false, 'iban' => $data['iban'], ]; + + // remove virtual balance when not an asset account: + if ($accountType->type !== AccountType::ASSET) { + $databaseData['virtual_balance'] = '0'; + } + $newAccount = new Account($databaseData); Log::debug('Final account creation dataset', $databaseData); $newAccount->save(); @@ -500,7 +515,16 @@ class AccountRepository implements AccountRepositoryInterface */ protected function updateMetadata(Account $account, array $data) { - foreach ($this->validFields as $field) { + $fields = $this->validFields; + + if ($account->accountType->type === AccountType::ASSET) { + $fields = $this->validAssetFields; + } + if ($account->accountType->type === AccountType::ASSET && $data['accountRole'] === 'ccAsset') { + $fields = $this->validCCFields; + } + + foreach ($fields as $field) { /** @var AccountMeta $entry */ $entry = $account->accountMeta()->where('name', $field)->first(); diff --git a/app/Transformers/AccountTransformer.php b/app/Transformers/AccountTransformer.php index 94f68ac3af..780f92b5c7 100644 --- a/app/Transformers/AccountTransformer.php +++ b/app/Transformers/AccountTransformer.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace FireflyIII\Transformers; +use Carbon\Carbon; use FireflyIII\Models\Account; use FireflyIII\Models\Note; use FireflyIII\Models\TransactionCurrency; @@ -49,7 +50,7 @@ class AccountTransformer extends TransformerAbstract * * @var array */ - protected $defaultIncludes = ['journals', 'piggy_banks', 'user']; + protected $defaultIncludes = []; /** @var ParameterBag */ protected $parameters; @@ -80,6 +81,7 @@ class AccountTransformer extends TransformerAbstract } $journals = $query->get(['transaction_journals.*']); + return $this->collection($journals, new TransactionJournalTransformer($this->parameters), 'journals'); } @@ -116,18 +118,24 @@ class AccountTransformer extends TransformerAbstract if (strlen($role) === 0) { $role = null; } - $currencyId = (int)$account->getMeta('currency_id'); - $currencyCode = null; + $currencyId = (int)$account->getMeta('currency_id'); + $currencyCode = null; + $decimalPlaces = 2; if ($currencyId > 0) { - $currency = TransactionCurrency::find($currencyId); - $currencyCode = $currency->code; + $currency = TransactionCurrency::find($currencyId); + $currencyCode = $currency->code; + $decimalPlaces = $currency->decimal_places; + } + + $date = new Carbon; + if (!is_null($this->parameters->get('date'))) { + $date = $this->parameters->get('date'); } if ($currencyId === 0) { $currencyId = null; } - $data = [ 'id' => (int)$account->id, 'updated_at' => $account->updated_at->toAtomString(), @@ -137,12 +145,15 @@ class AccountTransformer extends TransformerAbstract 'type' => $account->accountType->type, 'currency_id' => $currencyId, 'currency_code' => $currencyCode, + 'current_balance' => round(app('steam')->balance($account, $date), $decimalPlaces), + 'current_balance_date' => $date->format('Y-m-d'), 'notes' => null, 'monthly_payment_date' => $this->getMeta($account, 'ccMonthlyPaymentDate'), 'credit_card_type' => $this->getMeta($account, 'ccType'), 'account_number' => $this->getMeta($account, 'accountNumber'), 'iban' => $account->iban, 'bic' => $this->getMeta($account, 'BIC'), + 'virtual_balance' => round($account->virtual_balance, $decimalPlaces), 'role' => $role, 'links' => [ [ @@ -151,6 +162,8 @@ class AccountTransformer extends TransformerAbstract ], ], ]; + + // todo opening balance /** @var Note $note */ $note = $account->notes()->first(); if (!is_null($note)) { diff --git a/app/Transformers/UserTransformer.php b/app/Transformers/UserTransformer.php index f65c3c7aea..ff48d36386 100644 --- a/app/Transformers/UserTransformer.php +++ b/app/Transformers/UserTransformer.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace FireflyIII\Transformers; +use FireflyIII\Models\Role; use FireflyIII\User; use League\Fractal\TransformerAbstract; use Symfony\Component\HttpFoundation\ParameterBag; @@ -53,6 +54,11 @@ class UserTransformer extends TransformerAbstract */ public function transform(User $user): array { + /** @var Role $role */ + $role = $user->roles()->first(); + if (!is_null($role)) { + $role = $role->name; + } return [ 'id' => (int)$user->id, @@ -61,6 +67,7 @@ class UserTransformer extends TransformerAbstract 'email' => $user->email, 'blocked' => intval($user->blocked) === 1, 'blocked_code' => $user->blocked_code, + 'role' => $role, 'links' => [ [ 'rel' => 'self', diff --git a/app/Validation/FireflyValidator.php b/app/Validation/FireflyValidator.php index d65f085370..1340b7c9a7 100644 --- a/app/Validation/FireflyValidator.php +++ b/app/Validation/FireflyValidator.php @@ -368,7 +368,10 @@ class FireflyValidator extends Validator } if (isset($this->data['what'])) { - return $this->validateByAccountTypeString($value, $parameters); + return $this->validateByAccountTypeString($value, $parameters, $this->data['what']); + } + if (isset($this->data['type'])) { + return $this->validateByAccountTypeString($value, $parameters, $this->data['type']); } if (isset($this->data['account_type_id'])) { @@ -390,9 +393,12 @@ class FireflyValidator extends Validator * * @return bool */ - public function validateUniqueAccountNumberForUser($attribute, $value): bool + public function validateUniqueAccountNumberForUser($attribute, $value, $parameters): bool { $accountId = $this->data['id'] ?? 0; + if($accountId === 0) { + $accountId = $parameters[0] ?? 0; + } $query = AccountMeta::leftJoin('accounts', 'accounts.id', '=', 'account_meta.account_id') ->whereNull('accounts.deleted_at') @@ -601,18 +607,19 @@ class FireflyValidator extends Validator } /** - * @param $value - * @param $parameters + * @param string $value + * @param array $parameters + * @param string $type * * @return bool */ - private function validateByAccountTypeString($value, $parameters): bool + private function validateByAccountTypeString(string $value, array $parameters, string $type): bool { - $search = Config::get('firefly.accountTypeByIdentifier.' . $this->data['what']); - $type = AccountType::whereType($search)->first(); - $ignore = $parameters[0] ?? 0; + $search = Config::get('firefly.accountTypeByIdentifier.' . $type); + $accountType = AccountType::whereType($search)->first(); + $ignore = $parameters[0] ?? 0; - $set = auth()->user()->accounts()->where('account_type_id', $type->id)->where('id', '!=', $ignore)->get(); + $set = auth()->user()->accounts()->where('account_type_id', $accountType->id)->where('id', '!=', $ignore)->get(); /** @var Account $entry */ foreach ($set as $entry) { if ($entry->name === $value) { diff --git a/config/firefly.php b/config/firefly.php index e959322d22..b186dbdc46 100644 --- a/config/firefly.php +++ b/config/firefly.php @@ -34,6 +34,7 @@ return [ ], 'encryption' => (is_null(env('USE_ENCRYPTION')) || env('USE_ENCRYPTION') === true), 'version' => '4.7.0', + 'api_version' => '0.1', 'maxUploadSize' => 15242880, 'allowedMimes' => [ /* plain files */ diff --git a/routes/api.php b/routes/api.php index f905786357..57b0626cc4 100644 --- a/routes/api.php +++ b/routes/api.php @@ -19,6 +19,17 @@ * along with Firefly III. If not, see . */ +Route::group( + ['middleware' => ['auth:api', 'bindings'], 'namespace' => 'FireflyIII\Api\V1\Controllers', 'prefix' => 'about', 'as' => 'api.v1.about.'], + function () { + + // Accounts API routes: + Route::get('', ['uses' => 'AboutController@about', 'as' => 'index']); + Route::get('user', ['uses' => 'AboutController@user', 'as' => 'user']); + } +); + + Route::group( ['middleware' => ['auth:api', 'bindings'], 'namespace' => 'FireflyIII\Api\V1\Controllers', 'prefix' => 'accounts', 'as' => 'api.v1.accounts.'], function () { @@ -45,3 +56,15 @@ Route::group( } ); +Route::group( + ['middleware' => ['auth:api', 'bindings', \FireflyIII\Http\Middleware\IsAdmin::class], 'namespace' => 'FireflyIII\Api\V1\Controllers', 'prefix' => 'users', 'as' => 'api.v1.users.'], + function () { + + // Users API routes: + Route::get('', ['uses' => 'UserController@index', 'as' => 'index']); + Route::post('', ['uses' => 'UserController@store', 'as' => 'store']); + Route::get('{user}', ['uses' => 'UserController@show', 'as' => 'show']); + Route::put('{user}', ['uses' => 'UserController@update', 'as' => 'update']); + Route::delete('{user}', ['uses' => 'UserController@delete', 'as' => 'delete']); + } +); \ No newline at end of file