Add final API changes

This commit is contained in:
James Cole
2024-05-19 10:17:21 +02:00
parent 6d143f1624
commit c96226b9b4
7 changed files with 370 additions and 201 deletions

View File

@@ -28,6 +28,7 @@ use Carbon\Exceptions\InvalidFormatException;
use FireflyIII\JsonApi\Rules\IsValidFilter; use FireflyIII\JsonApi\Rules\IsValidFilter;
use FireflyIII\JsonApi\Rules\IsValidPage; use FireflyIII\JsonApi\Rules\IsValidPage;
use FireflyIII\Support\Http\Api\AccountFilter; use FireflyIII\Support\Http\Api\AccountFilter;
use FireflyIII\Support\Http\Api\ParsesQueryFilters;
use FireflyIII\Support\Request\ChecksLogin; use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes; use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest; use Illuminate\Foundation\Http\FormRequest;
@@ -43,6 +44,7 @@ class AutocompleteRequest extends FormRequest
use AccountFilter; use AccountFilter;
use ChecksLogin; use ChecksLogin;
use ConvertsDataTypes; use ConvertsDataTypes;
use ParsesQueryFilters;
/** /**
* Loops over all possible query parameters (these are shared over ALL auto complete requests) * Loops over all possible query parameters (these are shared over ALL auto complete requests)
@@ -53,25 +55,11 @@ class AutocompleteRequest extends FormRequest
public function getParameters(): array public function getParameters(): array
{ {
$queryParameters = QueryParameters::cast($this->all()); $queryParameters = QueryParameters::cast($this->all());
try {
$date = Carbon::createFromFormat('Y-m-d', $queryParameters->filter()?->value('date', date('Y-m-d')), config('app.timezone'));
} catch (InvalidFormatException $e) {
Log::debug(sprintf('Invalid date format in autocomplete request. Using today: %s', $e->getMessage()));
$date = today();
}
$query = $queryParameters->filter()?->value('query', []) ?? [];
$query = is_string($query) ? [$query] : $query;
$size = (int) ($queryParameters->page()['size'] ?? 50);
$accountTypeRequest = $queryParameters->filter()?->value('account_types', []) ?? [];
$accountTypeRequest = is_string($accountTypeRequest) ? [$accountTypeRequest] : $accountTypeRequest;
$accountTypes = $this->getAccountTypeParameter($accountTypeRequest);
return [ return [
'date' => $date, 'date' => $this->dateOrToday($queryParameters, 'date'),
'query' => $query, 'query' => $this->arrayOfStrings($queryParameters, 'query'),
'size' => $size, 'size' => $this->integerFromQueryParams($queryParameters,'size', 50),
'account_types' => $accountTypes, 'account_types' => $this->getAccountTypeParameter($this->arrayOfStrings($queryParameters, 'account_types')),
]; ];
} }

View File

@@ -0,0 +1,112 @@
<?php
/*
* DashboardChartRequest.php
* Copyright (c) 2023 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Api\V2\Request\Chart;
use FireflyIII\Enums\UserRoleEnum;
use FireflyIII\JsonApi\Rules\IsValidFilter;
use FireflyIII\JsonApi\Rules\IsValidPage;
use FireflyIII\Support\Http\Api\ParsesQueryFilters;
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
use LaravelJsonApi\Core\Query\QueryParameters;
use LaravelJsonApi\Validation\Rule as JsonApiRule;
/**
* Class ChartRequest
*/
class ChartRequest extends FormRequest
{
use ChecksLogin;
use ConvertsDataTypes;
use ValidatesUserGroupTrait;
use ParsesQueryFilters;
protected array $acceptedRoles = [UserRoleEnum::READ_ONLY];
public function getParameters(): array
{
$queryParameters = QueryParameters::cast($this->all());
return [
'start' => $this->dateOrToday($queryParameters, 'start'),
'end' => $this->dateOrToday($queryParameters, 'end'),
// preselected heeft maar een paar toegestane waardes.
// 'query' => $this->arrayOfStrings($queryParameters, 'query'),
// 'size' => $this->integerFromQueryParams($queryParameters,'size', 50),
// 'account_types' => $this->getAccountTypeParameter($this->arrayOfStrings($queryParameters, 'account_types')),
];
}
// return [
// 'accounts' => $this->getAccountList(),
// 'preselected' => $this->convertString('preselected'),
// ];
// }
/**
* The rules that the incoming request must be matched against.
*/
public function rules(): array
{
return [
'fields' => JsonApiRule::notSupported(),
'filter' => ['nullable', 'array', new IsValidFilter(['start', 'end', 'preselected','accounts'])],
'include' => JsonApiRule::notSupported(),
'page' => JsonApiRule::notSupported(),
'sort' => JsonApiRule::notSupported(),
];
// return [
// 'start' => 'required|date|after:1900-01-01|before:2099-12-31',
// 'end' => 'required|date|after_or_equal:start|before:2099-12-31|after:1900-01-01',
// 'preselected' => sprintf('in:%s', implode(',', config('firefly.preselected_accounts'))),
// 'accounts.*' => 'exists:accounts,id',
// ];
}
public function withValidator(Validator $validator): void
{
$validator->after(
static function (Validator $validator): void {
// validate transaction query data.
$data = $validator->getData();
if (!array_key_exists('accounts', $data)) {
// $validator->errors()->add('accounts', trans('validation.filled', ['attribute' => 'accounts']));
return;
}
if (!is_array($data['accounts'])) {
$validator->errors()->add('accounts', trans('validation.filled', ['attribute' => 'accounts']));
}
}
);
if ($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
}
}
}

