mirror of
https://github.com/coollabsio/coolify.git
synced 2026-08-24 10:05:47 -05:00
163 lines
4.2 KiB
PHP
163 lines
4.2 KiB
PHP
<?php
|
|
|
|
namespace App\Models;
|
|
|
|
use App\Traits\Auditable;
|
|
use Illuminate\Contracts\Encryption\DecryptException;
|
|
use Illuminate\Database\Eloquent\Casts\Attribute;
|
|
use Illuminate\Support\Facades\Crypt;
|
|
|
|
class GitlabApp extends BaseModel
|
|
{
|
|
use Auditable;
|
|
|
|
protected $fillable = [
|
|
'name',
|
|
'organization',
|
|
'api_url',
|
|
'html_url',
|
|
'custom_port',
|
|
'custom_user',
|
|
'is_system_wide',
|
|
'is_public',
|
|
'app_id',
|
|
'app_secret',
|
|
'oauth_id',
|
|
'client_id',
|
|
'client_secret',
|
|
'access_token',
|
|
'refresh_token',
|
|
'expires_at',
|
|
'redirect_uri',
|
|
'group_name',
|
|
'public_key',
|
|
'webhook_token',
|
|
'deploy_key_id',
|
|
'private_key_id',
|
|
'team_id',
|
|
];
|
|
|
|
protected $hidden = [
|
|
'webhook_token',
|
|
'app_secret',
|
|
'client_secret',
|
|
'access_token',
|
|
'refresh_token',
|
|
];
|
|
|
|
protected function casts(): array
|
|
{
|
|
return [
|
|
'access_token' => 'encrypted',
|
|
'refresh_token' => 'encrypted',
|
|
'client_secret' => 'encrypted',
|
|
'is_system_wide' => 'boolean',
|
|
'is_public' => 'boolean',
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Encrypt webhook tokens at rest. Supports legacy plaintext values until they are re-saved.
|
|
* Not a standard encrypted cast: webhooks look up by token value (see findByWebhookToken).
|
|
*/
|
|
protected function webhookToken(): Attribute
|
|
{
|
|
return Attribute::make(
|
|
get: function (?string $value): ?string {
|
|
if ($value === null || $value === '') {
|
|
return $value;
|
|
}
|
|
|
|
try {
|
|
return Crypt::decryptString($value);
|
|
} catch (DecryptException) {
|
|
// Legacy rows stored the token in plaintext.
|
|
return $value;
|
|
}
|
|
},
|
|
set: function (?string $value): ?string {
|
|
if ($value === null || $value === '') {
|
|
return $value;
|
|
}
|
|
|
|
return Crypt::encryptString($value);
|
|
},
|
|
);
|
|
}
|
|
|
|
public static function findByWebhookToken(string $token): ?self
|
|
{
|
|
if ($token === '') {
|
|
return null;
|
|
}
|
|
|
|
// Encrypted values cannot be matched with a SQL equality; sources are few per instance.
|
|
return static::query()->get()->first(
|
|
fn (self $app): bool => filled($app->webhook_token) && hash_equals((string) $app->webhook_token, $token)
|
|
);
|
|
}
|
|
|
|
protected static function booted(): void
|
|
{
|
|
static::deleting(function (GitlabApp $gitlabApp) {
|
|
if ($gitlabApp->applications()->count() > 0) {
|
|
throw new \RuntimeException('This source is being used by an application. Please delete all applications first.');
|
|
}
|
|
|
|
});
|
|
}
|
|
|
|
public static function ownedByCurrentTeam()
|
|
{
|
|
return GitlabApp::where(function ($query) {
|
|
$query->where('team_id', currentTeam()->id)
|
|
->orWhere('is_system_wide', true);
|
|
});
|
|
}
|
|
|
|
public static function public()
|
|
{
|
|
return GitlabApp::where(function ($query) {
|
|
$query->where('team_id', currentTeam()->id)->orWhere('is_system_wide', true);
|
|
})->where('is_public', true);
|
|
}
|
|
|
|
public static function private()
|
|
{
|
|
return GitlabApp::where(function ($query) {
|
|
$query->where('team_id', currentTeam()->id)->orWhere('is_system_wide', true);
|
|
})->where('is_public', false)->whereNotNull('access_token');
|
|
}
|
|
|
|
public function applications()
|
|
{
|
|
return $this->morphMany(Application::class, 'source');
|
|
}
|
|
|
|
public function privateKey()
|
|
{
|
|
return $this->belongsTo(PrivateKey::class);
|
|
}
|
|
|
|
public function team()
|
|
{
|
|
return $this->belongsTo(Team::class);
|
|
}
|
|
|
|
public function isConnected(): bool
|
|
{
|
|
return ! empty($this->access_token) && ! empty($this->refresh_token);
|
|
}
|
|
|
|
public function apiUrlBase(): string
|
|
{
|
|
$apiUrl = rtrim($this->api_url, '/');
|
|
|
|
if (! str_contains($apiUrl, '/api/v4')) {
|
|
$apiUrl .= '/api/v4';
|
|
}
|
|
|
|
return $apiUrl;
|
|
}
|
|
}
|