Merge branch 'develop' into feature/api-key-changes
This commit is contained in:
commit
80ddd5b659
21 changed files with 124 additions and 136 deletions
12
.env.example
12
.env.example
|
@ -2,10 +2,10 @@ APP_ENV=production
|
||||||
APP_DEBUG=false
|
APP_DEBUG=false
|
||||||
APP_KEY=SomeRandomString3232RandomString
|
APP_KEY=SomeRandomString3232RandomString
|
||||||
APP_THEME=pterodactyl
|
APP_THEME=pterodactyl
|
||||||
APP_TIMEZONE=UTC
|
APP_TIMEZONE=America/New_York
|
||||||
APP_CLEAR_TASKLOG=720
|
APP_CLEAR_TASKLOG=720
|
||||||
APP_DELETE_MINUTES=10
|
APP_DELETE_MINUTES=10
|
||||||
APP_URL=http://yoursite.com/
|
APP_URL=
|
||||||
|
|
||||||
DB_HOST=127.0.0.1
|
DB_HOST=127.0.0.1
|
||||||
DB_PORT=3306
|
DB_PORT=3306
|
||||||
|
@ -13,8 +13,8 @@ DB_DATABASE=panel
|
||||||
DB_USERNAME=pterodactyl
|
DB_USERNAME=pterodactyl
|
||||||
DB_PASSWORD=
|
DB_PASSWORD=
|
||||||
|
|
||||||
CACHE_DRIVER=redis
|
CACHE_DRIVER=
|
||||||
SESSION_DRIVER=database
|
SESSION_DRIVER=
|
||||||
|
|
||||||
HASHIDS_SALT=
|
HASHIDS_SALT=
|
||||||
HASHIDS_LENGTH=8
|
HASHIDS_LENGTH=8
|
||||||
|
@ -25,9 +25,9 @@ MAIL_PORT=2525
|
||||||
MAIL_USERNAME=
|
MAIL_USERNAME=
|
||||||
MAIL_PASSWORD=
|
MAIL_PASSWORD=
|
||||||
MAIL_ENCRYPTION=tls
|
MAIL_ENCRYPTION=tls
|
||||||
MAIL_FROM=you@example.com
|
MAIL_FROM=no-reply@example.com
|
||||||
|
|
||||||
QUEUE_DRIVER=database
|
QUEUE_DRIVER=
|
||||||
QUEUE_HIGH=high
|
QUEUE_HIGH=high
|
||||||
QUEUE_STANDARD=standard
|
QUEUE_STANDARD=standard
|
||||||
QUEUE_LOW=low
|
QUEUE_LOW=low
|
||||||
|
|
|
@ -13,9 +13,10 @@ services:
|
||||||
before_install:
|
before_install:
|
||||||
- mysql -e 'CREATE DATABASE IF NOT EXISTS travis;'
|
- mysql -e 'CREATE DATABASE IF NOT EXISTS travis;'
|
||||||
before_script:
|
before_script:
|
||||||
|
- echo 'opcache.enable_cli=1' >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini
|
||||||
- cp .env.travis .env
|
- cp .env.travis .env
|
||||||
- composer install --no-interaction --prefer-dist --no-suggest --verbose
|
- composer install --no-interaction --prefer-dist --no-suggest
|
||||||
- php artisan migrate --seed -v
|
- php artisan migrate --seed
|
||||||
script:
|
script:
|
||||||
- vendor/bin/phpunit --coverage-clover coverage.xml
|
- vendor/bin/phpunit --coverage-clover coverage.xml
|
||||||
notifications:
|
notifications:
|
||||||
|
|
|
@ -4,6 +4,12 @@ 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.7.0-beta.3 (Derelict Dermodactylus)
|
## v0.7.0-beta.3 (Derelict Dermodactylus)
|
||||||
|
### Fixed
|
||||||
|
* `[beta.2]` — Fixes a bug that would cause an endless exception message stream in the console when attemping to setup environment settings in certain instances.
|
||||||
|
* `[beta.2]` — Fixes a bug causing the dropdown menu for a server's egg to display the wrong selected value.
|
||||||
|
* `[beta.2]` — Fixes a bug that would throw a red page of death when submitting an invalid egg variable value for a server in the Admin CP.
|
||||||
|
* `[beta.2]` — Someone found a `@todo` that I never `@todid` and thus database hosts could not be created without being linked to a node. This is fixed...
|
||||||
|
* `[beta.2]` — Fixes bug that caused incorrect rendering of CPU usage on server graphs due to missing variable.
|
||||||
### Changed
|
### Changed
|
||||||
* API keys have been changed to only use a single public key passed in a bearer token. All existing keys can continue being used, however only the first 32 characters should be sent.
|
* API keys have been changed to only use a single public key passed in a bearer token. All existing keys can continue being used, however only the first 32 characters should be sent.
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
namespace Pterodactyl\Console\Commands\Environment;
|
namespace Pterodactyl\Console\Commands\Environment;
|
||||||
|
|
||||||
|
use DateTimeZone;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
use Illuminate\Contracts\Console\Kernel;
|
use Illuminate\Contracts\Console\Kernel;
|
||||||
use Pterodactyl\Traits\Commands\EnvironmentWriterTrait;
|
use Pterodactyl\Traits\Commands\EnvironmentWriterTrait;
|
||||||
|
@ -18,6 +19,25 @@ class AppSettingsCommand extends Command
|
||||||
{
|
{
|
||||||
use EnvironmentWriterTrait;
|
use EnvironmentWriterTrait;
|
||||||
|
|
||||||
|
const ALLOWED_CACHE_DRIVERS = [
|
||||||
|
'redis' => 'Redis (recommended)',
|
||||||
|
'memcached' => 'Memcached',
|
||||||
|
];
|
||||||
|
|
||||||
|
const ALLOWED_SESSION_DRIVERS = [
|
||||||
|
'redis' => 'Redis (recommended)',
|
||||||
|
'memcached' => 'Memcached',
|
||||||
|
'database' => 'MySQL Database',
|
||||||
|
'file' => 'Filesystem',
|
||||||
|
'cookie' => 'Cookie',
|
||||||
|
];
|
||||||
|
|
||||||
|
const ALLOWED_QUEUE_DRIVERS = [
|
||||||
|
'redis' => 'Redis (recommended)',
|
||||||
|
'database' => 'MySQL Database',
|
||||||
|
'sync' => 'Sync',
|
||||||
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \Illuminate\Contracts\Console\Kernel
|
* @var \Illuminate\Contracts\Console\Kernel
|
||||||
*/
|
*/
|
||||||
|
@ -37,11 +57,13 @@ class AppSettingsCommand extends Command
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $signature = 'p:environment:setup
|
protected $signature = 'p:environment:setup
|
||||||
|
{--new-salt : Wether or not to generate a new salt for Hashids.}
|
||||||
{--author= : The email that services created on this instance should be linked to.}
|
{--author= : The email that services created on this instance should be linked to.}
|
||||||
{--url= : The URL that this Panel is running on.}
|
{--url= : The URL that this Panel is running on.}
|
||||||
{--timezone= : The timezone to use for Panel times.}
|
{--timezone= : The timezone to use for Panel times.}
|
||||||
{--cache= : The cache driver backend to use.}
|
{--cache= : The cache driver backend to use.}
|
||||||
{--session= : The session driver backend to use.}
|
{--session= : The session driver backend to use.}
|
||||||
|
{--queue= : The queue driver backend to use.}
|
||||||
{--redis-host= : Redis host to use for connections.}
|
{--redis-host= : Redis host to use for connections.}
|
||||||
{--redis-pass= : Password used to connect to redis.}
|
{--redis-pass= : Password used to connect to redis.}
|
||||||
{--redis-port= : Port to connect to redis over.}';
|
{--redis-port= : Port to connect to redis over.}';
|
||||||
|
@ -72,7 +94,7 @@ class AppSettingsCommand extends Command
|
||||||
*/
|
*/
|
||||||
public function handle()
|
public function handle()
|
||||||
{
|
{
|
||||||
if (empty($this->config->get('hashids.salt')) || $this->option('--new-salt')) {
|
if (empty($this->config->get('hashids.salt')) || $this->option('new-salt')) {
|
||||||
$this->variables['HASHIDS_SALT'] = str_random(20);
|
$this->variables['HASHIDS_SALT'] = str_random(20);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,33 +109,31 @@ class AppSettingsCommand extends Command
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->output->comment(trans('command/messages.environment.app.timezone_help'));
|
$this->output->comment(trans('command/messages.environment.app.timezone_help'));
|
||||||
$this->variables['APP_TIMEZONE'] = $this->option('timezone') ?? $this->ask(
|
$this->variables['APP_TIMEZONE'] = $this->option('timezone') ?? $this->anticipate(
|
||||||
trans('command/messages.environment.app.timezone'), $this->config->get('app.timezone')
|
trans('command/messages.environment.app.timezone'),
|
||||||
|
DateTimeZone::listIdentifiers(DateTimeZone::ALL),
|
||||||
|
$this->config->get('app.timezone')
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$selected = $this->config->get('cache.default', 'redis');
|
||||||
$this->variables['CACHE_DRIVER'] = $this->option('cache') ?? $this->choice(
|
$this->variables['CACHE_DRIVER'] = $this->option('cache') ?? $this->choice(
|
||||||
trans('command/messages.environment.app.cache_driver'), [
|
trans('command/messages.environment.app.cache_driver'),
|
||||||
'redis' => 'Redis (recommended)',
|
self::ALLOWED_CACHE_DRIVERS,
|
||||||
'memcached' => 'Memcached',
|
array_key_exists($selected, self::ALLOWED_CACHE_DRIVERS) ? $selected : null
|
||||||
], $this->config->get('cache.default', 'redis')
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$selected = $this->config->get('session.driver', 'redis');
|
||||||
$this->variables['SESSION_DRIVER'] = $this->option('session') ?? $this->choice(
|
$this->variables['SESSION_DRIVER'] = $this->option('session') ?? $this->choice(
|
||||||
trans('command/messages.environment.app.session_driver'), [
|
trans('command/messages.environment.app.session_driver'),
|
||||||
'redis' => 'Redis (recommended)',
|
self::ALLOWED_SESSION_DRIVERS,
|
||||||
'memcached' => 'Memcached',
|
array_key_exists($selected, self::ALLOWED_SESSION_DRIVERS) ? $selected : null
|
||||||
'database' => 'MySQL Database',
|
|
||||||
'file' => 'Filesystem',
|
|
||||||
'cookie' => 'Cookie',
|
|
||||||
], $this->config->get('session.driver', 'redis')
|
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->variables['QUEUE_DRIVER'] = $this->option('session') ?? $this->choice(
|
$selected = $this->config->get('queue.default', 'redis');
|
||||||
trans('command/messages.environment.app.session_driver'), [
|
$this->variables['QUEUE_DRIVER'] = $this->option('queue') ?? $this->choice(
|
||||||
'redis' => 'Redis (recommended)',
|
trans('command/messages.environment.app.queue_driver'),
|
||||||
'database' => 'MySQL Database',
|
self::ALLOWED_QUEUE_DRIVERS,
|
||||||
'sync' => 'Sync',
|
array_key_exists($selected, self::ALLOWED_QUEUE_DRIVERS) ? $selected : null
|
||||||
], $this->config->get('queue.driver', 'redis')
|
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->checkForRedis();
|
$this->checkForRedis();
|
||||||
|
|
|
@ -9,6 +9,6 @@
|
||||||
|
|
||||||
namespace Pterodactyl\Exceptions;
|
namespace Pterodactyl\Exceptions;
|
||||||
|
|
||||||
class DisplayValidationException extends PterodactylException
|
class DisplayValidationException extends DisplayException
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -319,14 +319,14 @@ class ServersController extends Controller
|
||||||
/**
|
/**
|
||||||
* Display startup configuration page for a server.
|
* Display startup configuration page for a server.
|
||||||
*
|
*
|
||||||
* @param int $server
|
* @param \Pterodactyl\Models\Server $server
|
||||||
* @return \Illuminate\View\View
|
* @return \Illuminate\View\View
|
||||||
*
|
*
|
||||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||||
*/
|
*/
|
||||||
public function viewStartup($server)
|
public function viewStartup(Server $server)
|
||||||
{
|
{
|
||||||
$parameters = $this->repository->getVariablesWithValues($server, true);
|
$parameters = $this->repository->getVariablesWithValues($server->id, true);
|
||||||
if (! $parameters->server->installed) {
|
if (! $parameters->server->installed) {
|
||||||
abort(404);
|
abort(404);
|
||||||
}
|
}
|
||||||
|
@ -334,6 +334,7 @@ class ServersController extends Controller
|
||||||
$nests = $this->nestRepository->getWithEggs();
|
$nests = $this->nestRepository->getWithEggs();
|
||||||
|
|
||||||
Javascript::put([
|
Javascript::put([
|
||||||
|
'server' => $server,
|
||||||
'nests' => $nests->map(function ($item) {
|
'nests' => $nests->map(function ($item) {
|
||||||
return array_merge($item->toArray(), [
|
return array_merge($item->toArray(), [
|
||||||
'eggs' => $item->eggs->keyBy('id')->toArray(),
|
'eggs' => $item->eggs->keyBy('id')->toArray(),
|
||||||
|
|
|
@ -38,6 +38,9 @@ class ConsoleController extends Controller
|
||||||
$server = $request->attributes->get('server');
|
$server = $request->attributes->get('server');
|
||||||
|
|
||||||
$this->setRequest($request)->injectJavascript([
|
$this->setRequest($request)->injectJavascript([
|
||||||
|
'server' => [
|
||||||
|
'cpu' => $server->cpu,
|
||||||
|
],
|
||||||
'meta' => [
|
'meta' => [
|
||||||
'saveFile' => route('server.files.save', $server->uuidShort),
|
'saveFile' => route('server.files.save', $server->uuidShort),
|
||||||
'csrfToken' => csrf_token(),
|
'csrfToken' => csrf_token(),
|
||||||
|
|
|
@ -18,6 +18,10 @@ class DatabaseHostFormRequest extends AdminFormRequest
|
||||||
*/
|
*/
|
||||||
public function rules()
|
public function rules()
|
||||||
{
|
{
|
||||||
|
if (! $this->has('node_id')) {
|
||||||
|
$this->merge(['node_id' => null]);
|
||||||
|
}
|
||||||
|
|
||||||
if ($this->method() !== 'POST') {
|
if ($this->method() !== 'POST') {
|
||||||
return DatabaseHost::getUpdateRulesForId($this->route()->parameter('host')->id);
|
return DatabaseHost::getUpdateRulesForId($this->route()->parameter('host')->id);
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,14 +63,13 @@ class DatabaseHost extends Model implements CleansAttributes, ValidableContract
|
||||||
'host' => 'required',
|
'host' => 'required',
|
||||||
'port' => 'required',
|
'port' => 'required',
|
||||||
'username' => 'required',
|
'username' => 'required',
|
||||||
'node_id' => 'sometimes|required',
|
'node_id' => 'sometimes',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validation rules to assign to this model.
|
* Validation rules to assign to this model.
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
* @todo the node_id field doesn't validate correctly if no node is provided in request
|
|
||||||
*/
|
*/
|
||||||
protected static $dataIntegrityRules = [
|
protected static $dataIntegrityRules = [
|
||||||
'name' => 'string|max:255',
|
'name' => 'string|max:255',
|
||||||
|
@ -78,7 +77,7 @@ class DatabaseHost extends Model implements CleansAttributes, ValidableContract
|
||||||
'port' => 'numeric|between:1,65535',
|
'port' => 'numeric|between:1,65535',
|
||||||
'username' => 'string|max:32',
|
'username' => 'string|max:32',
|
||||||
'password' => 'nullable|string',
|
'password' => 'nullable|string',
|
||||||
'node_id' => 'nullable|exists:nodes,id',
|
'node_id' => 'nullable|integer|exists:nodes,id',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -78,9 +78,10 @@ class StartupModificationService
|
||||||
* @param \Pterodactyl\Models\Server $server
|
* @param \Pterodactyl\Models\Server $server
|
||||||
* @param array $data
|
* @param array $data
|
||||||
*
|
*
|
||||||
* @throws \Pterodactyl\Exceptions\DisplayException
|
* @throws \Illuminate\Validation\ValidationException
|
||||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||||
|
* @throws \Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException
|
||||||
*/
|
*/
|
||||||
public function handle(Server $server, array $data)
|
public function handle(Server $server, array $data)
|
||||||
{
|
{
|
||||||
|
|
|
@ -11,8 +11,8 @@ namespace Pterodactyl\Services\Servers;
|
||||||
|
|
||||||
use Pterodactyl\Models\User;
|
use Pterodactyl\Models\User;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
|
use Illuminate\Validation\ValidationException;
|
||||||
use Pterodactyl\Traits\Services\HasUserLevels;
|
use Pterodactyl\Traits\Services\HasUserLevels;
|
||||||
use Pterodactyl\Exceptions\DisplayValidationException;
|
|
||||||
use Pterodactyl\Contracts\Repository\ServerRepositoryInterface;
|
use Pterodactyl\Contracts\Repository\ServerRepositoryInterface;
|
||||||
use Illuminate\Contracts\Validation\Factory as ValidationFactory;
|
use Illuminate\Contracts\Validation\Factory as ValidationFactory;
|
||||||
use Pterodactyl\Contracts\Repository\EggVariableRepositoryInterface;
|
use Pterodactyl\Contracts\Repository\EggVariableRepositoryInterface;
|
||||||
|
@ -25,22 +25,22 @@ class VariableValidatorService
|
||||||
/**
|
/**
|
||||||
* @var \Pterodactyl\Contracts\Repository\EggVariableRepositoryInterface
|
* @var \Pterodactyl\Contracts\Repository\EggVariableRepositoryInterface
|
||||||
*/
|
*/
|
||||||
protected $optionVariableRepository;
|
private $optionVariableRepository;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \Pterodactyl\Contracts\Repository\ServerRepositoryInterface
|
* @var \Pterodactyl\Contracts\Repository\ServerRepositoryInterface
|
||||||
*/
|
*/
|
||||||
protected $serverRepository;
|
private $serverRepository;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \Pterodactyl\Contracts\Repository\ServerVariableRepositoryInterface
|
* @var \Pterodactyl\Contracts\Repository\ServerVariableRepositoryInterface
|
||||||
*/
|
*/
|
||||||
protected $serverVariableRepository;
|
private $serverVariableRepository;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \Illuminate\Contracts\Validation\Factory
|
* @var \Illuminate\Contracts\Validation\Factory
|
||||||
*/
|
*/
|
||||||
protected $validator;
|
private $validator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* VariableValidatorService constructor.
|
* VariableValidatorService constructor.
|
||||||
|
@ -68,32 +68,32 @@ class VariableValidatorService
|
||||||
* @param int $egg
|
* @param int $egg
|
||||||
* @param array $fields
|
* @param array $fields
|
||||||
* @return \Illuminate\Support\Collection
|
* @return \Illuminate\Support\Collection
|
||||||
|
* @throws \Illuminate\Validation\ValidationException
|
||||||
*/
|
*/
|
||||||
public function handle(int $egg, array $fields = []): Collection
|
public function handle(int $egg, array $fields = []): Collection
|
||||||
{
|
{
|
||||||
$variables = $this->optionVariableRepository->findWhere([['egg_id', '=', $egg]]);
|
$variables = $this->optionVariableRepository->findWhere([['egg_id', '=', $egg]]);
|
||||||
|
$messages = $this->validator->make([], []);
|
||||||
|
|
||||||
return $variables->map(function ($item) use ($fields) {
|
$response = $variables->map(function ($item) use ($fields, $messages) {
|
||||||
// Skip doing anything if user is not an admin and
|
// Skip doing anything if user is not an admin and
|
||||||
// variable is not user viewable or editable.
|
// variable is not user viewable or editable.
|
||||||
if (! $this->isUserLevel(User::USER_LEVEL_ADMIN) && (! $item->user_editable || ! $item->user_viewable)) {
|
if (! $this->isUserLevel(User::USER_LEVEL_ADMIN) && (! $item->user_editable || ! $item->user_viewable)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$validator = $this->validator->make([
|
$v = $this->validator->make([
|
||||||
'variable_value' => array_get($fields, $item->env_variable),
|
'variable_value' => array_get($fields, $item->env_variable),
|
||||||
], [
|
], [
|
||||||
'variable_value' => $item->rules,
|
'variable_value' => $item->rules,
|
||||||
|
], [], [
|
||||||
|
'variable_value' => trans('validation.internal.variable_value', ['env' => $item->name]),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if ($validator->fails()) {
|
if ($v->fails()) {
|
||||||
throw new DisplayValidationException(json_encode(
|
foreach ($v->getMessageBag()->all() as $message) {
|
||||||
collect([
|
$messages->getMessageBag()->add($item->env_variable, $message);
|
||||||
'notice' => [
|
}
|
||||||
trans('admin/server.exceptions.bad_variable', ['name' => $item->name]),
|
|
||||||
],
|
|
||||||
])->merge($validator->errors()->toArray())
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (object) [
|
return (object) [
|
||||||
|
@ -104,5 +104,11 @@ class VariableValidatorService
|
||||||
})->filter(function ($item) {
|
})->filter(function ($item) {
|
||||||
return is_object($item);
|
return is_object($item);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (! empty($messages->getMessageBag()->all())) {
|
||||||
|
throw new ValidationException($messages);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $response;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ trait JavascriptInjection
|
||||||
$server = $request->attributes->get('server');
|
$server = $request->attributes->get('server');
|
||||||
$token = $request->attributes->get('server_token');
|
$token = $request->attributes->get('server_token');
|
||||||
|
|
||||||
$response = array_merge([
|
$response = array_merge_recursive([
|
||||||
'server' => [
|
'server' => [
|
||||||
'uuid' => $server->uuid,
|
'uuid' => $server->uuid,
|
||||||
'uuidShort' => $server->uuidShort,
|
'uuidShort' => $server->uuidShort,
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
"name": "OxideMod",
|
"name": "OxideMod",
|
||||||
"description": "Set whether you want the server to use and auto update OxideMod or not. Valid options are \"1\" for true and \"0\" for false.",
|
"description": "Set whether you want the server to use and auto update OxideMod or not. Valid options are \"1\" for true and \"0\" for false.",
|
||||||
"env_variable": "OXIDE",
|
"env_variable": "OXIDE",
|
||||||
"default_value": "false",
|
"default_value": "0",
|
||||||
"user_viewable": 1,
|
"user_viewable": 1,
|
||||||
"user_editable": 1,
|
"user_editable": 1,
|
||||||
"rules": "required|boolean"
|
"rules": "required|boolean"
|
||||||
|
|
|
@ -16,7 +16,7 @@ return [
|
||||||
'default_allocation_not_found' => 'The requested default allocation was not found in this server\'s allocations.',
|
'default_allocation_not_found' => 'The requested default allocation was not found in this server\'s allocations.',
|
||||||
],
|
],
|
||||||
'alerts' => [
|
'alerts' => [
|
||||||
'startup_changed' => 'The startup configuration for this server has been updated. If this server\'s service or option was changed a reinstall will be occuring now.',
|
'startup_changed' => 'The startup configuration for this server has been updated. If this server\'s nest or egg was changed a reinstall will be occuring now.',
|
||||||
'server_deleted' => 'Server has successfully been deleted from the system.',
|
'server_deleted' => 'Server has successfully been deleted from the system.',
|
||||||
'server_created' => 'Server was successfully created on the panel. Please allow the daemon a few minutes to completely install this server.',
|
'server_created' => 'Server was successfully created on the panel. Please allow the daemon a few minutes to completely install this server.',
|
||||||
'build_updated' => 'The build details for this server have been updated. Some changes may require a restart to take effect.',
|
'build_updated' => 'The build details for this server have been updated. Some changes may require a restart to take effect.',
|
||||||
|
|
|
@ -82,6 +82,7 @@ return [
|
||||||
'timezone' => 'Application Timezone',
|
'timezone' => 'Application Timezone',
|
||||||
'cache_driver' => 'Cache Driver',
|
'cache_driver' => 'Cache Driver',
|
||||||
'session_driver' => 'Session Driver',
|
'session_driver' => 'Session Driver',
|
||||||
|
'queue_driver' => 'Queue Driver',
|
||||||
'using_redis' => 'You\'ve selected the Redis driver for one or more options, please provide valid connection information below. In most cases you can use the defaults provided unless you have modified your setup.',
|
'using_redis' => 'You\'ve selected the Redis driver for one or more options, please provide valid connection information below. In most cases you can use the defaults provided unless you have modified your setup.',
|
||||||
'redis_host' => 'Redis Host',
|
'redis_host' => 'Redis Host',
|
||||||
'redis_password' => 'Redis Password',
|
'redis_password' => 'Redis Password',
|
||||||
|
|
|
@ -85,23 +85,6 @@ return [
|
||||||
'uploaded' => 'The :attribute failed to upload.',
|
'uploaded' => 'The :attribute failed to upload.',
|
||||||
'url' => 'The :attribute format is invalid.',
|
'url' => 'The :attribute format is invalid.',
|
||||||
|
|
||||||
/*
|
|
||||||
|--------------------------------------------------------------------------
|
|
||||||
| Custom Validation Language Lines
|
|
||||||
|--------------------------------------------------------------------------
|
|
||||||
|
|
|
||||||
| Here you may specify custom validation messages for attributes using the
|
|
||||||
| convention "attribute.rule" to name the lines. This makes it quick to
|
|
||||||
| specify a specific custom language line for a given attribute rule.
|
|
||||||
|
|
|
||||||
*/
|
|
||||||
|
|
||||||
'custom' => [
|
|
||||||
'attribute-name' => [
|
|
||||||
'rule-name' => 'custom-message',
|
|
||||||
],
|
|
||||||
],
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Custom Validation Attributes
|
| Custom Validation Attributes
|
||||||
|
@ -114,4 +97,9 @@ return [
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'attributes' => [],
|
'attributes' => [],
|
||||||
|
|
||||||
|
// Internal validation logic for Pterodactyl
|
||||||
|
'internal' => [
|
||||||
|
'variable_value' => ':env variable',
|
||||||
|
],
|
||||||
];
|
];
|
||||||
|
|
|
@ -103,7 +103,7 @@
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="pNodeId" class="form-label">Linked Node</label>
|
<label for="pNodeId" class="form-label">Linked Node</label>
|
||||||
<select name="node_id" id="pNodeId" class="form-control">
|
<select name="node_id" id="pNodeId" class="form-control">
|
||||||
<option value="null">None</option>
|
<option value="">None</option>
|
||||||
@foreach($locations as $location)
|
@foreach($locations as $location)
|
||||||
<optgroup label="{{ $location->short }}">
|
<optgroup label="{{ $location->short }}">
|
||||||
@foreach($location->nodes as $node)
|
@foreach($location->nodes as $node)
|
||||||
|
|
|
@ -148,7 +148,7 @@
|
||||||
text: item.name,
|
text: item.name,
|
||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
}).change();
|
}).val(Pterodactyl.server.egg_id).change();
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#pEggId').on('change', function (event) {
|
$('#pEggId').on('change', function (event) {
|
||||||
|
@ -157,8 +157,8 @@
|
||||||
|
|
||||||
$('#setDefaultImage').html(_.get(objectChain, 'docker_image', 'undefined'));
|
$('#setDefaultImage').html(_.get(objectChain, 'docker_image', 'undefined'));
|
||||||
$('#pDockerImage').val(_.get(objectChain, 'docker_image', 'undefined'));
|
$('#pDockerImage').val(_.get(objectChain, 'docker_image', 'undefined'));
|
||||||
if (objectChain.id === parseInt('{{ $server->egg_id }}')) {
|
if (objectChain.id === parseInt(Pterodactyl.server.egg_id)) {
|
||||||
$('#pDockerImage').val('{{ $server->image }}');
|
$('#pDockerImage').val(Pterodactyl.server.image);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_.get(objectChain, 'startup', false)) {
|
if (!_.get(objectChain, 'startup', false)) {
|
||||||
|
@ -178,9 +178,9 @@
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
|
|
||||||
@if(! is_null($server->pack_id))
|
if (Pterodactyl.server.pack_id !== null) {
|
||||||
$('#pPackId').val({{ $server->pack_id }});
|
$('#pPackId').val(Pterodactyl.server.pack_id);
|
||||||
@endif
|
}
|
||||||
|
|
||||||
$('#appendVariablesTo').html('');
|
$('#appendVariablesTo').html('');
|
||||||
$.each(_.get(objectChain, 'variables', []), function (i, item) {
|
$.each(_.get(objectChain, 'variables', []), function (i, item) {
|
||||||
|
|
|
@ -133,7 +133,7 @@
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-xs-12">
|
<div class="col-xs-12">
|
||||||
@if (count($errors) > 0)
|
@if (count($errors) > 0)
|
||||||
<div class="callout callout-danger">
|
<div class="alert alert-danger">
|
||||||
@lang('base.validation_error')<br><br>
|
@lang('base.validation_error')<br><br>
|
||||||
<ul>
|
<ul>
|
||||||
@foreach ($errors->all() as $error)
|
@foreach ($errors->all() as $error)
|
||||||
|
@ -144,7 +144,7 @@
|
||||||
@endif
|
@endif
|
||||||
@foreach (Alert::getMessages() as $type => $messages)
|
@foreach (Alert::getMessages() as $type => $messages)
|
||||||
@foreach ($messages as $message)
|
@foreach ($messages as $message)
|
||||||
<div class="callout callout-{{ $type }} alert-dismissable" role="alert">
|
<div class="alert alert-{{ $type }} alert-dismissable" role="alert">
|
||||||
{!! $message !!}
|
{!! $message !!}
|
||||||
</div>
|
</div>
|
||||||
@endforeach
|
@endforeach
|
||||||
|
|
|
@ -215,7 +215,7 @@
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-xs-12">
|
<div class="col-xs-12">
|
||||||
@if (count($errors) > 0)
|
@if (count($errors) > 0)
|
||||||
<div class="callout callout-danger">
|
<div class="alert alert-danger">
|
||||||
@lang('base.validation_error')<br><br>
|
@lang('base.validation_error')<br><br>
|
||||||
<ul>
|
<ul>
|
||||||
@foreach ($errors->all() as $error)
|
@foreach ($errors->all() as $error)
|
||||||
|
@ -226,7 +226,7 @@
|
||||||
@endif
|
@endif
|
||||||
@foreach (Alert::getMessages() as $type => $messages)
|
@foreach (Alert::getMessages() as $type => $messages)
|
||||||
@foreach ($messages as $message)
|
@foreach ($messages as $message)
|
||||||
<div class="callout callout-{{ $type }} alert-dismissable" role="alert">
|
<div class="alert alert-{{ $type }} alert-dismissable" role="alert">
|
||||||
{!! $message !!}
|
{!! $message !!}
|
||||||
</div>
|
</div>
|
||||||
@endforeach
|
@endforeach
|
||||||
|
|
|
@ -1,11 +1,4 @@
|
||||||
<?php
|
<?php
|
||||||
/**
|
|
||||||
* Pterodactyl - Panel
|
|
||||||
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
|
|
||||||
*
|
|
||||||
* This software is licensed under the terms of the MIT license.
|
|
||||||
* https://opensource.org/licenses/MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Tests\Unit\Services\Servers;
|
namespace Tests\Unit\Services\Servers;
|
||||||
|
|
||||||
|
@ -15,8 +8,7 @@ use Pterodactyl\Models\User;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
use Pterodactyl\Models\EggVariable;
|
use Pterodactyl\Models\EggVariable;
|
||||||
use Illuminate\Contracts\Validation\Factory;
|
use Illuminate\Contracts\Validation\Factory;
|
||||||
use Pterodactyl\Exceptions\PterodactylException;
|
use Illuminate\Validation\ValidationException;
|
||||||
use Pterodactyl\Exceptions\DisplayValidationException;
|
|
||||||
use Pterodactyl\Services\Servers\VariableValidatorService;
|
use Pterodactyl\Services\Servers\VariableValidatorService;
|
||||||
use Pterodactyl\Contracts\Repository\ServerRepositoryInterface;
|
use Pterodactyl\Contracts\Repository\ServerRepositoryInterface;
|
||||||
use Pterodactyl\Contracts\Repository\EggVariableRepositoryInterface;
|
use Pterodactyl\Contracts\Repository\EggVariableRepositoryInterface;
|
||||||
|
@ -27,22 +19,17 @@ class VariableValidatorServiceTest extends TestCase
|
||||||
/**
|
/**
|
||||||
* @var \Pterodactyl\Contracts\Repository\EggVariableRepositoryInterface|\Mockery\Mock
|
* @var \Pterodactyl\Contracts\Repository\EggVariableRepositoryInterface|\Mockery\Mock
|
||||||
*/
|
*/
|
||||||
protected $optionVariableRepository;
|
private $optionVariableRepository;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \Pterodactyl\Contracts\Repository\ServerRepositoryInterface|\Mockery\Mock
|
* @var \Pterodactyl\Contracts\Repository\ServerRepositoryInterface|\Mockery\Mock
|
||||||
*/
|
*/
|
||||||
protected $serverRepository;
|
private $serverRepository;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \Pterodactyl\Contracts\Repository\ServerVariableRepositoryInterface|\Mockery\Mock
|
* @var \Pterodactyl\Contracts\Repository\ServerVariableRepositoryInterface|\Mockery\Mock
|
||||||
*/
|
*/
|
||||||
protected $serverVariableRepository;
|
private $serverVariableRepository;
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Illuminate\Contracts\Validation\Factory|\Mockery\Mock
|
|
||||||
*/
|
|
||||||
protected $validator;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Setup tests.
|
* Setup tests.
|
||||||
|
@ -54,7 +41,6 @@ class VariableValidatorServiceTest extends TestCase
|
||||||
$this->optionVariableRepository = m::mock(EggVariableRepositoryInterface::class);
|
$this->optionVariableRepository = m::mock(EggVariableRepositoryInterface::class);
|
||||||
$this->serverRepository = m::mock(ServerRepositoryInterface::class);
|
$this->serverRepository = m::mock(ServerRepositoryInterface::class);
|
||||||
$this->serverVariableRepository = m::mock(ServerVariableRepositoryInterface::class);
|
$this->serverVariableRepository = m::mock(ServerVariableRepositoryInterface::class);
|
||||||
$this->validator = m::mock(Factory::class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -77,13 +63,6 @@ class VariableValidatorServiceTest extends TestCase
|
||||||
$variables = $this->getVariableCollection();
|
$variables = $this->getVariableCollection();
|
||||||
$this->optionVariableRepository->shouldReceive('findWhere')->with([['egg_id', '=', 1]])->andReturn($variables);
|
$this->optionVariableRepository->shouldReceive('findWhere')->with([['egg_id', '=', 1]])->andReturn($variables);
|
||||||
|
|
||||||
$this->validator->shouldReceive('make')->with([
|
|
||||||
'variable_value' => 'Test_SomeValue_0',
|
|
||||||
], [
|
|
||||||
'variable_value' => $variables[0]->rules,
|
|
||||||
])->once()->andReturnSelf();
|
|
||||||
$this->validator->shouldReceive('fails')->withNoArgs()->once()->andReturn(false);
|
|
||||||
|
|
||||||
$response = $this->getService()->handle(1, [
|
$response = $this->getService()->handle(1, [
|
||||||
$variables[0]->env_variable => 'Test_SomeValue_0',
|
$variables[0]->env_variable => 'Test_SomeValue_0',
|
||||||
$variables[1]->env_variable => 'Test_SomeValue_1',
|
$variables[1]->env_variable => 'Test_SomeValue_1',
|
||||||
|
@ -112,15 +91,6 @@ class VariableValidatorServiceTest extends TestCase
|
||||||
$variables = $this->getVariableCollection();
|
$variables = $this->getVariableCollection();
|
||||||
$this->optionVariableRepository->shouldReceive('findWhere')->with([['egg_id', '=', 1]])->andReturn($variables);
|
$this->optionVariableRepository->shouldReceive('findWhere')->with([['egg_id', '=', 1]])->andReturn($variables);
|
||||||
|
|
||||||
foreach ($variables as $key => $variable) {
|
|
||||||
$this->validator->shouldReceive('make')->with([
|
|
||||||
'variable_value' => 'Test_SomeValue_' . $key,
|
|
||||||
], [
|
|
||||||
'variable_value' => $variables[$key]->rules,
|
|
||||||
])->once()->andReturnSelf();
|
|
||||||
$this->validator->shouldReceive('fails')->withNoArgs()->once()->andReturn(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
$service = $this->getService();
|
$service = $this->getService();
|
||||||
$service->setUserLevel(User::USER_LEVEL_ADMIN);
|
$service->setUserLevel(User::USER_LEVEL_ADMIN);
|
||||||
$response = $service->handle(1, [
|
$response = $service->handle(1, [
|
||||||
|
@ -152,28 +122,16 @@ class VariableValidatorServiceTest extends TestCase
|
||||||
$variables = $this->getVariableCollection();
|
$variables = $this->getVariableCollection();
|
||||||
$this->optionVariableRepository->shouldReceive('findWhere')->with([['egg_id', '=', 1]])->andReturn($variables);
|
$this->optionVariableRepository->shouldReceive('findWhere')->with([['egg_id', '=', 1]])->andReturn($variables);
|
||||||
|
|
||||||
$this->validator->shouldReceive('make')->with([
|
|
||||||
'variable_value' => null,
|
|
||||||
], [
|
|
||||||
'variable_value' => $variables[0]->rules,
|
|
||||||
])->once()->andReturnSelf();
|
|
||||||
$this->validator->shouldReceive('fails')->withNoArgs()->once()->andReturn(true);
|
|
||||||
|
|
||||||
$this->validator->shouldReceive('errors')->withNoArgs()->once()->andReturnSelf();
|
|
||||||
$this->validator->shouldReceive('toArray')->withNoArgs()->once()->andReturn([]);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$this->getService()->handle(1, [$variables[0]->env_variable => null]);
|
$this->getService()->handle(1, [$variables[0]->env_variable => null]);
|
||||||
} catch (PterodactylException $exception) {
|
} catch (ValidationException $exception) {
|
||||||
$this->assertInstanceOf(DisplayValidationException::class, $exception);
|
$messages = $exception->validator->getMessageBag()->all();
|
||||||
|
|
||||||
$decoded = json_decode($exception->getMessage());
|
$this->assertNotEmpty($messages);
|
||||||
$this->assertEquals(0, json_last_error(), 'Assert that response is decodable JSON.');
|
$this->assertSame(1, count($messages));
|
||||||
$this->assertObjectHasAttribute('notice', $decoded);
|
$this->assertSame(trans('validation.required', [
|
||||||
$this->assertEquals(
|
'attribute' => trans('validation.internal.variable_value', ['env' => $variables[0]->name]),
|
||||||
trans('admin/server.exceptions.bad_variable', ['name' => $variables[0]->name]),
|
]), $messages[0]);
|
||||||
$decoded->notice[0]
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,7 +163,7 @@ class VariableValidatorServiceTest extends TestCase
|
||||||
$this->optionVariableRepository,
|
$this->optionVariableRepository,
|
||||||
$this->serverRepository,
|
$this->serverRepository,
|
||||||
$this->serverVariableRepository,
|
$this->serverVariableRepository,
|
||||||
$this->validator
|
$this->app->make(Factory::class)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue