diff --git a/app/Exceptions/Handler.php b/app/Exceptions/Handler.php index bab6ef3e1..b3aefd1cd 100644 --- a/app/Exceptions/Handler.php +++ b/app/Exceptions/Handler.php @@ -46,10 +46,19 @@ class Handler extends ExceptionHandler */ public function render($request, Exception $exception) { - if ($request->expectsJson()) { + if ($request->expectsJson() || $request->isJson() || $request->is('api/*', 'remote/*', 'daemon/*')) { + + if (config('app.debug')) { + $report = [ + 'code' => (! $this->isHttpException($exception)) ?: $exception->getStatusCode(), + 'message' => class_basename($exception) . ' in ' . $exception->getFile() . ' on line ' . $exception->getLine(), + ]; + } + $response = response()->json([ - 'error' => ($exception instanceof DisplayException) ? $exception->getMessage() : 'An unhandled error occured while attempting to process this request.', - ], ($this->isHttpException($exception)) ? $exception->getStatusCode() : 500); + 'error' => $exception->getMessage(), + 'exception' => ! isset($report) ?: $report, + ], ($this->isHttpException($exception)) ? $exception->getStatusCode() : 500, [], JSON_UNESCAPED_SLASHES); parent::report($exception); } diff --git a/app/Http/Controllers/API/User/CoreController.php b/app/Http/Controllers/API/User/CoreController.php new file mode 100644 index 000000000..be9ce30ab --- /dev/null +++ b/app/Http/Controllers/API/User/CoreController.php @@ -0,0 +1,36 @@ +. + * + * 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\Http\Controllers\API\User; + +use Illuminate\Http\Request; +use Pterodactyl\Http\Controllers\Controller; + +class CoreController extends Controller +{ + public function index(Request $request) + { + dd($request->user()); + } +} diff --git a/app/Http/Controllers/API/BaseController.php b/app/Http/Controllers/API_old/BaseController.php similarity index 100% rename from app/Http/Controllers/API/BaseController.php rename to app/Http/Controllers/API_old/BaseController.php diff --git a/app/Http/Controllers/API/LocationController.php b/app/Http/Controllers/API_old/LocationController.php similarity index 100% rename from app/Http/Controllers/API/LocationController.php rename to app/Http/Controllers/API_old/LocationController.php diff --git a/app/Http/Controllers/API/NodeController.php b/app/Http/Controllers/API_old/NodeController.php similarity index 100% rename from app/Http/Controllers/API/NodeController.php rename to app/Http/Controllers/API_old/NodeController.php diff --git a/app/Http/Controllers/API/ServerController.php b/app/Http/Controllers/API_old/ServerController.php similarity index 100% rename from app/Http/Controllers/API/ServerController.php rename to app/Http/Controllers/API_old/ServerController.php diff --git a/app/Http/Controllers/API/ServiceController.php b/app/Http/Controllers/API_old/ServiceController.php similarity index 100% rename from app/Http/Controllers/API/ServiceController.php rename to app/Http/Controllers/API_old/ServiceController.php diff --git a/app/Http/Controllers/API/User/InfoController.php b/app/Http/Controllers/API_old/User/InfoController.php similarity index 100% rename from app/Http/Controllers/API/User/InfoController.php rename to app/Http/Controllers/API_old/User/InfoController.php diff --git a/app/Http/Controllers/API/User/ServerController.php b/app/Http/Controllers/API_old/User/ServerController.php similarity index 100% rename from app/Http/Controllers/API/User/ServerController.php rename to app/Http/Controllers/API_old/User/ServerController.php diff --git a/app/Http/Controllers/API/UserController.php b/app/Http/Controllers/API_old/UserController.php similarity index 100% rename from app/Http/Controllers/API/UserController.php rename to app/Http/Controllers/API_old/UserController.php diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index 845e14aab..a70895a3e 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -39,6 +39,7 @@ class Kernel extends HttpKernel \Pterodactyl\Http\Middleware\LanguageMiddleware::class, ], 'api' => [ + \Pterodactyl\Http\Middleware\HMACAuthorization::class, 'throttle:60,1', 'bindings', ], diff --git a/app/Http/Middleware/HMACAuthorization.php b/app/Http/Middleware/HMACAuthorization.php new file mode 100644 index 000000000..46f19c363 --- /dev/null +++ b/app/Http/Middleware/HMACAuthorization.php @@ -0,0 +1,242 @@ +. + * + * 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\Http\Middleware; + +use Auth; +use Crypt; +use Config; +use Closure; +use Response; +use IPTools\IP; +use IPTools\Range; +use Illuminate\Http\Request; +use Pterodactyl\Models\APIKey; +use Pterodactyl\Models\APIPermission; +use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; // 400 +use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; // 403 + +class HMACAuthorization +{ + /** + * The algorithm to use for handling HMAC encryption. + * + * @var string + */ + const HMAC_ALGORITHM = 'sha256'; + + /** + * Stored values from the Authorization header. + * + * @var array + */ + protected $token = []; + + /** + * The eloquent model for the API key. + * + * @var \Pterodactyl\Models\APIKey + */ + protected $key; + + /** + * The illuminate request object. + * + * @var \Illuminate\Http\Request + */ + private $request; + + /** + * Construct class instance. + * + * @return void + */ + public function __construct() + { + Config::set('session.driver', 'array'); + } + + /** + * Handle an incoming request for the API. + * + * @param \Illuminate\Http\Request $request + * @param \Closure $next + * @return mixed + */ + public function handle(Request $request, Closure $next) + { + $this->request = $request; + + $this->checkBearer(); + $this->validateRequest(); + $this->validateContents(); + + Auth::loginUsingId($this->key()->user_id); + + return $next($request); + } + + /** + * Checks that the Bearer token is provided and in a valid format. + * + * @return void + * + * @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException + */ + protected function checkBearer() + { + if (empty($this->request()->bearerToken())) { + throw new BadRequestHttpException('Request was missing required Authorization header.'); + } + + $token = explode('.', $this->request()->bearerToken()); + if (count($token) !== 2) { + throw new BadRequestHttpException('The Authorization header passed was not in a validate public/private key format.'); + } + + $this->token = [ + 'public' => $token[0], + 'hash' => $token[1], + ]; + } + + /** + * Determine if the request contains a valid public API key + * as well as permissions for the resource. + * + * @return void + * + * @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException + */ + protected function validateRequest() + { + $this->key = APIKey::where('public', $this->public())->first(); + if (! $this->key) { + throw new AccessDeniedHttpException('Unable to identify requester. Authorization token is invalid.'); + } + + if (empty($this->request()->route()->getName())) { + throw new \Exception('Attempting to access un-named route. This should not be possible.'); + } + + $this->validateIPAccess(); + + $query = APIPermission::where('key_id', $this->key()->id) + ->where('permission', $this->request()->route()->getName()); + + if (starts_with($this->request()->route()->getName(), 'api.user')) { + $query->orWhere('permission', 'api.user.*'); + } + + if (! $query->first()) { + throw new AccessDeniedHttpException('You do not have permission to access this resource on the API.'); + } + } + + /** + * Determine if the requesting IP address is allowed to use this API key. + * + * @return bool + * + * @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException + */ + protected function validateIPAccess() + { + if (! is_null($this->key()->allowed_ips)) { + foreach($this->key()->allowed_ips as $ip) { + if (Range::parse($ip)->contains(new IP($this->request()->ip()))) { + return true; + } + } + + throw new AccessDeniedHttpException('This IP address does not have permission to access the API using these credentials.'); + } + + return true; + } + + /** + * Determine if the HMAC sent in the request matches the one generated + * on the panel side. + * + * @return void + * + * @throws \Symfony\Component\HttpKernel\Exception\BadRequestHttpException + */ + protected function validateContents() + { + if (base64_decode($this->hash()) !== $this->generateSignature()) { + throw new BadRequestHttpException('The HMAC for the request was invalid.'); + } + } + + /** + * Generate a HMAC from the request and known API secret key. + * + * @return string + */ + protected function generateSignature() + { + $content = urldecode($this->request()->url()) . $this->request()->getContent(); + + return hash_hmac(self::HMAC_ALGORITHM, $content, Crypt::decrypt($this->key()->secret), true); + } + + /** + * Return the public key passed in the Authorization header. + * + * @return string + */ + protected function public() { + return $this->token['public']; + } + + /** + * Return the base64'd HMAC sent in the Authorization header. + * + * @return string + */ + protected function hash() { + return $this->token['hash']; + } + + /** + * Return the API Key model. + * + * @return \Pterodactyl\Models\APIKey + */ + protected function key() { + return $this->key; + } + + /** + * Return the Illuminate Request object. + * + * @return \Illuminate\Http\Request + */ + private function request() + { + return $this->request; + } +} diff --git a/app/Models/APIKey.php b/app/Models/APIKey.php index 68e481712..f560fda85 100644 --- a/app/Models/APIKey.php +++ b/app/Models/APIKey.php @@ -42,6 +42,15 @@ class APIKey extends Model */ protected $hidden = ['secret']; + /** + * Cast values to correct type. + * + * @var array + */ + protected $casts = [ + 'allowed_ips' => 'json', + ]; + /** * Fields that are not mass assignable. * diff --git a/app/Providers/RouteServiceProvider.php b/app/Providers/RouteServiceProvider.php index 0aa015828..d129489af 100644 --- a/app/Providers/RouteServiceProvider.php +++ b/app/Providers/RouteServiceProvider.php @@ -33,6 +33,14 @@ class RouteServiceProvider extends ServiceProvider */ public function map() { + Route::middleware(['api'])->prefix('/api/user') + ->namespace($this->namespace . '\API\User') + ->group(base_path('routes/api.php')); + + Route::middleware(['api'])->prefix('/api/admin') + ->namespace($this->namespace . '\API\Admin') + ->group(base_path('routes/api-admin.php')); + Route::middleware(['web', 'auth', 'csrf']) ->namespace($this->namespace . '\Base') ->group(base_path('routes/base.php')); diff --git a/composer.json b/composer.json index b0fcb26cc..ef76b71b0 100644 --- a/composer.json +++ b/composer.json @@ -12,26 +12,26 @@ ], "require": { "php": ">=7.0.0", - "laravel/framework": "5.4.16", - "laravel/tinker": "1.0.0", + "aws/aws-sdk-php": "3.25.1", "barryvdh/laravel-debugbar": "2.3.2", "doctrine/dbal": "2.5.12", + "edvinaskrucas/settings": "2.0.0", + "fideloper/proxy": "3.3.0", "guzzlehttp/guzzle": "6.2.3", + "igaster/laravel-theme": "1.14.0", + "laracasts/utilities": "2.1.0", + "laravel/framework": "5.4.16", + "laravel/tinker": "1.0.0", + "lord/laroute": "2.4.4", + "mtdowling/cron-expression": "1.2.0", + "nesbot/carbon": "1.22.1", + "nicolaslopezj/searchable": "1.9.5", "pragmarx/google2fa": "1.0.1", - "webpatser/laravel-uuid": "2.0.1", + "predis/predis": "1.1.1", "prologue/alerts": "0.4.1", "s1lentium/iptools": "1.1.0", - "edvinaskrucas/settings": "2.0.0", - "igaster/laravel-theme": "1.14.0", - "nesbot/carbon": "1.22.1", - "mtdowling/cron-expression": "1.2.0", - "dingo/api": "1.0.0-beta8", - "aws/aws-sdk-php": "3.25.1", - "predis/predis": "1.1.1", - "fideloper/proxy": "3.3.0", - "laracasts/utilities": "2.1.0", - "lord/laroute": "2.4.4", - "nicolaslopezj/searchable": "1.9.5" + "spatie/laravel-fractal": "3.5.0", + "webpatser/laravel-uuid": "2.0.1" }, "require-dev": { "fzaninotto/faker": "~1.4", diff --git a/composer.lock b/composer.lock index f4dcae4a8..4ce9d4ee0 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "5f54adee49654a63977f6c5593e5e1a8", - "content-hash": "081359d468db67f98d08ff1f304ea712", + "hash": "ae03837be570fb8ebf2a916a50614193", + "content-hash": "d4eb663cbd7d79c85e06d626b64cdbcd", "packages": [ { "name": "aws/aws-sdk-php", @@ -195,136 +195,6 @@ ], "time": "2016-05-05 11:49:03" }, - { - "name": "dingo/api", - "version": "v1.0.0-beta8", - "source": { - "type": "git", - "url": "https://github.com/dingo/api.git", - "reference": "46cffad61942caa094dd876155e503b6819c5095" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/dingo/api/zipball/46cffad61942caa094dd876155e503b6819c5095", - "reference": "46cffad61942caa094dd876155e503b6819c5095", - "shasum": "" - }, - "require": { - "dingo/blueprint": "0.2.*", - "illuminate/routing": "^5.1", - "illuminate/support": "^5.1", - "league/fractal": ">=0.12.0", - "php": "^5.5.9 || ^7.0" - }, - "require-dev": { - "illuminate/auth": "^5.1", - "illuminate/cache": "^5.1", - "illuminate/console": "^5.1", - "illuminate/database": "^5.1", - "illuminate/events": "^5.1", - "illuminate/filesystem": "^5.1", - "illuminate/log": "^5.1", - "illuminate/pagination": "^5.1", - "laravel/lumen-framework": "5.1.* || 5.2.*", - "lucadegasperi/oauth2-server-laravel": "5.0.*", - "mockery/mockery": "~0.9", - "phpunit/phpunit": "^4.8 || ^5.0", - "squizlabs/php_codesniffer": "~2.0", - "tymon/jwt-auth": "1.0.*" - }, - "suggest": { - "lucadegasperi/oauth2-server-laravel": "Protect your API with OAuth 2.0.", - "tymon/jwt-auth": "Protect your API with JSON Web Tokens." - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "psr-4": { - "Dingo\\Api\\": "src/" - }, - "files": [ - "src/helpers.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Jason Lewis", - "email": "jason.lewis1991@gmail.com" - } - ], - "description": "A RESTful API package for the Laravel and Lumen frameworks.", - "keywords": [ - "api", - "dingo", - "laravel", - "restful" - ], - "time": "2017-02-10 00:56:04" - }, - { - "name": "dingo/blueprint", - "version": "0.2.2", - "source": { - "type": "git", - "url": "https://github.com/dingo/blueprint.git", - "reference": "690bdf0f76b4428fd52835b9d778fb4551333867" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/dingo/blueprint/zipball/690bdf0f76b4428fd52835b9d778fb4551333867", - "reference": "690bdf0f76b4428fd52835b9d778fb4551333867", - "shasum": "" - }, - "require": { - "doctrine/annotations": "~1.2", - "illuminate/filesystem": "5.1.* || 5.2.* || 5.3.* || 5.4.*", - "illuminate/support": "5.1.* || 5.2.* || 5.3.* || 5.4.*", - "php": ">=5.5.9", - "phpdocumentor/reflection-docblock": "3.1.*" - }, - "require-dev": { - "phpunit/phpunit": "~4.0", - "squizlabs/php_codesniffer": "~2.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "0.2-dev" - } - }, - "autoload": { - "psr-4": { - "Dingo\\Blueprint\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Jason Lewis", - "email": "jason.lewis1991@gmail.com" - } - ], - "description": "API Blueprint documentation generator.", - "keywords": [ - "api", - "blueprint", - "dingo", - "docs", - "laravel" - ], - "time": "2017-02-11 17:28:57" - }, { "name": "dnoegel/php-xdg-base-dir", "version": "0.1", @@ -2157,152 +2027,6 @@ ], "time": "2017-03-13 16:27:32" }, - { - "name": "phpdocumentor/reflection-common", - "version": "1.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/144c307535e82c8fdcaacbcfc1d6d8eeb896687c", - "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c", - "shasum": "" - }, - "require": { - "php": ">=5.5" - }, - "require-dev": { - "phpunit/phpunit": "^4.6" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jaap van Otterdijk", - "email": "opensource@ijaap.nl" - } - ], - "description": "Common reflection classes used by phpdocumentor to reflect the code structure", - "homepage": "http://www.phpdoc.org", - "keywords": [ - "FQSEN", - "phpDocumentor", - "phpdoc", - "reflection", - "static analysis" - ], - "time": "2015-12-27 11:43:31" - }, - { - "name": "phpdocumentor/reflection-docblock", - "version": "3.1.1", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/8331b5efe816ae05461b7ca1e721c01b46bafb3e", - "reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e", - "shasum": "" - }, - "require": { - "php": ">=5.5", - "phpdocumentor/reflection-common": "^1.0@dev", - "phpdocumentor/type-resolver": "^0.2.0", - "webmozart/assert": "^1.0" - }, - "require-dev": { - "mockery/mockery": "^0.9.4", - "phpunit/phpunit": "^4.4" - }, - "type": "library", - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src/" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - } - ], - "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2016-09-30 07:12:33" - }, - { - "name": "phpdocumentor/type-resolver", - "version": "0.2.1", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb", - "reference": "e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb", - "shasum": "" - }, - "require": { - "php": ">=5.5", - "phpdocumentor/reflection-common": "^1.0" - }, - "require-dev": { - "mockery/mockery": "^0.9.4", - "phpunit/phpunit": "^5.2||^4.8.24" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src/" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - } - ], - "time": "2016-11-25 06:54:22" - }, { "name": "pragmarx/google2fa", "version": "v1.0.1", @@ -2766,6 +2490,115 @@ ], "time": "2016-08-21 15:57:09" }, + { + "name": "spatie/fractalistic", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/spatie/fractalistic.git", + "reference": "59a2e7dfbd49e58b7de7d5621c1e7365786809f9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/fractalistic/zipball/59a2e7dfbd49e58b7de7d5621c1e7365786809f9", + "reference": "59a2e7dfbd49e58b7de7d5621c1e7365786809f9", + "shasum": "" + }, + "require": { + "league/fractal": "^0.14.0|^0.15.0", + "php": "^5.6|^7.0" + }, + "require-dev": { + "illuminate/pagination": "^5.3", + "phpunit/phpunit": "^5.7" + }, + "type": "library", + "autoload": { + "psr-4": { + "Spatie\\Fractalistic\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "A developer friendly wrapper around Fractal", + "homepage": "https://github.com/spatie/fractalistic", + "keywords": [ + "api", + "fractal", + "fractalistic", + "spatie", + "transform" + ], + "time": "2017-01-19 20:51:03" + }, + { + "name": "spatie/laravel-fractal", + "version": "3.5.0", + "source": { + "type": "git", + "url": "https://github.com/spatie/laravel-fractal.git", + "reference": "16689b0ce340bc139ba767f0bf2904e4eab2b254" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/laravel-fractal/zipball/16689b0ce340bc139ba767f0bf2904e4eab2b254", + "reference": "16689b0ce340bc139ba767f0bf2904e4eab2b254", + "shasum": "" + }, + "require": { + "illuminate/contracts": "~5.1.0|~5.2.0|~5.3.0|~5.4.0", + "illuminate/support": "~5.1.0|~5.2.0|~5.3.0|~5.4.0", + "php": "^5.6|^7.0", + "spatie/fractalistic": "^1.0" + }, + "require-dev": { + "orchestra/testbench": "~3.2.0|3.3.0|~3.4.0", + "phpunit/phpunit": "^5.7.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Spatie\\Fractal\\": "src" + }, + "files": [ + "src/helpers.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "A Fractal service provider for Laravel and Lumen", + "homepage": "https://github.com/spatie/laravel-fractal", + "keywords": [ + "api", + "fractal", + "laravel", + "laravel-fractal", + "lumen", + "spatie", + "transform" + ], + "time": "2017-02-21 23:17:02" + }, { "name": "swiftmailer/swiftmailer", "version": "v5.4.6", @@ -3755,56 +3588,6 @@ ], "time": "2016-09-01 10:05:43" }, - { - "name": "webmozart/assert", - "version": "1.2.0", - "source": { - "type": "git", - "url": "https://github.com/webmozart/assert.git", - "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/webmozart/assert/zipball/2db61e59ff05fe5126d152bd0655c9ea113e550f", - "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f", - "shasum": "" - }, - "require": { - "php": "^5.3.3 || ^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.6", - "sebastian/version": "^1.0.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.3-dev" - } - }, - "autoload": { - "psr-4": { - "Webmozart\\Assert\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" - } - ], - "description": "Assertions to validate method input/output with nice error messages.", - "keywords": [ - "assert", - "check", - "validate" - ], - "time": "2016-11-23 20:04:58" - }, { "name": "webpatser/laravel-uuid", "version": "2.0.1", @@ -4223,6 +4006,152 @@ ], "time": "2017-01-26 22:05:40" }, + { + "name": "phpdocumentor/reflection-common", + "version": "1.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/144c307535e82c8fdcaacbcfc1d6d8eeb896687c", + "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "phpunit/phpunit": "^4.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "time": "2015-12-27 11:43:31" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "3.1.1", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/8331b5efe816ae05461b7ca1e721c01b46bafb3e", + "reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e", + "shasum": "" + }, + "require": { + "php": ">=5.5", + "phpdocumentor/reflection-common": "^1.0@dev", + "phpdocumentor/type-resolver": "^0.2.0", + "webmozart/assert": "^1.0" + }, + "require-dev": { + "mockery/mockery": "^0.9.4", + "phpunit/phpunit": "^4.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "time": "2016-09-30 07:12:33" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "0.2.1", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb", + "reference": "e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb", + "shasum": "" + }, + "require": { + "php": ">=5.5", + "phpdocumentor/reflection-common": "^1.0" + }, + "require-dev": { + "mockery/mockery": "^0.9.4", + "phpunit/phpunit": "^5.2||^4.8.24" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "time": "2016-11-25 06:54:22" + }, { "name": "phpspec/prophecy", "version": "v1.7.0", @@ -5299,13 +5228,61 @@ "description": "Symfony Yaml Component", "homepage": "https://symfony.com", "time": "2017-03-07 16:47:02" + }, + { + "name": "webmozart/assert", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/webmozart/assert.git", + "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozart/assert/zipball/2db61e59ff05fe5126d152bd0655c9ea113e550f", + "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.6", + "sebastian/version": "^1.0.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "time": "2016-11-23 20:04:58" } ], "aliases": [], "minimum-stability": "stable", - "stability-flags": { - "dingo/api": 10 - }, + "stability-flags": [], "prefer-stable": false, "prefer-lowest": false, "platform": { diff --git a/config/api.php b/config/api.php deleted file mode 100644 index 2a847e7ac..000000000 --- a/config/api.php +++ /dev/null @@ -1,220 +0,0 @@ - env('API_STANDARDS_TREE', 'x'), - - /* - |-------------------------------------------------------------------------- - | API Subtype - |-------------------------------------------------------------------------- - | - | Your subtype will follow the standards tree you use when used in the - | "Accept" header to negotiate the content type and version. - | - | For example: Accept: application/x.SUBTYPE.v1+json - | - */ - - 'subtype' => env('API_SUBTYPE', ''), - - /* - |-------------------------------------------------------------------------- - | Default API Version - |-------------------------------------------------------------------------- - | - | This is the default version when strict mode is disabled and your API - | is accessed via a web browser. It's also used as the default version - | when generating your APIs documentation. - | - */ - - 'version' => env('API_VERSION', 'v1'), - - /* - |-------------------------------------------------------------------------- - | Default API Prefix - |-------------------------------------------------------------------------- - | - | A default prefix to use for your API routes so you don't have to - | specify it for each group. - | - */ - - 'prefix' => env('API_PREFIX', 'api'), - - /* - |-------------------------------------------------------------------------- - | Default API Domain - |-------------------------------------------------------------------------- - | - | A default domain to use for your API routes so you don't have to - | specify it for each group. - | - */ - - 'domain' => env('API_DOMAIN', null), - - /* - |-------------------------------------------------------------------------- - | Name - |-------------------------------------------------------------------------- - | - | When documenting your API using the API Blueprint syntax you can - | configure a default name to avoid having to manually specify - | one when using the command. - | - */ - - 'name' => env('API_NAME', null), - - /* - |-------------------------------------------------------------------------- - | Conditional Requests - |-------------------------------------------------------------------------- - | - | Globally enable conditional requests so that an ETag header is added to - | any successful response. Subsequent requests will perform a check and - | will return a 304 Not Modified. This can also be enabled or disabled - | on certain groups or routes. - | - */ - - 'conditionalRequest' => env('API_CONDITIONAL_REQUEST', true), - - /* - |-------------------------------------------------------------------------- - | Strict Mode - |-------------------------------------------------------------------------- - | - | Enabling strict mode will require clients to send a valid Accept header - | with every request. This also voids the default API version, meaning - | your API will not be browsable via a web browser. - | - */ - - 'strict' => env('API_STRICT', false), - - /* - |-------------------------------------------------------------------------- - | Debug Mode - |-------------------------------------------------------------------------- - | - | Enabling debug mode will result in error responses caused by thrown - | exceptions to have a "debug" key that will be populated with - | more detailed information on the exception. - | - */ - - 'debug' => env('API_DEBUG', false), - - /* - |-------------------------------------------------------------------------- - | Generic Error Format - |-------------------------------------------------------------------------- - | - | When some HTTP exceptions are not caught and dealt with the API will - | generate a generic error response in the format provided. Any - | keys that aren't replaced with corresponding values will be - | removed from the final response. - | - */ - - 'errorFormat' => [ - 'message' => ':message', - 'errors' => ':errors', - 'code' => ':code', - 'status_code' => ':status_code', - 'debug' => ':debug', - ], - - /* - |-------------------------------------------------------------------------- - | API Middleware - |-------------------------------------------------------------------------- - | - | Middleware that will be applied globally to all API requests. - | - */ - - 'middleware' => [ - - ], - - /* - |-------------------------------------------------------------------------- - | Authentication Providers - |-------------------------------------------------------------------------- - | - | The authentication providers that should be used when attempting to - | authenticate an incoming API request. - | - */ - - 'auth' => [ - 'custom' => 'Pterodactyl\Http\Middleware\APISecretToken', - ], - - /* - |-------------------------------------------------------------------------- - | Throttling / Rate Limiting - |-------------------------------------------------------------------------- - | - | Consumers of your API can be limited to the amount of requests they can - | make. You can create your own throttles or simply change the default - | throttles. - | - */ - - 'throttling' => [ - - ], - - /* - |-------------------------------------------------------------------------- - | Response Transformer - |-------------------------------------------------------------------------- - | - | Responses can be transformed so that they are easier to format. By - | default a Fractal transformer will be used to transform any - | responses prior to formatting. You can easily replace - | this with your own transformer. - | - */ - - 'transformer' => env('API_TRANSFORMER', Dingo\Api\Transformer\Adapter\Fractal::class), - - /* - |-------------------------------------------------------------------------- - | Response Formats - |-------------------------------------------------------------------------- - | - | Responses can be returned in multiple formats by registering different - | response formatters. You can also customize an existing response - | formatter. - | - */ - - 'defaultFormat' => env('API_DEFAULT_FORMAT', 'json'), - - 'formats' => [ - 'json' => Dingo\Api\Http\Response\Format\Json::class, - ], - -]; diff --git a/config/app.php b/config/app.php index 1e575d420..3c3fb772d 100644 --- a/config/app.php +++ b/config/app.php @@ -127,8 +127,6 @@ return [ 'providers' => [ - Dingo\Api\Provider\LaravelServiceProvider::class, - /* * Laravel Framework Service Providers... */ @@ -180,6 +178,7 @@ return [ Fideloper\Proxy\TrustedProxyServiceProvider::class, Laracasts\Utilities\JavaScript\JavaScriptServiceProvider::class, Lord\Laroute\LarouteServiceProvider::class, + Spatie\Fractal\FractalServiceProvider::class, ], @@ -210,11 +209,10 @@ return [ 'Crypt' => Illuminate\Support\Facades\Crypt::class, 'DB' => Illuminate\Support\Facades\DB::class, 'Debugbar' => Barryvdh\Debugbar\Facade::class, - 'Dingo' => Dingo\Api\Facade\API::class, - 'DingoRoute'=> Dingo\Api\Facade\Route::class, 'Eloquent' => Illuminate\Database\Eloquent\Model::class, 'Event' => Illuminate\Support\Facades\Event::class, 'File' => Illuminate\Support\Facades\File::class, + 'Fractal' => Spatie\Fractal\FractalFacade::class, 'Gate' => Illuminate\Support\Facades\Gate::class, 'Google2FA' => PragmaRX\Google2FA\Vendor\Laravel\Facade::class, 'Hash' => Illuminate\Support\Facades\Hash::class, diff --git a/routes/api-admin.php b/routes/api-admin.php new file mode 100644 index 000000000..649828046 --- /dev/null +++ b/routes/api-admin.php @@ -0,0 +1,34 @@ +. + * + * 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. + */ + +Route::get('/', 'CoreController@index')->name('api.admin'); + +/* +|-------------------------------------------------------------------------- +| Location Controller Routes +|-------------------------------------------------------------------------- +| +| Endpoint: /api/admin +| +*/ diff --git a/routes/api.php b/routes/api.php new file mode 100644 index 000000000..1a7b71f4a --- /dev/null +++ b/routes/api.php @@ -0,0 +1,40 @@ +. + * + * 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. + */ + +Route::get('/', 'CoreController@index')->name('api.user'); + +/* +|-------------------------------------------------------------------------- +| Server Controller Routes +|-------------------------------------------------------------------------- +| +| Endpoint: /api/user/server/{server} +| +*/ +Route::group(['prefix' => '/server/{server}'], function () { + Route::get('/', 'ServerController@index')->name('api.user.server'); + + Route::post('/power', 'ServerController@power')->name('api.user.server.power'); + Route::post('/command', 'ServerController@command')->name('api.user.server.command'); +});