243 lines
7.3 KiB
PHP
243 lines
7.3 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Controller\Frontend;
|
|
|
|
use App\Container\EntityManagerAwareTrait;
|
|
use App\Container\EnvironmentAwareTrait;
|
|
use App\Container\SettingsAwareTrait;
|
|
use App\Entity\Repository\RolePermissionRepository;
|
|
use App\Entity\Settings;
|
|
use App\Entity\User;
|
|
use App\Exception\NotLoggedInException;
|
|
use App\Exception\ValidationException;
|
|
use App\Http\Response;
|
|
use App\Http\ServerRequest;
|
|
use App\Version;
|
|
use App\VueComponent\StationFormComponent;
|
|
use InvalidArgumentException;
|
|
use Psr\Http\Message\ResponseInterface;
|
|
use Symfony\Component\Validator\Validator\ValidatorInterface;
|
|
use Throwable;
|
|
|
|
final class SetupController
|
|
{
|
|
use EntityManagerAwareTrait;
|
|
use EnvironmentAwareTrait;
|
|
use SettingsAwareTrait;
|
|
|
|
public function __construct(
|
|
private readonly RolePermissionRepository $permissionRepo,
|
|
private readonly ValidatorInterface $validator,
|
|
private readonly StationFormComponent $stationFormComponent,
|
|
private readonly Version $version
|
|
) {
|
|
}
|
|
|
|
/**
|
|
* Setup Routing Controls
|
|
*
|
|
* @param ServerRequest $request
|
|
* @param Response $response
|
|
*/
|
|
public function indexAction(
|
|
ServerRequest $request,
|
|
Response $response
|
|
): ResponseInterface {
|
|
$current_step = $this->getSetupStep($request);
|
|
return $response->withRedirect($request->getRouter()->named('setup:' . $current_step));
|
|
}
|
|
|
|
/**
|
|
* Setup Step 1:
|
|
* Create Super Administrator Account
|
|
*/
|
|
public function registerAction(
|
|
ServerRequest $request,
|
|
Response $response
|
|
): ResponseInterface {
|
|
// Verify current step.
|
|
$current_step = $this->getSetupStep($request);
|
|
if ($current_step !== 'register' && $this->environment->isProduction()) {
|
|
return $response->withRedirect($request->getRouter()->named('setup:' . $current_step));
|
|
}
|
|
|
|
$csrf = $request->getCsrf();
|
|
|
|
$error = null;
|
|
|
|
if ($request->isPost()) {
|
|
try {
|
|
$data = $request->getParams();
|
|
|
|
$csrf->verify($data['csrf'] ?? null, 'register');
|
|
|
|
if (empty($data['username']) || empty($data['password'])) {
|
|
throw new InvalidArgumentException('Username and password required.');
|
|
}
|
|
|
|
$role = $this->permissionRepo->ensureSuperAdministratorRole();
|
|
|
|
// Create user account.
|
|
$user = new User();
|
|
$user->setEmail($data['username']);
|
|
$user->setNewPassword($data['password']);
|
|
$user->getRoles()->add($role);
|
|
|
|
$errors = $this->validator->validate($user);
|
|
if (count($errors) > 0) {
|
|
throw ValidationException::fromValidationErrors($errors);
|
|
}
|
|
|
|
$this->em->persist($user);
|
|
$this->em->flush();
|
|
|
|
// Log in the newly created user.
|
|
$auth = $request->getAuth();
|
|
$auth->authenticate($data['username'], $data['password']);
|
|
|
|
$acl = $request->getAcl();
|
|
$acl->reload();
|
|
|
|
return $response->withRedirect($request->getRouter()->named('setup:index'));
|
|
} catch (Throwable $e) {
|
|
$error = $e->getMessage();
|
|
}
|
|
}
|
|
|
|
return $request->getView()->renderVuePage(
|
|
response: $response,
|
|
component: 'Vue_SetupRegister',
|
|
id: 'setup-register',
|
|
layout: 'minimal',
|
|
title: __('Set Up AzuraCast'),
|
|
props: [
|
|
'csrf' => $csrf->generate('register'),
|
|
'error' => $error,
|
|
]
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Setup Step 2:
|
|
* Create Station and Parse Metadata
|
|
*/
|
|
public function stationAction(
|
|
ServerRequest $request,
|
|
Response $response
|
|
): ResponseInterface {
|
|
// Verify current step.
|
|
$current_step = $this->getSetupStep($request);
|
|
if ($current_step !== 'station' && $this->environment->isProduction()) {
|
|
return $response->withRedirect($request->getRouter()->named('setup:' . $current_step));
|
|
}
|
|
|
|
$router = $request->getRouter();
|
|
|
|
return $request->getView()->renderVuePage(
|
|
response: $response,
|
|
component: 'Vue_SetupStation',
|
|
id: 'setup-station',
|
|
title: __('Create a New Radio Station'),
|
|
props: array_merge(
|
|
$this->stationFormComponent->getProps($request),
|
|
[
|
|
'createUrl' => $router->named('api:admin:stations'),
|
|
'continueUrl' => $router->named('setup:settings'),
|
|
]
|
|
)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Setup Step 3:
|
|
* Set site settings.
|
|
*/
|
|
public function settingsAction(
|
|
ServerRequest $request,
|
|
Response $response
|
|
): ResponseInterface {
|
|
$router = $request->getRouter();
|
|
|
|
// Verify current step.
|
|
$current_step = $this->getSetupStep($request);
|
|
if ($current_step !== 'settings' && $this->environment->isProduction()) {
|
|
return $response->withRedirect($router->named('setup:' . $current_step));
|
|
}
|
|
|
|
return $request->getView()->renderVuePage(
|
|
response: $response,
|
|
component: 'Vue_SetupSettings',
|
|
id: 'setup-settings',
|
|
title: __('System Settings'),
|
|
props: [
|
|
'apiUrl' => $router->named('api:admin:settings', [
|
|
'group' => Settings::GROUP_GENERAL,
|
|
]),
|
|
'releaseChannel' => $this->version->getReleaseChannelEnum()->value,
|
|
'continueUrl' => $router->named('dashboard'),
|
|
],
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Placeholder function for "setup complete" redirection.
|
|
*
|
|
* @param ServerRequest $request
|
|
* @param Response $response
|
|
*/
|
|
public function completeAction(
|
|
ServerRequest $request,
|
|
Response $response
|
|
): ResponseInterface {
|
|
$request->getFlash()->error('<b>' . __('Setup has already been completed!') . '</b>');
|
|
|
|
return $response->withRedirect($request->getRouter()->named('dashboard'));
|
|
}
|
|
|
|
/**
|
|
* Determine which step of setup is currently active.
|
|
*
|
|
* @param ServerRequest $request
|
|
*/
|
|
private function getSetupStep(ServerRequest $request): string
|
|
{
|
|
$settings = $this->readSettings();
|
|
if ($settings->isSetupComplete()) {
|
|
return 'complete';
|
|
}
|
|
|
|
// Step 1: Register
|
|
$num_users = (int)$this->em->createQuery(
|
|
<<<'DQL'
|
|
SELECT COUNT(u.id) FROM App\Entity\User u
|
|
DQL
|
|
)->getSingleScalarResult();
|
|
|
|
if (0 === $num_users) {
|
|
return 'register';
|
|
}
|
|
|
|
// If past "register" step, require login.
|
|
$auth = $request->getAuth();
|
|
if (!$auth->isLoggedIn()) {
|
|
throw new NotLoggedInException();
|
|
}
|
|
|
|
// Step 2: Set up Station
|
|
$num_stations = (int)$this->em->createQuery(
|
|
<<<'DQL'
|
|
SELECT COUNT(s.id) FROM App\Entity\Station s
|
|
DQL
|
|
)->getSingleScalarResult();
|
|
|
|
if (0 === $num_stations) {
|
|
return 'station';
|
|
}
|
|
|
|
// Step 3: System Settings
|
|
return 'settings';
|
|
}
|
|
}
|