From fc5d6a99fe0f7704e041f065a51882a2db28d79c Mon Sep 17 00:00:00 2001 From: David Bomba Date: Sat, 21 Jan 2023 09:59:00 +1100 Subject: [PATCH] add guard to client gateway tokens --- app/Http/Controllers/BaseController.php | 3 +- .../ClientGatewayTokenController.php | 3 +- .../ListClientGatewayTokenRequest.php | 28 ++ tests/Feature/BaseApiTest.php | 314 +++++++++++++++++- 4 files changed, 338 insertions(+), 10 deletions(-) create mode 100644 app/Http/Requests/ClientGatewayToken/ListClientGatewayTokenRequest.php diff --git a/app/Http/Controllers/BaseController.php b/app/Http/Controllers/BaseController.php index 2a5772c0bd8b..3d687333ce81 100644 --- a/app/Http/Controllers/BaseController.php +++ b/app/Http/Controllers/BaseController.php @@ -898,8 +898,7 @@ class BaseController extends Controller elseif(in_array($this->entity_type, [BankTransactionRule::class,CompanyGateway::class, TaxRate::class, BankIntegration::class, Scheduler::class, BankTransaction::class, Webhook::class, ExpenseCategory::class])){ //table without assigned_user_id $query->where('user_id', '=', auth()->user()->id); } - elseif(in_array($this->entity_type,[ClientGatewayToken::class,Design::class,GroupSetting::class,PaymentTerm::class])){ - //need to pass these back regardless + elseif(in_array($this->entity_type,[Design::class, GroupSetting::class, PaymentTerm::class])){ nlog($this->entity_type); } else diff --git a/app/Http/Controllers/ClientGatewayTokenController.php b/app/Http/Controllers/ClientGatewayTokenController.php index 44912c5647a4..84b918c09a49 100644 --- a/app/Http/Controllers/ClientGatewayTokenController.php +++ b/app/Http/Controllers/ClientGatewayTokenController.php @@ -18,6 +18,7 @@ use App\Filters\ClientGatewayTokenFilters; use App\Http\Requests\ClientGatewayToken\CreateClientGatewayTokenRequest; use App\Http\Requests\ClientGatewayToken\DestroyClientGatewayTokenRequest; use App\Http\Requests\ClientGatewayToken\EditClientGatewayTokenRequest; +use App\Http\Requests\ClientGatewayToken\ListClientGatewayTokenRequest; use App\Http\Requests\ClientGatewayToken\ShowClientGatewayTokenRequest; use App\Http\Requests\ClientGatewayToken\StoreClientGatewayTokenRequest; use App\Http\Requests\ClientGatewayToken\UpdateClientGatewayTokenRequest; @@ -103,7 +104,7 @@ class ClientGatewayTokenController extends BaseController * @param ClientGatewayTokenFilters $filters * @return Response|mixed */ - public function index(Request $request) + public function index(ListClientGatewayTokenRequest $request) { $client_gateway_token_gateway_tokens = ClientGatewayToken::scope(); diff --git a/app/Http/Requests/ClientGatewayToken/ListClientGatewayTokenRequest.php b/app/Http/Requests/ClientGatewayToken/ListClientGatewayTokenRequest.php new file mode 100644 index 000000000000..afbfe279e95c --- /dev/null +++ b/app/Http/Requests/ClientGatewayToken/ListClientGatewayTokenRequest.php @@ -0,0 +1,28 @@ +user()->isAdmin(); + } +} diff --git a/tests/Feature/BaseApiTest.php b/tests/Feature/BaseApiTest.php index 03a1425814c1..0323f0f693db 100644 --- a/tests/Feature/BaseApiTest.php +++ b/tests/Feature/BaseApiTest.php @@ -11,11 +11,45 @@ namespace Tests\Feature; +use App\DataMapper\ClientRegistrationFields; +use App\DataMapper\ClientSettings; +use App\DataMapper\CompanySettings; +use App\Factory\ClientGatewayTokenFactory; use App\Factory\CompanyUserFactory; +use App\Factory\WebhookFactory; +use App\Models\BankIntegration; +use App\Models\BankTransaction; +use App\Models\BankTransactionRule; +use App\Models\Client; +use App\Models\ClientContact; +use App\Models\ClientGatewayToken; +use App\Models\Company; +use App\Models\CompanyGateway; use App\Models\CompanyToken; use App\Models\CompanyUser; +use App\Models\Credit; +use App\Models\Document; +use App\Models\Expense; +use App\Models\ExpenseCategory; +use App\Models\GroupSetting; +use App\Models\Invoice; +use App\Models\Payment; use App\Models\Product; +use App\Models\Project; +use App\Models\PurchaseOrder; +use App\Models\Quote; +use App\Models\RecurringExpense; +use App\Models\RecurringInvoice; +use App\Models\RecurringQuote; +use App\Models\Scheduler; +use App\Models\Subscription; +use App\Models\Task; +use App\Models\TaskStatus; +use App\Models\TaxRate; use App\Models\User; +use App\Models\Vendor; +use App\Models\VendorContact; +use App\Models\Webhook; use Illuminate\Routing\Middleware\ThrottleRequests; use Illuminate\Support\Str; use Illuminate\Testing\Fluent\AssertableJson; @@ -62,6 +96,10 @@ class BaseApiTest extends TestCase 'bank_transaction_rules', ]; + private string $low_token; + + private string $owner_token; + protected function setUp() :void { parent::setUp(); @@ -72,13 +110,70 @@ class BaseApiTest extends TestCase ThrottleRequests::class ); + $company = Company::factory()->create([ + 'account_id' => $this->account->id, + ]); + + $this->company = $company; + + $company->client_registration_fields = ClientRegistrationFields::generate(); + $settings = CompanySettings::defaults(); + $settings->company_logo = 'https://pdf.invoicing.co/favicon-v2.png'; + $settings->website = 'www.invoiceninja.com'; + $settings->address1 = 'Address 1'; + $settings->address2 = 'Address 2'; + $settings->city = 'City'; + $settings->state = 'State'; + $settings->postal_code = 'Postal Code'; + $settings->phone = '555-343-2323'; + $settings->email = 'test@example.com'; + $settings->country_id = '840'; + $settings->vat_number = 'vat number'; + $settings->id_number = 'id number'; + $settings->use_credits_payment = 'always'; + $settings->timezone_id = '1'; + $settings->entity_send_time = 0; + $company->track_inventory = true; + $company->settings = $settings; + $company->save(); + + $this->account->default_company_id = $company->id; + $this->account->save(); + + $owner_user = User::factory()->create([ + 'account_id' => $this->account->id, + 'confirmation_code' => $this->createDbHash(config('database.default')), + 'email' => $this->faker->safeEmail(), + ]); + + $this->owner_cu = CompanyUserFactory::create($owner_user->id, $company->id, $this->account->id); + $this->owner_cu->is_owner = true; + $this->owner_cu->is_admin = true; + $this->owner_cu->is_locked = false; + $this->owner_cu->permissions = '[]'; + $this->owner_cu->save(); + + $this->owner_token = \Illuminate\Support\Str::random(64); + + $user_id = $owner_user->id; + + $company_token = new CompanyToken; + $company_token->user_id = $owner_user->id; + $company_token->company_id = $company->id; + $company_token->account_id = $this->account->id; + $company_token->name = 'test token'; + $company_token->token = $this->owner_token; + $company_token->is_system = true; + $company_token->save(); + + $lower_permission_user = User::factory()->create([ 'account_id' => $this->account->id, 'confirmation_code' => $this->createDbHash(config('database.default')), 'email' => $this->faker->safeEmail(), ]); - $this->low_cu = CompanyUserFactory::create($lower_permission_user->id, $this->company->id, $this->account->id); + $this->low_cu = CompanyUserFactory::create($lower_permission_user->id, $company->id, $this->account->id); $this->low_cu->is_owner = false; $this->low_cu->is_admin = false; $this->low_cu->is_locked = false; @@ -96,6 +191,204 @@ class BaseApiTest extends TestCase $company_token->is_system = true; $company_token->save(); + + + Product::factory()->create([ + 'user_id' => $user_id, + 'company_id' => $company->id, + ]); + + $client = Client::factory()->create([ + 'user_id' => $user_id, + 'company_id' => $company->id, + ]); + + + $contact = ClientContact::factory()->create([ + 'user_id' => $user_id, + 'client_id' => $client->id, + 'company_id' => $company->id, + 'is_primary' => 1, + 'send_email' => true, + ]); + + $payment = Payment::factory()->create([ + 'user_id' => $user_id, + 'client_id' => $client->id, + 'company_id' => $company->id, + 'amount' => 10, + ]); + + $contact2 = ClientContact::factory()->create([ + 'user_id' => $user_id, + 'client_id' => $client->id, + 'company_id' => $company->id, + 'send_email' => true, + ]); + + $vendor = Vendor::factory()->create([ + 'user_id' => $user_id, + 'company_id' => $company->id, + 'currency_id' => 1, + ]); + + $vendor_contact = VendorContact::factory()->create([ + 'user_id' => $user_id, + 'vendor_id' => $this->vendor->id, + 'company_id' => $company->id, + 'is_primary' => 1, + 'send_email' => true, + ]); + + $vendor_contact2 = VendorContact::factory()->create([ + 'user_id' => $user_id, + 'vendor_id' => $this->vendor->id, + 'company_id' => $company->id, + 'send_email' => true, + ]); + + $project = Project::factory()->create([ + 'user_id' => $user_id, + 'company_id' => $company->id, + 'client_id' => $client->id, + ]); + + $expense = Expense::factory()->create([ + 'user_id' => $user_id, + 'company_id' => $company->id, + ]); + + $recurring_expense = RecurringExpense::factory()->create([ + 'user_id' => $user_id, + 'company_id' => $company->id, + 'frequency_id' => 5, + 'remaining_cycles' => 5, + ]); + + $recurring_quote = RecurringQuote::factory()->create([ + 'user_id' => $user_id, + 'company_id' => $company->id, + 'client_id' => $client->id, + ]); + + $task = Task::factory()->create([ + 'user_id' => $user_id, + 'company_id' => $company->id, + ]); + + $invoice = Invoice::factory()->create([ + 'user_id' => $user_id, + 'company_id' => $company->id, + 'client_id' => $client->id, + ]); + + $quote = Quote::factory()->create([ + 'user_id' => $user_id, + 'company_id' => $company->id, + 'client_id' => $client->id, + ]); + + $credit = Credit::factory()->create([ + 'user_id' => $user_id, + 'company_id' => $company->id, + 'client_id' => $client->id, + ]); + + $po = PurchaseOrder::factory()->create([ + 'user_id' => $user_id, + 'company_id' => $company->id, + 'vendor_id' => $vendor->id, + ]); + + + $recurring_invoice = RecurringInvoice::factory()->create([ + 'user_id' => $user_id, + 'company_id' => $company->id, + 'client_id' => $client->id, + ]); + + + $task_status = TaskStatus::factory()->create([ + 'user_id' => $user_id, + 'company_id' => $company->id, + ]); + + $task->status_id = TaskStatus::where('company_id', $company->id)->first()->id; + $task->save(); + + $expense_category = ExpenseCategory::factory()->create([ + 'user_id' => $user_id, + 'company_id' => $company->id, + ]); + + + $tax_rate = TaxRate::factory()->create([ + 'user_id' => $user_id, + 'company_id' => $company->id, + ]); + + $gs = new GroupSetting; + $gs->name = 'Test'; + $gs->company_id = $client->company_id; + $gs->settings = ClientSettings::buildClientSettings($company->settings, $client->settings); + + $gs_settings = $gs->settings; + $gs_settings->website = 'http://staging.invoicing.co'; + $gs->settings = $gs_settings; + $gs->save(); + + $scheduler = Scheduler::factory()->create([ + 'user_id' => $user_id, + 'company_id' => $company->id, + ]); + + $bank_integration = BankIntegration::factory()->create([ + 'user_id' => $user_id, + 'company_id' => $company->id, + 'account_id' => $this->account->id, + ]); + + $bank_transaction = BankTransaction::factory()->create([ + 'user_id' => $user_id, + 'company_id' => $company->id, + 'bank_integration_id' => $bank_integration->id, + ]); + + $bank_transaction_rule = BankTransactionRule::factory()->create([ + 'user_id' => $user_id, + 'company_id' => $company->id, + ]); + + + $subscription = Subscription::factory()->create([ + 'user_id' => $user_id, + 'company_id' => $company->id, + ]); + + $webhook = WebhookFactory::create($company->id, $user_id); + $webhook->save(); + + $document = Document::factory()->create([ + 'user_id' => $user_id, + 'company_id' => $company->id, + ]); + + $cg = new CompanyGateway; + $cg->company_id = $company->id; + $cg->user_id = $user_id; + $cg->gateway_key = 'd14dd26a37cecc30fdd65700bfb55b23'; + $cg->require_cvv = true; + $cg->require_billing_address = true; + $cg->require_shipping_address = true; + $cg->update_details = true; + $cg->config = encrypt(config('ninja.testvars.stripe')); + $cg->fees_and_limits = []; + $cg->save(); + + $cgt = ClientGatewayTokenFactory::create($company->id); + $cgt->save(); + + } // public function testGeneratingClassName() @@ -113,22 +406,24 @@ class BaseApiTest extends TestCase $response = $this->withHeaders([ 'X-API-SECRET' => config('ninja.api_secret'), - 'X-API-TOKEN' => $this->token, + 'X-API-TOKEN' => $this->owner_token, ])->get('/api/v1/users/'); $response->assertStatus(200) ->assertJson(fn (AssertableJson $json) => $json->has('data',2)->etc()); /*does not test the number of records however*/ - collect($this->list_routes)->each(function($route){ + collect($this->list_routes)->filter(function ($route){ + return !in_array($route, ['users','designs','payment_terms']); + })->each(function($route){ nlog($route); $response = $this->withHeaders([ 'X-API-SECRET' => config('ninja.api_secret'), - 'X-API-TOKEN' => $this->low_token, + 'X-API-TOKEN' => $this->owner_token, ])->get("/api/v1/{$route}/") ->assertJson(fn (AssertableJson $json) => $json->has('meta') - ->has('data') + ->has('data',1) ); }); @@ -185,7 +480,7 @@ class BaseApiTest extends TestCase collect($this->list_routes)->filter(function ($route){ - return !in_array($route, ['tasks','users','group_settings','designs']); + return !in_array($route, ['tasks', 'users', 'group_settings','designs','client_gateway_tokens']); })->each(function($route){ // nlog($route); $response = $this->withHeaders([ @@ -205,7 +500,12 @@ class BaseApiTest extends TestCase ])->get('/api/v1/companies/'.$this->company->hashed_id) ->assertStatus(401); - + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->low_token, + ])->get('/api/v1/client_gateway_tokens/') + ->assertStatus(401); + } }