From 3b6a4a6100b0bb790420e1c12bafc9fd45e0b29a Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Mon, 2 Nov 2015 00:10:20 +0200 Subject: [PATCH] Added Fractal --- app/Http/Controllers/AccountApiController.php | 40 ++++++++++++ app/Http/Controllers/Auth/AuthController.php | 8 ++- app/Http/Controllers/TokenController.php | 4 -- app/Http/Middleware/VerifyCsrfToken.php | 6 ++ app/Http/routes.php | 2 + app/Models/EntityModel.php | 5 +- app/Ninja/Repositories/AccountRepository.php | 11 ++++ app/Ninja/Serializers/ArraySerializer.php | 16 +++++ app/Ninja/Transformers/AccountTransformer.php | 27 ++++++++ app/Ninja/Transformers/UserTransformer.php | 18 +++++ composer.json | 3 +- composer.lock | 65 ++++++++++++++++++- config/app.php | 1 + 13 files changed, 198 insertions(+), 8 deletions(-) create mode 100644 app/Http/Controllers/AccountApiController.php create mode 100644 app/Ninja/Serializers/ArraySerializer.php create mode 100644 app/Ninja/Transformers/AccountTransformer.php create mode 100644 app/Ninja/Transformers/UserTransformer.php diff --git a/app/Http/Controllers/AccountApiController.php b/app/Http/Controllers/AccountApiController.php new file mode 100644 index 000000000000..a2154ac53fe2 --- /dev/null +++ b/app/Http/Controllers/AccountApiController.php @@ -0,0 +1,40 @@ +accountRepo = $accountRepo; + } + + public function index() + { + $manager = new Manager(); + $manager->setSerializer(new ArraySerializer()); + + $account = Auth::user()->account->load('users'); + $resource = new Item($account, new AccountTransformer, 'account'); + + $response = $manager->createData($resource)->toArray(); + $response = json_encode($response, JSON_PRETTY_PRINT); + $headers = Utils::getApiHeaders(); + + return Response::make($response, 200, $headers); + } +} diff --git a/app/Http/Controllers/Auth/AuthController.php b/app/Http/Controllers/Auth/AuthController.php index 6c732cf15dee..14ef9cf8b446 100644 --- a/app/Http/Controllers/Auth/AuthController.php +++ b/app/Http/Controllers/Auth/AuthController.php @@ -97,8 +97,14 @@ class AuthController extends Controller { } else { $users = $this->accountRepo->loadAccounts(Auth::user()->id); } - Session::put(SESSION_USER_ACCOUNTS, $users); + + if ($request->create_token) { + if ( ! env(API_SECRET) || $request->api_secret !== env(API_SECRET)) { + return 'Invalid secret'; + } + return $this->accountRepo->createToken($request->token_name); + } } elseif ($user) { $user->failed_logins = $user->failed_logins + 1; $user->save(); diff --git a/app/Http/Controllers/TokenController.php b/app/Http/Controllers/TokenController.php index 9feca2c1a9ae..47885fe84066 100644 --- a/app/Http/Controllers/TokenController.php +++ b/app/Http/Controllers/TokenController.php @@ -145,13 +145,9 @@ class TokenController extends BaseController if ($tokenPublicId) { $token->name = trim(Input::get('name')); } else { - $lastToken = AccountToken::withTrashed()->where('account_id', '=', Auth::user()->account_id) - ->orderBy('public_id', 'DESC')->first(); - $token = AccountToken::createNew(); $token->name = trim(Input::get('name')); $token->token = str_random(RANDOM_KEY_LENGTH); - $token->public_id = $lastToken ? $lastToken->public_id + 1 : 1; } $token->save(); diff --git a/app/Http/Middleware/VerifyCsrfToken.php b/app/Http/Middleware/VerifyCsrfToken.php index 903d6f028aab..6af49e9b273c 100644 --- a/app/Http/Middleware/VerifyCsrfToken.php +++ b/app/Http/Middleware/VerifyCsrfToken.php @@ -34,6 +34,12 @@ class VerifyCsrfToken extends BaseVerifier { } } + if ($request->is('login')) { + if (env(API_SECRET) && $request->api_secret === env(API_SECRET)) { + return $next($request); + } + } + return parent::handle($request, $next); } diff --git a/app/Http/routes.php b/app/Http/routes.php index 999b6400084e..71b31f2a0204 100644 --- a/app/Http/routes.php +++ b/app/Http/routes.php @@ -190,6 +190,7 @@ Route::group(['middleware' => 'auth'], function() { Route::group(['middleware' => 'api', 'prefix' => 'api/v1'], function() { Route::resource('ping', 'ClientApiController@ping'); + Route::get('accounts', 'AccountApiController@index'); Route::resource('clients', 'ClientApiController'); Route::get('quotes/{client_id?}', 'QuoteApiController@index'); Route::resource('quotes', 'QuoteApiController'); @@ -437,6 +438,7 @@ if (!defined('CONTACT_EMAIL')) { define('TEST_USERNAME', 'user@example.com'); define('TEST_PASSWORD', 'password'); + define('API_SECRET', 'API_SECRET'); define('TOKEN_BILLING_DISABLED', 1); define('TOKEN_BILLING_OPT_IN', 2); diff --git a/app/Models/EntityModel.php b/app/Models/EntityModel.php index 9dd294cacbd8..b8e7d651ada4 100644 --- a/app/Models/EntityModel.php +++ b/app/Models/EntityModel.php @@ -24,7 +24,10 @@ class EntityModel extends Eloquent Utils::fatalError(); } - $lastEntity = $className::withTrashed()->scope(false, $entity->account_id)->orderBy('public_id', 'DESC')->first(); + $lastEntity = $className::withTrashed() + ->scope(false, $entity->account_id) + ->orderBy('public_id', 'DESC') + ->first(); if ($lastEntity) { $entity->public_id = $lastEntity->public_id + 1; diff --git a/app/Ninja/Repositories/AccountRepository.php b/app/Ninja/Repositories/AccountRepository.php index a10ac45a9c67..2441330b9a5f 100644 --- a/app/Ninja/Repositories/AccountRepository.php +++ b/app/Ninja/Repositories/AccountRepository.php @@ -18,6 +18,7 @@ use App\Models\Contact; use App\Models\Account; use App\Models\User; use App\Models\UserAccount; +use App\Models\AccountToken; class AccountRepository { @@ -455,4 +456,14 @@ class AccountRepository return $code; } + + public function createToken($name) + { + $token = AccountToken::createNew(); + $token->name = trim($name) ?: 'TOKEN'; + $token->token = str_random(RANDOM_KEY_LENGTH); + $token->save(); + + return $token->token; + } } diff --git a/app/Ninja/Serializers/ArraySerializer.php b/app/Ninja/Serializers/ArraySerializer.php new file mode 100644 index 000000000000..021ab8128148 --- /dev/null +++ b/app/Ninja/Serializers/ArraySerializer.php @@ -0,0 +1,16 @@ + $data) : $data; + } + + public function item($resourceKey, array $data) + { + return ($resourceKey && $resourceKey !== 'data') ? array($resourceKey => $data) : $data; + } +} diff --git a/app/Ninja/Transformers/AccountTransformer.php b/app/Ninja/Transformers/AccountTransformer.php new file mode 100644 index 000000000000..469365d61d77 --- /dev/null +++ b/app/Ninja/Transformers/AccountTransformer.php @@ -0,0 +1,27 @@ +users; + + return $this->collection($users, new UserTransformer); + } + + public function transform(Account $account) + { + return [ + 'id' => (int) $account->id, + 'name' => $account->name, + ]; + } +} \ No newline at end of file diff --git a/app/Ninja/Transformers/UserTransformer.php b/app/Ninja/Transformers/UserTransformer.php new file mode 100644 index 000000000000..7dbd69dad4d5 --- /dev/null +++ b/app/Ninja/Transformers/UserTransformer.php @@ -0,0 +1,18 @@ + (int) $user->id, + 'first_name' => $user->first_name, + 'last_name' => $user->last_name, + 'email' => $user->email, + ]; + } +} \ No newline at end of file diff --git a/composer.json b/composer.json index a2effe62a122..b6de39bb76dc 100644 --- a/composer.json +++ b/composer.json @@ -39,7 +39,8 @@ "wildbit/laravel-postmark-provider": "dev-master", "Dwolla/omnipay-dwolla": "dev-master", "laravel/socialite": "~2.0", - "simshaun/recurr": "dev-master" + "simshaun/recurr": "dev-master", + "league/fractal": "0.13.*" }, "require-dev": { "phpunit/phpunit": "~4.0", diff --git a/composer.lock b/composer.lock index f32fe591538e..bd15b6e3aa2a 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "c6273849605c03edf4f72bc6b1033658", + "hash": "70ef9e09bca60a19c396c138d8a01d50", "packages": [ { "name": "alfaproject/omnipay-neteller", @@ -2243,6 +2243,69 @@ ], "time": "2015-09-30 22:26:59" }, + { + "name": "league/fractal", + "version": "0.13.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/fractal.git", + "reference": "3caeefbad51bce7a06947321938128512f42346c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/fractal/zipball/3caeefbad51bce7a06947321938128512f42346c", + "reference": "3caeefbad51bce7a06947321938128512f42346c", + "shasum": "" + }, + "require": { + "php": ">=5.4" + }, + "require-dev": { + "illuminate/contracts": "~5.0", + "mockery/mockery": "~0.9", + "pagerfanta/pagerfanta": "~1.0.0", + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "~1.5", + "zendframework/zend-paginator": "~2.3" + }, + "suggest": { + "illuminate/pagination": "The Illuminate Pagination component.", + "pagerfanta/pagerfanta": "Pagerfanta Paginator", + "zendframework/zend-paginator": "Zend Framework Paginator" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.13-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Fractal\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Phil Sturgeon", + "email": "me@philsturgeon.uk", + "homepage": "http://philsturgeon.uk/", + "role": "Developer" + } + ], + "description": "Handle the output of complex data structures ready for API output.", + "homepage": "http://fractal.thephpleague.com/", + "keywords": [ + "api", + "json", + "league", + "rest" + ], + "time": "2015-10-07 14:48:58" + }, { "name": "league/oauth1-client", "version": "1.6.1", diff --git a/config/app.php b/config/app.php index 00fd09f24e75..e5fcf2eebc9a 100644 --- a/config/app.php +++ b/config/app.php @@ -150,6 +150,7 @@ return [ 'Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider', 'Illuminate\Html\HtmlServiceProvider', 'Laravel\Socialite\SocialiteServiceProvider', + /* * Application Service Providers...