From bf390b65d9b58ef48273c284948428243680d044 Mon Sep 17 00:00:00 2001 From: James Cole Date: Mon, 25 Dec 2017 08:45:23 +0100 Subject: [PATCH] Replace Laravel binder with own binder. This will save in queries and increase security. --- app/Http/Kernel.php | 18 +- app/Models/Account.php | 29 +- app/Models/AccountMeta.php | 3 + app/Models/AccountType.php | 4 + app/Models/Attachment.php | 31 +- app/Models/AvailableBudget.php | 2 + app/Models/Bill.php | 24 +- app/Models/Budget.php | 14 +- app/Models/BudgetLimit.php | 19 +- app/Models/Category.php | 13 +- app/Models/Configuration.php | 2 + app/Models/CurrencyExchangeRate.php | 3 + app/Models/ExportJob.php | 15 +- app/Models/ImportJob.php | 18 +- app/Models/LinkType.php | 12 +- app/Models/Note.php | 2 + app/Models/PiggyBank.php | 21 +- app/Models/PiggyBankEvent.php | 5 +- app/Models/PiggyBankRepetition.php | 6 +- app/Models/Preference.php | 2 + app/Models/Role.php | 1 + app/Models/Rule.php | 14 +- app/Models/RuleAction.php | 1 + app/Models/RuleGroup.php | 12 +- app/Models/RuleTrigger.php | 1 + app/Models/Tag.php | 16 +- app/Models/Transaction.php | 14 +- app/Models/TransactionCurrency.php | 11 +- app/Models/TransactionJournal.php | 49 +- app/Models/TransactionJournalLink.php | 26 +- app/Models/TransactionJournalMeta.php | 3 + app/Models/TransactionType.php | 13 +- config/firefly.php | 59 +- routes/web.php | 4 +- tests/Unit/Middleware/AuthenticateTest.php | 112 ++ .../Middleware/AuthenticateTwoFactorTest.php | 218 ++++ tests/Unit/Middleware/BinderTest.php | 1016 +++++++++++++++++ 37 files changed, 1671 insertions(+), 142 deletions(-) create mode 100644 tests/Unit/Middleware/AuthenticateTest.php create mode 100644 tests/Unit/Middleware/AuthenticateTwoFactorTest.php create mode 100644 tests/Unit/Middleware/BinderTest.php diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index 707ceb5d7a..31273f8b2c 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -42,7 +42,6 @@ use Illuminate\Foundation\Http\Kernel as HttpKernel; use Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode; use Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull; use Illuminate\Foundation\Http\Middleware\ValidatePostSize; -use Illuminate\Routing\Middleware\SubstituteBindings; use Illuminate\Routing\Middleware\ThrottleRequests; use Illuminate\View\Middleware\ShareErrorsFromSession; @@ -85,7 +84,7 @@ class Kernel extends HttpKernel StartFireflySession::class, ShareErrorsFromSession::class, VerifyCsrfToken::class, - SubstituteBindings::class, + //SubstituteBindings::class, ], // MUST NOT be logged in. Does not care about 2FA or confirmation. @@ -96,7 +95,8 @@ class Kernel extends HttpKernel StartFireflySession::class, ShareErrorsFromSession::class, VerifyCsrfToken::class, - SubstituteBindings::class, + //SubstituteBindings::class, + Binder::class, RedirectIfAuthenticated::class, ], // MUST be logged in. @@ -109,7 +109,8 @@ class Kernel extends HttpKernel StartFireflySession::class, ShareErrorsFromSession::class, VerifyCsrfToken::class, - SubstituteBindings::class, + //SubstituteBindings::class, + Binder::class, Authenticate::class, RedirectIfTwoFactorAuthenticated::class, ], @@ -124,7 +125,8 @@ class Kernel extends HttpKernel StartFireflySession::class, ShareErrorsFromSession::class, VerifyCsrfToken::class, - SubstituteBindings::class, + //SubstituteBindings::class, + Binder::class, Authenticate::class, ], @@ -139,7 +141,7 @@ class Kernel extends HttpKernel StartFireflySession::class, ShareErrorsFromSession::class, VerifyCsrfToken::class, - SubstituteBindings::class, + //SubstituteBindings::class, Authenticate::class, AuthenticateTwoFactor::class, Range::class, @@ -157,7 +159,7 @@ class Kernel extends HttpKernel StartFireflySession::class, ShareErrorsFromSession::class, VerifyCsrfToken::class, - SubstituteBindings::class, + //SubstituteBindings::class, Authenticate::class, AuthenticateTwoFactor::class, IsAdmin::class, @@ -182,7 +184,7 @@ class Kernel extends HttpKernel = [ 'auth' => Authenticate::class, 'auth.basic' => AuthenticateWithBasicAuth::class, - 'bindings' => SubstituteBindings::class, + 'bindings' => Binder::class, 'can' => Authorize::class, 'guest' => RedirectIfAuthenticated::class, 'throttle' => ThrottleRequests::class, diff --git a/app/Models/Account.php b/app/Models/Account.php index 058303dd5c..c4e523a886 100644 --- a/app/Models/Account.php +++ b/app/Models/Account.php @@ -114,15 +114,17 @@ class Account extends Model } /** - * @param Account $value + * @param string $value * * @return Account */ - public static function routeBinder(self $value) + public static function routeBinder(string $value): Account { if (auth()->check()) { - if (intval($value->user_id) === auth()->user()->id) { - return $value; + $accountId = intval($value); + $account = auth()->user()->accounts()->find($accountId); + if (!is_null($account)) { + return $account; } } throw new NotFoundHttpException; @@ -130,6 +132,7 @@ class Account extends Model /** * @return HasMany + * @codeCoverageIgnore */ public function accountMeta(): HasMany { @@ -138,6 +141,7 @@ class Account extends Model /** * @return BelongsTo + * @codeCoverageIgnore */ public function accountType(): BelongsTo { @@ -146,6 +150,7 @@ class Account extends Model /** * @return string + * @codeCoverageIgnore */ public function getEditNameAttribute(): string { @@ -159,8 +164,6 @@ class Account extends Model } /** - * FIxxME can return null. - * * @param $value * * @return string @@ -185,6 +188,7 @@ class Account extends Model } /** + * @codeCoverageIgnore * @param string $fieldName * * @return string @@ -201,6 +205,7 @@ class Account extends Model } /** + * @codeCoverageIgnore * @param $value * * @return string @@ -285,6 +290,7 @@ class Account extends Model /** * @return HasMany + * @codeCoverageIgnore */ public function piggyBanks(): HasMany { @@ -292,6 +298,7 @@ class Account extends Model } /** + * @codeCoverageIgnore * @param EloquentBuilder $query * @param array $types */ @@ -305,6 +312,7 @@ class Account extends Model } /** + * @codeCoverageIgnore * @param EloquentBuilder $query * @param string $name * @param string $value @@ -322,7 +330,9 @@ class Account extends Model } /** + * @codeCoverageIgnore * @param $value + * @codeCoverageIgnore */ public function setIbanAttribute($value) { @@ -330,6 +340,7 @@ class Account extends Model } /** + * @codeCoverageIgnore * @param $value */ public function setNameAttribute($value) @@ -340,15 +351,18 @@ class Account extends Model } /** + * @codeCoverageIgnore * @param $value + * @codeCoverageIgnore */ public function setVirtualBalanceAttribute($value) { - $this->attributes['virtual_balance'] = strval(round($value, 12)); + $this->attributes['virtual_balance'] = strval($value); } /** * @return HasMany + * @codeCoverageIgnore */ public function transactions(): HasMany { @@ -357,6 +371,7 @@ class Account extends Model /** * @return BelongsTo + * @codeCoverageIgnore */ public function user(): BelongsTo { diff --git a/app/Models/AccountMeta.php b/app/Models/AccountMeta.php index 4586851005..f70953f3be 100644 --- a/app/Models/AccountMeta.php +++ b/app/Models/AccountMeta.php @@ -49,6 +49,7 @@ class AccountMeta extends Model /** * @return BelongsTo + * @codeCoverageIgnore */ public function account(): BelongsTo { @@ -58,6 +59,7 @@ class AccountMeta extends Model /** * @param $value * + * @codeCoverageIgnore * @return mixed */ public function getDataAttribute($value) @@ -67,6 +69,7 @@ class AccountMeta extends Model /** * @param $value + * @codeCoverageIgnore */ public function setDataAttribute($value) { diff --git a/app/Models/AccountType.php b/app/Models/AccountType.php index 2ff849a5de..9b34d0382e 100644 --- a/app/Models/AccountType.php +++ b/app/Models/AccountType.php @@ -30,6 +30,9 @@ use Illuminate\Database\Eloquent\Relations\HasMany; */ class AccountType extends Model { + /** + * + */ const DEFAULT = 'Default account'; /** * @@ -82,6 +85,7 @@ class AccountType extends Model /** * @return HasMany + * @codeCoverageIgnore */ public function accounts(): HasMany { diff --git a/app/Models/Attachment.php b/app/Models/Attachment.php index 0d9221b90c..957996968e 100644 --- a/app/Models/Attachment.php +++ b/app/Models/Attachment.php @@ -52,22 +52,25 @@ class Attachment extends Model protected $fillable = ['attachable_id', 'attachable_type', 'user_id', 'md5', 'filename', 'mime', 'title', 'notes', 'description', 'size', 'uploaded']; /** - * @param Attachment $value + * @param string $value * * @return Attachment */ - public static function routeBinder(Attachment $value) + public static function routeBinder(string $value): Attachment { if (auth()->check()) { - if (intval($value->user_id) === auth()->user()->id) { - return $value; + $attachmentId = intval($value); + $attachment = auth()->user()->attachments()->find($attachmentId); + if (!is_null($attachment)) { + return $attachment; } } throw new NotFoundHttpException; } /** - * Get all of the owning imageable models. + * Get all of the owning attachable models. + * @codeCoverageIgnore * * @return MorphTo */ @@ -78,7 +81,7 @@ class Attachment extends Model /** * Returns the expected filename for this attachment. - * + *@codeCoverageIgnore * @return string */ public function fileName(): string @@ -88,7 +91,7 @@ class Attachment extends Model /** * @param $value - * + *@codeCoverageIgnore * @return null|string */ public function getDescriptionAttribute($value) @@ -102,7 +105,7 @@ class Attachment extends Model /** * @param $value - * + *@codeCoverageIgnore * @return null|string */ public function getFilenameAttribute($value) @@ -116,7 +119,7 @@ class Attachment extends Model /** * @param $value - * + *@codeCoverageIgnore * @return null|string */ public function getMimeAttribute($value) @@ -130,7 +133,7 @@ class Attachment extends Model /** * @param $value - * + *@codeCoverageIgnore * @return null|string */ public function getNotesAttribute($value) @@ -144,7 +147,7 @@ class Attachment extends Model /** * @param $value - * + *@codeCoverageIgnore * @return null|string */ public function getTitleAttribute($value) @@ -157,6 +160,7 @@ class Attachment extends Model } /** + * @codeCoverageIgnore * @param string $value */ public function setDescriptionAttribute(string $value) @@ -165,6 +169,7 @@ class Attachment extends Model } /** + * @codeCoverageIgnore * @param string $value */ public function setFilenameAttribute(string $value) @@ -173,6 +178,7 @@ class Attachment extends Model } /** + * @codeCoverageIgnore * @param string $value */ public function setMimeAttribute(string $value) @@ -181,6 +187,7 @@ class Attachment extends Model } /** + * @codeCoverageIgnore * @param string $value */ public function setNotesAttribute(string $value) @@ -189,6 +196,7 @@ class Attachment extends Model } /** + * @codeCoverageIgnore * @param string $value */ public function setTitleAttribute(string $value) @@ -197,6 +205,7 @@ class Attachment extends Model } /** + * @codeCoverageIgnore * @return BelongsTo */ public function user(): BelongsTo diff --git a/app/Models/AvailableBudget.php b/app/Models/AvailableBudget.php index e559153c99..b936a1a580 100644 --- a/app/Models/AvailableBudget.php +++ b/app/Models/AvailableBudget.php @@ -49,6 +49,7 @@ class AvailableBudget extends Model protected $fillable = ['user_id', 'transaction_currency_id', 'amount', 'start_date', 'end_date']; /** + * @codeCoverageIgnore * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function transactionCurrency() @@ -57,6 +58,7 @@ class AvailableBudget extends Model } /** + * @codeCoverageIgnore * @return BelongsTo */ public function user(): BelongsTo diff --git a/app/Models/Bill.php b/app/Models/Bill.php index 43802baafe..68121c947c 100644 --- a/app/Models/Bill.php +++ b/app/Models/Bill.php @@ -69,21 +69,24 @@ class Bill extends Model protected $rules = ['name' => 'required|between:1,200']; /** - * @param Bill $value + * @param string $value * * @return Bill */ - public static function routeBinder(Bill $value) + public static function routeBinder(string $value): Bill { if (auth()->check()) { - if (intval($value->user_id) === auth()->user()->id) { - return $value; + $billId = intval($value); + $bill = auth()->user()->bills()->find($billId); + if (!is_null($bill)) { + return $bill; } } throw new NotFoundHttpException; } /** + * @codeCoverageIgnore * @return \Illuminate\Database\Eloquent\Relations\MorphMany */ public function attachments() @@ -92,6 +95,7 @@ class Bill extends Model } /** + * @codeCoverageIgnore * @param $value * * @return string @@ -106,6 +110,7 @@ class Bill extends Model } /** + * @codeCoverageIgnore * @param $value * * @return string @@ -120,6 +125,7 @@ class Bill extends Model } /** + * @codeCoverageIgnore * Get all of the notes. */ public function notes() @@ -128,23 +134,26 @@ class Bill extends Model } /** + * @codeCoverageIgnore * @param $value */ public function setAmountMaxAttribute($value) { - $this->attributes['amount_max'] = strval(round($value, 12)); + $this->attributes['amount_max'] = strval($value); } /** * @param $value + * @codeCoverageIgnore */ public function setAmountMinAttribute($value) { - $this->attributes['amount_min'] = strval(round($value, 12)); + $this->attributes['amount_min'] = strval($value); } /** * @param $value + * @codeCoverageIgnore */ public function setMatchAttribute($value) { @@ -155,6 +164,7 @@ class Bill extends Model /** * @param $value + * @codeCoverageIgnore */ public function setNameAttribute($value) { @@ -164,6 +174,7 @@ class Bill extends Model } /** + * @codeCoverageIgnore * @return HasMany */ public function transactionJournals(): HasMany @@ -172,6 +183,7 @@ class Bill extends Model } /** + * @codeCoverageIgnore * @return BelongsTo */ public function user(): BelongsTo diff --git a/app/Models/Budget.php b/app/Models/Budget.php index dda01f752f..a47b9e9176 100644 --- a/app/Models/Budget.php +++ b/app/Models/Budget.php @@ -88,17 +88,20 @@ class Budget extends Model * * @return Budget */ - public static function routeBinder(Budget $value) + public static function routeBinder(string $value): Budget { if (auth()->check()) { - if (intval($value->user_id) === auth()->user()->id) { - return $value; + $budgetId = intval($value); + $budget = auth()->user()->budgets()->find($budgetId); + if (!is_null($budget)) { + return $budget; } } throw new NotFoundHttpException; } /** + * @codeCoverageIgnore * @return \Illuminate\Database\Eloquent\Relations\HasMany */ public function budgetlimits() @@ -107,6 +110,7 @@ class Budget extends Model } /** + * @codeCoverageIgnore * @param $value * * @return string @@ -121,6 +125,7 @@ class Budget extends Model } /** + * @codeCoverageIgnore * @param $value */ public function setNameAttribute($value) @@ -131,6 +136,7 @@ class Budget extends Model } /** + * @codeCoverageIgnore * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany */ public function transactionJournals() @@ -139,6 +145,7 @@ class Budget extends Model } /** + * @codeCoverageIgnore * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany */ public function transactions() @@ -147,6 +154,7 @@ class Budget extends Model } /** + * @codeCoverageIgnore * @return BelongsTo */ public function user(): BelongsTo diff --git a/app/Models/BudgetLimit.php b/app/Models/BudgetLimit.php index 73354333c9..6d5ebad901 100644 --- a/app/Models/BudgetLimit.php +++ b/app/Models/BudgetLimit.php @@ -47,25 +47,27 @@ class BudgetLimit extends Model protected $dates = ['start_date', 'end_date']; /** - * @param $value + * @param string $value * * @return mixed */ - public static function routeBinder($value) + public static function routeBinder(string $value): BudgetLimit { if (auth()->check()) { - $object = self::where('budget_limits.id', $value) - ->leftJoin('budgets', 'budgets.id', '=', 'budget_limits.budget_id') - ->where('budgets.user_id', auth()->user()->id) - ->first(['budget_limits.*']); - if ($object) { - return $object; + $budgetLimitId = intval($value); + $budgetLimit = self::where('budget_limits.id', $budgetLimitId) + ->leftJoin('budgets', 'budgets.id', '=', 'budget_limits.budget_id') + ->where('budgets.user_id', auth()->user()->id) + ->first(['budget_limits.*']); + if (!is_null($budgetLimit)) { + return $budgetLimit; } } throw new NotFoundHttpException; } /** + * @codeCoverageIgnore * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function budget() @@ -74,6 +76,7 @@ class BudgetLimit extends Model } /** + * @codeCoverageIgnore * @param $value */ public function setAmountAttribute($value) diff --git a/app/Models/Category.php b/app/Models/Category.php index cf2b82ab97..c5b3b741ae 100644 --- a/app/Models/Category.php +++ b/app/Models/Category.php @@ -87,17 +87,20 @@ class Category extends Model * * @return Category */ - public static function routeBinder(Category $value) + public static function routeBinder(string $value): Category { if (auth()->check()) { - if (intval($value->user_id) === auth()->user()->id) { - return $value; + $categoryId = intval($value); + $category = auth()->user()->categories()->find($categoryId); + if (!is_null($category)) { + return $category; } } throw new NotFoundHttpException; } /** + * @codeCoverageIgnore * @param $value * * @return string @@ -112,6 +115,7 @@ class Category extends Model } /** + * @codeCoverageIgnore * @param $value */ public function setNameAttribute($value) @@ -122,6 +126,7 @@ class Category extends Model } /** + * @codeCoverageIgnore * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany */ public function transactionJournals() @@ -130,6 +135,7 @@ class Category extends Model } /** + * @codeCoverageIgnore * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany */ public function transactions() @@ -138,6 +144,7 @@ class Category extends Model } /** + * @codeCoverageIgnore * @return BelongsTo */ public function user(): BelongsTo diff --git a/app/Models/Configuration.php b/app/Models/Configuration.php index 64521a63d9..bf36775c52 100644 --- a/app/Models/Configuration.php +++ b/app/Models/Configuration.php @@ -48,6 +48,7 @@ class Configuration extends Model protected $table = 'configuration'; /** + * @codeCoverageIgnore * @param $value * * @return mixed @@ -58,6 +59,7 @@ class Configuration extends Model } /** + * @codeCoverageIgnore * @param $value */ public function setDataAttribute($value) diff --git a/app/Models/CurrencyExchangeRate.php b/app/Models/CurrencyExchangeRate.php index 32b1bc972e..7701cb9fff 100644 --- a/app/Models/CurrencyExchangeRate.php +++ b/app/Models/CurrencyExchangeRate.php @@ -35,6 +35,7 @@ class CurrencyExchangeRate extends Model protected $dates = ['date']; /** + * @codeCoverageIgnore * @return BelongsTo */ public function fromCurrency(): BelongsTo @@ -43,6 +44,7 @@ class CurrencyExchangeRate extends Model } /** + * @codeCoverageIgnore * @return BelongsTo */ public function toCurrency(): BelongsTo @@ -51,6 +53,7 @@ class CurrencyExchangeRate extends Model } /** + * @codeCoverageIgnore * @return BelongsTo */ public function user(): BelongsTo diff --git a/app/Models/ExportJob.php b/app/Models/ExportJob.php index 89a9c17028..65bcd1820b 100644 --- a/app/Models/ExportJob.php +++ b/app/Models/ExportJob.php @@ -41,24 +41,26 @@ class ExportJob extends Model ]; /** - * @param $value + * @param string $value * - * @return mixed + * @return ExportJob * * @throws NotFoundHttpException */ - public static function routeBinder($value) + public static function routeBinder(string $value): ExportJob { if (auth()->check()) { - $model = self::where('key', $value)->where('user_id', auth()->user()->id)->first(); - if (null !== $model) { - return $model; + $key = trim($value); + $exportJob = auth()->user()->exportJobs()->where('key', $key)->first(); + if (null !== $exportJob) { + return $exportJob; } } throw new NotFoundHttpException; } /** + * @codeCoverageIgnore * @param $status */ public function change($status) @@ -68,6 +70,7 @@ class ExportJob extends Model } /** + * @codeCoverageIgnore * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function user() diff --git a/app/Models/ImportJob.php b/app/Models/ImportJob.php index 40296bb818..b9256ea25a 100644 --- a/app/Models/ImportJob.php +++ b/app/Models/ImportJob.php @@ -65,17 +65,18 @@ class ImportJob extends Model * @throws NotFoundHttpException * @throws FireflyException */ - public static function routeBinder($value) + public static function routeBinder($value): ImportJob { if (auth()->check()) { - /** @var ImportJob $model */ - $model = self::where('key', $value)->where('user_id', auth()->user()->id)->first(); - if (null !== $model) { + $key = trim($value); + $importJob = auth()->user()->importJobs()->where('key', $key)->first(); + if (null !== $importJob) { // must have valid status: - if (!in_array($model->status, $model->validStatus)) { - throw new FireflyException(sprintf('Job with key "%s" has invalid status "%s"', $model->key, $model->status)); + if (!in_array($importJob->status, $importJob->validStatus)) { + throw new FireflyException(sprintf('ImportJob with key "%s" has invalid status "%s"', $importJob->key, $importJob->status)); } - return $model; + + return $importJob; } } throw new NotFoundHttpException; @@ -167,6 +168,7 @@ class ImportJob extends Model } /** + * @codeCoverageIgnore * @param $value */ public function setConfigurationAttribute($value) @@ -175,6 +177,7 @@ class ImportJob extends Model } /** + * @codeCoverageIgnore * @param $value */ public function setExtendedStatusAttribute($value) @@ -209,6 +212,7 @@ class ImportJob extends Model } /** + * @codeCoverageIgnore * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function user() diff --git a/app/Models/LinkType.php b/app/Models/LinkType.php index b32948e75b..143e30f4e6 100644 --- a/app/Models/LinkType.php +++ b/app/Models/LinkType.php @@ -50,22 +50,24 @@ class LinkType extends Model /** * @param $value * - * @return mixed + * @return LinkType * * @throws NotFoundHttpException */ - public static function routeBinder($value) + public static function routeBinder(string $value): LinkType { if (auth()->check()) { - $model = self::where('id', $value)->first(); - if (null !== $model) { - return $model; + $linkTypeId = intval($value); + $linkType = self::find($linkTypeId); + if (null !== $linkType) { + return $linkType; } } throw new NotFoundHttpException; } /** + * @codeCoverageIgnore * @return \Illuminate\Database\Eloquent\Relations\HasMany */ public function transactionJournalLinks() diff --git a/app/Models/Note.php b/app/Models/Note.php index 15853e7abc..df8b0de9de 100644 --- a/app/Models/Note.php +++ b/app/Models/Note.php @@ -45,6 +45,7 @@ class Note extends Model protected $fillable = ['title', 'text']; /** + * @codeCoverageIgnore * @return string */ public function getMarkdownAttribute(): string @@ -55,6 +56,7 @@ class Note extends Model } /** + * @codeCoverageIgnore * Get all of the owning noteable models. Currently piggy bank and * transaction journal. */ diff --git a/app/Models/PiggyBank.php b/app/Models/PiggyBank.php index 0d33f0800e..c4bf040c6c 100644 --- a/app/Models/PiggyBank.php +++ b/app/Models/PiggyBank.php @@ -61,21 +61,26 @@ class PiggyBank extends Model protected $hidden = ['targetamount_encrypted', 'encrypted']; /** - * @param PiggyBank $value + * @param string $value * * @return PiggyBank */ - public static function routeBinder(PiggyBank $value) + public static function routeBinder(string $value): PiggyBank { if (auth()->check()) { - if (intval($value->account->user_id) === auth()->user()->id) { - return $value; + $piggyBankId = intval($value); + $piggyBank = PiggyBank::where('piggy_banks.id', $piggyBankId) + ->leftJoin('accounts', 'accounts.id', '=', 'piggy_banks.account_id') + ->where('accounts.user_id', auth()->user()->id)->first(['piggy_banks.*']); + if (!is_null($piggyBank)) { + return $piggyBank; } } throw new NotFoundHttpException; } /** + * @codeCoverageIgnore * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function account(): BelongsTo @@ -105,6 +110,7 @@ class PiggyBank extends Model } /** + * @codeCoverageIgnore * @param $value * * @return string @@ -162,6 +168,7 @@ class PiggyBank extends Model } /** + * @codeCoverageIgnore * Get all of the piggy bank's notes. */ public function notes() @@ -170,6 +177,7 @@ class PiggyBank extends Model } /** + * @codeCoverageIgnore * @return \Illuminate\Database\Eloquent\Relations\HasMany */ public function piggyBankEvents() @@ -178,6 +186,7 @@ class PiggyBank extends Model } /** + * @codeCoverageIgnore * @return \Illuminate\Database\Eloquent\Relations\HasMany */ public function piggyBankRepetitions() @@ -186,6 +195,7 @@ class PiggyBank extends Model } /** + * @codeCoverageIgnore * @param $value */ public function setNameAttribute($value) @@ -196,10 +206,11 @@ class PiggyBank extends Model } /** + * @codeCoverageIgnore * @param $value */ public function setTargetamountAttribute($value) { - $this->attributes['targetamount'] = strval(round($value, 12)); + $this->attributes['targetamount'] = strval($value); } } diff --git a/app/Models/PiggyBankEvent.php b/app/Models/PiggyBankEvent.php index e44a45233b..683f2b7b9e 100644 --- a/app/Models/PiggyBankEvent.php +++ b/app/Models/PiggyBankEvent.php @@ -52,6 +52,7 @@ class PiggyBankEvent extends Model protected $hidden = ['amount_encrypted']; /** + * @codeCoverageIgnore * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function piggyBank() @@ -60,14 +61,16 @@ class PiggyBankEvent extends Model } /** + * @codeCoverageIgnore * @param $value */ public function setAmountAttribute($value) { - $this->attributes['amount'] = strval(round($value, 2)); + $this->attributes['amount'] = strval($value); } /** + * @codeCoverageIgnore * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function transactionJournal() diff --git a/app/Models/PiggyBankRepetition.php b/app/Models/PiggyBankRepetition.php index ddf0cab986..77e09eadbc 100644 --- a/app/Models/PiggyBankRepetition.php +++ b/app/Models/PiggyBankRepetition.php @@ -50,6 +50,7 @@ class PiggyBankRepetition extends Model protected $fillable = ['piggy_bank_id', 'startdate', 'targetdate', 'currentamount']; /** + * @codeCoverageIgnore * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function piggyBank() @@ -58,6 +59,7 @@ class PiggyBankRepetition extends Model } /** + * @codeCoverageIgnore * @param EloquentBuilder $query * @param Carbon $start * @param Carbon $target @@ -70,6 +72,7 @@ class PiggyBankRepetition extends Model } /** + * @codeCoverageIgnore * @param EloquentBuilder $query * @param Carbon $date * @@ -92,10 +95,11 @@ class PiggyBankRepetition extends Model } /** + * @codeCoverageIgnore * @param $value */ public function setCurrentamountAttribute($value) { - $this->attributes['currentamount'] = strval(round($value, 12)); + $this->attributes['currentamount'] = strval($value); } } diff --git a/app/Models/Preference.php b/app/Models/Preference.php index 18d80d4e36..d85c3323ba 100644 --- a/app/Models/Preference.php +++ b/app/Models/Preference.php @@ -79,6 +79,7 @@ class Preference extends Model } /** + * @codeCoverageIgnore * @param $value */ public function setDataAttribute($value) @@ -87,6 +88,7 @@ class Preference extends Model } /** + * @codeCoverageIgnore * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function user() diff --git a/app/Models/Role.php b/app/Models/Role.php index 5413d09165..339ed95f41 100644 --- a/app/Models/Role.php +++ b/app/Models/Role.php @@ -47,6 +47,7 @@ class Role extends Model protected $fillable = ['name', 'display_name', 'description']; /** + * @codeCoverageIgnore * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany */ public function users(): BelongsToMany diff --git a/app/Models/Rule.php b/app/Models/Rule.php index 6be62b2c9b..a59525674f 100644 --- a/app/Models/Rule.php +++ b/app/Models/Rule.php @@ -49,21 +49,24 @@ class Rule extends Model ]; /** - * @param Rule $value + * @param string $value * * @return Rule */ - public static function routeBinder(Rule $value) + public static function routeBinder(string $value): Rule { if (auth()->check()) { - if (intval($value->user_id) === auth()->user()->id) { - return $value; + $ruleId = intval($value); + $rule = auth()->user()->rules()->find($ruleId); + if (!is_null($rule)) { + return $rule; } } throw new NotFoundHttpException; } /** + * @codeCoverageIgnore * @return \Illuminate\Database\Eloquent\Relations\HasMany */ public function ruleActions() @@ -72,6 +75,7 @@ class Rule extends Model } /** + * @codeCoverageIgnore * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function ruleGroup() @@ -80,6 +84,7 @@ class Rule extends Model } /** + * @codeCoverageIgnore * @return \Illuminate\Database\Eloquent\Relations\HasMany */ public function ruleTriggers() @@ -88,6 +93,7 @@ class Rule extends Model } /** + * @codeCoverageIgnore * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function user() diff --git a/app/Models/RuleAction.php b/app/Models/RuleAction.php index 7f7af9ef8f..2bb86141fd 100644 --- a/app/Models/RuleAction.php +++ b/app/Models/RuleAction.php @@ -44,6 +44,7 @@ class RuleAction extends Model ]; /** + * @codeCoverageIgnore * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function rule() diff --git a/app/Models/RuleGroup.php b/app/Models/RuleGroup.php index 811fde0758..c57ebc4ad8 100644 --- a/app/Models/RuleGroup.php +++ b/app/Models/RuleGroup.php @@ -52,21 +52,24 @@ class RuleGroup extends Model protected $fillable = ['user_id', 'order', 'title', 'description', 'active']; /** - * @param RuleGroup $value + * @param string $value * * @return RuleGroup */ - public static function routeBinder(RuleGroup $value) + public static function routeBinder(string $value): RuleGroup { if (auth()->check()) { - if (intval($value->user_id) === auth()->user()->id) { - return $value; + $ruleGroupId = intval($value); + $ruleGroup = auth()->user()->ruleGroups()->find($ruleGroupId); + if (!is_null($ruleGroup)) { + return $ruleGroup; } } throw new NotFoundHttpException; } /** + * @codeCoverageIgnore * @return \Illuminate\Database\Eloquent\Relations\HasMany */ public function rules() @@ -75,6 +78,7 @@ class RuleGroup extends Model } /** + * @codeCoverageIgnore * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function user() diff --git a/app/Models/RuleTrigger.php b/app/Models/RuleTrigger.php index f52dc8367e..842be11e52 100644 --- a/app/Models/RuleTrigger.php +++ b/app/Models/RuleTrigger.php @@ -44,6 +44,7 @@ class RuleTrigger extends Model ]; /** + * @codeCoverageIgnore * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function rule() diff --git a/app/Models/Tag.php b/app/Models/Tag.php index a9d674bb18..f7d6351642 100644 --- a/app/Models/Tag.php +++ b/app/Models/Tag.php @@ -87,15 +87,17 @@ class Tag extends Model } /** - * @param Tag $value + * @param string $value * * @return Tag */ - public static function routeBinder(Tag $value) + public static function routeBinder(string $value): Tag { if (auth()->check()) { - if (intval($value->user_id) === auth()->user()->id) { - return $value; + $tagId = intval($value); + $tag = auth()->user()->tags()->find($tagId); + if (!is_null($tag)) { + return $tag; } } throw new NotFoundHttpException; @@ -120,6 +122,7 @@ class Tag extends Model } /** + * @codeCoverageIgnore * @param $value * * @return string @@ -134,6 +137,7 @@ class Tag extends Model } /** + * @codeCoverageIgnore * @param $value * * @return string @@ -166,6 +170,7 @@ class Tag extends Model } /** + * @codeCoverageIgnore * @param $value */ public function setDescriptionAttribute($value) @@ -174,6 +179,7 @@ class Tag extends Model } /** + * @codeCoverageIgnore * @param $value */ public function setTagAttribute($value) @@ -182,6 +188,7 @@ class Tag extends Model } /** + * @codeCoverageIgnore * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany */ public function transactionJournals() @@ -190,6 +197,7 @@ class Tag extends Model } /** + * @codeCoverageIgnore * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function user() diff --git a/app/Models/Transaction.php b/app/Models/Transaction.php index ce2cad1762..0378477c4b 100644 --- a/app/Models/Transaction.php +++ b/app/Models/Transaction.php @@ -107,6 +107,7 @@ class Transaction extends Model ]; /** + * @codeCoverageIgnore * @param Builder $query * @param string $table * @@ -130,6 +131,7 @@ class Transaction extends Model use SoftDeletes, ValidatingTrait; /** + * @codeCoverageIgnore * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function account() @@ -138,6 +140,7 @@ class Transaction extends Model } /** + * @codeCoverageIgnore * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany */ public function budgets() @@ -146,6 +149,7 @@ class Transaction extends Model } /** + * @codeCoverageIgnore * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany */ public function categories() @@ -154,6 +158,7 @@ class Transaction extends Model } /** + * @codeCoverageIgnore * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function foreignCurrency() @@ -162,6 +167,7 @@ class Transaction extends Model } /** + * @codeCoverageIgnore * @param $value * * @return float|int @@ -172,6 +178,7 @@ class Transaction extends Model } /** + * @codeCoverageIgnore * @param Builder $query * @param Carbon $date */ @@ -184,6 +191,7 @@ class Transaction extends Model } /** + * @codeCoverageIgnore * @param Builder $query * @param Carbon $date */ @@ -196,6 +204,7 @@ class Transaction extends Model } /** + * @codeCoverageIgnore * @param Builder $query * @param array $types */ @@ -212,14 +221,16 @@ class Transaction extends Model } /** + * @codeCoverageIgnore * @param $value */ public function setAmountAttribute($value) { - $this->attributes['amount'] = strval(round($value, 12)); + $this->attributes['amount'] = strval($value); } /** + * @codeCoverageIgnore * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function transactionCurrency() @@ -228,6 +239,7 @@ class Transaction extends Model } /** + * @codeCoverageIgnore * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function transactionJournal() diff --git a/app/Models/TransactionCurrency.php b/app/Models/TransactionCurrency.php index 4bc95b9ef6..beacb01102 100644 --- a/app/Models/TransactionCurrency.php +++ b/app/Models/TransactionCurrency.php @@ -51,19 +51,24 @@ class TransactionCurrency extends Model protected $fillable = ['name', 'code', 'symbol', 'decimal_places']; /** - * @param TransactionCurrency $currency + * @param string $value * * @return TransactionCurrency */ - public static function routeBinder(TransactionCurrency $currency) + public static function routeBinder(string $value): TransactionCurrency { if (auth()->check()) { - return $currency; + $currencyId = intval($value); + $currency = TransactionCurrency::find($currencyId); + if (!is_null($currency)) { + return $currency; + } } throw new NotFoundHttpException; } /** + * @codeCoverageIgnore * @return \Illuminate\Database\Eloquent\Relations\HasMany */ public function transactionJournals() diff --git a/app/Models/TransactionJournal.php b/app/Models/TransactionJournal.php index a78758dda2..4ba5ae9283 100644 --- a/app/Models/TransactionJournal.php +++ b/app/Models/TransactionJournal.php @@ -83,21 +83,20 @@ class TransactionJournal extends Model ]; /** - * @param $value + * @param string $value * - * @return mixed - * - * @throws NotFoundHttpException + * @return TransactionJournal */ - public static function routeBinder($value) + public static function routeBinder(string $value): TransactionJournal { if (auth()->check()) { - $object = self::where('transaction_journals.id', $value) - ->with('transactionType') - ->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id') - ->where('user_id', auth()->user()->id)->first(['transaction_journals.*']); - if (null !== $object) { - return $object; + $journalId = intval($value); + $journal = auth()->user()->transactionJournals()->where('transaction_journals.id', $journalId) + ->with('transactionType') + ->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id') + ->first(['transaction_journals.*']); + if (!is_null($journal)) { + return $journal; } } @@ -105,6 +104,7 @@ class TransactionJournal extends Model } /** + * @codeCoverageIgnore * @return \Illuminate\Database\Eloquent\Relations\MorphMany */ public function attachments() @@ -113,6 +113,7 @@ class TransactionJournal extends Model } /** + * @codeCoverageIgnore * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function bill() @@ -121,6 +122,7 @@ class TransactionJournal extends Model } /** + * @codeCoverageIgnore * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany */ public function budgets(): BelongsToMany @@ -129,6 +131,7 @@ class TransactionJournal extends Model } /** + * @codeCoverageIgnore * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany */ public function categories(): BelongsToMany @@ -137,6 +140,7 @@ class TransactionJournal extends Model } /** + * @codeCoverageIgnore * @param string $name * * @return bool @@ -149,6 +153,7 @@ class TransactionJournal extends Model } /** + * @codeCoverageIgnore * @return HasMany */ public function destinationJournalLinks(): HasMany @@ -157,6 +162,7 @@ class TransactionJournal extends Model } /** + * @codeCoverageIgnore * @param $value * * @return string @@ -171,6 +177,7 @@ class TransactionJournal extends Model } /** + * * @param string $name * * @return string @@ -206,6 +213,7 @@ class TransactionJournal extends Model } /** + * @codeCoverageIgnore * @param string $name * * @return bool @@ -216,6 +224,7 @@ class TransactionJournal extends Model } /** + * @codeCoverageIgnore * @return bool */ public function isDeposit(): bool @@ -228,6 +237,7 @@ class TransactionJournal extends Model } /** + * @codeCoverageIgnore * @return bool */ public function isOpeningBalance(): bool @@ -240,6 +250,7 @@ class TransactionJournal extends Model } /** + * @codeCoverageIgnore * @return bool */ public function isTransfer(): bool @@ -252,6 +263,7 @@ class TransactionJournal extends Model } /** + * @codeCoverageIgnore * @return bool */ public function isWithdrawal(): bool @@ -264,6 +276,7 @@ class TransactionJournal extends Model } /** + * @codeCoverageIgnore * Get all of the notes. */ public function notes() @@ -272,6 +285,7 @@ class TransactionJournal extends Model } /** + * @codeCoverageIgnore * @return \Illuminate\Database\Eloquent\Relations\HasMany */ public function piggyBankEvents(): HasMany @@ -280,6 +294,7 @@ class TransactionJournal extends Model } /** + * @codeCoverageIgnore * Save the model to the database. * * @param array $options @@ -295,6 +310,7 @@ class TransactionJournal extends Model } /** + * @codeCoverageIgnore * @param EloquentBuilder $query * @param Carbon $date * @@ -306,6 +322,7 @@ class TransactionJournal extends Model } /** + * @codeCoverageIgnore * @param EloquentBuilder $query * @param Carbon $date * @@ -317,6 +334,7 @@ class TransactionJournal extends Model } /** + * @codeCoverageIgnore * @param EloquentBuilder $query */ public function scopeSortCorrectly(EloquentBuilder $query) @@ -327,6 +345,7 @@ class TransactionJournal extends Model } /** + * @codeCoverageIgnore * @param EloquentBuilder $query * @param array $types */ @@ -341,6 +360,7 @@ class TransactionJournal extends Model } /** + * @codeCoverageIgnore * @param $value */ public function setDescriptionAttribute($value) @@ -388,6 +408,7 @@ class TransactionJournal extends Model } /** + * @codeCoverageIgnore * @return HasMany */ public function sourceJournalLinks(): HasMany @@ -396,6 +417,7 @@ class TransactionJournal extends Model } /** + * @codeCoverageIgnore * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany */ public function tags() @@ -404,6 +426,7 @@ class TransactionJournal extends Model } /** + * @codeCoverageIgnore * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function transactionCurrency() @@ -412,6 +435,7 @@ class TransactionJournal extends Model } /** + * @codeCoverageIgnore * @return HasMany */ public function transactionJournalMeta(): HasMany @@ -420,6 +444,7 @@ class TransactionJournal extends Model } /** + * @codeCoverageIgnore * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function transactionType() @@ -428,6 +453,7 @@ class TransactionJournal extends Model } /** + * @codeCoverageIgnore * @return HasMany */ public function transactions(): HasMany @@ -436,6 +462,7 @@ class TransactionJournal extends Model } /** + * @codeCoverageIgnore * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function user() diff --git a/app/Models/TransactionJournalLink.php b/app/Models/TransactionJournalLink.php index 92417a822f..f8f625d645 100644 --- a/app/Models/TransactionJournalLink.php +++ b/app/Models/TransactionJournalLink.php @@ -38,29 +38,31 @@ class TransactionJournalLink extends Model protected $table = 'journal_links'; /** - * @param $value + * @param string $value * * @return mixed * * @throws NotFoundHttpException */ - public static function routeBinder($value) + public static function routeBinder(string $value): TransactionJournalLink { if (auth()->check()) { - $model = self::where('journal_links.id', $value) - ->leftJoin('transaction_journals as t_a', 't_a.id', '=', 'source_id') - ->leftJoin('transaction_journals as t_b', 't_b.id', '=', 'destination_id') - ->where('t_a.user_id', auth()->user()->id) - ->where('t_b.user_id', auth()->user()->id) - ->first(['journal_links.*']); - if (null !== $model) { - return $model; + $linkId = intval($value); + $link = self::where('journal_links.id', $linkId) + ->leftJoin('transaction_journals as t_a', 't_a.id', '=', 'source_id') + ->leftJoin('transaction_journals as t_b', 't_b.id', '=', 'destination_id') + ->where('t_a.user_id', auth()->user()->id) + ->where('t_b.user_id', auth()->user()->id) + ->first(['journal_links.*']); + if (!is_null($link)) { + return $link; } } throw new NotFoundHttpException; } /** + * @codeCoverageIgnore * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function destination() @@ -69,6 +71,7 @@ class TransactionJournalLink extends Model } /** + * @codeCoverageIgnore * @param $value * * @return null|string @@ -83,6 +86,7 @@ class TransactionJournalLink extends Model } /** + * @codeCoverageIgnore * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function linkType(): BelongsTo @@ -91,6 +95,7 @@ class TransactionJournalLink extends Model } /** + * @codeCoverageIgnore * @param $value */ public function setCommentAttribute($value): void @@ -104,6 +109,7 @@ class TransactionJournalLink extends Model } /** + * @codeCoverageIgnore * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function source() diff --git a/app/Models/TransactionJournalMeta.php b/app/Models/TransactionJournalMeta.php index f9859bb665..827d3f7301 100644 --- a/app/Models/TransactionJournalMeta.php +++ b/app/Models/TransactionJournalMeta.php @@ -49,6 +49,7 @@ class TransactionJournalMeta extends Model protected $table = 'journal_meta'; /** + * @codeCoverageIgnore * @param $value * * @return mixed @@ -59,6 +60,7 @@ class TransactionJournalMeta extends Model } /** + * @codeCoverageIgnore * @param $value */ public function setDataAttribute($value) @@ -69,6 +71,7 @@ class TransactionJournalMeta extends Model } /** + * @codeCoverageIgnore * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function transactionJournal(): BelongsTo diff --git a/app/Models/TransactionType.php b/app/Models/TransactionType.php index 37ba8b3a47..5fd8972049 100644 --- a/app/Models/TransactionType.php +++ b/app/Models/TransactionType.php @@ -85,38 +85,43 @@ class TransactionType extends Model } /** + * @codeCoverageIgnore * @return bool */ - public function isDeposit() + public function isDeposit(): bool { return self::DEPOSIT === $this->type; } /** + * @codeCoverageIgnore * @return bool */ - public function isOpeningBalance() + public function isOpeningBalance(): bool { return self::OPENING_BALANCE === $this->type; } /** + * @codeCoverageIgnore * @return bool */ - public function isTransfer() + public function isTransfer(): bool { return self::TRANSFER === $this->type; } /** + * @codeCoverageIgnore * @return bool */ - public function isWithdrawal() + public function isWithdrawal(): bool { return self::WITHDRAWAL === $this->type; } /** + * @codeCoverageIgnore * @return \Illuminate\Database\Eloquent\Relations\HasMany */ public function transactionJournals() diff --git a/config/firefly.php b/config/firefly.php index b2c6201ce4..ba2d8eae30 100644 --- a/config/firefly.php +++ b/config/firefly.php @@ -146,35 +146,38 @@ return [ ], 'bindables' => [ - 'account' => 'FireflyIII\Models\Account', - 'attachment' => 'FireflyIII\Models\Attachment', - 'bill' => 'FireflyIII\Models\Bill', - 'budget' => 'FireflyIII\Models\Budget', - 'category' => 'FireflyIII\Models\Category', - 'transaction_type' => 'FireflyIII\Models\TransactionType', + // models + 'account' => \FireflyIII\Models\Account::class, + 'attachment' => \FireflyIII\Models\Attachment::class, + 'bill' => \FireflyIII\Models\Bill::class, + 'budget' => \FireflyIII\Models\Budget::class, + 'category' => \FireflyIII\Models\Category::class, + 'linkType' => \FireflyIII\Models\LinkType::class, + 'transaction_type' => \FireflyIII\Models\TransactionType::class, 'journalLink' => \FireflyIII\Models\TransactionJournalLink::class, - 'currency' => 'FireflyIII\Models\TransactionCurrency', - 'fromCurrencyCode' => 'FireflyIII\Support\Binder\CurrencyCode', - 'toCurrencyCode' => 'FireflyIII\Support\Binder\CurrencyCode', - 'limitrepetition' => 'FireflyIII\Models\LimitRepetition', - 'budgetlimit' => 'FireflyIII\Models\BudgetLimit', - 'piggyBank' => 'FireflyIII\Models\PiggyBank', - 'tj' => 'FireflyIII\Models\TransactionJournal', - 'unfinishedJournal' => 'FireflyIII\Support\Binder\UnfinishedJournal', - 'tag' => 'FireflyIII\Models\Tag', - 'rule' => 'FireflyIII\Models\Rule', - 'ruleGroup' => 'FireflyIII\Models\RuleGroup', - 'jobKey' => 'FireflyIII\Models\ExportJob', - 'importJob' => 'FireflyIII\Models\ImportJob', - 'accountList' => 'FireflyIII\Support\Binder\AccountList', - 'expenseList' => 'FireflyIII\Support\Binder\AccountList', - 'budgetList' => 'FireflyIII\Support\Binder\BudgetList', - 'journalList' => 'FireflyIII\Support\Binder\JournalList', - 'categoryList' => 'FireflyIII\Support\Binder\CategoryList', - 'tagList' => 'FireflyIII\Support\Binder\TagList', - 'start_date' => 'FireflyIII\Support\Binder\Date', - 'end_date' => 'FireflyIII\Support\Binder\Date', - 'date' => 'FireflyIII\Support\Binder\Date', + 'currency' => \FireflyIII\Models\TransactionCurrency::class, + 'budgetlimit' => \FireflyIII\Models\BudgetLimit::class, + 'piggyBank' => \FireflyIII\Models\PiggyBank::class, + 'tj' => \FireflyIII\Models\TransactionJournal::class, + 'tag' => \FireflyIII\Models\Tag::class, + 'rule' => \FireflyIII\Models\Rule::class, + 'ruleGroup' => \FireflyIII\Models\RuleGroup::class, + 'exportJob' => \FireflyIII\Models\ExportJob::class, + 'importJob' => \FireflyIII\Models\ImportJob::class, + + // binders + 'fromCurrencyCode' => \FireflyIII\Support\Binder\CurrencyCode::class, + 'toCurrencyCode' => \FireflyIII\Support\Binder\CurrencyCode::class, + 'unfinishedJournal' => \FireflyIII\Support\Binder\UnfinishedJournal::class, + 'accountList' => \FireflyIII\Support\Binder\AccountList::class, + 'expenseList' => \FireflyIII\Support\Binder\AccountList::class, + 'budgetList' => \FireflyIII\Support\Binder\BudgetList::class, + 'journalList' => \FireflyIII\Support\Binder\JournalList::class, + 'categoryList' => \FireflyIII\Support\Binder\CategoryList::class, + 'tagList' => \FireflyIII\Support\Binder\TagList::class, + 'start_date' => \FireflyIII\Support\Binder\Date::class, + 'end_date' => \FireflyIII\Support\Binder\Date::class, + 'date' => \FireflyIII\Support\Binder\Date::class, ], 'rule-triggers' => [ 'user_action' => 'FireflyIII\TransactionRules\Triggers\UserAction', diff --git a/routes/web.php b/routes/web.php index 843f3e94e8..f4773ece42 100755 --- a/routes/web.php +++ b/routes/web.php @@ -227,8 +227,8 @@ Route::group( Route::group( ['middleware' => 'user-full-auth', 'prefix' => 'export', 'as' => 'export.'], function () { Route::get('', ['uses' => 'ExportController@index', 'as' => 'index']); - Route::get('status/{jobKey}', ['uses' => 'ExportController@getStatus', 'as' => 'status']); - Route::get('download/{jobKey}', ['uses' => 'ExportController@download', 'as' => 'download']); + Route::get('status/{exportJob}', ['uses' => 'ExportController@getStatus', 'as' => 'status']); + Route::get('download/{exportJob}', ['uses' => 'ExportController@download', 'as' => 'download']); Route::post('submit', ['uses' => 'ExportController@postIndex', 'as' => 'submit']); diff --git a/tests/Unit/Middleware/AuthenticateTest.php b/tests/Unit/Middleware/AuthenticateTest.php new file mode 100644 index 0000000000..a80558f31b --- /dev/null +++ b/tests/Unit/Middleware/AuthenticateTest.php @@ -0,0 +1,112 @@ +. + */ + +declare(strict_types=1); + +namespace Tests\Unit\Helpers; + +use Route; +use Symfony\Component\HttpFoundation\Response; +use Tests\TestCase; + +/** + * Class AuthenticateTest + */ +class AuthenticateTest extends TestCase +{ + /** + * @covers \FireflyIII\Http\Middleware\Authenticate::handle + */ + public function testMiddleware() + { + $this->withoutExceptionHandling(); + $response = $this->get('/_test/authenticate'); + $this->assertEquals(Response::HTTP_FOUND, $response->getStatusCode()); + $response->assertRedirect(route('login')); + } + + /** + * @covers \FireflyIII\Http\Middleware\Authenticate::handle + */ + public function testMiddlewareAjax() + { + $server = ['HTTP_X-Requested-With' => 'XMLHttpRequest']; + $this->withoutExceptionHandling(); + $response = $this->get('/_test/authenticate', $server); + $this->assertEquals(Response::HTTP_UNAUTHORIZED, $response->getStatusCode()); + } + + /** + * @covers \FireflyIII\Http\Middleware\Authenticate::handle + */ + public function testMiddlewareAuth() + { + $this->be($this->user()); + $this->withoutExceptionHandling(); + $response = $this->get('/_test/authenticate'); + $this->assertEquals(Response::HTTP_OK, $response->getStatusCode()); + } + + /** + * @covers \FireflyIII\Http\Middleware\Authenticate::handle + */ + public function testMiddlewareBlockedUser() + { + $this->withoutExceptionHandling(); + $user = $this->user(); + $user->blocked = 1; + $this->be($user); + $response = $this->get('/_test/authenticate'); + $this->assertEquals(Response::HTTP_FOUND, $response->getStatusCode()); + $response->assertSessionHas('logoutMessage', strval(trans('firefly.block_account_logout'))); + $response->assertRedirect(route('login')); + } + + /** + * @covers \FireflyIII\Http\Middleware\Authenticate::handle + */ + public function testMiddlewareEmail() + { + $this->withoutExceptionHandling(); + $user = $this->user(); + $user->blocked = 1; + $user->blocked_code = 'email_changed'; + $this->be($user); + $response = $this->get('/_test/authenticate'); + $this->assertEquals(Response::HTTP_FOUND, $response->getStatusCode()); + $response->assertSessionHas('logoutMessage', strval(trans('firefly.email_changed_logout'))); + $response->assertRedirect(route('login')); + } + + /** + * Set up test + */ + protected function setUp() + { + parent::setUp(); + + Route::middleware('auth')->any( + '/_test/authenticate', function () { + return 'OK'; + } + ); + } +} \ No newline at end of file diff --git a/tests/Unit/Middleware/AuthenticateTwoFactorTest.php b/tests/Unit/Middleware/AuthenticateTwoFactorTest.php new file mode 100644 index 0000000000..b93970bea8 --- /dev/null +++ b/tests/Unit/Middleware/AuthenticateTwoFactorTest.php @@ -0,0 +1,218 @@ +. + */ + +declare(strict_types=1); + +namespace Tests\Unit\Helpers; + +use FireflyIII\Http\Middleware\AuthenticateTwoFactor; +use FireflyIII\Models\Preference; +use Preferences; +use Route; +use Symfony\Component\HttpFoundation\Response; +use Tests\TestCase; + +/** + * Class AuthenticateTwoFactorTest + */ +class AuthenticateTwoFactorTest extends TestCase +{ + /** + * @covers \FireflyIII\Http\Middleware\AuthenticateTwoFactor::handle + */ + public function testMiddleware() + { + $this->withoutExceptionHandling(); + $response = $this->get('/_test/authenticate'); + $this->assertEquals(Response::HTTP_FOUND, $response->getStatusCode()); + $response->assertRedirect(route('login')); + } + + /** + * @covers \FireflyIII\Http\Middleware\AuthenticateTwoFactor::handle + */ + public function testMiddlewareAjax() + { + $server = ['HTTP_X-Requested-With' => 'XMLHttpRequest']; + $this->withoutExceptionHandling(); + $response = $this->get('/_test/authenticate', $server); + $this->assertEquals(Response::HTTP_UNAUTHORIZED, $response->getStatusCode()); + } + + /** + * @covers \FireflyIII\Http\Middleware\AuthenticateTwoFactor::handle + */ + public function testMiddlewareBlockedUser() + { + $this->withoutExceptionHandling(); + $user = $this->user(); + $user->blocked = 1; + $this->be($user); + $response = $this->get('/_test/authenticate'); + $this->assertEquals(Response::HTTP_FOUND, $response->getStatusCode()); + $response->assertSessionHas('logoutMessage', strval(trans('firefly.block_account_logout'))); + $response->assertRedirect(route('login')); + } + + /** + * tests for user with no 2FA, should just go to requested page. + * + * 2FA enabled: false + * 2FA secret : false + * cookie : false + * + * + * @covers \FireflyIII\Http\Middleware\AuthenticateTwoFactor::handle + */ + public function testMiddlewareNoTwoFA() + { + $this->withoutExceptionHandling(); + $user = $this->user(); + $user->blocked = 0; + $this->be($user); + + // pref for has 2fa is false + $preference = new Preference; + $preference->data = false; + Preferences::shouldReceive('get')->withArgs(['twoFactorAuthEnabled', false])->once()->andReturn($preference); + + // pref for no twoFactorAuthSecret + Preferences::shouldReceive('get')->withArgs(['twoFactorAuthSecret'])->once()->andReturn(null); + + // no cookie + $cookie = []; + $response = $this->call('GET', '/_test/authenticate', [], $cookie); + $this->assertEquals(Response::HTTP_OK, $response->getStatusCode()); + } + + /** + * tests for user with 2FA but no secret. 2FA is not fired. + * + * 2FA enabled: true + * 2FA secret : false + * cookie : false + * + * + * @covers \FireflyIII\Http\Middleware\AuthenticateTwoFactor::handle + */ + public function testMiddlewareTwoFANoSecret() + { + $this->withoutExceptionHandling(); + $user = $this->user(); + $user->blocked = 0; + $this->be($user); + + // pref for has 2fa is true + $preference = new Preference; + $preference->data = true; + Preferences::shouldReceive('get')->withArgs(['twoFactorAuthEnabled', false])->once()->andReturn($preference); + + // pref for no twoFactorAuthSecret + Preferences::shouldReceive('get')->withArgs(['twoFactorAuthSecret'])->once()->andReturn(null); + + // no cookie + $cookie = []; + $response = $this->call('GET', '/_test/authenticate', [], $cookie); + $this->assertEquals(Response::HTTP_OK, $response->getStatusCode()); + } + + /** + * tests for user with 2FA and secret. 2FA is checked + * + * 2FA enabled: true + * 2FA secret : 'abcde' + * cookie : false + * + * + * @covers \FireflyIII\Http\Middleware\AuthenticateTwoFactor::handle + */ + public function testMiddlewareTwoFASecret() + { + $this->withoutExceptionHandling(); + $user = $this->user(); + $user->blocked = 0; + $this->be($user); + + // pref for has 2fa is true + $preference = new Preference; + $preference->data = true; + Preferences::shouldReceive('get')->withArgs(['twoFactorAuthEnabled', false])->once()->andReturn($preference); + + // pref for twoFactorAuthSecret + $secret = new Preference; + $secret->data = 'SomeSecret'; + Preferences::shouldReceive('get')->withArgs(['twoFactorAuthSecret'])->once()->andReturn($secret); + + // no cookie + $cookie = []; + $response = $this->call('GET', '/_test/authenticate', [], $cookie); + $this->assertEquals(Response::HTTP_FOUND, $response->getStatusCode()); + $response->assertRedirect(route('two-factor.index')); + } + + /** + * tests for user with 2FA and secret and cookie. Continue to page. + * + * 2FA enabled: true + * 2FA secret : 'abcde' + * cookie : false + * + * + * @covers \FireflyIII\Http\Middleware\AuthenticateTwoFactor::handle + */ + public function testMiddlewareTwoFAAuthed() + { + $this->withoutExceptionHandling(); + $user = $this->user(); + $user->blocked = 0; + $this->be($user); + + // pref for has 2fa is true + $preference = new Preference; + $preference->data = true; + Preferences::shouldReceive('get')->withArgs(['twoFactorAuthEnabled', false])->once()->andReturn($preference); + + // pref for twoFactorAuthSecret + $secret = new Preference; + $secret->data = 'SomeSecret'; + Preferences::shouldReceive('get')->withArgs(['twoFactorAuthSecret'])->once()->andReturn($secret); + + // no cookie + $cookie = ['twoFactorAuthenticated' => 'true']; + $response = $this->call('GET', '/_test/authenticate', [], $cookie); + $this->assertEquals(Response::HTTP_OK, $response->getStatusCode()); + } + + + /** + * Set up test + */ + protected function setUp() + { + parent::setUp(); + + Route::middleware(AuthenticateTwoFactor::class)->any( + '/_test/authenticate', function () { + return 'OK'; + } + ); + } +} \ No newline at end of file diff --git a/tests/Unit/Middleware/BinderTest.php b/tests/Unit/Middleware/BinderTest.php new file mode 100644 index 0000000000..b92460dcf2 --- /dev/null +++ b/tests/Unit/Middleware/BinderTest.php @@ -0,0 +1,1016 @@ +. + */ + +declare(strict_types=1); + +namespace Tests\Unit\Helpers; + + +use FireflyIII\Http\Middleware\Binder; +use Route; +use Symfony\Component\HttpFoundation\Response; +use Tests\TestCase; + +/** + * Class BinderTest + * Per object: works, not existing, not logged in + existing + */ +class BinderTest extends TestCase +{ + + /** + * @covers \FireflyIII\Http\Middleware\Binder::handle + * @covers \FireflyIII\Http\Middleware\Binder::__construct + * @covers \FireflyIII\Http\Middleware\Binder::performBinding + * @covers \FireflyIII\Models\Account::routeBinder + */ + public function testAccount() + { + Route::middleware(Binder::class)->any( + '/_test/binder/{account}', function () { + return 'OK'; + } + ); + + $this->be($this->user()); + $response = $this->get('/_test/binder/1'); + $this->assertEquals(Response::HTTP_OK, $response->getStatusCode()); + } + + /** + * @covers \FireflyIII\Http\Middleware\Binder::handle + * @covers \FireflyIII\Http\Middleware\Binder::__construct + * @covers \FireflyIII\Http\Middleware\Binder::performBinding + * @covers \FireflyIII\Models\Account::routeBinder + */ + public function testAccountNotFound() + { + Route::middleware(Binder::class)->any( + '/_test/binder/{account}', function () { + return 'OK'; + } + ); + + $this->be($this->user()); + $response = $this->get('/_test/binder/0'); + $this->assertEquals(Response::HTTP_NOT_FOUND, $response->getStatusCode()); + } + + /** + * @covers \FireflyIII\Http\Middleware\Binder::handle + * @covers \FireflyIII\Http\Middleware\Binder::__construct + * @covers \FireflyIII\Http\Middleware\Binder::performBinding + * @covers \FireflyIII\Models\Account::routeBinder + */ + public function testAccountNotLoggedIn() + { + Route::middleware(Binder::class)->any( + '/_test/binder/{account}', function () { + return 'OK'; + } + ); + + $response = $this->get('/_test/binder/1'); + $this->assertEquals(Response::HTTP_NOT_FOUND, $response->getStatusCode()); + } + + + /** + * @covers \FireflyIII\Http\Middleware\Binder::handle + * @covers \FireflyIII\Http\Middleware\Binder::__construct + * @covers \FireflyIII\Http\Middleware\Binder::performBinding + * @covers \FireflyIII\Models\Attachment::routeBinder + */ + public function testAttachment() + { + Route::middleware(Binder::class)->any( + '/_test/binder/{attachment}', function () { + return 'OK'; + } + ); + + $this->be($this->user()); + $response = $this->get('/_test/binder/1'); + $this->assertEquals(Response::HTTP_OK, $response->getStatusCode()); + } + + /** + * @covers \FireflyIII\Http\Middleware\Binder::handle + * @covers \FireflyIII\Http\Middleware\Binder::__construct + * @covers \FireflyIII\Http\Middleware\Binder::performBinding + * @covers \FireflyIII\Models\Attachment::routeBinder + */ + public function testAttachmentNotFound() + { + Route::middleware(Binder::class)->any( + '/_test/binder/{attachment}', function () { + return 'OK'; + } + ); + + $this->be($this->user()); + $response = $this->get('/_test/binder/0'); + $this->assertEquals(Response::HTTP_NOT_FOUND, $response->getStatusCode()); + } + + /** + * @covers \FireflyIII\Http\Middleware\Binder::handle + * @covers \FireflyIII\Http\Middleware\Binder::__construct + * @covers \FireflyIII\Http\Middleware\Binder::performBinding + * @covers \FireflyIII\Models\Attachment::routeBinder + */ + public function testAttachmentNotLoggedIn() + { + Route::middleware(Binder::class)->any( + '/_test/binder/{attachment}', function () { + return 'OK'; + } + ); + + $response = $this->get('/_test/binder/1'); + $this->assertEquals(Response::HTTP_NOT_FOUND, $response->getStatusCode()); + } + + /** + * @covers \FireflyIII\Http\Middleware\Binder::handle + * @covers \FireflyIII\Http\Middleware\Binder::__construct + * @covers \FireflyIII\Http\Middleware\Binder::performBinding + * @covers \FireflyIII\Models\Bill::routeBinder + */ + public function testBill() + { + Route::middleware(Binder::class)->any( + '/_test/binder/{bill}', function () { + return 'OK'; + } + ); + + $this->be($this->user()); + $response = $this->get('/_test/binder/1'); + $this->assertEquals(Response::HTTP_OK, $response->getStatusCode()); + } + + /** + * @covers \FireflyIII\Http\Middleware\Binder::handle + * @covers \FireflyIII\Http\Middleware\Binder::__construct + * @covers \FireflyIII\Http\Middleware\Binder::performBinding + * @covers \FireflyIII\Models\Bill::routeBinder + */ + public function testBillNotFound() + { + Route::middleware(Binder::class)->any( + '/_test/binder/{bill}', function () { + return 'OK'; + } + ); + + $this->be($this->user()); + $response = $this->get('/_test/binder/0'); + $this->assertEquals(Response::HTTP_NOT_FOUND, $response->getStatusCode()); + } + + /** + * @covers \FireflyIII\Http\Middleware\Binder::handle + * @covers \FireflyIII\Http\Middleware\Binder::__construct + * @covers \FireflyIII\Http\Middleware\Binder::performBinding + * @covers \FireflyIII\Models\Bill::routeBinder + */ + public function testBillNotLoggedIn() + { + Route::middleware(Binder::class)->any( + '/_test/binder/{bill}', function () { + return 'OK'; + } + ); + + $response = $this->get('/_test/binder/1'); + $this->assertEquals(Response::HTTP_NOT_FOUND, $response->getStatusCode()); + } + + /** + * @covers \FireflyIII\Http\Middleware\Binder::handle + * @covers \FireflyIII\Http\Middleware\Binder::__construct + * @covers \FireflyIII\Http\Middleware\Binder::performBinding + * @covers \FireflyIII\Models\Budget::routeBinder + */ + public function testBudget() + { + Route::middleware(Binder::class)->any( + '/_test/binder/{budget}', function () { + return 'OK'; + } + ); + + $this->be($this->user()); + $response = $this->get('/_test/binder/1'); + $this->assertEquals(Response::HTTP_OK, $response->getStatusCode()); + } + + /** + * @covers \FireflyIII\Http\Middleware\Binder::handle + * @covers \FireflyIII\Http\Middleware\Binder::__construct + * @covers \FireflyIII\Http\Middleware\Binder::performBinding + * @covers \FireflyIII\Models\BudgetLimit::routeBinder + */ + public function testBudgetLimit() + { + Route::middleware(Binder::class)->any( + '/_test/binder/{budgetlimit}', function () { + return 'OK'; + } + ); + + $this->be($this->user()); + $response = $this->get('/_test/binder/1'); + $this->assertEquals(Response::HTTP_OK, $response->getStatusCode()); + } + + /** + * @covers \FireflyIII\Http\Middleware\Binder::handle + * @covers \FireflyIII\Http\Middleware\Binder::__construct + * @covers \FireflyIII\Http\Middleware\Binder::performBinding + * @covers \FireflyIII\Models\BudgetLimit::routeBinder + */ + public function testBudgetLimitNotFound() + { + Route::middleware(Binder::class)->any( + '/_test/binder/{budgetlimit}', function () { + return 'OK'; + } + ); + + $this->be($this->user()); + $response = $this->get('/_test/binder/0'); + $this->assertEquals(Response::HTTP_NOT_FOUND, $response->getStatusCode()); + } + + /** + * @covers \FireflyIII\Http\Middleware\Binder::handle + * @covers \FireflyIII\Http\Middleware\Binder::__construct + * @covers \FireflyIII\Http\Middleware\Binder::performBinding + * @covers \FireflyIII\Models\BudgetLimit::routeBinder + */ + public function testBudgetLimitNotLoggedIn() + { + Route::middleware(Binder::class)->any( + '/_test/binder/{budgetlimit}', function () { + return 'OK'; + } + ); + + $response = $this->get('/_test/binder/1'); + $this->assertEquals(Response::HTTP_NOT_FOUND, $response->getStatusCode()); + } + + /** + * @covers \FireflyIII\Http\Middleware\Binder::handle + * @covers \FireflyIII\Http\Middleware\Binder::__construct + * @covers \FireflyIII\Http\Middleware\Binder::performBinding + * @covers \FireflyIII\Models\Budget::routeBinder + */ + public function testBudgetNotFound() + { + Route::middleware(Binder::class)->any( + '/_test/binder/{budget}', function () { + return 'OK'; + } + ); + + $this->be($this->user()); + $response = $this->get('/_test/binder/0'); + $this->assertEquals(Response::HTTP_NOT_FOUND, $response->getStatusCode()); + } + + /** + * @covers \FireflyIII\Http\Middleware\Binder::handle + * @covers \FireflyIII\Http\Middleware\Binder::__construct + * @covers \FireflyIII\Http\Middleware\Binder::performBinding + * @covers \FireflyIII\Models\Budget::routeBinder + */ + public function testBudgetNotLoggedIn() + { + Route::middleware(Binder::class)->any( + '/_test/binder/{budget}', function () { + return 'OK'; + } + ); + + $response = $this->get('/_test/binder/1'); + $this->assertEquals(Response::HTTP_NOT_FOUND, $response->getStatusCode()); + } + + /** + * @covers \FireflyIII\Http\Middleware\Binder::handle + * @covers \FireflyIII\Http\Middleware\Binder::__construct + * @covers \FireflyIII\Http\Middleware\Binder::performBinding + * @covers \FireflyIII\Models\Category::routeBinder + */ + public function testCategory() + { + Route::middleware(Binder::class)->any( + '/_test/binder/{category}', function () { + return 'OK'; + } + ); + + $this->be($this->user()); + $response = $this->get('/_test/binder/1'); + $this->assertEquals(Response::HTTP_OK, $response->getStatusCode()); + } + + /** + * @covers \FireflyIII\Http\Middleware\Binder::handle + * @covers \FireflyIII\Http\Middleware\Binder::__construct + * @covers \FireflyIII\Http\Middleware\Binder::performBinding + * @covers \FireflyIII\Models\Category::routeBinder + */ + public function testCategoryNotFound() + { + Route::middleware(Binder::class)->any( + '/_test/binder/{category}', function () { + return 'OK'; + } + ); + + $this->be($this->user()); + $response = $this->get('/_test/binder/0'); + $this->assertEquals(Response::HTTP_NOT_FOUND, $response->getStatusCode()); + } + + /** + * @covers \FireflyIII\Http\Middleware\Binder::handle + * @covers \FireflyIII\Http\Middleware\Binder::__construct + * @covers \FireflyIII\Http\Middleware\Binder::performBinding + * @covers \FireflyIII\Models\Category::routeBinder + */ + public function testCategoryNotLoggedIn() + { + Route::middleware(Binder::class)->any( + '/_test/binder/{category}', function () { + return 'OK'; + } + ); + + $response = $this->get('/_test/binder/1'); + $this->assertEquals(Response::HTTP_NOT_FOUND, $response->getStatusCode()); + } + + /** + * @covers \FireflyIII\Http\Middleware\Binder::handle + * @covers \FireflyIII\Http\Middleware\Binder::__construct + * @covers \FireflyIII\Http\Middleware\Binder::performBinding + * @covers \FireflyIII\Models\ExportJob::routeBinder + */ + public function testExportJob() + { + Route::middleware(Binder::class)->any( + '/_test/binder/{exportJob}', function () { + return 'OK'; + } + ); + + $this->be($this->user()); + $response = $this->get('/_test/binder/testExport'); + $this->assertEquals(Response::HTTP_OK, $response->getStatusCode()); + } + + /** + * @covers \FireflyIII\Http\Middleware\Binder::handle + * @covers \FireflyIII\Http\Middleware\Binder::__construct + * @covers \FireflyIII\Http\Middleware\Binder::performBinding + * @covers \FireflyIII\Models\ExportJob::routeBinder + */ + public function testExportJobNotFound() + { + Route::middleware(Binder::class)->any( + '/_test/binder/{exportJob}', function () { + return 'OK'; + } + ); + + $this->be($this->user()); + $response = $this->get('/_test/binder/0'); + $this->assertEquals(Response::HTTP_NOT_FOUND, $response->getStatusCode()); + } + + /** + * @covers \FireflyIII\Http\Middleware\Binder::handle + * @covers \FireflyIII\Http\Middleware\Binder::__construct + * @covers \FireflyIII\Http\Middleware\Binder::performBinding + * @covers \FireflyIII\Models\ExportJob::routeBinder + */ + public function testExportJobNotLoggedIn() + { + Route::middleware(Binder::class)->any( + '/_test/binder/{exportJob}', function () { + return 'OK'; + } + ); + + $response = $this->get('/_test/binder/testExport'); + $this->assertEquals(Response::HTTP_NOT_FOUND, $response->getStatusCode()); + } + + /** + * @covers \FireflyIII\Http\Middleware\Binder::handle + * @covers \FireflyIII\Http\Middleware\Binder::__construct + * @covers \FireflyIII\Http\Middleware\Binder::performBinding + * @covers \FireflyIII\Models\ImportJob::routeBinder + */ + public function testImportJob() + { + Route::middleware(Binder::class)->any( + '/_test/binder/{importJob}', function () { + return 'OK'; + } + ); + + $this->be($this->user()); + $response = $this->get('/_test/binder/testImport'); + $this->assertEquals(Response::HTTP_OK, $response->getStatusCode()); + } + + /** + * @covers \FireflyIII\Http\Middleware\Binder::handle + * @covers \FireflyIII\Http\Middleware\Binder::__construct + * @covers \FireflyIII\Http\Middleware\Binder::performBinding + * @covers \FireflyIII\Models\ImportJob::routeBinder + */ + public function testImportJobNotFound() + { + Route::middleware(Binder::class)->any( + '/_test/binder/{importJob}', function () { + return 'OK'; + } + ); + + $this->be($this->user()); + $response = $this->get('/_test/binder/0'); + $this->assertEquals(Response::HTTP_NOT_FOUND, $response->getStatusCode()); + } + + /** + * @covers \FireflyIII\Http\Middleware\Binder::handle + * @covers \FireflyIII\Http\Middleware\Binder::__construct + * @covers \FireflyIII\Http\Middleware\Binder::performBinding + * @covers \FireflyIII\Models\ImportJob::routeBinder + */ + public function testImportJobNotLoggedIn() + { + Route::middleware(Binder::class)->any( + '/_test/binder/{importJob}', function () { + return 'OK'; + } + ); + + $response = $this->get('/_test/binder/testImport'); + $this->assertEquals(Response::HTTP_NOT_FOUND, $response->getStatusCode()); + } + + + /** + * @covers \FireflyIII\Http\Middleware\Binder::handle + * @covers \FireflyIII\Http\Middleware\Binder::__construct + * @covers \FireflyIII\Http\Middleware\Binder::performBinding + * @covers \FireflyIII\Models\ImportJob::routeBinder + */ + public function testImportJobBadStatus() + { + Route::middleware(Binder::class)->any( + '/_test/binder/{importJob}', function () { + return 'OK'; + } + ); + $this->be($this->user()); + $response = $this->get('/_test/binder/bad-status'); + $this->assertEquals(Response::HTTP_INTERNAL_SERVER_ERROR, $response->getStatusCode()); + } + + + + /** + * @covers \FireflyIII\Http\Middleware\Binder::handle + * @covers \FireflyIII\Http\Middleware\Binder::__construct + * @covers \FireflyIII\Http\Middleware\Binder::performBinding + * @covers \FireflyIII\Models\LinkType::routeBinder + */ + public function testLinkType() + { + Route::middleware(Binder::class)->any( + '/_test/binder/{linkType}', function () { + return 'OK'; + } + ); + + $this->be($this->user()); + $response = $this->get('/_test/binder/1'); + $this->assertEquals(Response::HTTP_OK, $response->getStatusCode()); + } + + /** + * @covers \FireflyIII\Http\Middleware\Binder::handle + * @covers \FireflyIII\Http\Middleware\Binder::__construct + * @covers \FireflyIII\Http\Middleware\Binder::performBinding + * @covers \FireflyIII\Models\LinkType::routeBinder + */ + public function testLinkTypeNotFound() + { + Route::middleware(Binder::class)->any( + '/_test/binder/{linkType}', function () { + return 'OK'; + } + ); + + $this->be($this->user()); + $response = $this->get('/_test/binder/0'); + $this->assertEquals(Response::HTTP_NOT_FOUND, $response->getStatusCode()); + } + + /** + * @covers \FireflyIII\Http\Middleware\Binder::handle + * @covers \FireflyIII\Http\Middleware\Binder::__construct + * @covers \FireflyIII\Http\Middleware\Binder::performBinding + * @covers \FireflyIII\Models\LinkType::routeBinder + */ + public function testLinkTypeNotLoggedIn() + { + Route::middleware(Binder::class)->any( + '/_test/binder/{linkType}', function () { + return 'OK'; + } + ); + + $response = $this->get('/_test/binder/1'); + $this->assertEquals(Response::HTTP_NOT_FOUND, $response->getStatusCode()); + } + + /** + * @covers \FireflyIII\Http\Middleware\Binder::handle + * @covers \FireflyIII\Http\Middleware\Binder::__construct + * @covers \FireflyIII\Http\Middleware\Binder::performBinding + * @covers \FireflyIII\Models\PiggyBank::routeBinder + */ + public function testPiggyBank() + { + Route::middleware(Binder::class)->any( + '/_test/binder/{piggyBank}', function () { + return 'OK'; + } + ); + + $this->be($this->user()); + $response = $this->get('/_test/binder/1'); + $this->assertEquals(Response::HTTP_OK, $response->getStatusCode()); + } + + /** + * @covers \FireflyIII\Http\Middleware\Binder::handle + * @covers \FireflyIII\Http\Middleware\Binder::__construct + * @covers \FireflyIII\Http\Middleware\Binder::performBinding + * @covers \FireflyIII\Models\PiggyBank::routeBinder + */ + public function testPiggyBankNotFound() + { + Route::middleware(Binder::class)->any( + '/_test/binder/{piggyBank}', function () { + return 'OK'; + } + ); + + $this->be($this->user()); + $response = $this->get('/_test/binder/0'); + $this->assertEquals(Response::HTTP_NOT_FOUND, $response->getStatusCode()); + } + + /** + * @covers \FireflyIII\Http\Middleware\Binder::handle + * @covers \FireflyIII\Http\Middleware\Binder::__construct + * @covers \FireflyIII\Http\Middleware\Binder::performBinding + * @covers \FireflyIII\Models\PiggyBank::routeBinder + */ + public function testPiggyBankNotLoggedIn() + { + Route::middleware(Binder::class)->any( + '/_test/binder/{piggyBank}', function () { + return 'OK'; + } + ); + + $response = $this->get('/_test/binder/1'); + $this->assertEquals(Response::HTTP_NOT_FOUND, $response->getStatusCode()); + } + + /** + * @covers \FireflyIII\Http\Middleware\Binder::handle + * @covers \FireflyIII\Http\Middleware\Binder::__construct + * @covers \FireflyIII\Http\Middleware\Binder::performBinding + * @covers \FireflyIII\Models\Rule::routeBinder + */ + public function testRule() + { + Route::middleware(Binder::class)->any( + '/_test/binder/{rule}', function () { + return 'OK'; + } + ); + + $this->be($this->user()); + $response = $this->get('/_test/binder/1'); + $this->assertEquals(Response::HTTP_OK, $response->getStatusCode()); + } + + /** + * @covers \FireflyIII\Http\Middleware\Binder::handle + * @covers \FireflyIII\Http\Middleware\Binder::__construct + * @covers \FireflyIII\Http\Middleware\Binder::performBinding + * @covers \FireflyIII\Models\RuleGroup::routeBinder + */ + public function testRuleGroup() + { + Route::middleware(Binder::class)->any( + '/_test/binder/{ruleGroup}', function () { + return 'OK'; + } + ); + + $this->be($this->user()); + $response = $this->get('/_test/binder/1'); + $this->assertEquals(Response::HTTP_OK, $response->getStatusCode()); + } + + /** + * @covers \FireflyIII\Http\Middleware\Binder::handle + * @covers \FireflyIII\Http\Middleware\Binder::__construct + * @covers \FireflyIII\Http\Middleware\Binder::performBinding + * @covers \FireflyIII\Models\RuleGroup::routeBinder + */ + public function testRuleGroupNotFound() + { + Route::middleware(Binder::class)->any( + '/_test/binder/{ruleGroup}', function () { + return 'OK'; + } + ); + + $this->be($this->user()); + $response = $this->get('/_test/binder/0'); + $this->assertEquals(Response::HTTP_NOT_FOUND, $response->getStatusCode()); + } + + /** + * @covers \FireflyIII\Http\Middleware\Binder::handle + * @covers \FireflyIII\Http\Middleware\Binder::__construct + * @covers \FireflyIII\Http\Middleware\Binder::performBinding + * @covers \FireflyIII\Models\RuleGroup::routeBinder + */ + public function testRuleGroupNotLoggedIn() + { + Route::middleware(Binder::class)->any( + '/_test/binder/{ruleGroup}', function () { + return 'OK'; + } + ); + + $response = $this->get('/_test/binder/1'); + $this->assertEquals(Response::HTTP_NOT_FOUND, $response->getStatusCode()); + } + + /** + * @covers \FireflyIII\Http\Middleware\Binder::handle + * @covers \FireflyIII\Http\Middleware\Binder::__construct + * @covers \FireflyIII\Http\Middleware\Binder::performBinding + * @covers \FireflyIII\Models\Rule::routeBinder + */ + public function testRuleNotFound() + { + Route::middleware(Binder::class)->any( + '/_test/binder/{rule}', function () { + return 'OK'; + } + ); + + $this->be($this->user()); + $response = $this->get('/_test/binder/0'); + $this->assertEquals(Response::HTTP_NOT_FOUND, $response->getStatusCode()); + } + + /** + * @covers \FireflyIII\Http\Middleware\Binder::handle + * @covers \FireflyIII\Http\Middleware\Binder::__construct + * @covers \FireflyIII\Http\Middleware\Binder::performBinding + * @covers \FireflyIII\Models\Rule::routeBinder + */ + public function testRuleNotLoggedIn() + { + Route::middleware(Binder::class)->any( + '/_test/binder/{rule}', function () { + return 'OK'; + } + ); + + $response = $this->get('/_test/binder/1'); + $this->assertEquals(Response::HTTP_NOT_FOUND, $response->getStatusCode()); + } + + /** + * @covers \FireflyIII\Http\Middleware\Binder::handle + * @covers \FireflyIII\Http\Middleware\Binder::__construct + * @covers \FireflyIII\Http\Middleware\Binder::performBinding + * @covers \FireflyIII\Models\TransactionJournal::routeBinder + */ + public function testTJ() + { + Route::middleware(Binder::class)->any( + '/_test/binder/{tj}', function () { + return 'OK'; + } + ); + + $this->be($this->user()); + $response = $this->get('/_test/binder/1'); + $this->assertEquals(Response::HTTP_OK, $response->getStatusCode()); + } + + /** + * @covers \FireflyIII\Http\Middleware\Binder::handle + * @covers \FireflyIII\Http\Middleware\Binder::__construct + * @covers \FireflyIII\Http\Middleware\Binder::performBinding + * @covers \FireflyIII\Models\TransactionJournal::routeBinder + */ + public function testTJNotFound() + { + Route::middleware(Binder::class)->any( + '/_test/binder/{tj}', function () { + return 'OK'; + } + ); + + $this->be($this->user()); + $response = $this->get('/_test/binder/0'); + $this->assertEquals(Response::HTTP_NOT_FOUND, $response->getStatusCode()); + } + + /** + * @covers \FireflyIII\Http\Middleware\Binder::handle + * @covers \FireflyIII\Http\Middleware\Binder::__construct + * @covers \FireflyIII\Http\Middleware\Binder::performBinding + * @covers \FireflyIII\Models\TransactionJournal::routeBinder + */ + public function testTJNotLoggedIn() + { + Route::middleware(Binder::class)->any( + '/_test/binder/{tj}', function () { + return 'OK'; + } + ); + + $response = $this->get('/_test/binder/1'); + $this->assertEquals(Response::HTTP_NOT_FOUND, $response->getStatusCode()); + } + + /** + * @covers \FireflyIII\Http\Middleware\Binder::handle + * @covers \FireflyIII\Http\Middleware\Binder::__construct + * @covers \FireflyIII\Http\Middleware\Binder::performBinding + * @covers \FireflyIII\Models\Tag::routeBinder + */ + public function testTag() + { + Route::middleware(Binder::class)->any( + '/_test/binder/{tag}', function () { + return 'OK'; + } + ); + + $this->be($this->user()); + $response = $this->get('/_test/binder/1'); + $this->assertEquals(Response::HTTP_OK, $response->getStatusCode()); + } + + /** + * @covers \FireflyIII\Http\Middleware\Binder::handle + * @covers \FireflyIII\Http\Middleware\Binder::__construct + * @covers \FireflyIII\Http\Middleware\Binder::performBinding + * @covers \FireflyIII\Models\Tag::routeBinder + */ + public function testTagNotFound() + { + Route::middleware(Binder::class)->any( + '/_test/binder/{tag}', function () { + return 'OK'; + } + ); + + $this->be($this->user()); + $response = $this->get('/_test/binder/0'); + $this->assertEquals(Response::HTTP_NOT_FOUND, $response->getStatusCode()); + } + + /** + * @covers \FireflyIII\Http\Middleware\Binder::handle + * @covers \FireflyIII\Http\Middleware\Binder::__construct + * @covers \FireflyIII\Http\Middleware\Binder::performBinding + * @covers \FireflyIII\Models\Tag::routeBinder + */ + public function testTagNotLoggedIn() + { + Route::middleware(Binder::class)->any( + '/_test/binder/{tag}', function () { + return 'OK'; + } + ); + + $response = $this->get('/_test/binder/1'); + $this->assertEquals(Response::HTTP_NOT_FOUND, $response->getStatusCode()); + } + + /** + * @covers \FireflyIII\Http\Middleware\Binder::handle + * @covers \FireflyIII\Http\Middleware\Binder::__construct + * @covers \FireflyIII\Http\Middleware\Binder::performBinding + * @covers \FireflyIII\Models\TransactionCurrency::routeBinder + */ + public function testTransactionCurrency() + { + Route::middleware(Binder::class)->any( + '/_test/binder/{currency}', function () { + return 'OK'; + } + ); + + $this->be($this->user()); + $response = $this->get('/_test/binder/1'); + $this->assertEquals(Response::HTTP_OK, $response->getStatusCode()); + } + + /** + * @covers \FireflyIII\Http\Middleware\Binder::handle + * @covers \FireflyIII\Http\Middleware\Binder::__construct + * @covers \FireflyIII\Http\Middleware\Binder::performBinding + * @covers \FireflyIII\Models\TransactionCurrency::routeBinder + */ + public function testTransactionCurrencyNotFound() + { + Route::middleware(Binder::class)->any( + '/_test/binder/{currency}', function () { + return 'OK'; + } + ); + + $this->be($this->user()); + $response = $this->get('/_test/binder/0'); + $this->assertEquals(Response::HTTP_NOT_FOUND, $response->getStatusCode()); + } + + /** + * @covers \FireflyIII\Http\Middleware\Binder::handle + * @covers \FireflyIII\Http\Middleware\Binder::__construct + * @covers \FireflyIII\Http\Middleware\Binder::performBinding + * @covers \FireflyIII\Models\TransactionCurrency::routeBinder + */ + public function testTransactionCurrencyNotLoggedIn() + { + Route::middleware(Binder::class)->any( + '/_test/binder/{currency}', function () { + return 'OK'; + } + ); + + $response = $this->get('/_test/binder/1'); + $this->assertEquals(Response::HTTP_NOT_FOUND, $response->getStatusCode()); + } + + /** + * @covers \FireflyIII\Http\Middleware\Binder::handle + * @covers \FireflyIII\Http\Middleware\Binder::__construct + * @covers \FireflyIII\Http\Middleware\Binder::performBinding + * @covers \FireflyIII\Models\TransactionJournalLink::routeBinder + */ + public function testTransactionJournalLink() + { + Route::middleware(Binder::class)->any( + '/_test/binder/{journalLink}', function () { + return 'OK'; + } + ); + + $this->be($this->user()); + $response = $this->get('/_test/binder/1'); + $this->assertEquals(Response::HTTP_OK, $response->getStatusCode()); + } + + /** + * @covers \FireflyIII\Http\Middleware\Binder::handle + * @covers \FireflyIII\Http\Middleware\Binder::__construct + * @covers \FireflyIII\Http\Middleware\Binder::performBinding + * @covers \FireflyIII\Models\TransactionJournalLink::routeBinder + */ + public function testTransactionJournalLinkNotFound() + { + Route::middleware(Binder::class)->any( + '/_test/binder/{journalLink}', function () { + return 'OK'; + } + ); + + $this->be($this->user()); + $response = $this->get('/_test/binder/0'); + $this->assertEquals(Response::HTTP_NOT_FOUND, $response->getStatusCode()); + } + + /** + * @covers \FireflyIII\Http\Middleware\Binder::handle + * @covers \FireflyIII\Http\Middleware\Binder::__construct + * @covers \FireflyIII\Http\Middleware\Binder::performBinding + * @covers \FireflyIII\Models\TransactionJournalLink::routeBinder + */ + public function testTransactionJournalLinkNotLoggedIn() + { + Route::middleware(Binder::class)->any( + '/_test/binder/{journalLink}', function () { + return 'OK'; + } + ); + + $response = $this->get('/_test/binder/1'); + $this->assertEquals(Response::HTTP_NOT_FOUND, $response->getStatusCode()); + } + + /** + * @covers \FireflyIII\Http\Middleware\Binder::handle + * @covers \FireflyIII\Http\Middleware\Binder::__construct + * @covers \FireflyIII\Http\Middleware\Binder::performBinding + * @covers \FireflyIII\Models\TransactionType::routeBinder + */ + public function testTransactionType() + { + Route::middleware(Binder::class)->any( + '/_test/binder/{transaction_type}', function () { + return 'OK'; + } + ); + + $this->be($this->user()); + $response = $this->get('/_test/binder/withdrawal'); + $this->assertEquals(Response::HTTP_OK, $response->getStatusCode()); + } + + /** + * @covers \FireflyIII\Http\Middleware\Binder::handle + * @covers \FireflyIII\Http\Middleware\Binder::__construct + * @covers \FireflyIII\Http\Middleware\Binder::performBinding + * @covers \FireflyIII\Models\TransactionType::routeBinder + */ + public function testTransactionTypeNotFound() + { + Route::middleware(Binder::class)->any( + '/_test/binder/{transaction_type}', function () { + return 'OK'; + } + ); + + $this->be($this->user()); + $response = $this->get('/_test/binder/unknown'); + $this->assertEquals(Response::HTTP_NOT_FOUND, $response->getStatusCode()); + } + + /** + * @covers \FireflyIII\Http\Middleware\Binder::handle + * @covers \FireflyIII\Http\Middleware\Binder::__construct + * @covers \FireflyIII\Http\Middleware\Binder::performBinding + * @covers \FireflyIII\Models\TransactionType::routeBinder + */ + public function testTransactionTypeNotLoggedIn() + { + Route::middleware(Binder::class)->any( + '/_test/binder/{transaction_type}', function () { + return 'OK'; + } + ); + + $response = $this->get('/_test/binder/withdrawal'); + $this->assertEquals(Response::HTTP_NOT_FOUND, $response->getStatusCode()); + } + + + + +} \ No newline at end of file