From fa7daba41edb81958aae0e3cac9b0b5d2ecacef6 Mon Sep 17 00:00:00 2001 From: Dorian Zedler Date: Sun, 11 Jul 2021 09:12:51 +0200 Subject: [PATCH] Initial commit --- .gitignore | 1 + .htaccess | 30 +++ IconSmallSquareOutline.png | Bin 0 -> 23890 bytes index.php | 250 ++++++++++++++++++++ storageHelper.php | 31 +++ strings.php | 51 ++++ theme.php | 473 +++++++++++++++++++++++++++++++++++++ 7 files changed, 836 insertions(+) create mode 100644 .gitignore create mode 100644 .htaccess create mode 100644 IconSmallSquareOutline.png create mode 100644 index.php create mode 100644 storageHelper.php create mode 100644 strings.php create mode 100644 theme.php diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fe107c2 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/data.json \ No newline at end of file diff --git a/.htaccess b/.htaccess new file mode 100644 index 0000000..f4a3cef --- /dev/null +++ b/.htaccess @@ -0,0 +1,30 @@ + + +RewriteEngine On + +## Begin - Index +# If the requested path and file is not /index.php and the request +# has not already been internally rewritten to the index.php script +RewriteCond %{REQUEST_URI} !^/index\.php +# and the requested path and file doesn't directly match a physical file +RewriteCond %{REQUEST_FILENAME} !-f +# and the requested path and file doesn't directly match a physical folder +RewriteCond %{REQUEST_FILENAME} !-d +# internally rewrite the request to the index.php script +RewriteRule .* index.php [L] +## End - Index + +## Begin - Security +# Block all direct access for these folders +RewriteRule ^(\.git|cache|bin|logs|backup|webserver-configs|tests)/(.*) error [F] +# Block all direct access to files and folders beginning with a dot +RewriteRule (^|/)\.(?!well-known) - [F] +# Block access to specific files in the root folder +RewriteRule ^(LICENSE\.txt|composer\.lock|composer\.json|\.htaccess|README\.md|data\.json)$ error [F] +## End - Security + + + +# Begin - Prevent Browsing and Set Default Resources +Options -Indexes +DirectoryIndex index.php \ No newline at end of file diff --git a/IconSmallSquareOutline.png b/IconSmallSquareOutline.png new file mode 100644 index 0000000000000000000000000000000000000000..74c348d31685a4ed89ddad60dc9cfd0ba23249d4 GIT binary patch literal 23890 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 literal 0 HcmV?d00001 diff --git a/index.php b/index.php new file mode 100644 index 0000000..2187f27 --- /dev/null +++ b/index.php @@ -0,0 +1,250 @@ + true + ); + private $_themeConfig = array(); + private $_translations; + private $_basepath; + private $_resourcePath; + private $_path; + private $_dataFile = "./data.json"; + private $_storageHelper; + + public function __construct($translations) + { + session_start(); + $this->_translations = $translations; + + $this->_storageHelper = new StorageHelper($this->_dataFile); + + $this->_calculateBasepath(); + $this->_themeConfig["basePath"] = $this->_basepath; + $this->_themeConfig["mainIcon"] = $this->_resourcePath . "IconSmallSquareOutline.png"; + $this->_theme = new LandingpageTheme($this->_themeConfig, $this->_storageHelper, $this->_translations); + + $this->_processRequest(); + } + + private function _processRequest() + { + $this->_updatePermissions(); + $this->_checkPagePermissions(); + + if ($this->_stringEndsWith($this->_path, "submit")) { + if ($_SERVER['REQUEST_METHOD'] !== 'POST') { + $this->_redirect('/'); + } + + switch ($this->_path) { + case '/login/submit': + $this->_handleLoginSubmit(); + break; + + case '/logout/submit': + unset($_SESSION["auth"]); + $this->_redirect('/'); + break; + + case '/manage/submit': + $this->_handleManageSubmit(); + $this->_redirect('/manage'); + break; + + default: + $this->_redirect("/"); + break; + } + } else { + if ($this->_path === '/logout') { + $this->_redirect('/'); + } else { + $paramList = explode('/', ltrim($this->_path, '/'), 2); + $endpoint = $paramList[0]; + $username = $paramList[1]; + + if ($endpoint === "api" && isset($username)) + $this->_printJson($username); + else + $this->_theme->printPage($endpoint, $username); + } + } + + unset($_SESSION['lastResult']); + } + + private function _calculateBasepath() + { + if ($this->_serverConfig['hideIndexPhp']) { + $this->_basepath = str_replace(basename($_SERVER["SCRIPT_NAME"]), '', $_SERVER['SCRIPT_NAME']); + $this->_resourcePath = $this->_basepath; + } else { + $this->_basepath = $_SERVER["SCRIPT_NAME"]; + $this->_resourcePath = str_replace(basename($_SERVER["SCRIPT_NAME"]), '', $_SERVER['SCRIPT_NAME']); + } + + $this->_basepath = rtrim($this->_basepath, "/ "); + + if (($this->_basepath !== '' && strpos($_SERVER['REQUEST_URI'], $this->_basepath) === false) || $_SERVER['REQUEST_URI'] === $this->_basepath) + $this->_path = "/"; + else + $this->_path = str_replace($this->_basepath, "", $_SERVER['REQUEST_URI']); + } + + private function _redirect($path) + { + header('Location: ' . $this->_basepath . $path); + die(); + } + + // + // - Page printer (theme) + // + + private function _printJson($username) + { + header('Content-Type: application/json'); + header('Access-Control-Allow-Origin: *'); + $allUserdata = $this->_storageHelper->loadUserdata(); + if (array_key_exists($username, $allUserdata)) { + $userdata = $allUserdata[$username]; + die(json_encode(array( + "status" => 200, + "data" => array( + "time" => $userdata["time"], + "startedAt" => $userdata["startedAt"], + "header" => $userdata["header"] + ) + ))); + } else { + http_response_code(404); + die(json_encode(array( + "status" => 404, + "data" => null + ))); + } + } + + // ----------------------- + // - Permission handlers - + // ----------------------- + + private function _updatePermissions() + { + $_SESSION['permissions'][''] = false; + $_SESSION['permissions']['t'] = true; + $_SESSION['permissions']['api'] = true; + $_SESSION['permissions']['login'] = !$this->_isUserAuthenticated(); + $_SESSION['permissions']['logout'] = $this->_isUserAuthenticated(); + $_SESSION['permissions']['manage'] = $this->_isUserAuthenticated(); + } + + private function _checkPagePermissions() + { + $pageRedirectOnInsufficientPermissionsPriority = [ + 0 => "manage", + 1 => "login" + ]; + + $page = explode("/", $this->_path)[1]; + + if (!isset($_SESSION['permissions'][$page])) { + $this->_redirect('/'); + } else if ($_SESSION['permissions'][$page] === false) { + if (!$this->_isUserAuthenticated()) { + $_SESSION['lastResult'] = 'loginRequired'; + } + + if ($this->_path === '/' || $this->_path === '') { + // if the root is opened, do not throw an error! + unset($_SESSION['lastResult']); + } + + // redirect to the first page the user has access to + foreach ($pageRedirectOnInsufficientPermissionsPriority as $page) { + if ($_SESSION['permissions'][$page]) + $this->_redirect("/" . $page); + } + + die($this->_translations['results']['noPermissionToAnyPage']); + } + } + + // ------------------- + // - Submit handlers - + // ------------------- + + private function _handleLoginSubmit() + { + $username = $_POST["username"]; + $password = $_POST["password"]; + $userData = $this->_storageHelper->loadUserdata(); + if (array_key_exists($username, $userData) && password_verify($password, $userData[$username]['password'])) { + $_SESSION["auth"]["loggedIn"] = true; + $_SESSION["auth"]["username"] = $username; + $_SESSION['lastResult'] = "loginSuccess"; + $this->_redirect("/manage"); + } else { + $_SESSION['lastResult'] = "loginFailed"; + $this->_redirect("/login"); + } + } + + private function _handleManageSubmit() + { + $time = $_POST["time"]; + $header = $_POST["header"]; + $startedAt = time(); + $newData = array( + "time" => intval($time), + "header" => $header, + "startedAt" => $startedAt + ); + $this->_storageHelper->writeUserdata($_SESSION["auth"]["username"], $newData); + $_SESSION['lastResult'] = "timerSetSuccessfully"; + } + + // ---------------------------- + // - General helper functions - + // ---------------------------- + + private function _isUserAuthenticated() + { + $authenticated = + isset($_SESSION['auth']) + && isset($_SESSION['auth']['loggedIn']) + && $_SESSION['auth']['loggedIn'] === true + && isset($_SESSION['auth']['username']); + + if (!$authenticated && isset($_SESSION['auth'])) { + unset($_SESSION['auth']); + } + + return $authenticated; + } + + private function _stringStartsWith($haystack, $needle) + { + $length = strlen($needle); + return substr($haystack, 0, $length) === $needle; + } + + private function _stringEndsWith($haystack, $needle) + { + $length = strlen($needle); + if (!$length) { + return true; + } + return substr($haystack, -$length) === $needle; + } +} + +new SyncedTimer($translations); diff --git a/storageHelper.php b/storageHelper.php new file mode 100644 index 0000000..4e07038 --- /dev/null +++ b/storageHelper.php @@ -0,0 +1,31 @@ +_dataFile = $dataFile; + } + + function loadUserdata() + { + $data = json_decode(file_get_contents($this->_dataFile), true); + return $data; + } + + function writeUserdata($username, $newUserdata) + { + $allUserdata = $this->loadUserdata(); + $currentUserdata = $allUserdata[$username]; + $newUserdata = array_replace_recursive($currentUserdata, $newUserdata); + $dataFile = fopen($this->_dataFile, "w") or die("Unable to open file!"); + $allUserdata[$username] = $newUserdata; + + fwrite($dataFile, json_encode($allUserdata)); + fclose($dataFile) or die("Unable to write to data file!"); + } + +} \ No newline at end of file diff --git a/strings.php b/strings.php new file mode 100644 index 0000000..3095344 --- /dev/null +++ b/strings.php @@ -0,0 +1,51 @@ +{$customizationConfig['supportEmailAddress']} (%ERR%)"; +$translations['results']['permissionDenied'] = "Zugriff verweigert"; +$translations['results']['noPermissionToAnyPage'] = str_replace("%ERR%", "0005", $translations['results']['internalError']); +$translations['results']['loginSuccess'] = "Erfolgreich angemeldet"; +$translations['results']['loginFailed'] = "Ungültige Zugangsdaten"; +$translations['results']['loginRequired'] = "Bitte zuerst anmelden!"; +$translations['results']['oldPasswordIsWrong'] = "Das aktulle Passwort ist falsch"; +$translations['results']['newPasswordMustNotBeEqualToOldPassword'] = "Das neue Passwort darf nicht mit dem Alten übereinstimmen"; +$translations['results']['newPasswordAndRepeatDidNotMatch'] = "Die Passwörter stimmen nicht überein"; +$translations['results']['passwordIsTooShort'] = $translations['passwordRules'][0]; +$translations['results']['newPasswordMustNotBeOldPassword'] = "Das neue Passwort darf nicht mit dem Alten übereinstimmen."; +$translations['results']['passwordChangedSuccessfully'] = "Dein Passwort wurde erfolgreich geändert."; +$translations['results']['timerSetSuccessfully'] = "The timer was started successfully"; + +$translations['globals']['title'] = "{$customizationConfig['organizationName']} Account"; +$translations['globals']['usernameLabel'] = "Benutzername"; +$translations['globals']['passwordLabel'] = "Passwort"; +$translations['globals']['emailAddress'] = "E-Mail-Adresse"; + +$translations['login']['title'] = "Bitte anmelden"; +$translations['login']['submitLabel'] = "Anmelden"; +$translations['login']['footnote'] = "Login für Mitglieder des {$customizationConfig['fullOrganizationName']}"; + +$translations['changePassword']['passwordRulesHeader'] = "Regeln für Passwörter:"; +$translations['changePassword']['currentPasswordLabel'] = "Aktuelles Passwort"; +$translations['changePassword']['newPasswordLabel'] = "Neues Passwort"; +$translations['changePassword']['repeatNewPasswordLabel'] = "Neues Password Wiederholen"; +$translations['changePassword']['submitLabel'] = "Passwort ändern"; \ No newline at end of file diff --git a/theme.php b/theme.php new file mode 100644 index 0000000..f2d77b2 --- /dev/null +++ b/theme.php @@ -0,0 +1,473 @@ +_globalConfig = $config; + $this->_storageHelper = $storageHelper; + $this->_translations = $translations; + + $this->_resultLevels['loginSuccess'] = "success"; + $this->_resultLevels['loginFailed'] = "danger"; + $this->_resultLevels['ldapConnectFailed'] = "danger"; + $this->_resultLevels['ldapSearchFailed'] = "danger"; + $this->_resultLevels['ldapTlsInitializationFailed'] = "danger"; + $this->_resultLevels['bindingToLdapAdminFailed'] = "danger"; + $this->_resultLevels['loginRequired'] = "warning"; + $this->_resultLevels['oldPasswordIsWrong'] = "danger"; + $this->_resultLevels['newPasswordMustNotBeEqualToOldPassword'] = "danger"; + $this->_resultLevels['newPasswordAndRepeatDidNotMatch'] = "danger"; + $this->_resultLevels['passwordIsTooShort'] = "danger"; + $this->_resultLevels['passwordDoesNotContainANumberOrSpecialCharacter'] = "danger"; + $this->_resultLevels['passwordDoesNotContainALetter'] = "danger"; + $this->_resultLevels['passwordDoesNotContainAnUppercaseLetter'] = "danger"; + $this->_resultLevels['passwordDoesNotContainALowercaseLetter'] = "danger"; + $this->_resultLevels['passwordChangeLdapError'] = "danger"; + $this->_resultLevels['newPasswordMustNotBeOldPassword'] = "danger"; + $this->_resultLevels['passwordChangedSuccessfully'] = 'success'; + $this->_resultLevels['emailChangedSuccessfully'] = 'success'; + $this->_resultLevels['emailChangeLdapError'] = 'danger'; + $this->_resultLevels['invalidEmailError'] = 'danger'; + $this->_resultLevels['permissionDenied'] = 'danger'; + $this->_resultLevels['generateJitsiLinkRoomMustNotBeEmpty'] = 'danger'; + $this->_resultLevels['generateJitsiLinkSuccessfull'] = 'success'; + $this->_resultLevels['timerSetSuccessfully'] = 'success'; + } + + public function printPage($page, $parameters) + { + switch ($page) { + case 'login': + $this->_printLogin(); + break; + case "manage": + $this->_printManagePage(); + break; + case "t": + $this->_printTimerPage($parameters); + } + } + + private function _printLogin() + { + $this->_printHeader(true); +?> + + + + + +
+
+ +

