Replace existing Egg Reserved_Env_Variables with SERVER_ prefix (#1070)

* Add migration that updates egg->variables->env_variable, egg->startup, egg->servers->startup

* Update `EggImporterService` to replace `EggVariable::RESERVED_ENV_NAMES`

* Use `EggImporterService::parseReservedEnvNames`

* Refactor & Remove `Migration`
This commit is contained in:
MartinOscar 2025-03-15 19:51:10 +01:00 committed by GitHub
parent ea5914f362
commit e04abcbcf9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 48 additions and 12 deletions

View File

@ -192,7 +192,7 @@ class CreateEgg extends CreateRecord
->hintIcon('tabler-code')
->hintIconTooltip(fn ($state) => "{{{$state}}}")
->unique(modifyRuleUsing: fn (Unique $rule, Get $get) => $rule->where('egg_id', $get('../../id')), ignoreRecord: true)
->rules(EggVariable::$validationRules['env_variable'])
->rules(EggVariable::getRulesForField('env_variable'))
->validationMessages([
'unique' => trans('admin/egg.error_unique'),
'required' => trans('admin/egg.error_required'),

View File

@ -183,7 +183,7 @@ class EditEgg extends EditRecord
->hintIcon('tabler-code')
->hintIconTooltip(fn ($state) => "{{{$state}}}")
->unique(modifyRuleUsing: fn (Unique $rule, Get $get) => $rule->where('egg_id', $get('../../id')), ignoreRecord: true)
->rules(EggVariable::$validationRules['env_variable'])
->rules(EggVariable::getRulesForField('env_variable'))
->validationMessages([
'unique' => trans('admin/egg.error_unique'),
'required' => trans('admin/egg.error_required'),

View File

@ -33,7 +33,7 @@ use Illuminate\Database\Eloquent\Relations\HasMany;
class EggVariable extends Model implements Validatable
{
use HasFactory;
use HasValidation;
use HasValidation { getRules as getValidationRules; }
/**
* The resource name for this model when it is transformed into an
@ -44,7 +44,7 @@ class EggVariable extends Model implements Validatable
/**
* Reserved environment variable names.
*/
public const RESERVED_ENV_NAMES = 'P_SERVER_UUID,P_SERVER_ALLOCATION_LIMIT,SERVER_MEMORY,SERVER_IP,SERVER_PORT,ENV,HOME,USER,STARTUP,MODIFIED_STARTUP,SERVER_UUID,UUID,INTERNAL_IP,HOSTNAME,TERM,LANG,PWD,TZ,TIMEZONE';
public const RESERVED_ENV_NAMES = ['P_SERVER_UUID', 'P_SERVER_ALLOCATION_LIMIT', 'SERVER_MEMORY', 'SERVER_IP', 'SERVER_PORT', 'ENV', 'HOME', 'USER', 'STARTUP', 'MODIFIED_STARTUP', 'SERVER_UUID', 'UUID', 'INTERNAL_IP', 'HOSTNAME', 'TERM', 'LANG', 'PWD', 'TZ', 'TIMEZONE'];
/**
* Fields that are not mass assignable.
@ -57,7 +57,6 @@ class EggVariable extends Model implements Validatable
'sort' => ['nullable'],
'name' => ['required', 'string', 'between:1,255'],
'description' => ['string'],
'env_variable' => ['required', 'alphaDash', 'between:1,255', 'notIn:' . self::RESERVED_ENV_NAMES],
'default_value' => ['string'],
'user_viewable' => ['boolean'],
'user_editable' => ['boolean'],
@ -65,6 +64,20 @@ class EggVariable extends Model implements Validatable
'rules.*' => ['string'],
];
/**
* Implement language verification by overriding Eloquence's gather rules function.
*
* @return array<string|string[]>
*/
public static function getRules(): array
{
$rules = self::getValidationRules();
$rules['env_variable'] = ['required', 'alphaDash', 'between:1,255', 'notIn:' . implode(',', EggVariable::RESERVED_ENV_NAMES)];
return $rules;
}
protected $attributes = [
'user_editable' => 0,
'user_viewable' => 0,

View File

@ -122,11 +122,34 @@ class EggImporterService
};
// Make sure we only use recent variable format from now on
$parsed['config']['files'] = str_replace(
array_keys(self::UPGRADE_VARIABLES),
array_values(self::UPGRADE_VARIABLES),
$parsed['config']['files'] ?? '',
);
if (array_get($parsed['config'], 'files')) {
$parsed['config']['files'] = str_replace(
array_keys(self::UPGRADE_VARIABLES),
array_values(self::UPGRADE_VARIABLES),
$parsed['config']['files'],
);
}
[$forbidden, $allowed] = collect($parsed['variables'])
->map(fn ($variable) => array_merge(
$variable,
['env_variable' => strtoupper($variable['env_variable'])]
))
->partition(fn ($variable) => in_array($variable['env_variable'], EggVariable::RESERVED_ENV_NAMES));
$updatedVariables = $forbidden->map(fn ($variable) => array_merge(
$variable,
['env_variable' => 'SERVER_' . $variable['env_variable']]
));
if ($forbidden->count()) {
$parsed['variables'] = $allowed->merge($updatedVariables)->all();
if (!empty($parsed['startup'])) {
$pattern = '/\b(' . collect($forbidden)->map(fn ($variable) => preg_quote($variable['env_variable']))->join('|') . ')\b/';
$parsed['startup'] = preg_replace($pattern, 'SERVER_$1', $parsed['startup']) ?? $parsed['startup'];
}
}
return $parsed;
}

View File

@ -42,7 +42,7 @@ class VariableCreationService
*/
public function handle(int $egg, array $data): EggVariable
{
if (in_array(strtoupper(array_get($data, 'env_variable')), explode(',', EggVariable::RESERVED_ENV_NAMES))) {
if (in_array(strtoupper(array_get($data, 'env_variable')), EggVariable::RESERVED_ENV_NAMES)) {
throw new ReservedVariableNameException(sprintf('Cannot use the protected name %s for this environment variable.', array_get($data, 'env_variable')));
}

View File

@ -45,7 +45,7 @@ class VariableUpdateService
public function handle(EggVariable $variable, array $data): EggVariable
{
if (!is_null(array_get($data, 'env_variable'))) {
if (in_array(strtoupper(array_get($data, 'env_variable')), explode(',', EggVariable::RESERVED_ENV_NAMES))) {
if (in_array(strtoupper(array_get($data, 'env_variable')), EggVariable::RESERVED_ENV_NAMES)) {
throw new ReservedVariableNameException(trans('exceptions.service.variables.reserved_name', ['name' => array_get($data, 'env_variable')]));
}