View File

@@ -32,6 +32,7 @@ class IsValidFilter implements ValidationRule
public function __construct(array $keys) public function __construct(array $keys)
{ {
$this->allowed = $keys; $this->allowed = $keys;
$this->allowed[] = 'user_group_id';
} }
#[\Override] #[\Override]
@@ -45,7 +46,7 @@ class IsValidFilter implements ValidationRule
} }
foreach ($value as $key => $val) { foreach ($value as $key => $val) {
if (!in_array($key, $this->allowed, true)) { if (!in_array($key, $this->allowed, true)) {
$fail('validation.bad_api_filter')->translate(); $fail('validation.bad_api_filter')->translate(['filter' => $key]);
} }
} }
} }

View File

@@ -0,0 +1,57 @@
<?php
/*
* ParsesQueryFilters.php
* Copyright (c) 2024 james@firefly-iii.org.
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see https://www.gnu.org/licenses/.
*/
declare(strict_types=1);
namespace FireflyIII\Support\Http\Api;
use Carbon\Carbon;
use Carbon\Exceptions\InvalidFormatException;
use Illuminate\Support\Facades\Log;
use LaravelJsonApi\Core\Query\QueryParameters;
trait ParsesQueryFilters
{
private function dateOrToday(QueryParameters $parameters, string $field): Carbon
{
$date = today();
try {
$date = Carbon::createFromFormat('Y-m-d', $parameters->filter()?->value($field, date('Y-m-d')), config('app.timezone'));
} catch (InvalidFormatException $e) {
Log::debug(sprintf('Invalid date format in request. Using today: %s', $e->getMessage()));
}
return $date;
}
private function arrayOfStrings(QueryParameters $parameters, string $field): array
{
$array = $parameters->filter()?->value($field, []) ?? [];
return is_string($array) ? [$array] : $array;
}
private function integerFromQueryParams(QueryParameters $parameters, string $field, int $default): int
{
return (int) ($parameters->page()[$field] ?? $default);
}
}

View File

@@ -38,6 +38,11 @@ use Illuminate\Support\Facades\Log;
trait ValidatesUserGroupTrait trait ValidatesUserGroupTrait
{ {
/** /**
* An "undocumented" filter
*
*
* TODO add this filter to the API docs.
*
* @throws AuthorizationException * @throws AuthorizationException
* @throws AuthenticationException * @throws AuthenticationException
*/ */
@@ -50,6 +55,11 @@ trait ValidatesUserGroupTrait
throw new AuthenticationException(); throw new AuthenticationException();
} }
/** @var User $user */ /** @var User $user */
$user = auth()->user(); $user = auth()->user();
$groupId = 0; $groupId = 0;

View File

@@ -118,7 +118,7 @@ return [
// see cer.php for exchange rates feature flag. // see cer.php for exchange rates feature flag.
], ],
'version' => 'develop/2024-05-18', 'version' => 'develop/2024-05-18',
'api_version' => '2.0.14', 'api_version' => '2.1.0',
'db_version' => 24, 'db_version' => 24,
// generic settings // generic settings

View File

@@ -25,6 +25,7 @@
declare(strict_types=1); declare(strict_types=1);
return [ return [
'bad_api_filter' => 'This API endpoint does not support ":filter" as a filter.',
'bad_type_source' => 'Firefly III can\'t determine the transaction type based on this source account.', 'bad_type_source' => 'Firefly III can\'t determine the transaction type based on this source account.',
'bad_type_destination' => 'Firefly III can\'t determine the transaction type based on this destination account.', 'bad_type_destination' => 'Firefly III can\'t determine the transaction type based on this destination account.',
'missing_where' => 'Array is missing "where"-clause', 'missing_where' => 'Array is missing "where"-clause',