26 changed files with 1466 additions and 61 deletions
-
7.github/mergify.yml
-
1app/Http/Controllers/Import/AuthenticateController.php
-
81app/Http/Controllers/Import/ConfigurationController.php
-
5app/Http/Controllers/Import/ConversionController.php
-
30app/Http/Controllers/Import/MapController.php
-
184app/Http/Controllers/Import/Spectre/ConnectionController.php
-
4app/Http/Controllers/Import/UploadController.php
-
30app/Http/Middleware/ConnectionControllerMiddleware.php
-
111app/Http/Middleware/IsReadyForStep.php
-
57app/Services/CSV/Configuration/Configuration.php
-
2app/Services/Nordigen/Conversion/Routine/GenerateTransactions.php
-
1app/Services/Nordigen/TokenManager.php
-
7app/Services/Session/Constants.php
-
75app/Services/Spectre/Conversion/RoutineManager.php
-
94app/Services/Spectre/Request/GetAccountsRequest.php
-
96app/Services/Spectre/Request/ListConnectionsRequest.php
-
95app/Services/Spectre/Request/PostConnectSessionsRequest.php
-
88app/Services/Spectre/Request/PostCustomerRequest.php
-
131app/Services/Spectre/Response/GetAccountsResponse.php
-
131app/Services/Spectre/Response/ListConnectionsResponse.php
-
46app/Services/Spectre/Response/PostConnectSessionResponse.php
-
44app/Services/Spectre/Response/PostCustomerResponse.php
-
100resources/views/import/004-configure/index.twig
-
97resources/views/import/011-connection/index.twig
-
2resources/views/index.twig
-
8routes/web.php
@ -0,0 +1,7 @@ |
|||
pull_request_rules: |
|||
- name: Security update by dependabot |
|||
conditions: |
|||
- author~=^dependabot(|-preview)\[bot\]$ |
|||
actions: |
|||
merge: |
|||
method: merge |
@ -0,0 +1,184 @@ |
|||
<?php |
|||
declare(strict_types=1); |
|||
/* |
|||
* ConnectionController.php |
|||
* Copyright (c) 2021 james@firefly-iii.org |
|||
* |
|||
* This file is part of the Firefly III Data Importer |
|||
* (https://github.com/firefly-iii/data-importer). |
|||
* |
|||
* 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/>. |
|||
*/ |
|||
|
|||
namespace App\Http\Controllers\Import\Spectre; |
|||
|
|||
use App\Exceptions\ImporterErrorException; |
|||
use App\Http\Controllers\Controller; |
|||
use App\Http\Middleware\ConnectionControllerMiddleware; |
|||
use App\Services\CSV\Configuration\Configuration; |
|||
use App\Services\Session\Constants; |
|||
use App\Services\Spectre\Model\Customer; |
|||
use App\Services\Spectre\Request\ListConnectionsRequest; |
|||
use App\Services\Spectre\Request\ListCustomersRequest; |
|||
use App\Services\Spectre\Request\PostConnectSessionsRequest; |
|||
use App\Services\Spectre\Request\PostCustomerRequest; |
|||
use App\Services\Spectre\Response\ErrorResponse; |
|||
use App\Services\Spectre\Response\PostConnectSessionResponse; |
|||
use App\Services\Spectre\Response\PostCustomerResponse; |
|||
use App\Services\Storage\StorageService; |
|||
use Illuminate\Http\Request; |
|||
use JsonException; |
|||
use Log; |
|||
|
|||
/** |
|||
* Class ConnectionController |
|||
*/ |
|||
class ConnectionController extends Controller |
|||
{ |
|||
/** |
|||
* |
|||
*/ |
|||
public function __construct() |
|||
{ |
|||
parent::__construct(); |
|||
$this->middleware(ConnectionControllerMiddleware::class); |
|||
app('view')->share('pageTitle', 'Connection selection nice ey?'); |
|||
} |
|||
|
|||
/** |
|||
* |
|||
* @throws ImporterErrorException |
|||
*/ |
|||
public function index() |
|||
{ |
|||
$mainTitle = 'Spectre'; |
|||
$subTitle = 'Select your financial organisation'; |
|||
$url = config('spectre.url'); |
|||
|
|||
// TODO or cookie value
|
|||
$appId = config('spectre.app_id'); |
|||
$secret = config('spectre.secret'); |
|||
|
|||
// check if already has the correct customer:
|
|||
$hasCustomer = false; |
|||
$request = new ListCustomersRequest($url, $appId, $secret); |
|||
$list = $request->get(); |
|||
$identifier = null; |
|||
|
|||
if ($list instanceof ErrorResponse) { |
|||
throw new ImporterErrorException(sprintf('%s: %s', $list->class, $list->message)); |
|||
} |
|||
/** @var Customer $item */ |
|||
foreach ($list as $item) { |
|||
if (config('spectre.customer_identifier', 'default_ff3_customer') === $item->identifier) { |
|||
$hasCustomer = true; |
|||
$identifier = $item->id; |
|||
} |
|||
} |
|||
|
|||
if (false === $hasCustomer) { |
|||
// create new one
|
|||
$request = new PostCustomerRequest($url, $appId, $secret); |
|||
$request->identifier = config('spectre.customer_identifier', 'default_ff3_customer'); |
|||
/** @var PostCustomerResponse $customer */ |
|||
$customer = $request->post(); |
|||
$identifier = $customer->customer->id; |
|||
} |
|||
|
|||
// store identifier in config
|
|||
// skip next time?
|
|||
$configuration = Configuration::fromArray([]); |
|||
if (session()->has(Constants::CONFIGURATION)) { |
|||
$configuration = Configuration::fromArray(session()->get(Constants::CONFIGURATION)); |
|||
} |
|||
$configuration->setIdentifier($identifier); |
|||
|
|||
// save config
|
|||
$json = '[]'; |
|||
try { |
|||
$json = json_encode($configuration->toArray(), JSON_THROW_ON_ERROR, 512); |
|||
} catch (JsonException $e) { |
|||
Log::error($e->getMessage()); |
|||
} |
|||
StorageService::storeContent($json); |
|||
|
|||
session()->put(Constants::CONFIGURATION, $configuration->toArray()); |
|||
|
|||
Log::debug('About to get connections.'); |
|||
$request = new ListConnectionsRequest($url, $appId, $secret); |
|||
$request->customer = (string) $identifier; |
|||
$list = $request->get(); |
|||
|
|||
if ($list instanceof ErrorResponse) { |
|||
throw new ImporterErrorException(sprintf('%s: %s', $list->class, $list->message)); |
|||
} |
|||
|
|||
return view('import.011-connection.index', compact('mainTitle', 'subTitle', 'list', 'identifier', 'configuration')); |
|||
} |
|||
|
|||
/** |
|||
* @param Request $request |
|||
*/ |
|||
public function post(Request $request) |
|||
{ |
|||
$connectionId = $request->get('spectre_connection_id'); |
|||
|
|||
if ('00' === $connectionId) { |
|||
// get identifier
|
|||
$configuration = Configuration::fromArray([]); |
|||
if (session()->has(Constants::CONFIGURATION)) { |
|||
$configuration = Configuration::fromArray(session()->get(Constants::CONFIGURATION)); |
|||
} |
|||
|
|||
// make a new connection.
|
|||
// TODO grab from cookie
|
|||
$url = config('spectre.url'); |
|||
$appId = config('spectre.app_id'); |
|||
$secret = config('spectre.secret'); |
|||
$newToken = new PostConnectSessionsRequest($url, $appId, $secret); |
|||
$newToken->customer = $configuration->getIdentifier(); |
|||
$newToken->url = route('import.callback.index'); |
|||
/** @var PostConnectSessionResponse $result */ |
|||
$result = $newToken->post(); |
|||
|
|||
return redirect($result->connect_url); |
|||
} |
|||
|
|||
// store connection in config, go to fancy JS page.
|
|||
// store identifier in config
|
|||
// skip next time?
|
|||
$configuration = Configuration::fromArray([]); |
|||
if (session()->has(Constants::CONFIGURATION)) { |
|||
$configuration = Configuration::fromArray(session()->get(Constants::CONFIGURATION)); |
|||
} |
|||
$configuration->setConnection($connectionId); |
|||
|
|||
// save config
|
|||
$json = '[]'; |
|||
try { |
|||
$json = json_encode($configuration->toArray(), JSON_THROW_ON_ERROR, 512); |
|||
} catch (JsonException $e) { |
|||
Log::error($e->getMessage()); |
|||
} |
|||
StorageService::storeContent($json); |
|||
|
|||
session()->put(Constants::CONFIGURATION, $configuration->toSessionArray()); |
|||
session()->put(Constants::CONNECTION_SELECTED_INDICATOR, true); |
|||
|
|||
// redirect to job configuration
|
|||
return redirect(route('004-configure.index')); |
|||
|
|||
} |
|||
|
|||
} |
@ -0,0 +1,30 @@ |
|||
<?php |
|||
declare(strict_types=1); |
|||
/* |
|||
* ConnectionControllerMiddleware.php |
|||
* Copyright (c) 2021 james@firefly-iii.org |
|||
* |
|||
* This file is part of the Firefly III Data Importer |
|||
* (https://github.com/firefly-iii/data-importer). |
|||
* |
|||
* 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/>. |
|||
*/ |
|||
|
|||
namespace App\Http\Middleware; |
|||
|
|||
class ConnectionControllerMiddleware |
|||
{ |
|||
protected const STEP = 'select-connection'; |
|||
use IsReadyForStep; |
|||
} |
@ -0,0 +1,75 @@ |
|||
<?php |
|||
/* |
|||
* RoutineManager.php |
|||
* Copyright (c) 2021 james@firefly-iii.org |
|||
* |
|||
* This file is part of the Firefly III Data Importer |
|||
* (https://github.com/firefly-iii/data-importer). |
|||
* |
|||
* 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/>. |
|||
*/ |
|||
|
|||
namespace App\Services\Spectre\Conversion; |
|||
|
|||
use App\Services\CSV\Configuration\Configuration; |
|||
use App\Services\Shared\Conversion\GeneratesIdentifier; |
|||
use App\Services\Shared\Conversion\RoutineManagerInterface; |
|||
|
|||
/** |
|||
* Class RoutineManager |
|||
*/ |
|||
class RoutineManager implements RoutineManagerInterface |
|||
{ |
|||
use GeneratesIdentifier; |
|||
|
|||
private Configuration $configuration; |
|||
|
|||
/** |
|||
* |
|||
*/ |
|||
public function __construct(?string $identifier) |
|||
{ |
|||
if (null === $identifier) { |
|||
$this->generateIdentifier(); |
|||
} |
|||
if (null !== $identifier) { |
|||
$this->identifier = $identifier; |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* @inheritDoc |
|||
*/ |
|||
public function setConfiguration(Configuration $configuration): void |
|||
{ |
|||
// save config
|
|||
$this->configuration = $configuration; |
|||
} |
|||
|
|||
/** |
|||
* @inheritDoc |
|||
*/ |
|||
public function start(): array |
|||
{ |
|||
// TODO: Implement start() method.
|
|||
} |
|||
|
|||
/** |
|||
* @inheritDoc |
|||
*/ |
|||
public function getIdentifier(): string |
|||
{ |
|||
// TODO: Implement getIdentifier() method.
|
|||
} |
|||
} |
@ -0,0 +1,94 @@ |
|||
<?php |
|||
/** |
|||
* GetAccountsRequest.php |
|||
* Copyright (c) 2020 james@firefly-iii.org |
|||
* |
|||
* This file is part of the Firefly III Spectre importer |
|||
* (https://github.com/firefly-iii/spectre-importer). |
|||
* |
|||
* 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 App\Services\Spectre\Request; |
|||
|
|||
use App\Exceptions\ImporterErrorException; |
|||
use App\Services\Spectre\Response\ErrorResponse; |
|||
use App\Services\Spectre\Response\GetAccountsResponse; |
|||
use Log; |
|||
use App\Services\Shared\Response\Response; |
|||
|
|||
/** |
|||
* Class GetAccountsRequest |
|||
* TODO is not yet paginated. |
|||
*/ |
|||
class GetAccountsRequest extends Request |
|||
{ |
|||
public string $connection; |
|||
|
|||
|
|||
/** |
|||
* ListConnectionsRequest constructor. |
|||
* |
|||
* @param string $url |
|||
* @param string $appId |
|||
* @param string $secret |
|||
*/ |
|||
public function __construct(string $url, string $appId, string $secret) |
|||
{ |
|||
$this->type = 'all'; |
|||
$this->setBase($url); |
|||
$this->setAppId($appId); |
|||
$this->setSecret($secret); |
|||
$this->setUrl('accounts'); |
|||
} |
|||
|
|||
/** |
|||
* @inheritDoc |
|||
*/ |
|||
public function get(): Response |
|||
{ |
|||
Log::debug('GetAccountsRequest::get()'); |
|||
$this->setParameters( |
|||
[ |
|||
'connection_id' => $this->connection, |
|||
] |
|||
); |
|||
try { |
|||
$response = $this->authenticatedGet(); |
|||
} catch (ImporterErrorException $e) { |
|||
// JSON thing.
|
|||
return new ErrorResponse($e->json ?? []); |
|||
} |
|||
|
|||
return new GetAccountsResponse($response['data']); |
|||
} |
|||
|
|||
/** |
|||
* @inheritDoc |
|||
*/ |
|||
public function post(): Response |
|||
{ |
|||
// TODO: Implement post() method.
|
|||
} |
|||
|
|||
/** |
|||
* @inheritDoc |
|||
*/ |
|||
public function put(): Response |
|||
{ |
|||
// TODO: Implement put() method.
|
|||
} |
|||
} |
@ -0,0 +1,96 @@ |
|||
<?php |
|||
/** |
|||
* ListConnectionsRequest.php |
|||
* Copyright (c) 2020 james@firefly-iii.org |
|||
* |
|||
* This file is part of the Firefly III Spectre importer |
|||
* (https://github.com/firefly-iii/spectre-importer). |
|||
* |
|||
* 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 App\Services\Spectre\Request; |
|||
|
|||
use App\Exceptions\ImporterErrorException; |
|||
use App\Services\Spectre\Response\ErrorResponse; |
|||
use App\Services\Shared\Response\Response; |
|||
use App\Services\Spectre\Response\ListConnectionsResponse; |
|||
use JsonException; |
|||
use Log; |
|||
|
|||
/** |
|||
* Class ListConnectionsRequest |
|||
* TODO is not yet paginated. |
|||
*/ |
|||
class ListConnectionsRequest extends Request |
|||
{ |
|||
/** @var string */ |
|||
public string $customer; |
|||
|
|||
/** |
|||
* ListConnectionsRequest constructor. |
|||
* |
|||
* @param string $url |
|||
* @param string $appId |
|||
* @param string $secret |
|||
*/ |
|||
public function __construct(string $url, string $appId, string $secret) |
|||
{ |
|||
$this->setBase($url); |
|||
$this->setAppId($appId); |
|||
$this->setSecret($secret); |
|||
$this->setUrl('connections'); |
|||
} |
|||
|
|||
/** |
|||
* @inheritDoc |
|||
* @throws JsonException |
|||
*/ |
|||
public function get(): Response |
|||
{ |
|||
Log::debug('ListConnectionsRequest::get()'); |
|||
$this->setParameters( |
|||
[ |
|||
'customer_id' => $this->customer, |
|||
] |
|||
); |
|||
try { |
|||
$response = $this->authenticatedGet(); |
|||
} catch (ImporterErrorException $e) { |
|||
// JSON thing.
|
|||
return new ErrorResponse($e->json ?? []); |
|||
} |
|||
|
|||
return new ListConnectionsResponse($response['data']); |
|||
} |
|||
|
|||
/** |
|||
* @inheritDoc |
|||
*/ |
|||
public function post(): Response |
|||
{ |
|||
// TODO: Implement post() method.
|
|||
} |
|||
|
|||
/** |
|||
* @inheritDoc |
|||
*/ |
|||
public function put(): Response |
|||
{ |
|||
// TODO: Implement put() method.
|
|||
} |
|||
} |
@ -0,0 +1,95 @@ |
|||
<?php |
|||
/** |
|||
* PostConnectSessionsRequest.php |
|||
* Copyright (c) 2020 james@firefly-iii.org |
|||
* |
|||
* This file is part of the Firefly III Spectre importer |
|||
* (https://github.com/firefly-iii/spectre-importer). |
|||
* |
|||
* 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 App\Services\Spectre\Request; |
|||
|
|||
use App\Services\Spectre\Response\PostConnectSessionResponse; |
|||
use App\Services\Shared\Response\Response; |
|||
|
|||
/** |
|||
* Class PostConnectSessionsRequest |
|||
*/ |
|||
class PostConnectSessionsRequest extends Request |
|||
{ |
|||
public string $customer; |
|||
public string $url; |
|||
|
|||
/** |
|||
* PostConnectSessionsRequest constructor. |
|||
* |
|||
* @param string $url |
|||
* @param string $appId |
|||
* @param string $secret |
|||
*/ |
|||
public function __construct(string $url, string $appId, string $secret) |
|||
{ |
|||
$this->setBase($url); |
|||
$this->setAppId($appId); |
|||
$this->setSecret($secret); |
|||
$this->setUrl('connect_sessions/create'); |
|||
} |
|||
|
|||
/** |
|||
* @inheritDoc |
|||
*/ |
|||
public function get(): Response |
|||
{ |
|||
// TODO: Implement get() method.
|
|||
} |
|||
|
|||
/** |
|||
* @inheritDoc |
|||
*/ |
|||
public function post(): Response |
|||
{ |
|||
$body = [ |
|||
'data' => [ |
|||
'customer_id' => $this->customer, |
|||
'consent' => [ |
|||
'scopes' => ['account_details', 'transactions_details'], |
|||
'daily_refresh' => true, |
|||
'include_fake_providers' => true, |
|||
'show_consent_confirmation' => true, |
|||
'credentials_strategy' => 'ask', |
|||
], |
|||
'attempt' => [ |
|||
'return_to' => $this->url, |
|||
], |
|||
|
|||
], |
|||
]; |
|||
|
|||
$response = $this->sendUnsignedSpectrePost($body); |
|||
|
|||
return new PostConnectSessionResponse($response['data']); |
|||
} |
|||
|
|||
/** |
|||
* @inheritDoc |
|||
*/ |
|||
public function put(): Response |
|||
{ |
|||
// TODO: Implement put() method.
|
|||
} |
|||
} |
@ -0,0 +1,88 @@ |
|||
<?php |
|||
/** |
|||
* PostCustomerRequest.php |
|||
* Copyright (c) 2020 james@firefly-iii.org |
|||
* |
|||
* This file is part of the Firefly III Spectre importer |
|||
* (https://github.com/firefly-iii/spectre-importer). |
|||
* |
|||
* 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 App\Services\Spectre\Request; |
|||
|
|||
use App\Exceptions\ImporterErrorException; |
|||
use App\Services\Shared\Response\Response; |
|||
use App\Services\Spectre\Response\PostCustomerResponse; |
|||
|
|||
/** |
|||
* Class PostCustomerRequest |
|||
*/ |
|||
class PostCustomerRequest extends Request |
|||
{ |
|||
/** @var string */ |
|||
public string $identifier; |
|||
|
|||
/** |
|||
* PostCustomerRequest constructor. |
|||
* |
|||
* @param string $url |
|||
* @param string $appId |
|||
* @param string $secret |
|||
*/ |
|||
public function __construct(string $url, string $appId, string $secret) |
|||
{ |
|||
$this->setBase($url); |
|||
$this->setAppId($appId); |
|||
$this->setSecret($secret); |
|||
$this->setUrl('customers'); |
|||
} |
|||
|
|||
/** |
|||
* @inheritDoc |
|||
*/ |
|||
public function get(): Response |
|||
{ |
|||
// TODO: Implement get() method.
|
|||
} |
|||
|
|||
/** |
|||
* @inheritDoc |
|||
*/ |
|||
public function post(): Response |
|||
{ |
|||
if (null === $this->identifier) { |
|||
throw new ImporterErrorException('No identifier for PostCustomerRequest'); |
|||
} |
|||
$data = [ |
|||
'data' => [ |
|||
'identifier' => $this->identifier, |
|||
], |
|||
]; |
|||
|
|||
$response = $this->sendSignedSpectrePost($data); |
|||
|
|||
return new PostCustomerResponse($response['data']); |
|||
} |
|||
|
|||
/** |
|||
* @inheritDoc |
|||
*/ |
|||
public function put(): Response |
|||
{ |
|||
// TODO: Implement put() method.
|
|||
} |
|||
} |
@ -0,0 +1,131 @@ |
|||
<?php |
|||
/** |
|||
* GetAccountsResponse.php |
|||
* Copyright (c) 2020 james@firefly-iii.org |
|||
* |
|||
* This file is part of the Firefly III Spectre importer |
|||
* (https://github.com/firefly-iii/spectre-importer). |
|||
* |
|||
* 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 App\Services\Spectre\Response; |
|||
|
|||
use App\Services\Shared\Response\Response; |
|||
use App\Services\Spectre\Model\Account; |
|||
use Countable; |
|||
use Illuminate\Support\Collection; |
|||
use Iterator; |
|||
|
|||
/** |
|||
* Class GetAccountsResponse |
|||
*/ |
|||
class GetAccountsResponse extends Response implements Iterator, Countable |
|||
{ |
|||
/** @var Collection */ |
|||
private Collection $collection; |
|||
/** @var int */ |
|||
private int $position = 0; |
|||
|
|||
/** |
|||
* @inheritDoc |
|||
*/ |
|||
public function __construct(array $data) |
|||
{ |
|||
$this->collection = new Collection; |
|||
foreach ($data as $entry) { |
|||
$model = Account::fromArray($entry); |
|||
$this->collection->push($model); |
|||
} |
|||
} |
|||
|
|||
|
|||
/** |
|||
* Count elements of an object. |
|||
* |
|||
* @link https://php.net/manual/en/countable.count.php |
|||
* @return int The custom count as an integer. |
|||
* </p> |
|||
* <p> |
|||
* The return value is cast to an integer. |
|||
* @since 5.1.0 |
|||
*/ |
|||
public function count(): int |
|||
{ |
|||
return $this->collection->count(); |
|||
} |
|||
|
|||
/** |
|||
* Return the current element. |
|||
* |
|||
* @link https://php.net/manual/en/iterator.current.php |
|||
* @return Account |
|||
* @since 5.0.0 |
|||
*/ |
|||
public function current(): Account |
|||
{ |
|||
return $this->collection->get($this->position); |
|||
} |
|||
|
|||
/** |
|||
* Return the key of the current element. |
|||
* |
|||
* @link https://php.net/manual/en/iterator.key.php |
|||
* @return int |
|||
* @since 5.0.0 |
|||
*/ |
|||
public function key(): int |
|||
{ |
|||
return $this->position; |
|||
} |
|||
|
|||
/** |
|||
* Move forward to next element. |
|||
* |
|||
* @link https://php.net/manual/en/iterator.next.php |
|||
* @return void Any returned value is ignored. |
|||
* @since 5.0.0 |
|||
*/ |
|||
public function next(): void |
|||
{ |
|||
$this->position++; |
|||
} |
|||
|
|||
/** |
|||
* Rewind the Iterator to the first element. |
|||
* |
|||
* @link https://php.net/manual/en/iterator.rewind.php |
|||
* @return void Any returned value is ignored. |
|||
* @since 5.0.0 |
|||
*/ |
|||
public function rewind(): void |
|||
{ |
|||
$this->position = 0; |
|||
} |
|||
|
|||
/** |
|||
* Checks if current position is valid. |
|||
* |
|||
* @link https://php.net/manual/en/iterator.valid.php |
|||
* @return bool The return value will be casted to boolean and then evaluated. |
|||
* Returns true on success or false on failure. |
|||
* @since 5.0.0 |
|||
*/ |
|||
public function valid(): bool |
|||
{ |
|||
return $this->collection->has($this->position); |
|||
} |
|||
} |
@ -0,0 +1,131 @@ |
|||
<?php |
|||
/** |
|||
* ListConnectionsResponse.php |
|||
* Copyright (c) 2020 james@firefly-iii.org |
|||
* |
|||
* This file is part of the Firefly III Spectre importer |
|||
* (https://github.com/firefly-iii/spectre-importer). |
|||
* |
|||
* 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 App\Services\Spectre\Response; |
|||
|
|||
use App\Services\Shared\Response\Response; |
|||
use App\Services\Spectre\Model\Connection; |
|||
use Countable; |
|||
use Illuminate\Support\Collection; |
|||
use Iterator; |
|||
|
|||
/** |
|||
* Class ListConnectionsResponse |
|||
*/ |
|||
class ListConnectionsResponse extends Response implements Iterator, Countable |
|||
{ |
|||
private Collection $collection; |
|||
private int $position = 0; |
|||
|
|||
/** |
|||
* @inheritDoc |
|||
*/ |
|||
public function __construct(array $data) |
|||
{ |
|||
$this->collection = new Collection; |
|||
/** @var array $row */ |
|||
foreach ($data as $row) { |
|||
$model = Connection::fromArray($row); |
|||
$this->collection->push($model); |
|||
} |
|||
} |
|||
|
|||
|
|||
/** |
|||
* Count elements of an object. |
|||
* |
|||
* @link https://php.net/manual/en/countable.count.php |
|||
* @return int The custom count as an integer. |
|||
* </p> |
|||
* <p> |
|||
* The return value is cast to an integer. |
|||
* @since 5.1.0 |
|||
*/ |
|||
public function count(): int |
|||
{ |
|||
return $this->collection->count(); |
|||
} |
|||
|
|||
/** |
|||
* Return the current element. |
|||
* |
|||
* @link https://php.net/manual/en/iterator.current.php |
|||
* @return Connection |
|||
* @since 5.0.0 |
|||
*/ |
|||
public function current(): Connection |
|||
{ |
|||
return $this->collection->get($this->position); |
|||
} |
|||
|
|||
/** |
|||
* Return the key of the current element. |
|||
* |
|||
* @link https://php.net/manual/en/iterator.key.php |
|||
* @return int |
|||
* @since 5.0.0 |
|||
*/ |
|||
public function key(): int |
|||
{ |
|||
return $this->position; |
|||
} |
|||
|
|||
/** |
|||
* Move forward to next element. |
|||
* |
|||
* @link https://php.net/manual/en/iterator.next.php |
|||
* @return void Any returned value is ignored. |
|||
* @since 5.0.0 |
|||
*/ |
|||
public function next(): void |
|||
{ |
|||
$this->position++; |
|||
} |
|||
|
|||
/** |
|||
* Rewind the Iterator to the first element. |
|||
* |
|||
* @link https://php.net/manual/en/iterator.rewind.php |
|||
* @return void Any returned value is ignored. |
|||
* @since 5.0.0 |
|||
*/ |
|||
public function rewind(): void |
|||
{ |
|||
$this->position = 0; |
|||
} |
|||
|
|||
/** |
|||
* Checks if current position is valid. |
|||
* |
|||
* @link https://php.net/manual/en/iterator.valid.php |
|||
* @return bool The return value will be casted to boolean and then evaluated. |
|||
* Returns true on success or false on failure. |
|||
* @since 5.0.0 |
|||
*/ |
|||
public function valid(): bool |
|||
{ |
|||
return $this->collection->has($this->position); |
|||
} |
|||
} |
@ -0,0 +1,46 @@ |
|||
<?php |
|||
/** |
|||
* PostConnectSessionResponse.php |
|||
* Copyright (c) 2020 james@firefly-iii.org |
|||
* |
|||
* This file is part of the Firefly III Spectre importer |
|||
* (https://github.com/firefly-iii/spectre-importer). |
|||
* |
|||
* 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 App\Services\Spectre\Response; |
|||
|
|||
|
|||
use App\Services\Shared\Response\Response; |
|||
|
|||
/** |
|||
* Class PostConnectSessionResponse |
|||
*/ |
|||
class PostConnectSessionResponse extends Response |
|||
{ |
|||
|
|||
/** @var string */ |
|||
public string $connect_url; |
|||
|
|||
/** |
|||
* @inheritDoc |
|||
*/ |
|||
public function __construct(array $data) |
|||
{ |
|||
$this->connect_url = (string)$data['connect_url']; |
|||
} |
|||
} |
@ -0,0 +1,44 @@ |
|||
<?php |
|||
/** |
|||
* PostCustomerResponse.php |
|||
* Copyright (c) 2020 james@firefly-iii.org |
|||
* |
|||
* This file is part of the Firefly III Spectre importer |
|||
* (https://github.com/firefly-iii/spectre-importer). |
|||
* |
|||
* 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 App\Services\Spectre\Response; |
|||
|
|||
use App\Services\Shared\Response\Response; |
|||
use App\Services\Spectre\Model\Customer; |
|||
|
|||
/** |
|||
* Class PostCustomerResponse |
|||
*/ |
|||
class PostCustomerResponse extends Response |
|||
{ |
|||
public Customer $customer; |
|||
|
|||
/** |
|||
* @inheritDoc |
|||
*/ |
|||
public function __construct(array $data) |
|||
{ |
|||
$this->customer = Customer::fromArray($data); |
|||
} |
|||
} |
@ -0,0 +1,97 @@ |
|||
{% extends "./layout/default" %} |
|||
{% block content %} |
|||
<div class="container"> |
|||
<div class="row"> |
|||
<div class="col-lg-12"> |
|||
|
|||
</div> |
|||
</div> |
|||
<div class="row"> |
|||
<div class="col-lg-12"> |
|||
<h1>{{ mainTitle }}</h1> |
|||
<h2>{{ subTitle }}</h2> |
|||
</div> |
|||
</div> |
|||
<form method="post" action="{{ route('011-connections.post') }}" accept-charset="UTF-8" id="store"> |
|||
<input type="hidden" name="_token" value="{{ csrf_token() }}"/> |
|||
<div class="row"> |
|||
<div class="col-lg-12"> |
|||
<p class="lead">Select the connection to use or make a new connection</p> |
|||
<p> |
|||
Spectre creates connections; a representation of the connection to your financial institution. |
|||
Select below which one the importer must use, or opt to create a new connection if no connections are visible. |
|||
Please read |
|||
<a href="https://docs.firefly-iii.org/other-data-importers/usage/filter_import/" |
|||
target="_blank">the documentation for this page</a> if you want to know more. |
|||
</p> |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- list all connections --> |
|||
<div class="row"> |
|||
<div class="col-lg-12"> |
|||
<table class="table table-bordered table-striped"> |
|||
<thead> |
|||
<tr> |
|||
<th> </th> |
|||
<th>Bank</th> |
|||
<th>Last used</th> |
|||
<th>Status</th> |
|||
</tr> |
|||
</thead> |
|||
<tbody> |
|||
{% for item in list %} |
|||
<tr> |
|||
<td> |
|||
<input |
|||
{% if item.status == 'disabled' %}disabled{% endif %} |
|||
{% if configuration.getConnection == item.id %}checked="checked"{% endif %} |
|||
id="{{ item.id }}" type="radio" {% if list|length == 1%}checked{% endif%} name="spectre_connection_id" value="{{ item.id }}"> |
|||
</td> |
|||
<td> |
|||
<label for="{{ item.id }}"> |
|||
{{ item.providerName }} ({{ item.countryCode }}) |
|||
</label> |
|||
</td> |
|||
<td> |
|||
{{ item.lastSuccess.format("Y-m-d H:i:s") }}<br> |
|||
{{ item.updatedAt.format("Y-m-d H:i:s") }}<br> |
|||
</td> |
|||
<td> |
|||
{{ item.status }} |
|||
</td> |
|||
</tr> |
|||
{% endfor %} |
|||
<tr> |
|||
<td> |
|||
<input id="new_login" type="radio" name="spectre_connection_id" value="00" {% if configuration.getConnection == 0 %}checked="checked"{% endif %}> |
|||
</td> |
|||
<td colspan="3"> |
|||
<label for="new_login"><em> |
|||
Create a new connection |
|||
</em> |
|||
</label> |
|||
</td> |
|||
</tr> |
|||
</tbody> |
|||
</table> |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="row"> |
|||
<div class="col-lg-6"> |
|||
<!-- go back to upload --> |
|||
<a href="{{ route('back.upload') }}" class="btn btn-secondary">← Go back to upload</a> |
|||
<br> |
|||
<small class="text-muted">Changes on this page will not be saved.</small> |
|||
</div> |
|||
<div class="col-lg-6"> |
|||
<button type="submit" class="float-right btn btn-primary">Submit →</button> |
|||
</div> |
|||
</div> |
|||
</form> |
|||
</div> |
|||
{% endblock %} |
|||
{% block scripts %} |
|||
|
|||
{% endblock %} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue