Expand code for Spectre login.

This commit is contained in:
James Cole
2018-01-02 15:17:31 +01:00
parent d49aecdf49
commit 3f786856f3
12 changed files with 667 additions and 14 deletions

View File

@@ -0,0 +1,32 @@
<?php
/**
* DuplicatedCustomerException.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Services\Spectre\Exception;
/**
* Class DuplicatedCustomerException
*/
class DuplicatedCustomerException extends SpectreException
{
}

View File

@@ -0,0 +1,34 @@
<?php
/**
* SpectreException.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Services\Spectre\Exception;
use Exception;
/**
* Class SpectreException
*/
class SpectreException extends Exception
{
}

View File

@@ -0,0 +1,168 @@
<?php
/**
* Attempt.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Services\Spectre\Object;
use Carbon\Carbon;
/**
* Class Attempt
*/
class Attempt extends SpectreObject
{
/** @var string */
private $apiMode;
/** @var int */
private $apiVersion;
/** @var bool */
private $automaticFetch;
/** @var bool */
private $categorize;
/** @var Carbon */
private $consentGivenAt;
/** @var array */
private $consentTypes = [];
/** @var Carbon */
private $createdAt;
/** @var array */
private $customFields = [];
/** @var bool */
private $dailyRefresh;
/** @var string */
private $deviceType;
/** @var array */
private $excludeAccounts = [];
/** @var Carbon */
private $failAt;
/** @var string */
private $failErrorClass;
/** @var string */
private $failMessage;
/** @var string */
private $fetchType;
/** @var bool */
private $finished;
/** @var bool */
private $finishedRecent;
/** @var Carbon */
private $fromDate;
/** @var int */
private $id;
/** @var bool */
private $interactive;
/** @var string */
private $locale;
/** @var bool */
private $partial;
/** @var string */
private $remoteIp;
/** @var bool */
private $showConsentInformation;
/** @var array */
private $stages = [];
/** @var bool */
private $storeCredentials;
/** @var Carbon */
private $successAt;
/** @var Carbon */
private $toDate;
/** @var Carbon */
private $updatedAt;
/** @var string */
private $userAgent; // undocumented
/**
* Attempt constructor.
*
* @param array $data
*/
public function __construct(array $data)
{
$this->apiMode = $data['api_mode'];
$this->apiVersion = $data['api_version'];
$this->automaticFetch = $data['automatic_fetch'];
$this->categorize = $data['categorize'];
$this->createdAt = new Carbon($data['created_at']);
$this->consentGivenAt = new Carbon($data['consent_given_at']);
$this->consentTypes = $data['consent_types'];
$this->customFields = $data['custom_fields'];
$this->dailyRefresh = $data['daily_refresh'];
$this->deviceType = $data['device_type'];
$this->userAgent = $data['user_agent'] ?? '';
$this->remoteIp = $data['remote_ip'];
$this->excludeAccounts = $data['exclude_accounts'];
$this->failAt = new Carbon($data['fail_at']);
$this->failErrorClass = $data['fail_error_class'];
$this->failMessage = $data['fail_message'];
$this->fetchType = $data['fetch_type'];
$this->finished = $data['finished'];
$this->finishedRecent = $data['finished_recent'];
$this->fromDate = new Carbon($data['from_date']);
$this->id = $data['id'];
$this->interactive = $data['interactive'];
$this->locale = $data['locale'];
$this->partial = $data['partial'];
$this->showConsentInformation = $data['show_consent_confirmation'];
$this->stages = $data['stages'] ?? [];
$this->storeCredentials = $data['store_credentials'];
$this->successAt = new Carbon($data['success_at']);
$this->toDate = new Carbon($data['to_date']);
$this->updatedAt = new Carbon($data['updated_at']);
}
/**
* @return Carbon
*/
public function getCreatedAt(): Carbon
{
return $this->createdAt;
}
/**
* @return Carbon
*/
public function getFailAt(): Carbon
{
return $this->failAt;
}
/**
* @return null|string
*/
public function getFailErrorClass(): ?string
{
return $this->failErrorClass;
}
/**
* @return null|string
*/
public function getFailMessage(): ?string
{
return $this->failMessage;
}
}

