CluPilotCloud/app/Models/ProxyHost.php

87 lines
2.7 KiB
PHP

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
/**
* Ein Hostname, den der Reverse Proxy für diese Installation bedienen soll.
*
* Die Zeile ist der Wunsch, nicht der Zustand. Ob der Name wirklich bedient
* wird und ob er ein Zertifikat hat, steht nicht hier — das wird gemessen, an
* dem, was ein Besucher tatsächlich bekommt (siehe CertificateInspector).
*/
class ProxyHost extends Model
{
protected $fillable = ['hostname', 'purpose', 'note', 'source'];
/**
* Aus der Umgebung abgeleitet — nicht von Hand angelegt, also auch nicht
* von Hand zu entfernen: beim nächsten Abgleich käme er wieder, und ein
* Knopf, der nichts bewirkt, ist schlimmer als keiner.
*/
public function isFromConfig(): bool
{
return $this->source === 'config';
}
/** Hat die Prüfung ein gültiges Zertifikat gefunden? */
public function hasCertificate(): bool
{
return $this->certificate_expires_at !== null && $this->certificate_error === null;
}
protected function casts(): array
{
return [
'certificate_expires_at' => 'datetime',
'certificate_checked_at' => 'datetime',
];
}
/**
* Wofür der Name da ist — und damit, was er darf.
*
* `public` — Website, Portal, Status, Dateien. Vom offenen Internet
* erreichbar, Zertifikat über die HTTP-Prüfung.
* `console` — der Adminbereich. Er bekommt die Netzsperre und ist NICHT
* öffentlich; ein Zertifikat holt er trotzdem.
*
* Getrennt, weil ein Name mit dem falschen Zweck genau die Sorte Fehler
* ist, die niemand sieht: die Konsole öffentlich zu stellen sieht aus wie
* eine funktionierende Seite.
*/
public const PURPOSES = ['public', 'console'];
public function isConsole(): bool
{
return $this->purpose === 'console';
}
/** Tage bis zum Ablauf, oder null wenn nichts gemessen wurde. */
public function daysLeft(): ?int
{
if ($this->certificate_expires_at === null) {
return null;
}
// Aufgerundet auf ganze Tage und nie negativ dargestellt: „noch -3 Tage"
// ist keine Auskunft, „abgelaufen" ist eine.
return max(0, (int) now()->diffInDays($this->certificate_expires_at, false));
}
/**
* Läuft es bald ab?
*
* Dreißig Tage, weil Let's Encrypt bei neunzig Tagen Laufzeit nach dreißig
* verbleibenden längst hätte erneuern müssen. Was darunter steht, ist kein
* knappes Zertifikat mehr, sondern eine Erneuerung, die nicht stattfindet.
*/
public function isExpiringSoon(): bool
{
$days = $this->daysLeft();
return $days !== null && $days <= 30;
}
}