_trId("login.title"); ?>

+ _printResultAlert(); ?> + + " name="username" required autofocus> + + " name="password" required> + +

_trId("login.footnote"); ?>

+
+
+ + _printFooter(); + } + + private function _printManagePage() + { + $userData = $this->_storageHelper->loadUserdata()[$_SESSION["auth"]["username"]]; + $this->_printHeader(); + ?> + + + +
+ + +
+

Curent timer

+ +

00:00:00

+

Manage timer

+ _printResultAlert(); ?> +
+
+ +
+ +
+ + +
+
+ + " required> +
+ +
+
+
+ + _printTimerJs($_SESSION["auth"]["username"]); + $this->_printFooter(); + } + + private function _printTimerPage($username) + { + $userData = $this->_storageHelper->loadUserdata(); + if (!array_key_exists($username, $userData)) { + $this->_printNotFoundPage(); + } + + ?> + + + + + + + + + + + + +
+
+ +
+

00:00:00

+
+
+ + +
+ + +
+ _printTimerJs($username); ?> + +
+ + + +

Not found!

+ + + + + + + + + + + + + + + + <?= $this->_trId("globals.title"); ?> + + + _printAlert($this->_resultToMessage($_SESSION['lastResult']), $this->_resultLevels[$_SESSION['lastResult']]); + } + + private function _printAlert($content, $level = 'waring', $dismissible = true) + { + ?> +
fade show" role="alert"> + + + + +
+ + + + +_translations['results'][$result]; + } + + private function _trId($id) + { + $result = $this->_translations; + foreach (explode(".", $id) as $sub) { + $result = $result[$sub]; + } + return $result; + } + }