From 1556980686109aff3c52938681e8d9cdec139bb3 Mon Sep 17 00:00:00 2001 From: Andy Ford Date: Sun, 27 Jan 2019 20:46:17 +0000 Subject: [PATCH 01/10] Add Plugin Errors Table --- ...1_27_203429_create_plugin_errors_table.php | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 database/migrations/2019_01_27_203429_create_plugin_errors_table.php diff --git a/database/migrations/2019_01_27_203429_create_plugin_errors_table.php b/database/migrations/2019_01_27_203429_create_plugin_errors_table.php new file mode 100644 index 000000000..66c011bf2 --- /dev/null +++ b/database/migrations/2019_01_27_203429_create_plugin_errors_table.php @@ -0,0 +1,37 @@ +increments('id'); + $table->unsignedInteger('user_id')->comment('The user who the report is attributed to'); + $table->boolean('user_report')->comment('Whether the report was generated by the user or the plugin'); + $table->json('data')->comment('Report data'); + $table->timestamps(); + + $table->foreign('user_id') + ->references('id')->on('user'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('plugin_error'); + } +} From e4f7b84578802418149b1adc56aa6ce3468e372c Mon Sep 17 00:00:00 2001 From: Andy Ford Date: Sun, 27 Jan 2019 20:49:55 +0000 Subject: [PATCH 02/10] Add Model For Plugin Errors --- app/Models/PluginError/PluginError.php | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 app/Models/PluginError/PluginError.php diff --git a/app/Models/PluginError/PluginError.php b/app/Models/PluginError/PluginError.php new file mode 100644 index 000000000..ad8c60bef --- /dev/null +++ b/app/Models/PluginError/PluginError.php @@ -0,0 +1,23 @@ + Date: Sun, 27 Jan 2019 21:48:51 +0000 Subject: [PATCH 03/10] PSR --- app/Http/Controllers/PluginErrorController.php | 10 ++++++++++ app/Models/PluginError/PluginError.php | 2 +- .../Controllers/PluginErrorControllerTest.php | 15 +++++++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 app/Http/Controllers/PluginErrorController.php create mode 100644 tests/app/Http/Controllers/PluginErrorControllerTest.php diff --git a/app/Http/Controllers/PluginErrorController.php b/app/Http/Controllers/PluginErrorController.php new file mode 100644 index 000000000..267f6f724 --- /dev/null +++ b/app/Http/Controllers/PluginErrorController.php @@ -0,0 +1,10 @@ + Date: Sun, 27 Jan 2019 21:49:12 +0000 Subject: [PATCH 04/10] Add Route For Logging Plugin Errors --- .../Controllers/PluginErrorController.php | 35 +++++- routes/routes.php | 3 + .../Controllers/PluginErrorControllerTest.php | 102 ++++++++++++++++-- 3 files changed, 131 insertions(+), 9 deletions(-) diff --git a/app/Http/Controllers/PluginErrorController.php b/app/Http/Controllers/PluginErrorController.php index 267f6f724..5948147c8 100644 --- a/app/Http/Controllers/PluginErrorController.php +++ b/app/Http/Controllers/PluginErrorController.php @@ -1,10 +1,41 @@ checkForSuppliedData( + $request, + [ + 'user_report' => 'required|boolean', + 'data' => 'required|array', + ] + ); + + if ($dataCheck) { + return response(null, 400); + } + + PluginError::create( + [ + 'user_id' => Auth::user()->id, + 'user_report' => $request->json('user_report'), + 'data' => json_encode($request->json('data')), + ] + ); + return response('', 204); + } } diff --git a/routes/routes.php b/routes/routes.php index 5448f1ccb..d025b9591 100644 --- a/routes/routes.php +++ b/routes/routes.php @@ -37,6 +37,9 @@ // Regional Pressure $router->get('regional-pressure', 'RegionalPressureController@getRegionalPressures'); + + // Plugin Errors + $router->post('plugin-error', 'PluginErrorController@recordPluginError'); }); // Routes for user administration diff --git a/tests/app/Http/Controllers/PluginErrorControllerTest.php b/tests/app/Http/Controllers/PluginErrorControllerTest.php index 316c3bc5f..afc71cdbd 100644 --- a/tests/app/Http/Controllers/PluginErrorControllerTest.php +++ b/tests/app/Http/Controllers/PluginErrorControllerTest.php @@ -1,15 +1,103 @@ assertInstanceOf(PluginErrorController::class, $this->app->make(PluginErrorController::class)); + } + public function testItReturns400OnMissingUserReport() + { + $this->makeAuthenticatedApiRequest( + self::METHOD_POST, + 'plugin-error', + [ + 'data' => [ + 'foo' => 'bar' + ], + ] + )->seeStatusCode(400); + } + + public function testItReturns400OnMissingData() + { + $this->makeAuthenticatedApiRequest( + self::METHOD_POST, + 'plugin-error', + [ + 'user_report' => true, + ] + )->seeStatusCode(400); + } + + public function testItReturnsNoContentOnSuccess() + { + $this->makeAuthenticatedApiRequest( + self::METHOD_POST, + 'plugin-error', + [ + 'user_report' => true, + 'data' => [ + 'foo' => 'bar', + 'baz' => [ + 'foo' => 'bar', + ] + ], + ] + )->seeStatusCode(204); + } + + public function testItStoresUserReports() + { + $data = [ + 'baz' => [ + 'foo' => 'bar', + ], + 'foo' => 'bar', + ]; + + $this->makeAuthenticatedApiRequest( + self::METHOD_POST, + 'plugin-error', + [ + 'user_report' => true, + 'data' => $data + ] + ); + + $pluginError = PluginError::orderBy('created_at', 'desc')->first(); + $this->assertEquals(self::ACTIVE_USER_CID, $pluginError->user_id); + $this->assertEquals(1, $pluginError->user_report); + $this->assertEquals($data, json_decode($pluginError->data, true)); + } + + public function testItStoresNonUserReports() + { + $data = [ + 'baz' => [ + 'foo' => 'bar', + ], + 'foo' => 'bar', + ]; + + $this->makeAuthenticatedApiRequest( + self::METHOD_POST, + 'plugin-error', + [ + 'user_report' => false, + 'data' => $data + ] + ); + + $pluginError = PluginError::orderBy('created_at', 'desc')->first(); + $this->assertEquals(self::ACTIVE_USER_CID, $pluginError->user_id); + $this->assertEquals(0, $pluginError->user_report); + $this->assertEquals($data, json_decode($pluginError->data, true)); + } } From bee1ef27854ebb25ade2063b132d3d2731ac68b0 Mon Sep 17 00:00:00 2001 From: Andy Ford Date: Sun, 27 Jan 2019 21:51:55 +0000 Subject: [PATCH 05/10] Style --- routes/routes.php | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/routes/routes.php b/routes/routes.php index d025b9591..e7038145d 100644 --- a/routes/routes.php +++ b/routes/routes.php @@ -15,7 +15,7 @@ 'uses' => 'TeapotController@teapot', ] ); - + // Version checking $router->get( 'version/{version:[A-Za-z0-9\.\-]+}/status', @@ -26,15 +26,15 @@ 'uses' => 'VersionController@getVersionStatus' ] ); - + // Dependencies $router->get('dependency', 'DependencyController@getManifest'); - + // Squawks $router->get('squawk-assignment/{callsign:[A-Za-z0-9\-]{1,10}}', 'SquawkController@getSquawkAssignment'); $router->put('squawk-assignment/{callsign:[A-Za-z0-9\-]{1,10}}', 'SquawkController@assignSquawk'); $router->delete('squawk-assignment/{callsign:[A-Za-z0-9\-]{1,10}}', 'SquawkController@deleteSquawkAssignment'); - + // Regional Pressure $router->get('regional-pressure', 'RegionalPressureController@getRegionalPressures'); @@ -114,13 +114,13 @@ // Routes for user administration $router->group(['middleware' => 'scopes:' . AuthServiceProvider::SCOPE_VERSION_ADMIN], function () use ($router) { - // A test route for useradmin access - $router->get('versionadmin', 'TeapotController@teapot'); + // A test route for useradmin access + $router->get('versionadmin', 'TeapotController@teapot'); - // Routes for returning information about versions - $router->get('version', 'VersionController@getAllVersions'); - $router->get('version/{version:[A-Za-z0-9\.\-]+}', 'VersionController@getVersion'); + // Routes for returning information about versions + $router->get('version', 'VersionController@getAllVersions'); + $router->get('version/{version:[A-Za-z0-9\.\-]+}', 'VersionController@getVersion'); - // Route for updating and creating versions - $router->put('version/{version:[A-Za-z0-9\.\-]+}', 'VersionController@createOrUpdateVersion'); + // Route for updating and creating versions + $router->put('version/{version:[A-Za-z0-9\.\-]+}', 'VersionController@createOrUpdateVersion'); }); From 01435b5f98b5211f2cc86c697aca18980c4cc1c6 Mon Sep 17 00:00:00 2001 From: Andy Ford Date: Sun, 27 Jan 2019 21:52:58 +0000 Subject: [PATCH 06/10] Null On No Body Response --- app/Http/Controllers/PluginErrorController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Http/Controllers/PluginErrorController.php b/app/Http/Controllers/PluginErrorController.php index 5948147c8..42db41f62 100644 --- a/app/Http/Controllers/PluginErrorController.php +++ b/app/Http/Controllers/PluginErrorController.php @@ -36,6 +36,6 @@ public function recordPluginError(Request $request) : Response ] ); - return response('', 204); + return response(null, 204); } } From 5e3b184adf4a5cf805df25265b085bb59dfcaccd Mon Sep 17 00:00:00 2001 From: Andy Ford Date: Sun, 27 Jan 2019 22:20:03 +0000 Subject: [PATCH 07/10] Add Custom Exception For Plugin Errors --- app/Exceptions/PluginErrorException.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 app/Exceptions/PluginErrorException.php diff --git a/app/Exceptions/PluginErrorException.php b/app/Exceptions/PluginErrorException.php new file mode 100644 index 000000000..c49bb0977 --- /dev/null +++ b/app/Exceptions/PluginErrorException.php @@ -0,0 +1,15 @@ + Date: Sun, 27 Jan 2019 22:20:32 +0000 Subject: [PATCH 08/10] Add Event For Plugin Error Recieved --- app/Events/PluginErrorReceivedEvent.php | 26 +++++++++++++++++++ .../Events/PluginErrorReceivedEventTest.php | 21 +++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 app/Events/PluginErrorReceivedEvent.php create mode 100644 tests/app/Events/PluginErrorReceivedEventTest.php diff --git a/app/Events/PluginErrorReceivedEvent.php b/app/Events/PluginErrorReceivedEvent.php new file mode 100644 index 000000000..31f72ba3c --- /dev/null +++ b/app/Events/PluginErrorReceivedEvent.php @@ -0,0 +1,26 @@ +error = $error; + } + + /** + * @return PluginError + */ + public function getError(): PluginError + { + return $this->error; + } +} diff --git a/tests/app/Events/PluginErrorReceivedEventTest.php b/tests/app/Events/PluginErrorReceivedEventTest.php new file mode 100644 index 000000000..136c0cc16 --- /dev/null +++ b/tests/app/Events/PluginErrorReceivedEventTest.php @@ -0,0 +1,21 @@ +assertInstanceOf(PluginErrorReceivedEvent::class, new PluginErrorReceivedEvent(new PluginError)); + } + + public function testItCanReturnTheError() + { + $error = new PluginError; + $event = new PluginErrorReceivedEvent($error); + $this->assertEquals($error, $event->getError()); + } +} From 2667063a1810d5c827a4aaf9e3567492286fcc78 Mon Sep 17 00:00:00 2001 From: Andy Ford Date: Sun, 27 Jan 2019 22:20:42 +0000 Subject: [PATCH 09/10] Add Listener For PluginErrorRecievedEvents --- .../Controllers/PluginErrorController.php | 7 ++++-- .../RecordPluginErrorInBugsnag.php | 25 +++++++++++++++++++ .../RecordPluginErrorInBugsnagTest.php | 22 ++++++++++++++++ 3 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 app/Listeners/PluginError/RecordPluginErrorInBugsnag.php create mode 100644 tests/app/Listeners/PluginError/RecordPluginErrorInBugsnagTest.php diff --git a/app/Http/Controllers/PluginErrorController.php b/app/Http/Controllers/PluginErrorController.php index 42db41f62..7b0a7c03f 100644 --- a/app/Http/Controllers/PluginErrorController.php +++ b/app/Http/Controllers/PluginErrorController.php @@ -2,10 +2,12 @@ namespace App\Http\Controllers; +use App\Events\PluginErrorReceivedEvent; use App\Models\PluginError\PluginError; use Illuminate\Http\Request; use Illuminate\Http\Response; use Illuminate\Support\Facades\Auth; +use Illuminate\Support\Facades\Event; class PluginErrorController extends BaseController { @@ -28,7 +30,7 @@ public function recordPluginError(Request $request) : Response return response(null, 400); } - PluginError::create( + $pluginError = PluginError::create( [ 'user_id' => Auth::user()->id, 'user_report' => $request->json('user_report'), @@ -36,6 +38,7 @@ public function recordPluginError(Request $request) : Response ] ); - return response(null, 204); + Event::fire(new PluginErrorReceivedEvent($pluginError)); + return response('', 204); } } diff --git a/app/Listeners/PluginError/RecordPluginErrorInBugsnag.php b/app/Listeners/PluginError/RecordPluginErrorInBugsnag.php new file mode 100644 index 000000000..94897c990 --- /dev/null +++ b/app/Listeners/PluginError/RecordPluginErrorInBugsnag.php @@ -0,0 +1,25 @@ +assertInstanceOf(RecordPluginErrorInBugsnag::class, $listener); + } + + public function testItStopsEventPropagation() + { + $listener = new RecordPluginErrorInBugsnag(); + $this->assertFalse($listener->handle(new PluginErrorReceivedEvent(new PluginError))); + } +} From 419fe20a3e893d818636834f9c828121344c16ff Mon Sep 17 00:00:00 2001 From: Andy Ford Date: Sun, 27 Jan 2019 22:21:35 +0000 Subject: [PATCH 10/10] Style --- app/Exceptions/PluginErrorException.php | 1 - app/Listeners/PluginError/RecordPluginErrorInBugsnag.php | 2 -- 2 files changed, 3 deletions(-) diff --git a/app/Exceptions/PluginErrorException.php b/app/Exceptions/PluginErrorException.php index c49bb0977..b042b431d 100644 --- a/app/Exceptions/PluginErrorException.php +++ b/app/Exceptions/PluginErrorException.php @@ -11,5 +11,4 @@ */ class PluginErrorException extends Exception { - } diff --git a/app/Listeners/PluginError/RecordPluginErrorInBugsnag.php b/app/Listeners/PluginError/RecordPluginErrorInBugsnag.php index 94897c990..433266fdb 100644 --- a/app/Listeners/PluginError/RecordPluginErrorInBugsnag.php +++ b/app/Listeners/PluginError/RecordPluginErrorInBugsnag.php @@ -3,11 +3,9 @@ namespace App\Listeners\PluginError; - use App\Events\PluginErrorReceivedEvent; use App\Exceptions\PluginErrorException; use Bugsnag\BugsnagLaravel\Facades\Bugsnag; -use Illuminate\Support\Facades\Log; class RecordPluginErrorInBugsnag {