mirror of
https://github.com/tiennm99/coolify.git
synced 2026-10-14 08:18:08 +00:00
fix(models): replace forceFill/forceCreate with fill/create and add fillable guards
Replace all uses of `forceFill`, `forceCreate`, and `forceFill` with their non-force equivalents across models, actions, controllers, and Livewire components. Add explicit `$fillable` arrays to all affected Eloquent models to enforce mass assignment protection. Add ModelFillableCreationTest and ModelFillableRegressionTest to verify that model creation respects fillable constraints and prevent regressions.
This commit is contained in:
1 parent
047aff1c82
commit
1a603a10ed
79 files changed
+1411
-142
No files matched your search
@@ -203,6 +203,14 @@ class Application extends BaseModel
|
||||
'restart_count',
|
||||
'last_restart_at',
|
||||
'last_restart_type',
|
||||
'uuid',
|
||||
'environment_id',
|
||||
'destination_id',
|
||||
'destination_type',
|
||||
'source_id',
|
||||
'source_type',
|
||||
'repository_project_id',
|
||||
'private_key_id',
|
||||
];
|
||||
|
||||
protected $appends = ['server_status'];
|
||||
@@ -262,7 +270,7 @@ class Application extends BaseModel
|
||||
}
|
||||
}
|
||||
if (count($payload) > 0) {
|
||||
$application->forceFill($payload);
|
||||
$application->fill($payload);
|
||||
}
|
||||
|
||||
// Buildpack switching cleanup logic
|
||||
@@ -299,7 +307,7 @@ class Application extends BaseModel
|
||||
}
|
||||
});
|
||||
static::created(function ($application) {
|
||||
ApplicationSetting::forceCreate([
|
||||
ApplicationSetting::create([
|
||||
'application_id' => $application->id,
|
||||
]);
|
||||
$application->compose_parsing_version = self::$parserVersion;
|
||||
|
||||
@@ -44,6 +44,7 @@ class ApplicationDeploymentQueue extends Model
|
||||
'application_id',
|
||||
'deployment_uuid',
|
||||
'pull_request_id',
|
||||
'docker_registry_image_tag',
|
||||
'force_rebuild',
|
||||
'commit',
|
||||
'status',
|
||||
|
||||
@@ -11,6 +11,7 @@ class ApplicationPreview extends BaseModel
|
||||
use SoftDeletes;
|
||||
|
||||
protected $fillable = [
|
||||
'uuid',
|
||||
'application_id',
|
||||
'pull_request_id',
|
||||
'pull_request_html_url',
|
||||
@@ -62,7 +63,7 @@ class ApplicationPreview extends BaseModel
|
||||
});
|
||||
static::saving(function ($preview) {
|
||||
if ($preview->isDirty('status')) {
|
||||
$preview->forceFill(['last_online_at' => now()]);
|
||||
$preview->last_online_at = now();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ class ApplicationSetting extends Model
|
||||
];
|
||||
|
||||
protected $fillable = [
|
||||
'application_id',
|
||||
'is_static',
|
||||
'is_git_submodules_enabled',
|
||||
'is_git_lfs_enabled',
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace App\Models;
|
||||
class CloudProviderToken extends BaseModel
|
||||
{
|
||||
protected $fillable = [
|
||||
'team_id',
|
||||
'provider',
|
||||
'token',
|
||||
'name',
|
||||
|
||||
@@ -28,6 +28,8 @@ class Environment extends BaseModel
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'description',
|
||||
'project_id',
|
||||
'uuid',
|
||||
];
|
||||
|
||||
protected static function booted()
|
||||
|
||||
@@ -7,6 +7,8 @@ use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
class GithubApp extends BaseModel
|
||||
{
|
||||
protected $fillable = [
|
||||
'team_id',
|
||||
'private_key_id',
|
||||
'name',
|
||||
'organization',
|
||||
'api_url',
|
||||
|
||||
@@ -27,6 +27,8 @@ class Project extends BaseModel
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'description',
|
||||
'team_id',
|
||||
'uuid',
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -51,10 +53,10 @@ class Project extends BaseModel
|
||||
protected static function booted()
|
||||
{
|
||||
static::created(function ($project) {
|
||||
ProjectSetting::forceCreate([
|
||||
ProjectSetting::create([
|
||||
'project_id' => $project->id,
|
||||
]);
|
||||
Environment::forceCreate([
|
||||
Environment::create([
|
||||
'name' => 'production',
|
||||
'project_id' => $project->id,
|
||||
'uuid' => (string) new Cuid2,
|
||||
|
||||
@@ -6,7 +6,9 @@ use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class ProjectSetting extends Model
|
||||
{
|
||||
protected $fillable = [];
|
||||
protected $fillable = [
|
||||
'project_id',
|
||||
];
|
||||
|
||||
public function project()
|
||||
{
|
||||
|
||||
@@ -9,6 +9,8 @@ use Illuminate\Database\Eloquent\Relations\MorphTo;
|
||||
class ScheduledDatabaseBackup extends BaseModel
|
||||
{
|
||||
protected $fillable = [
|
||||
'uuid',
|
||||
'team_id',
|
||||
'description',
|
||||
'enabled',
|
||||
'save_s3',
|
||||
|
||||
@@ -7,6 +7,8 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
class ScheduledDatabaseBackupExecution extends BaseModel
|
||||
{
|
||||
protected $fillable = [
|
||||
'uuid',
|
||||
'scheduled_database_backup_id',
|
||||
'status',
|
||||
'message',
|
||||
'size',
|
||||
|
||||
@@ -30,12 +30,16 @@ class ScheduledTask extends BaseModel
|
||||
use HasSafeStringAttribute;
|
||||
|
||||
protected $fillable = [
|
||||
'uuid',
|
||||
'enabled',
|
||||
'name',
|
||||
'command',
|
||||
'frequency',
|
||||
'container',
|
||||
'timeout',
|
||||
'team_id',
|
||||
'application_id',
|
||||
'service_id',
|
||||
];
|
||||
|
||||
public static function ownedByCurrentTeamAPI(int $teamId)
|
||||
|
||||
@@ -23,6 +23,7 @@ use OpenApi\Attributes as OA;
|
||||
class ScheduledTaskExecution extends BaseModel
|
||||
{
|
||||
protected $fillable = [
|
||||
'scheduled_task_id',
|
||||
'status',
|
||||
'message',
|
||||
'finished_at',
|
||||
|
||||
@@ -135,7 +135,7 @@ class Server extends BaseModel
|
||||
$payload['ip_previous'] = $server->getOriginal('ip');
|
||||
}
|
||||
}
|
||||
$server->forceFill($payload);
|
||||
$server->fill($payload);
|
||||
});
|
||||
static::saved(function ($server) {
|
||||
if ($server->wasChanged('private_key_id') || $server->privateKey?->isDirty()) {
|
||||
@@ -265,6 +265,7 @@ class Server extends BaseModel
|
||||
'detected_traefik_version',
|
||||
'traefik_outdated_info',
|
||||
'server_metadata',
|
||||
'ip_previous',
|
||||
];
|
||||
|
||||
use HasSafeStringAttribute;
|
||||
|
||||
@@ -54,6 +54,7 @@ use OpenApi\Attributes as OA;
|
||||
class ServerSetting extends Model
|
||||
{
|
||||
protected $fillable = [
|
||||
'server_id',
|
||||
'is_swarm_manager',
|
||||
'is_jump_server',
|
||||
'is_build_server',
|
||||
|
||||
@@ -49,6 +49,7 @@ class Service extends BaseModel
|
||||
private static $parserVersion = '5';
|
||||
|
||||
protected $fillable = [
|
||||
'uuid',
|
||||
'name',
|
||||
'description',
|
||||
'docker_compose_raw',
|
||||
@@ -58,6 +59,10 @@ class Service extends BaseModel
|
||||
'config_hash',
|
||||
'compose_parsing_version',
|
||||
'is_container_label_escape_enabled',
|
||||
'environment_id',
|
||||
'server_id',
|
||||
'destination_id',
|
||||
'destination_type',
|
||||
];
|
||||
|
||||
protected $appends = ['server_status', 'status'];
|
||||
|
||||
@@ -12,6 +12,7 @@ class ServiceApplication extends BaseModel
|
||||
use HasFactory, SoftDeletes;
|
||||
|
||||
protected $fillable = [
|
||||
'service_id',
|
||||
'name',
|
||||
'human_name',
|
||||
'description',
|
||||
@@ -39,7 +40,7 @@ class ServiceApplication extends BaseModel
|
||||
});
|
||||
static::saving(function ($service) {
|
||||
if ($service->isDirty('status')) {
|
||||
$service->forceFill(['last_online_at' => now()]);
|
||||
$service->last_online_at = now();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ class ServiceDatabase extends BaseModel
|
||||
use HasFactory, SoftDeletes;
|
||||
|
||||
protected $fillable = [
|
||||
'service_id',
|
||||
'name',
|
||||
'human_name',
|
||||
'description',
|
||||
@@ -44,7 +45,7 @@ class ServiceDatabase extends BaseModel
|
||||
});
|
||||
static::saving(function ($service) {
|
||||
if ($service->isDirty('status')) {
|
||||
$service->forceFill(['last_online_at' => now()]);
|
||||
$service->last_online_at = now();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ class StandaloneClickhouse extends BaseModel
|
||||
use ClearsGlobalSearchCache, HasFactory, HasMetrics, HasSafeStringAttribute, SoftDeletes;
|
||||
|
||||
protected $fillable = [
|
||||
'uuid',
|
||||
'name',
|
||||
'description',
|
||||
'clickhouse_admin_user',
|
||||
@@ -40,6 +41,9 @@ class StandaloneClickhouse extends BaseModel
|
||||
'public_port_timeout',
|
||||
'custom_docker_run_options',
|
||||
'clickhouse_db',
|
||||
'destination_type',
|
||||
'destination_id',
|
||||
'environment_id',
|
||||
];
|
||||
|
||||
protected $appends = ['internal_db_url', 'external_db_url', 'database_type', 'server_status'];
|
||||
@@ -71,7 +75,7 @@ class StandaloneClickhouse extends BaseModel
|
||||
});
|
||||
static::saving(function ($database) {
|
||||
if ($database->isDirty('status')) {
|
||||
$database->forceFill(['last_online_at' => now()]);
|
||||
$database->last_online_at = now();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ class StandaloneDocker extends BaseModel
|
||||
use HasSafeStringAttribute;
|
||||
|
||||
protected $fillable = [
|
||||
'server_id',
|
||||
'name',
|
||||
'network',
|
||||
];
|
||||
|
||||
@@ -14,6 +14,7 @@ class StandaloneDragonfly extends BaseModel
|
||||
use ClearsGlobalSearchCache, HasFactory, HasMetrics, HasSafeStringAttribute, SoftDeletes;
|
||||
|
||||
protected $fillable = [
|
||||
'uuid',
|
||||
'name',
|
||||
'description',
|
||||
'dragonfly_password',
|
||||
@@ -39,6 +40,9 @@ class StandaloneDragonfly extends BaseModel
|
||||
'public_port_timeout',
|
||||
'enable_ssl',
|
||||
'custom_docker_run_options',
|
||||
'destination_type',
|
||||
'destination_id',
|
||||
'environment_id',
|
||||
];
|
||||
|
||||
protected $appends = ['internal_db_url', 'external_db_url', 'database_type', 'server_status'];
|
||||
@@ -70,7 +74,7 @@ class StandaloneDragonfly extends BaseModel
|
||||
});
|
||||
static::saving(function ($database) {
|
||||
if ($database->isDirty('status')) {
|
||||
$database->forceFill(['last_online_at' => now()]);
|
||||
$database->last_online_at = now();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ class StandaloneKeydb extends BaseModel
|
||||
use ClearsGlobalSearchCache, HasFactory, HasMetrics, HasSafeStringAttribute, SoftDeletes;
|
||||
|
||||
protected $fillable = [
|
||||
'uuid',
|
||||
'name',
|
||||
'description',
|
||||
'keydb_password',
|
||||
@@ -40,6 +41,9 @@ class StandaloneKeydb extends BaseModel
|
||||
'public_port_timeout',
|
||||
'enable_ssl',
|
||||
'custom_docker_run_options',
|
||||
'destination_type',
|
||||
'destination_id',
|
||||
'environment_id',
|
||||
];
|
||||
|
||||
protected $appends = ['internal_db_url', 'external_db_url', 'server_status'];
|
||||
@@ -71,7 +75,7 @@ class StandaloneKeydb extends BaseModel
|
||||
});
|
||||
static::saving(function ($database) {
|
||||
if ($database->isDirty('status')) {
|
||||
$database->forceFill(['last_online_at' => now()]);
|
||||
$database->last_online_at = now();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ class StandaloneMariadb extends BaseModel
|
||||
use ClearsGlobalSearchCache, HasFactory, HasMetrics, HasSafeStringAttribute, SoftDeletes;
|
||||
|
||||
protected $fillable = [
|
||||
'uuid',
|
||||
'name',
|
||||
'description',
|
||||
'mariadb_root_password',
|
||||
@@ -43,6 +44,9 @@ class StandaloneMariadb extends BaseModel
|
||||
'enable_ssl',
|
||||
'is_log_drain_enabled',
|
||||
'custom_docker_run_options',
|
||||
'destination_type',
|
||||
'destination_id',
|
||||
'environment_id',
|
||||
];
|
||||
|
||||
protected $appends = ['internal_db_url', 'external_db_url', 'database_type', 'server_status'];
|
||||
@@ -74,7 +78,7 @@ class StandaloneMariadb extends BaseModel
|
||||
});
|
||||
static::saving(function ($database) {
|
||||
if ($database->isDirty('status')) {
|
||||
$database->forceFill(['last_online_at' => now()]);
|
||||
$database->last_online_at = now();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ class StandaloneMongodb extends BaseModel
|
||||
use ClearsGlobalSearchCache, HasFactory, HasMetrics, HasSafeStringAttribute, SoftDeletes;
|
||||
|
||||
protected $fillable = [
|
||||
'uuid',
|
||||
'name',
|
||||
'description',
|
||||
'mongo_conf',
|
||||
@@ -43,6 +44,9 @@ class StandaloneMongodb extends BaseModel
|
||||
'is_log_drain_enabled',
|
||||
'is_include_timestamps',
|
||||
'custom_docker_run_options',
|
||||
'destination_type',
|
||||
'destination_id',
|
||||
'environment_id',
|
||||
];
|
||||
|
||||
protected $appends = ['internal_db_url', 'external_db_url', 'database_type', 'server_status'];
|
||||
@@ -80,7 +84,7 @@ class StandaloneMongodb extends BaseModel
|
||||
});
|
||||
static::saving(function ($database) {
|
||||
if ($database->isDirty('status')) {
|
||||
$database->forceFill(['last_online_at' => now()]);
|
||||
$database->last_online_at = now();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ class StandaloneMysql extends BaseModel
|
||||
use ClearsGlobalSearchCache, HasFactory, HasMetrics, HasSafeStringAttribute, SoftDeletes;
|
||||
|
||||
protected $fillable = [
|
||||
'uuid',
|
||||
'name',
|
||||
'description',
|
||||
'mysql_root_password',
|
||||
@@ -44,6 +45,9 @@ class StandaloneMysql extends BaseModel
|
||||
'is_log_drain_enabled',
|
||||
'is_include_timestamps',
|
||||
'custom_docker_run_options',
|
||||
'destination_type',
|
||||
'destination_id',
|
||||
'environment_id',
|
||||
];
|
||||
|
||||
protected $appends = ['internal_db_url', 'external_db_url', 'database_type', 'server_status'];
|
||||
@@ -76,7 +80,7 @@ class StandaloneMysql extends BaseModel
|
||||
});
|
||||
static::saving(function ($database) {
|
||||
if ($database->isDirty('status')) {
|
||||
$database->forceFill(['last_online_at' => now()]);
|
||||
$database->last_online_at = now();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ class StandalonePostgresql extends BaseModel
|
||||
use ClearsGlobalSearchCache, HasFactory, HasMetrics, HasSafeStringAttribute, SoftDeletes;
|
||||
|
||||
protected $fillable = [
|
||||
'uuid',
|
||||
'name',
|
||||
'description',
|
||||
'postgres_user',
|
||||
@@ -46,6 +47,9 @@ class StandalonePostgresql extends BaseModel
|
||||
'is_log_drain_enabled',
|
||||
'is_include_timestamps',
|
||||
'custom_docker_run_options',
|
||||
'destination_type',
|
||||
'destination_id',
|
||||
'environment_id',
|
||||
];
|
||||
|
||||
protected $appends = ['internal_db_url', 'external_db_url', 'database_type', 'server_status'];
|
||||
@@ -92,7 +96,7 @@ class StandalonePostgresql extends BaseModel
|
||||
});
|
||||
static::saving(function ($database) {
|
||||
if ($database->isDirty('status')) {
|
||||
$database->forceFill(['last_online_at' => now()]);
|
||||
$database->last_online_at = now();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ class StandaloneRedis extends BaseModel
|
||||
use ClearsGlobalSearchCache, HasFactory, HasMetrics, HasSafeStringAttribute, SoftDeletes;
|
||||
|
||||
protected $fillable = [
|
||||
'uuid',
|
||||
'name',
|
||||
'description',
|
||||
'redis_conf',
|
||||
@@ -39,6 +40,9 @@ class StandaloneRedis extends BaseModel
|
||||
'is_log_drain_enabled',
|
||||
'is_include_timestamps',
|
||||
'custom_docker_run_options',
|
||||
'destination_type',
|
||||
'destination_id',
|
||||
'environment_id',
|
||||
];
|
||||
|
||||
protected $appends = ['internal_db_url', 'external_db_url', 'database_type', 'server_status'];
|
||||
@@ -69,7 +73,7 @@ class StandaloneRedis extends BaseModel
|
||||
});
|
||||
static::saving(function ($database) {
|
||||
if ($database->isDirty('status')) {
|
||||
$database->forceFill(['last_online_at' => now()]);
|
||||
$database->last_online_at = now();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ use Illuminate\Database\Eloquent\Model;
|
||||
class Subscription extends Model
|
||||
{
|
||||
protected $fillable = [
|
||||
'team_id',
|
||||
'stripe_invoice_paid',
|
||||
'stripe_subscription_id',
|
||||
'stripe_customer_id',
|
||||
|
||||
@@ -7,6 +7,7 @@ use App\Support\ValidationPatterns;
|
||||
class SwarmDocker extends BaseModel
|
||||
{
|
||||
protected $fillable = [
|
||||
'server_id',
|
||||
'name',
|
||||
'network',
|
||||
];
|
||||
|
||||
@@ -10,6 +10,7 @@ class Tag extends BaseModel
|
||||
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'team_id',
|
||||
];
|
||||
|
||||
protected function customizeName($value)
|
||||
|
||||
+4
-1
@@ -49,6 +49,9 @@ class User extends Authenticatable implements SendsEmail
|
||||
'password',
|
||||
'force_password_reset',
|
||||
'marketing_emails',
|
||||
'pending_email',
|
||||
'email_change_code',
|
||||
'email_change_code_expires_at',
|
||||
];
|
||||
|
||||
protected $hidden = [
|
||||
@@ -409,7 +412,7 @@ class User extends Authenticatable implements SendsEmail
|
||||
$expiryMinutes = config('constants.email_change.verification_code_expiry_minutes', 10);
|
||||
$expiresAt = Carbon::now()->addMinutes($expiryMinutes);
|
||||
|
||||
$this->forceFill([
|
||||
$this->fill([
|
||||
'pending_email' => $newEmail,
|
||||
'email_change_code' => $code,
|
||||
'email_change_code_expires_at' => $expiresAt,
|
||||
|
||||
Reference in new issue
Block a user