View File

@@ -0,0 +1,40 @@
<?php
/**
* Holder.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Services\Spectre\Object;
/**
* Class Holder
*/
class Holder extends SpectreObject
{
/**
* Holder constructor.
*
* @param array $data
*/
public function __construct(array $data)
{
}
}

View File

@@ -0,0 +1,108 @@
<?php
/**
* Login.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Services\Spectre\Object;
use Carbon\Carbon;
/**
* Class Login
*/
class Login extends SpectreObject
{
/** @var Carbon */
private $consentGivenAt;
/** @var array */
private $consentTypes;
/** @var string */
private $countryCode;
/** @var Carbon */
private $createdAt;
/** @var int */
private $customerId;
/** @var bool */
private $dailyRefresh;
/** @var Holder */
private $holderInfo;
/** @var int */
private $id;
/** @var Attempt */
private $lastAttempt;
/** @var Carbon */
private $lastSuccessAt;
/** @var Carbon */
private $nextRefreshPossibleAt;
/** @var string */
private $providerCode;
/** @var int */
private $providerId;
/** @var string */
private $providerName;
/** @var bool */
private $showConsentConfirmation;
/** @var string */
private $status;
/** @var bool */
private $storeCredentials;
/** @var Carbon */
private $updatedAt;
/**
* Login constructor.
*
* @param array $data
*/
public function __construct(array $data)
{
$this->consentGivenAt = new Carbon($data['consent_given_at']);
$this->consentTypes = $data['consent_types'];
$this->countryCode = $data['country_code'];
$this->createdAt = new Carbon($data['created_at']);
$this->updatedAt = new Carbon($data['updated_at']);
$this->customerId = $data['customer_id'];
$this->dailyRefresh = $data['daily_refresh'];
$this->holderInfo = new Holder($data['holder_info']);
$this->id = $data['id'];
$this->lastAttempt = new Attempt($data['last_attempt']);
$this->lastSuccessAt = new Carbon($data['last_success_at']);
$this->nextRefreshPossibleAt = new Carbon($data['next_refresh_possible_at']);
$this->providerCode = $data['provider_code'];
$this->providerId = $data['provider_id'];
$this->providerName = $data['provider_name'];
$this->showConsentConfirmation = $data['show_consent_confirmation'];
$this->status = $data['status'];
$this->storeCredentials = $data['store_credentials'];
}
/**
* @return Attempt
*/
public function getLastAttempt(): Attempt
{
return $this->lastAttempt;
}
}

View File

