From 63058d8c8edfb8ed8a5e501aff3df98d9f6e3c2c Mon Sep 17 00:00:00 2001 From: Dane Everitt Date: Fri, 14 Oct 2016 16:20:24 -0400 Subject: [PATCH] Super early base implementation of notifications from daemon --- .../Controllers/Remote/RemoteController.php | 26 ++++++++ app/Http/Routes/RemoteRoutes.php | 5 ++ app/Services/NotificationService.php | 64 +++++++++++++++++++ 3 files changed, 95 insertions(+) create mode 100644 app/Services/NotificationService.php diff --git a/app/Http/Controllers/Remote/RemoteController.php b/app/Http/Controllers/Remote/RemoteController.php index ccbfdf445..ee1b86b4c 100644 --- a/app/Http/Controllers/Remote/RemoteController.php +++ b/app/Http/Controllers/Remote/RemoteController.php @@ -25,6 +25,7 @@ namespace Pterodactyl\Http\Controllers\Remote; use Pterodactyl\Models; use Pterodactyl\Exceptions\DisplayException; +use Pterodactyl\Services\NotificationService; use Pterodactyl\Http\Controllers\Controller; use Illuminate\Http\Request; @@ -82,4 +83,29 @@ class RemoteController extends Controller ], 200); } + public function event(Request $request) + { + $server = Models\Server::where('uuid', $request->input('server'))->first(); + if (!$server) { + return response()->json([ + 'error' => 'No server by that ID was found on the system.' + ], 422); + } + + $node = Models\Node::findOrFail($server->node); + + $hmac = $request->input('signed'); + if (base64_decode($hmac) !== hash_hmac('sha256', $server->uuid, $node->daemonSecret, true)) { + return response()->json([ + 'error' => 'Signed HMAC was invalid.' + ], 403); + } + + // Passes Validation, Setup Notifications + $notify = new NotificationService($server); + $notify->pass($request->input('notification')); + + return response('', 201); + } + } diff --git a/app/Http/Routes/RemoteRoutes.php b/app/Http/Routes/RemoteRoutes.php index 713d31c0f..802f1d923 100644 --- a/app/Http/Routes/RemoteRoutes.php +++ b/app/Http/Routes/RemoteRoutes.php @@ -40,6 +40,11 @@ class RemoteRoutes { 'as' => 'remote.install', 'uses' => 'Remote\RemoteController@postInstall' ]); + + $router->post('event', [ + 'as' => 'remote.event', + 'uses' => 'Remote\RemoteController@event' + ]); }); } diff --git a/app/Services/NotificationService.php b/app/Services/NotificationService.php new file mode 100644 index 000000000..b98bd0642 --- /dev/null +++ b/app/Services/NotificationService.php @@ -0,0 +1,64 @@ + + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +namespace Pterodactyl\Services; + +use Pterodactyl\Models\Server; +use Pterodactyl\Models\User; + +use Pterodactyl\Notifications\Daemon; + +class NotificationService { + + protected $server; + + protected $user; + + /** + * Daemon will pass an event name, this matches that event name with the notification to send. + * @var array + */ + protected $types = [ + // 'crashed' => 'CrashNotification', + // 'started' => 'StartNotification', + // 'stopped' => 'StopNotification', + // 'rebuild' => 'RebuildNotification' + ]; + + public function __construct(Server $server) + { + $this->server = $server; + $this->user = User::findOrFail($server->owner); + } + + public function pass(array $notification) + { + if (!$notification->type) { + return; + } + + if (class_exists($this->types[$notification->event]::class)) { + $user->notify(new $this->types[$notification->type]($notification->event)); + } + } +}