about screen with debug information for super-admin (#378)
This commit is contained in:
10
LICENSE
10
LICENSE
@@ -1,11 +1,13 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2017-2018 Kevin Papst
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
@@ -15,5 +17,5 @@ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
148
src/Controller/Admin/AboutController.php
Normal file
148
src/Controller/Admin/AboutController.php
Normal file
@@ -0,0 +1,148 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Kimai time-tracking app.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace App\Controller\Admin;
|
||||
|
||||
use App\Constants;
|
||||
use App\Controller\AbstractController;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
/**
|
||||
* Controller used for executing system relevant tasks.
|
||||
*
|
||||
* @Route(path="/admin/about")
|
||||
* @Security("is_granted('ROLE_SUPER_ADMIN')")
|
||||
*/
|
||||
class AboutController extends AbstractController
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $projectDirectory;
|
||||
|
||||
/**
|
||||
* @param string $projectDirectory
|
||||
*/
|
||||
public function __construct(string $projectDirectory)
|
||||
{
|
||||
$this->projectDirectory = $projectDirectory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route(path="", name="about", methods={"GET"})
|
||||
|
||||
* @param Request $request
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function indexAction(Request $request)
|
||||
{
|
||||
$phpInfo = $this->getPhpInfo();
|
||||
unset($phpInfo[0]);
|
||||
unset($phpInfo[1]);
|
||||
|
||||
$ini = [
|
||||
'allow_url_fopen',
|
||||
'allow_url_include',
|
||||
'default_charset',
|
||||
'default_mimetype',
|
||||
'display_errors',
|
||||
'error_log',
|
||||
'error_reporting',
|
||||
'log_errors',
|
||||
'max_execution_time',
|
||||
'memory_limit',
|
||||
'open_basedir',
|
||||
'post_max_size',
|
||||
'sys_temp_dir',
|
||||
];
|
||||
|
||||
$settings = [];
|
||||
foreach ($ini as $name) {
|
||||
try {
|
||||
$settings[$name] = ini_get($name);
|
||||
} catch (\Exception $ex) {
|
||||
$settings[$name] = "Couldn't load ini setting: " . $ex->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
return $this->render('admin/system.html.twig', [
|
||||
'modules' => get_loaded_extensions(),
|
||||
'dotenv' => [
|
||||
'APP_ENV' => getenv('APP_ENV'),
|
||||
'DATABASE_PREFIX' => getenv('DATABASE_PREFIX'),
|
||||
'MAILER_FROM' => getenv('MAILER_FROM'),
|
||||
'MAILER_URL' => getenv('MAILER_URL'),
|
||||
'CORS_ALLOW_ORIGIN' => getenv('CORS_ALLOW_ORIGIN'),
|
||||
],
|
||||
'info' => $phpInfo,
|
||||
'settings' => $settings,
|
||||
'license' => $this->getLicense(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function getLicense()
|
||||
{
|
||||
$filename = $this->projectDirectory . '/LICENSE';
|
||||
|
||||
try {
|
||||
$license = file_get_contents($filename);
|
||||
} catch (\Exception $ex) {
|
||||
$license = false;
|
||||
}
|
||||
|
||||
if (false === $license) {
|
||||
$license = 'Failed reading license file: ' . $filename . '. ' .
|
||||
'Check this instead: ' . Constants::GITHUB . 'blob/master/LICENSE';
|
||||
}
|
||||
|
||||
return $license;
|
||||
}
|
||||
|
||||
/**
|
||||
* @author https://php.net/manual/en/function.phpinfo.php#117961
|
||||
* @return array
|
||||
*/
|
||||
private function getPhpInfo()
|
||||
{
|
||||
$plainText = function ($input) {
|
||||
return trim(html_entity_decode(strip_tags($input)));
|
||||
};
|
||||
|
||||
ob_start();
|
||||
phpinfo(1);
|
||||
|
||||
$phpinfo = ['phpinfo' => []];
|
||||
|
||||
if (preg_match_all(
|
||||
'#(?:<h2.*?>(?:<a.*?>)?(.*?)(?:<\/a>)?<\/h2>)|' .
|
||||
'(?:<tr.*?><t[hd].*?>(.*?)\s*</t[hd]>(?:<t[hd].*?>(.*?)\s*</t[hd]>(?:<t[hd].*?>(.*?)\s*</t[hd]>)?)?</tr>)#s',
|
||||
ob_get_clean(),
|
||||
$matches,
|
||||
PREG_SET_ORDER
|
||||
)) {
|
||||
foreach ($matches as $match) {
|
||||
$fn = $plainText;
|
||||
if (isset($match[3])) {
|
||||
$keys1 = array_keys($phpinfo);
|
||||
$phpinfo[end($keys1)][$fn($match[2])] = isset($match[4]) ? [$fn($match[3]), $fn($match[4])] : $fn($match[3]);
|
||||
} else {
|
||||
$keys1 = array_keys($phpinfo);
|
||||
$phpinfo[end($keys1)][] = $fn($match[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $phpinfo['phpinfo'];
|
||||
}
|
||||
}
|
||||
112
templates/admin/system.html.twig
Normal file
112
templates/admin/system.html.twig
Normal file
@@ -0,0 +1,112 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block page_title %}{{ 'about.title'|trans({}, 'about') }}{% endblock %}
|
||||
{% block page_subtitle %}{{ 'about.subtitle'|trans({}, 'about') }}{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
|
||||
<div class="nav-tabs-custom">
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="active"><a href="#kimai" data-toggle="tab" aria-expanded="true">Kimai</a></li>
|
||||
<li><a href="#system" data-toggle="tab" aria-expanded="true">System</a></li>
|
||||
<li><a href="#license" data-toggle="tab" aria-expanded="true">License</a></li>
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane active" id="kimai">
|
||||
<dl>
|
||||
<dt>Version</dt><dd>{{ constant('App\\Constants::VERSION') }}</dd>
|
||||
<dt>Status</dt><dd>{{ constant('App\\Constants::STATUS') }}</dd>
|
||||
<dt>Name</dt><dd>{{ constant('App\\Constants::NAME') }}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="tab-pane" id="system">
|
||||
|
||||
<div class="box-group" id="accordion">
|
||||
<div class="panel box">
|
||||
<div class="box-header with-border">
|
||||
<h4 class="box-title">
|
||||
<a data-toggle="collapse" data-parent="#accordion" href="#collapseTwo" class="" aria-expanded="true">
|
||||
Environment
|
||||
</a>
|
||||
</h4>
|
||||
</div>
|
||||
<div id="collapseTwo" class="panel-collapse collapse in" aria-expanded="true" style="">
|
||||
<div class="box-body">
|
||||
|
||||
<dl>
|
||||
{% for name, value in dotenv %}
|
||||
<dt>{{ name }}</dt>
|
||||
<dd>{{ value }}</dd>
|
||||
{% endfor %}
|
||||
</dl>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel box">
|
||||
<div class="box-header with-border">
|
||||
<h4 class="box-title">
|
||||
<a data-toggle="collapse" data-parent="#accordion" href="#collapseThree" class="collapsed" aria-expanded="false">
|
||||
PHP
|
||||
</a>
|
||||
</h4>
|
||||
</div>
|
||||
<div id="collapseThree" class="panel-collapse collapse" aria-expanded="false" style="height: 0px;">
|
||||
<div class="box-body">
|
||||
|
||||
<dl>
|
||||
<dt>Version</dt><dd>{{ constant('PHP_VERSION') }}</dd>
|
||||
<dt>Modules</dt><dd>{{ modules|join(', ') }}</dd>
|
||||
{% for name, value in settings %}
|
||||
<dt>{{ name }}</dt>
|
||||
<dd>
|
||||
{% if value is empty %}
|
||||
<i>unknown</i>
|
||||
{% else %}
|
||||
{{ value }}
|
||||
{% endif %}
|
||||
</dd>
|
||||
{% endfor %}
|
||||
</dl>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel box">
|
||||
<div class="box-header with-border">
|
||||
<h4 class="box-title">
|
||||
<a data-toggle="collapse" data-parent="#accordion" href="#collapseFour" class="collapsed" aria-expanded="false">
|
||||
Server
|
||||
</a>
|
||||
</h4>
|
||||
</div>
|
||||
<div id="collapseFour" class="panel-collapse collapse" aria-expanded="false" style="height: 0px;">
|
||||
<div class="box-body">
|
||||
|
||||
<dl>
|
||||
{% for name, value in info %}
|
||||
<dt>{{ name }}</dt>
|
||||
<dd>{{ value|raw }}</dd>
|
||||
{% endfor %}
|
||||
</dl>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="tab-pane" id="license">
|
||||
<pre>{{ license }}</pre>
|
||||
<p>
|
||||
<a href="https://choosealicense.com/licenses/mit/" target="_blank">choosealicense.com</a>,
|
||||
<a href="https://en.wikipedia.org/wiki/MIT_License" target="_blank">wikipedia.org</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -28,6 +28,18 @@
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
{% if is_granted('ROLE_SUPER_ADMIN') %}
|
||||
<li>
|
||||
<a href="{{ path('about') }}">
|
||||
<i class="menu-icon far fa-copyright bg-aqua"></i>
|
||||
|
||||
<div class="menu-info">
|
||||
<h4 class="control-sidebar-subheading">{{ 'about.title'|trans({}, 'about') }}</h4>
|
||||
<p>{{ 'about.subtitle'|trans({}, 'about') }}</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
|
||||
<p><br>Made with ♥ by <a href="https://www.kevinpapst.de/">Kevin Papst</a> and <a href="{{ constant('App\\Constants::GITHUB') }}graphs/contributors" target="_blank">great contributors</a>.</p>
|
||||
|
||||
38
tests/Controller/Admin/AboutControllerTest.php
Normal file
38
tests/Controller/Admin/AboutControllerTest.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Kimai time-tracking app.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace App\Tests\Controller\Admin;
|
||||
|
||||
use App\Entity\User;
|
||||
use App\Tests\Controller\ControllerBaseTest;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \App\Controller\Admin\AboutController
|
||||
* @group integration
|
||||
*/
|
||||
class AboutControllerTest extends ControllerBaseTest
|
||||
{
|
||||
public function testIsSecure()
|
||||
{
|
||||
$this->assertUrlIsSecured('/admin/about');
|
||||
$this->assertUrlIsSecuredForRole(User::ROLE_ADMIN, '/admin/about');
|
||||
}
|
||||
|
||||
public function testIndexAction()
|
||||
{
|
||||
$client = $this->getClientForAuthenticatedUser(User::ROLE_SUPER_ADMIN);
|
||||
$this->assertAccessIsGranted($client, '/admin/about');
|
||||
|
||||
$result = $client->getCrawler()->filter('div.nav-tabs-custom ul.nav.nav-tabs li');
|
||||
$this->assertEquals(3, count($result));
|
||||
|
||||
$result = $client->getCrawler()->filter('div.nav-tabs-custom div.tab-content div.tab-pane');
|
||||
$this->assertEquals(3, count($result));
|
||||
}
|
||||
}
|
||||
15
translations/about.de.xliff
Normal file
15
translations/about.de.xliff
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<file date="2018-10-29T10:00:00Z" source-language="en" target-language="de" datatype="plaintext" original="about.en.xliff">
|
||||
<body>
|
||||
<trans-unit id="about.title">
|
||||
<source>about.title</source>
|
||||
<target>Über Kimai</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="about.subtitle">
|
||||
<source>about.subtitle</source>
|
||||
<target>System Informationen</target>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
15
translations/about.en.xliff
Normal file
15
translations/about.en.xliff
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<file date="2018-10-29T10:00:00Z" source-language="en" target-language="en" datatype="plaintext" original="none">
|
||||
<body>
|
||||
<trans-unit id="about.title">
|
||||
<source>about.title</source>
|
||||
<target>About Kimai</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="about.subtitle">
|
||||
<source>about.subtitle</source>
|
||||
<target>System information</target>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
Reference in New Issue
Block a user