Merge branch 'participo/docker-testing' of https://gitea.cwsvjudo.dedyn.io/marko/cwsvJudo into participo/docker-testing

This commit is contained in:
marko
2024-11-29 21:25:01 +01:00
19 changed files with 179 additions and 97 deletions

View File

@@ -20,7 +20,7 @@ dbConnector::connect(
);
// authentication of the current user
participo::authentificate();
participo::authenticate();
if (!participo::isUserAdmin()) {
header('Location: /participo', true, 301);
}

View File

@@ -14,7 +14,7 @@ dbConnector::connect(
$cwsvJudoConfig['db']['password']
);
participo::authentificate();
participo::authenticate();
$eventId = $_POST['eventId'] ?? null;
$startingTypeId = $_POST['type'] ?? null;

View File

@@ -14,7 +14,7 @@ dbConnector::connect(
$cwsvJudoConfig['db']['password']
);
participo::authentificate();
participo::authenticate();
$starterId = $_POST['starterId'] ?? null;
$returnToUrl = $_POST['returnToUrl'] ?? 'participo/';

View File

@@ -15,7 +15,7 @@ dbConnector::connect(
$cwsvJudoConfig['db']['password']
);
participo::authentificate();
participo::authenticate();
$loginName = $_POST['loginName'] ?? null;
$name = $_POST['name'] ?? null;

View File

@@ -2,14 +2,14 @@
/// @file common settings and includes for the participo api
/// - set locale to german
setlocale(LC_ALL, "de_DE@euro", "de_DE", "de", "ge");
/// - extend the include search path for
/// - extend the include search path for:
set_include_path(implode(
PATH_SEPARATOR,
[
get_include_path(),
/// - user defined libs (e.g. participo)
/// - user defined libs (e.g. participo)
"../lib",
/// - config files (we reuse the participo-wide configuration)
/// - config files (we reuse the participo-wide configuration)
".."
]
));

View File

@@ -21,7 +21,7 @@ setlocale(LC_ALL, 'de_DE@euro', 'de_DE', 'de', 'ge');
$cwsvJudoConfig['db']['password']
);
participo::authentificate();
participo::authenticate();
$user = participo::sessionUser();
$usersKids = getUsersKids(dbConnector::getDbConnection(), $_SESSION['user']['userId']);

View File

@@ -6,7 +6,8 @@ require_once 'participoLib/event.php';
// Configs
require_once 'config/participo.php';
require_once $config['basePath'] . '/config/cwsvJudo.config.php';
// @todo Switch to json saved settings
require_once $config['home'] . '/.local/cwsvJudo.config.php';
participo::init($cwsvJudoConfig);
@@ -24,12 +25,12 @@ participo::init($cwsvJudoConfig);
<!-- inits for the materializeCss -->
<script src="events.js"></script>
<title><?php echo($meta['title']); ?></title>
<title><?php echo ($meta['title'] ?? "title missing"); ?></title>
<meta name="description"
content="<?php echo($meta['description']); ?>" />
content="<?php echo ($meta['description'] ?? "description missing"); ?>" />
<link rel="icon" href="<?echo($config['ressourceUrl']);?>/graphiken/icons/cwsv.ico" />
<link rel="apple-touch-icon" href="<?echo($config['baseUrl']);?>/apple-touch-icon.png">
<link rel="icon" href="<? echo ($config['ressourceUrl']); ?>/graphiken/icons/cwsv.ico" />
<link rel="apple-touch-icon" href="<? echo ($config['baseUrl']); ?>/apple-touch-icon.png">
</head>
@@ -44,4 +45,4 @@ participo::init($cwsvJudoConfig);
</main>
</body>
</html>
</html>

View File

