Skip to content

Commit

Permalink
about screen with debug information for super-admin (#378)
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinpapst committed Oct 29, 2018
1 parent 55aedcd commit 34a3f4e
Show file tree
Hide file tree
Showing 7 changed files with 346 additions and 4 deletions.
10 changes: 6 additions & 4 deletions 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.
Expand All @@ -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 changes: 148 additions & 0 deletions src/Controller/Admin/AboutController.php
@@ -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 changes: 112 additions & 0 deletions templates/admin/system.html.twig
@@ -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 %}
12 changes: 12 additions & 0 deletions templates/sidebar/home.html.twig
Expand Up @@ -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 changes: 38 additions & 0 deletions tests/Controller/Admin/AboutControllerTest.php
@@ -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 changes: 15 additions & 0 deletions translations/about.de.xliff
@@ -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 changes: 15 additions & 0 deletions translations/about.en.xliff
@@ -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>

0 comments on commit 34a3f4e

Please sign in to comment.