forked from zer.ooo/web
add config builder + fix server overview
This commit is contained in:
parent
0333aa10c7
commit
d72f6fa784
13 changed files with 250 additions and 14 deletions
|
@ -37,14 +37,20 @@ routes:
|
||||||
/sign:
|
/sign:
|
||||||
post: Panel\Servers\Sign
|
post: Panel\Servers\Sign
|
||||||
/{fingerprint}:
|
/{fingerprint}:
|
||||||
|
get: Panel\Servers\Show
|
||||||
|
/edit:
|
||||||
get: Panel\Servers\Edit\Show
|
get: Panel\Servers\Edit\Show
|
||||||
post: Panel\Servers\Edit\Action
|
post: Panel\Servers\Edit\Action
|
||||||
/{fingerprint}/config: Panel\Servers\Config
|
/config:
|
||||||
/{fingerprint}/config/{cert}: Panel\Servers\Config
|
get: Panel\Servers\Config
|
||||||
|
/{cert}: Panel\Servers\Config
|
||||||
/invites:
|
/invites:
|
||||||
get: Panel\Invites
|
get: Panel\Invites
|
||||||
/create:
|
/create:
|
||||||
post: Panel\Invites\Create
|
post: Panel\Invites\Create
|
||||||
|
/config-builder:
|
||||||
|
get: Panel\ConfigBuilder\Show
|
||||||
|
post: Panel\ConfigBuilder\Action
|
||||||
/server:
|
/server:
|
||||||
/register:
|
/register:
|
||||||
post: Server\Register
|
post: Server\Register
|
|
@ -250,31 +250,37 @@ body {
|
||||||
.certificate-list li .actions .certificate-download-key:hover,
|
.certificate-list li .actions .certificate-download-key:hover,
|
||||||
.certificate-list li .actions .no:hover,
|
.certificate-list li .actions .no:hover,
|
||||||
.certificate-list li .actions .copy:hover,
|
.certificate-list li .actions .copy:hover,
|
||||||
.certificate-list li .actions .edit:hover, .certificate-list li .revoke-q .certificate-download:hover,
|
.certificate-list li .actions .edit:hover,
|
||||||
|
.certificate-list li .actions .details:hover, .certificate-list li .revoke-q .certificate-download:hover,
|
||||||
.certificate-list li .revoke-q .certificate-download-key:hover,
|
.certificate-list li .revoke-q .certificate-download-key:hover,
|
||||||
.certificate-list li .revoke-q .no:hover,
|
.certificate-list li .revoke-q .no:hover,
|
||||||
.certificate-list li .revoke-q .copy:hover,
|
.certificate-list li .revoke-q .copy:hover,
|
||||||
.certificate-list li .revoke-q .edit:hover,
|
.certificate-list li .revoke-q .edit:hover,
|
||||||
|
.certificate-list li .revoke-q .details:hover,
|
||||||
.servers li .actions .certificate-download:hover,
|
.servers li .actions .certificate-download:hover,
|
||||||
.servers li .actions .certificate-download-key:hover,
|
.servers li .actions .certificate-download-key:hover,
|
||||||
.servers li .actions .no:hover,
|
.servers li .actions .no:hover,
|
||||||
.servers li .actions .copy:hover,
|
.servers li .actions .copy:hover,
|
||||||
.servers li .actions .edit:hover,
|
.servers li .actions .edit:hover,
|
||||||
|
.servers li .actions .details:hover,
|
||||||
.servers li .revoke-q .certificate-download:hover,
|
.servers li .revoke-q .certificate-download:hover,
|
||||||
.servers li .revoke-q .certificate-download-key:hover,
|
.servers li .revoke-q .certificate-download-key:hover,
|
||||||
.servers li .revoke-q .no:hover,
|
.servers li .revoke-q .no:hover,
|
||||||
.servers li .revoke-q .copy:hover,
|
.servers li .revoke-q .copy:hover,
|
||||||
.servers li .revoke-q .edit:hover,
|
.servers li .revoke-q .edit:hover,
|
||||||
|
.servers li .revoke-q .details:hover,
|
||||||
.invites li .actions .certificate-download:hover,
|
.invites li .actions .certificate-download:hover,
|
||||||
.invites li .actions .certificate-download-key:hover,
|
.invites li .actions .certificate-download-key:hover,
|
||||||
.invites li .actions .no:hover,
|
.invites li .actions .no:hover,
|
||||||
.invites li .actions .copy:hover,
|
.invites li .actions .copy:hover,
|
||||||
.invites li .actions .edit:hover,
|
.invites li .actions .edit:hover,
|
||||||
|
.invites li .actions .details:hover,
|
||||||
.invites li .revoke-q .certificate-download:hover,
|
.invites li .revoke-q .certificate-download:hover,
|
||||||
.invites li .revoke-q .certificate-download-key:hover,
|
.invites li .revoke-q .certificate-download-key:hover,
|
||||||
.invites li .revoke-q .no:hover,
|
.invites li .revoke-q .no:hover,
|
||||||
.invites li .revoke-q .copy:hover,
|
.invites li .revoke-q .copy:hover,
|
||||||
.invites li .revoke-q .edit:hover {
|
.invites li .revoke-q .edit:hover,
|
||||||
|
.invites li .revoke-q .details:hover {
|
||||||
background: #aca4bc; }
|
background: #aca4bc; }
|
||||||
.certificate-list li .actions .no, .certificate-list li .revoke-q .no,
|
.certificate-list li .actions .no, .certificate-list li .revoke-q .no,
|
||||||
.servers li .actions .no,
|
.servers li .actions .no,
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -255,7 +255,8 @@ body {
|
||||||
.certificate-download-key,
|
.certificate-download-key,
|
||||||
.no,
|
.no,
|
||||||
.copy,
|
.copy,
|
||||||
.edit {
|
.edit,
|
||||||
|
.details {
|
||||||
&:hover {
|
&:hover {
|
||||||
background: #aca4bc;
|
background: #aca4bc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ $(function () {
|
||||||
|
|
||||||
var data = $('.server-form input,.server-form select').serializeArray();
|
var data = $('.server-form input,.server-form select').serializeArray();
|
||||||
|
|
||||||
$.post('/panel/server/' + fingerprint, data, function (data) {
|
$.post('/panel/server/' + fingerprint + '/edit', data, function (data) {
|
||||||
if (!data.success) {
|
if (!data.success) {
|
||||||
error(data.error);
|
error(data.error);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -43,6 +43,10 @@ class Panel extends Session
|
||||||
'name' => 'Invites',
|
'name' => 'Invites',
|
||||||
'path' => '/panel/invites'
|
'path' => '/panel/invites'
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
'name' => 'Config builder',
|
||||||
|
'path' => '/panel/config-builder'
|
||||||
|
],
|
||||||
[
|
[
|
||||||
'name' => 'Profile > ' . $this->getUser()->getUsername(),
|
'name' => 'Profile > ' . $this->getUser()->getUsername(),
|
||||||
'path' => '/panel/profile'
|
'path' => '/panel/profile'
|
||||||
|
|
83
src/Handler/Panel/ConfigBuilder/Action.php
Normal file
83
src/Handler/Panel/ConfigBuilder/Action.php
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
namespace Eater\Glim\Handler\Panel\ConfigBuilder;
|
||||||
|
|
||||||
|
use Eater\Glim\Handler\Session;
|
||||||
|
use Eater\Glim\Model\Certificate;
|
||||||
|
use Eater\Glim\Model\CertificateQuery;
|
||||||
|
use Eater\Glim\Model\Server;
|
||||||
|
use Eater\Glim\Model\ServerQuery;
|
||||||
|
|
||||||
|
class Action extends Session
|
||||||
|
{
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
$zipFile = tempnam(sys_get_temp_dir(), '0zip');
|
||||||
|
$zip = new \ZipArchive();
|
||||||
|
$zip->open($zipFile, \ZipArchive::CREATE);
|
||||||
|
$server = ServerQuery::create()->findOneByFingerprint($this->post('fingerprint'));
|
||||||
|
$name = $server->getFqdn();
|
||||||
|
|
||||||
|
$this->fillZipWithCaAndConfig($zip, $server);
|
||||||
|
|
||||||
|
$cert = $this->post('cert');
|
||||||
|
|
||||||
|
if ($cert !== null) {
|
||||||
|
$certModel = CertificateQuery::create()->findOneByUserAndName($this->getUser(), $cert);
|
||||||
|
$this->addClientCertificateData($zip, $certModel);
|
||||||
|
|
||||||
|
$name .= '-' . $certModel->getName() . '.' . $certModel->getSerial();
|
||||||
|
}
|
||||||
|
|
||||||
|
$zip->close();
|
||||||
|
|
||||||
|
$zipContents = file_get_contents($zipFile);
|
||||||
|
unlink($zipFile);
|
||||||
|
|
||||||
|
return $this->getResponse()
|
||||||
|
->withHeader('Content-Type', 'application/zip')
|
||||||
|
->withHeader('Content-Disposition', 'attachment; filename="' . $name . '.zip"')
|
||||||
|
->write($zipContents);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \ZipArchive $zip
|
||||||
|
* @param Server $server
|
||||||
|
*/
|
||||||
|
public function fillZipWithCaAndConfig($zip, $server)
|
||||||
|
{
|
||||||
|
$config = $this->getConfigForServerFingerprint($server);
|
||||||
|
$zip->addFromString('server.conf', $config);
|
||||||
|
$zip->addFromString('ca.crt', file_get_contents($this->getCore()->getBaseDir() . '/storage/ca/ca.crt'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Server $server
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getConfigForServerFingerprint($server)
|
||||||
|
{
|
||||||
|
/** @var \Twig_Environment $twig */
|
||||||
|
$twig = $this->get('twig');
|
||||||
|
|
||||||
|
$config = $twig->render('etc/openvpn-client.conf.twig', [
|
||||||
|
'server' => $server
|
||||||
|
]);
|
||||||
|
|
||||||
|
return $config;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \ZipArchive $zip
|
||||||
|
* @param Certificate $cert
|
||||||
|
*/
|
||||||
|
public function addClientCertificateData($zip, $cert)
|
||||||
|
{
|
||||||
|
$zip->addFromString('client.crt', $cert->getCertificate());
|
||||||
|
|
||||||
|
if ($cert->hasPrivateKey()) {
|
||||||
|
$zip->addFromString('client.key', $cert->getPrivateKey());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
23
src/Handler/Panel/ConfigBuilder/Show.php
Normal file
23
src/Handler/Panel/ConfigBuilder/Show.php
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
namespace Eater\Glim\Handler\Panel\ConfigBuilder;
|
||||||
|
|
||||||
|
|
||||||
|
use Eater\Glim\Handler\Panel;
|
||||||
|
use Eater\Glim\Model\ServerQuery;
|
||||||
|
|
||||||
|
class Show extends Panel
|
||||||
|
{
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
$servers = ServerQuery::create()->filterByStatus('signed')->find();
|
||||||
|
|
||||||
|
return $this->render(
|
||||||
|
'panel/config_builder.html.twig',
|
||||||
|
[
|
||||||
|
'servers' => $servers
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
34
src/Handler/Panel/Servers/Show.php
Normal file
34
src/Handler/Panel/Servers/Show.php
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Created by PhpStorm.
|
||||||
|
* User: eater
|
||||||
|
* Date: 4/10/16
|
||||||
|
* Time: 9:30 PM
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Eater\Glim\Handler\Panel\Servers;
|
||||||
|
|
||||||
|
|
||||||
|
use Eater\Glim\Handler\Panel;
|
||||||
|
use Eater\Glim\Model\ServerQuery;
|
||||||
|
|
||||||
|
class Show extends Panel
|
||||||
|
{
|
||||||
|
protected $shouldHaveSuperuser = true;
|
||||||
|
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
$server = ServerQuery::create()->findOneByFingerprint($this->attr('fingerprint'));
|
||||||
|
|
||||||
|
if ($server === null) {
|
||||||
|
return $this->getResponse()->withStatus(404);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->render(
|
||||||
|
"panel/servers/show.html.twig",
|
||||||
|
[
|
||||||
|
'server' => $server
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
26
views/panel/config_builder.html.twig
Normal file
26
views/panel/config_builder.html.twig
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
{% extends "panel.html.twig" %}
|
||||||
|
|
||||||
|
{% block panel_contents %}
|
||||||
|
<h1 class="title">Config builder</h1>
|
||||||
|
<form target="_blank" action="/panel/config-builder" method="post" class="form">
|
||||||
|
<div class="row">
|
||||||
|
<label for="server">Server</label>
|
||||||
|
<select name="fingerprint" id="server">
|
||||||
|
{% for server in servers %}
|
||||||
|
<option value="{{ server.getFingerprint() }}">{{ server.getFqdn() }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<label for="certificate">Certificate</label>
|
||||||
|
<select name="cert" id="certificate">
|
||||||
|
{% for certificate in user.getActiveCertificates() %}
|
||||||
|
<option value="{{ certificate.getName() }}">{{ certificate.getName() }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="buttons">
|
||||||
|
<button type="submit">Build</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
|
@ -16,10 +16,14 @@
|
||||||
{% for server in servers %}
|
{% for server in servers %}
|
||||||
<li>
|
<li>
|
||||||
<div class="text">
|
<div class="text">
|
||||||
{{ server.getName() }}
|
{{ server.getFQDN() }}
|
||||||
</div>
|
</div>
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
<span><a href="/panel/servers/{{ server.getFingerprint() }}">Details</a></span>
|
<span class="details"><a target="_blank" href="/panel/server/{{ server.getFingerprint() }}/config">download config</a></span>
|
||||||
|
<span class="details"><a href="/panel/server/{{ server.getFingerprint() }}">details</a></span>
|
||||||
|
{% if user.isSuperUser() %}
|
||||||
|
<span class="edit"><a href="/panel/server/{{ server.getFingerprint() }}/edit">edit</a></span>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
{% else %}
|
{% else %}
|
||||||
|
@ -44,7 +48,7 @@
|
||||||
</form>
|
</form>
|
||||||
</span>
|
</span>
|
||||||
<span class="edit" >
|
<span class="edit" >
|
||||||
<a href="/panel/server/{{ server.getFingerprint() }}">edit</a>
|
<a href="/panel/server/{{ server.getFingerprint() }}/edit">edit</a>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -47,8 +47,8 @@
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<label for="second-dns">second DNS</label>
|
<label for="first-dns">first DNS</label>
|
||||||
<input name="second-dns" id="first-dns" type="text" value="{{ server.getSecondDns() ?: '8.8.4.4' }}" />
|
<input name="first-dns" id="first-dns" type="text" value="{{ server.getFirstDns() ?: '8.8.8.8' }}" />
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<label class="control-label col-md-4" for="second-dns">second DNS</label>
|
<label class="control-label col-md-4" for="second-dns">second DNS</label>
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
{% extends "panel.html.twig" %}
|
||||||
|
|
||||||
|
{% block panel_contents %}
|
||||||
|
<h1 class="title">Server '{{ server.getFqdn() }}'</h1>
|
||||||
|
<div class="server-form" data-fingerprint="{{ server.getFingerprint() }}">
|
||||||
|
<div class="row">
|
||||||
|
<label for="fqdn">Hostname</label>
|
||||||
|
<label>{{ server.getFqdn() }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<label for="external-ip">External IP</label>
|
||||||
|
<label>{{ server.getExternalIp() }}</label>
|
||||||
|
</div>
|
||||||
|
<h2>Details</h2>
|
||||||
|
<div class="row">
|
||||||
|
<label for="location">Location</label>
|
||||||
|
<label>{{ server.getLocation() }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<label for="speed">Speed</label>
|
||||||
|
<label>{{ server.getSpeed() }}</label>
|
||||||
|
</div>
|
||||||
|
<h2>Config</h2>
|
||||||
|
<div class="row">
|
||||||
|
<label for="internal-ip">Internal IP</label>
|
||||||
|
<label>{{ server.getInternalIp() }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<label>Netmask</label>
|
||||||
|
<label>{{ server.getNetmask() }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<label>Port</label>
|
||||||
|
<label>{{ server.getPort() }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<label>Protocol</label>
|
||||||
|
<label>{{ server.getProtocol() }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<label for="first-dns">first DNS</label>
|
||||||
|
<label>{{ server.getFirstDns() }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<label class="control-label col-md-4" for="second-dns">second DNS</label>
|
||||||
|
<label>{{ server.getSecondDns() }}</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
Loading…
Reference in a new issue