1
0
This commit is contained in:
Mike Schwörer 2018-01-21 19:07:43 +01:00
parent 28ae8beb2d
commit f373b208f6
Signed by: Mikescher
GPG Key ID: D3C7172E0A70F8CF
15 changed files with 435 additions and 11 deletions

View File

@ -102,6 +102,19 @@ body {
.boxedcontent .bc_data { .boxedcontent .bc_data {
padding: 8px; } padding: 8px; }
.button {
color: #DDD;
text-decoration: none;
background-color: #222;
font-size: 1rem;
border: 1px solid black;
height: 36px;
line-height: 36px;
padding: 2px 2rem; }
.button:hover {
background-color: #555; }
/* 400px */ /* 400px */
#headerdiv { #headerdiv {
z-index: 999; z-index: 999;
@ -887,6 +900,41 @@ html, body {
text-decoration: none; text-decoration: none;
color: #22F; } color: #22F; }
/* 400px */
.admincontent {
display: block;
width: 100%; }
.admincontent .boxedcontent {
margin-bottom: 20px; }
.egh_ajaxOutput {
display: flex;
box-sizing: border-box;
width: 100%;
align-self: center;
justify-self: center;
margin-left: auto;
margin-right: auto;
resize: none;
height: 300px; }
/* 400px */
#loginform div {
display: flex;
flex-direction: column; }
#loginform div button {
margin: 10px 0;
padding: 0; }
.loginerror {
display: flex;
background: #FF4444;
font-weight: bold;
padding: 0 5px;
margin: 5px 0 20px 0; }
/* 400px */ /* 400px */
.euler_pnl_base { .euler_pnl_base {
display: inline-flex; display: inline-flex;

View File

@ -21,6 +21,8 @@ body{background-color:#EEE;color:#CCC;font-family:serif}
.boxedcontent{color:#333;border:1px solid black;background-color:#e0e0e0;width:100%;margin-left:auto;margin-right:auto} .boxedcontent{color:#333;border:1px solid black;background-color:#e0e0e0;width:100%;margin-left:auto;margin-right:auto}
.boxedcontent .bc_header{background-color:#BBB;padding:0 4px} .boxedcontent .bc_header{background-color:#BBB;padding:0 4px}
.boxedcontent .bc_data{padding:8px} .boxedcontent .bc_data{padding:8px}
.button{color:#DDD;text-decoration:none;background-color:#222;font-size:1rem;border:1px solid black;height:36px;line-height:36px;padding:2px 2rem}
.button:hover{background-color:#555}
#headerdiv{z-index:999;background-color:#333;display:flex;border-bottom:1px solid #111;box-shadow:0 0 8px #000;position:fixed;width:100%} #headerdiv{z-index:999;background-color:#333;display:flex;border-bottom:1px solid #111;box-shadow:0 0 8px #000;position:fixed;width:100%}
#headerdiv .logowrapper{flex:initial;margin:0;padding:0;height:42px} #headerdiv .logowrapper{flex:initial;margin:0;padding:0;height:42px}
#headerdiv .logowrapper .logo{height:30px;margin:4px 0 8px 6px;flex:initial} #headerdiv .logowrapper .logo{height:30px;margin:4px 0 8px 6px;flex:initial}
@ -221,6 +223,12 @@ html,body{margin:0;padding:0;height:100%}
.egg_footer{margin-top:5px;text-align:right;margin-right:5px;margin-bottom:5px;color:#888} .egg_footer{margin-top:5px;text-align:right;margin-right:5px;margin-bottom:5px;color:#888}
.egg_footer>a{text-decoration:none;color:inherit} .egg_footer>a{text-decoration:none;color:inherit}
.egg_footer>a:hover{text-decoration:none;color:#22F} .egg_footer>a:hover{text-decoration:none;color:#22F}
.admincontent{display:block;width:100%}
.admincontent .boxedcontent{margin-bottom:20px}
.egh_ajaxOutput{display:flex;box-sizing:border-box;width:100%;align-self:center;justify-self:center;margin-left:auto;margin-right:auto;resize:none;height:300px}
#loginform div{display:flex;flex-direction:column}
#loginform div button{margin:10px 0;padding:0}
.loginerror{display:flex;background:#f44;font-weight:bold;padding:0 5px;margin:5px 0 20px 0}
.euler_pnl_base{display:inline-flex;flex-direction:column;border:1px solid #AAA;border-radius:5px 5px 0 0;margin:15px} .euler_pnl_base{display:inline-flex;flex-direction:column;border:1px solid #AAA;border-radius:5px 5px 0 0;margin:15px}
.euler_pnl_header{display:flex;align-items:center;justify-content:center;padding:4px;background:#AAA} .euler_pnl_header{display:flex;align-items:center;justify-content:center;padding:4px;background:#AAA}
.euler_pnl_header a{color:#222;text-decoration:none;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:22px;font-weight:900} .euler_pnl_header a{color:#222;text-decoration:none;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:22px;font-weight:900}

View File

@ -10,6 +10,8 @@
@import 'styles_programslist'; @import 'styles_programslist';
@import 'styles_programsview'; @import 'styles_programsview';
@import 'styles_about'; @import 'styles_about';
@import 'styles_admin';
@import 'styles_login';
@import 'styles_eulerpanel'; @import 'styles_eulerpanel';
@import 'styles_programspanel'; @import 'styles_programspanel';

View File

@ -0,0 +1,23 @@
@import 'styles_config';
.admincontent {
display: block;
width: 100%;
}
.admincontent .boxedcontent{
margin-bottom: 20px;
}
.egh_ajaxOutput {
display: flex;
box-sizing: border-box;
width: 100%;
align-self: center;
justify-self: center;
margin-left: auto;
margin-right: auto;
resize: none;
height: 300px;
}

View File

@ -104,3 +104,19 @@ body {
padding: 8px; padding: 8px;
} }
} }
.button {
color: #DDD;
text-decoration: none;
background-color: #222;
font-size: 1rem;
border: 1px solid black;
height: 36px;
line-height: 36px;
padding: 2px 2rem;
}
.button:hover {
background-color: #555;
}

View File

@ -0,0 +1,19 @@
@import 'styles_config';
#loginform div {
display: flex;
flex-direction: column;
}
#loginform div button {
margin: 10px 0;
padding: 0;
}
.loginerror {
display: flex;
background: #FF4444;
font-weight: bold;
padding: 0 5px;
margin: 5px 0 20px 0;
}

View File

@ -0,0 +1,55 @@
function queryStatus(appendix, secret)
{
jQuery.ajax({
url: '/admin/egh/status?secret='+secret,
success: function(result)
{
let ajaxOutput = $('#egh_ajaxOutput');
ajaxOutput.val(result + '\r\n' + appendix);
ajaxOutput.scrollTop(ajaxOutput[0].scrollHeight);
},
async: true
});
}
function startAjaxRefresh(secret)
{
$('#egh_ajaxOutput').val("Started.");
val = setInterval(function(){ queryStatus('', secret); }, 500);
jQuery.ajax({
url: '/admin/egh/reload?secret='+secret,
success: function(result)
{
clearInterval(val);
queryStatus('Finished.', secret);
},
error: function( jqXHR, textStatus, errorThrown)
{
clearInterval(val);
queryStatus('AN ERROR OCCURED:' + '\r\n' + textStatus, secret);
},
async: true
});
}
function startAjaxRedraw(secret)
{
$('#egh_ajaxOutput').val("Started.");
val = setInterval(function(){ queryStatus('', secret); }, 500);
jQuery.ajax({
url: '/admin/egh/redraw?secret='+secret,
success: function(result)
{
clearInterval(val);
queryStatus('Finished.', secret);
},
error: function( jqXHR, textStatus, errorThrown)
{
clearInterval(val);
queryStatus('AN ERROR OCCURED:' + '\r\n' + textStatus, secret);
},
async: true
});
}

View File

@ -66,11 +66,9 @@ class ExtendedGitGraph
$_SESSION[self::PROGRESS_SESSION_COOKIE] .= $txt . "\r\n"; $_SESSION[self::PROGRESS_SESSION_COOKIE] .= $txt . "\r\n";
session_commit(); session_commit();
} }
else if ($this->outputMode === self::OUT_STDOUT)
{
print $txt; print $txt;
print "\r\n"; print "\r\n";
}
$logfile = Utils::sharpFormat($this->logFilePath, ['num'=>'']); $logfile = Utils::sharpFormat($this->logFilePath, ['num'=>'']);
file_put_contents($logfile, $txt.PHP_EOL , FILE_APPEND | LOCK_EX); file_put_contents($logfile, $txt.PHP_EOL , FILE_APPEND | LOCK_EX);
@ -181,4 +179,11 @@ class ExtendedGitGraph
{ {
return $this->renderedHTML; return $this->renderedHTML;
} }
public function getAll()
{
$all = '';
foreach ($this->get() as $year => $html) $all .= $html . "\n";
return $all;
}
} }

View File

@ -10,6 +10,7 @@ $URL_RULES =
[ 'url' => ['msmain', 'index'], 'target' => 'pages/main.php', 'options' => [], ], [ 'url' => ['msmain', 'index'], 'target' => 'pages/main.php', 'options' => [], ],
[ 'url' => ['about'], 'target' => 'pages/about.php', 'options' => [], ], [ 'url' => ['about'], 'target' => 'pages/about.php', 'options' => [], ],
[ 'url' => ['msmain', 'about'], 'target' => 'pages/about.php', 'options' => [], ], [ 'url' => ['msmain', 'about'], 'target' => 'pages/about.php', 'options' => [], ],
[ 'url' => ['login'], 'target' => 'pages/login.php', 'options' => [ 'login_target' => '/' ], ],
[ 'url' => ['programs'], 'target' => 'pages/programs_list.php', 'options' => [ 'categoryfilter' => '' ], ], [ 'url' => ['programs'], 'target' => 'pages/programs_list.php', 'options' => [ 'categoryfilter' => '' ], ],
[ 'url' => ['programs', 'index'], 'target' => 'pages/programs_list.php', 'options' => [ 'categoryfilter' => '%GET%' ], ], [ 'url' => ['programs', 'index'], 'target' => 'pages/programs_list.php', 'options' => [ 'categoryfilter' => '%GET%' ], ],
@ -34,8 +35,8 @@ $URL_RULES =
[ 'url' => ['api', 'setselfadress'], 'target' => 'pages/api_setselfadress.php', 'options' => [], ], [ 'url' => ['api', 'setselfadress'], 'target' => 'pages/api_setselfadress.php', 'options' => [], ],
[ 'url' => ['api', 'statsping'], 'target' => 'pages/api_stats.php', 'options' => [ 'Name' => '%GET%', 'ClientID' => '%GET%', 'Version' => '%GET%', 'ProviderStr' => '%GET%', 'ProviderID' => '%GET%', 'NoteCount' => '%GET%', ], ], [ 'url' => ['api', 'statsping'], 'target' => 'pages/api_stats.php', 'options' => [ 'Name' => '%GET%', 'ClientID' => '%GET%', 'Version' => '%GET%', 'ProviderStr' => '%GET%', 'ProviderID' => '%GET%', 'NoteCount' => '%GET%', ], ],
[ 'url' => ['msmain', 'admin', 'egh', '?{commandcode}'], 'target' => 'pages/admin_egh.php', 'options' => [ 'commandcode' => '%URL%' ], ], [ 'url' => ['admin'], 'target' => 'pages/admin.php', 'options' => [ '_opt' => 'password'], ],
[ 'url' => ['msmain', 'adminEGH'], 'target' => 'pages/admin_egh.php', 'options' => [ 'commandcode' => '%GET%' ], ], [ 'url' => ['admin', 'egh', '?{cmd}'], 'target' => 'pages/admin_egh.php', 'options' => [ 'cmd' => '%URL%', 'secret' => '%GET%' ], ],
[ 'url' => ['blog'], 'target' => 'pages/blog_list.php', 'options' => [], ], [ 'url' => ['blog'], 'target' => 'pages/blog_list.php', 'options' => [], ],
[ 'url' => ['log'], 'target' => 'pages/blog_list.php', 'options' => [], ], [ 'url' => ['log'], 'target' => 'pages/blog_list.php', 'options' => [], ],
@ -94,6 +95,8 @@ try {
if ($partcount !== count($rule['url'])) continue; if ($partcount !== count($rule['url'])) continue;
$urlparams = []; $urlparams = [];
$opt = key_exists('_opt', $rule['options']) ? explode($rule['options']['_opt'], '|') : [];
$target = $rule['target'];
$match = true; $match = true;
for($i = 0; $i < $partcount; $i++) for($i = 0; $i < $partcount; $i++)
@ -136,8 +139,26 @@ try {
} }
if (!$match) continue; if (!$match) continue;
if (in_array('disabled', $opt)) continue;
if (in_array('password', $opt))
{
$auth = hash('sha256', $CONFIG['admin_username'] . ';' . $CONFIG['admin_password']);
if (!key_exists('mikescher_auth', $_COOKIE))
{
$opt['login_target'] = $path;
$target = 'pages/login.php';
}
else if ($auth !== $_COOKIE['mikescher_auth'])
{
$opt['login_target'] = $path;
$target = 'pages/login.php';
}
}
$OPTIONS = $opt; $OPTIONS = $opt;
include $rule['target']; include $target;
return; return;
} }
@ -174,5 +195,4 @@ try {
//TODO optimize image sizes for display/download (? - auto?) //TODO optimize image sizes for display/download (? - auto?)
//TODO send cache header (?) //TODO send cache header (?)
//TODO programs add [license] //TODO programs add [license]
//TODO admin
//TODO last 3 blog entries on /index/ (?) //TODO last 3 blog entries on /index/ (?)

View File

@ -1,5 +1,9 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<?php
require_once (__DIR__ . '/../internals/base.php');
global $OPTIONS;
?>
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>Mikescher.com - About</title> <title>Mikescher.com - About</title>

59
www/pages/admin.php Normal file
View File

@ -0,0 +1,59 @@
<!DOCTYPE html>
<html lang="en">
<?php
require_once (__DIR__ . '/../internals/base.php');
?>
<head>
<meta charset="utf-8">
<title>Mikescher.com - About</title>
<link rel="icon" type="image/png" href="/data/images/favicon.png"/>
<link rel="canonical" href="https://www.mikescher.com/about"/>
<?php printCSS(); ?>
<?php includeScriptOnce("http://code.jquery.com/jquery-latest.min.js", true, '') ?>
<?php includeScriptOnce("/data/javascript/admin.js", true, 'defer') ?>
</head>
<body>
<div id="mastercontainer">
<?php $HEADER_ACTIVE = 'admin'; include (__DIR__ . '/../fragments/header.php'); ?>
<div id="content" class="content-responsive">
<div class="admincontent">
<div class="contentheader"><h1>Admin</h1><hr/></div>
<div class="boxedcontent">
<div class="bc_header">Version</div>
<div class="bc_data">
<div><b style="display:inline-block; min-width: 100px">Branch:&nbsp;</b><span><?php echo exec('git rev-parse --abbrev-ref HEAD'); ?></span></div>
<div><b style="display:inline-block; min-width: 100px">Commit:&nbsp;</b><span><?php echo exec('git rev-parse HEAD'); ?></span></div>
<div><b style="display:inline-block; min-width: 100px">Date:&nbsp;</b><span><?php echo exec('git log -1 --format=%cd'); ?></span></div>
<div><b style="display:inline-block; min-width: 100px">Message:&nbsp;</b><span><?php echo nl2br(exec('git log -1')); ?></span></div>
</div>
</div>
<div class="boxedcontent">
<div class="bc_header">ExtendedGitGraph</div>
<div class="bc_data">
<textarea class="egh_ajaxOutput" id="egh_ajaxOutput" readonly="readonly"></textarea>
<a class="button" href="javascript:startAjaxRefresh('<?php echo $CONFIG['ajax_secret'] ?>')">Update</a>
<a class="button" href="javascript:startAjaxRedraw('<?php echo $CONFIG['ajax_secret'] ?>')">Redraw</a>
</div>
</div>
</div>
</div>
<?php include (__DIR__ . '/../fragments/footer.php'); ?>
</div>
</body>
</html>

70
www/pages/admin_egh.php Normal file
View File

@ -0,0 +1,70 @@
<?php
require_once (__DIR__ . '/../internals/base.php');
require_once (__DIR__ . '/../extern/egh/ExtendedGitGraph.php');
$cmd = $OPTIONS['cmd'];
$secret = $OPTIONS['secret'];
if ($secret !== $CONFIG['ajax_secret'])
die('Unauthorized.');
function create()
{
global $CONFIG;
$v = new ExtendedGitGraph(__DIR__ . '/../temp/egh_cache.bin', ExtendedGitGraph::OUT_SESSION, __DIR__ . '/../temp/egh_log{num}.log');
$v->addRemote('github-user', null, 'Mikescher', 'Mikescher');
//$v->addRemote('github-user', null, 'Mikescher', 'Sam-Development');
//$v->addRemote('github-repository', null, 'Mikescher', 'Anastron/ColorRunner');
$v->addRemote('gitea-repository', null, 'Mikescher', 'Mikescher/server-scripts');
$v->addRemote('gitea-repository', null, 'Mikescher', 'Mikescher/apache-sites');
$v->addRemote('gitea-repository', null, 'Mikescher', 'Mikescher/MVU_API');
$v->setColorScheme($CONFIG['egh_theme']);
$v->ConnectionGithub->setAPIToken($CONFIG['egh_token']);
$v->ConnectionGitea->setURL('https://gogs.mikescher.com');
return $v;
}
if ($cmd === 'status')
{
if (session_status() !== PHP_SESSION_ACTIVE) session_start();
if (key_exists('ajax_progress_egh_refresh', $_SESSION))
echo $_SESSION['ajax_progress_egh_refresh'];
else
echo '[[ NO SESSION STARTED ]]';
return;
}
else if ($cmd === 'refresh')
{
set_time_limit(900); // 15min
$v = create();
$v->init();
$v->updateFromRemotes();
$v->generate();
file_put_contents(__DIR__ . '/../dynamic/egh.html', $v->getAll());
}
else if ($cmd === 'redraw')
{
set_time_limit(900); // 15min
$v = create();
$v->init();
$v->updateFromCache();
$v->generate();
file_put_contents(__DIR__ . '/../dynamic/egh.html', $v->getAll());
}
else
{
die('Wrong command.');
}

92
www/pages/login.php Normal file
View File

@ -0,0 +1,92 @@
<!DOCTYPE html>
<html lang="en">
<?php
require_once (__DIR__ . '/../internals/base.php');
global $OPTIONS;
$err = false;
if (key_exists('username', $_GET) && key_exists('password', $_GET) && key_exists('redirect', $_GET))
{
if ($_GET['username'] === $CONFIG['admin_username'] && $_GET['password'] === $CONFIG['admin_password'])
{
$expires = time() + (24*60*60); // 24h
$hash = hash('sha256', $_GET['username'] . ';' . $_GET['password']);
setcookie('mikescher_auth', $hash, $expires);
header('Location: ' . $_GET['redirect']);
die();
}
else
{
$err = true;
}
}
$redirect = $OPTIONS['login_target'];
?>
<head>
<meta charset="utf-8">
<title>Mikescher.com - Login</title>
<link rel="icon" type="image/png" href="/data/images/favicon.png"/>
<link rel="canonical" href="https://www.mikescher.com/login"/>
<?php printCSS(); ?>
</head>
<body>
<div id="mastercontainer">
<?php $HEADER_ACTIVE = 'login'; include (__DIR__ . '/../fragments/header.php'); ?>
<div id="content" class="content-responsive">
<div class="aboutcontent">
<div class="boxedcontent">
<div class="bc_header">Mikescher.com - Login</div>
<div class="bc_data">
<div class="form">
<form id="loginform" action="/login" method="GET">
<?php if ($err): ?>
<span class="loginerror">Wrong username or password</span>
<?php endif; ?>
<div>
<label for="username" class="required">Username</label>
<input name="username" id="username" type="text">
</div>
<div>
<label for="password">Password</label>
<input name="password" id="password" type="password">
</div>
<div style="display: none; visibility: hidden">
<label for="redirect">Redirect</label>
<input name="redirect" id="redirect" type="text" value="<?php echo $redirect ?>">
</div>
<div>
<button class="button" type="submit" name="yt0">Login</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<?php include (__DIR__ . '/../fragments/footer.php'); ?>
</div>
</body>
</html>

3
www/temp/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
*
!.gitignore
!.gitkeep

0
www/temp/.gitkeep Normal file
View File