mirror of
https://github.com/tiennm99/coolify.git
synced 2026-10-15 02:16:43 +00:00
refactor: use forceCreate() for internal model creation
Replace create() with forceCreate() across internal model creation operations to bypass mass assignment protection. This is appropriate for internal code that constructs complete model state without user input. Add InternalModelCreationMassAssignmentTest to ensure internal model creation behavior is properly tested. Optimize imports by using shortened Livewire attribute references and removing unused imports.
This commit is contained in:
1 parent
71cde5a063
commit
1da1f32f0e
41 files changed
+265
-145
No files matched your search
@@ -22,25 +22,25 @@ use Visus\Cuid2\Cuid2;
|
||||
*
|
||||
* @param string $composeYaml The raw Docker Compose YAML content
|
||||
*
|
||||
* @throws \Exception If the compose file contains command injection attempts
|
||||
* @throws Exception If the compose file contains command injection attempts
|
||||
*/
|
||||
function validateDockerComposeForInjection(string $composeYaml): void
|
||||
{
|
||||
try {
|
||||
$parsed = Yaml::parse($composeYaml);
|
||||
} catch (\Exception $e) {
|
||||
throw new \Exception('Invalid YAML format: '.$e->getMessage(), 0, $e);
|
||||
} catch (Exception $e) {
|
||||
throw new Exception('Invalid YAML format: '.$e->getMessage(), 0, $e);
|
||||
}
|
||||
|
||||
if (! is_array($parsed) || ! isset($parsed['services']) || ! is_array($parsed['services'])) {
|
||||
throw new \Exception('Docker Compose file must contain a "services" section');
|
||||
throw new Exception('Docker Compose file must contain a "services" section');
|
||||
}
|
||||
// Validate service names
|
||||
foreach ($parsed['services'] as $serviceName => $serviceConfig) {
|
||||
try {
|
||||
validateShellSafePath($serviceName, 'service name');
|
||||
} catch (\Exception $e) {
|
||||
throw new \Exception(
|
||||
} catch (Exception $e) {
|
||||
throw new Exception(
|
||||
'Invalid Docker Compose service name: '.$e->getMessage().
|
||||
' Service names must not contain shell metacharacters.',
|
||||
0,
|
||||
@@ -68,8 +68,8 @@ function validateDockerComposeForInjection(string $composeYaml): void
|
||||
if (! $isSimpleEnvVar && ! $isEnvVarWithDefault && ! $isEnvVarWithPath) {
|
||||
try {
|
||||
validateShellSafePath($source, 'volume source');
|
||||
} catch (\Exception $e) {
|
||||
throw new \Exception(
|
||||
} catch (Exception $e) {
|
||||
throw new Exception(
|
||||
'Invalid Docker volume definition (array syntax): '.$e->getMessage().
|
||||
' Please use safe path names without shell metacharacters.',
|
||||
0,
|
||||
@@ -84,8 +84,8 @@ function validateDockerComposeForInjection(string $composeYaml): void
|
||||
if (is_string($target)) {
|
||||
try {
|
||||
validateShellSafePath($target, 'volume target');
|
||||
} catch (\Exception $e) {
|
||||
throw new \Exception(
|
||||
} catch (Exception $e) {
|
||||
throw new Exception(
|
||||
'Invalid Docker volume definition (array syntax): '.$e->getMessage().
|
||||
' Please use safe path names without shell metacharacters.',
|
||||
0,
|
||||
@@ -105,7 +105,7 @@ function validateDockerComposeForInjection(string $composeYaml): void
|
||||
*
|
||||
* @param string $volumeString The volume string to validate
|
||||
*
|
||||
* @throws \Exception If the volume string contains command injection attempts
|
||||
* @throws Exception If the volume string contains command injection attempts
|
||||
*/
|
||||
function validateVolumeStringForInjection(string $volumeString): void
|
||||
{
|
||||
@@ -325,9 +325,9 @@ function parseDockerVolumeString(string $volumeString): array
|
||||
if (! $isSimpleEnvVar && ! $isEnvVarWithPath) {
|
||||
try {
|
||||
validateShellSafePath($sourceStr, 'volume source');
|
||||
} catch (\Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
// Re-throw with more context about the volume string
|
||||
throw new \Exception(
|
||||
throw new Exception(
|
||||
'Invalid Docker volume definition: '.$e->getMessage().
|
||||
' Please use safe path names without shell metacharacters.'
|
||||
);
|
||||
@@ -343,8 +343,8 @@ function parseDockerVolumeString(string $volumeString): array
|
||||
// Still, defense in depth is important
|
||||
try {
|
||||
validateShellSafePath($targetStr, 'volume target');
|
||||
} catch (\Exception $e) {
|
||||
throw new \Exception(
|
||||
} catch (Exception $e) {
|
||||
throw new Exception(
|
||||
'Invalid Docker volume definition: '.$e->getMessage().
|
||||
' Please use safe path names without shell metacharacters.'
|
||||
);
|
||||
@@ -375,7 +375,7 @@ function applicationParser(Application $resource, int $pull_request_id = 0, ?int
|
||||
|
||||
try {
|
||||
$yaml = Yaml::parse($compose);
|
||||
} catch (\Exception) {
|
||||
} catch (Exception) {
|
||||
return collect([]);
|
||||
}
|
||||
$services = data_get($yaml, 'services', collect([]));
|
||||
@@ -409,8 +409,8 @@ function applicationParser(Application $resource, int $pull_request_id = 0, ?int
|
||||
// Validate service name for command injection
|
||||
try {
|
||||
validateShellSafePath($serviceName, 'service name');
|
||||
} catch (\Exception $e) {
|
||||
throw new \Exception(
|
||||
} catch (Exception $e) {
|
||||
throw new Exception(
|
||||
'Invalid Docker Compose service name: '.$e->getMessage().
|
||||
' Service names must not contain shell metacharacters.'
|
||||
);
|
||||
@@ -465,7 +465,7 @@ function applicationParser(Application $resource, int $pull_request_id = 0, ?int
|
||||
$fqdn = generateFqdn(server: $server, random: "$uuid", parserVersion: $resource->compose_parsing_version);
|
||||
}
|
||||
|
||||
if ($value && get_class($value) === \Illuminate\Support\Stringable::class && $value->startsWith('/')) {
|
||||
if ($value && get_class($value) === Illuminate\Support\Stringable::class && $value->startsWith('/')) {
|
||||
$path = $value->value();
|
||||
if ($path !== '/') {
|
||||
$fqdn = "$fqdn$path";
|
||||
@@ -738,8 +738,8 @@ function applicationParser(Application $resource, int $pull_request_id = 0, ?int
|
||||
if (! $isSimpleEnvVar && ! $isEnvVarWithDefault && ! $isEnvVarWithPath) {
|
||||
try {
|
||||
validateShellSafePath($sourceValue, 'volume source');
|
||||
} catch (\Exception $e) {
|
||||
throw new \Exception(
|
||||
} catch (Exception $e) {
|
||||
throw new Exception(
|
||||
'Invalid Docker volume definition (array syntax): '.$e->getMessage().
|
||||
' Please use safe path names without shell metacharacters.'
|
||||
);
|
||||
@@ -749,8 +749,8 @@ function applicationParser(Application $resource, int $pull_request_id = 0, ?int
|
||||
if ($target !== null && ! empty($target->value())) {
|
||||
try {
|
||||
validateShellSafePath($target->value(), 'volume target');
|
||||
} catch (\Exception $e) {
|
||||
throw new \Exception(
|
||||
} catch (Exception $e) {
|
||||
throw new Exception(
|
||||
'Invalid Docker volume definition (array syntax): '.$e->getMessage().
|
||||
' Please use safe path names without shell metacharacters.'
|
||||
);
|
||||
@@ -1489,7 +1489,7 @@ function applicationParser(Application $resource, int $pull_request_id = 0, ?int
|
||||
}
|
||||
}
|
||||
$resource->docker_compose_raw = Yaml::dump($originalYaml, 10, 2);
|
||||
} catch (\Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
// If parsing fails, keep the original docker_compose_raw unchanged
|
||||
ray('Failed to update docker_compose_raw in applicationParser: '.$e->getMessage());
|
||||
}
|
||||
@@ -1519,7 +1519,7 @@ function serviceParser(Service $resource): Collection
|
||||
|
||||
try {
|
||||
$yaml = Yaml::parse($compose);
|
||||
} catch (\Exception) {
|
||||
} catch (Exception) {
|
||||
return collect([]);
|
||||
}
|
||||
$services = data_get($yaml, 'services', collect([]));
|
||||
@@ -1566,8 +1566,8 @@ function serviceParser(Service $resource): Collection
|
||||
// Validate service name for command injection
|
||||
try {
|
||||
validateShellSafePath($serviceName, 'service name');
|
||||
} catch (\Exception $e) {
|
||||
throw new \Exception(
|
||||
} catch (Exception $e) {
|
||||
throw new Exception(
|
||||
'Invalid Docker Compose service name: '.$e->getMessage().
|
||||
' Service names must not contain shell metacharacters.'
|
||||
);
|
||||
@@ -1593,20 +1593,25 @@ function serviceParser(Service $resource): Collection
|
||||
// Use image detection for non-migrated services
|
||||
$isDatabase = isDatabaseImage($image, $service);
|
||||
if ($isDatabase) {
|
||||
$applicationFound = ServiceApplication::where('name', $serviceName)->where('service_id', $resource->id)->first();
|
||||
if ($applicationFound) {
|
||||
$savedService = $applicationFound;
|
||||
$databaseFound = ServiceDatabase::where('name', $serviceName)->where('service_id', $resource->id)->first();
|
||||
if ($databaseFound) {
|
||||
$savedService = $databaseFound;
|
||||
} else {
|
||||
$savedService = ServiceDatabase::firstOrCreate([
|
||||
$savedService = ServiceDatabase::forceCreate([
|
||||
'name' => $serviceName,
|
||||
'service_id' => $resource->id,
|
||||
]);
|
||||
}
|
||||
} else {
|
||||
$savedService = ServiceApplication::firstOrCreate([
|
||||
'name' => $serviceName,
|
||||
'service_id' => $resource->id,
|
||||
]);
|
||||
$applicationFound = ServiceApplication::where('name', $serviceName)->where('service_id', $resource->id)->first();
|
||||
if ($applicationFound) {
|
||||
$savedService = $applicationFound;
|
||||
} else {
|
||||
$savedService = ServiceApplication::forceCreate([
|
||||
'name' => $serviceName,
|
||||
'service_id' => $resource->id,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Update image if it changed
|
||||
@@ -1772,7 +1777,7 @@ function serviceParser(Service $resource): Collection
|
||||
// Strip scheme for environment variable values
|
||||
$fqdnValueForEnv = str($fqdn)->after('://')->value();
|
||||
|
||||
if ($value && get_class($value) === \Illuminate\Support\Stringable::class && $value->startsWith('/')) {
|
||||
if ($value && get_class($value) === Illuminate\Support\Stringable::class && $value->startsWith('/')) {
|
||||
$path = $value->value();
|
||||
if ($path !== '/') {
|
||||
// Only add path if it's not already present (prevents duplication on subsequent parse() calls)
|
||||
@@ -2120,8 +2125,8 @@ function serviceParser(Service $resource): Collection
|
||||
if (! $isSimpleEnvVar && ! $isEnvVarWithDefault && ! $isEnvVarWithPath) {
|
||||
try {
|
||||
validateShellSafePath($sourceValue, 'volume source');
|
||||
} catch (\Exception $e) {
|
||||
throw new \Exception(
|
||||
} catch (Exception $e) {
|
||||
throw new Exception(
|
||||
'Invalid Docker volume definition (array syntax): '.$e->getMessage().
|
||||
' Please use safe path names without shell metacharacters.'
|
||||
);
|
||||
@@ -2131,8 +2136,8 @@ function serviceParser(Service $resource): Collection
|
||||
if ($target !== null && ! empty($target->value())) {
|
||||
try {
|
||||
validateShellSafePath($target->value(), 'volume target');
|
||||
} catch (\Exception $e) {
|
||||
throw new \Exception(
|
||||
} catch (Exception $e) {
|
||||
throw new Exception(
|
||||
'Invalid Docker volume definition (array syntax): '.$e->getMessage().
|
||||
' Please use safe path names without shell metacharacters.'
|
||||
);
|
||||
@@ -2741,7 +2746,7 @@ function serviceParser(Service $resource): Collection
|
||||
}
|
||||
}
|
||||
$resource->docker_compose_raw = Yaml::dump($originalYaml, 10, 2);
|
||||
} catch (\Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
// If parsing fails, keep the original docker_compose_raw unchanged
|
||||
ray('Failed to update docker_compose_raw in serviceParser: '.$e->getMessage());
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user