@@ -22,7 +22,7 @@ dbConnector::connect(
$cwsvJudoConfig["db"]["password"]
);
participo::authentificate();
participo::authenticate();
$meta = [
"title" => "Event Planer",

View File

@@ -4,7 +4,7 @@
<div class="nav-wrapper">
<a href="/participo" class="breadcrumb">cwsvJudo-Apps</a>
<a href="/participo/events" class="breadcrumb">
<?php echo($meta['title']); ?>
<?php echo($meta['title'] ?? "missing title"); ?>
</a>
<a class="right top-nav sidenav-trigger waves-effect waves-light hide-on-large-only" href="#"
data-target="nav-mobile">

View File

@@ -32,4 +32,4 @@ dbConnector::connect(
);
// authentication of the current user
participo::authentificate();
participo::authenticate();

View File

@@ -14,7 +14,7 @@
require_once $basePath . '/ressourcen/phpLib/parsedown/Parsedown.php';
require_once $basePath . '/ressourcen/phpLib/Spyc/Spyc.php';
participo::authentificate();
participo::authenticate();
// get a list of all infoZettel
$fileList = glob($basePath . '/infoZettel/*.md');

View File

@@ -24,7 +24,7 @@ class EventPage
public function getHtmlNotFound()
{
return '<div>Der Event "' .
$this->id .
$this->eventId .
'" existiert leider nicht!</div>' .
"<h2>Anstehende Termine</h2>" .
eventPlaner::getHtmlEventTable(eventPlaner::getComingWkEvents());

View File

@@ -7,6 +7,7 @@ require_once "participoLib/eventPage.php";
require_once "participoLib/starter.php";
require_once "participoLib/planer.php";
/**
* FrameWork for the participoApp
*/
@@ -123,7 +124,7 @@ class participo
*
* @retval void
*/
public static function authentificate($action = "login")
public static function authenticate($action = "login")
{
// Ensure a session is started
session_start();
@@ -147,15 +148,17 @@ class participo
logLoginsToJsonFile($user->getLoginName());
// we're not logged in, but authorized for the stuff we want to do. So don't redirect
return;
} else {
participo::addMessage("error", "Api key invalid (e.g., deprecated)");
}
}
// if not returned yet: no login, no valid apiKey -> redirect to login page
// if not returned yet: no login, no valid apiKey -> redirect to login page but remove the api key rom the query
if (!self::isLoginValid()) {
header(
"Location: login?returnToUrl=" .
urlencode(
$_SERVER["REQUEST_URI"] . ($_POST["fragment"] ?? "")
participo::removeQueryParameter($_SERVER["REQUEST_URI"], "apiKey") . ($_POST["fragment"] ?? "")
),
true,
301
@@ -164,6 +167,38 @@ class participo
}
}
/**
* remove query parameter from an url
*
* @param [string] $url url to clean of a query parameter
* @param [string] $param query parameter to remove
*
* @return [string] input url with query parameter (key and value) removed
*/
public static function removeQueryParameter(string $url, string $param): string
{
if (str_contains($url, "?")) {
list($baseUrl, $urlQuery) = explode('?', $url, 2);
parse_str($urlQuery, $urlQueryArr);
unset($urlQueryArr[$param]);
if (count($urlQueryArr)) {
return $baseUrl . '?' . http_build_query($urlQueryArr);
}
}
return $url;
}
/**
* Store persistent data in the session data
*/
public static function shutdown(){
$_SESSION["participo"] = [
"messages" => participo::getMessages()
];
}
/** Initialize the participoApp
*
* - validate the login
@@ -174,13 +209,33 @@ class participo
*/
public static function init($config)
{
self::authentificate();
// setup the storing of
register_shutdown_function("participo::shutdown");
// set up a database connection
self::initDb(
$config["db"]["host"],
$config["db"]["name"],
$config["db"]["user"],
$config["db"]["password"]
);
// authenticate the user
self::authenticate();
// init the participo app
// - get stored messages from the session data
self::initMessages();
}
/**
* Move the messages from the session data into the participo app
*
* - move means the source gets deleted after copying
*/
private static function initMessages() : void
{
self::$message = $_SESSION["participo"]["messages"] ?? ["error" => null, "success" => null, "notice" => null];
unset($_SESSION["participo"]["messages"]);
}
private static function initDb($host, $name, $user, $password)
@@ -194,28 +249,28 @@ class participo
* - Params in the request that aren't in given a parsing function aren't parsed and hence not returned.
*
* @param [array(paramName => parseFunction)] $params array of the name of the param and a sanitizer/parsing/input function
* @return array(parsedParam=>paramValue) Associative array of the name of the param and its parsed value
* @return [array(parsedParam=>paramValue)] Associative array of the name of the param and its parsed value
*/
public static function parseParams($params)
{
$method = $_SERVER["REQUEST_METHOD"];
$request = explode("/", substr(@$_SERVER["PATH_INFO"], 1));
// $request = explode("/", substr($_SERVER["PATH_INFO"], 1));
$parsedParams = [];
foreach ($params as $paramName => $parseFunction) {
$parsedParams[$paramName] = null;
switch ($method) {
// case 'PUT':
// do_something_with_put($request);
// break;
// case 'PUT':
// do_something_with_put($request);
// break;
case "POST":
$parsedParams[$paramName] = $parseFunction(
$_POST[$paramName]
$_POST[$paramName] ?? null
);
break;
case "GET":
$parsedParams[$paramName] = $parseFunction(
$_GET[$paramName]
$_GET[$paramName] ?? null
);
break;
default:
@@ -236,6 +291,11 @@ class participo
self::$message[$type] = (self::$message[$type] ?? "") . $message;
}
// public static function htmlEchoMessages(){
// echo(htmlRetMessage(participo::getMessages()));
// self::$message = null;
// }
/** check password for user
*
* @param string $loginName user who wants to get in
@@ -296,9 +356,7 @@ class participo
return self::hasUserAttribute($userId, "isAdmin");
}
public static function getUserId()
{
}
public static function getUserId() {}
/** get current logged in users kids */
public static function getKids($userId = null)
@@ -510,10 +568,10 @@ class AppCard
($this->link != null ? "</a>" : "") .
($this->imgUrl != null
? '<img alt="' .
$this->title .
'" style="display:block;margin-left:auto;margin-right:auto;max-height:10vh;" class="responsive-img" src="' .
$this->imgUrl .
'" />'
$this->title .
'" style="display:block;margin-left:auto;margin-right:auto;max-height:10vh;" class="responsive-img" src="' .
$this->imgUrl .
'" />'
: "") .
"<p>" .
$this->description .
@@ -619,7 +677,7 @@ function loadMarkdownFile($fileName)
{
// load the whole file
$fileText = file_get_contents($fileName);
// split at '---' to get ((),yamls,array)
// split at '---' to get ((),yaml,array)
$fileParts = preg_split('/[\n]*[-]{3}[\n]/', $fileText, 3);
// not all mdFiles have a yamlHeader, so the mdText can be at different indices
$yaml = [];

View File

@@ -1,12 +1,10 @@
<?php
require_once 'config/participo.php';
require_once $config['home'] . '/.local/cwsvJudo.config.php';
require_once 'participoLib/participo.php';
require_once 'participoLib/apiKey.php';
require_once './local/dbConf.php';
require_once $config['home'] . '/.local/cwsvJudo.config.php';
$dbConnection = dbConnector::connect(
$cwsvJudoConfig['db']['host'],
@@ -14,9 +12,9 @@ $dbConnection = dbConnector::connect(
$cwsvJudoConfig['db']['user'],
$cwsvJudoConfig['db']['password']
);
// Check, if the login is already set. If so move to the main page (or the returnToUrl)
if (isset($_SESSION['login'])) {
if (isset($_SESSION) && isset($_SESSION['login'])) {
// @todo prevent self redirection
header('Location: http://' . ($_POST['returnToUrl'] ?? '.'), true, 301);
}
@@ -46,53 +44,60 @@ else {
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!-- includes of neccessary libs -->
<!-- includes of necessary libs -->
<?php readfile('./shared/imports.php'); ?>
<title>cwsvJudo Online Apps</title>
<meta name="description" content="Loginseite der Online-Apps der Judoka des CWSV">
<meta name="description" content="Login-Seite der Online-Apps der Judoka des CWSV">
</head>
<body class="container">
<h1>Loginseite der Online-Apps der Judoka des CWSV</h1>
<?php echo(htmlRetMessage(participo::getMessages())); ?>
<form action="./login.php" method="post">
<fieldset>
<legend>Benutzerdaten</legend>
<div>
<label for="username">Benutzername</label>
<input id="username" type="text" name="f[username]" <?php echo isset($_POST['f']['username']) ? ' value="' . htmlspecialchars($_POST['f']['username']) . '"' : '' ?> />
</div>
<div>
<label for="password">Kennnwort</label>
<input id="password" type="password" name="f[password]" />
</div>
<?php if (isset($_GET['returnToUrl'])) {
echo('<input type="hidden" name="returnToUrl" value="' . htmlspecialchars($_GET['returnToUrl']) . '" />');
} ?>
<?php if (isset($_POST['returnToUrl'])) {
echo('<input type="hidden" name="returnToUrl" value="' . htmlspecialchars($_POST['returnToUrl']) . '" />');
} ?>
<input id="fragment" type="hidden" name="fragment" />
<!-- add the fragment to the post data-->
<script>
if(window.location.hash){
document.getElementById("fragment").value=window.location.hash;
}
</script>
</fieldset>
<fieldset>
<div>
<input type="submit" name="submit" value="Anmelden" />
<body>
<h1>Login-Seite der Online-Apps der Judoka des CWSV</h1>
<?php echo(htmlRetMessage(participo::getMessages())); ?>
<div class="container">
<div class="row">
<div class="col s6 offset-s3 z-depth-1">
<h2 id="title">Benutzerdaten</h2>
<form id="loginForm" action="./login.php" method="post">
<div class="input-field">
<input id="username" type="text" name="f[username]" <?php echo isset($_POST['f']['username']) ? ' value="' . htmlspecialchars($_POST['f']['username']) . '"' : '' ?> />
<label for="username">Benutzername</label>
</div>
<div class="input-field">
<input id="password" type="password" name="f[password]" />
<label for="password">Kennwort</label>
</div>
<?php # If a return url was given, add it as input to the form
if (isset($_GET['returnToUrl'])) {
echo('<input type="hidden" name="returnToUrl" value="' . htmlspecialchars($_GET['returnToUrl']) . '" />');
}
?>
<input id="fragment" type="hidden" name="fragment" />
<!-- add the fragment (stuff behind the # in the url) to the post data -->
<script>
if(window.location.hash){
document.getElementById("fragment").value=window.location.hash;
}
</script>
<!-- <p>
<input type="checkbox" id="remember"/>
<label for="remember" id="checkbox" >Remember me</label>
</p> -->
<input type="submit" name="submit" value="Anmelden" class="waves-effect waves-light btn" id="submitButton" />
<fieldset class="notice"><legend>Hinweise</legend>
<ul style="padding-left: inherit;">
<li style="list-style-type: circle;" >Logindaten sollten vom Übungsleiter vergeben worden sein.</li>
<ul><li style="list-style-type: circle;">Verlorene oder vergessene Logins oder Passwörter können über den Übungsleiter neu vergeben werden.</li></ul>
<li style="list-style-type: circle;" >Dieses Projekt ist in mehr oder weniger aktiven Entwicklung. Sollte mal was nicht funktionieren, kann es sein, dass ich gerade daran herum schreibe. Also ruhig zu einem späteren Zeitpunkt noch einmal probieren.</li>
</ul>
</fieldset>
</form>
</div>
</fieldset>
<fieldset class="notice"><legend>Hinweise</legend>
<ul style="padding-left: inherit;">
<li style="list-style-type: circle;" >Logindaten sollten vom Übungsleiter vergeben worden sein.</li>
<ul><li style="list-style-type: circle;">Verlorene oder vergessene Logins oder Passwörter können über den Übungsleiter neu vergeben werden.</li></ul>
<li style="list-style-type: circle;" >Dieses Projekt ist in mehr oder weniger aktiven Entwicklung. Sollte mal was nicht funktionieren, kann es sein, dass ich gerade daran herumschreibe. Also ruhig zu einem späteren Zeitpunkt noch einmal probieren.</li>
</ul>
</fieldset>
</form>
</div>
</div>
</body>
</html>

View File

@@ -4,13 +4,13 @@
if (ini_get('session.use_cookies')) {
$params = session_get_cookie_params();
setcookie(
session_name(),
$name=session_name(),
'',
time() - 42000,
$params['path'],
$params['domain'],
$params['secure"'],
$params['httponly']
$expires=(time() - 42000),
$path=$params['path'] ?? "",
$domain=$params['domain'] ?? "",
$params['secure"'] ?? false,
$params['httponly'] ?? false
);
}
session_destroy();

View File

@@ -19,7 +19,7 @@ dbConnector::connect(
$cwsvJudoConfig['db']['password']
);
participo::authentificate();
participo::authenticate();
$user = participo::sessionUser();
$usersKids = getUsersKids(dbConnector::getDbConnection(), $_SESSION['user']['userId']);

View File

@@ -4,3 +4,7 @@ password = "kodokan"
[url]
home = "http://127.0.0.1/participo"
# home = "http://cwsvjudo.bplaced.net/participo"
[settings]
headless = true

View File

@@ -14,10 +14,12 @@ class Participo:
def __init__(self) -> None:
from selenium.webdriver import Firefox, FirefoxOptions
options = FirefoxOptions()
options.add_argument("-headless")
self.config = load_config()
options = FirefoxOptions()
if self.config["settings"]["headless"]:
options.add_argument("-headless")
self.driver = Firefox(options=options)
self.delay = 5
@@ -33,8 +35,20 @@ class Participo:
self.driver.get(url=self.config["url"]["home"])
def load_section(self, section: str):
from urllib3.exceptions import ReadTimeoutError
section_url = "/".join((self.config["url"]["home"], section))
self.driver.get(url=section_url)
try:
self.driver.get(url=section_url)
except ReadTimeoutError as e:
logging.warning(
"\n".join(
(
f"TimeoutError loading {section} ({e} - {repr(e)})",
f"- Check for missing resources on section/page {section}",
)
)
)
def login(self):
credentials = self.config["credentials"]

View File

@@ -18,7 +18,7 @@ class TestParticipo(unittest.TestCase):
participo.login()
self.assertTrue(participo.check_login())
sections = ("events", "infoZettel", "attendance", "user")
sections = ("events", "infoZettel", "attendance", "user", "logout")
for section in sections:
with self.subTest(msg=f"- {section}"):
participo.load_section(section=section)