diff --git a/app/Helpers/Bank/Yodlee/Yodlee.php b/app/Helpers/Bank/Yodlee/Yodlee.php index cbab6f997410..8ff9275cce0f 100644 --- a/app/Helpers/Bank/Yodlee/Yodlee.php +++ b/app/Helpers/Bank/Yodlee/Yodlee.php @@ -16,7 +16,7 @@ use Illuminate\Support\Facades\Http; class Yodlee { - public bool $test_mode; + public bool $test_mode = false; private string $api_endpoint = 'https://production.api.yodlee.com/ysl'; @@ -30,12 +30,12 @@ class Yodlee protected string $admin_name; - public function __construct(bool $test_mode = false) - { - $this->test_mode = $test_mode; + protected ?string $bank_account_id; - if($this->test_mode) - $this->api_endpoint = $this->test_api_endpoint; + public function __construct(?string $bank_account_id = null) + { + + $this->bank_account_id = $bank_account_id; $this->client_id = config('ninja.yodlee.client_id'); @@ -45,13 +45,34 @@ class Yodlee } - public function getAccessToken($user = false) + public function setTestMode() { - if(!$user) + $this->test_mode = true; + + return $this; + } + + public function getEndpoint() + { + + return $this->test_mode ? $this->test_api_endpoint : $this->api_endpoint; + + } + + /** + * If we do not pass in a user + * we pass in the admin username instead + */ + public function getAccessToken($is_admin = false) + { + if($is_admin) $user = $this->admin_name; + else + $user = $this->bank_account_id ?: $this->admin_name; $response = $this->bankFormRequest('/auth/token', 'post', [], ['loginName' => $user]); - +//catch failures here + nlog($response); return $response->token->accessToken; } @@ -59,7 +80,7 @@ class Yodlee public function createUser() { - $token = $this->getAccessToken(); + $token = $this->getAccessToken(true); $user['user'] = [ 'loginName' => 'test123', @@ -96,7 +117,7 @@ class Yodlee } */ - $response = Http::withHeaders($this->getHeaders(["Authorization" => "Bearer {$token}"]))->post($this->api_endpoint. "/user/register", $user); + $response = Http::withHeaders($this->getHeaders(["Authorization" => "Bearer {$token}"]))->post($this->getEndpoint(). "/user/register", $user); if($response->successful()) return $response->object(); @@ -109,10 +130,12 @@ class Yodlee } - public function getAccounts($token, $params = []) + public function getAccounts($params = []) { - $response = Http::withHeaders($this->getHeaders(["Authorization" => "Bearer {$token}"]))->get($this->api_endpoint. "/accounts", $params); + $token = $this->getAccessToken(); + + $response = Http::withHeaders($this->getHeaders(["Authorization" => "Bearer {$token}"]))->get($this->getEndpoint(). "/accounts", $params); if($response->successful()) return $response->object(); @@ -125,10 +148,11 @@ class Yodlee } - public function getTransactions($token, $params = []) + public function getTransactions($params = []) { + $token = $this->getAccessToken(); - $response = Http::withHeaders($this->getHeaders(["Authorization" => "Bearer {$token}"]))->get($this->api_endpoint. "/transactions", $params); + $response = Http::withHeaders($this->getHeaders(["Authorization" => "Bearer {$token}"]))->get($this->getEndpoint(). "/transactions", $params); if($response->successful()) return $response->object(); @@ -138,24 +162,11 @@ class Yodlee } - public function getTransactionCategories($token, $params = []) + public function getTransactionCategories($params = []) { + $token = $this->getAccessToken(); - $response = Http::withHeaders($this->getHeaders(["Authorization" => "Bearer {$token}"]))->get($this->api_endpoint. "/transactions/categories", $params); - - if($response->successful()) - return $response->object(); - - if($response->failed()) - return $response->body(); - - } - - - private function bankRequest(string $uri, string $verb, array $data = [], array $headers = []) - { - - $response = Http::withHeaders($this->getHeaders($headers))->{$verb}($this->api_endpoint . $uri, $this->buildBody()); + $response = Http::withHeaders($this->getHeaders(["Authorization" => "Bearer {$token}"]))->get($this->getEndpoint(). "/transactions/categories", $params); if($response->successful()) return $response->object(); @@ -168,7 +179,7 @@ class Yodlee private function bankFormRequest(string $uri, string $verb, array $data = [], array $headers) { - $response = Http::withHeaders($this->getFormHeaders($headers))->asForm()->{$verb}($this->api_endpoint . $uri, $this->buildBody()); + $response = Http::withHeaders($this->getFormHeaders($headers))->asForm()->{$verb}($this->getEndpoint() . $uri, $this->buildBody()); if($response->successful()) return $response->object(); diff --git a/app/Http/Controllers/BankIntegrationController.php b/app/Http/Controllers/BankIntegrationController.php index 7c5adfadd44c..093202a3934f 100644 --- a/app/Http/Controllers/BankIntegrationController.php +++ b/app/Http/Controllers/BankIntegrationController.php @@ -12,6 +12,8 @@ namespace App\Http\Controllers; use App\Factory\BankIntegrationFactory; +use App\Helpers\Bank\Yodlee\Yodlee; +use App\Http\Requests\BankIntegration\AdminBankIntegrationRequest; use App\Http\Requests\BankIntegration\CreateBankIntegrationRequest; use App\Http\Requests\BankIntegration\DestroyBankIntegrationRequest; use App\Http\Requests\BankIntegration\EditBankIntegrationRequest; @@ -414,4 +416,55 @@ class BankIntegrationController extends BaseController return $this->itemResponse($bank_integration->fresh()); } + + /** + * Return the remote list of accounts stored on the third part provider. + * + * @return Response + * + * + * + * @OA\Post( + * path="/api/v1/bank_integrations/remote_accounts", + * operationId="getRemoteAccounts", + * tags={"bank_integrations"}, + * summary="Gets the list of accounts from the remote server", + * description="Adds an bank_integration to a company", + * @OA\Parameter(ref="#/components/parameters/X-Api-Secret"), + * @OA\Parameter(ref="#/components/parameters/X-Api-Token"), + * @OA\Parameter(ref="#/components/parameters/X-Requested-With"), + * @OA\Parameter(ref="#/components/parameters/include"), + * @OA\Response( + * response=200, + * description="Returns the saved bank_integration object", + * @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"), + * @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"), + * @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"), + * @OA\JsonContent(ref="#/components/schemas/BankIntegration"), + * ), + * @OA\Response( + * response=422, + * description="Validation error", + * @OA\JsonContent(ref="#/components/schemas/ValidationError"), + * + * ), + * @OA\Response( + * response="default", + * description="Unexpected Error", + * @OA\JsonContent(ref="#/components/schemas/Error"), + * ), + * ) + */ + public function remote_accounts(AdminBankIntegrationRequest $request) + { + // As yodlee is the first integration we don't need to perform switches yet, however + // if we add additional providers we can reuse this class + + $bank_account_id = auth()->user()->account->bank_integration_account_id; + + $yodlee = new Yodlee(); + $yodlee->setTestMode(true); + + $yodlee->getAccounts($bank_account_id); + } } \ No newline at end of file diff --git a/app/Http/Requests/BankIntegration/AdminBankIntegrationRequest.php b/app/Http/Requests/BankIntegration/AdminBankIntegrationRequest.php new file mode 100644 index 000000000000..b3a7aab38d81 --- /dev/null +++ b/app/Http/Requests/BankIntegration/AdminBankIntegrationRequest.php @@ -0,0 +1,28 @@ +user()->isAdmin(); + } +} diff --git a/tests/Feature/Bank/YodleeApiTest.php b/tests/Feature/Bank/YodleeApiTest.php index 9267bead54d1..f8746e0a9156 100644 --- a/tests/Feature/Bank/YodleeApiTest.php +++ b/tests/Feature/Bank/YodleeApiTest.php @@ -31,20 +31,23 @@ class YodleeApiTest extends TestCase public function testCreateUser() { - $yodlee = new Yodlee(true); + $yodlee = new Yodlee(); + $yodlee->setTestMode(); - $user = $yodlee->createUser(); + // $user = $yodlee->createUser(); - nlog($user); + // nlog($user); + $this->assertNotNull($yodlee); } public function testAccessTokenGeneration() { - $yodlee = new Yodlee(true); + $yodlee = new Yodlee('sbMem62e1e69547bfb1'); + $yodlee->setTestMode(); - $access_token = $yodlee->getAccessToken('sbMem62e1e69547bfb1'); + $access_token = $yodlee->getAccessToken(true); // nlog($access_token); @@ -230,11 +233,10 @@ class YodleeApiTest extends TestCase { - $yodlee = new Yodlee(true); - - $access_token = $yodlee->getAccessToken('sbMem62e1e69547bfb2'); + $yodlee = new Yodlee('sbMem62e1e69547bfb2'); + $yodlee->setTestMode(); - $transactions = $yodlee->getTransactionCategories($access_token); + $transactions = $yodlee->getTransactionCategories(); // nlog($transactions); @@ -344,11 +346,10 @@ class YodleeApiTest extends TestCase public function testGetAccounts() { - $yodlee = new Yodlee(true); - - $access_token = $yodlee->getAccessToken('sbMem62e1e69547bfb1'); + $yodlee = new Yodlee('sbMem62e1e69547bfb1'); + $yodlee->setTestMode(); - $accounts = $yodlee->getAccounts($access_token); + $accounts = $yodlee->getAccounts(); // nlog($accounts); } @@ -403,13 +404,10 @@ class YodleeApiTest extends TestCase public function testGetTransactions() { - $yodlee = new Yodlee(true); - - $access_token = $yodlee->getAccessToken('sbMem62e1e69547bfb1'); + $yodlee = new Yodlee('sbMem62e1e69547bfb1'); + $yodlee->setTestMode(); - nlog($access_token); - - $transactions = $yodlee->getTransactions($access_token, ['categoryId' => 2, 'fromDate' => '2000-01-01']); + $transactions = $yodlee->getTransactions(['categoryId' => 2, 'fromDate' => '2000-01-01']); nlog($transactions);