requireAdmin($this->auth, $this->session, $request)) !== null) { return $response; } // Stellt sicher, dass die Standarddomain existiert. $this->domains->defaultDomain($this->config->baseUrl()); // Ergebnis einer eben angestossenen Pruefung einmalig anzeigen. $checkResult = $this->session->get('_domain_check'); $this->session->remove('_domain_check'); return $this->html('domains/index', [ 'domains' => $this->domains->all(), 'groups' => $this->groups->all(), 'requestHost' => ShortDomain::normalizeRequestHost((string) ($request->server['HTTP_HOST'] ?? '')), 'checkResult' => is_array($checkResult) ? $checkResult : null, 'pageTitle' => 'Domains', ]); } /** * Prueft, ob die Domain tatsaechlich bei dieser Installation ankommt. * * @param array $args */ public function check(Request $request, array $args = []): Response { if (($response = $this->requireAdmin($this->auth, $this->session, $request)) !== null) { return $response; } if (($response = $this->requireCsrf($this->csrf, $request)) !== null) { return $response; } $domain = $this->domains->find((int) ($args['id'] ?? 0)); if ($domain === null) { return $this->domainNotFound(); } $this->session->set('_domain_check', [ 'domain_id' => (int) $domain['id'], 'domain' => ShortDomain::displayName((string) $domain['base_url']), 'result' => $this->checker->check($domain), ]); return $this->redirect('/admin/domains'); } /** * Oeffentlicher Endpunkt, den die Pruefung von aussen aufruft. * * Ohne gueltiges, kurzlebiges Token antwortet er wie eine beliebige * unbekannte Adresse - es wird also nichts ueber die Installation * preisgegeben. Kommt ein gueltiges Token an, ist damit bewiesen, * dass der Aufruf hier gelandet ist. */ public function verify(Request $request): Response { if (!CheckToken::isValid($request->query('token'), $this->settings->secret())) { return Response::html('Not Found', 404); } return Response::json(['ok' => true]) ->withHeader('Cache-Control', 'no-store'); } public function create(Request $request): Response { if (($response = $this->requireAdmin($this->auth, $this->session, $request)) !== null) { return $response; } return $this->html('domains/form', [ 'domain' => null, 'groups' => $this->groups->all(), 'values' => [ 'base_url' => '', 'label' => '', 'is_default' => '0', 'group_id' => (string) $this->groups->defaultGroupId(), ], 'errors' => [], 'pageTitle' => 'Neue Domain', ]); } public function store(Request $request): Response { if (($response = $this->requireAdmin($this->auth, $this->session, $request)) !== null) { return $response; } if (($response = $this->requireCsrf($this->csrf, $request)) !== null) { return $response; } $values = $this->readValues($request); $baseUrl = ShortDomain::normalizeBaseUrl($values['base_url']); $errors = $this->validate($baseUrl); if ($errors === [] && $this->domains->hostExists(ShortDomain::hostOf($baseUrl))) { $errors['base_url'] = 'Diese Domain ist bereits eingetragen.'; } $groupId = $this->resolveGroupId($values['group_id'], $errors); if ($errors !== []) { return $this->html('domains/form', [ 'domain' => null, 'groups' => $this->groups->all(), 'values' => $values, 'errors' => $errors, 'pageTitle' => 'Neue Domain', ], 422); } // Die erste Domain ist zwangslaeufig die Standarddomain. $isDefault = $values['is_default'] === '1' || $this->domains->count() === 0; $this->domains->create($baseUrl, $values['label'] !== '' ? $values['label'] : null, $isDefault, $groupId); $this->session->flash('success', sprintf( 'Domain "%s" wurde angelegt. Bitte daran denken, sie im DNS und beim Webserver auf diese Installation zu zeigen.', ShortDomain::displayName($baseUrl), )); return $this->redirect('/admin/domains'); } /** * @param array $args */ public function edit(Request $request, array $args = []): Response { if (($response = $this->requireAdmin($this->auth, $this->session, $request)) !== null) { return $response; } $domain = $this->domains->find((int) ($args['id'] ?? 0)); if ($domain === null) { return $this->domainNotFound(); } return $this->html('domains/form', [ 'domain' => $domain, 'groups' => $this->groups->all(), 'values' => [ 'base_url' => (string) $domain['base_url'], 'label' => (string) ($domain['label'] ?? ''), 'is_default' => ((int) $domain['is_default'] === 1) ? '1' : '0', 'group_id' => (string) $domain['group_id'], ], 'errors' => [], 'pageTitle' => 'Domain bearbeiten', ]); } /** * @param array $args */ public function update(Request $request, array $args = []): Response { if (($response = $this->requireAdmin($this->auth, $this->session, $request)) !== null) { return $response; } if (($response = $this->requireCsrf($this->csrf, $request)) !== null) { return $response; } $id = (int) ($args['id'] ?? 0); $domain = $this->domains->find($id); if ($domain === null) { return $this->domainNotFound(); } $values = $this->readValues($request); $baseUrl = ShortDomain::normalizeBaseUrl($values['base_url']); $errors = $this->validate($baseUrl); if ($errors === [] && $this->domains->hostExists(ShortDomain::hostOf($baseUrl), $id)) { $errors['base_url'] = 'Diese Domain ist bereits eingetragen.'; } $groupId = $this->resolveGroupId($values['group_id'], $errors); if ($errors !== []) { return $this->html('domains/form', [ 'domain' => $domain, 'groups' => $this->groups->all(), 'values' => $values, 'errors' => $errors, 'pageTitle' => 'Domain bearbeiten', ], 422); } $this->domains->update($id, $baseUrl, $values['label'] !== '' ? $values['label'] : null, $groupId); if ($values['is_default'] === '1') { $this->domains->makeDefault($id); } $this->session->flash('success', 'Die Domain wurde gespeichert.'); return $this->redirect('/admin/domains'); } /** * @param array $args */ public function makeDefault(Request $request, array $args = []): Response { if (($response = $this->requireAdmin($this->auth, $this->session, $request)) !== null) { return $response; } if (($response = $this->requireCsrf($this->csrf, $request)) !== null) { return $response; } $domain = $this->domains->find((int) ($args['id'] ?? 0)); if ($domain === null) { return $this->domainNotFound(); } $this->domains->makeDefault((int) $domain['id']); $this->session->flash('success', sprintf( '"%s" ist jetzt die Standarddomain.', ShortDomain::displayName((string) $domain['base_url']), )); return $this->redirect('/admin/domains'); } /** * @param array $args */ public function destroy(Request $request, array $args = []): Response { if (($response = $this->requireAdmin($this->auth, $this->session, $request)) !== null) { return $response; } if (($response = $this->requireCsrf($this->csrf, $request)) !== null) { return $response; } $domain = $this->domains->find((int) ($args['id'] ?? 0)); if ($domain === null) { return $this->domainNotFound(); } $id = (int) $domain['id']; $name = ShortDomain::displayName((string) $domain['base_url']); if ((int) $domain['is_default'] === 1) { $this->session->flash( 'error', 'Die Standarddomain kann nicht gelöscht werden. Bitte zuerst eine andere Domain als Standard festlegen.', ); return $this->redirect('/admin/domains'); } $linkCount = $this->domains->linkCount($id); if ($linkCount > 0) { $this->session->flash('error', sprintf( 'An "%s" hängen noch %d Kurzlink(s). Bitte diese zuerst löschen oder auf eine andere Domain umstellen.', $name, $linkCount, )); return $this->redirect('/admin/domains'); } $this->domains->delete($id); $this->session->flash('success', sprintf('Domain "%s" wurde gelöscht.', $name)); return $this->redirect('/admin/domains'); } /** * @return array */ private function validate(string $baseUrl): array { $error = ShortDomain::validationError($baseUrl); return $error === null ? [] : ['base_url' => $error]; } /** * Prueft die gewaehlte Gruppe. Ohne Angabe gilt die Standardgruppe - * eine Domain ohne Gruppe waere sonst fuer niemanden ausser * Administratoren nutzbar. * * @param array $errors */ private function resolveGroupId(string $value, array &$errors): int { if ($value === '') { return $this->groups->defaultGroupId(); } $group = $this->groups->find((int) $value); if ($group === null) { $errors['group_id'] = 'Bitte eine gültige Gruppe auswählen.'; return $this->groups->defaultGroupId(); } return (int) $group['id']; } /** * @return array{base_url:string,label:string,is_default:string,group_id:string} */ private function readValues(Request $request): array { return [ 'base_url' => $request->post('base_url'), 'label' => mb_substr($request->post('label'), 0, 255), 'is_default' => $request->hasPost('is_default') ? '1' : '0', 'group_id' => $request->post('group_id'), ]; } private function domainNotFound(): Response { return $this->html('errors/error', [ 'title' => 'Domain nicht gefunden', 'message' => 'Die gewünschte Domain existiert nicht (mehr).', 'pageTitle' => 'Nicht gefunden', ], 404); } }