Merge branch 'develop' into feature/service-changes

This commit is contained in:
Dane Everitt 2016-12-14 16:53:53 -05:00
commit fc38b09e1f
No known key found for this signature in database
GPG key ID: EEA66103B3D71F53
169 changed files with 2268 additions and 2289 deletions

View file

@ -1,61 +1,6 @@
<!-- The checkboxes below can be clicked once you submit this report if you'd like --> Please describe your issue in full below. Include what products are affected, as well as what version(s) you are running. Please also include information about your system, such as `uname -a` and `php -v` and `docker info` if applicable.
<!-- You can also use "- [x]" to mark it as checked. -->
## Product
Please check the corresponding boxes below for which products this is about.
- [ ] Panel If you're just making a suggestion, be descriptive, and link to any issues that might be releated as well.
- [ ] Daemon
- [ ] Dockerfile(s) [Please list if so: __ ]
## Type You can delete from this line up.
- [ ] Bug or Issue ---------------------
- [ ] Feature Request
- [ ] Enhancement
- [ ] Other
<!-- You only need to fill out the information below if this is a bug report. -->
<!-- Please delete this line and everything below if this is NOT a bug report. -->
## What Happens
<!-- Please include a description of what is happening when you encounter this bug. -->
## How to Reproduce
<!-- Please provide us a list of step for how to reproduce this issue. -->
1. Step 1
2. Step 2
3. etc.
## Error Logs
<!-- Please include a paste output of the errors if they are logged. They can be found in: -->
<!-- Panel: /var/www/pterodactyl/html/storage/logs/ Daemon: /srv/daemon/logs -->
<!-- You can also paste them on https://gist.github.com and include their links below. -->
```
error logs
```
## System Information
#### Output of `uname -a`:
```
paste here
```
#### Output of `php -v` (if Panel):
```
paste here
```
#### Output of `node -v` (if Daemon):
```
paste here
```
#### Output of `docker info` and `docker -v` (if Daemon or Dockerfiles):
```
paste here
```

View file

@ -3,6 +3,29 @@ This file is a running track of new features and fixes to each version of the pa
This project follows [Semantic Versioning](http://semver.org) guidelines. This project follows [Semantic Versioning](http://semver.org) guidelines.
## v0.5.5 (Bodacious Boreopterus)
### Added
* New API route to return allocations given a server ID. This adds support for a community-driven WHMCS module :rocket: available [here](https://github.com/hammerdawn/Pterodactyl-WHMCS).
### Fixed
* Fixes subuser display when trying to edit an existing subuser.
## v0.5.4 (Bodacious Boreopterus)
### Added
* Changing node configuration values now automatically makes a call to the daemon and updates the configuration there. Changing daemon tokens now does not require any intervention, and takes effect immediately. SSL & Port configurations will still require a daemon reboot.
* New button in file manager that triggers the right click menu to enable support on mobile devices and those who cannot right click (blessed be them).
* Support for filtering users when listing all users on the system.
* Container ID and User ID on the daemon are now shown when viewing a server in the panel.
### Changed
* File uploads now account for a maximum file size that is assigned for the daemon, and gives cleaner errors when that limit is reached.
* File upload limit can now be controlled from the panel.
* Updates regex and default values for some Minecraft services to reflect current technology.
### Fixed
* Fixes potential for generated password to not meet own validation requirements.
* Fixes some regex checking issues with newer versions of Minecraft.
## v0.5.3 (Bodacious Boreopterus) ## v0.5.3 (Bodacious Boreopterus)
### Fixed ### Fixed
* Fixed an error that occurred when viewing a node listing when no nodes were created yet due to a mis-declared variable. Also fixes a bug that would have all nodes trying to connect to the daemon using the same secret token on the node listing, causing only the last node to display properly. * Fixed an error that occurred when viewing a node listing when no nodes were created yet due to a mis-declared variable. Also fixes a bug that would have all nodes trying to connect to the daemon using the same secret token on the node listing, causing only the last node to display properly.

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,10 +21,10 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Console\Commands; namespace Pterodactyl\Console\Commands;
use DB; use DB;
use Illuminate\Console\Command; use Illuminate\Console\Command;
class ClearServices extends Command class ClearServices extends Command
@ -60,8 +60,7 @@ class ClearServices extends Command
*/ */
public function handle() public function handle()
{ {
if (! $this->confirm('This is a destructive operation, are you sure you wish to continue?')) {
if (!$this->confirm('This is a destructive operation, are you sure you wish to continue?')) {
$this->error('Canceling.'); $this->error('Canceling.');
exit(); exit();
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,19 +21,16 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Console\Commands; namespace Pterodactyl\Console\Commands;
use DB;
use Carbon; use Carbon;
use Pterodactyl\Models; use Pterodactyl\Models;
use Illuminate\Console\Command; use Illuminate\Console\Command;
use Illuminate\Foundation\Bus\DispatchesJobs; use Illuminate\Foundation\Bus\DispatchesJobs;
use Pterodactyl\Jobs\SendScheduledTask;
class ClearTasks extends Command class ClearTasks extends Command
{ {
use DispatchesJobs; use DispatchesJobs;
/** /**

View file

@ -28,6 +28,6 @@ class Inspire extends Command
*/ */
public function handle() public function handle()
{ {
$this->comment(PHP_EOL.Inspiring::quote().PHP_EOL); $this->comment(PHP_EOL . Inspiring::quote() . PHP_EOL);
} }
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,11 +21,10 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Console\Commands; namespace Pterodactyl\Console\Commands;
use Hash;
use Illuminate\Console\Command; use Illuminate\Console\Command;
use Pterodactyl\Repositories\UserRepository; use Pterodactyl\Repositories\UserRepository;
class MakeUser extends Command class MakeUser extends Command
@ -77,6 +76,7 @@ class MakeUser extends Command
try { try {
$user = new UserRepository; $user = new UserRepository;
$user->create($email, $password, $admin); $user->create($email, $password, $admin);
return $this->info('User successfully created.'); return $this->info('User successfully created.');
} catch (\Exception $ex) { } catch (\Exception $ex) {
return $this->error($ex->getMessage()); return $this->error($ex->getMessage());

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,19 +21,17 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Console\Commands; namespace Pterodactyl\Console\Commands;
use DB;
use Carbon; use Carbon;
use Pterodactyl\Models; use Pterodactyl\Models;
use Illuminate\Console\Command; use Illuminate\Console\Command;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Pterodactyl\Jobs\SendScheduledTask; use Pterodactyl\Jobs\SendScheduledTask;
use Illuminate\Foundation\Bus\DispatchesJobs;
class RunTasks extends Command class RunTasks extends Command
{ {
use DispatchesJobs; use DispatchesJobs;
/** /**

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,10 +21,11 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Console\Commands; namespace Pterodactyl\Console\Commands;
use Illuminate\Console\Command;
use Version; use Version;
use Illuminate\Console\Command;
class ShowVersion extends Command class ShowVersion extends Command
{ {

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,6 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Console\Commands; namespace Pterodactyl\Console\Commands;
use Illuminate\Console\Command; use Illuminate\Console\Command;
@ -66,7 +67,7 @@ class UpdateEmailSettings extends Command
{ {
$variables = []; $variables = [];
$file = base_path() . '/.env'; $file = base_path() . '/.env';
if (!file_exists($file)) { if (! file_exists($file)) {
$this->error('Missing environment file! It appears that you have not installed this panel correctly.'); $this->error('Missing environment file! It appears that you have not installed this panel correctly.');
exit(); exit();
} }
@ -75,35 +76,35 @@ class UpdateEmailSettings extends Command
$this->table([ $this->table([
'Option', 'Option',
'Description' 'Description',
], [ ], [
[ [
'smtp', 'smtp',
'SMTP Server Email' 'SMTP Server Email',
], ],
[ [
'mail', 'mail',
'PHP\'s Internal Mail Server' 'PHP\'s Internal Mail Server',
], ],
[ [
'mailgun', 'mailgun',
'Mailgun Email Service' 'Mailgun Email Service',
], ],
[ [
'mandrill', 'mandrill',
'Mandrill Transactional Email Service' 'Mandrill Transactional Email Service',
], ],
[ [
'postmark', 'postmark',
'Postmark Transactional Email Service' 'Postmark Transactional Email Service',
] ],
]); ]);
$variables['MAIL_DRIVER'] = is_null($this->option('driver')) ? $this->choice('Which email driver would you like to use?', [ $variables['MAIL_DRIVER'] = is_null($this->option('driver')) ? $this->choice('Which email driver would you like to use?', [
'smtp', 'smtp',
'mail', 'mail',
'mailgun', 'mailgun',
'mandrill', 'mandrill',
'postmark' 'postmark',
]) : $this->option('driver'); ]) : $this->option('driver');
switch ($variables['MAIL_DRIVER']) { switch ($variables['MAIL_DRIVER']) {

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,6 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Console\Commands; namespace Pterodactyl\Console\Commands;
use Uuid; use Uuid;
@ -66,10 +67,9 @@ class UpdateEnvironment extends Command
*/ */
public function handle() public function handle()
{ {
$variables = []; $variables = [];
$file = base_path() . '/.env'; $file = base_path() . '/.env';
if (!file_exists($file)) { if (! file_exists($file)) {
$this->error('Missing environment file! It appears that you have not installed this panel correctly.'); $this->error('Missing environment file! It appears that you have not installed this panel correctly.');
exit(); exit();
} }
@ -77,12 +77,12 @@ class UpdateEnvironment extends Command
$envContents = file_get_contents($file); $envContents = file_get_contents($file);
$this->info('Simply leave blank and press enter to fields that you do not wish to update.'); $this->info('Simply leave blank and press enter to fields that you do not wish to update.');
if (!env('SERVICE_AUTHOR', false)) { if (! env('SERVICE_AUTHOR', false)) {
$this->info('No service author set, setting one now.'); $this->info('No service author set, setting one now.');
$variables['SERVICE_AUTHOR'] = env('SERVICE_AUTHOR', (string) Uuid::generate(4)); $variables['SERVICE_AUTHOR'] = env('SERVICE_AUTHOR', (string) Uuid::generate(4));
} }
if (!env('QUEUE_STANDARD', false) || !env('QUEUE_DRIVER', false)) { if (! env('QUEUE_STANDARD', false) || ! env('QUEUE_DRIVER', false)) {
$this->info('Setting default queue settings.'); $this->info('Setting default queue settings.');
$variables['QUEUE_DRIVER'] = env('QUEUE_DRIVER', 'database'); $variables['QUEUE_DRIVER'] = env('QUEUE_DRIVER', 'database');
$variables['QUEUE_HIGH'] = env('QUEUE_HIGH', 'high'); $variables['QUEUE_HIGH'] = env('QUEUE_HIGH', 'high');
@ -91,25 +91,25 @@ class UpdateEnvironment extends Command
} }
if (is_null($this->option('dbhost'))) { if (is_null($this->option('dbhost'))) {
$variables['DB_HOST'] = $this->anticipate('Database Host', [ 'localhost', '127.0.0.1', env('DB_HOST') ], env('DB_HOST')); $variables['DB_HOST'] = $this->anticipate('Database Host', ['localhost', '127.0.0.1', env('DB_HOST')], env('DB_HOST'));
} else { } else {
$variables['DB_HOST'] = $this->option('dbhost'); $variables['DB_HOST'] = $this->option('dbhost');
} }
if (is_null($this->option('dbport'))) { if (is_null($this->option('dbport'))) {
$variables['DB_PORT'] = $this->anticipate('Database Port', [ 3306, env('DB_PORT') ], env('DB_PORT')); $variables['DB_PORT'] = $this->anticipate('Database Port', [3306, env('DB_PORT')], env('DB_PORT'));
} else { } else {
$variables['DB_PORT'] = $this->option('dbport'); $variables['DB_PORT'] = $this->option('dbport');
} }
if (is_null($this->option('dbname'))) { if (is_null($this->option('dbname'))) {
$variables['DB_DATABASE'] = $this->anticipate('Database Name', [ 'pterodactyl', 'homestead', ENV('DB_DATABASE') ], env('DB_DATABASE')); $variables['DB_DATABASE'] = $this->anticipate('Database Name', ['pterodactyl', 'homestead', ENV('DB_DATABASE')], env('DB_DATABASE'));
} else { } else {
$variables['DB_DATABASE'] = $this->option('dbname'); $variables['DB_DATABASE'] = $this->option('dbname');
} }
if (is_null($this->option('dbuser'))) { if (is_null($this->option('dbuser'))) {
$variables['DB_USERNAME'] = $this->anticipate('Database Username', [ ENV('DB_DATABASE') ], env('DB_USERNAME')); $variables['DB_USERNAME'] = $this->anticipate('Database Username', [ENV('DB_DATABASE')], env('DB_USERNAME'));
} else { } else {
$variables['DB_USERNAME'] = $this->option('dbuser'); $variables['DB_USERNAME'] = $this->option('dbuser');
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,6 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Events; namespace Pterodactyl\Events;
use Illuminate\Queue\SerializesModels; use Illuminate\Queue\SerializesModels;
@ -40,5 +41,4 @@ class ServerDeleted
{ {
$this->server = $id; $this->server = $id;
} }
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,9 +21,9 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Exceptions; namespace Pterodactyl\Exceptions;
class AccountNotFoundException extends \Exception class AccountNotFoundException extends \Exception
{ {
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,13 +21,13 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Exceptions; namespace Pterodactyl\Exceptions;
use Log; use Log;
class DisplayException extends \Exception class DisplayException extends \Exception
{ {
private $_logging = null; private $_logging = null;
public function __construct($message, $log = null) public function __construct($message, $log = null)
@ -44,5 +44,4 @@ class DisplayException extends \Exception
{ {
return $this->_logging; return $this->_logging;
} }
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,6 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Exceptions; namespace Pterodactyl\Exceptions;
class DisplayValidationException extends \Exception class DisplayValidationException extends \Exception

View file

@ -3,12 +3,8 @@
namespace Pterodactyl\Exceptions; namespace Pterodactyl\Exceptions;
use Log; use Log;
use Exception; use Exception;
use DisplayException; use DisplayException;
use DisplayValidationException;
use AccountNotFoundException;
use Illuminate\Auth\AuthenticationException; use Illuminate\Auth\AuthenticationException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
@ -52,7 +48,7 @@ class Handler extends ExceptionHandler
{ {
if ($request->isXmlHttpRequest() || $request->ajax() || $request->is('remote/*')) { if ($request->isXmlHttpRequest() || $request->ajax() || $request->is('remote/*')) {
$response = response()->json([ $response = response()->json([
'error' => ($exception instanceof DisplayException) ? $exception->getMessage() : 'An unhandled error occured while attempting to process this request.' 'error' => ($exception instanceof DisplayException) ? $exception->getMessage() : 'An unhandled error occured while attempting to process this request.',
], 500); ], 500);
// parent::render() will log it, we are bypassing it in this case. // parent::render() will log it, we are bypassing it in this case.
@ -74,7 +70,7 @@ class Handler extends ExceptionHandler
if ($request->expectsJson()) { if ($request->expectsJson()) {
return response()->json(['error' => 'Unauthenticated.'], 401); return response()->json(['error' => 'Unauthenticated.'], 401);
} }
return redirect()->guest('/auth/login'); return redirect()->guest('/auth/login');
} }
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,13 +21,13 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Facades; namespace Pterodactyl\Facades;
use Illuminate\Support\Facades\Facade; use Illuminate\Support\Facades\Facade;
class Version extends Facade class Version extends Facade
{ {
protected static function getFacadeAccessor() protected static function getFacadeAccessor()
{ {
return '\Pterodactyl\Services\VersionService'; return '\Pterodactyl\Services\VersionService';

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,6 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Http\Controllers\API; namespace Pterodactyl\Http\Controllers\API;
use Dingo\Api\Routing\Helpers; use Dingo\Api\Routing\Helpers;

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,6 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Http\Controllers\API; namespace Pterodactyl\Http\Controllers\API;
use DB; use DB;
@ -32,14 +33,13 @@ use Pterodactyl\Models\Location;
*/ */
class LocationController extends BaseController class LocationController extends BaseController
{ {
public function __construct() public function __construct()
{ {
// //
} }
/** /**
* List All Locations * List All Locations.
* *
* Lists all locations currently on the system. * Lists all locations currently on the system.
* *
@ -47,18 +47,13 @@ class LocationController extends BaseController
* @Versions({"v1"}) * @Versions({"v1"})
* @Response(200) * @Response(200)
*/ */
public function list(Request $request) public function lists(Request $request)
{ {
$locations = Location::select('locations.*', DB::raw('GROUP_CONCAT(nodes.id) as nodes')) return Location::select('locations.*', DB::raw('GROUP_CONCAT(nodes.id) as nodes'))
->join('nodes', 'locations.id', '=', 'nodes.location') ->join('nodes', 'locations.id', '=', 'nodes.location')
->groupBy('locations.id') ->groupBy('locations.id')
->get(); ->get()->each(function ($location) {
foreach($locations as &$location) {
$location->nodes = explode(',', $location->nodes); $location->nodes = explode(',', $location->nodes);
})->all();
} }
return $locations->toArray();
}
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,18 +21,15 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Http\Controllers\API; namespace Pterodactyl\Http\Controllers\API;
use Illuminate\Http\Request;
use Pterodactyl\Models; use Pterodactyl\Models;
use Pterodactyl\Transformers\NodeTransformer; use Illuminate\Http\Request;
use Pterodactyl\Transformers\AllocationTransformer;
use Pterodactyl\Repositories\NodeRepository;
use Pterodactyl\Exceptions\DisplayValidationException;
use Pterodactyl\Exceptions\DisplayException;
use Dingo\Api\Exception\ResourceException; use Dingo\Api\Exception\ResourceException;
use Pterodactyl\Exceptions\DisplayException;
use Pterodactyl\Repositories\NodeRepository;
use Pterodactyl\Exceptions\DisplayValidationException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException; use Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException;
@ -42,14 +39,13 @@ use Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException;
*/ */
class NodeController extends BaseController class NodeController extends BaseController
{ {
public function __construct() public function __construct()
{ {
// //
} }
/** /**
* List All Nodes * List All Nodes.
* *
* Lists all nodes currently on the system. * Lists all nodes currently on the system.
* *
@ -60,13 +56,13 @@ class NodeController extends BaseController
* }) * })
* @Response(200) * @Response(200)
*/ */
public function list(Request $request) public function lists(Request $request)
{ {
return Models\Node::all()->toArray(); return Models\Node::all()->toArray();
} }
/** /**
* Create a New Node * Create a New Node.
* *
* @Post("/nodes") * @Post("/nodes")
* @Versions({"v1"}) * @Versions({"v1"})
@ -102,7 +98,8 @@ class NodeController extends BaseController
try { try {
$node = new NodeRepository; $node = new NodeRepository;
$new = $node->create($request->all()); $new = $node->create($request->all());
return [ 'id' => $new ];
return ['id' => $new];
} catch (DisplayValidationException $ex) { } catch (DisplayValidationException $ex) {
throw new ResourceException('A validation error occured.', json_decode($ex->getMessage(), true)); throw new ResourceException('A validation error occured.', json_decode($ex->getMessage(), true));
} catch (DisplayException $ex) { } catch (DisplayException $ex) {
@ -113,7 +110,7 @@ class NodeController extends BaseController
} }
/** /**
* List Specific Node * List Specific Node.
* *
* Lists specific fields about a server or all fields pertaining to that node. * Lists specific fields about a server or all fields pertaining to that node.
* *
@ -129,16 +126,16 @@ class NodeController extends BaseController
{ {
$node = Models\Node::where('id', $id); $node = Models\Node::where('id', $id);
if (!is_null($request->input('fields'))) { if (! is_null($request->input('fields'))) {
foreach(explode(',', $request->input('fields')) as $field) { foreach (explode(',', $request->input('fields')) as $field) {
if (!empty($field)) { if (! empty($field)) {
$node->addSelect($field); $node->addSelect($field);
} }
} }
} }
try { try {
if (!$node->first()) { if (! $node->first()) {
throw new NotFoundHttpException('No node by that ID was found.'); throw new NotFoundHttpException('No node by that ID was found.');
} }
@ -146,8 +143,8 @@ class NodeController extends BaseController
'node' => $node->first(), 'node' => $node->first(),
'allocations' => [ 'allocations' => [
'assigned' => Models\Allocation::where('node', $id)->whereNotNull('assigned_to')->get(), 'assigned' => Models\Allocation::where('node', $id)->whereNotNull('assigned_to')->get(),
'unassigned' => Models\Allocation::where('node', $id)->whereNull('assigned_to')->get() 'unassigned' => Models\Allocation::where('node', $id)->whereNull('assigned_to')->get(),
] ],
]; ];
} catch (NotFoundHttpException $ex) { } catch (NotFoundHttpException $ex) {
throw $ex; throw $ex;
@ -158,59 +155,61 @@ class NodeController extends BaseController
public function config(Request $request, $id) public function config(Request $request, $id)
{ {
if (!$request->secure()) { if (! $request->secure()) {
throw new BadRequestHttpException('This API route can only be accessed using a secure connection.'); throw new BadRequestHttpException('This API route can only be accessed using a secure connection.');
} }
$node = Models\Node::where('id', $id)->first(); $node = Models\Node::where('id', $id)->first();
if (!$node) { if (! $node) {
throw new NotFoundHttpException('No node by that ID was found.'); throw new NotFoundHttpException('No node by that ID was found.');
} }
return [ return [
'web' => [ 'web' => [
'listen' => $node->daemonListen, 'listen' => $node->daemonListen,
'host' => '0.0.0.0',
'ssl' => [ 'ssl' => [
'enabled' => ($node->scheme === 'https'), 'enabled' => ($node->scheme === 'https'),
'certificate' => '/etc/certs/' . $node->fqdn . '/fullchain.pem', 'certificate' => '/etc/certs/' . $node->fqdn . '/fullchain.pem',
'key' => '/etc/certs/' . $node->fqdn . '/privkey.pem' 'key' => '/etc/certs/' . $node->fqdn . '/privkey.pem',
] ],
], ],
'docker' => [ 'docker' => [
'socket' => '/var/run/docker.sock', 'socket' => '/var/run/docker.sock',
'autoupdate_images' => true 'autoupdate_images' => true,
], ],
'sftp' => [ 'sftp' => [
'path' => $node->daemonBase, 'path' => $node->daemonBase,
'port' => (int) $node->daemonSFTP, 'port' => (int) $node->daemonSFTP,
'container' => '0x0000' 'container' => 'ptdl-sftp',
],
'query' => [
'kill_on_fail' => true,
'fail_limit' => 5,
], ],
'logger' => [ 'logger' => [
'path' => 'logs/', 'path' => 'logs/',
'src' => false, 'src' => false,
'level' => 'info', 'level' => 'info',
'period' => '1d', 'period' => '1d',
'count' => 3 'count' => 3,
], ],
'remote' => [ 'remote' => [
'base' => config('app.url'),
'download' => route('remote.download'), 'download' => route('remote.download'),
'installed' => route('remote.install') 'installed' => route('remote.install'),
], ],
'uploads' => [ 'uploads' => [
'maximumSize' => 100000000 'size_limit' => $node->upload_size,
], ],
'keys' => [ 'keys' => [
$node->daemonSecret $node->daemonSecret,
], ],
'query' => [
'kill_on_fail' => true,
'fail_limit' => 3
]
]; ];
} }
/** /**
* List all Node Allocations * List all Node Allocations.
* *
* Returns a listing of all allocations for every node. * Returns a listing of all allocations for every node.
* *
@ -224,11 +223,37 @@ class NodeController extends BaseController
if ($allocations->count() < 1) { if ($allocations->count() < 1) {
throw new NotFoundHttpException('No allocations have been created.'); throw new NotFoundHttpException('No allocations have been created.');
} }
return $allocations; return $allocations;
} }
/** /**
* Delete Node * List Node Allocation based on assigned to ID.
*
* Returns a listing of the allocation for the specified server id.
*
* @Get("/nodes/allocations/{id}")
* @Versions({"v1"})
* @Response(200)
*/
public function allocationsView(Request $request, $id)
{
$query = Models\Allocation::where('assigned_to', $id)->get();
try {
if (empty($query)) {
throw new NotFoundHttpException('No allocations for that server were found.');
}
return $query;
} catch (NotFoundHttpException $ex) {
throw $ex;
} catch (\Exception $ex) {
throw new BadRequestHttpException('There was an issue with the fields passed in the request.');
}
}
/**
* Delete Node.
* *
* @Delete("/nodes/{id}") * @Delete("/nodes/{id}")
* @Versions({"v1"}) * @Versions({"v1"})
@ -242,12 +267,12 @@ class NodeController extends BaseController
try { try {
$node = new NodeRepository; $node = new NodeRepository;
$node->delete($id); $node->delete($id);
return $this->response->noContent(); return $this->response->noContent();
} catch (DisplayException $ex) { } catch (DisplayException $ex) {
throw new ResourceException($ex->getMessage()); throw new ResourceException($ex->getMessage());
} catch(\Exception $e) { } catch (\Exception $e) {
throw new ServiceUnavailableHttpException('An error occured while attempting to delete this node.'); throw new ServiceUnavailableHttpException('An error occured while attempting to delete this node.');
} }
} }
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,18 +21,16 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Http\Controllers\API;
use Illuminate\Http\Request; namespace Pterodactyl\Http\Controllers\API;
use Log; use Log;
use Pterodactyl\Models; use Pterodactyl\Models;
use Pterodactyl\Transformers\ServerTransformer; use Illuminate\Http\Request;
use Pterodactyl\Repositories\ServerRepository;
use Pterodactyl\Exceptions\DisplayValidationException;
use Pterodactyl\Exceptions\DisplayException;
use Dingo\Api\Exception\ResourceException; use Dingo\Api\Exception\ResourceException;
use Pterodactyl\Exceptions\DisplayException;
use Pterodactyl\Repositories\ServerRepository;
use Pterodactyl\Exceptions\DisplayValidationException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException; use Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException;
@ -42,14 +40,13 @@ use Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException;
*/ */
class ServerController extends BaseController class ServerController extends BaseController
{ {
public function __construct() public function __construct()
{ {
// //
} }
/** /**
* List All Servers * List All Servers.
* *
* Lists all servers currently on the system. * Lists all servers currently on the system.
* *
@ -60,13 +57,13 @@ class ServerController extends BaseController
* }) * })
* @Response(200) * @Response(200)
*/ */
public function list(Request $request) public function lists(Request $request)
{ {
return Models\Server::all()->toArray(); return Models\Server::all()->toArray();
} }
/** /**
* Create Server * Create Server.
* *
* @Post("/servers") * @Post("/servers")
* @Versions({"v1"}) * @Versions({"v1"})
@ -77,7 +74,8 @@ class ServerController extends BaseController
try { try {
$server = new ServerRepository; $server = new ServerRepository;
$new = $server->create($request->all()); $new = $server->create($request->all());
return [ 'id' => $new ];
return ['id' => $new];
} catch (DisplayValidationException $ex) { } catch (DisplayValidationException $ex) {
throw new ResourceException('A validation error occured.', json_decode($ex->getMessage(), true)); throw new ResourceException('A validation error occured.', json_decode($ex->getMessage(), true));
} catch (DisplayException $ex) { } catch (DisplayException $ex) {
@ -89,7 +87,7 @@ class ServerController extends BaseController
} }
/** /**
* List Specific Server * List Specific Server.
* *
* Lists specific fields about a server or all fields pertaining to that server. * Lists specific fields about a server or all fields pertaining to that server.
* *
@ -105,16 +103,16 @@ class ServerController extends BaseController
{ {
$query = Models\Server::where('id', $id); $query = Models\Server::where('id', $id);
if (!is_null($request->input('fields'))) { if (! is_null($request->input('fields'))) {
foreach(explode(',', $request->input('fields')) as $field) { foreach (explode(',', $request->input('fields')) as $field) {
if (!empty($field)) { if (! empty($field)) {
$query->addSelect($field); $query->addSelect($field);
} }
} }
} }
try { try {
if (!$query->first()) { if (! $query->first()) {
throw new NotFoundHttpException('No server by that ID was found.'); throw new NotFoundHttpException('No server by that ID was found.');
} }
@ -126,8 +124,8 @@ class ServerController extends BaseController
$response = $client->request('GET', '/servers', [ $response = $client->request('GET', '/servers', [
'headers' => [ 'headers' => [
'X-Access-Token' => $node->daemonSecret 'X-Access-Token' => $node->daemonSecret,
] ],
]); ]);
// Only return the daemon token if the request is using HTTPS // Only return the daemon token if the request is using HTTPS
@ -140,14 +138,14 @@ class ServerController extends BaseController
} }
return $server->toArray(); return $server->toArray();
} catch (NotFoundHttpException $ex) { } catch (NotFoundHttpException $ex) {
throw $ex; throw $ex;
} catch (\GuzzleHttp\Exception\TransferException $ex) { } catch (\GuzzleHttp\Exception\TransferException $ex) {
// Couldn't hit the daemon, return what we have though. // Couldn't hit the daemon, return what we have though.
$server->daemon = [ $server->daemon = [
'error' => 'There was an error encountered while attempting to connect to the remote daemon.' 'error' => 'There was an error encountered while attempting to connect to the remote daemon.',
]; ];
return $server->toArray(); return $server->toArray();
} catch (\Exception $ex) { } catch (\Exception $ex) {
throw new BadRequestHttpException('There was an issue with the fields passed in the request.'); throw new BadRequestHttpException('There was an issue with the fields passed in the request.');
@ -155,7 +153,7 @@ class ServerController extends BaseController
} }
/** /**
* Update Server configuration * Update Server configuration.
* *
* Updates display information on panel. * Updates display information on panel.
* *
@ -179,6 +177,7 @@ class ServerController extends BaseController
try { try {
$server = new ServerRepository; $server = new ServerRepository;
$server->updateDetails($id, $request->all()); $server->updateDetails($id, $request->all());
return Models\Server::findOrFail($id); return Models\Server::findOrFail($id);
} catch (DisplayValidationException $ex) { } catch (DisplayValidationException $ex) {
throw new ResourceException('A validation error occured.', json_decode($ex->getMessage(), true)); throw new ResourceException('A validation error occured.', json_decode($ex->getMessage(), true));
@ -190,7 +189,7 @@ class ServerController extends BaseController
} }
/** /**
* Update Server Build Configuration * Update Server Build Configuration.
* *
* Updates server build information on panel and on node. * Updates server build information on panel and on node.
* *
@ -221,10 +220,9 @@ class ServerController extends BaseController
public function build(Request $request, $id) public function build(Request $request, $id)
{ {
try { try {
throw new BadRequestHttpException('There was an error while attempting to add this node to the system.');
$server = new ServerRepository; $server = new ServerRepository;
$server->changeBuild($id, $request->all()); $server->changeBuild($id, $request->all());
return Models\Server::findOrFail($id); return Models\Server::findOrFail($id);
} catch (DisplayValidationException $ex) { } catch (DisplayValidationException $ex) {
throw new ResourceException('A validation error occured.', json_decode($ex->getMessage(), true)); throw new ResourceException('A validation error occured.', json_decode($ex->getMessage(), true));
@ -236,7 +234,7 @@ class ServerController extends BaseController
} }
/** /**
* Suspend Server * Suspend Server.
* *
* @Post("/servers/{id}/suspend") * @Post("/servers/{id}/suspend")
* @Versions({"v1"}) * @Versions({"v1"})
@ -250,6 +248,7 @@ class ServerController extends BaseController
try { try {
$server = new ServerRepository; $server = new ServerRepository;
$server->suspend($id); $server->suspend($id);
return $this->response->noContent(); return $this->response->noContent();
} catch (DisplayException $ex) { } catch (DisplayException $ex) {
throw new ResourceException($ex->getMessage()); throw new ResourceException($ex->getMessage());
@ -259,7 +258,7 @@ class ServerController extends BaseController
} }
/** /**
* Unsuspend Server * Unsuspend Server.
* *
* @Post("/servers/{id}/unsuspend") * @Post("/servers/{id}/unsuspend")
* @Versions({"v1"}) * @Versions({"v1"})
@ -273,6 +272,7 @@ class ServerController extends BaseController
try { try {
$server = new ServerRepository; $server = new ServerRepository;
$server->unsuspend($id); $server->unsuspend($id);
return $this->response->noContent(); return $this->response->noContent();
} catch (DisplayException $ex) { } catch (DisplayException $ex) {
throw new ResourceException($ex->getMessage()); throw new ResourceException($ex->getMessage());
@ -282,7 +282,7 @@ class ServerController extends BaseController
} }
/** /**
* Delete Server * Delete Server.
* *
* @Delete("/servers/{id}/{force}") * @Delete("/servers/{id}/{force}")
* @Versions({"v1"}) * @Versions({"v1"})
@ -297,12 +297,12 @@ class ServerController extends BaseController
try { try {
$server = new ServerRepository; $server = new ServerRepository;
$server->deleteServer($id, $force); $server->deleteServer($id, $force);
return $this->response->noContent(); return $this->response->noContent();
} catch (DisplayException $ex) { } catch (DisplayException $ex) {
throw new ResourceException($ex->getMessage()); throw new ResourceException($ex->getMessage());
} catch(\Exception $e) { } catch (\Exception $e) {
throw new ServiceUnavailableHttpException('An error occured while attempting to delete this server.'); throw new ServiceUnavailableHttpException('An error occured while attempting to delete this server.');
} }
} }
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,13 +21,11 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Http\Controllers\API; namespace Pterodactyl\Http\Controllers\API;
use Illuminate\Http\Request;
use Pterodactyl\Models; use Pterodactyl\Models;
use Pterodactyl\Transformers\ServiceTransformer; use Illuminate\Http\Request;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/** /**
@ -35,13 +33,12 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
*/ */
class ServiceController extends BaseController class ServiceController extends BaseController
{ {
public function __construct() public function __construct()
{ {
// //
} }
public function list(Request $request) public function lists(Request $request)
{ {
return Models\Service::all()->toArray(); return Models\Service::all()->toArray();
} }
@ -49,20 +46,16 @@ class ServiceController extends BaseController
public function view(Request $request, $id) public function view(Request $request, $id)
{ {
$service = Models\Service::find($id); $service = Models\Service::find($id);
if (!$service) { if (! $service) {
throw new NotFoundHttpException('No service by that ID was found.'); throw new NotFoundHttpException('No service by that ID was found.');
} }
$options = Models\ServiceOptions::select('id', 'name', 'description', 'tag', 'docker_image')->where('parent_service', $service->id)->get();
foreach($options as &$opt) {
$opt->variables = Models\ServiceVariables::where('option_id', $opt->id)->get();
}
return [ return [
'service' => $service, 'service' => $service,
'options' => $options 'options' => Models\ServiceOptions::select('id', 'name', 'description', 'tag', 'docker_image')
->where('parent_service', $service->id)
->with('variables')
->get(),
]; ];
} }
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,38 +21,31 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Http\Controllers\API\User; namespace Pterodactyl\Http\Controllers\API\User;
use Auth;
use Dingo;
use Pterodactyl\Models; use Pterodactyl\Models;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Pterodactyl\Http\Controllers\API\BaseController; use Pterodactyl\Http\Controllers\API\BaseController;
class InfoController extends BaseController class InfoController extends BaseController
{ {
public function me(Request $request) public function me(Request $request)
{ {
$servers = Models\Server::getUserServers(); return Models\Server::getUserServers()->map(function ($server) {
$response = []; return [
foreach($servers as &$server) {
$response = array_merge($response, [[
'id' => $server->uuidShort, 'id' => $server->uuidShort,
'uuid' => $server->uuid, 'uuid' => $server->uuid,
'name' => $server->name, 'name' => $server->name,
'node' => $server->nodeName, 'node' => $server->nodeName,
'ip' => [ 'ip' => [
'set' => $server->ip, 'set' => $server->ip,
'alias' => $server->ip_alias 'alias' => $server->ip_alias,
], ],
'port' => $server->port, 'port' => $server->port,
'service' => $server->a_serviceName, 'service' => $server->a_serviceName,
'option' => $server->a_serviceOptionName 'option' => $server->a_serviceOptionName,
]]); ];
} })->all();
return $response;
} }
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,18 +21,17 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Http\Controllers\API\User; namespace Pterodactyl\Http\Controllers\API\User;
use Auth;
use Log; use Log;
use Auth;
use Pterodactyl\Models; use Pterodactyl\Models;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Pterodactyl\Http\Controllers\API\BaseController; use Pterodactyl\Http\Controllers\API\BaseController;
class ServerController extends BaseController class ServerController extends BaseController
{ {
public function info(Request $request, $uuid) public function info(Request $request, $uuid)
{ {
$server = Models\Server::getByUUID($uuid); $server = Models\Server::getByUUID($uuid);
@ -43,28 +42,29 @@ class ServerController extends BaseController
$response = $client->request('GET', '/server', [ $response = $client->request('GET', '/server', [
'headers' => [ 'headers' => [
'X-Access-Token' => $server->daemonSecret, 'X-Access-Token' => $server->daemonSecret,
'X-Access-Server' => $server->uuid 'X-Access-Server' => $server->uuid,
] ],
]); ]);
$json = json_decode($response->getBody()); $json = json_decode($response->getBody());
$daemon = [ $daemon = [
'status' => $json->status, 'status' => $json->status,
'stats' => $json->proc, 'stats' => $json->proc,
'query' => $json->query 'query' => $json->query,
]; ];
} catch (\Exception $ex) { } catch (\Exception $ex) {
$daemon = [ $daemon = [
'error' => 'An error was encountered while trying to connect to the daemon to collece information. It might be offline.' 'error' => 'An error was encountered while trying to connect to the daemon to collece information. It might be offline.',
]; ];
Log::error($ex); Log::error($ex);
} }
$allocations = Models\Allocation::select('id', 'ip', 'port', 'ip_alias as alias')->where('assigned_to', $server->id)->get(); $allocations = Models\Allocation::select('id', 'ip', 'port', 'ip_alias as alias')->where('assigned_to', $server->id)->get();
foreach($allocations as &$allocation) { foreach ($allocations as &$allocation) {
$allocation->default = ($allocation->id === $server->allocation); $allocation->default = ($allocation->id === $server->allocation);
unset($allocation->id); unset($allocation->id);
} }
return [ return [
'uuidShort' => $server->uuidShort, 'uuidShort' => $server->uuidShort,
'uuid' => $server->uuid, 'uuid' => $server->uuid,
@ -76,23 +76,22 @@ class ServerController extends BaseController
'disk' => $server->disk, 'disk' => $server->disk,
'io' => $server->io, 'io' => $server->io,
'cpu' => $server->cpu, 'cpu' => $server->cpu,
'oom_disabled' => (bool) $server->oom_disabled 'oom_disabled' => (bool) $server->oom_disabled,
], ],
'allocations' => $allocations, 'allocations' => $allocations,
'sftp' => [ 'sftp' => [
'username' => (Auth::user()->can('view-sftp', $server)) ? $server->username : null 'username' => (Auth::user()->can('view-sftp', $server)) ? $server->username : null,
], ],
'daemon' => [ 'daemon' => [
'token' => ($request->secure()) ? $server->daemonSecret : false, 'token' => ($request->secure()) ? $server->daemonSecret : false,
'response' => $daemon 'response' => $daemon,
] ],
]; ];
} }
public function power(Request $request, $uuid) public function power(Request $request, $uuid)
{ {
$server = Models\Server::getByUUID($uuid); $server = Models\Server::getByUUID($uuid);
$node = Models\Node::getByID($server->node);
$client = Models\Node::guzzleRequest($server->node); $client = Models\Node::guzzleRequest($server->node);
Auth::user()->can('power-' . $request->input('action'), $server); Auth::user()->can('power-' . $request->input('action'), $server);
@ -100,12 +99,12 @@ class ServerController extends BaseController
$res = $client->request('PUT', '/server/power', [ $res = $client->request('PUT', '/server/power', [
'headers' => [ 'headers' => [
'X-Access-Server' => $server->uuid, 'X-Access-Server' => $server->uuid,
'X-Access-Token' => $server->daemonSecret 'X-Access-Token' => $server->daemonSecret,
], ],
'exceptions' => false, 'exceptions' => false,
'json' => [ 'json' => [
'action' => $request->input('action') 'action' => $request->input('action'),
] ],
]); ]);
if ($res->getStatusCode() !== 204) { if ($res->getStatusCode() !== 204) {

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,18 +21,15 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Http\Controllers\API; namespace Pterodactyl\Http\Controllers\API;
use Illuminate\Http\Request;
use Dingo\Api\Exception\ResourceException;
use Pterodactyl\Models; use Pterodactyl\Models;
use Pterodactyl\Transformers\UserTransformer; use Illuminate\Http\Request;
use Pterodactyl\Repositories\UserRepository; use Dingo\Api\Exception\ResourceException;
use Pterodactyl\Exceptions\DisplayValidationException;
use Pterodactyl\Exceptions\DisplayException; use Pterodactyl\Exceptions\DisplayException;
use Pterodactyl\Repositories\UserRepository;
use Pterodactyl\Exceptions\DisplayValidationException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException; use Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException;
@ -42,14 +39,12 @@ use Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException;
*/ */
class UserController extends BaseController class UserController extends BaseController
{ {
public function __construct() public function __construct()
{ {
} }
/** /**
* List All Users * List All Users.
* *
* Lists all users currently on the system. * Lists all users currently on the system.
* *
@ -60,13 +55,13 @@ class UserController extends BaseController
* }) * })
* @Response(200) * @Response(200)
*/ */
public function list(Request $request) public function lists(Request $request)
{ {
return Models\User::all()->toArray(); return Models\User::all()->toArray();
} }
/** /**
* List Specific User * List Specific User.
* *
* Lists specific fields about a user or all fields pertaining to that user. * Lists specific fields about a user or all fields pertaining to that user.
* *
@ -82,16 +77,16 @@ class UserController extends BaseController
{ {
$query = Models\User::where('id', $id); $query = Models\User::where('id', $id);
if (!is_null($request->input('fields'))) { if (! is_null($request->input('fields'))) {
foreach(explode(',', $request->input('fields')) as $field) { foreach (explode(',', $request->input('fields')) as $field) {
if (!empty($field)) { if (! empty($field)) {
$query->addSelect($field); $query->addSelect($field);
} }
} }
} }
try { try {
if (!$query->first()) { if (! $query->first()) {
throw new NotFoundHttpException('No user by that ID was found.'); throw new NotFoundHttpException('No user by that ID was found.');
} }
@ -105,11 +100,10 @@ class UserController extends BaseController
} catch (\Exception $ex) { } catch (\Exception $ex) {
throw new BadRequestHttpException('There was an issue with the fields passed in the request.'); throw new BadRequestHttpException('There was an issue with the fields passed in the request.');
} }
} }
/** /**
* Create a New User * Create a New User.
* *
* @Post("/users") * @Post("/users")
* @Versions({"v1"}) * @Versions({"v1"})
@ -129,7 +123,8 @@ class UserController extends BaseController
try { try {
$user = new UserRepository; $user = new UserRepository;
$create = $user->create($request->input('email'), $request->input('password'), $request->input('admin'), $request->input('custom_id')); $create = $user->create($request->input('email'), $request->input('password'), $request->input('admin'), $request->input('custom_id'));
return [ 'id' => $create ];
return ['id' => $create];
} catch (DisplayValidationException $ex) { } catch (DisplayValidationException $ex) {
throw new ResourceException('A validation error occured.', json_decode($ex->getMessage(), true)); throw new ResourceException('A validation error occured.', json_decode($ex->getMessage(), true));
} catch (DisplayException $ex) { } catch (DisplayException $ex) {
@ -140,7 +135,7 @@ class UserController extends BaseController
} }
/** /**
* Update an Existing User * Update an Existing User.
* *
* The data sent in the request will be used to update the existing user on the system. * The data sent in the request will be used to update the existing user on the system.
* *
@ -162,6 +157,7 @@ class UserController extends BaseController
try { try {
$user = new UserRepository; $user = new UserRepository;
$user->update($id, $request->all()); $user->update($id, $request->all());
return Models\User::findOrFail($id); return Models\User::findOrFail($id);
} catch (DisplayValidationException $ex) { } catch (DisplayValidationException $ex) {
throw new ResourceException('A validation error occured.', json_decode($ex->getMessage(), true)); throw new ResourceException('A validation error occured.', json_decode($ex->getMessage(), true));
@ -173,7 +169,7 @@ class UserController extends BaseController
} }
/** /**
* Delete a User * Delete a User.
* *
* @Delete("/users/{id}") * @Delete("/users/{id}")
* @Versions({"v1"}) * @Versions({"v1"})
@ -191,6 +187,7 @@ class UserController extends BaseController
try { try {
$user = new UserRepository; $user = new UserRepository;
$user->delete($id); $user->delete($id);
return $this->response->noContent(); return $this->response->noContent();
} catch (DisplayException $ex) { } catch (DisplayException $ex) {
throw new ResourceException($ex->getMessage()); throw new ResourceException($ex->getMessage());
@ -198,5 +195,4 @@ class UserController extends BaseController
throw new ServiceUnavailableHttpException('Unable to delete this user due to an error.'); throw new ServiceUnavailableHttpException('Unable to delete this user due to an error.');
} }
} }
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,20 +21,19 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Http\Controllers\Admin; namespace Pterodactyl\Http\Controllers\Admin;
use Alert; use Alert;
use Settings; use Settings;
use Validator; use Validator;
use Pterodactyl\Http\Controllers\Controller;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Pterodactyl\Http\Controllers\Controller;
class BaseController extends Controller class BaseController extends Controller
{ {
/** /**
* Controller Constructor * Controller Constructor.
*/ */
public function __construct() public function __construct()
{ {
@ -57,7 +56,7 @@ class BaseController extends Controller
'company' => 'required|between:1,256', 'company' => 'required|between:1,256',
'default_language' => 'required|alpha_dash|min:2|max:5', 'default_language' => 'required|alpha_dash|min:2|max:5',
'email_from' => 'required|email', 'email_from' => 'required|email',
'email_sender_name' => 'required|between:1,256' 'email_sender_name' => 'required|between:1,256',
]); ]);
if ($validator->fails()) { if ($validator->fails()) {
@ -70,8 +69,7 @@ class BaseController extends Controller
Settings::set('email_sender_name', $request->input('email_sender_name')); Settings::set('email_sender_name', $request->input('email_sender_name'));
Alert::success('Settings have been successfully updated.')->flash(); Alert::success('Settings have been successfully updated.')->flash();
return redirect()->route('admin.settings'); return redirect()->route('admin.settings');
} }
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,25 +21,23 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Http\Controllers\Admin; namespace Pterodactyl\Http\Controllers\Admin;
use Alert;
use DB; use DB;
use Log; use Log;
use Alert;
use Pterodactyl\Models; use Pterodactyl\Models;
use Pterodactyl\Repositories\DatabaseRepository;
use Pterodactyl\Exceptions\DisplayException;
use Pterodactyl\Exceptions\DisplayValidationException;
use Pterodactyl\Http\Controllers\Controller;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Pterodactyl\Exceptions\DisplayException;
use Pterodactyl\Http\Controllers\Controller;
use Pterodactyl\Repositories\DatabaseRepository;
use Pterodactyl\Exceptions\DisplayValidationException;
class DatabaseController extends Controller class DatabaseController extends Controller
{ {
/** /**
* Controller Constructor * Controller Constructor.
*/ */
public function __construct() public function __construct()
{ {
@ -63,7 +61,7 @@ class DatabaseController extends Controller
'nodes.name as a_linkedNode', 'nodes.name as a_linkedNode',
DB::raw('(SELECT COUNT(*) FROM `databases` WHERE `databases`.`db_server` = database_servers.id) as c_databases') DB::raw('(SELECT COUNT(*) FROM `databases` WHERE `databases`.`db_server` = database_servers.id) as c_databases')
)->leftJoin('nodes', 'nodes.id', '=', 'database_servers.linked_node') )->leftJoin('nodes', 'nodes.id', '=', 'database_servers.linked_node')
->paginate(20) ->paginate(20),
]); ]);
} }
@ -72,7 +70,7 @@ class DatabaseController extends Controller
return view('admin.databases.new', [ return view('admin.databases.new', [
'nodes' => Models\Node::select('nodes.id', 'nodes.name', 'locations.long as a_location') 'nodes' => Models\Node::select('nodes.id', 'nodes.name', 'locations.long as a_location')
->join('locations', 'locations.id', '=', 'nodes.location') ->join('locations', 'locations.id', '=', 'nodes.location')
->get() ->get(),
]); ]);
} }
@ -81,12 +79,13 @@ class DatabaseController extends Controller
try { try {
$repo = new DatabaseRepository; $repo = new DatabaseRepository;
$repo->add($request->except([ $repo->add($request->except([
'_token' '_token',
])); ]));
Alert::success('Successfully added a new database server to the system.')->flash(); Alert::success('Successfully added a new database server to the system.')->flash();
return redirect()->route('admin.databases', [ return redirect()->route('admin.databases', [
'tab' => 'tab_dbservers' 'tab' => 'tab_dbservers',
]); ]);
} catch (DisplayValidationException $ex) { } catch (DisplayValidationException $ex) {
return redirect()->route('admin.databases.new')->withErrors(json_decode($ex->getMessage()))->withInput(); return redirect()->route('admin.databases.new')->withErrors(json_decode($ex->getMessage()))->withInput();
@ -97,6 +96,7 @@ class DatabaseController extends Controller
Log::error($ex); Log::error($ex);
Alert::danger('An error occurred while attempting to delete this database server from the system.')->flash(); Alert::danger('An error occurred while attempting to delete this database server from the system.')->flash();
} }
return redirect()->route('admin.databases.new')->withInput(); return redirect()->route('admin.databases.new')->withInput();
} }
} }
@ -108,8 +108,9 @@ class DatabaseController extends Controller
$repo->drop($id); $repo->drop($id);
} catch (\Exception $ex) { } catch (\Exception $ex) {
Log::error($ex); Log::error($ex);
return response()->json([ return response()->json([
'error' => ($ex instanceof DisplayException) ? $ex->getMessage() : 'An error occurred while attempting to delete this database from the system.' 'error' => ($ex instanceof DisplayException) ? $ex->getMessage() : 'An error occurred while attempting to delete this database from the system.',
], 500); ], 500);
} }
} }
@ -121,10 +122,10 @@ class DatabaseController extends Controller
$repo->delete($id); $repo->delete($id);
} catch (\Exception $ex) { } catch (\Exception $ex) {
Log::error($ex); Log::error($ex);
return response()->json([ return response()->json([
'error' => ($ex instanceof DisplayException) ? $ex->getMessage() : 'An error occurred while attempting to delete this database server from the system.' 'error' => ($ex instanceof DisplayException) ? $ex->getMessage() : 'An error occurred while attempting to delete this database server from the system.',
], 500); ], 500);
} }
} }
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,23 +21,20 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Http\Controllers\Admin; namespace Pterodactyl\Http\Controllers\Admin;
use DB; use DB;
use Alert; use Alert;
use Pterodactyl\Models; use Pterodactyl\Models;
use Pterodactyl\Repositories\LocationRepository;
use Pterodactyl\Http\Controllers\Controller;
use Pterodactyl\Exceptions\DisplayValidationException;
use Pterodactyl\Exceptions\DisplayException;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Pterodactyl\Exceptions\DisplayException;
use Pterodactyl\Http\Controllers\Controller;
use Pterodactyl\Repositories\LocationRepository;
use Pterodactyl\Exceptions\DisplayValidationException;
class LocationsController extends Controller class LocationsController extends Controller
{ {
public function __construct() public function __construct()
{ {
// //
@ -50,7 +47,7 @@ class LocationsController extends Controller
'locations.*', 'locations.*',
DB::raw('(SELECT COUNT(*) FROM nodes WHERE nodes.location = locations.id) as a_nodeCount'), DB::raw('(SELECT COUNT(*) FROM nodes WHERE nodes.location = locations.id) as a_nodeCount'),
DB::raw('(SELECT COUNT(*) FROM servers WHERE servers.node IN (SELECT nodes.id FROM nodes WHERE nodes.location = locations.id)) as a_serverCount') DB::raw('(SELECT COUNT(*) FROM servers WHERE servers.node IN (SELECT nodes.id FROM nodes WHERE nodes.location = locations.id)) as a_serverCount')
)->paginate(20) )->paginate(20),
]); ]);
} }
@ -62,19 +59,20 @@ class LocationsController extends Controller
DB::raw('(SELECT COUNT(*) FROM servers WHERE servers.node IN (SELECT nodes.id FROM nodes WHERE nodes.location = locations.id)) as a_serverCount') DB::raw('(SELECT COUNT(*) FROM servers WHERE servers.node IN (SELECT nodes.id FROM nodes WHERE nodes.location = locations.id)) as a_serverCount')
)->where('id', $id)->first(); )->where('id', $id)->first();
if (!$model) { if (! $model) {
return response()->json([ return response()->json([
'error' => 'No location with that ID exists on the system.' 'error' => 'No location with that ID exists on the system.',
], 404); ], 404);
} }
if ($model->a_nodeCount > 0 || $model->a_serverCount > 0) { if ($model->a_nodeCount > 0 || $model->a_serverCount > 0) {
return response()->json([ return response()->json([
'error' => 'You cannot remove a location that is currently assigned to a node or server.' 'error' => 'You cannot remove a location that is currently assigned to a node or server.',
], 422); ], 422);
} }
$model->delete(); $model->delete();
return response('', 204); return response('', 204);
} }
@ -83,10 +81,11 @@ class LocationsController extends Controller
try { try {
$location = new LocationRepository; $location = new LocationRepository;
$location->edit($id, $request->all()); $location->edit($id, $request->all());
return response('', 204); return response('', 204);
} catch (DisplayValidationException $ex) { } catch (DisplayValidationException $ex) {
return response()->json([ return response()->json([
'error' => 'There was a validation error while processing this request. Location descriptions must be between 1 and 255 characters, and the location code must be between 1 and 10 characters with no spaces or special characters.' 'error' => 'There was a validation error while processing this request. Location descriptions must be between 1 and 255 characters, and the location code must be between 1 and 10 characters with no spaces or special characters.',
], 422); ], 422);
} catch (\Exception $ex) { } catch (\Exception $ex) {
// This gets caught and processed into JSON anyways. // This gets caught and processed into JSON anyways.
@ -99,9 +98,10 @@ class LocationsController extends Controller
try { try {
$location = new LocationRepository; $location = new LocationRepository;
$id = $location->create($request->except([ $id = $location->create($request->except([
'_token' '_token',
])); ]));
Alert::success('New location successfully added.')->flash(); Alert::success('New location successfully added.')->flash();
return redirect()->route('admin.locations'); return redirect()->route('admin.locations');
} catch (DisplayValidationException $ex) { } catch (DisplayValidationException $ex) {
return redirect()->route('admin.locations')->withErrors(json_decode($ex->getMessage()))->withInput(); return redirect()->route('admin.locations')->withErrors(json_decode($ex->getMessage()))->withInput();
@ -111,7 +111,7 @@ class LocationsController extends Controller
Log::error($ex); Log::error($ex);
Alert::danger('An unhandled exception occured while attempting to add this location. Please try again.')->flash(); Alert::danger('An unhandled exception occured while attempting to add this location. Please try again.')->flash();
} }
return redirect()->route('admin.locations')->withInput(); return redirect()->route('admin.locations')->withInput();
} }
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,27 +21,24 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Http\Controllers\Admin; namespace Pterodactyl\Http\Controllers\Admin;
use Alert;
use Debugbar;
use Log;
use DB; use DB;
use Log;
use Alert;
use Validator; use Validator;
use Pterodactyl\Models; use Pterodactyl\Models;
use Pterodactyl\Repositories\NodeRepository;
use Pterodactyl\Exceptions\DisplayException;
use Pterodactyl\Exceptions\DisplayValidationException;
use Pterodactyl\Http\Controllers\Controller;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Pterodactyl\Exceptions\DisplayException;
use Pterodactyl\Http\Controllers\Controller;
use Pterodactyl\Repositories\NodeRepository;
use Pterodactyl\Exceptions\DisplayValidationException;
class NodesController extends Controller class NodesController extends Controller
{ {
/** /**
* Controller Constructor * Controller Constructor.
*/ */
public function __construct() public function __construct()
{ {
@ -50,7 +47,7 @@ class NodesController extends Controller
public function getScript(Request $request, $id) public function getScript(Request $request, $id)
{ {
return response()->view('admin.nodes.remote.deploy', [ 'node' => Models\Node::findOrFail($id) ])->header('Content-Type', 'text/plain'); return response()->view('admin.nodes.remote.deploy', ['node' => Models\Node::findOrFail($id)])->header('Content-Type', 'text/plain');
} }
public function getIndex(Request $request) public function getIndex(Request $request)
@ -66,13 +63,14 @@ class NodesController extends Controller
public function getNew(Request $request) public function getNew(Request $request)
{ {
if (!Models\Location::all()->count()) { if (! Models\Location::all()->count()) {
Alert::warning('You must add a location before you can add a new node.')->flash(); Alert::warning('You must add a location before you can add a new node.')->flash();
return redirect()->route('admin.locations'); return redirect()->route('admin.locations');
} }
return view('admin.nodes.new', [ return view('admin.nodes.new', [
'locations' => Models\Location::all() 'locations' => Models\Location::all(),
]); ]);
} }
@ -81,12 +79,13 @@ class NodesController extends Controller
try { try {
$node = new NodeRepository; $node = new NodeRepository;
$new = $node->create($request->except([ $new = $node->create($request->except([
'_token' '_token',
])); ]));
Alert::success('Successfully created new node. <strong>Before you can add any servers you need to first assign some IP addresses and ports.</strong>')->flash(); Alert::success('Successfully created new node. <strong>Before you can add any servers you need to first assign some IP addresses and ports.</strong>')->flash();
return redirect()->route('admin.nodes.view', [ return redirect()->route('admin.nodes.view', [
'id' => $new, 'id' => $new,
'tab' => 'tab_allocation' 'tab' => 'tab_allocation',
]); ]);
} catch (DisplayValidationException $e) { } catch (DisplayValidationException $e) {
return redirect()->route('admin.nodes.new')->withErrors(json_decode($e->getMessage()))->withInput(); return redirect()->route('admin.nodes.new')->withErrors(json_decode($e->getMessage()))->withInput();
@ -96,6 +95,7 @@ class NodesController extends Controller
Log::error($e); Log::error($e);
Alert::danger('An unhandled exception occured while attempting to add this node. Please try again.')->flash(); Alert::danger('An unhandled exception occured while attempting to add this node. Please try again.')->flash();
} }
return redirect()->route('admin.nodes.new')->withInput(); return redirect()->route('admin.nodes.new')->withInput();
} }
@ -129,12 +129,13 @@ class NodesController extends Controller
try { try {
$node = new NodeRepository; $node = new NodeRepository;
$node->update($id, $request->except([ $node->update($id, $request->except([
'_token' '_token',
])); ]));
Alert::success('Successfully update this node\'s information. If you changed any daemon settings you will need to restart it now.')->flash(); Alert::success('Successfully update this node\'s information. If you changed any daemon settings you will need to restart it now.')->flash();
return redirect()->route('admin.nodes.view', [ return redirect()->route('admin.nodes.view', [
'id' => $id, 'id' => $id,
'tab' => 'tab_settings' 'tab' => 'tab_settings',
]); ]);
} catch (DisplayValidationException $e) { } catch (DisplayValidationException $e) {
return redirect()->route('admin.nodes.view', $id)->withErrors(json_decode($e->getMessage()))->withInput(); return redirect()->route('admin.nodes.view', $id)->withErrors(json_decode($e->getMessage()))->withInput();
@ -144,9 +145,10 @@ class NodesController extends Controller
Log::error($e); Log::error($e);
Alert::danger('An unhandled exception occured while attempting to edit this node. Please try again.')->flash(); Alert::danger('An unhandled exception occured while attempting to edit this node. Please try again.')->flash();
} }
return redirect()->route('admin.nodes.view', [ return redirect()->route('admin.nodes.view', [
'id' => $id, 'id' => $id,
'tab' => 'tab_settings' 'tab' => 'tab_settings',
])->withInput(); ])->withInput();
} }
@ -155,9 +157,10 @@ class NodesController extends Controller
$query = Models\Allocation::where('node', $node)->whereNull('assigned_to')->where('id', $allocation)->delete(); $query = Models\Allocation::where('node', $node)->whereNull('assigned_to')->where('id', $allocation)->delete();
if ((int) $query === 0) { if ((int) $query === 0) {
return response()->json([ return response()->json([
'error' => 'Unable to find an allocation matching those details to delete.' 'error' => 'Unable to find an allocation matching those details to delete.',
], 400); ], 400);
} }
return response('', 204); return response('', 204);
} }
@ -166,21 +169,23 @@ class NodesController extends Controller
$query = Models\Allocation::where('node', $node)->whereNull('assigned_to')->where('ip', $request->input('ip'))->delete(); $query = Models\Allocation::where('node', $node)->whereNull('assigned_to')->where('ip', $request->input('ip'))->delete();
if ((int) $query === 0) { if ((int) $query === 0) {
Alert::danger('There was an error while attempting to delete allocations on that IP.')->flash(); Alert::danger('There was an error while attempting to delete allocations on that IP.')->flash();
return redirect()->route('admin.nodes.view', [ return redirect()->route('admin.nodes.view', [
'id' => $node, 'id' => $node,
'tab' => 'tab_allocations' 'tab' => 'tab_allocations',
]); ]);
} }
Alert::success('Deleted all unallocated ports for <code>' . $request->input('ip') . '</code>.')->flash(); Alert::success('Deleted all unallocated ports for <code>' . $request->input('ip') . '</code>.')->flash();
return redirect()->route('admin.nodes.view', [ return redirect()->route('admin.nodes.view', [
'id' => $node, 'id' => $node,
'tab' => 'tab_allocation' 'tab' => 'tab_allocation',
]); ]);
} }
public function setAlias(Request $request, $node) public function setAlias(Request $request, $node)
{ {
if (!$request->input('allocation')) { if (! $request->input('allocation')) {
return response('Missing required parameters.', 422); return response('Missing required parameters.', 422);
} }
@ -198,36 +203,36 @@ class NodesController extends Controller
public function getAllocationsJson(Request $request, $id) public function getAllocationsJson(Request $request, $id)
{ {
$allocations = Models\Allocation::select('ip')->where('node', $id)->groupBy('ip')->get(); $allocations = Models\Allocation::select('ip')->where('node', $id)->groupBy('ip')->get();
return response()->json($allocations); return response()->json($allocations);
} }
public function postAllocations(Request $request, $id) public function postAllocations(Request $request, $id)
{ {
$validator = Validator::make($request->all(), [ $validator = Validator::make($request->all(), [
'allocate_ip.*' => 'required|string', 'allocate_ip.*' => 'required|string',
'allocate_port.*' => 'required' 'allocate_port.*' => 'required',
]); ]);
if ($validator->fails()) { if ($validator->fails()) {
return redirect()->route('admin.nodes.view', [ return redirect()->route('admin.nodes.view', [
'id' => $id, 'id' => $id,
'tab' => 'tab_allocation' 'tab' => 'tab_allocation',
])->withErrors($validator->errors())->withInput(); ])->withErrors($validator->errors())->withInput();
} }
$processedData = []; $processedData = [];
foreach($request->input('allocate_ip') as $ip) { foreach ($request->input('allocate_ip') as $ip) {
if (!array_key_exists($ip, $processedData)) { if (! array_key_exists($ip, $processedData)) {
$processedData[$ip] = []; $processedData[$ip] = [];
} }
} }
foreach($request->input('allocate_port') as $portid => $ports) { foreach ($request->input('allocate_port') as $portid => $ports) {
if (array_key_exists($portid, $request->input('allocate_ip'))) { if (array_key_exists($portid, $request->input('allocate_ip'))) {
$json = json_decode($ports); $json = json_decode($ports);
if (json_last_error() === 0 && !empty($json)) { if (json_last_error() === 0 && ! empty($json)) {
foreach($json as &$parsed) { foreach ($json as &$parsed) {
array_push($processedData[$request->input('allocate_ip')[$portid]], $parsed->value); array_push($processedData[$request->input('allocate_ip')[$portid]], $parsed->value);
} }
} }
@ -246,7 +251,7 @@ class NodesController extends Controller
} finally { } finally {
return redirect()->route('admin.nodes.view', [ return redirect()->route('admin.nodes.view', [
'id' => $id, 'id' => $id,
'tab' => 'tab_allocation' 'tab' => 'tab_allocation',
]); ]);
} }
} }
@ -257,6 +262,7 @@ class NodesController extends Controller
$repo = new NodeRepository; $repo = new NodeRepository;
$repo->delete($id); $repo->delete($id);
Alert::success('Successfully deleted the requested node from the panel.')->flash(); Alert::success('Successfully deleted the requested node from the panel.')->flash();
return redirect()->route('admin.nodes'); return redirect()->route('admin.nodes');
} catch (DisplayException $e) { } catch (DisplayException $e) {
Alert::danger($e->getMessage())->flash(); Alert::danger($e->getMessage())->flash();
@ -267,8 +273,7 @@ class NodesController extends Controller
return redirect()->route('admin.nodes.view', [ return redirect()->route('admin.nodes.view', [
'id' => $id, 'id' => $id,
'tab' => 'tab_delete' 'tab' => 'tab_delete',
]); ]);
} }
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,28 +21,24 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Http\Controllers\Admin; namespace Pterodactyl\Http\Controllers\Admin;
use Alert;
use Debugbar;
use DB; use DB;
use Log; use Log;
use Alert;
use Pterodactyl\Models; use Pterodactyl\Models;
use Illuminate\Http\Request;
use Pterodactyl\Exceptions\DisplayException;
use Pterodactyl\Http\Controllers\Controller;
use Pterodactyl\Repositories\ServerRepository; use Pterodactyl\Repositories\ServerRepository;
use Pterodactyl\Repositories\DatabaseRepository; use Pterodactyl\Repositories\DatabaseRepository;
use Pterodactyl\Exceptions\DisplayException;
use Pterodactyl\Exceptions\DisplayValidationException; use Pterodactyl\Exceptions\DisplayValidationException;
use Pterodactyl\Http\Controllers\Controller;
use Illuminate\Http\Request;
class ServersController extends Controller class ServersController extends Controller
{ {
/** /**
* Controller Constructor * Controller Constructor.
*/ */
public function __construct() public function __construct()
{ {
@ -62,17 +58,17 @@ class ServersController extends Controller
->join('users', 'servers.owner', '=', 'users.id') ->join('users', 'servers.owner', '=', 'users.id')
->join('allocations', 'servers.allocation', '=', 'allocations.id'); ->join('allocations', 'servers.allocation', '=', 'allocations.id');
if ($request->input('filter') && !is_null($request->input('filter'))) { if ($request->input('filter') && ! is_null($request->input('filter'))) {
preg_match_all('/[^\s"\']+|"([^"]*)"|\'([^\']*)\'/', urldecode($request->input('filter')), $matches); preg_match_all('/[^\s"\']+|"([^"]*)"|\'([^\']*)\'/', urldecode($request->input('filter')), $matches);
foreach($matches[0] as $match) { foreach ($matches[0] as $match) {
$match = str_replace('"', '', $match); $match = str_replace('"', '', $match);
if (strpos($match, ':')) { if (strpos($match, ':')) {
list($field, $term) = explode(':', $match); list($field, $term) = explode(':', $match);
if ($field === 'node') { if ($field === 'node') {
$field = 'nodes.name'; $field = 'nodes.name';
} else if ($field === 'owner') { } elseif ($field === 'owner') {
$field = 'users.email'; $field = 'users.email';
} else if (!strpos($field, '.')) { } elseif (! strpos($field, '.')) {
$field = 'servers.' . $field; $field = 'servers.' . $field;
} }
@ -107,7 +103,7 @@ class ServersController extends Controller
} }
return view('admin.servers.index', [ return view('admin.servers.index', [
'servers' => $servers 'servers' => $servers,
]); ]);
} }
@ -115,7 +111,7 @@ class ServersController extends Controller
{ {
return view('admin.servers.new', [ return view('admin.servers.new', [
'locations' => Models\Location::all(), 'locations' => Models\Location::all(),
'services' => Models\Service::all() 'services' => Models\Service::all(),
]); ]);
} }
@ -123,9 +119,7 @@ class ServersController extends Controller
{ {
$server = Models\Server::withTrashed()->select( $server = Models\Server::withTrashed()->select(
'servers.*', 'servers.*',
'nodes.name as a_nodeName',
'users.email as a_ownerEmail', 'users.email as a_ownerEmail',
'locations.long as a_locationName',
'services.name as a_serviceName', 'services.name as a_serviceName',
DB::raw('IFNULL(service_options.executable, services.executable) as a_serviceExecutable'), DB::raw('IFNULL(service_options.executable, services.executable) as a_serviceExecutable'),
'service_options.docker_image', 'service_options.docker_image',
@ -135,19 +129,24 @@ class ServersController extends Controller
'allocations.ip_alias' 'allocations.ip_alias'
)->join('nodes', 'servers.node', '=', 'nodes.id') )->join('nodes', 'servers.node', '=', 'nodes.id')
->join('users', 'servers.owner', '=', 'users.id') ->join('users', 'servers.owner', '=', 'users.id')
->join('locations', 'nodes.location', '=', 'locations.id')
->join('services', 'servers.service', '=', 'services.id') ->join('services', 'servers.service', '=', 'services.id')
->join('service_options', 'servers.option', '=', 'service_options.id') ->join('service_options', 'servers.option', '=', 'service_options.id')
->join('allocations', 'servers.allocation', '=', 'allocations.id') ->join('allocations', 'servers.allocation', '=', 'allocations.id')
->where('servers.id', $id) ->where('servers.id', $id)
->first(); ->first();
if (!$server) { if (! $server) {
return abort(404); return abort(404);
} }
return view('admin.servers.view', [ return view('admin.servers.view', [
'server' => $server, 'server' => $server,
'node' => Models\Node::select(
'nodes.*',
'locations.long as a_locationName'
)->join('locations', 'nodes.location', '=', 'locations.id')
->where('nodes.id', $server->node)
->first(),
'assigned' => Models\Allocation::where('assigned_to', $id)->orderBy('ip', 'asc')->orderBy('port', 'asc')->get(), 'assigned' => Models\Allocation::where('assigned_to', $id)->orderBy('ip', 'asc')->orderBy('port', 'asc')->get(),
'unassigned' => Models\Allocation::where('node', $server->node)->whereNull('assigned_to')->orderBy('ip', 'asc')->orderBy('port', 'asc')->get(), 'unassigned' => Models\Allocation::where('node', $server->node)->whereNull('assigned_to')->orderBy('ip', 'asc')->orderBy('port', 'asc')->get(),
'startup' => Models\ServiceVariables::select('service_variables.*', 'server_variables.variable_value as a_serverValue') 'startup' => Models\ServiceVariables::select('service_variables.*', 'server_variables.variable_value as a_serverValue')
@ -159,30 +158,29 @@ class ServersController extends Controller
->where('server_id', $server->id) ->where('server_id', $server->id)
->join('database_servers', 'database_servers.id', '=', 'databases.db_server') ->join('database_servers', 'database_servers.id', '=', 'databases.db_server')
->get(), ->get(),
'db_servers' => Models\DatabaseServer::all() 'db_servers' => Models\DatabaseServer::all(),
]); ]);
} }
public function postNewServer(Request $request) public function postNewServer(Request $request)
{ {
try { try {
$server = new ServerRepository; $server = new ServerRepository;
$response = $server->create($request->except([ $response = $server->create($request->all());
'_token'
])); return redirect()->route('admin.servers.view', ['id' => $response]);
return redirect()->route('admin.servers.view', [ 'id' => $response ]);
} catch (DisplayValidationException $ex) { } catch (DisplayValidationException $ex) {
return redirect()->route('admin.servers.new')->withErrors(json_decode($ex->getMessage()))->withInput(); return redirect()->route('admin.servers.new')->withErrors(json_decode($ex->getMessage()))->withInput();
} catch (DisplayException $ex) { } catch (DisplayException $ex) {
Alert::danger($ex->getMessage())->flash(); Alert::danger($ex->getMessage())->flash();
return redirect()->route('admin.servers.new')->withInput(); return redirect()->route('admin.servers.new')->withInput();
} catch (\Exception $ex) { } catch (\Exception $ex) {
Log::error($ex); Log::error($ex);
Alert::danger('An unhandled exception occured while attemping to add this server. Please try again.')->flash(); Alert::danger('An unhandled exception occured while attemping to add this server. Please try again.')->flash();
return redirect()->route('admin.servers.new')->withInput(); return redirect()->route('admin.servers.new')->withInput();
} }
} }
/** /**
@ -193,15 +191,13 @@ class ServersController extends Controller
*/ */
public function postNewServerGetNodes(Request $request) public function postNewServerGetNodes(Request $request)
{ {
if (! $request->input('location')) {
if(!$request->input('location')) {
return response()->json([ return response()->json([
'error' => 'Missing location in request.' 'error' => 'Missing location in request.',
], 500); ], 500);
} }
return response()->json(Models\Node::select('id', 'name', 'public')->where('location', $request->input('location'))->get()); return response()->json(Models\Node::select('id', 'name', 'public')->where('location', $request->input('location'))->get());
} }
/** /**
@ -212,25 +208,24 @@ class ServersController extends Controller
*/ */
public function postNewServerGetIps(Request $request) public function postNewServerGetIps(Request $request)
{ {
if (! $request->input('node')) {
if(!$request->input('node')) {
return response()->json([ return response()->json([
'error' => 'Missing node in request.' 'error' => 'Missing node in request.',
], 500); ], 500);
} }
$ips = Models\Allocation::where('node', $request->input('node'))->whereNull('assigned_to')->get(); $ips = Models\Allocation::where('node', $request->input('node'))->whereNull('assigned_to')->get();
$listing = []; $listing = [];
foreach($ips as &$ip) { foreach ($ips as &$ip) {
if (array_key_exists($ip->ip, $listing)) { if (array_key_exists($ip->ip, $listing)) {
$listing[$ip->ip] = array_merge($listing[$ip->ip], [$ip->port]); $listing[$ip->ip] = array_merge($listing[$ip->ip], [$ip->port]);
} else { } else {
$listing[$ip->ip] = [$ip->port]; $listing[$ip->ip] = [$ip->port];
} }
} }
return response()->json($listing);
return response()->json($listing);
} }
/** /**
@ -241,16 +236,15 @@ class ServersController extends Controller
*/ */
public function postNewServerServiceOptions(Request $request) public function postNewServerServiceOptions(Request $request)
{ {
if (! $request->input('service')) {
if(!$request->input('service')) {
return response()->json([ return response()->json([
'error' => 'Missing service in request.' 'error' => 'Missing service in request.',
], 500); ], 500);
} }
$service = Models\Service::select('executable', 'startup')->where('id', $request->input('service'))->first(); $service = Models\Service::select('executable', 'startup')->where('id', $request->input('service'))->first();
return response()->json(Models\ServiceOptions::select('id', 'name', 'docker_image')->where('parent_service', $request->input('service'))->orderBy('name', 'asc')->get());
return response()->json(Models\ServiceOptions::select('id', 'name', 'docker_image')->where('parent_service', $request->input('service'))->orderBy('name', 'asc')->get());
} }
/** /**
@ -261,10 +255,9 @@ class ServersController extends Controller
*/ */
public function postNewServerOptionDetails(Request $request) public function postNewServerOptionDetails(Request $request)
{ {
if (! $request->input('option')) {
if(!$request->input('option')) {
return response()->json([ return response()->json([
'error' => 'Missing option in request.' 'error' => 'Missing option in request.',
], 500); ], 500);
} }
@ -279,28 +272,25 @@ class ServersController extends Controller
'packs' => Models\ServicePack::select('id', 'name', 'version')->where('option', $request->input('option'))->where('selectable', true)->get(), 'packs' => Models\ServicePack::select('id', 'name', 'version')->where('option', $request->input('option'))->where('selectable', true)->get(),
'variables' => Models\ServiceVariables::where('option_id', $request->input('option'))->get(), 'variables' => Models\ServiceVariables::where('option_id', $request->input('option'))->get(),
'exec' => $option->executable, 'exec' => $option->executable,
'startup' => $option->startup 'startup' => $option->startup,
]); ]);
} }
public function postUpdateServerDetails(Request $request, $id) public function postUpdateServerDetails(Request $request, $id)
{ {
try { try {
$server = new ServerRepository; $server = new ServerRepository;
$server->updateDetails($id, [ $server->updateDetails($id, [
'owner' => $request->input('owner'), 'owner' => $request->input('owner'),
'name' => $request->input('name'), 'name' => $request->input('name'),
'reset_token' => ($request->input('reset_token', false) === 'on') ? true : false 'reset_token' => ($request->input('reset_token', false) === 'on') ? true : false,
]); ]);
Alert::success('Server details were successfully updated.')->flash(); Alert::success('Server details were successfully updated.')->flash();
} catch (DisplayValidationException $ex) { } catch (DisplayValidationException $ex) {
return redirect()->route('admin.servers.view', [ return redirect()->route('admin.servers.view', [
'id' => $id, 'id' => $id,
'tab' => 'tab_details' 'tab' => 'tab_details',
])->withErrors(json_decode($ex->getMessage()))->withInput(); ])->withErrors(json_decode($ex->getMessage()))->withInput();
} catch (DisplayException $ex) { } catch (DisplayException $ex) {
Alert::danger($ex->getMessage())->flash(); Alert::danger($ex->getMessage())->flash();
@ -311,21 +301,22 @@ class ServersController extends Controller
return redirect()->route('admin.servers.view', [ return redirect()->route('admin.servers.view', [
'id' => $id, 'id' => $id,
'tab' => 'tab_details' 'tab' => 'tab_details',
])->withInput(); ])->withInput();
} }
public function postUpdateContainerDetails(Request $request, $id) { public function postUpdateContainerDetails(Request $request, $id)
{
try { try {
$server = new ServerRepository; $server = new ServerRepository;
$server->updateContainer($id, [ $server->updateContainer($id, [
'image' => $request->input('docker_image') 'image' => $request->input('docker_image'),
]); ]);
Alert::success('Successfully updated this server\'s docker image.')->flash(); Alert::success('Successfully updated this server\'s docker image.')->flash();
} catch (DisplayValidationException $ex) { } catch (DisplayValidationException $ex) {
return redirect()->route('admin.servers.view', [ return redirect()->route('admin.servers.view', [
'id' => $id, 'id' => $id,
'tab' => 'tab_details' 'tab' => 'tab_details',
])->withErrors(json_decode($ex->getMessage()))->withInput(); ])->withErrors(json_decode($ex->getMessage()))->withInput();
} catch (DisplayException $ex) { } catch (DisplayException $ex) {
Alert::danger($ex->getMessage())->flash(); Alert::danger($ex->getMessage())->flash();
@ -336,11 +327,12 @@ class ServersController extends Controller
return redirect()->route('admin.servers.view', [ return redirect()->route('admin.servers.view', [
'id' => $id, 'id' => $id,
'tab' => 'tab_details' 'tab' => 'tab_details',
]); ]);
} }
public function postUpdateServerToggleBuild(Request $request, $id) { public function postUpdateServerToggleBuild(Request $request, $id)
{
$server = Models\Server::findOrFail($id); $server = Models\Server::findOrFail($id);
$node = Models\Node::findOrFail($server->node); $node = Models\Node::findOrFail($server->node);
$client = Models\Node::guzzleRequest($server->node); $client = Models\Node::guzzleRequest($server->node);
@ -349,8 +341,8 @@ class ServersController extends Controller
$res = $client->request('POST', '/server/rebuild', [ $res = $client->request('POST', '/server/rebuild', [
'headers' => [ 'headers' => [
'X-Access-Server' => $server->uuid, 'X-Access-Server' => $server->uuid,
'X-Access-Token' => $node->daemonSecret 'X-Access-Token' => $node->daemonSecret,
] ],
]); ]);
Alert::success('A rebuild has been queued successfully. It will run the next time this server is booted.')->flash(); Alert::success('A rebuild has been queued successfully. It will run the next time this server is booted.')->flash();
} catch (\GuzzleHttp\Exception\TransferException $ex) { } catch (\GuzzleHttp\Exception\TransferException $ex) {
@ -360,14 +352,13 @@ class ServersController extends Controller
return redirect()->route('admin.servers.view', [ return redirect()->route('admin.servers.view', [
'id' => $id, 'id' => $id,
'tab' => 'tab_manage' 'tab' => 'tab_manage',
]); ]);
} }
public function postUpdateServerUpdateBuild(Request $request, $id) public function postUpdateServerUpdateBuild(Request $request, $id)
{ {
try { try {
$server = new ServerRepository; $server = new ServerRepository;
$server->changeBuild($id, [ $server->changeBuild($id, [
'default' => $request->input('default'), 'default' => $request->input('default'),
@ -382,13 +373,14 @@ class ServersController extends Controller
} catch (DisplayValidationException $ex) { } catch (DisplayValidationException $ex) {
return redirect()->route('admin.servers.view', [ return redirect()->route('admin.servers.view', [
'id' => $id, 'id' => $id,
'tab' => 'tab_build' 'tab' => 'tab_build',
])->withErrors(json_decode($ex->getMessage()))->withInput(); ])->withErrors(json_decode($ex->getMessage()))->withInput();
} catch (DisplayException $ex) { } catch (DisplayException $ex) {
Alert::danger($ex->getMessage())->flash(); Alert::danger($ex->getMessage())->flash();
return redirect()->route('admin.servers.view', [ return redirect()->route('admin.servers.view', [
'id' => $id, 'id' => $id,
'tab' => 'tab_build' 'tab' => 'tab_build',
]); ]);
} catch (\Exception $ex) { } catch (\Exception $ex) {
Log::error($ex); Log::error($ex);
@ -397,7 +389,7 @@ class ServersController extends Controller
return redirect()->route('admin.servers.view', [ return redirect()->route('admin.servers.view', [
'id' => $id, 'id' => $id,
'tab' => 'tab_build' 'tab' => 'tab_build',
]); ]);
} }
@ -407,16 +399,18 @@ class ServersController extends Controller
$server = new ServerRepository; $server = new ServerRepository;
$server->deleteServer($id, $force); $server->deleteServer($id, $force);
Alert::success('Server has been marked for deletion on the system.')->flash(); Alert::success('Server has been marked for deletion on the system.')->flash();
return redirect()->route('admin.servers'); return redirect()->route('admin.servers');
} catch (DisplayException $ex) { } catch (DisplayException $ex) {
Alert::danger($ex->getMessage())->flash(); Alert::danger($ex->getMessage())->flash();
} catch(\Exception $ex) { } catch (\Exception $ex) {
Log::error($ex); Log::error($ex);
Alert::danger('An unhandled exception occured while attemping to delete this server. Please try again.')->flash(); Alert::danger('An unhandled exception occured while attemping to delete this server. Please try again.')->flash();
} }
return redirect()->route('admin.servers.view', [ return redirect()->route('admin.servers.view', [
'id' => $id, 'id' => $id,
'tab' => 'tab_delete' 'tab' => 'tab_delete',
]); ]);
} }
@ -428,13 +422,13 @@ class ServersController extends Controller
Alert::success('Server status was successfully toggled.')->flash(); Alert::success('Server status was successfully toggled.')->flash();
} catch (DisplayException $ex) { } catch (DisplayException $ex) {
Alert::danger($ex->getMessage())->flash(); Alert::danger($ex->getMessage())->flash();
} catch(\Exception $ex) { } catch (\Exception $ex) {
Log::error($ex); Log::error($ex);
Alert::danger('An unhandled exception occured while attemping to toggle this servers status.')->flash(); Alert::danger('An unhandled exception occured while attemping to toggle this servers status.')->flash();
} finally { } finally {
return redirect()->route('admin.servers.view', [ return redirect()->route('admin.servers.view', [
'id' => $id, 'id' => $id,
'tab' => 'tab_manage' 'tab' => 'tab_manage',
]); ]);
} }
} }
@ -444,18 +438,18 @@ class ServersController extends Controller
try { try {
$server = new ServerRepository; $server = new ServerRepository;
$server->updateStartup($id, $request->except([ $server->updateStartup($id, $request->except([
'_token' '_token',
]), true); ]), true);
Alert::success('Server startup variables were successfully updated.')->flash(); Alert::success('Server startup variables were successfully updated.')->flash();
} catch (\Pterodactyl\Exceptions\DisplayException $e) { } catch (\Pterodactyl\Exceptions\DisplayException $e) {
Alert::danger($e->getMessage())->flash(); Alert::danger($e->getMessage())->flash();
} catch(\Exception $e) { } catch (\Exception $e) {
Log::error($e); Log::error($e);
Alert::danger('An unhandled exception occured while attemping to update startup variables for this server. Please try again.')->flash(); Alert::danger('An unhandled exception occured while attemping to update startup variables for this server. Please try again.')->flash();
} finally { } finally {
return redirect()->route('admin.servers.view', [ return redirect()->route('admin.servers.view', [
'id' => $id, 'id' => $id,
'tab' => 'tab_startup' 'tab' => 'tab_startup',
])->withInput(); ])->withInput();
} }
} }
@ -465,13 +459,13 @@ class ServersController extends Controller
try { try {
$repo = new DatabaseRepository; $repo = new DatabaseRepository;
$repo->create($id, $request->except([ $repo->create($id, $request->except([
'_token' '_token',
])); ]));
Alert::success('Added new database to this server.')->flash(); Alert::success('Added new database to this server.')->flash();
} catch (DisplayValidationException $ex) { } catch (DisplayValidationException $ex) {
return redirect()->route('admin.servers.view', [ return redirect()->route('admin.servers.view', [
'id' => $id, 'id' => $id,
'tab' => 'tab_database' 'tab' => 'tab_database',
])->withInput()->withErrors(json_decode($ex->getMessage()))->withInput(); ])->withInput()->withErrors(json_decode($ex->getMessage()))->withInput();
} catch (\Exception $ex) { } catch (\Exception $ex) {
Log::error($ex); Log::error($ex);
@ -480,7 +474,7 @@ class ServersController extends Controller
return redirect()->route('admin.servers.view', [ return redirect()->route('admin.servers.view', [
'id' => $id, 'id' => $id,
'tab' => 'tab_database' 'tab' => 'tab_database',
])->withInput(); ])->withInput();
} }
@ -492,13 +486,13 @@ class ServersController extends Controller
Alert::success('Server has been suspended on the system. All running processes have been stopped and will not be startable until it is un-suspended.'); Alert::success('Server has been suspended on the system. All running processes have been stopped and will not be startable until it is un-suspended.');
} catch (DisplayException $e) { } catch (DisplayException $e) {
Alert::danger($e->getMessage())->flash(); Alert::danger($e->getMessage())->flash();
} catch(\Exception $e) { } catch (\Exception $e) {
Log::error($e); Log::error($e);
Alert::danger('An unhandled exception occured while attemping to suspend this server. Please try again.')->flash(); Alert::danger('An unhandled exception occured while attemping to suspend this server. Please try again.')->flash();
} finally { } finally {
return redirect()->route('admin.servers.view', [ return redirect()->route('admin.servers.view', [
'id' => $id, 'id' => $id,
'tab' => 'tab_manage' 'tab' => 'tab_manage',
]); ]);
} }
} }
@ -511,13 +505,13 @@ class ServersController extends Controller
Alert::success('Server has been unsuspended on the system. Access has been re-enabled.'); Alert::success('Server has been unsuspended on the system. Access has been re-enabled.');
} catch (DisplayException $e) { } catch (DisplayException $e) {
Alert::danger($e->getMessage())->flash(); Alert::danger($e->getMessage())->flash();
} catch(\Exception $e) { } catch (\Exception $e) {
Log::error($e); Log::error($e);
Alert::danger('An unhandled exception occured while attemping to unsuspend this server. Please try again.')->flash(); Alert::danger('An unhandled exception occured while attemping to unsuspend this server. Please try again.')->flash();
} finally { } finally {
return redirect()->route('admin.servers.view', [ return redirect()->route('admin.servers.view', [
'id' => $id, 'id' => $id,
'tab' => 'tab_manage' 'tab' => 'tab_manage',
]); ]);
} }
} }
@ -526,27 +520,31 @@ class ServersController extends Controller
{ {
try { try {
$repo = new ServerRepository; $repo = new ServerRepository;
if (!is_null($request->input('cancel'))) { if (! is_null($request->input('cancel'))) {
$repo->cancelDeletion($id); $repo->cancelDeletion($id);
Alert::success('Server deletion has been cancelled. This server will remain suspended until you unsuspend it.')->flash(); Alert::success('Server deletion has been cancelled. This server will remain suspended until you unsuspend it.')->flash();
return redirect()->route('admin.servers.view', $id); return redirect()->route('admin.servers.view', $id);
} else if(!is_null($request->input('delete'))) { } elseif (! is_null($request->input('delete'))) {
$repo->deleteNow($id); $repo->deleteNow($id);
Alert::success('Server was successfully deleted from the system.')->flash(); Alert::success('Server was successfully deleted from the system.')->flash();
return redirect()->route('admin.servers'); return redirect()->route('admin.servers');
} else if(!is_null($request->input('force_delete'))) { } elseif (! is_null($request->input('force_delete'))) {
$repo->deleteNow($id, true); $repo->deleteNow($id, true);
Alert::success('Server was successfully force deleted from the system.')->flash(); Alert::success('Server was successfully force deleted from the system.')->flash();
return redirect()->route('admin.servers'); return redirect()->route('admin.servers');
} }
} catch (DisplayException $ex) { } catch (DisplayException $ex) {
Alert::danger($ex->getMessage())->flash(); Alert::danger($ex->getMessage())->flash();
return redirect()->route('admin.servers.view', $id); return redirect()->route('admin.servers.view', $id);
} catch (\Exception $ex) { } catch (\Exception $ex) {
Log::error($ex); Log::error($ex);
Alert::danger('An unhandled error occured while attempting to perform this action.')->flash(); Alert::danger('An unhandled error occured while attempting to perform this action.')->flash();
return redirect()->route('admin.servers.view', $id); return redirect()->route('admin.servers.view', $id);
} }
} }
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,25 +21,23 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Http\Controllers\Admin; namespace Pterodactyl\Http\Controllers\Admin;
use Alert;
use DB; use DB;
use Log; use Log;
use Validator; use Alert;
use Storage; use Storage;
use Validator;
use Pterodactyl\Models; use Pterodactyl\Models;
use Pterodactyl\Repositories\ServiceRepository;
use Pterodactyl\Exceptions\DisplayException;
use Pterodactyl\Exceptions\DisplayValidationException;
use Pterodactyl\Http\Controllers\Controller;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Pterodactyl\Exceptions\DisplayException;
use Pterodactyl\Http\Controllers\Controller;
use Pterodactyl\Repositories\ServiceRepository;
use Pterodactyl\Exceptions\DisplayValidationException;
class ServiceController extends Controller class ServiceController extends Controller
{ {
public function __construct() public function __construct()
{ {
// //
@ -51,7 +49,7 @@ class ServiceController extends Controller
'services' => Models\Service::select( 'services' => Models\Service::select(
'services.*', 'services.*',
DB::raw('(SELECT COUNT(*) FROM servers WHERE servers.service = services.id) as c_servers') DB::raw('(SELECT COUNT(*) FROM servers WHERE servers.service = services.id) as c_servers')
)->get() )->get(),
]); ]);
} }
@ -65,9 +63,10 @@ class ServiceController extends Controller
try { try {
$repo = new ServiceRepository\Service; $repo = new ServiceRepository\Service;
$id = $repo->create($request->except([ $id = $repo->create($request->except([
'_token' '_token',
])); ]));
Alert::success('Successfully created new service!')->flash(); Alert::success('Successfully created new service!')->flash();
return redirect()->route('admin.services.service', $id); return redirect()->route('admin.services.service', $id);
} catch (DisplayValidationException $ex) { } catch (DisplayValidationException $ex) {
return redirect()->route('admin.services.new')->withErrors(json_decode($ex->getMessage()))->withInput(); return redirect()->route('admin.services.new')->withErrors(json_decode($ex->getMessage()))->withInput();
@ -77,6 +76,7 @@ class ServiceController extends Controller
Log::error($ex); Log::error($ex);
Alert::danger('An error occured while attempting to add a new service.')->flash(); Alert::danger('An error occured while attempting to add a new service.')->flash();
} }
return redirect()->route('admin.services.new')->withInput(); return redirect()->route('admin.services.new')->withInput();
} }
@ -87,7 +87,7 @@ class ServiceController extends Controller
'options' => Models\ServiceOptions::select( 'options' => Models\ServiceOptions::select(
'service_options.*', 'service_options.*',
DB::raw('(SELECT COUNT(*) FROM servers WHERE servers.option = service_options.id) as c_servers') DB::raw('(SELECT COUNT(*) FROM servers WHERE servers.option = service_options.id) as c_servers')
)->where('parent_service', $service)->get() )->where('parent_service', $service)->get(),
]); ]);
} }
@ -96,7 +96,7 @@ class ServiceController extends Controller
try { try {
$repo = new ServiceRepository\Service; $repo = new ServiceRepository\Service;
$repo->update($service, $request->except([ $repo->update($service, $request->except([
'_token' '_token',
])); ]));
Alert::success('Successfully updated this service.')->flash(); Alert::success('Successfully updated this service.')->flash();
} catch (DisplayValidationException $ex) { } catch (DisplayValidationException $ex) {
@ -107,6 +107,7 @@ class ServiceController extends Controller
Log::error($ex); Log::error($ex);
Alert::danger('An error occurred while attempting to update this service.')->flash(); Alert::danger('An error occurred while attempting to update this service.')->flash();
} }
return redirect()->route('admin.services.service', $service)->withInput(); return redirect()->route('admin.services.service', $service)->withInput();
} }
@ -116,6 +117,7 @@ class ServiceController extends Controller
$repo = new ServiceRepository\Service; $repo = new ServiceRepository\Service;
$repo->delete($service); $repo->delete($service);
Alert::success('Successfully deleted that service.')->flash(); Alert::success('Successfully deleted that service.')->flash();
return redirect()->route('admin.services'); return redirect()->route('admin.services');
} catch (DisplayException $ex) { } catch (DisplayException $ex) {
Alert::danger($ex->getMessage())->flash(); Alert::danger($ex->getMessage())->flash();
@ -123,12 +125,14 @@ class ServiceController extends Controller
Log::error($ex); Log::error($ex);
Alert::danger('An error was encountered while attempting to delete that service.')->flash(); Alert::danger('An error was encountered while attempting to delete that service.')->flash();
} }
return redirect()->route('admin.services.service', $service); return redirect()->route('admin.services.service', $service);
} }
public function getOption(Request $request, $service, $option) public function getOption(Request $request, $service, $option)
{ {
$opt = Models\ServiceOptions::findOrFail($option); $opt = Models\ServiceOptions::findOrFail($option);
return view('admin.services.options.view', [ return view('admin.services.options.view', [
'service' => Models\Service::findOrFail($opt->parent_service), 'service' => Models\Service::findOrFail($opt->parent_service),
'option' => $opt, 'option' => $opt,
@ -136,7 +140,7 @@ class ServiceController extends Controller
'servers' => Models\Server::select('servers.*', 'users.email as a_ownerEmail') 'servers' => Models\Server::select('servers.*', 'users.email as a_ownerEmail')
->join('users', 'users.id', '=', 'servers.owner') ->join('users', 'users.id', '=', 'servers.owner')
->where('option', $option) ->where('option', $option)
->paginate(10) ->paginate(10),
]); ]);
} }
@ -145,7 +149,7 @@ class ServiceController extends Controller
try { try {
$repo = new ServiceRepository\Option; $repo = new ServiceRepository\Option;
$repo->update($option, $request->except([ $repo->update($option, $request->except([
'_token' '_token',
])); ]));
Alert::success('Option settings successfully updated.')->flash(); Alert::success('Option settings successfully updated.')->flash();
} catch (DisplayValidationException $ex) { } catch (DisplayValidationException $ex) {
@ -154,6 +158,7 @@ class ServiceController extends Controller
Log::error($ex); Log::error($ex);
Alert::danger('An error occured while attempting to modify this option.')->flash(); Alert::danger('An error occured while attempting to modify this option.')->flash();
} }
return redirect()->route('admin.services.option', [$service, $option])->withInput(); return redirect()->route('admin.services.option', [$service, $option])->withInput();
} }
@ -165,6 +170,7 @@ class ServiceController extends Controller
$repo->delete($option); $repo->delete($option);
Alert::success('Successfully deleted that option.')->flash(); Alert::success('Successfully deleted that option.')->flash();
return redirect()->route('admin.services.service', $service->parent_service); return redirect()->route('admin.services.service', $service->parent_service);
} catch (DisplayException $ex) { } catch (DisplayException $ex) {
Alert::danger($ex->getMessage())->flash(); Alert::danger($ex->getMessage())->flash();
@ -172,6 +178,7 @@ class ServiceController extends Controller
Log::error($ex); Log::error($ex);
Alert::danger('An error was encountered while attempting to delete this option.')->flash(); Alert::danger('An error was encountered while attempting to delete this option.')->flash();
} }
return redirect()->route('admin.services.option', [$service, $option]); return redirect()->route('admin.services.option', [$service, $option]);
} }
@ -185,18 +192,19 @@ class ServiceController extends Controller
$data = [ $data = [
'user_viewable' => '0', 'user_viewable' => '0',
'user_editable' => '0', 'user_editable' => '0',
'required' => '0' 'required' => '0',
]; ];
foreach($request->except(['_token']) as $id => $val) { foreach ($request->except(['_token']) as $id => $val) {
$data[str_replace($variable.'_', '', $id)] = $val; $data[str_replace($variable . '_', '', $id)] = $val;
} }
$repo->update($variable, $data); $repo->update($variable, $data);
Alert::success('Successfully updated variable.')->flash(); Alert::success('Successfully updated variable.')->flash();
} catch (DisplayValidationException $ex) { } catch (DisplayValidationException $ex) {
$data = []; $data = [];
foreach(json_decode($ex->getMessage(), true) as $id => $val) { foreach (json_decode($ex->getMessage(), true) as $id => $val) {
$data[$variable.'_'.$id] = $val; $data[$variable . '_' . $id] = $val;
} }
return redirect()->route('admin.services.option', [$service, $option])->withErrors((object) $data)->withInput(); return redirect()->route('admin.services.option', [$service, $option])->withErrors((object) $data)->withInput();
} catch (DisplayException $ex) { } catch (DisplayException $ex) {
Alert::danger($ex->getMessage())->flash(); Alert::danger($ex->getMessage())->flash();
@ -204,6 +212,7 @@ class ServiceController extends Controller
Log::error($ex); Log::error($ex);
Alert::danger('An error occurred while attempting to update this service.')->flash(); Alert::danger('An error occurred while attempting to update this service.')->flash();
} }
return redirect()->route('admin.services.option', [$service, $option])->withInput(); return redirect()->route('admin.services.option', [$service, $option])->withInput();
} }
@ -211,7 +220,7 @@ class ServiceController extends Controller
{ {
return view('admin.services.options.variable', [ return view('admin.services.options.variable', [
'service' => Models\Service::findOrFail($service), 'service' => Models\Service::findOrFail($service),
'option' => Models\ServiceOptions::where('parent_service', $service)->where('id', $option)->firstOrFail() 'option' => Models\ServiceOptions::where('parent_service', $service)->where('id', $option)->firstOrFail(),
]); ]);
} }
@ -220,9 +229,10 @@ class ServiceController extends Controller
try { try {
$repo = new ServiceRepository\Variable; $repo = new ServiceRepository\Variable;
$repo->create($option, $request->except([ $repo->create($option, $request->except([
'_token' '_token',
])); ]));
Alert::success('Successfully added new variable to this option.')->flash(); Alert::success('Successfully added new variable to this option.')->flash();
return redirect()->route('admin.services.option', [$service, $option])->withInput(); return redirect()->route('admin.services.option', [$service, $option])->withInput();
} catch (DisplayValidationException $ex) { } catch (DisplayValidationException $ex) {
return redirect()->route('admin.services.option.variable.new', [$service, $option])->withErrors(json_decode($ex->getMessage()))->withInput(); return redirect()->route('admin.services.option.variable.new', [$service, $option])->withErrors(json_decode($ex->getMessage()))->withInput();
@ -232,6 +242,7 @@ class ServiceController extends Controller
Log::error($ex); Log::error($ex);
Alert::danger('An error occurred while attempting to add this variable.')->flash(); Alert::danger('An error occurred while attempting to add this variable.')->flash();
} }
return redirect()->route('admin.services.option.variable.new', [$service, $option])->withInput(); return redirect()->route('admin.services.option.variable.new', [$service, $option])->withInput();
} }
@ -247,9 +258,10 @@ class ServiceController extends Controller
try { try {
$repo = new ServiceRepository\Option; $repo = new ServiceRepository\Option;
$id = $repo->create($service, $request->except([ $id = $repo->create($service, $request->except([
'_token' '_token',
])); ]));
Alert::success('Successfully created new service option.')->flash(); Alert::success('Successfully created new service option.')->flash();
return redirect()->route('admin.services.option', [$service, $id]); return redirect()->route('admin.services.option', [$service, $id]);
} catch (DisplayValidationException $ex) { } catch (DisplayValidationException $ex) {
return redirect()->route('admin.services.option.new', $service)->withErrors(json_decode($ex->getMessage()))->withInput(); return redirect()->route('admin.services.option.new', $service)->withErrors(json_decode($ex->getMessage()))->withInput();
@ -257,6 +269,7 @@ class ServiceController extends Controller
Log::error($ex); Log::error($ex);
Alert::danger('An error occured while attempting to add this service option.')->flash(); Alert::danger('An error occured while attempting to add this service option.')->flash();
} }
return redirect()->route('admin.services.option.new', $service)->withInput(); return redirect()->route('admin.services.option.new', $service)->withInput();
} }
@ -272,6 +285,7 @@ class ServiceController extends Controller
Log::error($ex); Log::error($ex);
Alert::danger('An error occured while attempting to delete that variable.')->flash(); Alert::danger('An error occured while attempting to delete that variable.')->flash();
} }
return redirect()->route('admin.services.option', [$service, $option]); return redirect()->route('admin.services.option', [$service, $option]);
} }
@ -306,5 +320,4 @@ class ServiceController extends Controller
], 503); ], 503);
} }
} }
} }

View file

@ -2,7 +2,7 @@
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>
* Some Modifications (c) 2015 Dylan Seidt <dylan.seidt@gmail.com> * Some Modifications (c) 2015 Dylan Seidt <dylan.seidt@gmail.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -22,27 +22,23 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Http\Controllers\Admin; namespace Pterodactyl\Http\Controllers\Admin;
use Alert;
use Settings;
use Mail;
use Log; use Log;
use Pterodactyl\Models\User; use Alert;
use Pterodactyl\Repositories\UserRepository;
use Pterodactyl\Models\Server;
use Pterodactyl\Exceptions\DisplayException;
use Pterodactyl\Exceptions\DisplayValidationException;
use Pterodactyl\Http\Controllers\Controller;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Pterodactyl\Models\User;
use Pterodactyl\Models\Server;
use Pterodactyl\Exceptions\DisplayException;
use Pterodactyl\Http\Controllers\Controller;
use Pterodactyl\Repositories\UserRepository;
use Pterodactyl\Exceptions\DisplayValidationException;
class UserController extends Controller class UserController extends Controller
{ {
/** /**
* Controller Constructor * Controller Constructor.
*/ */
public function __construct() public function __construct()
{ {
@ -51,8 +47,33 @@ class UserController extends Controller
public function getIndex(Request $request) public function getIndex(Request $request)
{ {
$query = User::select('users.*');
if ($request->input('filter') && ! is_null($request->input('filter'))) {
preg_match_all('/[^\s"\']+|"([^"]*)"|\'([^\']*)\'/', urldecode($request->input('filter')), $matches);
foreach ($matches[0] as $match) {
$match = str_replace('"', '', $match);
if (strpos($match, ':')) {
list($field, $term) = explode(':', $match);
$query->orWhere($field, 'LIKE', '%' . $term . '%');
} else {
$query->where('email', 'LIKE', '%' . $match . '%');
$query->orWhere([
['uuid', 'LIKE', '%' . $match . '%'],
['root_admin', 'LIKE', '%' . $match . '%'],
]);
}
}
}
try {
$users = $query->paginate(20);
} catch (\Exception $ex) {
Alert::warning('There was an error with the search parameters provided.');
$users = User::all()->paginate(20);
}
return view('admin.users.index', [ return view('admin.users.index', [
'users' => User::paginate(20) 'users' => $users,
]); ]);
} }
@ -79,13 +100,15 @@ class UserController extends Controller
$repo = new UserRepository; $repo = new UserRepository;
$repo->delete($id); $repo->delete($id);
Alert::success('Successfully deleted user from system.')->flash(); Alert::success('Successfully deleted user from system.')->flash();
return redirect()->route('admin.users'); return redirect()->route('admin.users');
} catch(DisplayException $ex) { } catch (DisplayException $ex) {
Alert::danger($ex->getMessage())->flash(); Alert::danger($ex->getMessage())->flash();
} catch (\Exception $ex) { } catch (\Exception $ex) {
Log::error($ex); Log::error($ex);
Alert::danger('An exception was encountered while attempting to delete this user.')->flash(); Alert::danger('An exception was encountered while attempting to delete this user.')->flash();
} }
return redirect()->route('admin.users.view', $id); return redirect()->route('admin.users.view', $id);
} }
@ -95,12 +118,14 @@ class UserController extends Controller
$user = new UserRepository; $user = new UserRepository;
$userid = $user->create($request->input('email'), $request->input('password')); $userid = $user->create($request->input('email'), $request->input('password'));
Alert::success('Account has been successfully created.')->flash(); Alert::success('Account has been successfully created.')->flash();
return redirect()->route('admin.users.view', $userid); return redirect()->route('admin.users.view', $userid);
} catch (DisplayValidationException $ex) { } catch (DisplayValidationException $ex) {
return redirect()->route('admin.users.new')->withErrors(json_decode($ex->getMessage()))->withInput(); return redirect()->route('admin.users.new')->withErrors(json_decode($ex->getMessage()))->withInput();
} catch (\Exception $ex) { } catch (\Exception $ex) {
Log::error($ex); Log::error($ex);
Alert::danger('An error occured while attempting to add a new user.')->flash(); Alert::danger('An error occured while attempting to add a new user.')->flash();
return redirect()->route('admin.users.new'); return redirect()->route('admin.users.new');
} }
} }
@ -127,15 +152,16 @@ class UserController extends Controller
Log::error($e); Log::error($e);
Alert::danger('An error occured while attempting to update this user.')->flash(); Alert::danger('An error occured while attempting to update this user.')->flash();
} }
return redirect()->route('admin.users.view', $user); return redirect()->route('admin.users.view', $user);
} }
public function getJson(Request $request) public function getJson(Request $request)
{ {
foreach(User::select('email')->get() as $user) { foreach (User::select('email')->get() as $user) {
$resp[] = $user->email; $resp[] = $user->email;
} }
return $resp; return $resp;
} }
} }

View file

@ -2,7 +2,7 @@
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>
* Some Modifications (c) 2015 Dylan Seidt <dylan.seidt@gmail.com> * Some Modifications (c) 2015 Dylan Seidt <dylan.seidt@gmail.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -22,20 +22,15 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Http\Controllers\Auth;
use Pterodactyl\Models\User; namespace Pterodactyl\Http\Controllers\Auth;
use Auth; use Auth;
use Alert; use Alert;
use Validator;
use Pterodactyl\Http\Controllers\Controller;
use PragmaRX\Google2FA\Google2FA;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Foundation\Auth\ThrottlesLogins; use Pterodactyl\Models\User;
use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers; use PragmaRX\Google2FA\Google2FA;
use Pterodactyl\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers; use Illuminate\Foundation\Auth\AuthenticatesUsers;
class LoginController extends Controller class LoginController extends Controller
@ -62,14 +57,14 @@ class LoginController extends Controller
/** /**
* Lockout time for failed login requests. * Lockout time for failed login requests.
* *
* @var integer * @var int
*/ */
protected $lockoutTime = 120; protected $lockoutTime = 120;
/** /**
* After how many attempts should logins be throttled and locked. * After how many attempts should logins be throttled and locked.
* *
* @var integer * @var int
*/ */
protected $maxLoginAttempts = 3; protected $maxLoginAttempts = 3;
@ -91,7 +86,6 @@ class LoginController extends Controller
*/ */
public function login(Request $request) public function login(Request $request)
{ {
$this->validate($request, [ $this->validate($request, [
'email' => 'required|email', 'email' => 'required|email',
'password' => 'required', 'password' => 'required',
@ -99,42 +93,40 @@ class LoginController extends Controller
if ($lockedOut = $this->hasTooManyLoginAttempts($request)) { if ($lockedOut = $this->hasTooManyLoginAttempts($request)) {
$this->fireLockoutEvent($request); $this->fireLockoutEvent($request);
return $this->sendLockoutResponse($request); return $this->sendLockoutResponse($request);
} }
// Is the email & password valid? // Is the email & password valid?
if (!Auth::once([ if (! Auth::once([
'email' => $request->input('email'), 'email' => $request->input('email'),
'password' => $request->input('password') 'password' => $request->input('password'),
], $request->has('remember'))) { ], $request->has('remember'))) {
if (! $lockedOut) {
if (!$lockedOut) {
$this->incrementLoginAttempts($request); $this->incrementLoginAttempts($request);
} }
return $this->sendFailedLoginResponse($request); return $this->sendFailedLoginResponse($request);
} }
// Verify TOTP Token was Valid // Verify TOTP Token was Valid
if(Auth::user()->use_totp === 1) { if (Auth::user()->use_totp === 1) {
$G2FA = new Google2FA(); $G2FA = new Google2FA();
if(is_null($request->input('totp_token')) || !$G2FA->verifyKey(Auth::user()->totp_secret, $request->input('totp_token'))) { if (is_null($request->input('totp_token')) || ! $G2FA->verifyKey(Auth::user()->totp_secret, $request->input('totp_token'))) {
if (! $lockedOut) {
if (!$lockedOut) {
$this->incrementLoginAttempts($request); $this->incrementLoginAttempts($request);
} }
Alert::danger(trans('auth.totp_failed'))->flash(); Alert::danger(trans('auth.totp_failed'))->flash();
return $this->sendFailedLoginResponse($request);
return $this->sendFailedLoginResponse($request);
} }
} }
// Successfully Authenticated. // Successfully Authenticated.
Auth::login(Auth::user(), $request->has('remember')); Auth::login(Auth::user(), $request->has('remember'));
return $this->sendLoginResponse($request);
return $this->sendLoginResponse($request);
} }
/** /**
@ -147,5 +139,4 @@ class LoginController extends Controller
{ {
return response()->json(User::select('id')->where('email', $request->input('email'))->where('use_totp', 1)->first()); return response()->json(User::select('id')->where('email', $request->input('email'))->where('use_totp', 1)->first());
} }
} }

View file

@ -2,8 +2,8 @@
namespace Pterodactyl\Http\Controllers\Auth; namespace Pterodactyl\Http\Controllers\Auth;
use Pterodactyl\User;
use Validator; use Validator;
use Pterodactyl\User;
use Pterodactyl\Http\Controllers\Controller; use Pterodactyl\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\RegistersUsers; use Illuminate\Foundation\Auth\RegistersUsers;

View file

@ -33,8 +33,8 @@ class ResetPasswordController extends Controller
$this->middleware('guest'); $this->middleware('guest');
} }
protected function rules()
protected function rules() { {
return [ return [
'token' => 'required', 'email' => 'required|email', 'token' => 'required', 'email' => 'required|email',
'password' => 'required|confirmed|' . User::PASSWORD_RULES, 'password' => 'required|confirmed|' . User::PASSWORD_RULES,

View file

@ -2,7 +2,7 @@
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>
* Some Modifications (c) 2015 Dylan Seidt <dylan.seidt@gmail.com> * Some Modifications (c) 2015 Dylan Seidt <dylan.seidt@gmail.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -22,35 +22,33 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Http\Controllers\Base; namespace Pterodactyl\Http\Controllers\Base;
use Alert;
use Log; use Log;
use Alert;
use Pterodactyl\Models; use Pterodactyl\Models;
use Illuminate\Http\Request;
use Pterodactyl\Repositories\APIRepository; use Pterodactyl\Repositories\APIRepository;
use Pterodactyl\Exceptions\DisplayValidationException;
use Pterodactyl\Exceptions\DisplayException; use Pterodactyl\Exceptions\DisplayException;
use Pterodactyl\Http\Controllers\Controller; use Pterodactyl\Http\Controllers\Controller;
use Pterodactyl\Exceptions\DisplayValidationException;
use Illuminate\Http\Request;
class APIController extends Controller class APIController extends Controller
{ {
public function index(Request $request) public function index(Request $request)
{ {
$keys = Models\APIKey::where('user', $request->user()->id)->get(); $keys = Models\APIKey::where('user', $request->user()->id)->get();
foreach($keys as &$key) { foreach ($keys as &$key) {
$key->permissions = Models\APIPermission::where('key_id', $key->id)->get(); $key->permissions = Models\APIPermission::where('key_id', $key->id)->get();
} }
return view('base.api.index', [ return view('base.api.index', [
'keys' => $keys 'keys' => $keys,
]); ]);
} }
public function new(Request $request) public function create(Request $request)
{ {
return view('base.api.new'); return view('base.api.new');
} }
@ -59,8 +57,9 @@ class APIController extends Controller
{ {
try { try {
$repo = new APIRepository($request->user()); $repo = new APIRepository($request->user());
$secret = $repo->new($request->except(['_token'])); $secret = $repo->create($request->except(['_token']));
Alert::success('An API Keypair has successfully been generated. The API secret for this public key is shown below and will not be shown again.<br /><br /><code>' . $secret . '</code>')->flash(); Alert::success('An API Keypair has successfully been generated. The API secret for this public key is shown below and will not be shown again.<br /><br /><code>' . $secret . '</code>')->flash();
return redirect()->route('account.api'); return redirect()->route('account.api');
} catch (DisplayValidationException $ex) { } catch (DisplayValidationException $ex) {
return redirect()->route('account.api.new')->withErrors(json_decode($ex->getMessage()))->withInput(); return redirect()->route('account.api.new')->withErrors(json_decode($ex->getMessage()))->withInput();
@ -70,6 +69,7 @@ class APIController extends Controller
Log::error($ex); Log::error($ex);
Alert::danger('An unhandled exception occured while attempting to add this API key.')->flash(); Alert::danger('An unhandled exception occured while attempting to add this API key.')->flash();
} }
return redirect()->route('account.api.new')->withInput(); return redirect()->route('account.api.new')->withInput();
} }
@ -78,10 +78,11 @@ class APIController extends Controller
try { try {
$repo = new APIRepository($request->user()); $repo = new APIRepository($request->user());
$repo->revoke($key); $repo->revoke($key);
return response('', 204); return response('', 204);
} catch (\Exception $ex) { } catch (\Exception $ex) {
return response()->json([ return response()->json([
'error' => 'An error occured while attempting to remove this key.' 'error' => 'An error occured while attempting to remove this key.',
], 503); ], 503);
} }
} }

View file

@ -2,7 +2,7 @@
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>
* Some Modifications (c) 2015 Dylan Seidt <dylan.seidt@gmail.com> * Some Modifications (c) 2015 Dylan Seidt <dylan.seidt@gmail.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -22,16 +22,15 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Http\Controllers\Base; namespace Pterodactyl\Http\Controllers\Base;
use Alert; use Alert;
use Illuminate\Http\Request;
use Pterodactyl\Models\User; use Pterodactyl\Models\User;
use Pterodactyl\Exceptions\DisplayException; use Pterodactyl\Exceptions\DisplayException;
use Pterodactyl\Http\Controllers\Controller; use Pterodactyl\Http\Controllers\Controller;
use Illuminate\Http\Request;
class AccountController extends Controller class AccountController extends Controller
{ {
/** /**
@ -53,16 +52,16 @@ class AccountController extends Controller
*/ */
public function email(Request $request) public function email(Request $request)
{ {
$this->validate($request, [ $this->validate($request, [
'new_email' => 'required|email', 'new_email' => 'required|email',
'password' => 'required' 'password' => 'required',
]); ]);
$user = $request->user(); $user = $request->user();
if (!password_verify($request->input('password'), $user->password)) { if (! password_verify($request->input('password'), $user->password)) {
Alert::danger('The password provided was not valid for this account.')->flash(); Alert::danger('The password provided was not valid for this account.')->flash();
return redirect()->route('account'); return redirect()->route('account');
} }
@ -70,8 +69,8 @@ class AccountController extends Controller
$user->save(); $user->save();
Alert::success('Your email address has successfully been updated.')->flash(); Alert::success('Your email address has successfully been updated.')->flash();
return redirect()->route('account');
return redirect()->route('account');
} }
/** /**
@ -82,17 +81,17 @@ class AccountController extends Controller
*/ */
public function password(Request $request) public function password(Request $request)
{ {
$this->validate($request, [ $this->validate($request, [
'current_password' => 'required', 'current_password' => 'required',
'new_password' => 'required|confirmed|different:current_password|' . User::PASSWORD_RULES, 'new_password' => 'required|confirmed|different:current_password|' . User::PASSWORD_RULES,
'new_password_confirmation' => 'required' 'new_password_confirmation' => 'required',
]); ]);
$user = $request->user(); $user = $request->user();
if (!password_verify($request->input('current_password'), $user->password)) { if (! password_verify($request->input('current_password'), $user->password)) {
Alert::danger('The password provided was not valid for this account.')->flash(); Alert::danger('The password provided was not valid for this account.')->flash();
return redirect()->route('account'); return redirect()->route('account');
} }
@ -104,6 +103,5 @@ class AccountController extends Controller
} }
return redirect()->route('account'); return redirect()->route('account');
} }
} }

View file

@ -2,7 +2,7 @@
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>
* Some Modifications (c) 2015 Dylan Seidt <dylan.seidt@gmail.com> * Some Modifications (c) 2015 Dylan Seidt <dylan.seidt@gmail.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -22,18 +22,17 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Http\Controllers\Base; namespace Pterodactyl\Http\Controllers\Base;
use Illuminate\Http\Request;
use Pterodactyl\Models\Server; use Pterodactyl\Models\Server;
use Pterodactyl\Http\Controllers\Controller; use Pterodactyl\Http\Controllers\Controller;
use Illuminate\Http\Request;
class IndexController extends Controller class IndexController extends Controller
{ {
/** /**
* Controller Constructor * Controller Constructor.
*/ */
public function __construct() public function __construct()
{ {
@ -62,7 +61,15 @@ class IndexController extends Controller
public function getPassword(Request $request, $length = 16) public function getPassword(Request $request, $length = 16)
{ {
$length = ($length < 8) ? 8 : $length; $length = ($length < 8) ? 8 : $length;
return str_random($length);
$returnable = false;
while (! $returnable) {
$generated = str_random($length);
if (preg_match('/[A-Z]+[a-z]+[0-9]+/', $generated)) {
$returnable = true;
}
} }
return $generated;
}
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,18 +21,17 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Http\Controllers\Base; namespace Pterodactyl\Http\Controllers\Base;
use Auth; use Auth;
use Session; use Session;
use Pterodactyl\Models\User;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Pterodactyl\Models\User;
use Pterodactyl\Http\Controllers\Controller; use Pterodactyl\Http\Controllers\Controller;
class LanguageController extends Controller class LanguageController extends Controller
{ {
protected $languages = [ protected $languages = [
'de' => 'Danish', 'de' => 'Danish',
'en' => 'English', 'en' => 'English',
@ -47,7 +46,7 @@ class LanguageController extends Controller
]; ];
/** /**
* Controller Constructor * Controller Constructor.
*/ */
public function __construct() public function __construct()
{ {
@ -64,7 +63,7 @@ class LanguageController extends Controller
} }
Session::set('applocale', $language); Session::set('applocale', $language);
} }
return redirect()->back(); return redirect()->back();
} }
} }

View file

@ -2,7 +2,7 @@
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>
* Some Modifications (c) 2015 Dylan Seidt <dylan.seidt@gmail.com> * Some Modifications (c) 2015 Dylan Seidt <dylan.seidt@gmail.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -22,19 +22,17 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Http\Controllers\Base; namespace Pterodactyl\Http\Controllers\Base;
use Google2FA;
use Alert; use Alert;
use Google2FA;
use Illuminate\Http\Request;
use Pterodactyl\Models\Session; use Pterodactyl\Models\Session;
use Pterodactyl\Http\Controllers\Controller; use Pterodactyl\Http\Controllers\Controller;
use Illuminate\Http\Request;
class SecurityController extends Controller class SecurityController extends Controller
{ {
/** /**
* Returns Security Management Page. * Returns Security Management Page.
* *
@ -44,7 +42,7 @@ class SecurityController extends Controller
public function index(Request $request) public function index(Request $request)
{ {
return view('base.security', [ return view('base.security', [
'sessions' => Session::where('user_id', $request->user()->id)->get() 'sessions' => Session::where('user_id', $request->user()->id)->get(),
]); ]);
} }
@ -57,7 +55,6 @@ class SecurityController extends Controller
*/ */
public function generateTotp(Request $request) public function generateTotp(Request $request)
{ {
$user = $request->user(); $user = $request->user();
$user->totp_secret = Google2FA::generateSecretKey(); $user->totp_secret = Google2FA::generateSecretKey();
@ -69,9 +66,8 @@ class SecurityController extends Controller
$user->email, $user->email,
$user->totp_secret $user->totp_secret
), ),
'secret' => $user->totp_secret 'secret' => $user->totp_secret,
]); ]);
} }
/** /**
@ -82,18 +78,16 @@ class SecurityController extends Controller
*/ */
public function setTotp(Request $request) public function setTotp(Request $request)
{ {
if (! $request->has('token')) {
if (!$request->has('token')) {
return response(null, 500); return response(null, 500);
} }
$user = $request->user(); $user = $request->user();
if($user->toggleTotp($request->input('token'))) { if ($user->toggleTotp($request->input('token'))) {
return response('true'); return response('true');
} }
return response('false'); return response('false');
} }
/** /**
@ -104,27 +98,27 @@ class SecurityController extends Controller
*/ */
public function disableTotp(Request $request) public function disableTotp(Request $request)
{ {
if (! $request->has('token')) {
if (!$request->has('token')) {
Alert::danger('Missing required `token` field in request.')->flash(); Alert::danger('Missing required `token` field in request.')->flash();
return redirect()->route('account.totp'); return redirect()->route('account.totp');
} }
$user = $request->user(); $user = $request->user();
if($user->toggleTotp($request->input('token'))) { if ($user->toggleTotp($request->input('token'))) {
return redirect()->route('account.security'); return redirect()->route('account.security');
} }
Alert::danger('The TOTP token provided was invalid.')->flash(); Alert::danger('The TOTP token provided was invalid.')->flash();
return redirect()->route('account.security');
return redirect()->route('account.security');
} }
public function revoke(Request $request, $id) public function revoke(Request $request, $id)
{ {
$session = Session::where('id', $id)->where('user_id', $request->user()->id)->firstOrFail(); $session = Session::where('id', $id)->where('user_id', $request->user()->id)->firstOrFail();
$session->delete(); $session->delete();
return redirect()->route('account.security'); return redirect()->route('account.security');
} }
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,47 +21,47 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Http\Controllers\Remote; namespace Pterodactyl\Http\Controllers\Remote;
use Pterodactyl\Models; use Pterodactyl\Models;
use Pterodactyl\Exceptions\DisplayException;
use Pterodactyl\Services\NotificationService;
use Pterodactyl\Http\Controllers\Controller;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Pterodactyl\Http\Controllers\Controller;
use Pterodactyl\Services\NotificationService;
class RemoteController extends Controller class RemoteController extends Controller
{ {
/** /**
* Controller Constructor * Controller Constructor.
*/ */
public function __construct() public function __construct()
{ {
// No middleware for this route. // No middleware for this route.
} }
public function postDownload(Request $request) { public function postDownload(Request $request)
{
$download = Models\Download::where('token', $request->input('token', '00'))->first(); $download = Models\Download::where('token', $request->input('token', '00'))->first();
if (!$download) { if (! $download) {
return response()->json([ return response()->json([
'error' => 'An invalid request token was recieved with this request.' 'error' => 'An invalid request token was recieved with this request.',
], 403); ], 403);
} }
$download->delete(); $download->delete();
return response()->json([ return response()->json([
'path' => $download->path, 'path' => $download->path,
'server' => $download->server 'server' => $download->server,
]); ]);
} }
public function postInstall(Request $request) public function postInstall(Request $request)
{ {
$server = Models\Server::where('uuid', $request->input('server'))->first(); $server = Models\Server::where('uuid', $request->input('server'))->first();
if (!$server) { if (! $server) {
return response()->json([ return response()->json([
'error' => 'No server by that ID was found on the system.' 'error' => 'No server by that ID was found on the system.',
], 422); ], 422);
} }
@ -71,7 +71,7 @@ class RemoteController extends Controller
if (base64_decode($hmac) !== hash_hmac('sha256', $server->uuid, $node->daemonSecret, true)) { if (base64_decode($hmac) !== hash_hmac('sha256', $server->uuid, $node->daemonSecret, true)) {
return response()->json([ return response()->json([
'error' => 'Signed HMAC was invalid.' 'error' => 'Signed HMAC was invalid.',
], 403); ], 403);
} }
@ -79,16 +79,16 @@ class RemoteController extends Controller
$server->save(); $server->save();
return response()->json([ return response()->json([
'message' => 'Recieved!' 'message' => 'Recieved!',
], 200); ], 200);
} }
public function event(Request $request) public function event(Request $request)
{ {
$server = Models\Server::where('uuid', $request->input('server'))->first(); $server = Models\Server::where('uuid', $request->input('server'))->first();
if (!$server) { if (! $server) {
return response()->json([ return response()->json([
'error' => 'No server by that ID was found on the system.' 'error' => 'No server by that ID was found on the system.',
], 422); ], 422);
} }
@ -97,7 +97,7 @@ class RemoteController extends Controller
$hmac = $request->input('signed'); $hmac = $request->input('signed');
if (base64_decode($hmac) !== hash_hmac('sha256', $server->uuid, $node->daemonSecret, true)) { if (base64_decode($hmac) !== hash_hmac('sha256', $server->uuid, $node->daemonSecret, true)) {
return response()->json([ return response()->json([
'error' => 'Signed HMAC was invalid.' 'error' => 'Signed HMAC was invalid.',
], 403); ], 403);
} }
@ -107,5 +107,4 @@ class RemoteController extends Controller
return response('', 201); return response('', 201);
} }
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,24 +21,20 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Http\Controllers\Server; namespace Pterodactyl\Http\Controllers\Server;
use Log; use Log;
use Pterodactyl\Models; use Pterodactyl\Models;
use Pterodactyl\Exceptions\DisplayException;
use Pterodactyl\Exceptions\DisplayValidationException;
use Pterodactyl\Repositories;
use Pterodactyl\Http\Controllers\Controller;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Pterodactyl\Repositories;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException; use GuzzleHttp\Exception\RequestException;
use Pterodactyl\Exceptions\DisplayException;
use Pterodactyl\Http\Controllers\Controller;
use Pterodactyl\Exceptions\DisplayValidationException;
class AjaxController extends Controller class AjaxController extends Controller
{ {
/** /**
* @var array * @var array
*/ */
@ -55,7 +51,7 @@ class AjaxController extends Controller
protected $directory; protected $directory;
/** /**
* Controller Constructor * Controller Constructor.
*/ */
public function __construct() public function __construct()
{ {
@ -73,7 +69,7 @@ class AjaxController extends Controller
{ {
$server = Models\Server::getByUUID($uuid); $server = Models\Server::getByUUID($uuid);
if (!$server) { if (! $server) {
return response()->json([], 404); return response()->json([], 404);
} }
@ -81,14 +77,15 @@ class AjaxController extends Controller
try { try {
$res = $client->request('GET', '/server', [ $res = $client->request('GET', '/server', [
'headers' => Models\Server::getGuzzleHeaders($uuid) 'headers' => Models\Server::getGuzzleHeaders($uuid),
]); ]);
if($res->getStatusCode() === 200) { if ($res->getStatusCode() === 200) {
return response()->json(json_decode($res->getBody())); return response()->json(json_decode($res->getBody()));
} }
} catch (RequestException $e) { } catch (RequestException $e) {
// //
} }
return response()->json([]); return response()->json([]);
} }
@ -101,13 +98,12 @@ class AjaxController extends Controller
*/ */
public function postDirectoryList(Request $request, $uuid) public function postDirectoryList(Request $request, $uuid)
{ {
$server = Models\Server::getByUUID($uuid); $server = Models\Server::getByUUID($uuid);
$this->directory = '/' . trim(urldecode($request->input('directory', '/')), '/'); $this->directory = '/' . trim(urldecode($request->input('directory', '/')), '/');
$this->authorize('list-files', $server); $this->authorize('list-files', $server);
$prevDir = [ $prevDir = [
'header' => ($this->directory !== '/') ? $this->directory : '' 'header' => ($this->directory !== '/') ? $this->directory : '',
]; ];
if ($this->directory !== '/') { if ($this->directory !== '/') {
$prevDir['first'] = true; $prevDir['first'] = true;
@ -116,7 +112,7 @@ class AjaxController extends Controller
// Determine if we should show back links in the file browser. // Determine if we should show back links in the file browser.
// This code is strange, and could probably be rewritten much better. // This code is strange, and could probably be rewritten much better.
$goBack = explode('/', trim($this->directory, '/')); $goBack = explode('/', trim($this->directory, '/'));
if (!empty(array_filter($goBack)) && count($goBack) >= 2) { if (! empty(array_filter($goBack)) && count($goBack) >= 2) {
$prevDir['show'] = true; $prevDir['show'] = true;
array_pop($goBack); array_pop($goBack);
$prevDir['link'] = '/' . implode('/', $goBack); $prevDir['link'] = '/' . implode('/', $goBack);
@ -131,6 +127,7 @@ class AjaxController extends Controller
return response($ex->getMessage(), 500); return response($ex->getMessage(), 500);
} catch (\Exception $ex) { } catch (\Exception $ex) {
Log::error($ex); Log::error($ex);
return response('An error occured while attempting to load the requested directory, please try again.', 500); return response('An error occured while attempting to load the requested directory, please try again.', 500);
} }
@ -139,9 +136,8 @@ class AjaxController extends Controller
'files' => $directoryContents->files, 'files' => $directoryContents->files,
'folders' => $directoryContents->folders, 'folders' => $directoryContents->folders,
'editableMime' => Repositories\HelperRepository::editableFiles(), 'editableMime' => Repositories\HelperRepository::editableFiles(),
'directory' => $prevDir 'directory' => $prevDir,
]); ]);
} }
/** /**
@ -153,7 +149,6 @@ class AjaxController extends Controller
*/ */
public function postSaveFile(Request $request, $uuid) public function postSaveFile(Request $request, $uuid)
{ {
$server = Models\Server::getByUUID($uuid); $server = Models\Server::getByUUID($uuid);
$this->authorize('save-files', $server); $this->authorize('save-files', $server);
@ -161,39 +156,39 @@ class AjaxController extends Controller
try { try {
$controller->saveFileContents($request->input('file'), $request->input('contents')); $controller->saveFileContents($request->input('file'), $request->input('contents'));
return response(null, 204); return response(null, 204);
} catch (DisplayException $ex) { } catch (DisplayException $ex) {
return response($ex->getMessage(), 500); return response($ex->getMessage(), 500);
} catch (\Exception $ex) { } catch (\Exception $ex) {
Log::error($ex); Log::error($ex);
return response('An error occured while attempting to save this file, please try again.', 500); return response('An error occured while attempting to save this file, please try again.', 500);
} }
} }
/** /**
* [postSetPrimary description] * [postSetPrimary description].
* @param Request $request * @param Request $request
* @param string $uuid * @param string $uuid
* @return \Illuminate\Http\Response * @return \Illuminate\Http\Response
*/ */
public function postSetPrimary(Request $request, $uuid) public function postSetPrimary(Request $request, $uuid)
{ {
$server = Models\Server::getByUUID($uuid); $server = Models\Server::getByUUID($uuid);
$this->authorize('set-connection', $server); $this->authorize('set-connection', $server);
if ((int) $request->input('allocation') === $server->allocation) { if ((int) $request->input('allocation') === $server->allocation) {
return response()->json([ return response()->json([
'error' => 'You are already using this as your default connection.' 'error' => 'You are already using this as your default connection.',
], 409); ], 409);
} }
try { try {
$allocation = Models\Allocation::where('id', $request->input('allocation'))->where('assigned_to', $server->id)->first(); $allocation = Models\Allocation::where('id', $request->input('allocation'))->where('assigned_to', $server->id)->first();
if (!$allocation) { if (! $allocation) {
return response()->json([ return response()->json([
'error' => 'No allocation matching your request was found in the system.' 'error' => 'No allocation matching your request was found in the system.',
], 422); ], 422);
} }
@ -201,6 +196,7 @@ class AjaxController extends Controller
$repo->changeBuild($server->id, [ $repo->changeBuild($server->id, [
'default' => $allocation->ip . ':' . $allocation->port, 'default' => $allocation->ip . ':' . $allocation->port,
]); ]);
return response('The default connection for this server has been updated. Please be aware that you will need to restart your server for this change to go into effect.'); return response('The default connection for this server has been updated. Please be aware that you will need to restart your server for this change to go into effect.');
} catch (DisplayValidationException $ex) { } catch (DisplayValidationException $ex) {
return response()->json([ return response()->json([
@ -212,8 +208,9 @@ class AjaxController extends Controller
], 503); ], 503);
} catch (\Exception $ex) { } catch (\Exception $ex) {
Log::error($ex); Log::error($ex);
return response()->json([ return response()->json([
'error' => 'An unhandled exception occured while attemping to modify the default connection for this server.' 'error' => 'An unhandled exception occured while attemping to modify the default connection for this server.',
], 503); ], 503);
} }
} }
@ -225,21 +222,21 @@ class AjaxController extends Controller
$this->authorize('reset-db-password', $server); $this->authorize('reset-db-password', $server);
try { try {
$repo = new Repositories\DatabaseRepository; $repo = new Repositories\DatabaseRepository;
$password = str_random(16); $password = str_random(16);
$repo->modifyPassword($request->input('database'), $password); $repo->modifyPassword($request->input('database'), $password);
return response($password); return response($password);
} catch (\Pterodactyl\Exceptions\DisplayException $ex) { } catch (\Pterodactyl\Exceptions\DisplayException $ex) {
return response()->json([ return response()->json([
'error' => $ex->getMessage(), 'error' => $ex->getMessage(),
], 503); ], 503);
} catch(\Exception $ex) { } catch (\Exception $ex) {
Log::error($ex); Log::error($ex);
return response()->json([ return response()->json([
'error' => 'An unhandled error occured while attempting to modify this database\'s password.' 'error' => 'An unhandled error occured while attempting to modify this database\'s password.',
], 503); ], 503);
} }
} }
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,30 +21,26 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Http\Controllers\Server; namespace Pterodactyl\Http\Controllers\Server;
use Auth;
use DB; use DB;
use Log;
use Uuid; use Uuid;
use Alert; use Alert;
use Log;
use Pterodactyl\Models; use Pterodactyl\Models;
use Pterodactyl\Exceptions\DisplayException;
use Pterodactyl\Exceptions\DisplayValidationException;
use Pterodactyl\Repositories\Daemon\FileRepository;
use Pterodactyl\Repositories\ServerRepository;
use Pterodactyl\Http\Controllers\Controller;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use InvalidArgumentException; use InvalidArgumentException;
use Pterodactyl\Exceptions\DisplayException;
use Pterodactyl\Http\Controllers\Controller;
use Pterodactyl\Repositories\ServerRepository;
use Pterodactyl\Repositories\Daemon\FileRepository;
use Pterodactyl\Exceptions\DisplayValidationException;
class ServerController extends Controller class ServerController extends Controller
{ {
/** /**
* Controller Constructor * Controller Constructor.
* *
* @return void * @return void
*/ */
@ -62,7 +58,7 @@ class ServerController extends Controller
try { try {
return response()->view('server.js.' . $folder . '.' . $routeFile, [ return response()->view('server.js.' . $folder . '.' . $routeFile, [
'server' => $server, 'server' => $server,
'node' => Models\Node::find($server->node) 'node' => Models\Node::find($server->node),
])->header('Content-Type', 'application/javascript'); ])->header('Content-Type', 'application/javascript');
} catch (InvalidArgumentException $ex) { } catch (InvalidArgumentException $ex) {
return abort(404); return abort(404);
@ -80,10 +76,11 @@ class ServerController extends Controller
public function getIndex(Request $request) public function getIndex(Request $request)
{ {
$server = Models\Server::getByUUID($request->route()->server); $server = Models\Server::getByUUID($request->route()->server);
return view('server.index', [ return view('server.index', [
'server' => $server, 'server' => $server,
'allocations' => Models\Allocation::where('assigned_to', $server->id)->orderBy('ip', 'asc')->orderBy('port', 'asc')->get(), 'allocations' => Models\Allocation::where('assigned_to', $server->id)->orderBy('ip', 'asc')->orderBy('port', 'asc')->get(),
'node' => Models\Node::find($server->node) 'node' => Models\Node::find($server->node),
]); ]);
} }
@ -95,13 +92,12 @@ class ServerController extends Controller
*/ */
public function getFiles(Request $request) public function getFiles(Request $request)
{ {
$server = Models\Server::getByUUID($request->route()->server); $server = Models\Server::getByUUID($request->route()->server);
$this->authorize('list-files', $server); $this->authorize('list-files', $server);
return view('server.files.index', [ return view('server.files.index', [
'server' => $server, 'server' => $server,
'node' => Models\Node::find($server->node) 'node' => Models\Node::find($server->node),
]); ]);
} }
@ -113,14 +109,13 @@ class ServerController extends Controller
*/ */
public function getAddFile(Request $request) public function getAddFile(Request $request)
{ {
$server = Models\Server::getByUUID($request->route()->server); $server = Models\Server::getByUUID($request->route()->server);
$this->authorize('add-files', $server); $this->authorize('add-files', $server);
return view('server.files.add', [ return view('server.files.add', [
'server' => $server, 'server' => $server,
'node' => Models\Node::find($server->node), 'node' => Models\Node::find($server->node),
'directory' => (in_array($request->get('dir'), [null, '/', ''])) ? '' : trim($request->get('dir'), '/') . '/' 'directory' => (in_array($request->get('dir'), [null, '/', ''])) ? '' : trim($request->get('dir'), '/') . '/',
]); ]);
} }
@ -134,7 +129,6 @@ class ServerController extends Controller
*/ */
public function getEditFile(Request $request, $uuid, $file) public function getEditFile(Request $request, $uuid, $file)
{ {
$server = Models\Server::getByUUID($uuid); $server = Models\Server::getByUUID($uuid);
$this->authorize('edit-files', $server); $this->authorize('edit-files', $server);
@ -145,10 +139,12 @@ class ServerController extends Controller
$fileContent = $controller->returnFileContents($file); $fileContent = $controller->returnFileContents($file);
} catch (DisplayException $ex) { } catch (DisplayException $ex) {
Alert::danger($ex->getMessage())->flash(); Alert::danger($ex->getMessage())->flash();
return redirect()->route('server.files.index', $uuid); return redirect()->route('server.files.index', $uuid);
} catch (\Exception $ex) { } catch (\Exception $ex) {
Log::error($ex); Log::error($ex);
Alert::danger('An error occured while attempting to load the requested file for editing, please try again.')->flash(); Alert::danger('An error occured while attempting to load the requested file for editing, please try again.')->flash();
return redirect()->route('server.files.index', $uuid); return redirect()->route('server.files.index', $uuid);
} }
@ -158,9 +154,8 @@ class ServerController extends Controller
'file' => $file, 'file' => $file,
'stat' => $fileContent['stat'], 'stat' => $fileContent['stat'],
'contents' => $fileContent['file']->content, 'contents' => $fileContent['file']->content,
'directory' => (in_array($fileInfo->dirname, ['.', './', '/'])) ? '/' : trim($fileInfo->dirname, '/') . '/' 'directory' => (in_array($fileInfo->dirname, ['.', './', '/'])) ? '/' : trim($fileInfo->dirname, '/') . '/',
]); ]);
} }
/** /**
@ -173,7 +168,6 @@ class ServerController extends Controller
*/ */
public function getDownloadFile(Request $request, $uuid, $file) public function getDownloadFile(Request $request, $uuid, $file)
{ {
$server = Models\Server::getByUUID($uuid); $server = Models\Server::getByUUID($uuid);
$node = Models\Node::find($server->node); $node = Models\Node::find($server->node);
@ -187,8 +181,7 @@ class ServerController extends Controller
$download->save(); $download->save();
return redirect( $node->scheme . '://' . $node->fqdn . ':' . $node->daemonListen . '/server/file/download/' . $download->token); return redirect($node->scheme . '://' . $node->fqdn . ':' . $node->daemonListen . '/server/file/download/' . $download->token);
} }
/** /**
@ -224,7 +217,7 @@ class ServerController extends Controller
]; ];
$processed = str_replace(array_keys($serverVariables), array_values($serverVariables), $server->startup); $processed = str_replace(array_keys($serverVariables), array_values($serverVariables), $server->startup);
foreach($variables as &$variable) { foreach ($variables as &$variable) {
$replace = ($variable->user_viewable === 1) ? $variable->a_serverValue : '**'; $replace = ($variable->user_viewable === 1) ? $variable->a_serverValue : '**';
$processed = str_replace('{{' . $variable->env_variable . '}}', $replace, $processed); $processed = str_replace('{{' . $variable->env_variable . '}}', $replace, $processed);
} }
@ -259,6 +252,7 @@ class ServerController extends Controller
Log::error($ex); Log::error($ex);
Alert::danger('An unknown error occured while attempting to update this server\'s SFTP settings.')->flash(); Alert::danger('An unknown error occured while attempting to update this server\'s SFTP settings.')->flash();
} }
return redirect()->route('server.settings', $uuid); return redirect()->route('server.settings', $uuid);
} }
@ -270,19 +264,19 @@ class ServerController extends Controller
try { try {
$repo = new ServerRepository; $repo = new ServerRepository;
$repo->updateStartup($server->id, $request->except([ $repo->updateStartup($server->id, $request->except([
'_token' '_token',
])); ]));
Alert::success('Server startup variables were successfully updated.')->flash(); Alert::success('Server startup variables were successfully updated.')->flash();
} catch (DisplayException $ex) { } catch (DisplayException $ex) {
Alert::danger($ex->getMessage())->flash(); Alert::danger($ex->getMessage())->flash();
} catch(\Exception $ex) { } catch (\Exception $ex) {
Log::error($ex); Log::error($ex);
Alert::danger('An unhandled exception occured while attemping to update startup variables for this server. Please try again.')->flash(); Alert::danger('An unhandled exception occured while attemping to update startup variables for this server. Please try again.')->flash();
} }
return redirect()->route('server.settings', [ return redirect()->route('server.settings', [
'uuid' => $uuid, 'uuid' => $uuid,
'tab' => 'tab_startup' 'tab' => 'tab_startup',
]); ]);
} }
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,27 +21,24 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Http\Controllers\Server; namespace Pterodactyl\Http\Controllers\Server;
use DB; use DB;
use Log;
use Auth; use Auth;
use Alert; use Alert;
use Log;
use Pterodactyl\Models; use Pterodactyl\Models;
use Pterodactyl\Repositories\SubuserRepository;
use Pterodactyl\Exceptions\DisplayException;
use Pterodactyl\Exceptions\DisplayValidationException;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Pterodactyl\Exceptions\DisplayException;
use Pterodactyl\Http\Controllers\Controller; use Pterodactyl\Http\Controllers\Controller;
use Pterodactyl\Repositories\SubuserRepository;
use Pterodactyl\Exceptions\DisplayValidationException;
class SubuserController extends Controller class SubuserController extends Controller
{ {
/** /**
* Controller Constructor * Controller Constructor.
* *
* @return void * @return void
*/ */
@ -61,9 +58,8 @@ class SubuserController extends Controller
'subusers' => Models\Subuser::select('subusers.*', 'users.email as a_userEmail') 'subusers' => Models\Subuser::select('subusers.*', 'users.email as a_userEmail')
->join('users', 'users.id', '=', 'subusers.user_id') ->join('users', 'users.id', '=', 'subusers.user_id')
->where('server_id', $server->id) ->where('server_id', $server->id)
->get() ->get(),
]); ]);
} }
public function getView(Request $request, $uuid, $id) public function getView(Request $request, $uuid, $id)
@ -76,7 +72,7 @@ class SubuserController extends Controller
->where(DB::raw('md5(subusers.id)'), $id)->where('subusers.server_id', $server->id) ->where(DB::raw('md5(subusers.id)'), $id)->where('subusers.server_id', $server->id)
->first(); ->first();
if (!$subuser) { if (! $subuser) {
abort(404); abort(404);
} }
@ -85,7 +81,7 @@ class SubuserController extends Controller
->where('user_id', $subuser->user_id)->where('server_id', $server->id) ->where('user_id', $subuser->user_id)->where('server_id', $server->id)
->get(); ->get();
foreach($modelPermissions as &$perm) { foreach ($modelPermissions as &$perm) {
$permissions[$perm->permission] = true; $permissions[$perm->permission] = true;
} }
@ -99,17 +95,15 @@ class SubuserController extends Controller
public function postView(Request $request, $uuid, $id) public function postView(Request $request, $uuid, $id)
{ {
$server = Models\Server::getByUUID($uuid); $server = Models\Server::getByUUID($uuid);
$this->authorize('edit-subuser', $server); $this->authorize('edit-subuser', $server);
$subuser = Models\Subuser::where(DB::raw('md5(id)'), $id)->where('server_id', $server->id)->first(); $subuser = Models\Subuser::where(DB::raw('md5(id)'), $id)->where('server_id', $server->id)->first();
try { try {
if (! $subuser) {
if (!$subuser) {
throw new DisplayException('Unable to locate a subuser by that ID.'); throw new DisplayException('Unable to locate a subuser by that ID.');
} else if ($subuser->user_id === Auth::user()->id) { } elseif ($subuser->user_id === Auth::user()->id) {
throw new DisplayException('You are not authorized to edit you own account.'); throw new DisplayException('You are not authorized to edit you own account.');
} }
@ -117,14 +111,14 @@ class SubuserController extends Controller
$repo->update($subuser->id, [ $repo->update($subuser->id, [
'permissions' => $request->input('permissions'), 'permissions' => $request->input('permissions'),
'server' => $server->id, 'server' => $server->id,
'user' => $subuser->user_id 'user' => $subuser->user_id,
]); ]);
Alert::success('Subuser permissions have successfully been updated.')->flash(); Alert::success('Subuser permissions have successfully been updated.')->flash();
} catch (DisplayValidationException $ex) { } catch (DisplayValidationException $ex) {
return redirect()->route('server.subusers.view', [ return redirect()->route('server.subusers.view', [
'uuid' => $uuid, 'uuid' => $uuid,
'id' => $id 'id' => $id,
])->withErrors(json_decode($ex->getMessage())); ])->withErrors(json_decode($ex->getMessage()));
} catch (DisplayException $ex) { } catch (DisplayException $ex) {
Alert::danger($ex->getMessage())->flash(); Alert::danger($ex->getMessage())->flash();
@ -132,9 +126,10 @@ class SubuserController extends Controller
Log::error($ex); Log::error($ex);
Alert::danger('An unknown error occured while attempting to update this subuser.')->flash(); Alert::danger('An unknown error occured while attempting to update this subuser.')->flash();
} }
return redirect()->route('server.subusers.view', [ return redirect()->route('server.subusers.view', [
'uuid' => $uuid, 'uuid' => $uuid,
'id' => $id 'id' => $id,
]); ]);
} }
@ -145,7 +140,7 @@ class SubuserController extends Controller
return view('server.users.new', [ return view('server.users.new', [
'server' => $server, 'server' => $server,
'node' => Models\Node::find($server->node) 'node' => Models\Node::find($server->node),
]); ]);
} }
@ -157,12 +152,13 @@ class SubuserController extends Controller
try { try {
$repo = new SubuserRepository; $repo = new SubuserRepository;
$id = $repo->create($server->id, $request->except([ $id = $repo->create($server->id, $request->except([
'_token' '_token',
])); ]));
Alert::success('Successfully created new subuser.')->flash(); Alert::success('Successfully created new subuser.')->flash();
return redirect()->route('server.subusers.view', [ return redirect()->route('server.subusers.view', [
'uuid' => $uuid, 'uuid' => $uuid,
'id' => md5($id) 'id' => md5($id),
]); ]);
} catch (DisplayValidationException $ex) { } catch (DisplayValidationException $ex) {
return redirect()->route('server.subusers.new', $uuid)->withErrors(json_decode($ex->getMessage()))->withInput(); return redirect()->route('server.subusers.new', $uuid)->withErrors(json_decode($ex->getMessage()))->withInput();
@ -172,6 +168,7 @@ class SubuserController extends Controller
Log::error($ex); Log::error($ex);
Alert::danger('An unknown error occured while attempting to add a new subuser.')->flash(); Alert::danger('An unknown error occured while attempting to add a new subuser.')->flash();
} }
return redirect()->route('server.subusers.new', $uuid)->withInput(); return redirect()->route('server.subusers.new', $uuid)->withInput();
} }
@ -182,23 +179,23 @@ class SubuserController extends Controller
try { try {
$subuser = Models\Subuser::select('id')->where(DB::raw('md5(id)'), $id)->where('server_id', $server->id)->first(); $subuser = Models\Subuser::select('id')->where(DB::raw('md5(id)'), $id)->where('server_id', $server->id)->first();
if (!$subuser) { if (! $subuser) {
throw new DisplayException('No subuser by that ID was found on the system.'); throw new DisplayException('No subuser by that ID was found on the system.');
} }
$repo = new SubuserRepository; $repo = new SubuserRepository;
$repo->delete($subuser->id); $repo->delete($subuser->id);
return response('', 204); return response('', 204);
} catch (DisplayException $ex) { } catch (DisplayException $ex) {
response()->json([ response()->json([
'error' => $ex->getMessage() 'error' => $ex->getMessage(),
], 422); ], 422);
} catch (\Exception $ex) { } catch (\Exception $ex) {
Log::error($ex); Log::error($ex);
response()->json([ response()->json([
'error' => 'An unknown error occured while attempting to delete this subuser.' 'error' => 'An unknown error occured while attempting to delete this subuser.',
], 503); ], 503);
} }
} }
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,19 +21,17 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Http\Controllers\Server; namespace Pterodactyl\Http\Controllers\Server;
use Alert;
use Log; use Log;
use Cron; use Alert;
use Pterodactyl\Repositories;
use Pterodactyl\Models; use Pterodactyl\Models;
use Pterodactyl\Exceptions\DisplayException;
use Pterodactyl\Exceptions\DisplayValidationException;
use Pterodactyl\Http\Controllers\Controller;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Pterodactyl\Repositories;
use Pterodactyl\Exceptions\DisplayException;
use Pterodactyl\Http\Controllers\Controller;
use Pterodactyl\Exceptions\DisplayValidationException;
class TaskController extends Controller class TaskController extends Controller
{ {
@ -53,8 +51,8 @@ class TaskController extends Controller
'tasks' => Models\Task::where('server', $server->id)->get(), 'tasks' => Models\Task::where('server', $server->id)->get(),
'actions' => [ 'actions' => [
'command' => 'Send Command', 'command' => 'Send Command',
'power' => 'Set Power Status' 'power' => 'Set Power Status',
] ],
]); ]);
} }
@ -65,7 +63,7 @@ class TaskController extends Controller
return view('server.tasks.new', [ return view('server.tasks.new', [
'server' => $server, 'server' => $server,
'node' => Models\Node::findOrFail($server->node) 'node' => Models\Node::findOrFail($server->node),
]); ]);
} }
@ -77,7 +75,7 @@ class TaskController extends Controller
try { try {
$repo = new Repositories\TaskRepository; $repo = new Repositories\TaskRepository;
$repo->create($server->id, $request->except([ $repo->create($server->id, $request->except([
'_token' '_token',
])); ]));
} catch (DisplayValidationException $ex) { } catch (DisplayValidationException $ex) {
return redirect()->route('server.tasks', $uuid)->withErrors(json_decode($ex->getMessage()))->withInput(); return redirect()->route('server.tasks', $uuid)->withErrors(json_decode($ex->getMessage()))->withInput();
@ -87,8 +85,8 @@ class TaskController extends Controller
Log::error($ex); Log::error($ex);
Alert::danger('An unknown error occured while attempting to create this task.')->flash(); Alert::danger('An unknown error occured while attempting to create this task.')->flash();
} }
return redirect()->route('server.tasks', $uuid);
return redirect()->route('server.tasks', $uuid);
} }
public function getView(Request $request, $uuid, $id) public function getView(Request $request, $uuid, $id)
@ -99,7 +97,7 @@ class TaskController extends Controller
return view('server.tasks.view', [ return view('server.tasks.view', [
'server' => $server, 'server' => $server,
'node' => Models\Node::findOrFail($server->node), 'node' => Models\Node::findOrFail($server->node),
'task' => Models\Task::where('id', $id)->where('server', $server->id)->firstOrFail() 'task' => Models\Task::where('id', $id)->where('server', $server->id)->firstOrFail(),
]); ]);
} }
@ -110,20 +108,22 @@ class TaskController extends Controller
$task = Models\Task::findOrFail($id); $task = Models\Task::findOrFail($id);
if (!$task || $server->id !== $task->server) { if (! $task || $server->id !== $task->server) {
return response()->json([ return response()->json([
'error' => 'No task by that ID was found associated with this server.' 'error' => 'No task by that ID was found associated with this server.',
], 404); ], 404);
} }
try { try {
$repo = new Repositories\TaskRepository; $repo = new Repositories\TaskRepository;
$repo->delete($id); $repo->delete($id);
return response()->json([], 204); return response()->json([], 204);
} catch (\Exception $ex) { } catch (\Exception $ex) {
Log::error($ex); Log::error($ex);
return response()->json([ return response()->json([
'error' => 'A server error occured while attempting to delete this task.' 'error' => 'A server error occured while attempting to delete this task.',
], 503); ], 503);
} }
} }
@ -135,22 +135,24 @@ class TaskController extends Controller
$task = Models\Task::findOrFail($id); $task = Models\Task::findOrFail($id);
if (!$task || $server->id !== $task->server) { if (! $task || $server->id !== $task->server) {
return response()->json([ return response()->json([
'error' => 'No task by that ID was found associated with this server.' 'error' => 'No task by that ID was found associated with this server.',
], 404); ], 404);
} }
try { try {
$repo = new Repositories\TaskRepository; $repo = new Repositories\TaskRepository;
$resp = $repo->toggle($id); $resp = $repo->toggle($id);
return response()->json([ return response()->json([
'status' => $resp 'status' => $resp,
]); ]);
} catch (\Exception $ex) { } catch (\Exception $ex) {
Log::error($ex); Log::error($ex);
return response()->json([ return response()->json([
'error' => 'A server error occured while attempting to toggle this task.' 'error' => 'A server error occured while attempting to toggle this task.',
], 503); ], 503);
} }
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,6 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Http\Middleware; namespace Pterodactyl\Http\Middleware;
use Auth; use Auth;
@ -28,24 +29,20 @@ use Crypt;
use Config; use Config;
use IPTools\IP; use IPTools\IP;
use IPTools\Range; use IPTools\Range;
use Dingo\Api\Routing\Route;
use Illuminate\Http\Request;
use Pterodactyl\Models\User;
use Pterodactyl\Models\APIKey; use Pterodactyl\Models\APIKey;
use Pterodactyl\Models\APIPermission; use Pterodactyl\Models\APIPermission;
use Pterodactyl\Models\User;
use Pterodactyl\Services\APILogService; use Pterodactyl\Services\APILogService;
use Illuminate\Http\Request;
use Dingo\Api\Routing\Route;
use Dingo\Api\Auth\Provider\Authorization; use Dingo\Api\Auth\Provider\Authorization;
use Symfony\Component\HttpKernel\Exception\HttpException; // 400
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; // 400 use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; // 401
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException; // 401
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; // 403 use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; // 403
use Symfony\Component\HttpKernel\Exception\HttpException; //500 use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException; //500
class APISecretToken extends Authorization class APISecretToken extends Authorization
{ {
protected $algo = 'sha256'; protected $algo = 'sha256';
protected $permissionAllowed = false; protected $permissionAllowed = false;
@ -64,7 +61,7 @@ class APISecretToken extends Authorization
public function authenticate(Request $request, Route $route) public function authenticate(Request $request, Route $route)
{ {
if (!$request->bearerToken() || empty($request->bearerToken())) { if (! $request->bearerToken() || empty($request->bearerToken())) {
APILogService::log($request, 'The authentication header was missing or malformed.'); APILogService::log($request, 'The authentication header was missing or malformed.');
throw new UnauthorizedHttpException('The authentication header was missing or malformed.'); throw new UnauthorizedHttpException('The authentication header was missing or malformed.');
} }
@ -72,22 +69,22 @@ class APISecretToken extends Authorization
list($public, $hashed) = explode('.', $request->bearerToken()); list($public, $hashed) = explode('.', $request->bearerToken());
$key = APIKey::where('public', $public)->first(); $key = APIKey::where('public', $public)->first();
if (!$key) { if (! $key) {
APILogService::log($request, 'Invalid API Key.'); APILogService::log($request, 'Invalid API Key.');
throw new AccessDeniedHttpException('Invalid API Key.'); throw new AccessDeniedHttpException('Invalid API Key.');
} }
// Check for Resource Permissions // Check for Resource Permissions
if (!empty($request->route()->getName())) { if (! empty($request->route()->getName())) {
if(!is_null($key->allowed_ips)) { if (! is_null($key->allowed_ips)) {
$inRange = false; $inRange = false;
foreach(json_decode($key->allowed_ips) as $ip) { foreach (json_decode($key->allowed_ips) as $ip) {
if (Range::parse($ip)->contains(new IP($request->ip()))) { if (Range::parse($ip)->contains(new IP($request->ip()))) {
$inRange = true; $inRange = true;
break; break;
} }
} }
if (!$inRange) { if (! $inRange) {
APILogService::log($request, 'This IP address <' . $request->ip() . '> does not have permission to use this API key.'); APILogService::log($request, 'This IP address <' . $request->ip() . '> does not have permission to use this API key.');
throw new AccessDeniedHttpException('This IP address <' . $request->ip() . '> does not have permission to use this API key.'); throw new AccessDeniedHttpException('This IP address <' . $request->ip() . '> does not have permission to use this API key.');
} }
@ -98,11 +95,11 @@ class APISecretToken extends Authorization
// Suport Wildcards // Suport Wildcards
if (starts_with($request->route()->getName(), 'api.user')) { if (starts_with($request->route()->getName(), 'api.user')) {
$permission->orWhere('permission', 'api.user.*'); $permission->orWhere('permission', 'api.user.*');
} else if(starts_with($request->route()->getName(), 'api.admin')) { } elseif (starts_with($request->route()->getName(), 'api.admin')) {
$permission->orWhere('permission', 'api.admin.*'); $permission->orWhere('permission', 'api.admin.*');
} }
if (!$permission->first()) { if (! $permission->first()) {
APILogService::log($request, 'You do not have permission to access this resource. This API Key requires the ' . $request->route()->getName() . ' permission node.'); APILogService::log($request, 'You do not have permission to access this resource. This API Key requires the ' . $request->route()->getName() . ' permission node.');
throw new AccessDeniedHttpException('You do not have permission to access this resource. This API Key requires the ' . $request->route()->getName() . ' permission node.'); throw new AccessDeniedHttpException('You do not have permission to access this resource. This API Key requires the ' . $request->route()->getName() . ' permission node.');
} }
@ -116,21 +113,21 @@ class APISecretToken extends Authorization
} }
$this->url = urldecode($request->fullUrl()); $this->url = urldecode($request->fullUrl());
if($this->_generateHMAC($request->getContent(), $decrypted) !== base64_decode($hashed)) { if ($this->_generateHMAC($request->getContent(), $decrypted) !== base64_decode($hashed)) {
APILogService::log($request, 'The hashed body was not valid. Potential modification of contents in route.'); APILogService::log($request, 'The hashed body was not valid. Potential modification of contents in route.');
throw new BadRequestHttpException('The hashed body was not valid. Potential modification of contents in route.'); throw new BadRequestHttpException('The hashed body was not valid. Potential modification of contents in route.');
} }
// Log the Route Access // Log the Route Access
APILogService::log($request, null, true); APILogService::log($request, null, true);
return Auth::loginUsingId($key->user);
return Auth::loginUsingId($key->user);
} }
protected function _generateHMAC($body, $key) protected function _generateHMAC($body, $key)
{ {
$data = $this->url . $body; $data = $this->url . $body;
return hash_hmac($this->algo, $data, $key, true); return hash_hmac($this->algo, $data, $key, true);
} }
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,6 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Http\Middleware; namespace Pterodactyl\Http\Middleware;
use Closure; use Closure;
@ -63,7 +64,7 @@ class AdminAuthenticate
} }
} }
if($this->auth->user()->root_admin !== 1) { if ($this->auth->user()->root_admin !== 1) {
return abort(403); return abort(403);
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,12 +21,12 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Http\Middleware; namespace Pterodactyl\Http\Middleware;
use Closure;
use Auth; use Auth;
use Closure;
use Pterodactyl\Models\Server; use Pterodactyl\Models\Server;
use Debugbar;
class CheckServer class CheckServer
{ {
@ -39,13 +39,12 @@ class CheckServer
*/ */
public function handle($request, Closure $next) public function handle($request, Closure $next)
{ {
if (! Auth::user()) {
if (!Auth::user()) {
return redirect()->guest('auth/login'); return redirect()->guest('auth/login');
} }
$server = Server::getByUUID($request->route()->server); $server = Server::getByUUID($request->route()->server);
if (!$server) { if (! $server) {
return response()->view('errors.404', [], 404); return response()->view('errors.404', [], 404);
} }
@ -58,6 +57,5 @@ class CheckServer
} }
return $next($request); return $next($request);
} }
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,18 +21,17 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Http\Middleware; namespace Pterodactyl\Http\Middleware;
use Auth; use Auth;
use Closure; use Closure;
use Session; use Session;
use Settings; use Settings;
use Illuminate\Support\Facades\App; use Illuminate\Support\Facades\App;
class LanguageMiddleware class LanguageMiddleware
{ {
public function __construct() public function __construct()
{ {
// //
@ -49,12 +48,13 @@ class LanguageMiddleware
{ {
if (Session::has('applocale')) { if (Session::has('applocale')) {
App::setLocale(Session::get('applocale')); App::setLocale(Session::get('applocale'));
} else if(Auth::check() && isset(Auth::user()->language)) { } elseif (Auth::check() && isset(Auth::user()->language)) {
Session::set('applocale', Auth::user()->language); Session::set('applocale', Auth::user()->language);
App::setLocale(Auth::user()->language); App::setLocale(Auth::user()->language);
} else { } else {
App::setLocale(Settings::get('default_language', 'en')); App::setLocale(Settings::get('default_language', 'en'));
} }
return $next($request); return $next($request);
} }
} }

View file

@ -13,6 +13,6 @@ class VerifyCsrfToken extends BaseVerifier
*/ */
protected $except = [ protected $except = [
'remote/*', 'remote/*',
'api/*' 'api/*',
]; ];
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,162 +21,164 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Http\Routes; namespace Pterodactyl\Http\Routes;
use Pterodactyl\Models;
use Illuminate\Routing\Router; use Illuminate\Routing\Router;
class APIRoutes class APIRoutes
{ {
public function map(Router $router)
public function map(Router $router) { {
$api = app('Dingo\Api\Routing\Router'); $api = app('Dingo\Api\Routing\Router');
$api->version('v1', ['prefix' => 'api/me', 'middleware' => 'api.auth'], function ($api) { $api->version('v1', ['prefix' => 'api/me', 'middleware' => 'api.auth'], function ($api) {
$api->get('/', [ $api->get('/', [
'as' => 'api.user.me', 'as' => 'api.user.me',
'uses' => 'Pterodactyl\Http\Controllers\API\User\InfoController@me' 'uses' => 'Pterodactyl\Http\Controllers\API\User\InfoController@me',
]); ]);
$api->get('/server/{uuid}', [ $api->get('/server/{uuid}', [
'as' => 'api.user.server', 'as' => 'api.user.server',
'uses' => 'Pterodactyl\Http\Controllers\API\User\ServerController@info' 'uses' => 'Pterodactyl\Http\Controllers\API\User\ServerController@info',
]); ]);
$api->put('/server/{uuid}', [ $api->put('/server/{uuid}', [
'as' => 'api.user.server.power', 'as' => 'api.user.server.power',
'uses' => 'Pterodactyl\Http\Controllers\API\User\ServerController@power' 'uses' => 'Pterodactyl\Http\Controllers\API\User\ServerController@power',
]); ]);
}); });
$api->version('v1', ['prefix' => 'api', 'middleware' => 'api.auth'], function ($api) { $api->version('v1', ['prefix' => 'api', 'middleware' => 'api.auth'], function ($api) {
/** /*
* User Routes * User Routes
*/ */
$api->get('users', [ $api->get('users', [
'as' => 'api.admin.users.list', 'as' => 'api.admin.users.list',
'uses' => 'Pterodactyl\Http\Controllers\API\UserController@list' 'uses' => 'Pterodactyl\Http\Controllers\API\UserController@lists',
]); ]);
$api->post('users', [ $api->post('users', [
'as' => 'api.admin.users.create', 'as' => 'api.admin.users.create',
'uses' => 'Pterodactyl\Http\Controllers\API\UserController@create' 'uses' => 'Pterodactyl\Http\Controllers\API\UserController@create',
]); ]);
$api->get('users/{id}', [ $api->get('users/{id}', [
'as' => 'api.admin.users.view', 'as' => 'api.admin.users.view',
'uses' => 'Pterodactyl\Http\Controllers\API\UserController@view' 'uses' => 'Pterodactyl\Http\Controllers\API\UserController@view',
]); ]);
$api->patch('users/{id}', [ $api->patch('users/{id}', [
'as' => 'api.admin.users.update', 'as' => 'api.admin.users.update',
'uses' => 'Pterodactyl\Http\Controllers\API\UserController@update' 'uses' => 'Pterodactyl\Http\Controllers\API\UserController@update',
]); ]);
$api->delete('users/{id}', [ $api->delete('users/{id}', [
'as' => 'api.admin.users.delete', 'as' => 'api.admin.users.delete',
'uses' => 'Pterodactyl\Http\Controllers\API\UserController@delete' 'uses' => 'Pterodactyl\Http\Controllers\API\UserController@delete',
]); ]);
/** /*
* Server Routes * Server Routes
*/ */
$api->get('servers', [ $api->get('servers', [
'as' => 'api.admin.servers.list', 'as' => 'api.admin.servers.list',
'uses' => 'Pterodactyl\Http\Controllers\API\ServerController@list' 'uses' => 'Pterodactyl\Http\Controllers\API\ServerController@lists',
]); ]);
$api->post('servers', [ $api->post('servers', [
'as' => 'api.admin.servers.create', 'as' => 'api.admin.servers.create',
'uses' => 'Pterodactyl\Http\Controllers\API\ServerController@create' 'uses' => 'Pterodactyl\Http\Controllers\API\ServerController@create',
]); ]);
$api->get('servers/{id}', [ $api->get('servers/{id}', [
'as' => 'api.admin.servers.view', 'as' => 'api.admin.servers.view',
'uses' => 'Pterodactyl\Http\Controllers\API\ServerController@view' 'uses' => 'Pterodactyl\Http\Controllers\API\ServerController@view',
]); ]);
$api->patch('servers/{id}/config', [ $api->patch('servers/{id}/config', [
'as' => 'api.admin.servers.config', 'as' => 'api.admin.servers.config',
'uses' => 'Pterodactyl\Http\Controllers\API\ServerController@config' 'uses' => 'Pterodactyl\Http\Controllers\API\ServerController@config',
]); ]);
$api->patch('servers/{id}/build', [ $api->patch('servers/{id}/build', [
'as' => 'api.admin.servers.build', 'as' => 'api.admin.servers.build',
'uses' => 'Pterodactyl\Http\Controllers\API\ServerController@build' 'uses' => 'Pterodactyl\Http\Controllers\API\ServerController@build',
]); ]);
$api->post('servers/{id}/suspend', [ $api->post('servers/{id}/suspend', [
'as' => 'api.admin.servers.suspend', 'as' => 'api.admin.servers.suspend',
'uses' => 'Pterodactyl\Http\Controllers\API\ServerController@suspend' 'uses' => 'Pterodactyl\Http\Controllers\API\ServerController@suspend',
]); ]);
$api->post('servers/{id}/unsuspend', [ $api->post('servers/{id}/unsuspend', [
'as' => 'api.admin.servers.unsuspend', 'as' => 'api.admin.servers.unsuspend',
'uses' => 'Pterodactyl\Http\Controllers\API\ServerController@unsuspend' 'uses' => 'Pterodactyl\Http\Controllers\API\ServerController@unsuspend',
]); ]);
$api->delete('servers/{id}/{force?}', [ $api->delete('servers/{id}/{force?}', [
'as' => 'api.admin.servers.delete', 'as' => 'api.admin.servers.delete',
'uses' => 'Pterodactyl\Http\Controllers\API\ServerController@delete' 'uses' => 'Pterodactyl\Http\Controllers\API\ServerController@delete',
]); ]);
/** /*
* Node Routes * Node Routes
*/ */
$api->get('nodes', [ $api->get('nodes', [
'as' => 'api.admin.nodes.list', 'as' => 'api.admin.nodes.list',
'uses' => 'Pterodactyl\Http\Controllers\API\NodeController@list' 'uses' => 'Pterodactyl\Http\Controllers\API\NodeController@lists',
]); ]);
$api->post('nodes', [ $api->post('nodes', [
'as' => 'api.admin.nodes.create', 'as' => 'api.admin.nodes.create',
'uses' => 'Pterodactyl\Http\Controllers\API\NodeController@create' 'uses' => 'Pterodactyl\Http\Controllers\API\NodeController@create',
]); ]);
$api->get('nodes/allocations', [ $api->get('nodes/allocations', [
'as' => 'api.admin.nodes.allocations', 'as' => 'api.admin.nodes.allocations',
'uses' => 'Pterodactyl\Http\Controllers\API\NodeController@allocations' 'uses' => 'Pterodactyl\Http\Controllers\API\NodeController@allocations',
]);
$api->get('nodes/allocations/{id}', [
'as' => 'api.admin.nodes.allocations',
'uses' => 'Pterodactyl\Http\Controllers\API\NodeController@allocationsView',
]); ]);
$api->get('nodes/{id}', [ $api->get('nodes/{id}', [
'as' => 'api.admin.nodes.view', 'as' => 'api.admin.nodes.view',
'uses' => 'Pterodactyl\Http\Controllers\API\NodeController@view' 'uses' => 'Pterodactyl\Http\Controllers\API\NodeController@view',
]); ]);
$api->get('nodes/{id}/config', [ $api->get('nodes/{id}/config', [
'as' => 'api.admin.nodes.view', 'as' => 'api.admin.nodes.view',
'uses' => 'Pterodactyl\Http\Controllers\API\NodeController@config' 'uses' => 'Pterodactyl\Http\Controllers\API\NodeController@config',
]); ]);
$api->delete('nodes/{id}', [ $api->delete('nodes/{id}', [
'as' => 'api.admin.nodes.delete', 'as' => 'api.admin.nodes.delete',
'uses' => 'Pterodactyl\Http\Controllers\API\NodeController@delete' 'uses' => 'Pterodactyl\Http\Controllers\API\NodeController@delete',
]); ]);
/** /*
* Location Routes * Location Routes
*/ */
$api->get('locations', [ $api->get('locations', [
'as' => 'api.admin.locations.list', 'as' => 'api.admin.locations.list',
'uses' => 'Pterodactyl\Http\Controllers\API\LocationController@list' 'uses' => 'Pterodactyl\Http\Controllers\API\LocationController@lists',
]); ]);
/** /*
* Service Routes * Service Routes
*/ */
$api->get('services', [ $api->get('services', [
'as' => 'api.admin.services.list', 'as' => 'api.admin.services.list',
'uses' => 'Pterodactyl\Http\Controllers\API\ServiceController@list' 'uses' => 'Pterodactyl\Http\Controllers\API\ServiceController@lists',
]); ]);
$api->get('services/{id}', [ $api->get('services/{id}', [
'as' => 'api.admin.services.view', 'as' => 'api.admin.services.view',
'uses' => 'Pterodactyl\Http\Controllers\API\ServiceController@view' 'uses' => 'Pterodactyl\Http\Controllers\API\ServiceController@view',
]); ]);
}); });
} }
} }

View file

@ -2,7 +2,7 @@
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>
* Some Modifications (c) 2015 Dylan Seidt <dylan.seidt@gmail.com> * Some Modifications (c) 2015 Dylan Seidt <dylan.seidt@gmail.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -22,13 +22,15 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Http\Routes; namespace Pterodactyl\Http\Routes;
use Illuminate\Routing\Router; use Illuminate\Routing\Router;
class AdminRoutes { class AdminRoutes
{
public function map(Router $router) { public function map(Router $router)
{
// Admin Index // Admin Index
$router->get('admin', [ $router->get('admin', [
@ -36,9 +38,9 @@ class AdminRoutes {
'middleware' => [ 'middleware' => [
'auth', 'auth',
'admin', 'admin',
'csrf' 'csrf',
], ],
'uses' => 'Admin\BaseController@getIndex' 'uses' => 'Admin\BaseController@getIndex',
]); ]);
$router->group([ $router->group([
@ -46,15 +48,15 @@ class AdminRoutes {
'middleware' => [ 'middleware' => [
'auth', 'auth',
'admin', 'admin',
'csrf' 'csrf',
] ],
], function () use ($router) { ], function () use ($router) {
$router->get('/', [ $router->get('/', [
'as' => 'admin.settings', 'as' => 'admin.settings',
'uses' => 'Admin\BaseController@getSettings' 'uses' => 'Admin\BaseController@getSettings',
]); ]);
$router->post('/', [ $router->post('/', [
'uses' => 'Admin\BaseController@postSettings' 'uses' => 'Admin\BaseController@postSettings',
]); ]);
}); });
@ -63,48 +65,47 @@ class AdminRoutes {
'middleware' => [ 'middleware' => [
'auth', 'auth',
'admin', 'admin',
'csrf' 'csrf',
] ],
], function () use ($router) { ], function () use ($router) {
// View All Accounts on System // View All Accounts on System
$router->get('/', [ $router->get('/', [
'as' => 'admin.users', 'as' => 'admin.users',
'uses' => 'Admin\UserController@getIndex' 'uses' => 'Admin\UserController@getIndex',
]); ]);
$router->get('/accounts.json', [ $router->get('/accounts.json', [
'as' => 'admin.users.json', 'as' => 'admin.users.json',
'uses' => 'Admin\UserController@getJson' 'uses' => 'Admin\UserController@getJson',
]); ]);
// View Specific Account // View Specific Account
$router->get('/view/{id}', [ $router->get('/view/{id}', [
'as' => 'admin.users.view', 'as' => 'admin.users.view',
'uses' => 'Admin\UserController@getView' 'uses' => 'Admin\UserController@getView',
]); ]);
// View Specific Account // View Specific Account
$router->post('/view/{id}', [ $router->post('/view/{id}', [
'uses' => 'Admin\UserController@updateUser' 'uses' => 'Admin\UserController@updateUser',
]); ]);
// Delete an Account Matching an ID // Delete an Account Matching an ID
$router->delete('/view/{id}', [ $router->delete('/view/{id}', [
'uses' => 'Admin\UserController@deleteUser' 'uses' => 'Admin\UserController@deleteUser',
]); ]);
// Show Create Account Page // Show Create Account Page
$router->get('/new', [ $router->get('/new', [
'as' => 'admin.users.new', 'as' => 'admin.users.new',
'uses' => 'Admin\UserController@getNew' 'uses' => 'Admin\UserController@getNew',
]); ]);
// Handle Creating New Account // Handle Creating New Account
$router->post('/new', [ $router->post('/new', [
'uses' => 'Admin\UserController@postNew' 'uses' => 'Admin\UserController@postNew',
]); ]);
}); });
// Server Routes // Server Routes
@ -113,37 +114,37 @@ class AdminRoutes {
'middleware' => [ 'middleware' => [
'auth', 'auth',
'admin', 'admin',
'csrf' 'csrf',
] ],
], function () use ($router) { ], function () use ($router) {
// View All Servers // View All Servers
$router->get('/', [ $router->get('/', [
'as' => 'admin.servers', 'as' => 'admin.servers',
'uses' => 'Admin\ServersController@getIndex' ]); 'uses' => 'Admin\ServersController@getIndex', ]);
// View Create Server Page // View Create Server Page
$router->get('/new', [ $router->get('/new', [
'as' => 'admin.servers.new', 'as' => 'admin.servers.new',
'uses' => 'Admin\ServersController@getNew' 'uses' => 'Admin\ServersController@getNew',
]); ]);
// Handle POST Request for Creating Server // Handle POST Request for Creating Server
$router->post('/new', [ $router->post('/new', [
'uses' => 'Admin\ServersController@postNewServer' 'uses' => 'Admin\ServersController@postNewServer',
]); ]);
// Assorted Page Helpers // Assorted Page Helpers
$router->post('/new/get-nodes', [ $router->post('/new/get-nodes', [
'uses' => 'Admin\ServersController@postNewServerGetNodes' 'uses' => 'Admin\ServersController@postNewServerGetNodes',
]); ]);
$router->post('/new/get-ips', [ $router->post('/new/get-ips', [
'uses' => 'Admin\ServersController@postNewServerGetIps' 'uses' => 'Admin\ServersController@postNewServerGetIps',
]); ]);
$router->post('/new/service-options', [ $router->post('/new/service-options', [
'uses' => 'Admin\ServersController@postNewServerServiceOptions' 'uses' => 'Admin\ServersController@postNewServerServiceOptions',
]); ]);
$router->post('/new/option-details', [ $router->post('/new/option-details', [
@ -154,67 +155,66 @@ class AdminRoutes {
// View Specific Server // View Specific Server
$router->get('/view/{id}', [ $router->get('/view/{id}', [
'as' => 'admin.servers.view', 'as' => 'admin.servers.view',
'uses' => 'Admin\ServersController@getView' 'uses' => 'Admin\ServersController@getView',
]); ]);
// Database Stuffs // Database Stuffs
$router->post('/view/{id}/database', [ $router->post('/view/{id}/database', [
'as' => 'admin.servers.database', 'as' => 'admin.servers.database',
'uses' => 'Admin\ServersController@postDatabase' 'uses' => 'Admin\ServersController@postDatabase',
]); ]);
// Change Server Details // Change Server Details
$router->post('/view/{id}/details', [ $router->post('/view/{id}/details', [
'uses' => 'Admin\ServersController@postUpdateServerDetails' 'uses' => 'Admin\ServersController@postUpdateServerDetails',
]); ]);
// Change Server Details // Change Server Details
$router->post('/view/{id}/container', [ $router->post('/view/{id}/container', [
'as' => 'admin.servers.post.container', 'as' => 'admin.servers.post.container',
'uses' => 'Admin\ServersController@postUpdateContainerDetails' 'uses' => 'Admin\ServersController@postUpdateContainerDetails',
]); ]);
// Change Server Details // Change Server Details
$router->post('/view/{id}/startup', [ $router->post('/view/{id}/startup', [
'as' => 'admin.servers.post.startup', 'as' => 'admin.servers.post.startup',
'uses' => 'Admin\ServersController@postUpdateServerStartup' 'uses' => 'Admin\ServersController@postUpdateServerStartup',
]); ]);
// Rebuild Server // Rebuild Server
$router->post('/view/{id}/rebuild', [ $router->post('/view/{id}/rebuild', [
'uses' => 'Admin\ServersController@postUpdateServerToggleBuild' 'uses' => 'Admin\ServersController@postUpdateServerToggleBuild',
]); ]);
// Change Build Details // Change Build Details
$router->post('/view/{id}/build', [ $router->post('/view/{id}/build', [
'uses' => 'Admin\ServersController@postUpdateServerUpdateBuild' 'uses' => 'Admin\ServersController@postUpdateServerUpdateBuild',
]); ]);
// Suspend Server // Suspend Server
$router->post('/view/{id}/suspend', [ $router->post('/view/{id}/suspend', [
'uses' => 'Admin\ServersController@postSuspendServer' 'uses' => 'Admin\ServersController@postSuspendServer',
]); ]);
// Unsuspend Server // Unsuspend Server
$router->post('/view/{id}/unsuspend', [ $router->post('/view/{id}/unsuspend', [
'uses' => 'Admin\ServersController@postUnsuspendServer' 'uses' => 'Admin\ServersController@postUnsuspendServer',
]); ]);
// Change Install Status // Change Install Status
$router->post('/view/{id}/installed', [ $router->post('/view/{id}/installed', [
'uses' => 'Admin\ServersController@postToggleInstall' 'uses' => 'Admin\ServersController@postToggleInstall',
]); ]);
// Delete [force delete] // Delete [force delete]
$router->delete('/view/{id}/{force?}', [ $router->delete('/view/{id}/{force?}', [
'uses' => 'Admin\ServersController@deleteServer' 'uses' => 'Admin\ServersController@deleteServer',
]); ]);
$router->post('/view/{id}/queuedDeletion', [ $router->post('/view/{id}/queuedDeletion', [
'uses' => 'Admin\ServersController@postQueuedDeletionHandler', 'uses' => 'Admin\ServersController@postQueuedDeletionHandler',
'as' => 'admin.servers.post.queuedDeletion' 'as' => 'admin.servers.post.queuedDeletion',
]); ]);
}); });
// Node Routes // Node Routes
@ -223,70 +223,69 @@ class AdminRoutes {
'middleware' => [ 'middleware' => [
'auth', 'auth',
'admin', 'admin',
'csrf' 'csrf',
] ],
], function () use ($router) { ], function () use ($router) {
// View All Nodes // View All Nodes
$router->get('/', [ $router->get('/', [
'as' => 'admin.nodes', 'as' => 'admin.nodes',
'uses' => 'Admin\NodesController@getIndex' 'uses' => 'Admin\NodesController@getIndex',
]); ]);
// Add New Node // Add New Node
$router->get('/new', [ $router->get('/new', [
'as' => 'admin.nodes.new', 'as' => 'admin.nodes.new',
'uses' => 'Admin\NodesController@getNew' 'uses' => 'Admin\NodesController@getNew',
]); ]);
$router->post('/new', [ $router->post('/new', [
'uses' => 'Admin\NodesController@postNew' 'uses' => 'Admin\NodesController@postNew',
]); ]);
// View Node // View Node
$router->get('/view/{id}', [ $router->get('/view/{id}', [
'as' => 'admin.nodes.view', 'as' => 'admin.nodes.view',
'uses' => 'Admin\NodesController@getView' 'uses' => 'Admin\NodesController@getView',
]); ]);
$router->post('/view/{id}', [ $router->post('/view/{id}', [
'uses' => 'Admin\NodesController@postView' 'uses' => 'Admin\NodesController@postView',
]); ]);
$router->delete('/view/{id}/deallocate/single/{allocation}', [ $router->delete('/view/{id}/deallocate/single/{allocation}', [
'uses' => 'Admin\NodesController@deallocateSingle' 'uses' => 'Admin\NodesController@deallocateSingle',
]); ]);
$router->post('/view/{id}/deallocate/block', [ $router->post('/view/{id}/deallocate/block', [
'uses' => 'Admin\NodesController@deallocateBlock' 'uses' => 'Admin\NodesController@deallocateBlock',
]); ]);
$router->post('/view/{id}/alias', [ $router->post('/view/{id}/alias', [
'as' => 'admin.nodes.alias', 'as' => 'admin.nodes.alias',
'uses' => 'Admin\NodesController@setAlias' 'uses' => 'Admin\NodesController@setAlias',
]); ]);
$router->get('/view/{id}/allocations.json', [ $router->get('/view/{id}/allocations.json', [
'as' => 'admin.nodes.view.allocations', 'as' => 'admin.nodes.view.allocations',
'uses' => 'Admin\NodesController@getAllocationsJson' 'uses' => 'Admin\NodesController@getAllocationsJson',
]); ]);
$router->post('/view/{id}/allocations', [ $router->post('/view/{id}/allocations', [
'as' => 'admin.nodes.post.allocations', 'as' => 'admin.nodes.post.allocations',
'uses' => 'Admin\NodesController@postAllocations' 'uses' => 'Admin\NodesController@postAllocations',
]); ]);
// View Deploy // View Deploy
$router->get('/view/{id}/deploy', [ $router->get('/view/{id}/deploy', [
'as' => 'admin.nodes.deply', 'as' => 'admin.nodes.deply',
'uses' => 'Admin\NodesController@getScript' 'uses' => 'Admin\NodesController@getScript',
]); ]);
$router->delete('/view/{id}', [ $router->delete('/view/{id}', [
'as' => 'admin.nodes.delete', 'as' => 'admin.nodes.delete',
'uses' => 'Admin\NodesController@deleteNode' 'uses' => 'Admin\NodesController@deleteNode',
]); ]);
}); });
// Location Routes // Location Routes
@ -295,21 +294,21 @@ class AdminRoutes {
'middleware' => [ 'middleware' => [
'auth', 'auth',
'admin', 'admin',
'csrf' 'csrf',
] ],
], function () use ($router) { ], function () use ($router) {
$router->get('/', [ $router->get('/', [
'as' => 'admin.locations', 'as' => 'admin.locations',
'uses' => 'Admin\LocationsController@getIndex' 'uses' => 'Admin\LocationsController@getIndex',
]); ]);
$router->delete('/{id}', [ $router->delete('/{id}', [
'uses' => 'Admin\LocationsController@deleteLocation' 'uses' => 'Admin\LocationsController@deleteLocation',
]); ]);
$router->patch('/{id}', [ $router->patch('/{id}', [
'uses' => 'Admin\LocationsController@patchLocation' 'uses' => 'Admin\LocationsController@patchLocation',
]); ]);
$router->post('/', [ $router->post('/', [
'uses' => 'Admin\LocationsController@postLocation' 'uses' => 'Admin\LocationsController@postLocation',
]); ]);
}); });
@ -319,27 +318,27 @@ class AdminRoutes {
'middleware' => [ 'middleware' => [
'auth', 'auth',
'admin', 'admin',
'csrf' 'csrf',
] ],
], function () use ($router) { ], function () use ($router) {
$router->get('/', [ $router->get('/', [
'as' => 'admin.databases', 'as' => 'admin.databases',
'uses' => 'Admin\DatabaseController@getIndex' 'uses' => 'Admin\DatabaseController@getIndex',
]); ]);
$router->get('/new', [ $router->get('/new', [
'as' => 'admin.databases.new', 'as' => 'admin.databases.new',
'uses' => 'Admin\DatabaseController@getNew' 'uses' => 'Admin\DatabaseController@getNew',
]); ]);
$router->post('/new', [ $router->post('/new', [
'uses' => 'Admin\DatabaseController@postNew' 'uses' => 'Admin\DatabaseController@postNew',
]); ]);
$router->delete('/delete/{id}', [ $router->delete('/delete/{id}', [
'as' => 'admin.databases.delete', 'as' => 'admin.databases.delete',
'uses' => 'Admin\DatabaseController@deleteDatabase' 'uses' => 'Admin\DatabaseController@deleteDatabase',
]); ]);
$router->delete('/delete-server/{id}', [ $router->delete('/delete-server/{id}', [
'as' => 'admin.databases.delete-server', 'as' => 'admin.databases.delete-server',
'uses' => 'Admin\DatabaseController@deleteServer' 'uses' => 'Admin\DatabaseController@deleteServer',
]); ]);
}); });
@ -349,34 +348,34 @@ class AdminRoutes {
'middleware' => [ 'middleware' => [
'auth', 'auth',
'admin', 'admin',
'csrf' 'csrf',
] ],
], function () use ($router) { ], function () use ($router) {
$router->get('/', [ $router->get('/', [
'as' => 'admin.services', 'as' => 'admin.services',
'uses' => 'Admin\ServiceController@getIndex' 'uses' => 'Admin\ServiceController@getIndex',
]); ]);
$router->get('/new', [ $router->get('/new', [
'as' => 'admin.services.new', 'as' => 'admin.services.new',
'uses' => 'Admin\ServiceController@getNew' 'uses' => 'Admin\ServiceController@getNew',
]); ]);
$router->post('/new', [ $router->post('/new', [
'uses' => 'Admin\ServiceController@postNew' 'uses' => 'Admin\ServiceController@postNew',
]); ]);
$router->get('/service/{id}', [ $router->get('/service/{id}', [
'as' => 'admin.services.service', 'as' => 'admin.services.service',
'uses' => 'Admin\ServiceController@getService' 'uses' => 'Admin\ServiceController@getService',
]); ]);
$router->post('/service/{id}', [ $router->post('/service/{id}', [
'uses' => 'Admin\ServiceController@postService' 'uses' => 'Admin\ServiceController@postService',
]); ]);
$router->delete('/service/{id}', [ $router->delete('/service/{id}', [
'uses' => 'Admin\ServiceController@deleteService' 'uses' => 'Admin\ServiceController@deleteService',
]); ]);
$router->get('/service/{id}/configuration', [ $router->get('/service/{id}/configuration', [
@ -390,43 +389,43 @@ class AdminRoutes {
$router->get('/service/{service}/option/new', [ $router->get('/service/{service}/option/new', [
'as' => 'admin.services.option.new', 'as' => 'admin.services.option.new',
'uses' => 'Admin\ServiceController@newOption' 'uses' => 'Admin\ServiceController@newOption',
]); ]);
$router->post('/service/{service}/option/new', [ $router->post('/service/{service}/option/new', [
'uses' => 'Admin\ServiceController@postNewOption' 'uses' => 'Admin\ServiceController@postNewOption',
]); ]);
$router->get('/service/{service}/option/{option}', [ $router->get('/service/{service}/option/{option}', [
'as' => 'admin.services.option', 'as' => 'admin.services.option',
'uses' => 'Admin\ServiceController@getOption' 'uses' => 'Admin\ServiceController@getOption',
]); ]);
$router->post('/service/{service}/option/{option}', [ $router->post('/service/{service}/option/{option}', [
'uses' => 'Admin\ServiceController@postOption' 'uses' => 'Admin\ServiceController@postOption',
]); ]);
$router->delete('/service/{service}/option/{id}', [ $router->delete('/service/{service}/option/{id}', [
'uses' => 'Admin\ServiceController@deleteOption' 'uses' => 'Admin\ServiceController@deleteOption',
]); ]);
$router->get('/service/{service}/option/{option}/variable/new', [ $router->get('/service/{service}/option/{option}/variable/new', [
'as' => 'admin.services.option.variable.new', 'as' => 'admin.services.option.variable.new',
'uses' => 'Admin\ServiceController@getNewVariable' 'uses' => 'Admin\ServiceController@getNewVariable',
]); ]);
$router->post('/service/{service}/option/{option}/variable/new', [ $router->post('/service/{service}/option/{option}/variable/new', [
'uses' => 'Admin\ServiceController@postNewVariable' 'uses' => 'Admin\ServiceController@postNewVariable',
]); ]);
$router->post('/service/{service}/option/{option}/variable/{variable}', [ $router->post('/service/{service}/option/{option}/variable/{variable}', [
'as' => 'admin.services.option.variable', 'as' => 'admin.services.option.variable',
'uses' => 'Admin\ServiceController@postOptionVariable' 'uses' => 'Admin\ServiceController@postOptionVariable',
]); ]);
$router->get('/service/{service}/option/{option}/variable/{variable}/delete', [ $router->get('/service/{service}/option/{option}/variable/{variable}/delete', [
'as' => 'admin.services.option.variable.delete', 'as' => 'admin.services.option.variable.delete',
'uses' => 'Admin\ServiceController@deleteVariable' 'uses' => 'Admin\ServiceController@deleteVariable',
]); ]);
}); });
@ -477,7 +476,5 @@ class AdminRoutes {
'uses' => 'Admin\PackController@export' 'uses' => 'Admin\PackController@export'
]); ]);
}); });
} }
} }

View file

@ -2,7 +2,7 @@
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>
* Some Modifications (c) 2015 Dylan Seidt <dylan.seidt@gmail.com> * Some Modifications (c) 2015 Dylan Seidt <dylan.seidt@gmail.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -22,71 +22,68 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Http\Routes; namespace Pterodactyl\Http\Routes;
use Illuminate\Routing\Router;
use Request;
use Pterodactyl\Models\User as User;
use Auth; use Auth;
class AuthRoutes { use Illuminate\Routing\Router;
public function map(Router $router) { class AuthRoutes
{
public function map(Router $router)
{
$router->group([ $router->group([
'prefix' => 'auth', 'prefix' => 'auth',
'middleware' => [ 'middleware' => [
'guest', 'guest',
'csrf' 'csrf',
] ],
], function () use ($router) { ], function () use ($router) {
// Display Login Page // Display Login Page
$router->get('login', [ $router->get('login', [
'as' => 'auth.login', 'as' => 'auth.login',
'uses' => 'Auth\LoginController@showLoginForm' 'uses' => 'Auth\LoginController@showLoginForm',
]); ]);
// Handle Login // Handle Login
$router->post('login', [ $router->post('login', [
'uses' => 'Auth\LoginController@login' 'uses' => 'Auth\LoginController@login',
]); ]);
// Determine if we need to ask for a TOTP Token // Determine if we need to ask for a TOTP Token
$router->post('login/totp', [ $router->post('login/totp', [
'uses' => 'Auth\LoginController@checkTotp' 'uses' => 'Auth\LoginController@checkTotp',
]); ]);
// Show Password Reset Form // Show Password Reset Form
$router->get('password', [ $router->get('password', [
'as' => 'auth.password', 'as' => 'auth.password',
'uses' => 'Auth\ForgotPasswordController@showLinkRequestForm' 'uses' => 'Auth\ForgotPasswordController@showLinkRequestForm',
]); ]);
// Handle Password Reset // Handle Password Reset
$router->post('password', [ $router->post('password', [
'uses' => 'Auth\ForgotPasswordController@sendResetLinkEmail' 'uses' => 'Auth\ForgotPasswordController@sendResetLinkEmail',
]); ]);
// Show Verification Checkpoint // Show Verification Checkpoint
$router->get('password/reset/{token}', [ $router->get('password/reset/{token}', [
'as' => 'auth.reset', 'as' => 'auth.reset',
'uses' => 'Auth\ResetPasswordController@showResetForm' 'uses' => 'Auth\ResetPasswordController@showResetForm',
]); ]);
// Handle Verification // Handle Verification
$router->post('password/reset', [ $router->post('password/reset', [
'uses' => 'Auth\ResetPasswordController@reset' 'uses' => 'Auth\ResetPasswordController@reset',
]); ]);
}); });
// Not included above because we don't want the guest middleware // Not included above because we don't want the guest middleware
$router->get('auth/logout', [ $router->get('auth/logout', [
'as' => 'auth.logout', 'as' => 'auth.logout',
'middleware' => 'auth', 'middleware' => 'auth',
'uses' => 'Auth\LoginController@logout' 'uses' => 'Auth\LoginController@logout',
]); ]);
} }
} }

View file

@ -2,7 +2,7 @@
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>
* Some Modifications (c) 2015 Dylan Seidt <dylan.seidt@gmail.com> * Some Modifications (c) 2015 Dylan Seidt <dylan.seidt@gmail.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -22,19 +22,21 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Http\Routes; namespace Pterodactyl\Http\Routes;
use Illuminate\Routing\Router; use Illuminate\Routing\Router;
class BaseRoutes { class BaseRoutes
{
public function map(Router $router) { public function map(Router $router)
{
// Index of Panel // Index of Panel
$router->get('/', [ $router->get('/', [
'as' => 'index', 'as' => 'index',
'middleware' => 'auth', 'middleware' => 'auth',
'uses' => 'Base\IndexController@getIndex' 'uses' => 'Base\IndexController@getIndex',
]); ]);
// Handle Index. Redirect /index to / // Handle Index. Redirect /index to /
@ -46,7 +48,7 @@ class BaseRoutes {
$router->get('/password-gen/{length}', [ $router->get('/password-gen/{length}', [
'as' => 'password-gen', 'as' => 'password-gen',
'middleware' => 'auth', 'middleware' => 'auth',
'uses' => 'Base\IndexController@getPassword' 'uses' => 'Base\IndexController@getPassword',
]); ]);
// Account Routes // Account Routes
@ -54,18 +56,18 @@ class BaseRoutes {
'prefix' => 'account', 'prefix' => 'account',
'middleware' => [ 'middleware' => [
'auth', 'auth',
'csrf' 'csrf',
] ],
], function () use ($router) { ], function () use ($router) {
$router->get('/', [ $router->get('/', [
'as' => 'account', 'as' => 'account',
'uses' => 'Base\AccountController@index' 'uses' => 'Base\AccountController@index',
]); ]);
$router->post('/password', [ $router->post('/password', [
'uses' => 'Base\AccountController@password' 'uses' => 'Base\AccountController@password',
]); ]);
$router->post('/email', [ $router->post('/email', [
'uses' => 'Base\AccountController@email' 'uses' => 'Base\AccountController@email',
]); ]);
}); });
@ -74,23 +76,23 @@ class BaseRoutes {
'prefix' => 'account/api', 'prefix' => 'account/api',
'middleware' => [ 'middleware' => [
'auth', 'auth',
'csrf' 'csrf',
] ],
], function () use ($router) { ], function () use ($router) {
$router->get('/', [ $router->get('/', [
'as' => 'account.api', 'as' => 'account.api',
'uses' => 'Base\APIController@index' 'uses' => 'Base\APIController@index',
]); ]);
$router->get('/new', [ $router->get('/new', [
'as' => 'account.api.new', 'as' => 'account.api.new',
'uses' => 'Base\APIController@new' 'uses' => 'Base\APIController@create',
]); ]);
$router->post('/new', [ $router->post('/new', [
'uses' => 'Base\APIController@save' 'uses' => 'Base\APIController@save',
]); ]);
$router->delete('/revoke/{key}', [ $router->delete('/revoke/{key}', [
'uses' => 'Base\APIController@revoke' 'uses' => 'Base\APIController@revoke',
]); ]);
}); });
@ -99,28 +101,26 @@ class BaseRoutes {
'prefix' => 'account/security', 'prefix' => 'account/security',
'middleware' => [ 'middleware' => [
'auth', 'auth',
'csrf' 'csrf',
] ],
], function () use ($router) { ], function () use ($router) {
$router->get('/', [ $router->get('/', [
'as' => 'account.security', 'as' => 'account.security',
'uses' => 'Base\SecurityController@index' 'uses' => 'Base\SecurityController@index',
]); ]);
$router->get('/revoke/{id}', [ $router->get('/revoke/{id}', [
'as' => 'account.security.revoke', 'as' => 'account.security.revoke',
'uses' => 'Base\SecurityController@revoke' 'uses' => 'Base\SecurityController@revoke',
]); ]);
$router->put('/totp', [ $router->put('/totp', [
'uses' => 'Base\SecurityController@generateTotp' 'uses' => 'Base\SecurityController@generateTotp',
]); ]);
$router->post('/totp', [ $router->post('/totp', [
'uses' => 'Base\SecurityController@setTotp' 'uses' => 'Base\SecurityController@setTotp',
]); ]);
$router->delete('/totp', [ $router->delete('/totp', [
'uses' => 'Base\SecurityController@disableTotp' 'uses' => 'Base\SecurityController@disableTotp',
]); ]);
}); });
} }
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,18 +21,18 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Http\Routes; namespace Pterodactyl\Http\Routes;
use Illuminate\Routing\Router; use Illuminate\Routing\Router;
class LanguageRoutes { class LanguageRoutes
{
public function map(Router $router) public function map(Router $router)
{ {
$router->get('language/{lang}', [ $router->get('language/{lang}', [
'as' => 'langauge.set', 'as' => 'langauge.set',
'uses' => 'Base\LanguageController@setLanguage' 'uses' => 'Base\LanguageController@setLanguage',
]); ]);
} }
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,31 +21,31 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Http\Routes; namespace Pterodactyl\Http\Routes;
use Illuminate\Routing\Router; use Illuminate\Routing\Router;
use Request;
class RemoteRoutes { class RemoteRoutes
{
public function map(Router $router) { public function map(Router $router)
{
$router->group(['prefix' => 'remote'], function () use ($router) { $router->group(['prefix' => 'remote'], function () use ($router) {
// Handles Remote Download Authentication Requests // Handles Remote Download Authentication Requests
$router->post('download', [ $router->post('download', [
'as' => 'remote.download', 'as' => 'remote.download',
'uses' => 'Remote\RemoteController@postDownload' 'uses' => 'Remote\RemoteController@postDownload',
]); ]);
$router->post('install', [ $router->post('install', [
'as' => 'remote.install', 'as' => 'remote.install',
'uses' => 'Remote\RemoteController@postInstall' 'uses' => 'Remote\RemoteController@postInstall',
]); ]);
$router->post('event', [ $router->post('event', [
'as' => 'remote.event', 'as' => 'remote.event',
'uses' => 'Remote\RemoteController@event' 'uses' => 'Remote\RemoteController@event',
]); ]);
}); });
} }
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,148 +21,149 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Http\Routes; namespace Pterodactyl\Http\Routes;
use Illuminate\Routing\Router; use Illuminate\Routing\Router;
class ServerRoutes { class ServerRoutes
{
public function map(Router $router) { public function map(Router $router)
{
$router->group([ $router->group([
'prefix' => 'server/{server}', 'prefix' => 'server/{server}',
'middleware' => [ 'middleware' => [
'auth', 'auth',
'server', 'server',
'csrf' 'csrf',
] ],
], function ($server) use ($router) { ], function ($server) use ($router) {
// Index View for Server // Index View for Server
$router->get('/', [ $router->get('/', [
'as' => 'server.index', 'as' => 'server.index',
'uses' => 'Server\ServerController@getIndex' 'uses' => 'Server\ServerController@getIndex',
]); ]);
// Settings // Settings
$router->get('/settings', [ $router->get('/settings', [
'as' => 'server.settings', 'as' => 'server.settings',
'uses' => 'Server\ServerController@getSettings' 'uses' => 'Server\ServerController@getSettings',
]); ]);
$router->post('/settings/sftp', [ $router->post('/settings/sftp', [
'as' => 'server.settings.sftp', 'as' => 'server.settings.sftp',
'uses' => 'Server\ServerController@postSettingsSFTP' 'uses' => 'Server\ServerController@postSettingsSFTP',
]); ]);
$router->post('/settings/startup', [ $router->post('/settings/startup', [
'as' => 'server.settings.startup', 'as' => 'server.settings.startup',
'uses' => 'Server\ServerController@postSettingsStartup' 'uses' => 'Server\ServerController@postSettingsStartup',
]); ]);
// File Manager Routes // File Manager Routes
$router->get('/files', [ $router->get('/files', [
'as' => 'server.files.index', 'as' => 'server.files.index',
'uses' => 'Server\ServerController@getFiles' 'uses' => 'Server\ServerController@getFiles',
]); ]);
$router->get('/files/edit/{file}', [ $router->get('/files/edit/{file}', [
'as' => 'server.files.edit', 'as' => 'server.files.edit',
'uses' => 'Server\ServerController@getEditFile' 'uses' => 'Server\ServerController@getEditFile',
])->where('file', '.*'); ])->where('file', '.*');
$router->get('/files/download/{file}', [ $router->get('/files/download/{file}', [
'as' => 'server.files.download', 'as' => 'server.files.download',
'uses' => 'Server\ServerController@getDownloadFile' 'uses' => 'Server\ServerController@getDownloadFile',
])->where('file', '.*'); ])->where('file', '.*');
$router->get('/files/add', [ $router->get('/files/add', [
'as' => 'server.files.add', 'as' => 'server.files.add',
'uses' => 'Server\ServerController@getAddFile' 'uses' => 'Server\ServerController@getAddFile',
]); ]);
$router->post('files/directory-list', [ $router->post('files/directory-list', [
'as' => 'server.files.directory-list', 'as' => 'server.files.directory-list',
'uses' => 'Server\AjaxController@postDirectoryList' 'uses' => 'Server\AjaxController@postDirectoryList',
]); ]);
$router->post('files/save', [ $router->post('files/save', [
'as' => 'server.files.save', 'as' => 'server.files.save',
'uses' => 'Server\AjaxController@postSaveFile' 'uses' => 'Server\AjaxController@postSaveFile',
]); ]);
// Sub-User Routes // Sub-User Routes
$router->get('users', [ $router->get('users', [
'as' => 'server.subusers', 'as' => 'server.subusers',
'uses' => 'Server\SubuserController@getIndex' 'uses' => 'Server\SubuserController@getIndex',
]); ]);
$router->get('users/new', [ $router->get('users/new', [
'as' => 'server.subusers.new', 'as' => 'server.subusers.new',
'uses' => 'Server\SubuserController@getNew' 'uses' => 'Server\SubuserController@getNew',
]); ]);
$router->post('users/new', [ $router->post('users/new', [
'uses' => 'Server\SubuserController@postNew' 'uses' => 'Server\SubuserController@postNew',
]); ]);
$router->get('users/view/{id}', [ $router->get('users/view/{id}', [
'as' => 'server.subusers.view', 'as' => 'server.subusers.view',
'uses' => 'Server\SubuserController@getView' 'uses' => 'Server\SubuserController@getView',
]); ]);
$router->post('users/view/{id}', [ $router->post('users/view/{id}', [
'uses' => 'Server\SubuserController@postView' 'uses' => 'Server\SubuserController@postView',
]); ]);
$router->delete('users/delete/{id}', [ $router->delete('users/delete/{id}', [
'uses' => 'Server\SubuserController@deleteSubuser' 'uses' => 'Server\SubuserController@deleteSubuser',
]); ]);
$router->get('tasks/', [ $router->get('tasks/', [
'as' => 'server.tasks', 'as' => 'server.tasks',
'uses' => 'Server\TaskController@getIndex' 'uses' => 'Server\TaskController@getIndex',
]); ]);
$router->get('tasks/view/{id}', [ $router->get('tasks/view/{id}', [
'as' => 'server.tasks.view', 'as' => 'server.tasks.view',
'uses' => 'Server\TaskController@getView' 'uses' => 'Server\TaskController@getView',
]); ]);
$router->get('tasks/new', [ $router->get('tasks/new', [
'as' => 'server.tasks.new', 'as' => 'server.tasks.new',
'uses' => 'Server\TaskController@getNew' 'uses' => 'Server\TaskController@getNew',
]); ]);
$router->post('tasks/new', [ $router->post('tasks/new', [
'uses' => 'Server\TaskController@postNew' 'uses' => 'Server\TaskController@postNew',
]); ]);
$router->delete('tasks/delete/{id}', [ $router->delete('tasks/delete/{id}', [
'as' => 'server.tasks.delete', 'as' => 'server.tasks.delete',
'uses' => 'Server\TaskController@deleteTask' 'uses' => 'Server\TaskController@deleteTask',
]); ]);
$router->post('tasks/toggle/{id}', [ $router->post('tasks/toggle/{id}', [
'as' => 'server.tasks.toggle', 'as' => 'server.tasks.toggle',
'uses' => 'Server\TaskController@toggleTask' 'uses' => 'Server\TaskController@toggleTask',
]); ]);
// Assorted AJAX Routes // Assorted AJAX Routes
$router->group(['prefix' => 'ajax'], function ($server) use ($router) { $router->group(['prefix' => 'ajax'], function ($server) use ($router) {
// Returns Server Status // Returns Server Status
$router->get('status', [ $router->get('status', [
'uses' => 'Server\AjaxController@getStatus' 'uses' => 'Server\AjaxController@getStatus',
]); ]);
// Sets the Default Connection for the Server // Sets the Default Connection for the Server
$router->post('set-primary', [ $router->post('set-primary', [
'uses' => 'Server\AjaxController@postSetPrimary' 'uses' => 'Server\AjaxController@postSetPrimary',
]); ]);
$router->post('settings/reset-database-password', [ $router->post('settings/reset-database-password', [
'as' => 'server.ajax.reset-database-password', 'as' => 'server.ajax.reset-database-password',
'uses' => 'Server\AjaxController@postResetDatabasePassword' 'uses' => 'Server\AjaxController@postResetDatabasePassword',
]); ]);
}); });
@ -171,11 +172,9 @@ class ServerRoutes {
// Returns Server Status // Returns Server Status
$router->get('{folder}/{file}', [ $router->get('{folder}/{file}', [
'as' => 'server.js', 'as' => 'server.js',
'uses' => 'Server\ServerController@getJavascript' 'uses' => 'Server\ServerController@getJavascript',
])->where('file', '.*'); ])->where('file', '.*');
}); });
}); });
} }
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,16 +21,12 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Jobs; namespace Pterodactyl\Jobs;
use DB;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels; use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Contracts\Queue\ShouldQueue;
use Pterodactyl\Models;
use Pterodactyl\Repositories\ServerRepository; use Pterodactyl\Repositories\ServerRepository;
class DeleteServer extends Job implements ShouldQueue class DeleteServer extends Job implements ShouldQueue
@ -46,7 +42,7 @@ class DeleteServer extends Job implements ShouldQueue
/** /**
* Create a new job instance. * Create a new job instance.
* *
* @param integer $server * @param int $server
* @return void * @return void
*/ */
public function __construct($id) public function __construct($id)

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,19 +21,17 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Jobs; namespace Pterodactyl\Jobs;
use Pterodactyl\Jobs\Job; use Cron;
use Carbon;
use Pterodactyl\Models;
use Illuminate\Queue\SerializesModels; use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Contracts\Queue\ShouldQueue;
use DB;
use Carbon;
use Cron;
use Pterodactyl\Models;
use Pterodactyl\Repositories\Daemon\CommandRepository;
use Pterodactyl\Repositories\Daemon\PowerRepository; use Pterodactyl\Repositories\Daemon\PowerRepository;
use Pterodactyl\Repositories\Daemon\CommandRepository;
class SendScheduledTask extends Job implements ShouldQueue class SendScheduledTask extends Job implements ShouldQueue
{ {
@ -76,7 +74,7 @@ class SendScheduledTask extends Job implements ShouldQueue
if ($this->task->action === 'command') { if ($this->task->action === 'command') {
$repo = new CommandRepository($this->server); $repo = new CommandRepository($this->server);
$response = $repo->send($this->task->data); $response = $repo->send($this->task->data);
} else if ($this->task->action === 'power') { } elseif ($this->task->action === 'power') {
$repo = new PowerRepository($this->server); $repo = new PowerRepository($this->server);
$response = $repo->do($this->task->data); $response = $repo->do($this->task->data);
} }
@ -84,14 +82,14 @@ class SendScheduledTask extends Job implements ShouldQueue
'task_id' => $this->task->id, 'task_id' => $this->task->id,
'run_time' => $time, 'run_time' => $time,
'run_status' => 0, 'run_status' => 0,
'response' => $response 'response' => $response,
]); ]);
} catch (\Exception $ex) { } catch (\Exception $ex) {
$log->fill([ $log->fill([
'task_id' => $this->task->id, 'task_id' => $this->task->id,
'run_time' => $time, 'run_time' => $time,
'run_status' => 1, 'run_status' => 1,
'response' => $ex->getMessage() 'response' => $ex->getMessage(),
]); ]);
} finally { } finally {
$cron = Cron::factory(sprintf('%s %s %s %s %s %s', $cron = Cron::factory(sprintf('%s %s %s %s %s %s',
@ -105,7 +103,7 @@ class SendScheduledTask extends Job implements ShouldQueue
$this->task->fill([ $this->task->fill([
'last_run' => $time, 'last_run' => $time,
'next_run' => $cron->getNextRunDate(), 'next_run' => $cron->getNextRunDate(),
'queued' => 0 'queued' => 0,
]); ]);
$this->task->save(); $this->task->save();
$log->save(); $log->save();

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,14 +21,12 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Jobs; namespace Pterodactyl\Jobs;
use Debugbar;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels; use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Contracts\Queue\ShouldQueue;
use Pterodactyl\Repositories\ServerRepository; use Pterodactyl\Repositories\ServerRepository;
class SuspendServer extends Job implements ShouldQueue class SuspendServer extends Job implements ShouldQueue
@ -44,7 +42,7 @@ class SuspendServer extends Job implements ShouldQueue
/** /**
* Create a new job instance. * Create a new job instance.
* *
* @param integer $id * @param int $id
* @return void * @return void
*/ */
public function __construct($id) public function __construct($id)

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,19 +21,17 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Listeners; namespace Pterodactyl\Listeners;
use Carbon; use Carbon;
use Pterodactyl\Jobs\DeleteServer;
use Pterodactyl\Jobs\SuspendServer;
use Pterodactyl\Events\ServerDeleted; use Pterodactyl\Events\ServerDeleted;
use Illuminate\Foundation\Bus\DispatchesJobs; use Illuminate\Foundation\Bus\DispatchesJobs;
use Pterodactyl\Jobs\SuspendServer;
use Pterodactyl\Jobs\DeleteServer;
class DeleteServerListener class DeleteServerListener
{ {
use DispatchesJobs; use DispatchesJobs;
/** /**

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,13 +21,13 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Models; namespace Pterodactyl\Models;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
class APIKey extends Model class APIKey extends Model
{ {
/** /**
* The table associated with the model. * The table associated with the model.
* *
@ -48,5 +48,4 @@ class APIKey extends Model
* @var array * @var array
*/ */
protected $guarded = ['id', 'created_at', 'updated_at']; protected $guarded = ['id', 'created_at', 'updated_at'];
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,13 +21,13 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Models; namespace Pterodactyl\Models;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
class APILog extends Model class APILog extends Model
{ {
/** /**
* The table associated with the model. * The table associated with the model.
* *
@ -55,7 +55,6 @@ class APILog extends Model
* @var array * @var array
*/ */
protected $casts = [ protected $casts = [
'authorized' => 'boolean' 'authorized' => 'boolean',
]; ];
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,13 +21,13 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Models; namespace Pterodactyl\Models;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
class APIPermission extends Model class APIPermission extends Model
{ {
/** /**
* The table associated with the model. * The table associated with the model.
* *
@ -54,8 +54,7 @@ class APIPermission extends Model
/** /**
* Disable timestamps for this table. * Disable timestamps for this table.
* *
* @var boolean * @var bool
*/ */
public $timestamps = false; public $timestamps = false;
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,13 +21,13 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Models; namespace Pterodactyl\Models;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
class Allocation extends Model class Allocation extends Model
{ {
/** /**
* The table associated with the model. * The table associated with the model.
* *
@ -52,5 +52,4 @@ class Allocation extends Model
'port' => 'integer', 'port' => 'integer',
'assigned_to' => 'integer', 'assigned_to' => 'integer',
]; ];
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,13 +21,13 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Models; namespace Pterodactyl\Models;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
class Database extends Model class Database extends Model
{ {
/** /**
* The table associated with the model. * The table associated with the model.
* *
@ -58,5 +58,4 @@ class Database extends Model
'server' => 'integer', 'server' => 'integer',
'db_server' => 'integer', 'db_server' => 'integer',
]; ];
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,13 +21,13 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Models; namespace Pterodactyl\Models;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
class DatabaseServer extends Model class DatabaseServer extends Model
{ {
/** /**
* The table associated with the model. * The table associated with the model.
* *
@ -57,7 +57,6 @@ class DatabaseServer extends Model
protected $casts = [ protected $casts = [
'id' => 'integer', 'id' => 'integer',
'server_id' => 'integer', 'server_id' => 'integer',
'db_server' => 'integer' 'db_server' => 'integer',
]; ];
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,19 +21,17 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Models; namespace Pterodactyl\Models;
use Debugbar;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
class Download extends Model class Download extends Model
{ {
/** /**
* The table associated with the model. * The table associated with the model.
* *
* @var string * @var string
*/ */
protected $table = 'downloads'; protected $table = 'downloads';
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,13 +21,13 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Models; namespace Pterodactyl\Models;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
class Location extends Model class Location extends Model
{ {
/** /**
* The table associated with the model. * The table associated with the model.
* *
@ -41,5 +41,4 @@ class Location extends Model
* @var array * @var array
*/ */
protected $guarded = ['id', 'created_at', 'updated_at']; protected $guarded = ['id', 'created_at', 'updated_at'];
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,6 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Models; namespace Pterodactyl\Models;
use GuzzleHttp\Client; use GuzzleHttp\Client;
@ -28,7 +29,6 @@ use Illuminate\Database\Eloquent\Model;
class Node extends Model class Node extends Model
{ {
/** /**
* The table associated with the model. * The table associated with the model.
* *
@ -88,9 +88,9 @@ class Node extends Model
return self::$nodes[$id]; return self::$nodes[$id];
} }
self::$nodes[$id] = Node::where('id', $id)->first(); self::$nodes[$id] = self::where('id', $id)->first();
return self::$nodes[$id];
return self::$nodes[$id];
} }
/** /**
@ -116,7 +116,5 @@ class Node extends Model
]); ]);
return self::$guzzle[$node]; return self::$guzzle[$node];
} }
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,13 +21,13 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Models; namespace Pterodactyl\Models;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
class Permission extends Model class Permission extends Model
{ {
/** /**
* The table associated with the model. * The table associated with the model.
* *
@ -61,5 +61,4 @@ class Permission extends Model
{ {
return $query->where('server_id', $server->id); return $query->where('server_id', $server->id);
} }
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,18 +21,15 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Models; namespace Pterodactyl\Models;
use Auth; use Auth;
use Pterodactyl\Models\Subuser;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Database\Eloquent\SoftDeletes;
use Pterodactyl\Exceptions\DisplayException;
class Server extends Model class Server extends Model
{ {
use SoftDeletes; use SoftDeletes;
/** /**
@ -95,7 +92,7 @@ class Server extends Model
protected static $user; protected static $user;
/** /**
* Constructor * Constructor.
*/ */
public function __construct() public function __construct()
{ {
@ -112,7 +109,6 @@ class Server extends Model
*/ */
public static function getUserDaemonSecret(Server $server) public static function getUserDaemonSecret(Server $server)
{ {
if (self::$user->id === $server->owner || self::$user->root_admin === 1) { if (self::$user->id === $server->owner || self::$user->root_admin === 1) {
return $server->daemonSecret; return $server->daemonSecret;
} }
@ -124,7 +120,6 @@ class Server extends Model
} }
return $subuser->daemonSecret; return $subuser->daemonSecret;
} }
/** /**
@ -135,7 +130,6 @@ class Server extends Model
*/ */
public static function getUserServers($paginate = null) public static function getUserServers($paginate = null)
{ {
$query = self::select( $query = self::select(
'servers.*', 'servers.*',
'nodes.name as nodeName', 'nodes.name as nodeName',
@ -160,7 +154,6 @@ class Server extends Model
} }
return $query->get(); return $query->get();
} }
/** /**
@ -173,7 +166,6 @@ class Server extends Model
*/ */
public static function getByUUID($uuid) public static function getByUUID($uuid)
{ {
if (array_key_exists($uuid, self::$serverUUIDInstance)) { if (array_key_exists($uuid, self::$serverUUIDInstance)) {
return self::$serverUUIDInstance[$uuid]; return self::$serverUUIDInstance[$uuid];
} }
@ -189,33 +181,30 @@ class Server extends Model
$result = $query->first(); $result = $query->first();
if(!is_null($result)) { if (! is_null($result)) {
$result->daemonSecret = self::getUserDaemonSecret($result); $result->daemonSecret = self::getUserDaemonSecret($result);
} }
self::$serverUUIDInstance[$uuid] = $result; self::$serverUUIDInstance[$uuid] = $result;
return self::$serverUUIDInstance[$uuid];
return self::$serverUUIDInstance[$uuid];
} }
/** /**
* Returns non-administrative headers for accessing a server on Scales * Returns non-administrative headers for accessing a server on the daemon.
* *
* @param string $uuid * @param string $uuid
* @return array * @return array
*/ */
public static function getGuzzleHeaders($uuid) public static function getGuzzleHeaders($uuid)
{ {
if (array_key_exists($uuid, self::$serverUUIDInstance)) { if (array_key_exists($uuid, self::$serverUUIDInstance)) {
return [ return [
'X-Access-Server' => self::$serverUUIDInstance[$uuid]->uuid, 'X-Access-Server' => self::$serverUUIDInstance[$uuid]->uuid,
'X-Access-Token' => self::$serverUUIDInstance[$uuid]->daemonSecret 'X-Access-Token' => self::$serverUUIDInstance[$uuid]->daemonSecret,
]; ];
} }
return []; return [];
} }
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,13 +21,13 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Models; namespace Pterodactyl\Models;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
class ServerVariables extends Model class ServerVariables extends Model
{ {
/** /**
* The table associated with the model. * The table associated with the model.
* *
@ -51,5 +51,4 @@ class ServerVariables extends Model
'server_id' => 'integer', 'server_id' => 'integer',
'variable_id' => 'integer', 'variable_id' => 'integer',
]; ];
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,13 +21,13 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Models; namespace Pterodactyl\Models;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
class Service extends Model class Service extends Model
{ {
/** /**
* The table associated with the model. * The table associated with the model.
* *
@ -41,5 +41,4 @@ class Service extends Model
* @var array * @var array
*/ */
protected $guarded = ['id', 'created_at', 'updated_at']; protected $guarded = ['id', 'created_at', 'updated_at'];
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,13 +21,13 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Models; namespace Pterodactyl\Models;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
class ServiceOptions extends Model class ServiceOptions extends Model
{ {
/** /**
* The table associated with the model. * The table associated with the model.
* *
@ -51,4 +51,13 @@ class ServiceOptions extends Model
'parent_service' => 'integer', 'parent_service' => 'integer',
]; ];
/**
* Gets all variables associated with this service.
*
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function variables()
{
return $this->hasMany(ServiceVariables::class, 'option_id');
}
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,13 +21,13 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Models; namespace Pterodactyl\Models;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
class ServiceVariables extends Model class ServiceVariables extends Model
{ {
/** /**
* The table associated with the model. * The table associated with the model.
* *
@ -53,5 +53,4 @@ class ServiceVariables extends Model
'user_editable' => 'integer', 'user_editable' => 'integer',
'required' => 'integer', 'required' => 'integer',
]; ];
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,13 +21,13 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Models; namespace Pterodactyl\Models;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
class Session extends Model class Session extends Model
{ {
/** /**
* The table associated with the model. * The table associated with the model.
* *
@ -44,5 +44,4 @@ class Session extends Model
'id' => 'string', 'id' => 'string',
'user_id' => 'integer', 'user_id' => 'integer',
]; ];
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,6 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Models; namespace Pterodactyl\Models;
use Auth; use Auth;
@ -28,7 +29,6 @@ use Illuminate\Database\Eloquent\Model;
class Subuser extends Model class Subuser extends Model
{ {
/** /**
* The table associated with the model. * The table associated with the model.
* *
@ -66,7 +66,7 @@ class Subuser extends Model
protected static $user; protected static $user;
/** /**
* Constructor * Constructor.
*/ */
public function __construct() public function __construct()
{ {
@ -80,18 +80,8 @@ class Subuser extends Model
*/ */
public static function accessServers() public static function accessServers()
{ {
$access = [];
$union = self::select('server_id')->where('user_id', self::$user->id); $union = self::select('server_id')->where('user_id', self::$user->id);
$select = Server::select('id')->where('owner', self::$user->id)->union($union)->get();
foreach($select as &$select) { return Server::select('id')->where('owner', self::$user->id)->union($union)->pluck('id');
$access = array_merge($access, [ $select->id ]);
} }
return $access;
}
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,13 +21,13 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Models; namespace Pterodactyl\Models;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
class Task extends Model class Task extends Model
{ {
/** /**
* The table associated with the model. * The table associated with the model.
* *
@ -59,5 +59,4 @@ class Task extends Model
* @var array * @var array
*/ */
protected $dates = ['last_run', 'next_run', 'created_at', 'updated_at']; protected $dates = ['last_run', 'next_run', 'created_at', 'updated_at'];
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,13 +21,13 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Models; namespace Pterodactyl\Models;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
class TaskLog extends Model class TaskLog extends Model
{ {
/** /**
* The table associated with the model. * The table associated with the model.
* *
@ -50,7 +50,7 @@ class TaskLog extends Model
protected $casts = [ protected $casts = [
'id' => 'integer', 'id' => 'integer',
'task_id' => 'integer', 'task_id' => 'integer',
'run_status' => 'integer' 'run_status' => 'integer',
]; ];
/** /**
@ -59,5 +59,4 @@ class TaskLog extends Model
* @var array * @var array
*/ */
protected $dates = ['run_time', 'created_at', 'updated_at']; protected $dates = ['run_time', 'created_at', 'updated_at'];
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,25 +21,24 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Models; namespace Pterodactyl\Models;
use Hash; use Hash;
use Google2FA; use Google2FA;
use Pterodactyl\Exceptions\AccountNotFoundException;
use Pterodactyl\Exceptions\DisplayException;
use Pterodactyl\Models\Permission;
use Pterodactyl\Notifications\SendPasswordReset as ResetPasswordNotification;
use Illuminate\Auth\Authenticatable; use Illuminate\Auth\Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Notifications\Notifiable;
use Pterodactyl\Exceptions\DisplayException;
use Illuminate\Auth\Passwords\CanResetPassword; use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Foundation\Auth\Access\Authorizable; use Illuminate\Foundation\Auth\Access\Authorizable;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract; use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract; use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract; use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
use Pterodactyl\Notifications\SendPasswordReset as ResetPasswordNotification;
class User extends Model implements AuthenticatableContract, class User extends Model implements
AuthenticatableContract,
AuthorizableContract, AuthorizableContract,
CanResetPasswordContract CanResetPasswordContract
{ {
@ -77,7 +76,7 @@ class User extends Model implements AuthenticatableContract,
protected $hidden = ['password', 'remember_token', 'totp_secret']; protected $hidden = ['password', 'remember_token', 'totp_secret'];
/** /**
* The rules for user passwords * The rules for user passwords.
* *
* @var string * @var string
*/ */
@ -92,20 +91,18 @@ class User extends Model implements AuthenticatableContract,
* Enables or disables TOTP on an account if the token is valid. * Enables or disables TOTP on an account if the token is valid.
* *
* @param int $token The token that we want to verify. * @param int $token The token that we want to verify.
* @return boolean * @return bool
*/ */
public function toggleTotp($token) public function toggleTotp($token)
{ {
if (! Google2FA::verifyKey($this->totp_secret, $token)) {
if (!Google2FA::verifyKey($this->totp_secret, $token)) {
return false; return false;
} }
$this->use_totp = !$this->use_totp; $this->use_totp = ! $this->use_totp;
$this->save(); $this->save();
return true; return true;
} }
/** /**
@ -113,7 +110,7 @@ class User extends Model implements AuthenticatableContract,
* - 8 or more characters in length * - 8 or more characters in length
* - at least one uppercase character * - at least one uppercase character
* - at least one lowercase character * - at least one lowercase character
* - at least one number * - at least one number.
* *
* @param string $password The raw password to set the account password to. * @param string $password The raw password to set the account password to.
* @param string $regex The regex to use when validating the password. Defaults to '((?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,})'. * @param string $regex The regex to use when validating the password. Defaults to '((?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,})'.
@ -121,16 +118,12 @@ class User extends Model implements AuthenticatableContract,
*/ */
public function setPassword($password, $regex = '((?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,})') public function setPassword($password, $regex = '((?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,})')
{ {
if (! preg_match($regex, $password)) {
if (!preg_match($regex, $password)) {
throw new DisplayException('The password passed did not meet the minimum password requirements.'); throw new DisplayException('The password passed did not meet the minimum password requirements.');
} }
$this->password = Hash::make($password); $this->password = Hash::make($password);
$this->save(); $this->save();
return;
} }
/** /**
@ -143,5 +136,4 @@ class User extends Model implements AuthenticatableContract,
{ {
$this->notify(new ResetPasswordNotification($token)); $this->notify(new ResetPasswordNotification($token));
} }
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,6 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Notifications; namespace Pterodactyl\Notifications;
use Illuminate\Bus\Queueable; use Illuminate\Bus\Queueable;
@ -73,5 +74,4 @@ class AccountCreated extends Notification implements ShouldQueue
->line('Email: ' . $notifiable->email) ->line('Email: ' . $notifiable->email)
->action('Setup Your Account', url('/auth/password/reset/' . $this->token . '?email=' . $notifiable->email)); ->action('Setup Your Account', url('/auth/password/reset/' . $this->token . '?email=' . $notifiable->email));
} }
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,6 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Notifications; namespace Pterodactyl\Notifications;
use Illuminate\Bus\Queueable; use Illuminate\Bus\Queueable;

View file

@ -52,5 +52,4 @@ class ServerCreated extends Notification implements ShouldQueue
->action('Peel Off the Protective Wrap', route('server.index', $this->server->uuidShort)) ->action('Peel Off the Protective Wrap', route('server.index', $this->server->uuidShort))
->line('Please let us know if you have any additional questions or concerns!'); ->line('Please let us know if you have any additional questions or concerns!');
} }
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,6 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Policies; namespace Pterodactyl\Policies;
use Pterodactyl\Models\User; use Pterodactyl\Models\User;
@ -28,7 +29,6 @@ use Pterodactyl\Models\Server;
class ServerPolicy class ServerPolicy
{ {
/** /**
* Create a new policy instance. * Create a new policy instance.
* *
@ -42,9 +42,9 @@ class ServerPolicy
/** /**
* Determine if current user is the owner of a server. * Determine if current user is the owner of a server.
* *
* @param Pterodactyl\Models\User $user * @param \Pterodactyl\Models\User $user
* @param Pterodactyl\Models\Server $server * @param \Pterodactyl\Models\Server $server
* @return boolean * @return bool
*/ */
protected function isOwner(User $user, Server $server) protected function isOwner(User $user, Server $server)
{ {
@ -54,9 +54,9 @@ class ServerPolicy
/** /**
* Runs before any of the functions are called. Used to determine if user is root admin, if so, ignore permissions. * Runs before any of the functions are called. Used to determine if user is root admin, if so, ignore permissions.
* *
* @param Pterodactyl\Models\User $user * @param \Pterodactyl\Models\User $user
* @param string $ability * @param string $ability
* @return boolean * @return bool
*/ */
public function before(User $user, $ability) public function before(User $user, $ability)
{ {
@ -68,578 +68,450 @@ class ServerPolicy
/** /**
* Check if user has permission to control power for a server. * Check if user has permission to control power for a server.
* *
* @param Pterodactyl\Models\User $user * @param \Pterodactyl\Models\User $user
* @param Pterodactyl\Models\Server $server * @param \Pterodactyl\Models\Server $server
* @return boolean * @return bool
*/ */
public function power(User $user, Server $server) public function power(User $user, Server $server)
{ {
if ($this->isOwner($user, $server)) { return $this->checkPermission($user, $server, 'power');
return true;
}
return $user->permissions()->server($server)->permission('power')->exists();
} }
/** /**
* Check if user has permission to start a server. * Check if user has permission to start a server.
* *
* @param Pterodactyl\Models\User $user * @param \Pterodactyl\Models\User $user
* @param Pterodactyl\Models\Server $server * @param \Pterodactyl\Models\Server $server
* @return boolean * @return bool
*/ */
public function powerStart(User $user, Server $server) public function powerStart(User $user, Server $server)
{ {
if ($this->isOwner($user, $server)) { return $this->checkPermission($user, $server, 'power-start');
return true;
}
return $user->permissions()->server($server)->permission('power-start')->exists();
} }
/** /**
* Check if user has permission to stop a server. * Check if user has permission to stop a server.
* *
* @param Pterodactyl\Models\User $user * @param \Pterodactyl\Models\User $user
* @param Pterodactyl\Models\Server $server * @param \Pterodactyl\Models\Server $server
* @return boolean * @return bool
*/ */
public function powerStop(User $user, Server $server) public function powerStop(User $user, Server $server)
{ {
if ($this->isOwner($user, $server)) { return $this->checkPermission($user, $server, 'power-stop');
return true;
}
return $user->permissions()->server($server)->permission('power-stop')->exists();
} }
/** /**
* Check if user has permission to restart a server. * Check if user has permission to restart a server.
* *
* @param Pterodactyl\Models\User $user * @param \Pterodactyl\Models\User $user
* @param Pterodactyl\Models\Server $server * @param \Pterodactyl\Models\Server $server
* @return boolean * @return bool
*/ */
public function powerRestart(User $user, Server $server) public function powerRestart(User $user, Server $server)
{ {
if ($this->isOwner($user, $server)) { return $this->checkPermission($user, $server, 'power-restart');
return true;
}
return $user->permissions()->server($server)->permission('power-restart')->exists();
} }
/** /**
* Check if user has permission to kill a server. * Check if user has permission to kill a server.
* *
* @param Pterodactyl\Models\User $user * @param \Pterodactyl\Models\User $user
* @param Pterodactyl\Models\Server $server * @param \Pterodactyl\Models\Server $server
* @return boolean * @return bool
*/ */
public function powerKill(User $user, Server $server) public function powerKill(User $user, Server $server)
{ {
if ($this->isOwner($user, $server)) { return $this->checkPermission($user, $server, 'power-kill');
return true;
}
return $user->permissions()->server($server)->permission('power-kill')->exists();
} }
/** /**
* Check if user has permission to run a command on a server. * Check if user has permission to run a command on a server.
* *
* @param Pterodactyl\Models\User $user * @param \Pterodactyl\Models\User $user
* @param Pterodactyl\Models\Server $server * @param \Pterodactyl\Models\Server $server
* @return boolean * @return bool
*/ */
public function sendCommand(User $user, Server $server) public function sendCommand(User $user, Server $server)
{ {
if ($this->isOwner($user, $server)) { return $this->checkPermission($user, $server, 'send-command');
return true;
}
return $user->permissions()->server($server)->permission('send-command')->exists();
} }
/** /**
* Check if user has permission to list files on a server. * Check if user has permission to list files on a server.
* *
* @param Pterodactyl\Models\User $user * @param \Pterodactyl\Models\User $user
* @param Pterodactyl\Models\Server $server * @param \Pterodactyl\Models\Server $server
* @return boolean * @return bool
*/ */
public function listFiles(User $user, Server $server) public function listFiles(User $user, Server $server)
{ {
if ($this->isOwner($user, $server)) { return $this->checkPermission($user, $server, 'list-files');
return true;
}
return $user->permissions()->server($server)->permission('list-files')->exists();
} }
/** /**
* Check if user has permission to edit files on a server. * Check if user has permission to edit files on a server.
* *
* @param Pterodactyl\Models\User $user * @param \Pterodactyl\Models\User $user
* @param Pterodactyl\Models\Server $server * @param \Pterodactyl\Models\Server $server
* @return boolean * @return bool
*/ */
public function editFiles(User $user, Server $server) public function editFiles(User $user, Server $server)
{ {
if ($this->isOwner($user, $server)) { return $this->checkPermission($user, $server, 'edit-files');
return true;
}
return $user->permissions()->server($server)->permission('edit-files')->exists();
} }
/** /**
* Check if user has permission to save files on a server. * Check if user has permission to save files on a server.
* *
* @param Pterodactyl\Models\User $user * @param \Pterodactyl\Models\User $user
* @param Pterodactyl\Models\Server $server * @param \Pterodactyl\Models\Server $server
* @return boolean * @return bool
*/ */
public function saveFiles(User $user, Server $server) public function saveFiles(User $user, Server $server)
{ {
if ($this->isOwner($user, $server)) { return $this->checkPermission($user, $server, 'save-files');
return true;
}
return $user->permissions()->server($server)->permission('save-files')->exists();
} }
/** /**
* Check if user has permission to move and rename files and folders on a server. * Check if user has permission to move and rename files and folders on a server.
* *
* @param Pterodactyl\Models\User $user * @param \Pterodactyl\Models\User $user
* @param Pterodactyl\Models\Server $server * @param \Pterodactyl\Models\Server $server
* @return boolean * @return bool
*/ */
public function moveFiles(User $user, Server $server) public function moveFiles(User $user, Server $server)
{ {
if ($this->isOwner($user, $server)) { return $this->checkPermission($user, $server, 'move-files');
return true;
}
return $user->permissions()->server($server)->permission('move-files')->exists();
} }
/** /**
* Check if user has permission to copy folders and files on a server. * Check if user has permission to copy folders and files on a server.
* *
* @param Pterodactyl\Models\User $user * @param \Pterodactyl\Models\User $user
* @param Pterodactyl\Models\Server $server * @param \Pterodactyl\Models\Server $server
* @return boolean * @return bool
*/ */
public function copyFiles(User $user, Server $server) public function copyFiles(User $user, Server $server)
{ {
if ($this->isOwner($user, $server)) { return $this->checkPermission($user, $server, 'copy-files');
return true;
}
return $user->permissions()->server($server)->permission('copy-files')->exists();
} }
/** /**
* Check if user has permission to compress files and folders on a server. * Check if user has permission to compress files and folders on a server.
* *
* @param Pterodactyl\Models\User $user * @param \Pterodactyl\Models\User $user
* @param Pterodactyl\Models\Server $server * @param \Pterodactyl\Models\Server $server
* @return boolean * @return bool
*/ */
public function compressFiles(User $user, Server $server) public function compressFiles(User $user, Server $server)
{ {
if ($this->isOwner($user, $server)) { return $this->checkPermission($user, $server, 'compress-files');
return true;
}
return $user->permissions()->server($server)->permission('compress-files')->exists();
} }
/** /**
* Check if user has permission to decompress files on a server. * Check if user has permission to decompress files on a server.
* *
* @param Pterodactyl\Models\User $user * @param \Pterodactyl\Models\User $user
* @param Pterodactyl\Models\Server $server * @param \Pterodactyl\Models\Server $server
* @return boolean * @return bool
*/ */
public function decompressFiles(User $user, Server $server) public function decompressFiles(User $user, Server $server)
{ {
if ($this->isOwner($user, $server)) { return $this->checkPermission($user, $server, 'decompress-files');
return true;
}
return $user->permissions()->server($server)->permission('decompress-files')->exists();
} }
/** /**
* Check if user has permission to add files to a server. * Check if user has permission to add files to a server.
* *
* @param Pterodactyl\Models\User $user * @param \Pterodactyl\Models\User $user
* @param Pterodactyl\Models\Server $server * @param \Pterodactyl\Models\Server $server
* @return boolean * @return bool
*/ */
public function addFiles(User $user, Server $server) public function addFiles(User $user, Server $server)
{ {
if ($this->isOwner($user, $server)) { return $this->checkPermission($user, $server, 'add-files');
return true;
}
return $user->permissions()->server($server)->permission('add-files')->exists();
} }
/** /**
* Check if user has permission to upload files to a server. * Check if user has permission to upload files to a server.
* This permission relies on the user having the 'add-files' permission as well due to page authorization. * This permission relies on the user having the 'add-files' permission as well due to page authorization.
* *
* @param Pterodactyl\Models\User $user * @param \Pterodactyl\Models\User $user
* @param Pterodactyl\Models\Server $server * @param \Pterodactyl\Models\Server $server
* @return boolean * @return bool
*/ */
public function uploadFiles(User $user, Server $server) public function uploadFiles(User $user, Server $server)
{ {
if ($this->isOwner($user, $server)) { return $this->checkPermission($user, $server, 'upload-files');
return true;
}
return $user->permissions()->server($server)->permission('upload-files')->exists();
} }
/** /**
* Check if user has permission to download files from a server. * Check if user has permission to download files from a server.
* *
* @param Pterodactyl\Models\User $user * @param \Pterodactyl\Models\User $user
* @param Pterodactyl\Models\Server $server * @param \Pterodactyl\Models\Server $server
* @return boolean * @return bool
*/ */
public function downloadFiles(User $user, Server $server) public function downloadFiles(User $user, Server $server)
{ {
if ($this->isOwner($user, $server)) { return $this->checkPermission($user, $server, 'download-files');
return true;
}
return $user->permissions()->server($server)->permission('download-files')->exists();
} }
/** /**
* Check if user has permission to delete files from a server. * Check if user has permission to delete files from a server.
* *
* @param Pterodactyl\Models\User $user * @param \Pterodactyl\Models\User $user
* @param Pterodactyl\Models\Server $server * @param \Pterodactyl\Models\Server $server
* @return boolean * @return bool
*/ */
public function deleteFiles(User $user, Server $server) public function deleteFiles(User $user, Server $server)
{ {
if ($this->isOwner($user, $server)) { return $this->checkPermission($user, $server, 'delete-files');
return true;
}
return $user->permissions()->server($server)->permission('delete-files')->exists();
} }
/** /**
* Check if user has permission to view subusers for the server. * Check if user has permission to view subusers for the server.
* *
* @param Pterodactyl\Models\User $user * @param \Pterodactyl\Models\User $user
* @param Pterodactyl\Models\Server $server * @param \Pterodactyl\Models\Server $server
* @return boolean * @return bool
*/ */
public function listSubusers(User $user, Server $server) public function listSubusers(User $user, Server $server)
{ {
if ($this->isOwner($user, $server)) { return $this->checkPermission($user, $server, 'list-subusers');
return true;
}
return $user->permissions()->server($server)->permission('list-subusers')->exists();
} }
/** /**
* Check if user has permission to view specific subuser permissions. * Check if user has permission to view specific subuser permissions.
* *
* @param Pterodactyl\Models\User $user * @param \Pterodactyl\Models\User $user
* @param Pterodactyl\Models\Server $server * @param \Pterodactyl\Models\Server $server
* @return boolean * @return bool
*/ */
public function viewSubuser(User $user, Server $server) public function viewSubuser(User $user, Server $server)
{ {
if ($this->isOwner($user, $server)) { return $this->checkPermission($user, $server, 'view-subuser');
return true;
}
return $user->permissions()->server($server)->permission('view-subuser')->exists();
} }
/** /**
* Check if user has permission to edit a subuser. * Check if user has permission to edit a subuser.
* *
* @param Pterodactyl\Models\User $user * @param \Pterodactyl\Models\User $user
* @param Pterodactyl\Models\Server $server * @param \Pterodactyl\Models\Server $server
* @return boolean * @return bool
*/ */
public function editSubuser(User $user, Server $server) public function editSubuser(User $user, Server $server)
{ {
if ($this->isOwner($user, $server)) { return $this->checkPermission($user, $server, 'edit-subuser');
return true;
}
return $user->permissions()->server($server)->permission('edit-subuser')->exists();
} }
/** /**
* Check if user has permission to delete a subuser. * Check if user has permission to delete a subuser.
* *
* @param Pterodactyl\Models\User $user * @param \Pterodactyl\Models\User $user
* @param Pterodactyl\Models\Server $server * @param \Pterodactyl\Models\Server $server
* @return boolean * @return bool
*/ */
public function deleteSubuser(User $user, Server $server) public function deleteSubuser(User $user, Server $server)
{ {
if ($this->isOwner($user, $server)) { return $this->checkPermission($user, $server, 'delete-subuser');
return true;
}
return $user->permissions()->server($server)->permission('delete-subuser')->exists();
} }
/** /**
* Check if user has permission to edit a subuser. * Check if user has permission to edit a subuser.
* *
* @param Pterodactyl\Models\User $user * @param \Pterodactyl\Models\User $user
* @param Pterodactyl\Models\Server $server * @param \Pterodactyl\Models\Server $server
* @return boolean * @return bool
*/ */
public function createSubuser(User $user, Server $server) public function createSubuser(User $user, Server $server)
{ {
if ($this->isOwner($user, $server)) { return $this->checkPermission($user, $server, 'create-subuser');
return true;
}
return $user->permissions()->server($server)->permission('create-subuser')->exists();
} }
/** /**
* Check if user has permission to set the default connection for a server. * Check if user has permission to set the default connection for a server.
* *
* @param Pterodactyl\Models\User $user * @param \Pterodactyl\Models\User $user
* @param Pterodactyl\Models\Server $server * @param \Pterodactyl\Models\Server $server
* @return boolean * @return bool
*/ */
public function setConnection(User $user, Server $server) public function setConnection(User $user, Server $server)
{ {
if ($this->isOwner($user, $server)) { return $this->checkPermission($user, $server, 'set-connection');
return true;
}
return $user->permissions()->server($server)->permission('set-connection')->exists();
} }
/** /**
* Check if user has permission to view the startup command used for a server. * Check if user has permission to view the startup command used for a server.
* *
* @param Pterodactyl\Models\User $user * @param \Pterodactyl\Models\User $user
* @param Pterodactyl\Models\Server $server * @param \Pterodactyl\Models\Server $server
* @return boolean * @return bool
*/ */
public function viewStartup(User $user, Server $server) public function viewStartup(User $user, Server $server)
{ {
if ($this->isOwner($user, $server)) { return $this->checkPermission($user, $server, 'view-startup');
return true;
}
return $user->permissions()->server($server)->permission('view-startup')->exists();
} }
/** /**
* Check if user has permission to edit the startup command used for a server. * Check if user has permission to edit the startup command used for a server.
* *
* @param Pterodactyl\Models\User $user * @param \Pterodactyl\Models\User $user
* @param Pterodactyl\Models\Server $server * @param \Pterodactyl\Models\Server $server
* @return boolean * @return bool
*/ */
public function editStartup(User $user, Server $server) public function editStartup(User $user, Server $server)
{ {
if ($this->isOwner($user, $server)) { return $this->checkPermission($user, $server, 'edit-startup');
return true;
}
return $user->permissions()->server($server)->permission('edit-startup')->exists();
} }
/** /**
* Check if user has permission to view the SFTP information for a server. * Check if user has permission to view the SFTP information for a server.
* *
* @param Pterodactyl\Models\User $user * @param \Pterodactyl\Models\User $user
* @param Pterodactyl\Models\Server $server * @param \Pterodactyl\Models\Server $server
* @return boolean * @return bool
*/ */
public function viewSftp(User $user, Server $server) public function viewSftp(User $user, Server $server)
{ {
if ($this->isOwner($user, $server)) { return $this->checkPermission($user, $server, 'view-sftp');
return true;
}
return $user->permissions()->server($server)->permission('view-sftp')->exists();
} }
/** /**
* Check if user has permission to reset the SFTP password for a server. * Check if user has permission to reset the SFTP password for a server.
* *
* @param Pterodactyl\Models\User $user * @param \Pterodactyl\Models\User $user
* @param Pterodactyl\Models\Server $server * @param \Pterodactyl\Models\Server $server
* @return boolean * @return bool
*/ */
public function resetSftp(User $user, Server $server) public function resetSftp(User $user, Server $server)
{ {
if ($this->isOwner($user, $server)) { return $this->checkPermission($user, $server, 'reset-sftp');
return true;
}
return $user->permissions()->server($server)->permission('reset-sftp')->exists();
} }
/** /**
* Check if user has permission to view the SFTP password for a server. * Check if user has permission to view the SFTP password for a server.
* *
* @param Pterodactyl\Models\User $user * @param \Pterodactyl\Models\User $user
* @param Pterodactyl\Models\Server $server * @param \Pterodactyl\Models\Server $server
* @return boolean * @return bool
*/ */
public function viewSftpPassword(User $user, Server $server) public function viewSftpPassword(User $user, Server $server)
{ {
if ($this->isOwner($user, $server)) { return $this->checkPermission($user, $server, 'view-sftp-password');
return true;
}
return $user->permissions()->server($server)->permission('view-sftp-password')->exists();
} }
/** /**
* Check if user has permission to view databases for a server. * Check if user has permission to view databases for a server.
* *
* @param Pterodactyl\Models\User $user * @param \Pterodactyl\Models\User $user
* @param Pterodactyl\Models\Server $server * @param \Pterodactyl\Models\Server $server
* @return boolean * @return bool
*/ */
public function viewDatabases(User $user, Server $server) public function viewDatabases(User $user, Server $server)
{ {
if ($this->isOwner($user, $server)) { return $this->checkPermission($user, $server, 'view-databases');
return true;
}
return $user->permissions()->server($server)->permission('view-databases')->exists();
} }
/** /**
* Check if user has permission to reset database passwords. * Check if user has permission to reset database passwords.
* *
* @param Pterodactyl\Models\User $user * @param \Pterodactyl\Models\User $user
* @param Pterodactyl\Models\Server $server * @param \Pterodactyl\Models\Server $server
* @return boolean * @return bool
*/ */
public function resetDbPassword(User $user, Server $server) public function resetDbPassword(User $user, Server $server)
{ {
if ($this->isOwner($user, $server)) { return $this->checkPermission($user, $server, 'reset-db-password');
return true;
}
return $user->permissions()->server($server)->permission('reset-db-password')->exists();
} }
/** /**
* Check if user has permission to view all tasks for a server. * Check if user has permission to view all tasks for a server.
* *
* @param Pterodactyl\Models\User $user * @param \Pterodactyl\Models\User $user
* @param Pterodactyl\Models\Server $server * @param \Pterodactyl\Models\Server $server
* @return boolean * @return bool
*/ */
public function listTasks(User $user, Server $server) public function listTasks(User $user, Server $server)
{ {
if ($this->isOwner($user, $server)) { return $this->checkPermission($user, $server, 'list-tasks');
return true;
}
return $user->permissions()->server($server)->permission('list-tasks')->exists();
} }
/** /**
* Check if user has permission to view a specific task for a server. * Check if user has permission to view a specific task for a server.
* *
* @param Pterodactyl\Models\User $user * @param \Pterodactyl\Models\User $user
* @param Pterodactyl\Models\Server $server * @param \Pterodactyl\Models\Server $server
* @return boolean * @return bool
*/ */
public function viewTask(User $user, Server $server) public function viewTask(User $user, Server $server)
{ {
if ($this->isOwner($user, $server)) { return $this->checkPermission($user, $server, 'view-task');
return true;
}
return $user->permissions()->server($server)->permission('view-task')->exists();
} }
/** /**
* Check if user has permission to view a toggle a task for a server. * Check if user has permission to view a toggle a task for a server.
* *
* @param Pterodactyl\Models\User $user * @param \Pterodactyl\Models\User $user
* @param Pterodactyl\Models\Server $server * @param \Pterodactyl\Models\Server $server
* @return boolean * @return bool
*/ */
public function toggleTask(User $user, Server $server) public function toggleTask(User $user, Server $server)
{ {
if ($this->isOwner($user, $server)) { return $this->checkPermission($user, $server, 'toggle-task');
return true;
}
return $user->permissions()->server($server)->permission('toggle-task')->exists();
} }
/** /**
* Check if user has permission to queue a task for a server. * Check if user has permission to queue a task for a server.
* *
* @param Pterodactyl\Models\User $user * @param \Pterodactyl\Models\User $user
* @param Pterodactyl\Models\Server $server * @param \Pterodactyl\Models\Server $server
* @return boolean * @return bool
*/ */
public function queueTask(User $user, Server $server) public function queueTask(User $user, Server $server)
{ {
if ($this->isOwner($user, $server)) { return $this->checkPermission($user, $server, 'queue-task');
return true;
}
return $user->permissions()->server($server)->permission('queue-task')->exists();
} }
/** /**
* Check if user has permission to delete a specific task for a server. * Check if user has permission to delete a specific task for a server.
* *
* @param Pterodactyl\Models\User $user * @param \Pterodactyl\Models\User $user
* @param Pterodactyl\Models\Server $server * @param \Pterodactyl\Models\Server $server
* @return boolean * @return bool
*/ */
public function deleteTask(User $user, Server $server) public function deleteTask(User $user, Server $server)
{ {
if ($this->isOwner($user, $server)) { return $this->checkPermission($user, $server, 'delete-task');
return true;
}
return $user->permissions()->server($server)->permission('delete-task')->exists();
} }
/** /**
* Check if user has permission to create a task for a server. * Check if user has permission to create a task for a server.
* *
* @param Pterodactyl\Models\User $user * @param \Pterodactyl\Models\User $user
* @param Pterodactyl\Models\Server $server * @param \Pterodactyl\Models\Server $server
* @return boolean * @return bool
*/ */
public function createTask(User $user, Server $server) public function createTask(User $user, Server $server)
{
return $this->checkPermission($user, $server, 'create-task');
}
/**
* Checks if the user has the given permission on/for the server.
*
* @param \Pterodactyl\Models\User $user
* @param \Pterodactyl\Models\Server $server
* @param $permission
* @return bool
*/
private function checkPermission(User $user, Server $server, $permission)
{ {
if ($this->isOwner($user, $server)) { if ($this->isOwner($user, $server)) {
return true; return true;
} }
return $user->permissions()->server($server)->permission('create-task')->exists(); return $user->permissions()->server($server)->permission($permission)->exists();
} }
} }

View file

@ -13,7 +13,7 @@ class AuthServiceProvider extends ServiceProvider
* @var array * @var array
*/ */
protected $policies = [ protected $policies = [
'Pterodactyl\Models\Server' => 'Pterodactyl\Policies\ServerPolicy' 'Pterodactyl\Models\Server' => 'Pterodactyl\Policies\ServerPolicy',
]; ];
/** /**

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,21 +21,20 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Repositories; namespace Pterodactyl\Repositories;
use Auth;
use DB; use DB;
use Auth;
use Crypt; use Crypt;
use Validator; use Validator;
use IPTools\Network; use IPTools\Network;
use Pterodactyl\Models; use Pterodactyl\Models;
use Pterodactyl\Exceptions\DisplayException; use Pterodactyl\Exceptions\DisplayException;
use Pterodactyl\Exceptions\DisplayValidationException; use Pterodactyl\Exceptions\DisplayValidationException;
class APIRepository class APIRepository
{ {
/** /**
* Valid API permissions. * Valid API permissions.
* @var array * @var array
@ -97,7 +96,7 @@ class APIRepository
protected $user; protected $user;
/** /**
* Constructor * Constructor.
*/ */
public function __construct(Models\User $user = null) public function __construct(Models\User $user = null)
{ {
@ -117,17 +116,17 @@ class APIRepository
* *
* @return string Returns the generated secret token. * @return string Returns the generated secret token.
*/ */
public function new(array $data) public function create(array $data)
{ {
$validator = Validator::make($data, [ $validator = Validator::make($data, [
'memo' => 'string|max:500', 'memo' => 'string|max:500',
'permissions' => 'sometimes|required|array', 'permissions' => 'sometimes|required|array',
'adminPermissions' => 'sometimes|required|array' 'adminPermissions' => 'sometimes|required|array',
]); ]);
$validator->after(function($validator) use ($data) { $validator->after(function ($validator) use ($data) {
if (array_key_exists('allowed_ips', $data) && !empty($data['allowed_ips'])) { if (array_key_exists('allowed_ips', $data) && ! empty($data['allowed_ips'])) {
foreach(explode("\n", $data['allowed_ips']) as $ip) { foreach (explode("\n", $data['allowed_ips']) as $ip) {
$ip = trim($ip); $ip = trim($ip);
try { try {
Network::parse($ip); Network::parse($ip);
@ -155,14 +154,16 @@ class APIRepository
'secret' => Crypt::encrypt($secretKey), 'secret' => Crypt::encrypt($secretKey),
'allowed_ips' => empty($this->allowed) ? null : json_encode($this->allowed), 'allowed_ips' => empty($this->allowed) ? null : json_encode($this->allowed),
'memo' => $data['memo'], 'memo' => $data['memo'],
'expires_at' => null 'expires_at' => null,
]); ]);
$key->save(); $key->save();
$totalPermissions = 0; $totalPermissions = 0;
if (isset($data['permissions'])) { if (isset($data['permissions'])) {
foreach($data['permissions'] as $permNode) { foreach ($data['permissions'] as $permNode) {
if (!strpos($permNode, ':')) continue; if (! strpos($permNode, ':')) {
continue;
}
list($toss, $permission) = explode(':', $permNode); list($toss, $permission) = explode(':', $permNode);
if (in_array($permission, $this->permissions['user'])) { if (in_array($permission, $this->permissions['user'])) {
@ -170,7 +171,7 @@ class APIRepository
$model = new Models\APIPermission; $model = new Models\APIPermission;
$model->fill([ $model->fill([
'key_id' => $key->id, 'key_id' => $key->id,
'permission' => 'api.user.' . $permission 'permission' => 'api.user.' . $permission,
]); ]);
$model->save(); $model->save();
} }
@ -178,8 +179,10 @@ class APIRepository
} }
if ($this->user->root_admin === 1 && isset($data['adminPermissions'])) { if ($this->user->root_admin === 1 && isset($data['adminPermissions'])) {
foreach($data['adminPermissions'] as $permNode) { foreach ($data['adminPermissions'] as $permNode) {
if (!strpos($permNode, ':')) continue; if (! strpos($permNode, ':')) {
continue;
}
list($toss, $permission) = explode(':', $permNode); list($toss, $permission) = explode(':', $permNode);
if (in_array($permission, $this->permissions['admin'])) { if (in_array($permission, $this->permissions['admin'])) {
@ -187,7 +190,7 @@ class APIRepository
$model = new Models\APIPermission; $model = new Models\APIPermission;
$model->fill([ $model->fill([
'key_id' => $key->id, 'key_id' => $key->id,
'permission' => 'api.admin.' . $permission 'permission' => 'api.admin.' . $permission,
]); ]);
$model->save(); $model->save();
} }
@ -199,12 +202,12 @@ class APIRepository
} }
DB::commit(); DB::commit();
return $secretKey; return $secretKey;
} catch (\Exception $ex) { } catch (\Exception $ex) {
DB::rollBack(); DB::rollBack();
throw $ex; throw $ex;
} }
} }
/** /**
@ -216,13 +219,13 @@ class APIRepository
* *
* @return void * @return void
*/ */
public function revoke(string $key) public function revoke($key)
{ {
DB::beginTransaction(); DB::beginTransaction();
try { try {
$model = Models\APIKey::where('public', $key)->where('user', $this->user->id)->firstOrFail(); $model = Models\APIKey::where('public', $key)->where('user', $this->user->id)->firstOrFail();
$permissions = Models\APIPermission::where('key_id', $model->id)->delete(); Models\APIPermission::where('key_id', $model->id)->delete();
$model->delete(); $model->delete();
DB::commit(); DB::commit();
@ -231,5 +234,4 @@ class APIRepository
throw $ex; throw $ex;
} }
} }
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,16 +21,16 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Repositories\Daemon; namespace Pterodactyl\Repositories\Daemon;
use GuzzleHttp\Client;
use Pterodactyl\Models; use Pterodactyl\Models;
use GuzzleHttp\Exception\RequestException;
use Pterodactyl\Exceptions\DisplayException; use Pterodactyl\Exceptions\DisplayException;
use GuzzleHttp\Client; class CommandRepository
use GuzzleHttp\Exception\RequestException; {
class CommandRepository {
protected $server; protected $server;
protected $node; protected $node;
protected $client; protected $client;
@ -43,9 +43,9 @@ class CommandRepository {
} }
/** /**
* [send description] * [send description].
* @param string $command * @param string $command
* @return boolean * @return bool
* @throws DisplayException * @throws DisplayException
* @throws RequestException * @throws RequestException
*/ */
@ -59,11 +59,11 @@ class CommandRepository {
$response = $this->client->request('POST', '/server/command', [ $response = $this->client->request('POST', '/server/command', [
'headers' => [ 'headers' => [
'X-Access-Token' => $this->server->daemonSecret, 'X-Access-Token' => $this->server->daemonSecret,
'X-Access-Server' => $this->server->uuid 'X-Access-Server' => $this->server->uuid,
], ],
'json' => [ 'json' => [
'command' => $command 'command' => $command,
] ],
]); ]);
if ($response->getStatusCode() < 200 || $response->getStatusCode() >= 300) { if ($response->getStatusCode() < 200 || $response->getStatusCode() >= 300) {
@ -75,5 +75,4 @@ class CommandRepository {
throw $ex; throw $ex;
} }
} }
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,22 +21,18 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Repositories\Daemon; namespace Pterodactyl\Repositories\Daemon;
use \Exception; use Exception;
use Log;
use Pterodactyl\Models\Server;
use Pterodactyl\Models\Node;
use Pterodactyl\Repositories\HelperRepository;
use Pterodactyl\Exceptions\DisplayException;
use GuzzleHttp\Client; use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException; use Pterodactyl\Models\Node;
use Pterodactyl\Models\Server;
use Pterodactyl\Exceptions\DisplayException;
use Pterodactyl\Repositories\HelperRepository;
class FileRepository class FileRepository
{ {
/** /**
* The Eloquent Model associated with the requested server. * The Eloquent Model associated with the requested server.
* *
@ -60,25 +56,23 @@ class FileRepository
/** /**
* The Guzzle Client headers associated with the requested server and node. * The Guzzle Client headers associated with the requested server and node.
* (non-administrative headers) * (non-administrative headers).
* *
* @var array * @var array
*/ */
protected $headers; protected $headers;
/** /**
* Constructor * Constructor.
* *
* @param string $server The server Short UUID * @param string $server The server Short UUID
*/ */
public function __construct($uuid) public function __construct($uuid)
{ {
$this->server = Server::getByUUID($uuid); $this->server = Server::getByUUID($uuid);
$this->node = Node::getByID($this->server->node); $this->node = Node::getByID($this->server->node);
$this->client = Node::guzzleRequest($this->server->node); $this->client = Node::guzzleRequest($this->server->node);
$this->headers = Server::getGuzzleHeaders($uuid); $this->headers = Server::getGuzzleHeaders($uuid);
} }
/** /**
@ -89,7 +83,6 @@ class FileRepository
*/ */
public function returnFileContents($file) public function returnFileContents($file)
{ {
if (empty($file)) { if (empty($file)) {
throw new Exception('Not all parameters were properly passed to the function.'); throw new Exception('Not all parameters were properly passed to the function.');
} }
@ -98,16 +91,16 @@ class FileRepository
$file->dirname = (in_array($file->dirname, ['.', './', '/'])) ? null : trim($file->dirname, '/') . '/'; $file->dirname = (in_array($file->dirname, ['.', './', '/'])) ? null : trim($file->dirname, '/') . '/';
$res = $this->client->request('GET', '/server/file/stat/' . rawurlencode($file->dirname.$file->basename) , [ $res = $this->client->request('GET', '/server/file/stat/' . rawurlencode($file->dirname . $file->basename), [
'headers' => $this->headers 'headers' => $this->headers,
]); ]);
$stat = json_decode($res->getBody()); $stat = json_decode($res->getBody());
if($res->getStatusCode() !== 200 || !isset($stat->size)) { if ($res->getStatusCode() !== 200 || ! isset($stat->size)) {
throw new DisplayException('The daemon provided a non-200 error code on stat lookup: HTTP\\' . $res->getStatusCode()); throw new DisplayException('The daemon provided a non-200 error code on stat lookup: HTTP\\' . $res->getStatusCode());
} }
if (!in_array($stat->mime, HelperRepository::editableFiles())) { if (! in_array($stat->mime, HelperRepository::editableFiles())) {
throw new DisplayException('You cannot edit that type of file (' . $stat->mime . ') through the panel.'); throw new DisplayException('You cannot edit that type of file (' . $stat->mime . ') through the panel.');
} }
@ -115,24 +108,23 @@ class FileRepository
throw new DisplayException('That file is too large to open in the browser, consider using a SFTP client.'); throw new DisplayException('That file is too large to open in the browser, consider using a SFTP client.');
} }
$res = $this->client->request('GET', '/server/file/f/' . rawurlencode($file->dirname.$file->basename) , [ $res = $this->client->request('GET', '/server/file/f/' . rawurlencode($file->dirname . $file->basename), [
'headers' => $this->headers 'headers' => $this->headers,
]); ]);
$json = json_decode($res->getBody()); $json = json_decode($res->getBody());
if($res->getStatusCode() !== 200 || !isset($json->content)) { if ($res->getStatusCode() !== 200 || ! isset($json->content)) {
throw new DisplayException('The daemon provided a non-200 error code: HTTP\\' . $res->getStatusCode()); throw new DisplayException('The daemon provided a non-200 error code: HTTP\\' . $res->getStatusCode());
} }
return [ return [
'file' => $json, 'file' => $json,
'stat' => $stat 'stat' => $stat,
]; ];
} }
/** /**
* Save the contents of a requested file on the Scales instance. * Save the contents of a requested file on the daemon.
* *
* @param string $file * @param string $file
* @param string $content * @param string $content
@ -140,7 +132,6 @@ class FileRepository
*/ */
public function saveFileContents($file, $content) public function saveFileContents($file, $content)
{ {
if (empty($file)) { if (empty($file)) {
throw new Exception('A valid file and path must be specified to save a file.'); throw new Exception('A valid file and path must be specified to save a file.');
} }
@ -152,9 +143,9 @@ class FileRepository
$res = $this->client->request('POST', '/server/file/save', [ $res = $this->client->request('POST', '/server/file/save', [
'headers' => $this->headers, 'headers' => $this->headers,
'json' => [ 'json' => [
'path' => rawurlencode($file->dirname.$file->basename), 'path' => rawurlencode($file->dirname . $file->basename),
'content' => $content 'content' => $content,
] ],
]); ]);
if ($res->getStatusCode() !== 204) { if ($res->getStatusCode() !== 204) {
@ -162,67 +153,57 @@ class FileRepository
} }
return true; return true;
} }
/** /**
* Returns a listing of all files and folders within a specified Scales directory. * Returns a listing of all files and folders within a specified directory on the daemon.
* *
* @param string $directory * @param string $directory
* @return object * @return object
*/ */
public function returnDirectoryListing($directory) public function returnDirectoryListing($directory)
{ {
if (empty($directory)) { if (empty($directory)) {
throw new Exception('A valid directory must be specified in order to list its contents.'); throw new Exception('A valid directory must be specified in order to list its contents.');
} }
$res = $this->client->request('GET', '/server/directory/' . rawurlencode($directory), [ $res = $this->client->request('GET', '/server/directory/' . rawurlencode($directory), [
'headers' => $this->headers 'headers' => $this->headers,
]); ]);
$json = json_decode($res->getBody()); $json = json_decode($res->getBody());
if($res->getStatusCode() !== 200) { if ($res->getStatusCode() !== 200) {
throw new DisplayException('An error occured while attempting to save this file. ' . $res->getBody()); throw new DisplayException('An error occured while attempting to save this file. ' . $res->getBody());
} }
// Iterate through results // Iterate through results
$files = []; $files = [];
$folders = []; $folders = [];
foreach($json as &$value) { foreach ($json as &$value) {
if ($value->directory === true) { if ($value->directory === true) {
// @TODO Handle Symlinks // @TODO Handle Symlinks
$folders = array_merge($folders, [[ $folders[] = [
'entry' => $value->name, 'entry' => $value->name,
'directory' => trim($directory, '/'), 'directory' => trim($directory, '/'),
'size' => null, 'size' => null,
'date' => strtotime($value->modified), 'date' => strtotime($value->modified),
'mime' => $value->mime 'mime' => $value->mime,
]]); ];
} elseif ($value->file === true) {
} else if ($value->file === true) { $files[] = [
$files = array_merge($files, [[
'entry' => $value->name, 'entry' => $value->name,
'directory' => trim($directory, '/'), 'directory' => trim($directory, '/'),
'extension' => pathinfo($value->name, PATHINFO_EXTENSION), 'extension' => pathinfo($value->name, PATHINFO_EXTENSION),
'size' => HelperRepository::bytesToHuman($value->size), 'size' => HelperRepository::bytesToHuman($value->size),
'date' => strtotime($value->modified), 'date' => strtotime($value->modified),
'mime' => $value->mime 'mime' => $value->mime,
]]); ];
} }
} }
return (object) [ return (object) [
'files' => $files, 'files' => $files,
'folders' => $folders, 'folders' => $folders,
]; ];
} }
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,16 +21,15 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Repositories\Daemon; namespace Pterodactyl\Repositories\Daemon;
use GuzzleHttp\Client;
use Pterodactyl\Models; use Pterodactyl\Models;
use Pterodactyl\Exceptions\DisplayException; use Pterodactyl\Exceptions\DisplayException;
use GuzzleHttp\Client; class PowerRepository
use GuzzleHttp\Exception\RequestException; {
class PowerRepository {
protected $server; protected $server;
protected $node; protected $node;
protected $client; protected $client;
@ -52,11 +51,11 @@ class PowerRepository {
$response = $this->client->request('PUT', '/server/power', [ $response = $this->client->request('PUT', '/server/power', [
'headers' => [ 'headers' => [
'X-Access-Token' => $this->server->daemonSecret, 'X-Access-Token' => $this->server->daemonSecret,
'X-Access-Server' => $this->server->uuid 'X-Access-Server' => $this->server->uuid,
], ],
'json' => [ 'json' => [
'action' => $action 'action' => $action,
] ],
]); ]);
if ($response->getStatusCode() < 200 || $response->getStatusCode() >= 300) { if ($response->getStatusCode() < 200 || $response->getStatusCode() >= 300) {
@ -88,5 +87,4 @@ class PowerRepository {
{ {
$this->do('kill'); $this->do('kill');
} }
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,21 +21,19 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Repositories; namespace Pterodactyl\Repositories;
use Crypt;
use Log;
use DB; use DB;
use Crypt;
use Validator; use Validator;
use Pterodactyl\Models; use Pterodactyl\Models;
use Pterodactyl\Exceptions\DisplayException; use Pterodactyl\Exceptions\DisplayException;
use Illuminate\Database\Capsule\Manager as Capsule;
use Pterodactyl\Exceptions\DisplayValidationException; use Pterodactyl\Exceptions\DisplayValidationException;
use Illuminate\Database\Capsule\Manager as Capsule; class DatabaseRepository
{
class DatabaseRepository {
/** /**
* Adds a new database to a given database server. * Adds a new database to a given database server.
* @param int $server Id of the server to add a database for. * @param int $server Id of the server to add a database for.
@ -64,7 +62,7 @@ class DatabaseRepository {
'database' => "s{$server->id}_{$options['database']}", 'database' => "s{$server->id}_{$options['database']}",
'username' => $server->uuidShort . '_' . str_random(7), 'username' => $server->uuidShort . '_' . str_random(7),
'remote' => $options['remote'], 'remote' => $options['remote'],
'password' => Crypt::encrypt(str_random(20)) 'password' => Crypt::encrypt(str_random(20)),
]); ]);
$db->save(); $db->save();
@ -84,11 +82,10 @@ class DatabaseRepository {
'prefix' => '', 'prefix' => '',
'options' => [ 'options' => [
\PDO::ATTR_TIMEOUT => 3, \PDO::ATTR_TIMEOUT => 3,
] ],
]); ]);
$capsule->setAsGlobal(); $capsule->setAsGlobal();
} catch (\Exception $ex) { } catch (\Exception $ex) {
DB::rollBack(); DB::rollBack();
throw new DisplayException('There was an error while connecting to the Database Host Server. Please check the error logs.', $ex); throw new DisplayException('There was an error while connecting to the Database Host Server. Please check the error logs.', $ex);
@ -128,7 +125,6 @@ class DatabaseRepository {
DB::beginTransaction(); DB::beginTransaction();
try { try {
$db->password = Crypt::encrypt($password); $db->password = Crypt::encrypt($password);
$db->save(); $db->save();
@ -145,7 +141,7 @@ class DatabaseRepository {
'prefix' => '', 'prefix' => '',
'options' => [ 'options' => [
\PDO::ATTR_TIMEOUT => 3, \PDO::ATTR_TIMEOUT => 3,
] ],
]); ]);
$capsule->setAsGlobal(); $capsule->setAsGlobal();
@ -157,16 +153,16 @@ class DatabaseRepository {
)); ));
DB::commit(); DB::commit();
} catch(\Exception $ex) { } catch (\Exception $ex) {
DB::rollback(); DB::rollback();
throw $ex; throw $ex;
} }
} }
/** /**
* Drops a database from the associated MySQL Server * Drops a database from the associated MySQL Server.
* @param int $database The ID of the database to drop. * @param int $database The ID of the database to drop.
* @return boolean * @return bool
*/ */
public function drop($database) public function drop($database)
{ {
@ -189,7 +185,7 @@ class DatabaseRepository {
'prefix' => '', 'prefix' => '',
'options' => [ 'options' => [
\PDO::ATTR_TIMEOUT => 3, \PDO::ATTR_TIMEOUT => 3,
] ],
]); ]);
$capsule->setAsGlobal(); $capsule->setAsGlobal();
@ -200,12 +196,12 @@ class DatabaseRepository {
$db->delete(); $db->delete();
DB::commit(); DB::commit();
return true; return true;
} catch (\Exception $ex) { } catch (\Exception $ex) {
DB::rollback(); DB::rollback();
throw $ex; throw $ex;
} }
} }
/** /**
@ -231,7 +227,6 @@ class DatabaseRepository {
*/ */
public function add(array $data) public function add(array $data)
{ {
if (isset($data['host'])) { if (isset($data['host'])) {
$data['host'] = gethostbyname($data['host']); $data['host'] = gethostbyname($data['host']);
} }
@ -265,7 +260,7 @@ class DatabaseRepository {
'prefix' => '', 'prefix' => '',
'options' => [ 'options' => [
\PDO::ATTR_TIMEOUT => 3, \PDO::ATTR_TIMEOUT => 3,
] ],
]); ]);
$capsule->setAsGlobal(); $capsule->setAsGlobal();
@ -280,8 +275,8 @@ class DatabaseRepository {
'port' => $data['port'], 'port' => $data['port'],
'username' => $data['username'], 'username' => $data['username'],
'password' => Crypt::encrypt($data['password']), 'password' => Crypt::encrypt($data['password']),
'max_databases' => NULL, 'max_databases' => null,
'linked_node' => (!empty($data['linked_node']) && $data['linked_node'] > 0) ? $data['linked_node'] : NULL 'linked_node' => (! empty($data['linked_node']) && $data['linked_node'] > 0) ? $data['linked_node'] : null,
]); ]);
$dbh->save(); $dbh->save();
@ -291,5 +286,4 @@ class DatabaseRepository {
throw $ex; throw $ex;
} }
} }
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,10 +21,11 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Repositories; namespace Pterodactyl\Repositories;
class HelperRepository { class HelperRepository
{
/** /**
* Listing of editable files in the control panel. * Listing of editable files in the control panel.
* @var array * @var array
@ -40,10 +41,9 @@ class HelperRepository {
'text/plain', 'text/plain',
'text/x-perl', 'text/x-perl',
'text/x-shellscript', 'text/x-shellscript',
'inode/x-empty' 'inode/x-empty',
]; ];
public function __construct() public function __construct()
{ {
// //
@ -58,17 +58,14 @@ class HelperRepository {
*/ */
public static function bytesToHuman($bytes, $decimals = 2) public static function bytesToHuman($bytes, $decimals = 2)
{ {
$sz = explode(',', 'B,KB,MB,GB'); $sz = explode(',', 'B,KB,MB,GB');
$factor = floor((strlen($bytes) - 1) / 3); $factor = floor((strlen($bytes) - 1) / 3);
return sprintf("%.{$decimals}f", $bytes / pow(1024, $factor)).' '.$sz[$factor]; return sprintf("%.{$decimals}f", $bytes / pow(1024, $factor)) . ' ' . $sz[$factor];
} }
public static function editableFiles() public static function editableFiles()
{ {
return self::$editable; return self::$editable;
} }
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,16 +21,15 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Repositories; namespace Pterodactyl\Repositories;
use Validator; use Validator;
use Pterodactyl\Models; use Pterodactyl\Models;
use Pterodactyl\Exceptions\DisplayValidationException; use Pterodactyl\Exceptions\DisplayValidationException;
class LocationRepository class LocationRepository
{ {
public function __construct() public function __construct()
{ {
// //
@ -40,13 +39,13 @@ class LocationRepository
* Creates a new location on the system. * Creates a new location on the system.
* @param array $data * @param array $data
* @throws Pterodactyl\Exceptions\DisplayValidationException * @throws Pterodactyl\Exceptions\DisplayValidationException
* @return integer * @return int
*/ */
public function create(array $data) public function create(array $data)
{ {
$validator = Validator::make($data, [ $validator = Validator::make($data, [
'short' => 'required|regex:/^[a-z0-9_.-]{1,10}$/i|unique:locations,short', 'short' => 'required|regex:/^[a-z0-9_.-]{1,10}$/i|unique:locations,short',
'long' => 'required|string|min:1|max:255' 'long' => 'required|string|min:1|max:255',
]); ]);
// Run validator, throw catchable and displayable exception if it fails. // Run validator, throw catchable and displayable exception if it fails.
@ -58,7 +57,7 @@ class LocationRepository
$location = new Models\Location; $location = new Models\Location;
$location->fill([ $location->fill([
'long' => $data['long'], 'long' => $data['long'],
'short' => $data['short'] 'short' => $data['short'],
]); ]);
$location->save(); $location->save();
@ -67,16 +66,16 @@ class LocationRepository
/** /**
* Modifies a location based on the fields passed in $data. * Modifies a location based on the fields passed in $data.
* @param integer $id * @param int $id
* @param array $data * @param array $data
* @throws Pterodactyl\Exceptions\DisplayValidationException * @throws Pterodactyl\Exceptions\DisplayValidationException
* @return boolean * @return bool
*/ */
public function edit($id, array $data) public function edit($id, array $data)
{ {
$validator = Validator::make($data, [ $validator = Validator::make($data, [
'short' => 'regex:/^[a-z0-9_.-]{1,10}$/i', 'short' => 'regex:/^[a-z0-9_.-]{1,10}$/i',
'long' => 'string|min:1|max:255' 'long' => 'string|min:1|max:255',
]); ]);
// Run validator, throw catchable and displayable exception if it fails. // Run validator, throw catchable and displayable exception if it fails.

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,20 +21,19 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Repositories; namespace Pterodactyl\Repositories;
use DB; use DB;
use Validator; use Validator;
use IPTools\Network;
use Pterodactyl\Models; use Pterodactyl\Models;
use Pterodactyl\Services\UuidService; use Pterodactyl\Services\UuidService;
use IPTools\Network;
use Pterodactyl\Exceptions\DisplayException; use Pterodactyl\Exceptions\DisplayException;
use Pterodactyl\Exceptions\DisplayValidationException; use Pterodactyl\Exceptions\DisplayValidationException;
class NodeRepository { class NodeRepository
{
public function __construct() public function __construct()
{ {
// //
@ -70,7 +69,7 @@ class NodeRepository {
} }
// Verify FQDN is resolvable, or if not using SSL that the IP is valid. // Verify FQDN is resolvable, or if not using SSL that the IP is valid.
if (!filter_var(gethostbyname($data['fqdn']), FILTER_VALIDATE_IP)) { if (! filter_var(gethostbyname($data['fqdn']), FILTER_VALIDATE_IP)) {
throw new DisplayException('The FQDN (or IP Address) provided does not resolve to a valid IP address.'); throw new DisplayException('The FQDN (or IP Address) provided does not resolve to a valid IP address.');
} }
@ -88,7 +87,6 @@ class NodeRepository {
$node->save(); $node->save();
return $node->id; return $node->id;
} }
public function update($id, array $data) public function update($id, array $data)
@ -106,6 +104,7 @@ class NodeRepository {
'memory_overallocate' => 'numeric|min:-1', 'memory_overallocate' => 'numeric|min:-1',
'disk' => 'numeric|min:1', 'disk' => 'numeric|min:1',
'disk_overallocate' => 'numeric|min:-1', 'disk_overallocate' => 'numeric|min:-1',
'upload_size' => 'numeric|min:0',
'daemonBase' => 'regex:/^([\/][\d\w.\-\/]+)$/', 'daemonBase' => 'regex:/^([\/][\d\w.\-\/]+)$/',
'daemonSFTP' => 'numeric|between:1,65535', 'daemonSFTP' => 'numeric|between:1,65535',
'daemonListen' => 'numeric|between:1,65535', 'daemonListen' => 'numeric|between:1,65535',
@ -122,17 +121,16 @@ class NodeRepository {
if (isset($data['fqdn'])) { if (isset($data['fqdn'])) {
// Verify the FQDN if using SSL // Verify the FQDN if using SSL
if ((isset($data['scheme']) && $data['scheme'] === 'https') || (!isset($data['scheme']) && $node->scheme === 'https')) { if ((isset($data['scheme']) && $data['scheme'] === 'https') || (! isset($data['scheme']) && $node->scheme === 'https')) {
if (filter_var($data['fqdn'], FILTER_VALIDATE_IP)) { if (filter_var($data['fqdn'], FILTER_VALIDATE_IP)) {
throw new DisplayException('A fully qualified domain name is required to use secure comunication on this node.'); throw new DisplayException('A fully qualified domain name is required to use secure comunication on this node.');
} }
} }
// Verify FQDN is resolvable, or if not using SSL that the IP is valid. // Verify FQDN is resolvable, or if not using SSL that the IP is valid.
if (!filter_var(gethostbyname($data['fqdn']), FILTER_VALIDATE_IP)) { if (! filter_var(gethostbyname($data['fqdn']), FILTER_VALIDATE_IP)) {
throw new DisplayException('The FQDN (or IP Address) provided does not resolve to a valid IP address.'); throw new DisplayException('The FQDN (or IP Address) provided does not resolve to a valid IP address.');
} }
} }
// Should we be nulling the overallocations? // Should we be nulling the overallocations?
@ -151,9 +149,43 @@ class NodeRepository {
unset($data['reset_secret']); unset($data['reset_secret']);
} }
// Store the Data $oldDaemonKey = $node->daemonSecret;
return $node->update($data); $node->update($data);
try {
$client = Models\Node::guzzleRequest($node->id);
$client->request('PATCH', '/config', [
'headers' => [
'X-Access-Token' => $oldDaemonKey,
],
'json' => [
'web' => [
'listen' => $node->daemonListen,
'ssl' => [
'enabled' => ($node->scheme === 'https'),
'certificate' => '/etc/letsencrypt/live/' . $node->fqdn . '/fullchain.pem',
'key' => '/etc/letsencrypt/live/' . $node->fqdn . '/privkey.pem',
],
],
'sftp' => [
'path' => $node->daemonBase,
'port' => $node->daemonSFTP,
],
'remote' => [
'base' => config('app.url'),
'download' => route('remote.download'),
'installed' => route('remote.install'),
],
'uploads' => [
'size_limit' => $node->upload_size,
],
'keys' => [
$node->daemonSecret,
],
],
]);
} catch (\Exception $ex) {
throw new DisplayException('Failed to update the node configuration, however your changes have been saved to the database. You will need to manually update the configuration file for the node to apply these changes.');
}
} }
public function addAllocations($id, array $allocations) public function addAllocations($id, array $allocations)
@ -163,7 +195,7 @@ class NodeRepository {
DB::beginTransaction(); DB::beginTransaction();
try { try {
foreach($allocations as $rawIP => $ports) { foreach ($allocations as $rawIP => $ports) {
try { try {
$setAlias = null; $setAlias = null;
$parsedIP = Network::parse($rawIP); $parsedIP = Network::parse($rawIP);
@ -175,25 +207,25 @@ class NodeRepository {
throw $ex; throw $ex;
} }
} }
foreach($parsedIP as $ip) { foreach ($parsedIP as $ip) {
foreach($ports as $port) { foreach ($ports as $port) {
if (!is_int($port) && !preg_match('/^(\d{1,5})-(\d{1,5})$/', $port)) { if (! is_int($port) && ! preg_match('/^(\d{1,5})-(\d{1,5})$/', $port)) {
throw new DisplayException('The mapping for ' . $port . ' is invalid and cannot be processed.'); throw new DisplayException('The mapping for ' . $port . ' is invalid and cannot be processed.');
} }
if (preg_match('/^(\d{1,5})-(\d{1,5})$/', $port, $matches)) { if (preg_match('/^(\d{1,5})-(\d{1,5})$/', $port, $matches)) {
foreach(range($matches[1], $matches[2]) as $assignPort) { foreach (range($matches[1], $matches[2]) as $assignPort) {
$alloc = Models\Allocation::firstOrNew([ $alloc = Models\Allocation::firstOrNew([
'node' => $node->id, 'node' => $node->id,
'ip' => $ip, 'ip' => $ip,
'port' => $assignPort 'port' => $assignPort,
]); ]);
if (!$alloc->exists) { if (! $alloc->exists) {
$alloc->fill([ $alloc->fill([
'node' => $node->id, 'node' => $node->id,
'ip' => $ip, 'ip' => $ip,
'port' => $assignPort, 'port' => $assignPort,
'ip_alias' => $setAlias, 'ip_alias' => $setAlias,
'assigned_to' => null 'assigned_to' => null,
]); ]);
$alloc->save(); $alloc->save();
} }
@ -202,15 +234,15 @@ class NodeRepository {
$alloc = Models\Allocation::firstOrNew([ $alloc = Models\Allocation::firstOrNew([
'node' => $node->id, 'node' => $node->id,
'ip' => $ip, 'ip' => $ip,
'port' => $port 'port' => $port,
]); ]);
if (!$alloc->exists) { if (! $alloc->exists) {
$alloc->fill([ $alloc->fill([
'node' => $node->id, 'node' => $node->id,
'ip' => $ip, 'ip' => $ip,
'port' => $port, 'port' => $port,
'ip_alias' => $setAlias, 'ip_alias' => $setAlias,
'assigned_to' => null 'assigned_to' => null,
]); ]);
$alloc->save(); $alloc->save();
} }
@ -254,5 +286,4 @@ class NodeRepository {
throw $ex; throw $ex;
} }
} }
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,29 +21,25 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Repositories; namespace Pterodactyl\Repositories;
use Crypt;
use DB; use DB;
use Debugbar;
use Validator;
use Log; use Log;
use Crypt;
use Validator;
use Pterodactyl\Models; use Pterodactyl\Models;
use Pterodactyl\Events\ServerDeleted;
use Pterodactyl\Services\UuidService; use Pterodactyl\Services\UuidService;
use Pterodactyl\Services\DeploymentService; use Pterodactyl\Services\DeploymentService;
use Pterodactyl\Notifications\ServerCreated;
use Pterodactyl\Events\ServerDeleted;
use Pterodactyl\Exceptions\DisplayException; use Pterodactyl\Exceptions\DisplayException;
use Pterodactyl\Exceptions\AccountNotFoundException; use Pterodactyl\Notifications\ServerCreated;
use Pterodactyl\Exceptions\DisplayValidationException; use Pterodactyl\Exceptions\DisplayValidationException;
class ServerRepository class ServerRepository
{ {
protected $daemonPermissions = [ protected $daemonPermissions = [
's:*' 's:*',
]; ];
public function __construct() public function __construct()
@ -53,7 +49,7 @@ class ServerRepository
/** /**
* Generates a SFTP username for a server given a server name. * Generates a SFTP username for a server given a server name.
* format: mumble_67c7a4b0 * format: mumble_67c7a4b0.
* *
* @param string $name * @param string $name
* @param string $uuid * @param string $uuid
@ -61,16 +57,15 @@ class ServerRepository
*/ */
protected function generateSFTPUsername($name, $uuid = null) protected function generateSFTPUsername($name, $uuid = null)
{ {
$uuid = is_null($uuid) ? str_random(8) : $uuid; $uuid = is_null($uuid) ? str_random(8) : $uuid;
return strtolower(substr(preg_replace('/\s+/', '', $name), 0, 6) . '_' . $uuid);
return strtolower(substr(preg_replace('/\s+/', '', $name), 0, 6) . '_' . $uuid);
} }
/** /**
* Adds a new server to the system. * Adds a new server to the system.
* @param array $data An array of data descriptors for creating the server. These should align to the columns in the database. * @param array $data An array of data descriptors for creating the server. These should align to the columns in the database.
* @return integer * @return int
*/ */
public function create(array $data) public function create(array $data)
{ {
@ -89,26 +84,26 @@ class ServerRepository
'pack' => 'bail|required|numeric|min:0', 'pack' => 'bail|required|numeric|min:0',
'startup' => 'string', 'startup' => 'string',
'custom_image_name' => 'required_if:use_custom_image,on', 'custom_image_name' => 'required_if:use_custom_image,on',
'auto_deploy' => 'sometimes|boolean' 'auto_deploy' => 'sometimes|boolean',
'custom_id' => 'sometimes|required|numeric|unique:servers,id',
]); ]);
$validator->sometimes('node', 'bail|required|numeric|min:1|exists:nodes,id', function ($input) { $validator->sometimes('node', 'bail|required|numeric|min:1|exists:nodes,id', function ($input) {
return !($input->auto_deploy); return ! ($input->auto_deploy);
}); });
$validator->sometimes('ip', 'required|ip', function ($input) { $validator->sometimes('ip', 'required|ip', function ($input) {
return (!$input->auto_deploy && !$input->allocation); return ! $input->auto_deploy && ! $input->allocation;
}); });
$validator->sometimes('port', 'required|numeric|min:1|max:65535', function ($input) { $validator->sometimes('port', 'required|numeric|min:1|max:65535', function ($input) {
return (!$input->auto_deploy && !$input->allocation); return ! $input->auto_deploy && ! $input->allocation;
}); });
$validator->sometimes('allocation', 'numeric|exists:allocations,id', function ($input) { $validator->sometimes('allocation', 'numeric|exists:allocations,id', function ($input) {
return !($input->auto_deploy || ($input->port && $input->ip)); return ! ($input->auto_deploy || ($input->port && $input->ip));
}); });
// Run validator, throw catchable and displayable exception if it fails. // Run validator, throw catchable and displayable exception if it fails.
// Exception includes a JSON result of failed validation rules. // Exception includes a JSON result of failed validation rules.
if ($validator->fails()) { if ($validator->fails()) {
@ -121,12 +116,12 @@ class ServerRepository
$user = Models\User::select('id', 'email')->where('email', $data['owner'])->first(); $user = Models\User::select('id', 'email')->where('email', $data['owner'])->first();
} }
if (!$user) { if (! $user) {
throw new DisplayException('The user id or email passed to the function was not found on the system.'); throw new DisplayException('The user id or email passed to the function was not found on the system.');
} }
$autoDeployed = false; $autoDeployed = false;
if (isset($data['auto_deploy']) && in_array($data['auto_deploy'], [true, 1, "1"])) { if (isset($data['auto_deploy']) && in_array($data['auto_deploy'], [true, 1, '1'])) {
// This is an auto-deployment situation // This is an auto-deployment situation
// Ignore any other passed node data // Ignore any other passed node data
unset($data['node'], $data['ip'], $data['port'], $data['allocation']); unset($data['node'], $data['ip'], $data['port'], $data['allocation']);
@ -140,16 +135,16 @@ class ServerRepository
// Verify IP & Port are a.) free and b.) assigned to the node. // Verify IP & Port are a.) free and b.) assigned to the node.
// We know the node exists because of 'exists:nodes,id' in the validation // We know the node exists because of 'exists:nodes,id' in the validation
if (!$autoDeployed) { if (! $autoDeployed) {
if (!isset($data['allocation'])) { if (! isset($data['allocation'])) {
$allocation = Models\Allocation::where('ip', $data['ip'])->where('port', $data['port'])->where('node', $data['node'])->whereNull('assigned_to')->first(); $allocation = Models\Allocation::where('ip', $data['ip'])->where('port', $data['port'])->where('node', $data['node'])->whereNull('assigned_to')->first();
} else { } else {
$allocation = Models\Allocation::where('id' , $data['allocation'])->where('node', $data['node'])->whereNull('assigned_to')->first(); $allocation = Models\Allocation::where('id', $data['allocation'])->where('node', $data['node'])->whereNull('assigned_to')->first();
} }
} }
// Something failed in the query, either that combo doesn't exist, or it is in use. // Something failed in the query, either that combo doesn't exist, or it is in use.
if (!$allocation) { if (! $allocation) {
throw new DisplayException('The selected IP/Port combination or Allocation ID is either already in use, or unavaliable for this node.'); throw new DisplayException('The selected IP/Port combination or Allocation ID is either already in use, or unavaliable for this node.');
} }
@ -158,7 +153,7 @@ class ServerRepository
// We need to verify that the option exists for the service, and then check for // We need to verify that the option exists for the service, and then check for
// any required variable fields. (fields are labeled env_<env_variable>) // any required variable fields. (fields are labeled env_<env_variable>)
$option = Models\ServiceOptions::where('id', $data['option'])->where('parent_service', $data['service'])->first(); $option = Models\ServiceOptions::where('id', $data['option'])->where('parent_service', $data['service'])->first();
if (!$option) { if (! $option) {
throw new DisplayException('The requested service option does not exist for the specified service.'); throw new DisplayException('The requested service option does not exist for the specified service.');
} }
@ -181,46 +176,45 @@ class ServerRepository
$variables = Models\ServiceVariables::where('option_id', $data['option'])->get(); $variables = Models\ServiceVariables::where('option_id', $data['option'])->get();
$variableList = []; $variableList = [];
if ($variables) { if ($variables) {
foreach($variables as $variable) { foreach ($variables as $variable) {
// Is the variable required? // Is the variable required?
if (!$data['env_' . $variable->env_variable]) { if (! $data['env_' . $variable->env_variable]) {
if ($variable->required === 1) { if ($variable->required === 1) {
throw new DisplayException('A required service option variable field (env_' . $variable->env_variable . ') was missing from the request.'); throw new DisplayException('A required service option variable field (env_' . $variable->env_variable . ') was missing from the request.');
} }
$variableList = array_merge($variableList, [[ $variableList[] = [
'id' => $variable->id, 'id' => $variable->id,
'env' => $variable->env_variable, 'env' => $variable->env_variable,
'val' => $variable->default_value 'val' => $variable->default_value,
]]); ];
continue; continue;
} }
// Check aganist Regex Pattern // Check aganist Regex Pattern
if (!is_null($variable->regex) && !preg_match($variable->regex, $data['env_' . $variable->env_variable])) { if (! is_null($variable->regex) && ! preg_match($variable->regex, $data['env_' . $variable->env_variable])) {
throw new DisplayException('Failed to validate service option variable field (env_' . $variable->env_variable . ') aganist regex (' . $variable->regex . ').'); throw new DisplayException('Failed to validate service option variable field (env_' . $variable->env_variable . ') aganist regex (' . $variable->regex . ').');
} }
$variableList = array_merge($variableList, [[ $variableList[] = [
'id' => $variable->id, 'id' => $variable->id,
'env' => $variable->env_variable, 'env' => $variable->env_variable,
'val' => $data['env_' . $variable->env_variable] 'val' => $data['env_' . $variable->env_variable],
]]); ];
continue; continue;
} }
} }
// Check Overallocation // Check Overallocation
if (!$autoDeployed) { if (! $autoDeployed) {
if (is_numeric($node->memory_overallocate) || is_numeric($node->disk_overallocate)) { if (is_numeric($node->memory_overallocate) || is_numeric($node->disk_overallocate)) {
$totals = Models\Server::select(DB::raw('SUM(memory) as memory, SUM(disk) as disk'))->where('node', $node->id)->first(); $totals = Models\Server::select(DB::raw('SUM(memory) as memory, SUM(disk) as disk'))->where('node', $node->id)->first();
// Check memory limits // Check memory limits
if (is_numeric($node->memory_overallocate)) { if (is_numeric($node->memory_overallocate)) {
$newMemory = $totals->memory + $data['memory']; $newMemory = $totals->memory + $data['memory'];
$memoryLimit = ($node->memory * (1 + ($node->memory_overallocate / 100))); $memoryLimit = ($node->memory * (1 + ($node->memory_overallocate / 100)));
if($newMemory > $memoryLimit) { if ($newMemory > $memoryLimit) {
throw new DisplayException('The amount of memory allocated to this server would put the node over its allocation limits. This node is allowed ' . ($node->memory_overallocate + 100) . '% of its assigned ' . $node->memory . 'Mb of memory (' . $memoryLimit . 'Mb) of which ' . (($totals->memory / $node->memory) * 100) . '% (' . $totals->memory . 'Mb) is in use already. By allocating this server the node would be at ' . (($newMemory / $node->memory) * 100) . '% (' . $newMemory . 'Mb) usage.'); throw new DisplayException('The amount of memory allocated to this server would put the node over its allocation limits. This node is allowed ' . ($node->memory_overallocate + 100) . '% of its assigned ' . $node->memory . 'Mb of memory (' . $memoryLimit . 'Mb) of which ' . (($totals->memory / $node->memory) * 100) . '% (' . $totals->memory . 'Mb) is in use already. By allocating this server the node would be at ' . (($newMemory / $node->memory) * 100) . '% (' . $newMemory . 'Mb) usage.');
} }
} }
@ -229,7 +223,7 @@ class ServerRepository
if (is_numeric($node->disk_overallocate)) { if (is_numeric($node->disk_overallocate)) {
$newDisk = $totals->disk + $data['disk']; $newDisk = $totals->disk + $data['disk'];
$diskLimit = ($node->disk * (1 + ($node->disk_overallocate / 100))); $diskLimit = ($node->disk * (1 + ($node->disk_overallocate / 100)));
if($newDisk > $diskLimit) { if ($newDisk > $diskLimit) {
throw new DisplayException('The amount of disk allocated to this server would put the node over its allocation limits. This node is allowed ' . ($node->disk_overallocate + 100) . '% of its assigned ' . $node->disk . 'Mb of disk (' . $diskLimit . 'Mb) of which ' . (($totals->disk / $node->disk) * 100) . '% (' . $totals->disk . 'Mb) is in use already. By allocating this server the node would be at ' . (($newDisk / $node->disk) * 100) . '% (' . $newDisk . 'Mb) usage.'); throw new DisplayException('The amount of disk allocated to this server would put the node over its allocation limits. This node is allowed ' . ($node->disk_overallocate + 100) . '% of its assigned ' . $node->disk . 'Mb of disk (' . $diskLimit . 'Mb) of which ' . (($totals->disk / $node->disk) * 100) . '% (' . $totals->disk . 'Mb) is in use already. By allocating this server the node would be at ' . (($newDisk / $node->disk) * 100) . '% (' . $newDisk . 'Mb) usage.');
} }
} }
@ -245,6 +239,11 @@ class ServerRepository
$server = new Models\Server; $server = new Models\Server;
$genUuid = $uuid->generate('servers', 'uuid'); $genUuid = $uuid->generate('servers', 'uuid');
$genShortUuid = $uuid->generateShort('servers', 'uuidShort', $genUuid); $genShortUuid = $uuid->generateShort('servers', 'uuidShort', $genUuid);
if (isset($data['custom_id'])) {
$server->id = $data['custom_id'];
}
$server->fill([ $server->fill([
'uuid' => $genUuid, 'uuid' => $genUuid,
'uuidShort' => $genShortUuid, 'uuidShort' => $genShortUuid,
@ -266,7 +265,7 @@ class ServerRepository
'daemonSecret' => $uuid->generate('servers', 'daemonSecret'), 'daemonSecret' => $uuid->generate('servers', 'daemonSecret'),
'image' => (isset($data['custom_image_name'])) ? $data['custom_image_name'] : $option->docker_image, 'image' => (isset($data['custom_image_name'])) ? $data['custom_image_name'] : $option->docker_image,
'username' => $this->generateSFTPUsername($data['name'], $genShortUuid), 'username' => $this->generateSFTPUsername($data['name'], $genShortUuid),
'sftp_password' => Crypt::encrypt('not set') 'sftp_password' => Crypt::encrypt('not set'),
]); ]);
$server->save(); $server->save();
@ -275,18 +274,17 @@ class ServerRepository
$allocation->save(); $allocation->save();
// Add Variables // Add Variables
$environmentVariables = []; $environmentVariables = [
$environmentVariables = array_merge($environmentVariables, [ 'STARTUP' => $data['startup'],
'STARTUP' => $data['startup'] ];
]);
foreach($variableList as $item) { foreach ($variableList as $item) {
$environmentVariables = array_merge($environmentVariables, [ $environmentVariables[$item['env']] = $item['val'];
$item['env'] => $item['val']
]);
Models\ServerVariables::create([ Models\ServerVariables::create([
'server_id' => $server->id, 'server_id' => $server->id,
'variable_id' => $item['id'], 'variable_id' => $item['id'],
'variable_value' => $item['val'] 'variable_value' => $item['val'],
]); ]);
} }
@ -297,13 +295,13 @@ class ServerRepository
'node' => $node->name, 'node' => $node->name,
'service' => $service->name, 'service' => $service->name,
'option' => $option->name, 'option' => $option->name,
'uuidShort' => $server->uuidShort 'uuidShort' => $server->uuidShort,
]))); ])));
$client = Models\Node::guzzleRequest($node->id); $client = Models\Node::guzzleRequest($node->id);
$client->request('POST', '/servers', [ $client->request('POST', '/servers', [
'headers' => [ 'headers' => [
'X-Access-Token' => $node->daemonSecret 'X-Access-Token' => $node->daemonSecret,
], ],
'json' => [ 'json' => [
'uuid' => (string) $server->uuid, 'uuid' => (string) $server->uuid,
@ -314,7 +312,7 @@ class ServerRepository
'port' => (int) $allocation->port, 'port' => (int) $allocation->port,
], ],
'ports' => [ 'ports' => [
(string) $allocation->ip => [ (int) $allocation->port ], (string) $allocation->ip => [(int) $allocation->port],
], ],
'env' => $environmentVariables, 'env' => $environmentVariables,
'memory' => (int) $server->memory, 'memory' => (int) $server->memory,
@ -333,10 +331,11 @@ class ServerRepository
(string) $server->daemonSecret => $this->daemonPermissions, (string) $server->daemonSecret => $this->daemonPermissions,
], ],
'rebuild' => false, 'rebuild' => false,
] ],
]); ]);
DB::commit(); DB::commit();
return $server->id; return $server->id;
} catch (\GuzzleHttp\Exception\TransferException $ex) { } catch (\GuzzleHttp\Exception\TransferException $ex) {
DB::rollBack(); DB::rollBack();
@ -345,25 +344,23 @@ class ServerRepository
DB::rollBack(); DB::rollBack();
throw $ex; throw $ex;
} }
} }
/** /**
* [updateDetails description] * [updateDetails description].
* @param integer $id * @param int $id
* @param array $data * @param array $data
* @return boolean * @return bool
*/ */
public function updateDetails($id, array $data) public function updateDetails($id, array $data)
{ {
$uuid = new UuidService; $uuid = new UuidService;
$resetDaemonKey = false; $resetDaemonKey = false;
// Validate Fields // Validate Fields
$validator = Validator::make($data, [ $validator = Validator::make($data, [
'owner' => 'email|exists:users,email', 'owner' => 'email|exists:users,email',
'name' => 'regex:([\w -]{4,35})' 'name' => 'regex:([\w -]{4,35})',
]); ]);
// Run validator, throw catchable and displayable exception if it fails. // Run validator, throw catchable and displayable exception if it fails.
@ -400,8 +397,9 @@ class ServerRepository
$server->save(); $server->save();
// Do we need to update? If not, return successful. // Do we need to update? If not, return successful.
if (!$resetDaemonKey) { if (! $resetDaemonKey) {
DB::commit(); DB::commit();
return true; return true;
} }
@ -412,19 +410,20 @@ class ServerRepository
$res = $client->request('PATCH', '/server', [ $res = $client->request('PATCH', '/server', [
'headers' => [ 'headers' => [
'X-Access-Server' => $server->uuid, 'X-Access-Server' => $server->uuid,
'X-Access-Token' => $node->daemonSecret 'X-Access-Token' => $node->daemonSecret,
], ],
'exceptions' => false, 'exceptions' => false,
'json' => [ 'json' => [
'keys' => [ 'keys' => [
(string) $oldDaemonKey => [], (string) $oldDaemonKey => [],
(string) $server->daemonSecret => $this->daemonPermissions (string) $server->daemonSecret => $this->daemonPermissions,
] ],
] ],
]); ]);
if ($res->getStatusCode() === 204) { if ($res->getStatusCode() === 204) {
DB::commit(); DB::commit();
return true; return true;
} else { } else {
throw new DisplayException('Daemon returned a a non HTTP/204 error code. HTTP/' + $res->getStatusCode()); throw new DisplayException('Daemon returned a a non HTTP/204 error code. HTTP/' + $res->getStatusCode());
@ -434,11 +433,10 @@ class ServerRepository
Log::error($ex); Log::error($ex);
throw new DisplayException('An error occured while attempting to update this server\'s information.'); throw new DisplayException('An error occured while attempting to update this server\'s information.');
} }
} }
/** /**
* [updateContainer description] * [updateContainer description].
* @param int $id * @param int $id
* @param array $data * @param array $data
* @return bool * @return bool
@ -446,7 +444,7 @@ class ServerRepository
public function updateContainer($id, array $data) public function updateContainer($id, array $data)
{ {
$validator = Validator::make($data, [ $validator = Validator::make($data, [
'image' => 'required|string' 'image' => 'required|string',
]); ]);
// Run validator, throw catchable and displayable exception if it fails. // Run validator, throw catchable and displayable exception if it fails.
@ -468,16 +466,17 @@ class ServerRepository
$client->request('PATCH', '/server', [ $client->request('PATCH', '/server', [
'headers' => [ 'headers' => [
'X-Access-Server' => $server->uuid, 'X-Access-Server' => $server->uuid,
'X-Access-Token' => $node->daemonSecret 'X-Access-Token' => $node->daemonSecret,
], ],
'json' => [ 'json' => [
'build' => [ 'build' => [
'image' => $server->image 'image' => $server->image,
] ],
] ],
]); ]);
DB::commit(); DB::commit();
return true; return true;
} catch (\GuzzleHttp\Exception\TransferException $ex) { } catch (\GuzzleHttp\Exception\TransferException $ex) {
DB::rollBack(); DB::rollBack();
@ -486,22 +485,20 @@ class ServerRepository
DB::rollBack(); DB::rollBack();
throw $ex; throw $ex;
} }
} }
/** /**
* [changeBuild description] * [changeBuild description].
* @param integer $id * @param int $id
* @param array $data * @param array $data
* @return boolean * @return bool
*/ */
public function changeBuild($id, array $data) public function changeBuild($id, array $data)
{ {
$validator = Validator::make($data, [ $validator = Validator::make($data, [
'default' => [ 'default' => [
'string', 'string',
'regex:/^(\d|[1-9]\d|1\d\d|2([0-4]\d|5[0-5]))\.(\d|[1-9]\d|1\d\d|2([0-4]\d|5[0-5]))\.(\d|[1-9]\d|1\d\d|2([0-4]\d|5[0-5]))\.(\d|[1-9]\d|1\d\d|2([0-4]\d|5[0-5])):(\d{1,5})$/' 'regex:/^(\d|[1-9]\d|1\d\d|2([0-4]\d|5[0-5]))\.(\d|[1-9]\d|1\d\d|2([0-4]\d|5[0-5]))\.(\d|[1-9]\d|1\d\d|2([0-4]\d|5[0-5]))\.(\d|[1-9]\d|1\d\d|2([0-4]\d|5[0-5])):(\d{1,5})$/',
], ],
'add_additional' => 'nullable|array', 'add_additional' => 'nullable|array',
'remove_additional' => 'nullable|array', 'remove_additional' => 'nullable|array',
@ -509,7 +506,7 @@ class ServerRepository
'swap' => 'integer|min:-1', 'swap' => 'integer|min:-1',
'io' => 'integer|min:10|max:1000', 'io' => 'integer|min:10|max:1000',
'cpu' => 'integer|min:0', 'cpu' => 'integer|min:0',
'disk' => 'integer|min:0' 'disk' => 'integer|min:0',
]); ]);
// Run validator, throw catchable and displayable exception if it fails. // Run validator, throw catchable and displayable exception if it fails.
@ -530,14 +527,14 @@ class ServerRepository
list($ip, $port) = explode(':', $data['default']); list($ip, $port) = explode(':', $data['default']);
if ($ip !== $allocation->ip || (int) $port !== $allocation->port) { if ($ip !== $allocation->ip || (int) $port !== $allocation->port) {
$selection = Models\Allocation::where('ip', $ip)->where('port', $port)->where('assigned_to', $server->id)->first(); $selection = Models\Allocation::where('ip', $ip)->where('port', $port)->where('assigned_to', $server->id)->first();
if (!$selection) { if (! $selection) {
throw new DisplayException('The requested default connection (' . $ip . ':' . $port . ') is not allocated to this server.'); throw new DisplayException('The requested default connection (' . $ip . ':' . $port . ') is not allocated to this server.');
} }
$server->allocation = $selection->id; $server->allocation = $selection->id;
$newBuild['default'] = [ $newBuild['default'] = [
'ip' => $ip, 'ip' => $ip,
'port' => (int) $port 'port' => (int) $port,
]; ];
// Re-Run to keep updated for rest of function // Re-Run to keep updated for rest of function
@ -551,7 +548,7 @@ class ServerRepository
foreach ($data['remove_additional'] as $id => $combo) { foreach ($data['remove_additional'] as $id => $combo) {
list($ip, $port) = explode(':', $combo); list($ip, $port) = explode(':', $combo);
// Invalid, not worth killing the whole thing, we'll just skip over it. // Invalid, not worth killing the whole thing, we'll just skip over it.
if (!filter_var($ip, FILTER_VALIDATE_IP) || !preg_match('/^(\d{1,5})$/', $port)) { if (! filter_var($ip, FILTER_VALIDATE_IP) || ! preg_match('/^(\d{1,5})$/', $port)) {
break; break;
} }
@ -562,7 +559,7 @@ class ServerRepository
$newPorts = true; $newPorts = true;
Models\Allocation::where('ip', $ip)->where('port', $port)->where('assigned_to', $server->id)->update([ Models\Allocation::where('ip', $ip)->where('port', $port)->where('assigned_to', $server->id)->update([
'assigned_to' => null 'assigned_to' => null,
]); ]);
} }
} }
@ -572,7 +569,7 @@ class ServerRepository
foreach ($data['add_additional'] as $id => $combo) { foreach ($data['add_additional'] as $id => $combo) {
list($ip, $port) = explode(':', $combo); list($ip, $port) = explode(':', $combo);
// Invalid, not worth killing the whole thing, we'll just skip over it. // Invalid, not worth killing the whole thing, we'll just skip over it.
if (!filter_var($ip, FILTER_VALIDATE_IP) || !preg_match('/^(\d{1,5})$/', $port)) { if (! filter_var($ip, FILTER_VALIDATE_IP) || ! preg_match('/^(\d{1,5})$/', $port)) {
break; break;
} }
@ -583,7 +580,7 @@ class ServerRepository
$newPorts = true; $newPorts = true;
Models\Allocation::where('ip', $ip)->where('port', $port)->whereNull('assigned_to')->update([ Models\Allocation::where('ip', $ip)->where('port', $port)->whereNull('assigned_to')->update([
'assigned_to' => $server->id 'assigned_to' => $server->id,
]); ]);
} }
} }
@ -593,9 +590,9 @@ class ServerRepository
$assignments = Models\Allocation::where('assigned_to', $server->id)->get(); $assignments = Models\Allocation::where('assigned_to', $server->id)->get();
foreach ($assignments as &$assignment) { foreach ($assignments as &$assignment) {
if (array_key_exists((string) $assignment->ip, $additionalAssignments)) { if (array_key_exists((string) $assignment->ip, $additionalAssignments)) {
array_push($additionalAssignments[ (string) $assignment->ip ], (int) $assignment->port); array_push($additionalAssignments[(string) $assignment->ip], (int) $assignment->port);
} else { } else {
$additionalAssignments[ (string) $assignment->ip ] = [ (int) $assignment->port ]; $additionalAssignments[(string) $assignment->ip] = [(int) $assignment->port];
} }
} }
@ -636,22 +633,23 @@ class ServerRepository
// This won't be committed unless the HTTP request succeedes anyways // This won't be committed unless the HTTP request succeedes anyways
$server->save(); $server->save();
if (!empty($newBuild)) { if (! empty($newBuild)) {
$node = Models\Node::getByID($server->node); $node = Models\Node::getByID($server->node);
$client = Models\Node::guzzleRequest($server->node); $client = Models\Node::guzzleRequest($server->node);
$client->request('PATCH', '/server', [ $client->request('PATCH', '/server', [
'headers' => [ 'headers' => [
'X-Access-Server' => $server->uuid, 'X-Access-Server' => $server->uuid,
'X-Access-Token' => $node->daemonSecret 'X-Access-Token' => $node->daemonSecret,
], ],
'json' => [ 'json' => [
'build' => $newBuild 'build' => $newBuild,
] ],
]); ]);
} }
DB::commit(); DB::commit();
return true; return true;
} catch (\GuzzleHttp\Exception\TransferException $ex) { } catch (\GuzzleHttp\Exception\TransferException $ex) {
DB::rollBack(); DB::rollBack();
@ -660,12 +658,10 @@ class ServerRepository
DB::rollBack(); DB::rollBack();
throw $ex; throw $ex;
} }
} }
public function updateStartup($id, array $data, $admin = false) public function updateStartup($id, array $data, $admin = false)
{ {
$server = Models\Server::findOrFail($id); $server = Models\Server::findOrFail($id);
DB::beginTransaction(); DB::beginTransaction();
@ -687,24 +683,24 @@ class ServerRepository
$variableList = []; $variableList = [];
if ($variables) { if ($variables) {
foreach($variables as &$variable) { foreach ($variables as &$variable) {
// Move on if the new data wasn't even sent // Move on if the new data wasn't even sent
if (!isset($data[$variable->env_variable])) { if (! isset($data[$variable->env_variable])) {
$variableList = array_merge($variableList, [[ $variableList[] = [
'id' => $variable->id, 'id' => $variable->id,
'env' => $variable->env_variable, 'env' => $variable->env_variable,
'val' => $variable->a_currentValue 'val' => $variable->a_currentValue,
]]); ];
continue; continue;
} }
// Update Empty but skip validation // Update Empty but skip validation
if (empty($data[$variable->env_variable])) { if (empty($data[$variable->env_variable])) {
$variableList = array_merge($variableList, [[ $variableList[] = [
'id' => $variable->id, 'id' => $variable->id,
'env' => $variable->env_variable, 'env' => $variable->env_variable,
'val' => null 'val' => null,
]]); ];
continue; continue;
} }
@ -717,37 +713,34 @@ class ServerRepository
} }
// Variable hidden and/or not user editable // Variable hidden and/or not user editable
if (($variable->user_viewable === 0 || $variable->user_editable === 0) && !$admin) { if (($variable->user_viewable === 0 || $variable->user_editable === 0) && ! $admin) {
throw new DisplayException('A service option variable field (' . $variable->env_variable . ') does not exist or you do not have permission to edit it.'); throw new DisplayException('A service option variable field (' . $variable->env_variable . ') does not exist or you do not have permission to edit it.');
} }
// Check aganist Regex Pattern // Check aganist Regex Pattern
if (!is_null($variable->regex) && !preg_match($variable->regex, $data[$variable->env_variable])) { if (! is_null($variable->regex) && ! preg_match($variable->regex, $data[$variable->env_variable])) {
throw new DisplayException('Failed to validate service option variable field (' . $variable->env_variable . ') aganist regex (' . $variable->regex . ').'); throw new DisplayException('Failed to validate service option variable field (' . $variable->env_variable . ') aganist regex (' . $variable->regex . ').');
} }
$variableList = array_merge($variableList, [[ $variableList[] = [
'id' => $variable->id, 'id' => $variable->id,
'env' => $variable->env_variable, 'env' => $variable->env_variable,
'val' => $data[$variable->env_variable] 'val' => $data[$variable->env_variable],
]]); ];
} }
} }
// Add Variables // Add Variables
$environmentVariables = []; $environmentVariables = [
$environmentVariables = array_merge($environmentVariables, [ 'STARTUP' => $server->startup,
'STARTUP' => $server->startup ];
]); foreach ($variableList as $item) {
foreach($variableList as $item) { $environmentVariables[$item['env']] = $item['val'];
$environmentVariables = array_merge($environmentVariables, [
$item['env'] => $item['val']
]);
// Update model or make a new record if it doesn't exist. // Update model or make a new record if it doesn't exist.
$model = Models\ServerVariables::firstOrNew([ $model = Models\ServerVariables::firstOrNew([
'variable_id' => $item['id'], 'variable_id' => $item['id'],
'server_id' => $server->id 'server_id' => $server->id,
]); ]);
$model->variable_value = $item['val']; $model->variable_value = $item['val'];
$model->save(); $model->save();
@ -759,16 +752,17 @@ class ServerRepository
$client->request('PATCH', '/server', [ $client->request('PATCH', '/server', [
'headers' => [ 'headers' => [
'X-Access-Server' => $server->uuid, 'X-Access-Server' => $server->uuid,
'X-Access-Token' => $node->daemonSecret 'X-Access-Token' => $node->daemonSecret,
], ],
'json' => [ 'json' => [
'build' => [ 'build' => [
'env|overwrite' => $environmentVariables 'env|overwrite' => $environmentVariables,
] ],
] ],
]); ]);
DB::commit(); DB::commit();
return true; return true;
} catch (\GuzzleHttp\Exception\TransferException $ex) { } catch (\GuzzleHttp\Exception\TransferException $ex) {
DB::rollBack(); DB::rollBack();
@ -777,7 +771,6 @@ class ServerRepository
DB::rollBack(); DB::rollBack();
throw $ex; throw $ex;
} }
} }
public function deleteServer($id, $force) public function deleteServer($id, $force)
@ -801,13 +794,14 @@ class ServerRepository
} }
} }
public function deleteNow($id, $force = false) { public function deleteNow($id, $force = false)
{
$server = Models\Server::withTrashed()->findOrFail($id); $server = Models\Server::withTrashed()->findOrFail($id);
$node = Models\Node::findOrFail($server->node); $node = Models\Node::findOrFail($server->node);
// Handle server being restored previously or // Handle server being restored previously or
// an accidental queue. // an accidental queue.
if (!$server->trashed()) { if (! $server->trashed()) {
return; return;
} }
@ -815,7 +809,7 @@ class ServerRepository
try { try {
// Unassign Allocations // Unassign Allocations
Models\Allocation::where('assigned_to', $server->id)->update([ Models\Allocation::where('assigned_to', $server->id)->update([
'assigned_to' => null 'assigned_to' => null,
]); ]);
// Remove Variables // Remove Variables
@ -837,7 +831,7 @@ class ServerRepository
// This is the one un-recoverable point where // This is the one un-recoverable point where
// transactions will not save us. // transactions will not save us.
$repository = new DatabaseRepository; $repository = new DatabaseRepository;
foreach(Models\Database::select('id')->where('server_id', $server->id)->get() as &$database) { foreach (Models\Database::select('id')->where('server_id', $server->id)->get() as &$database) {
$repository->drop($database->id); $repository->drop($database->id);
} }
@ -845,8 +839,8 @@ class ServerRepository
$client->request('DELETE', '/servers', [ $client->request('DELETE', '/servers', [
'headers' => [ 'headers' => [
'X-Access-Token' => $node->daemonSecret, 'X-Access-Token' => $node->daemonSecret,
'X-Access-Server' => $server->uuid 'X-Access-Server' => $server->uuid,
] ],
]); ]);
$server->forceDelete(); $server->forceDelete();
@ -882,13 +876,14 @@ class ServerRepository
throw new DisplayException('This server was marked as having a failed install, you cannot override this.'); throw new DisplayException('This server was marked as having a failed install, you cannot override this.');
} }
$server->installed = ($server->installed === 1) ? 0 : 1; $server->installed = ($server->installed === 1) ? 0 : 1;
return $server->save(); return $server->save();
} }
/** /**
* Suspends a server instance making it unable to be booted or used by a user. * Suspends a server instance making it unable to be booted or used by a user.
* @param integer $id * @param int $id
* @return boolean * @return bool
*/ */
public function suspend($id, $deleted = false) public function suspend($id, $deleted = false)
{ {
@ -911,8 +906,8 @@ class ServerRepository
$client->request('POST', '/server/suspend', [ $client->request('POST', '/server/suspend', [
'headers' => [ 'headers' => [
'X-Access-Token' => $node->daemonSecret, 'X-Access-Token' => $node->daemonSecret,
'X-Access-Server' => $server->uuid 'X-Access-Server' => $server->uuid,
] ],
]); ]);
return DB::commit(); return DB::commit();
@ -927,8 +922,8 @@ class ServerRepository
/** /**
* Unsuspends a server instance. * Unsuspends a server instance.
* @param integer $id * @param int $id
* @return boolean * @return bool
*/ */
public function unsuspend($id) public function unsuspend($id)
{ {
@ -951,8 +946,8 @@ class ServerRepository
$client->request('POST', '/server/unsuspend', [ $client->request('POST', '/server/unsuspend', [
'headers' => [ 'headers' => [
'X-Access-Token' => $node->daemonSecret, 'X-Access-Token' => $node->daemonSecret,
'X-Access-Server' => $server->uuid 'X-Access-Server' => $server->uuid,
] ],
]); ]);
return DB::commit(); return DB::commit();
@ -973,7 +968,7 @@ class ServerRepository
$validator = Validator::make([ $validator = Validator::make([
'password' => $password, 'password' => $password,
], [ ], [
'password' => 'required|regex:/^((?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,})$/' 'password' => 'required|regex:/^((?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,})$/',
]); ]);
if ($validator->fails()) { if ($validator->fails()) {
@ -990,7 +985,7 @@ class ServerRepository
$client->request('POST', '/server/password', [ $client->request('POST', '/server/password', [
'headers' => [ 'headers' => [
'X-Access-Token' => $node->daemonSecret, 'X-Access-Token' => $node->daemonSecret,
'X-Access-Server' => $server->uuid 'X-Access-Server' => $server->uuid,
], ],
'json' => [ 'json' => [
'password' => $password, 'password' => $password,
@ -998,6 +993,7 @@ class ServerRepository
]); ]);
DB::commit(); DB::commit();
return true; return true;
} catch (\GuzzleHttp\Exception\TransferException $ex) { } catch (\GuzzleHttp\Exception\TransferException $ex) {
DB::rollBack(); DB::rollBack();
@ -1006,7 +1002,5 @@ class ServerRepository
DB::rollBack(); DB::rollBack();
throw $ex; throw $ex;
} }
} }
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,20 +21,17 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Repositories\ServiceRepository; namespace Pterodactyl\Repositories\ServiceRepository;
use DB; use DB;
use Validator; use Validator;
use Pterodactyl\Models; use Pterodactyl\Models;
use Pterodactyl\Services\UuidService;
use Pterodactyl\Exceptions\DisplayException; use Pterodactyl\Exceptions\DisplayException;
use Pterodactyl\Exceptions\DisplayValidationException; use Pterodactyl\Exceptions\DisplayValidationException;
class Option class Option
{ {
public function __construct() public function __construct()
{ {
// //
@ -50,7 +47,7 @@ class Option
'tag' => 'required|string|max:255', 'tag' => 'required|string|max:255',
'executable' => 'sometimes|string|max:255', 'executable' => 'sometimes|string|max:255',
'docker_image' => 'required|string|max:255', 'docker_image' => 'required|string|max:255',
'startup' => 'sometimes|string' 'startup' => 'sometimes|string',
]); ]);
if ($validator->fails()) { if ($validator->fails()) {
@ -105,7 +102,7 @@ class Option
'tag' => 'sometimes|required|string|max:255', 'tag' => 'sometimes|required|string|max:255',
'executable' => 'sometimes|string|max:255', 'executable' => 'sometimes|string|max:255',
'docker_image' => 'sometimes|required|string|max:255', 'docker_image' => 'sometimes|required|string|max:255',
'startup' => 'sometimes|string' 'startup' => 'sometimes|string',
]); ]);
if ($validator->fails()) { if ($validator->fails()) {
@ -121,7 +118,7 @@ class Option
} }
$option->fill($data); $option->fill($data);
$option->save();
}
return $option->save();
}
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,22 +21,19 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Repositories\ServiceRepository; namespace Pterodactyl\Repositories\ServiceRepository;
use DB; use DB;
use Validator;
use Uuid; use Uuid;
use Storage; use Storage;
use Validator;
use Pterodactyl\Models; use Pterodactyl\Models;
use Pterodactyl\Services\UuidService;
use Pterodactyl\Exceptions\DisplayException; use Pterodactyl\Exceptions\DisplayException;
use Pterodactyl\Exceptions\DisplayValidationException; use Pterodactyl\Exceptions\DisplayValidationException;
class Service class Service
{ {
public function __construct() public function __construct()
{ {
// //
@ -49,7 +46,7 @@ class Service
'description' => 'required|string', 'description' => 'required|string',
'file' => 'required|unique:services,file|regex:/^[\w.-]{1,50}$/', 'file' => 'required|unique:services,file|regex:/^[\w.-]{1,50}$/',
'executable' => 'max:255|regex:/^(.*)$/', 'executable' => 'max:255|regex:/^(.*)$/',
'startup' => 'string' 'startup' => 'string',
]); ]);
if ($validator->fails()) { if ($validator->fails()) {
@ -86,7 +83,7 @@ class Service
'description' => 'sometimes|required|string', 'description' => 'sometimes|required|string',
'file' => 'sometimes|required|regex:/^[\w.-]{1,50}$/', 'file' => 'sometimes|required|regex:/^[\w.-]{1,50}$/',
'executable' => 'sometimes|max:255|regex:/^(.*)$/', 'executable' => 'sometimes|max:255|regex:/^(.*)$/',
'startup' => 'sometimes|string' 'startup' => 'sometimes|string',
]); ]);
if ($validator->fails()) { if ($validator->fails()) {
@ -94,7 +91,8 @@ class Service
} }
$service->fill($data); $service->fill($data);
$service->save();
return $service->save();
} }
public function delete($id) public function delete($id)
@ -147,5 +145,4 @@ class Service
} }
} }
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,20 +21,17 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Repositories\ServiceRepository; namespace Pterodactyl\Repositories\ServiceRepository;
use DB; use DB;
use Validator; use Validator;
use Pterodactyl\Models; use Pterodactyl\Models;
use Pterodactyl\Services\UuidService;
use Pterodactyl\Exceptions\DisplayException; use Pterodactyl\Exceptions\DisplayException;
use Pterodactyl\Exceptions\DisplayValidationException; use Pterodactyl\Exceptions\DisplayValidationException;
class Variable class Variable
{ {
public function __construct() public function __construct()
{ {
// //
@ -52,14 +49,14 @@ class Variable
'user_viewable' => 'sometimes|required|numeric|size:1', 'user_viewable' => 'sometimes|required|numeric|size:1',
'user_editable' => 'sometimes|required|numeric|size:1', 'user_editable' => 'sometimes|required|numeric|size:1',
'required' => 'sometimes|required|numeric|size:1', 'required' => 'sometimes|required|numeric|size:1',
'regex' => 'required|string|min:1' 'regex' => 'required|string|min:1',
]); ]);
if ($validator->fails()) { if ($validator->fails()) {
throw new DisplayValidationException($validator->errors()); throw new DisplayValidationException($validator->errors());
} }
if ($data['default_value'] !== '' && !preg_match($data['regex'], $data['default_value'])) { if ($data['default_value'] !== '' && ! preg_match($data['regex'], $data['default_value'])) {
throw new DisplayException('The default value you entered cannot violate the regex requirements.'); throw new DisplayException('The default value you entered cannot violate the regex requirements.');
} }
@ -74,10 +71,12 @@ class Variable
$variable = new Models\ServiceVariables; $variable = new Models\ServiceVariables;
$variable->option_id = $option->id; $variable->option_id = $option->id;
$variable->fill($data); $variable->fill($data);
$variable->save();
return $variable->save();
} }
public function delete($id) { public function delete($id)
{
$variable = Models\ServiceVariables::findOrFail($id); $variable = Models\ServiceVariables::findOrFail($id);
DB::beginTransaction(); DB::beginTransaction();
@ -104,7 +103,7 @@ class Variable
'user_viewable' => 'sometimes|required|numeric|boolean', 'user_viewable' => 'sometimes|required|numeric|boolean',
'user_editable' => 'sometimes|required|numeric|boolean', 'user_editable' => 'sometimes|required|numeric|boolean',
'required' => 'sometimes|required|numeric|boolean', 'required' => 'sometimes|required|numeric|boolean',
'regex' => 'sometimes|required|string|min:1' 'regex' => 'sometimes|required|string|min:1',
]); ]);
if ($validator->fails()) { if ($validator->fails()) {
@ -114,7 +113,7 @@ class Variable
$data['default_value'] = (isset($data['default_value'])) ? $data['default_value'] : $variable->default_value; $data['default_value'] = (isset($data['default_value'])) ? $data['default_value'] : $variable->default_value;
$data['regex'] = (isset($data['regex'])) ? $data['regex'] : $variable->regex; $data['regex'] = (isset($data['regex'])) ? $data['regex'] : $variable->regex;
if ($data['default_value'] !== '' && !preg_match($data['regex'], $data['default_value'])) { if ($data['default_value'] !== '' && ! preg_match($data['regex'], $data['default_value'])) {
throw new DisplayException('The default value you entered cannot violate the regex requirements.'); throw new DisplayException('The default value you entered cannot violate the regex requirements.');
} }
@ -127,7 +126,7 @@ class Variable
$data['required'] = (isset($data['required']) && in_array((int) $data['required'], [0, 1])) ? $data['required'] : $variable->required; $data['required'] = (isset($data['required']) && in_array((int) $data['required'], [0, 1])) ? $data['required'] : $variable->required;
$variable->fill($data); $variable->fill($data);
$variable->save();
}
return $variable->save();
}
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,23 +21,20 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Repositories; namespace Pterodactyl\Repositories;
use DB; use DB;
use Mail;
use Settings; use Settings;
use Validator; use Validator;
use Mail;
use Pterodactyl\Models; use Pterodactyl\Models;
use Pterodactyl\Repositories\UserRepository;
use Pterodactyl\Services\UuidService; use Pterodactyl\Services\UuidService;
use Pterodactyl\Exceptions\DisplayValidationException;
use Pterodactyl\Exceptions\DisplayException; use Pterodactyl\Exceptions\DisplayException;
use Pterodactyl\Exceptions\DisplayValidationException;
class SubuserRepository class SubuserRepository
{ {
/** /**
* Core permissions required for every subuser on the daemon. * Core permissions required for every subuser on the daemon.
* Without this we cannot connect the websocket or get basic * Without this we cannot connect the websocket or get basic
@ -46,7 +43,7 @@ class SubuserRepository
*/ */
protected $coreDaemonPermissions = [ protected $coreDaemonPermissions = [
's:get', 's:get',
's:console' 's:console',
]; ];
/** /**
@ -101,7 +98,7 @@ class SubuserRepository
// Databases // Databases
'view-databases' => null, 'view-databases' => null,
'reset-db-password' => null 'reset-db-password' => null,
]; ];
public function __construct() public function __construct()
@ -111,18 +108,18 @@ class SubuserRepository
/** /**
* Creates a new subuser on the server. * Creates a new subuser on the server.
* @param integer $id The ID of the server to add this subuser to. * @param int $id The ID of the server to add this subuser to.
* @param array $data * @param array $data
* @throws DisplayValidationException * @throws DisplayValidationException
* @throws DisplayException * @throws DisplayException
* @return integer Returns the ID of the newly created subuser. * @return int Returns the ID of the newly created subuser.
*/ */
public function create($sid, array $data) public function create($sid, array $data)
{ {
$server = Models\Server::findOrFail($sid); $server = Models\Server::findOrFail($sid);
$validator = Validator::make($data, [ $validator = Validator::make($data, [
'permissions' => 'required|array', 'permissions' => 'required|array',
'email' => 'required|email' 'email' => 'required|email',
]); ]);
if ($validator->fails()) { if ($validator->fails()) {
@ -134,7 +131,7 @@ class SubuserRepository
try { try {
// Determine if this user exists or if we need to make them an account. // Determine if this user exists or if we need to make them an account.
$user = Models\User::where('email', $data['email'])->first(); $user = Models\User::where('email', $data['email'])->first();
if (!$user) { if (! $user) {
$password = str_random(16); $password = str_random(16);
try { try {
$repo = new UserRepository; $repo = new UserRepository;
@ -151,22 +148,22 @@ class SubuserRepository
$subuser->fill([ $subuser->fill([
'user_id' => $user->id, 'user_id' => $user->id,
'server_id' => $server->id, 'server_id' => $server->id,
'daemonSecret' => (string) $uuid->generate('servers', 'uuid') 'daemonSecret' => (string) $uuid->generate('servers', 'uuid'),
]); ]);
$subuser->save(); $subuser->save();
$daemonPermissions = $this->coreDaemonPermissions; $daemonPermissions = $this->coreDaemonPermissions;
foreach($data['permissions'] as $permission) { foreach ($data['permissions'] as $permission) {
if (array_key_exists($permission, $this->permissions)) { if (array_key_exists($permission, $this->permissions)) {
// Build the daemon permissions array for sending. // Build the daemon permissions array for sending.
if (!is_null($this->permissions[$permission])) { if (! is_null($this->permissions[$permission])) {
array_push($daemonPermissions, $this->permissions[$permission]); array_push($daemonPermissions, $this->permissions[$permission]);
} }
$model = new Models\Permission; $model = new Models\Permission;
$model->fill([ $model->fill([
'user_id' => $user->id, 'user_id' => $user->id,
'server_id' => $server->id, 'server_id' => $server->id,
'permission' => $permission 'permission' => $permission,
]); ]);
$model->save(); $model->save();
} }
@ -182,13 +179,13 @@ class SubuserRepository
$res = $client->request('PATCH', '/server', [ $res = $client->request('PATCH', '/server', [
'headers' => [ 'headers' => [
'X-Access-Server' => $server->uuid, 'X-Access-Server' => $server->uuid,
'X-Access-Token' => $node->daemonSecret 'X-Access-Token' => $node->daemonSecret,
], ],
'json' => [ 'json' => [
'keys' => [ 'keys' => [
$subuser->daemonSecret => $daemonPermissions $subuser->daemonSecret => $daemonPermissions,
] ],
] ],
]); ]);
$email = $data['email']; $email = $data['email'];
@ -201,6 +198,7 @@ class SubuserRepository
$message->subject(Settings::get('company') . ' - Added to Server'); $message->subject(Settings::get('company') . ' - Added to Server');
}); });
DB::commit(); DB::commit();
return $subuser->id; return $subuser->id;
} catch (\GuzzleHttp\Exception\TransferException $ex) { } catch (\GuzzleHttp\Exception\TransferException $ex) {
DB::rollBack(); DB::rollBack();
@ -209,12 +207,13 @@ class SubuserRepository
DB::rollBack(); DB::rollBack();
throw $ex; throw $ex;
} }
return false; return false;
} }
/** /**
* Revokes a users permissions on a server. * Revokes a users permissions on a server.
* @param integer $id The ID of the subuser row in MySQL. * @param int $id The ID of the subuser row in MySQL.
* @param array $data * @param array $data
* @throws DisplayValidationException * @throws DisplayValidationException
* @throws DisplayException * @throws DisplayException
@ -236,17 +235,18 @@ class SubuserRepository
$res = $client->request('PATCH', '/server', [ $res = $client->request('PATCH', '/server', [
'headers' => [ 'headers' => [
'X-Access-Server' => $server->uuid, 'X-Access-Server' => $server->uuid,
'X-Access-Token' => $node->daemonSecret 'X-Access-Token' => $node->daemonSecret,
], ],
'json' => [ 'json' => [
'keys' => [ 'keys' => [
$subuser->daemonSecret => [] $subuser->daemonSecret => [],
] ],
] ],
]); ]);
$subuser->delete(); $subuser->delete();
DB::commit(); DB::commit();
return true; return true;
} catch (\GuzzleHttp\Exception\TransferException $ex) { } catch (\GuzzleHttp\Exception\TransferException $ex) {
DB::rollBack(); DB::rollBack();
@ -255,12 +255,13 @@ class SubuserRepository
DB::rollBack(); DB::rollBack();
throw $ex; throw $ex;
} }
return false; return false;
} }
/** /**
* Updates permissions for a given subuser. * Updates permissions for a given subuser.
* @param integer $id The ID of the subuser row in MySQL. (Not the user ID) * @param int $id The ID of the subuser row in MySQL. (Not the user ID)
* @param array $data * @param array $data
* @throws DisplayValidationException * @throws DisplayValidationException
* @throws DisplayException * @throws DisplayException
@ -287,17 +288,17 @@ class SubuserRepository
Models\Permission::where('user_id', $subuser->user_id)->where('server_id', $subuser->server_id)->delete(); Models\Permission::where('user_id', $subuser->user_id)->where('server_id', $subuser->server_id)->delete();
$daemonPermissions = $this->coreDaemonPermissions; $daemonPermissions = $this->coreDaemonPermissions;
foreach($data['permissions'] as $permission) { foreach ($data['permissions'] as $permission) {
if (array_key_exists($permission, $this->permissions)) { if (array_key_exists($permission, $this->permissions)) {
// Build the daemon permissions array for sending. // Build the daemon permissions array for sending.
if (!is_null($this->permissions[$permission])) { if (! is_null($this->permissions[$permission])) {
array_push($daemonPermissions, $this->permissions[$permission]); array_push($daemonPermissions, $this->permissions[$permission]);
} }
$model = new Models\Permission; $model = new Models\Permission;
$model->fill([ $model->fill([
'user_id' => $data['user'], 'user_id' => $data['user'],
'server_id' => $data['server'], 'server_id' => $data['server'],
'permission' => $permission 'permission' => $permission,
]); ]);
$model->save(); $model->save();
} }
@ -312,16 +313,17 @@ class SubuserRepository
$res = $client->request('PATCH', '/server', [ $res = $client->request('PATCH', '/server', [
'headers' => [ 'headers' => [
'X-Access-Server' => $server->uuid, 'X-Access-Server' => $server->uuid,
'X-Access-Token' => $node->daemonSecret 'X-Access-Token' => $node->daemonSecret,
], ],
'json' => [ 'json' => [
'keys' => [ 'keys' => [
$subuser->daemonSecret => $daemonPermissions $subuser->daemonSecret => $daemonPermissions,
] ],
] ],
]); ]);
DB::commit(); DB::commit();
return true; return true;
} catch (\GuzzleHttp\Exception\TransferException $ex) { } catch (\GuzzleHttp\Exception\TransferException $ex) {
DB::rollBack(); DB::rollBack();
@ -330,7 +332,7 @@ class SubuserRepository
DB::rollBack(); DB::rollBack();
throw $ex; throw $ex;
} }
return false; return false;
} }
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,19 +21,17 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Repositories; namespace Pterodactyl\Repositories;
use Cron; use Cron;
use Validator; use Validator;
use Pterodactyl\Models; use Pterodactyl\Models;
use Pterodactyl\Exceptions\DisplayValidationException;
use Pterodactyl\Exceptions\DisplayException; use Pterodactyl\Exceptions\DisplayException;
use Pterodactyl\Exceptions\DisplayValidationException;
class TaskRepository class TaskRepository
{ {
protected $defaults = [ protected $defaults = [
'year' => '*', 'year' => '*',
'day_of_week' => '*', 'day_of_week' => '*',
@ -64,6 +62,7 @@ class TaskRepository
$task = Models\Task::findOrFail($id); $task = Models\Task::findOrFail($id);
try { try {
$task->delete(); $task->delete();
return true; return true;
} catch (\Exception $ex) { } catch (\Exception $ex) {
throw $ex; throw $ex;
@ -111,20 +110,20 @@ class TaskRepository
'month' => 'string|sometimes', 'month' => 'string|sometimes',
'day_of_month' => 'string|sometimes', 'day_of_month' => 'string|sometimes',
'hour' => 'string|sometimes', 'hour' => 'string|sometimes',
'minute' => 'string|sometimes' 'minute' => 'string|sometimes',
]); ]);
if ($validator->fails()) { if ($validator->fails()) {
throw new DisplayValidationException(json_encode($validator->errors())); throw new DisplayValidationException(json_encode($validator->errors()));
} }
if (!in_array($data['action'], $this->actions)) { if (! in_array($data['action'], $this->actions)) {
throw new DisplayException('The action provided is not valid.'); throw new DisplayException('The action provided is not valid.');
} }
$cron = $this->defaults; $cron = $this->defaults;
foreach ($this->defaults as $setting => $value) { foreach ($this->defaults as $setting => $value) {
if (array_key_exists($setting, $data) && !is_null($data[$setting]) && $data[$setting] !== '') { if (array_key_exists($setting, $data) && ! is_null($data[$setting]) && $data[$setting] !== '') {
$cron[$setting] = $data[$setting]; $cron[$setting] = $data[$setting];
} }
} }
@ -157,11 +156,9 @@ class TaskRepository
'hour' => $cron['hour'], 'hour' => $cron['hour'],
'minute' => $cron['minute'], 'minute' => $cron['minute'],
'last_run' => null, 'last_run' => null,
'next_run' => $buildCron->getNextRunDate() 'next_run' => $buildCron->getNextRunDate(),
]); ]);
return $task->save(); return $task->save();
} }
} }

View file

@ -2,7 +2,7 @@
/** /**
* Pterodactyl - Panel * Pterodactyl - Panel
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>
* Some Modifications (c) 2015 Dylan Seidt <dylan.seidt@gmail.com> * Some Modifications (c) 2015 Dylan Seidt <dylan.seidt@gmail.com>.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -22,26 +22,22 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
namespace Pterodactyl\Repositories; namespace Pterodactyl\Repositories;
use DB; use DB;
use Settings;
use Hash;
use Validator;
use Mail;
use Carbon;
use Auth; use Auth;
use Hash;
use Carbon;
use Validator;
use Pterodactyl\Models; use Pterodactyl\Models;
use Pterodactyl\Services\UuidService; use Pterodactyl\Services\UuidService;
use Pterodactyl\Notifications\AccountCreated;
use Pterodactyl\Exceptions\DisplayValidationException;
use Pterodactyl\Exceptions\DisplayException; use Pterodactyl\Exceptions\DisplayException;
use Pterodactyl\Notifications\AccountCreated;
use Pterodactyl\Exceptions\DisplayValidationException;
class UserRepository class UserRepository
{ {
public function __construct() public function __construct()
{ {
// //
@ -54,7 +50,7 @@ class UserRepository
* @param string|null $password An unhashed version of the user's password. * @param string|null $password An unhashed version of the user's password.
* @param bool $admin Boolean value if user should be an admin or not. * @param bool $admin Boolean value if user should be an admin or not.
* @param int $token A custom user ID. * @param int $token A custom user ID.
* @return bool|integer * @return bool|int
*/ */
public function create($email, $password = null, $admin = false, $token = null) public function create($email, $password = null, $admin = false, $token = null)
{ {
@ -83,7 +79,7 @@ class UserRepository
$uuid = new UuidService; $uuid = new UuidService;
// Support for API Services // Support for API Services
if (!is_null($token)) { if (! is_null($token)) {
$user->id = $token; $user->id = $token;
} }
@ -99,12 +95,13 @@ class UserRepository
DB::table('password_resets')->insert([ DB::table('password_resets')->insert([
'email' => $user->email, 'email' => $user->email,
'token' => $token, 'token' => $token,
'created_at' => Carbon::now()->toDateTimeString() 'created_at' => Carbon::now()->toDateTimeString(),
]); ]);
$user->notify((new AccountCreated($token))); $user->notify((new AccountCreated($token)));
DB::commit(); DB::commit();
return $user->id; return $user->id;
} catch (\Exception $ex) { } catch (\Exception $ex) {
DB::rollBack(); DB::rollBack();
@ -115,9 +112,9 @@ class UserRepository
/** /**
* Updates a user on the panel. * Updates a user on the panel.
* *
* @param integer $id * @param int $id
* @param array $data An array of columns and their associated values to update for the user. * @param array $data An array of columns and their associated values to update for the user.
* @return boolean * @return bool
*/ */
public function update($id, array $data) public function update($id, array $data)
{ {
@ -129,7 +126,7 @@ class UserRepository
'root_admin' => 'sometimes|required|boolean', 'root_admin' => 'sometimes|required|boolean',
'language' => 'sometimes|required|string|min:1|max:5', 'language' => 'sometimes|required|string|min:1|max:5',
'use_totp' => 'sometimes|required|boolean', 'use_totp' => 'sometimes|required|boolean',
'totp_secret' => 'sometimes|required|size:16' 'totp_secret' => 'sometimes|required|size:16',
]); ]);
// Run validator, throw catchable and displayable exception if it fails. // Run validator, throw catchable and displayable exception if it fails.
@ -138,7 +135,7 @@ class UserRepository
throw new DisplayValidationException($validator->errors()); throw new DisplayValidationException($validator->errors());
} }
if(array_key_exists('password', $data)) { if (array_key_exists('password', $data)) {
$data['password'] = Hash::make($data['password']); $data['password'] = Hash::make($data['password']);
} }
@ -147,23 +144,24 @@ class UserRepository
} }
$user->fill($data); $user->fill($data);
$user->save();
return $user->save();
} }
/** /**
* Deletes a user on the panel, returns the number of records deleted. * Deletes a user on the panel, returns the number of records deleted.
* *
* @param integer $id * @param int $id
* @return integer * @return int
*/ */
public function delete($id) public function delete($id)
{ {
if(Models\Server::where('owner', $id)->count() > 0) { if (Models\Server::where('owner', $id)->count() > 0) {
throw new DisplayException('Cannot delete a user with active servers attached to thier account.'); throw new DisplayException('Cannot delete a user with active servers attached to thier account.');
} }
// @TODO: this should probably be checked outside of this method because we won't always have Auth::user() // @TODO: this should probably be checked outside of this method because we won't always have Auth::user()
if(!is_null(Auth::user()) && Auth::user()->id === $id) { if (! is_null(Auth::user()) && Auth::user()->id === $id) {
throw new DisplayException('Cannot delete your own account.'); throw new DisplayException('Cannot delete your own account.');
} }
@ -175,11 +173,11 @@ class UserRepository
Models\User::destroy($id); Models\User::destroy($id);
DB::commit(); DB::commit();
return true; return true;
} catch (\Exception $ex) { } catch (\Exception $ex) {
DB::rollBack(); DB::rollBack();
throw $ex; throw $ex;
} }
} }
} }

Some files were not shown because too many files have changed in this diff Show more