@@ -44,6 +44,7 @@ class CreateTokenRequest extends SpectreRequest
/**
*
* @throws \FireflyIII\Exceptions\FireflyException
* @throws \FireflyIII\Services\Spectre\Exception\SpectreException
*/
public function call(): void
{

View File

@@ -0,0 +1,82 @@
<?php
/**
* ListCustomersRequest.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Services\Spectre\Request;
use FireflyIII\Services\Spectre\Object\Customer;
use Log;
/**
* Class ListCustomersRequest
*/
class ListCustomersRequest extends SpectreRequest
{
/** @var array */
private $customers = [];
/**
*
* @throws \FireflyIII\Exceptions\FireflyException
* @throws \FireflyIII\Services\Spectre\Exception\SpectreException
*/
public function call(): void
{
$hasNextPage = true;
$nextId = 0;
while ($hasNextPage) {
Log::debug(sprintf('Now calling ListCustomersRequest for next_id %d', $nextId));
$parameters = ['from_id' => $nextId];
$uri = '/api/v3/customers/?' . http_build_query($parameters);
$response = $this->sendSignedSpectreGet($uri, []);
// count entries:
Log::debug(sprintf('Found %d entries in data-array', count($response['data'])));
// extract next ID
$hasNextPage = false;
if (isset($response['meta']['next_id']) && intval($response['meta']['next_id']) > $nextId) {
$hasNextPage = true;
$nextId = $response['meta']['next_id'];
Log::debug(sprintf('Next ID is now %d.', $nextId));
} else {
Log::debug('No next page.');
}
// store customers:
foreach ($response['data'] as $customerArray) {
$this->customers[] = new Customer($customerArray);
}
}
}
/**
* @return array
*/
public function getCustomers(): array
{
return $this->customers;
}
}

View File

@@ -0,0 +1,91 @@
<?php
/**
* ListLoginsRequest.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Services\Spectre\Request;
use FireflyIII\Services\Spectre\Object\Customer;
use FireflyIII\Services\Spectre\Object\Login;
use Log;
/**
* Class ListLoginsRequest
*/
class ListLoginsRequest extends SpectreRequest
{
/** @var Customer */
private $customer;
/** @var array */
private $logins = [];
/**
* @return array
*/
public function getLogins(): array
{
return $this->logins;
}
/**
*
*/
public function call(): void
{
$hasNextPage = true;
$nextId = 0;
while ($hasNextPage) {
Log::debug(sprintf('Now calling ListLoginsRequest for next_id %d', $nextId));
$parameters = ['from_id' => $nextId, 'customer_id' => $this->customer->getId()];
$uri = '/api/v3/logins/?' . http_build_query($parameters);
$response = $this->sendSignedSpectreGet($uri, []);
// count entries:
Log::debug(sprintf('Found %d entries in data-array', count($response['data'])));
// extract next ID
$hasNextPage = false;
if (isset($response['meta']['next_id']) && intval($response['meta']['next_id']) > $nextId) {
$hasNextPage = true;
$nextId = $response['meta']['next_id'];
Log::debug(sprintf('Next ID is now %d.', $nextId));
} else {
Log::debug('No next page.');
}
// store logins:
/** @var array $loginArray */
foreach ($response['data'] as $loginArray) {
$this->logins[] = new Login($loginArray);
}
}
}
/**
* @param Customer $customer
*/
public function setCustomer(Customer $customer): void
{
$this->customer = $customer;
}
}

View File

@@ -34,6 +34,7 @@ class NewCustomerRequest extends SpectreRequest
/**
* @throws \FireflyIII\Exceptions\FireflyException
* @throws \FireflyIII\Services\Spectre\Exception\SpectreException
*/
public function call(): void
{

View File

@@ -23,6 +23,8 @@ declare(strict_types=1);
namespace FireflyIII\Services\Spectre\Request;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Services\Spectre\Exception\DuplicatedCustomerException;
use FireflyIII\Services\Spectre\Exception\SpectreException;
use FireflyIII\User;
use Log;
use Requests;
@@ -179,6 +181,7 @@ abstract class SpectreRequest
* @return array
*
* @throws FireflyException
* @throws SpectreException
*/
protected function sendSignedSpectreGet(string $uri, array $data): array
{
@@ -222,6 +225,7 @@ abstract class SpectreRequest
* @return array
*
* @throws FireflyException
* @throws SpectreException
*/
protected function sendSignedSpectrePost(string $uri, array $data): array
{
@@ -255,15 +259,21 @@ abstract class SpectreRequest
* @param Requests_Response $response
*
* @throws FireflyException
* @throws SpectreException
*/
private function detectError(Requests_Response $response): void
{
$body = $response->body;
$array = json_decode($body, true);
if (isset($array['error_class'])) {
$message = $array['error_message'] ?? '(no message)';
$message = $array['error_message'] ?? '(no message)';
$errorClass = $array['error_class'];
$class = sprintf('\\FireflyIII\\Services\\Spectre\Exception\\%sException', $errorClass);
if (class_exists($class)) {
throw new $class($message);
}
throw new FireflyException(sprintf('Error of class %s: %s', $array['error_class'], $message));
throw new FireflyException(sprintf('Error of class %s: %s', $errorClass, $message));
}
$statusCode = intval($response->status_code);