System update (refactoring)

This commit is contained in:
markseu 2016-06-27 15:28:10 +02:00
parent 0d8c3a17e8
commit 4cf437e623
7 changed files with 390 additions and 285 deletions

View file

@ -51,6 +51,7 @@ WebinterfaceUserPasswordMinLength: 4
WebinterfaceUserHashAlgorithm: bcrypt
WebinterfaceUserHashCost: 10
WebinterfaceUserStatus: active
WebinterfaceUserPending: none
WebinterfaceUserHome: /
WebinterfaceUserFile: user.ini
WebinterfaceNewFile: page-new-(.*).txt

View file

@ -5,7 +5,7 @@
// Command line plugin
class YellowCommandline
{
const Version = "0.6.11";
const Version = "0.6.12";
var $yellow; //access to API
var $files; //number of files
var $errors; //number of errors
@ -16,27 +16,19 @@ class YellowCommandline
function onLoad($yellow)
{
$this->yellow = $yellow;
$this->yellow->config->setDefault("commandlinePluginsUrl", "https://github.com/datenstrom/yellow-plugins");
$this->yellow->config->setDefault("commandlineThemesUrl", "https://github.com/datenstrom/yellow-themes");
$this->yellow->config->setDefault("commandlineVersionFile", "version.ini");
}
// Handle command
function onCommand($args)
{
list($name, $command) = $args;
list($command) = $args;
switch($command)
{
case "": $statusCode = $this->helpCommand(); break;
case "version": $statusCode = $this->versionCommand($args); break;
case "build": $statusCode = $this->buildCommand($args); break;
case "clean": $statusCode = $this->cleanCommand($args); break;
default: $statusCode = $this->pluginCommand($args);
}
if($statusCode == 0)
{
$statusCode = 400;
echo "Yellow $command: Command not found\n";
case "version": $statusCode = $this->versionCommand($args); break;
default: $statusCode = 0;
}
return $statusCode;
}
@ -44,9 +36,9 @@ class YellowCommandline
// Handle command help
function onCommandHelp()
{
$help .= "version\n";
$help .= "build [DIRECTORY LOCATION]\n";
$help .= "clean [DIRECTORY LOCATION]\n";
$help .= "version\n";
return $help;
}
@ -58,35 +50,11 @@ class YellowCommandline
return 200;
}
// Show software version and updates
function versionCommand($args)
{
$statusCode = 0;
$serverSoftware = $this->yellow->toolbox->getServerSoftware();
echo "Yellow ".YellowCore::Version.", PHP ".PHP_VERSION.", $serverSoftware\n";
list($dummy, $command) = $args;
list($statusCode, $dataCurrent) = $this->getSoftwareVersion();
list($statusCode, $dataLatest) = $this->getSoftwareVersion(false);
foreach($dataCurrent as $key=>$value)
{
if(strnatcasecmp($dataCurrent[$key], $dataLatest[$key]) >= 0)
{
echo "$key $value\n";
} else {
echo "$key $value - Update available\n";
++$updates;
}
}
if($statusCode != 200) echo "ERROR checking updates: $dataLatest[error]\n";
if($updates) echo "Yellow $command: $updates update".($updates==1 ? "":"s")." available\n";
return $statusCode;
}
// Build static files
function buildCommand($args)
{
$statusCode = 0;
list($dummy, $command, $path, $location) = $args;
list($command, $path, $location) = $args;
if(empty($location) || $location[0]=='/')
{
if($this->checkStaticConfig())
@ -95,13 +63,9 @@ class YellowCommandline
} else {
$statusCode = 500;
$this->files = 0; $this->errors = 1;
if($this->yellow->config->get("installationMode"))
{
echo "ERROR building files: Please open your website in a web browser to detect server settings!\n";
} else {
$fileName = $this->yellow->config->get("configDir").$this->yellow->config->get("configFile");
echo "ERROR building files: Please configure ServerScheme, ServerName, ServerBase, ServerTime in file '$fileName'!\n";
}
$fileName = $this->yellow->config->get("configDir").$this->yellow->config->get("configFile");
echo "ERROR building files: Please configure ServerScheme, ServerName, ServerBase, ServerTime in file '$fileName'!\n";
echo "ERROR building files: To see your web server configuration, open your website in a web browser!\n";
}
echo "Yellow $command: $this->files file".($this->files!=1 ? 's' : '');
echo ", $this->errors error".($this->errors!=1 ? 's' : '');
@ -116,7 +80,6 @@ class YellowCommandline
// Build static files and additional locations
function buildStatic($path, $location)
{
$this->yellow->toolbox->timerStart($time);
$path = rtrim(empty($path) ? $this->yellow->config->get("staticDir") : $path, '/');
$this->files = $this->errors = $statusCode = 0;
$this->locationsArgs = $this->locationsArgsPagination = array();
@ -156,8 +119,6 @@ class YellowCommandline
} else {
$statusCode = $this->buildStaticFile($path, $location);
}
$this->yellow->toolbox->timerStop($time);
if(defined("DEBUG") && DEBUG>=1) echo "YellowCommandline::buildStatic time:$time ms\n";
return $statusCode;
}
@ -261,7 +222,7 @@ class YellowCommandline
function cleanCommand($args)
{
$statusCode = 0;
list($dummy, $command, $path, $location) = $args;
list($command, $path, $location) = $args;
if(empty($location) || $location[0]=='/')
{
$statusCode = $this->cleanStatic($path, $location);
@ -280,7 +241,7 @@ class YellowCommandline
$path = rtrim(empty($path) ? $this->yellow->config->get("staticDir") : $path, '/');
if(empty($location))
{
$statusCode = max($statusCode, $this->pluginCommand(array("all", "clean")));
$statusCode = max($statusCode, $this->commandForward("all", "clean"));
$statusCode = max($statusCode, $this->cleanStaticDirectory($path));
} else {
$statusCode = $this->cleanStaticFile($path, $location);
@ -319,30 +280,53 @@ class YellowCommandline
return $statusCode;
}
// Forward plugin command
function pluginCommand($args)
// Forward command to other plugins
function commandForward($args)
{
$statusCode = 0;
foreach($this->yellow->plugins->plugins as $key=>$value)
{
if($key == "commandline") continue;
if(method_exists($value["obj"], "onCommand"))
if(method_exists($value["obj"], "onCommand") && $found)
{
$statusCode = $value["obj"]->onCommand($args);
$statusCode = $value["obj"]->onCommand(func_get_args());
if($statusCode != 0) break;
}
if($key == "commandline") $found = true;
}
return $statusCode;
}
// Show software version and updates
function versionCommand($args)
{
$statusCode = 0;
$serverSoftware = $this->yellow->toolbox->getServerSoftware();
echo "Yellow ".YellowCore::Version.", PHP ".PHP_VERSION.", $serverSoftware\n";
list($command) = $args;
list($statusCode, $dataCurrent) = $this->getSoftwareVersion();
list($statusCode, $dataLatest) = $this->getSoftwareVersion(true);
foreach($dataCurrent as $key=>$value)
{
if(strnatcasecmp($dataCurrent[$key], $dataLatest[$key]) >= 0)
{
echo "$key $value\n";
} else {
echo "$key $value - Update available\n";
++$updates;
}
}
if($statusCode != 200) echo "ERROR checking updates: $dataLatest[error]\n";
if($updates) echo "Yellow $command: $updates update".($updates==1 ? "":"s")." available\n";
return $statusCode;
}
// Check static configuration
function checkStaticConfig()
{
$installationMode = $this->yellow->config->get("installationMode");
$serverScheme = $this->yellow->config->get("serverScheme");
$serverName = $this->yellow->config->get("serverName");
$serverBase = $this->yellow->config->get("serverBase");
return !$installationMode && !empty($serverScheme) && !empty($serverName) &&
return !empty($serverScheme) && !empty($serverName) &&
$this->yellow->lookup->isValidLocation($serverBase) && $serverBase!="/";
}
@ -434,66 +418,6 @@ class YellowCommandline
return $locations;
}
// Return software version
function getSoftwareVersion($current = true)
{
$data = array();
if($current)
{
$statusCode = 200;
foreach($this->yellow->plugins->getData() as $key=>$value) $data[$key] = $value;
foreach($this->yellow->themes->getData() as $key=>$value) $data[$key] = $value;
} else {
list($statusCodePlugins, $dataPlugins) = $this->getSoftwareVersionFromUrl($this->yellow->config->get("commandlinePluginsUrl"));
list($statusCodeThemes, $dataThemes) = $this->getSoftwareVersionFromUrl($this->yellow->config->get("commandlineThemesUrl"));
$statusCode = max($statusCodePlugins, $statusCodeThemes);
$data = array_merge($dataPlugins, $dataThemes);
}
return array($statusCode, $data);
}
// Return software version from URL
function getSoftwareVersionFromUrl($url)
{
$data = array();
$urlVersion = $url;
if(preg_match("#^https://github.com/(.+)$#", $url, $matches))
{
$urlVersion = "https://raw.githubusercontent.com/".$matches[1]."/master/".$this->yellow->config->get("commandlineVersionFile");
}
if(extension_loaded("curl"))
{
$curlHandle = curl_init();
curl_setopt($curlHandle, CURLOPT_URL, $urlVersion);
curl_setopt($curlHandle, CURLOPT_USERAGENT, "Mozilla/5.0 (compatible; YellowCore/".YellowCore::Version).")";
curl_setopt($curlHandle, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curlHandle, CURLOPT_CONNECTTIMEOUT, 30);
$rawData = curl_exec($curlHandle);
$statusCode = curl_getinfo($curlHandle, CURLINFO_HTTP_CODE);
curl_close($curlHandle);
if($statusCode == 200)
{
if(defined("DEBUG") && DEBUG>=2) echo "YellowCommandline::getSoftwareVersion location:$urlVersion\n";
foreach($this->yellow->toolbox->getTextLines($rawData) as $line)
{
preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches);
if(!empty($matches[1]) && !empty($matches[2]))
{
list($version, $url) = explode(',', $matches[2]);
$data[$matches[1]] = $version;
if(defined("DEBUG") && DEBUG>=3) echo "YellowCommandline::getSoftwareVersion $matches[1]:$version\n";
}
}
}
if($statusCode == 0) $statusCode = 444;
$data["error"] = "$url - ".$this->yellow->toolbox->getHttpStatusFormatted($statusCode);
} else {
$statusCode = 500;
$data["error"] = "Plugin 'commandline' requires cURL library!";
}
return array($statusCode, $data);
}
// Return command help
function getCommandHelp()
{
@ -512,6 +436,21 @@ class YellowCommandline
uksort($data, strnatcasecmp);
return $data;
}
// Return software version
function getSoftwareVersion($latest = false)
{
$data = array();
if($this->yellow->plugins->isExisting("update"))
{
list($statusCode, $data) = $this->yellow->plugins->get("update")->getSoftwareVersion($latest);
} else {
$statusCode = 200;
foreach($this->yellow->plugins->getData() as $key=>$value) $data[$key] = $value;
foreach($this->yellow->themes->getData() as $key=>$value) $data[$key] = $value;
}
return array($statusCode, $data);
}
}
$yellow->plugins->register("commandline", "YellowCommandline", YellowCommandline::Version);

View file

@ -89,21 +89,6 @@ class YellowCore
$this->themes->load();
}
// Handle command
function command($name, $args = NULL)
{
$statusCode = 0;
if($this->plugins->isExisting($name))
{
$plugin = $this->plugins->plugins[$name];
if(method_exists($plugin["obj"], "onCommand")) $statusCode = $plugin["obj"]->onCommand(func_get_args());
} else {
$statusCode = 500;
$this->page->error($statusCode, "Plugin '$name' does not exist!");
}
return $statusCode;
}
// Handle request
function request()
{
@ -262,6 +247,30 @@ class YellowCore
}
}
// Handle command
function command($args = NULL)
{
$statusCode = 0;
$this->toolbox->timerStart($time);
foreach($this->plugins->plugins as $key=>$value)
{
if(method_exists($value["obj"], "onCommand"))
{
$statusCode = $value["obj"]->onCommand(func_get_args());
if($statusCode != 0) break;
}
}
$this->toolbox->timerStop($time);
if(defined("DEBUG") && DEBUG>=1) echo "YellowCore::command time:$time ms<br/>\n";
if($statusCode == 0)
{
$statusCode = 400;
list($name, $command) = func_get_args();
echo "Yellow $command: Command not found\n";
}
return $statusCode;
}
// Parse snippet
function snippet($name, $args = NULL)
{

262
system/plugins/update.php Normal file
View file

@ -0,0 +1,262 @@
<?php
// Copyright (c) 2013-2016 Datenstrom, http://datenstrom.se
// This file may be used and distributed under the terms of the public license.
// Update plugin
class YellowUpdate
{
const Version = "0.6.1";
var $yellow; //access to API
// Handle initialisation
function onLoad($yellow)
{
$this->yellow = $yellow;
$this->yellow->config->setDefault("updatePluginsUrl", "https://github.com/datenstrom/yellow-plugins");
$this->yellow->config->setDefault("updateThemesUrl", "https://github.com/datenstrom/yellow-themes");
$this->yellow->config->setDefault("updateVersionFile", "version.ini");
$this->yellow->config->setDefault("updateFile", "update.ini");
}
// Handle request
function onRequest($serverScheme, $serverName, $base, $location, $fileName)
{
$statusCode = 0;
if($this->isInstallation())
{
$statusCode = $this->processRequestInstallation($serverScheme, $serverName, $base, $location, $fileName);
} else {
$statusCode = $this->processRequestUpdate($serverScheme, $serverName, $base, $location, $fileName);
}
return $statusCode;
}
// Handle command
function onCommand($args)
{
list($command) = $args;
switch($command)
{
case "update": $statusCode = $this->updateCommand($args); break;
default: $statusCode = 0;
}
return $statusCode;
}
// Handle command help
function onCommandHelp()
{
return "update [FEATURE]";
}
// Update plugins and themes
function updateCommand($args)
{
$statusCode = 0;
list($command, $feature) = $args;
list($statusCode, $dataCurrent) = $this->getSoftwareVersion();
list($statusCode, $dataLatest) = $this->getSoftwareVersion(true);
foreach($dataCurrent as $key=>$value)
{
if(strnatcasecmp($dataCurrent[$key], $dataLatest[$key]) < 0)
{
if(empty($feature) || preg_match("/$feature/i", $key)) ++$updates;
}
}
if($statusCode != 200) echo "ERROR checking updates: $data[error]\n";
if($updates)
{
echo "Yellow $command: $updates update".($updates==1 ? "":"s")." available\n";
} else {
echo "Yellow $command: No updates available\n";
}
return $statusCode;
}
// Process request to update software
function processRequestUpdate($serverScheme, $serverName, $base, $location, $fileName)
{
return 0;
}
// Process request to install website
function processRequestInstallation($serverScheme, $serverName, $base, $location, $fileName)
{
$statusCode = 0;
if(!$this->yellow->isStaticFile($location, $fileName, false))
{
$fileName = $this->yellow->lookup->findFileNew($fileName,
$this->yellow->config->get("webinterfaceNewFile"), $this->yellow->config->get("configDir"), "installation");
$this->yellow->pages->pages["root/"] = array();
$this->yellow->page = new YellowPage($this->yellow);
$this->yellow->page->setRequestInformation($serverScheme, $serverName, $base, $location, $fileName);
$this->yellow->page->parseData($this->getRawDataInstallation($fileName, $this->yellow->getRequestLanguage()), false, 404);
$this->yellow->page->parserSafeMode = false;
$this->yellow->page->parseContent();
$name = trim(preg_replace("/[^\pL\d\-\. ]/u", "-", $_REQUEST["name"]));
$email = trim($_REQUEST["email"]);
$password = trim($_REQUEST["password"]);
$language = trim($_REQUEST["language"]);
$status = trim($_REQUEST["status"]);
if($status == "install")
{
$status = "ok";
$fileNameHome = $this->yellow->lookup->findFileFromLocation("/");
$fileData = strreplaceu("\r\n", "\n", $this->yellow->toolbox->readFile($fileNameHome));
if($fileData==$this->getRawDataHome("en") && $language!="en")
{
$status = $this->yellow->toolbox->createFile($fileNameHome, $this->getRawDataHome($language)) ? "ok" : "error";
if($status == "error") $this->yellow->page->error(500, "Can't write file '$fileNameHome'!");
}
}
if($status == "ok")
{
if(!empty($email) && !empty($password) && $this->yellow->plugins->isExisting("webinterface"))
{
$fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("webinterfaceUserFile");
$status = $this->yellow->plugins->get("webinterface")->users->update($fileNameUser, $email, $password, $name, $language) ? "ok" : "error";
if($status == "error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!");
}
}
if($status == "ok")
{
if($this->yellow->config->get("sitename") == "Yellow") $_REQUEST["sitename"] = $name;
$fileNameConfig = $this->yellow->config->get("configDir").$this->yellow->config->get("configFile");
$status = $this->yellow->config->update($fileNameConfig, $this->getConfigData()) ? "done" : "error";
if($status == "error") $this->yellow->page->error(500, "Can't write file '$fileNameConfig'!");
}
if($status == "done")
{
$statusCode = 303;
$location = $this->yellow->lookup->normaliseUrl($serverScheme, $serverName, $base, $location);
$this->yellow->sendStatus($statusCode, $location);
} else {
$statusCode = $this->yellow->sendPage();
}
}
return $statusCode;
}
// Return raw data for installation page
function getRawDataInstallation($fileName, $language)
{
$rawData = $this->yellow->toolbox->readFile($fileName);
if(empty($rawData))
{
$this->yellow->text->setLanguage($language);
$rawData = "---\nTitle:".$this->yellow->text->get("webinterfaceInstallationTitle")."\nLanguage:$language\nNavigation:navigation\n---\n";
$rawData .= "<form class=\"installation-form\" action=\"".$this->yellow->page->getLocation()."\" method=\"post\">\n";
$rawData .= "<p><label for=\"name\">".$this->yellow->text->get("webinterfaceSignupName")."</label><br /><input class=\"form-control\" type=\"text\" maxlength=\"64\" name=\"name\" id=\"name\" value=\"\"></p>\n";
$rawData .= "<p><label for=\"email\">".$this->yellow->text->get("webinterfaceSignupEmail")."</label><br /><input class=\"form-control\" type=\"text\" maxlength=\"64\" name=\"email\" id=\"email\" value=\"\"></p>\n";
$rawData .= "<p><label for=\"password\">".$this->yellow->text->get("webinterfaceSignupPassword")."</label><br /><input class=\"form-control\" type=\"password\" maxlength=\"64\" name=\"password\" id=\"password\" value=\"\"></p>\n";
if(count($this->yellow->text->getLanguages()) > 1)
{
$rawData .= "<p>";
foreach($this->yellow->text->getLanguages() as $language)
{
$checked = $language==$this->yellow->text->language ? " checked=\"checked\"" : "";
$rawData .= "<label for=\"$language\"><input type=\"radio\" name=\"language\" id=\"$language\" value=\"$language\"$checked> ".$this->yellow->text->getTextHtml("languageDescription", $language)."</label><br />";
}
$rawData .= "</p>\n";
}
$rawData .= "<input class=\"btn\" type=\"submit\" value=\"".$this->yellow->text->get("webinterfaceOkButton")."\" />\n";
$rawData .= "<input type=\"hidden\" name=\"status\" value=\"install\" />\n";
$rawData .= "</form>\n";
}
return $rawData;
}
// Return raw data for home page
function getRawDataHome($language)
{
$rawData = "---\nTitle: Home\n---\n".strreplaceu("\\n", "\n", $this->yellow->text->getText("webinterfaceInstallationHomePage", $language));
return $rawData;
}
// Return configuration data
function getConfigData()
{
$data = array();
foreach($_REQUEST as $key=>$value)
{
if(!$this->yellow->config->isExisting($key)) continue;
$data[$key] = trim($value);
}
$data["# serverScheme"] = $this->yellow->toolbox->getServerScheme();
$data["# serverName"] = $this->yellow->toolbox->getServerName();
$data["# serverBase"] = $this->yellow->toolbox->getServerBase();
$data["# serverTime"] = $this->yellow->toolbox->getServerTime();
$data["installationMode"] = "0";
return $data;
}
// Return software version
function getSoftwareVersion($latest = false)
{
$data = array();
if($latest)
{
list($statusCodePlugins, $dataPlugins) = $this->getSoftwareVersionFromUrl($this->yellow->config->get("updatePluginsUrl"));
list($statusCodeThemes, $dataThemes) = $this->getSoftwareVersionFromUrl($this->yellow->config->get("updateThemesUrl"));
$statusCode = max($statusCodePlugins, $statusCodeThemes);
$data = array_merge($dataPlugins, $dataThemes);
} else {
$statusCode = 200;
foreach($this->yellow->plugins->getData() as $key=>$value) $data[$key] = $value;
foreach($this->yellow->themes->getData() as $key=>$value) $data[$key] = $value;
}
return array($statusCode, $data);
}
// Return software version from URL
function getSoftwareVersionFromUrl($url)
{
$data = array();
$urlVersion = $url;
if(preg_match("#^https://github.com/(.+)$#", $url, $matches))
{
$urlVersion = "https://raw.githubusercontent.com/".$matches[1]."/master/".$this->yellow->config->get("updateVersionFile");
}
if(extension_loaded("curl"))
{
$curlHandle = curl_init();
curl_setopt($curlHandle, CURLOPT_URL, $urlVersion);
curl_setopt($curlHandle, CURLOPT_USERAGENT, "Mozilla/5.0 (compatible; YellowCore/".YellowCore::Version).")";
curl_setopt($curlHandle, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curlHandle, CURLOPT_CONNECTTIMEOUT, 30);
$rawData = curl_exec($curlHandle);
$statusCode = curl_getinfo($curlHandle, CURLINFO_HTTP_CODE);
curl_close($curlHandle);
if($statusCode == 200)
{
if(defined("DEBUG") && DEBUG>=2) echo "YellowUpdate::getSoftwareVersion location:$urlVersion\n";
foreach($this->yellow->toolbox->getTextLines($rawData) as $line)
{
preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches);
if(!empty($matches[1]) && !empty($matches[2]))
{
list($version, $url) = explode(',', $matches[2]);
$data[$matches[1]] = $version;
if(defined("DEBUG") && DEBUG>=3) echo "YellowUpdate::getSoftwareVersion $matches[1]:$version\n";
}
}
}
if($statusCode == 0) $statusCode = 444;
$data["error"] = "$url - ".$this->yellow->toolbox->getHttpStatusFormatted($statusCode);
} else {
$statusCode = 500;
$data["error"] = "Plugin 'update' requires cURL library!";
}
return array($statusCode, $data);
}
// Return if installation is necessary
function isInstallation()
{
return PHP_SAPI!="cli" && $this->yellow->config->get("installationMode");
}
}
$yellow->plugins->register("update", "YellowUpdate", YellowUpdate::Version);
?>

View file

@ -1,4 +1,4 @@
/* Yellow web interface 0.6.8 */
/* Yellow web interface 0.6.9 */
.yellow-bar { position:relative; overflow:hidden; height:2em; margin-bottom:10px; }
.yellow-bar-left { display:block; float:left; }

View file

@ -4,7 +4,7 @@
// Yellow API
var yellow =
{
version: "0.6.8",
version: "0.6.9",
action: function(action) { yellow.webinterface.action(action, "none"); },
onLoad: function() { yellow.webinterface.loadInterface(); },
onClick: function(e) { yellow.webinterface.hidePanesOnClick(yellow.toolbox.getEventElement(e)); },
@ -132,7 +132,7 @@ yellow.webinterface =
"<form method=\"post\">"+
"<a href=\"#\" onclick=\"yellow.action('close'); return false;\" class=\"yellow-close\">x</a>"+
"<h1>"+this.getText("SignupTitle")+"</h1>"+
"<div id=\"yellow-pane-signup-status\" class=\""+paneStatus+"\">"+this.getText(paneAction+"Status", "", paneStatus)+"</div>"+
"<div id=\"yellow-pane-signup-status\" class=\""+paneStatus+"\">"+this.getText(paneAction+"Status", "webinterface", paneStatus)+"</div>"+
"<div id=\"yellow-pane-signup-fields\">"+
"<input type=\"hidden\" name=\"action\" value=\"signup\" />"+
"<p><label for=\"yellow-pane-signup-name\">"+this.getText("SignupName")+"</label><br /><input class=\"yellow-form-control\" name=\"name\" id=\"yellow-pane-signup-name\" maxlength=\"64\" value=\""+yellow.toolbox.encodeHtml(this.getRequest("name"))+"\" /></p>"+
@ -170,7 +170,7 @@ yellow.webinterface =
"<form method=\"post\">"+
"<a href=\"#\" onclick=\"yellow.action('close'); return false;\" class=\"yellow-close\">x</a>"+
"<h1 id=\"yellow-pane-settings-title\">"+this.getText("SettingsTitle")+"</h1>"+
"<div id=\"yellow-pane-settings-status\" class=\""+paneStatus+"\">"+this.getText(paneAction+"Status", "", paneStatus)+"</div>"+
"<div id=\"yellow-pane-settings-status\" class=\""+paneStatus+"\">"+this.getText(paneAction+"Status", "webinterface", paneStatus)+"</div>"+
"<div id=\"yellow-pane-settings-fields\">"+
"<input type=\"hidden\" name=\"action\" value=\"settings\" />"+
"<p><label for=\"yellow-pane-settings-name\">"+this.getText("SignupName")+"</label><br /><input class=\"yellow-form-control\" name=\"name\" id=\"yellow-pane-settings-name\" maxlength=\"64\" value=\""+yellow.toolbox.encodeHtml(this.getRequest("name"))+"\" /></p>"+

View file

@ -5,7 +5,7 @@
// Web interface plugin
class YellowWebinterface
{
const Version = "0.6.8";
const Version = "0.6.9";
var $yellow; //access to API
var $active; //web interface is active? (boolean)
var $userEmail; //web interface user
@ -13,7 +13,6 @@ class YellowWebinterface
var $userRestrictions; //web interface user can change page? (boolean)
var $action; //web interface action
var $status; //web interface status
var $installation; //web interface installation
var $users; //web interface users
var $merge; //web interface merge
var $rawDataSource; //raw data of page for comparison
@ -23,7 +22,6 @@ class YellowWebinterface
function onLoad($yellow)
{
$this->yellow = $yellow;
$this->installation = new YellowInstallation($yellow);
$this->users = new YellowUsers($yellow);
$this->merge = new YellowMerge($yellow);
$this->yellow->config->setDefault("webinterfaceServerScheme", $this->yellow->config->get("serverScheme"));
@ -33,6 +31,7 @@ class YellowWebinterface
$this->yellow->config->setDefault("webinterfaceUserHashAlgorithm", "bcrypt");
$this->yellow->config->setDefault("webinterfaceUserHashCost", "10");
$this->yellow->config->setDefault("webinterfaceUserStatus", "active");
$this->yellow->config->setDefault("webinterfaceUserPending", "none");
$this->yellow->config->setDefault("webinterfaceUserHome", "/");
$this->yellow->config->setDefault("webinterfaceUserFile", "user.ini");
$this->yellow->config->setDefault("webinterfaceNewFile", "page-new-(.*).txt");
@ -44,10 +43,9 @@ class YellowWebinterface
function onRequest($serverScheme, $serverName, $base, $location, $fileName)
{
$statusCode = 0;
if($this->yellow->config->get("installationMode"))
if($this->checkRequest($location))
{
$statusCode = $this->installation->processRequest($serverScheme, $serverName, $base, $location, $fileName);
} else if($this->checkRequest($location)) {
list($serverScheme, $serverName, $base, $location, $fileName) = $this->updateRequestInformation();
$statusCode = $this->processRequest($serverScheme, $serverName, $base, $location, $fileName);
}
return $statusCode;
@ -107,7 +105,7 @@ class YellowWebinterface
// Handle command
function onCommand($args)
{
list($name, $command) = $args;
list($command) = $args;
switch($command)
{
case "clean": $statusCode = $this->cleanCommand($args); break;
@ -120,14 +118,15 @@ class YellowWebinterface
// Handle command help
function onCommandHelp()
{
return "user [EMAIL PASSWORD NAME LANGUAGE STATUS HOME]\n";
return "user [EMAIL PASSWORD NAME LANGUAGE STATUS]\n";
}
// Clean user accounts
function cleanCommand($args)
{
$statusCode = 0;
$fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("webinterfaceUserFile");
$statusCode = $this->users->clean($fileNameUser) ? 200 : 500;
if(!$this->users->clean($fileNameUser)) $statusCode = 500;
if($statusCode == 500) echo "ERROR cleaning configuration: Can't write file '$fileNameUser'!\n";
return status;
}
@ -136,7 +135,7 @@ class YellowWebinterface
function userCommand($args)
{
$statusCode = 0;
list($dummy, $command, $email, $password, $name, $language, $status, $home) = $args;
list($command, $email, $password, $name, $language, $status) = $args;
if(!empty($email) && !empty($password))
{
$userExisting = $this->users->isExisting($email);
@ -149,7 +148,7 @@ class YellowWebinterface
if($status == "ok")
{
$fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("webinterfaceUserFile");
$status = $this->users->update($fileNameUser, $email, $password, $name, $language, $status, $home) ? "ok" : "error";
$status = $this->users->update($fileNameUser, $email, $password, $name, $language, $status) ? "ok" : "error";
if($status == "error") echo "ERROR updating configuration: Can't write file '$fileNameUser'!\n";
}
if($status == "ok")
@ -173,7 +172,6 @@ class YellowWebinterface
function processRequest($serverScheme, $serverName, $base, $location, $fileName)
{
$statusCode = 0;
list($serverScheme, $serverName, $base, $location, $fileName) = $this->updateRequestInformation();
if($this->checkUser($location, $fileName))
{
switch($_REQUEST["action"])
@ -203,7 +201,6 @@ class YellowWebinterface
{
$statusCode = $this->yellow->processRequest($serverScheme, $serverName, $base, $location, $fileName, false);
$fileNameConfig = $this->yellow->config->get("configDir").$this->yellow->config->get("configFile");
if($this->action == "off") $this->yellow->page->error(500, "Please configure webmaster email in file '$fileNameConfig'!");
if($this->action == "fail") $this->yellow->page->error(500, "Login failed, [please log in](javascript:yellow.action('login');)!");
}
return $statusCode;
@ -563,7 +560,6 @@ class YellowWebinterface
$this->action = "fail";
}
}
if(!$this->users->getNumber() && !$this->users->isWebmaster()) $this->action = "off";
return $this->isUser();
}
@ -826,7 +822,8 @@ class YellowWebinterface
$data = array();
foreach($this->users->users as $key=>$value)
{
$data[$key] = "$value[email] - $value[name] $value[language] $value[status] $value[home]";
$data[$key] = "$value[email] password $value[name] $value[language] $value[status]";
if($this->getUserRestrictions($value["email"], "/locationcheck/", "/filecheck")) $data[$key] .= " - User restricted";
}
usort($data, strnatcasecmp);
return $data;
@ -863,127 +860,6 @@ class YellowWebinterface
return $this->active;
}
}
// Yellow installation
class YellowInstallation
{
var $yellow; //access to API
function __construct($yellow)
{
$this->yellow = $yellow;
}
// Process request to install
function processRequest($serverScheme, $serverName, $base, $location, $fileName)
{
$statusCode = 0;
if(!$this->yellow->isStaticFile($location, $fileName, false))
{
$fileName = $this->yellow->config->get("configDir")."page-installation.txt";
$this->yellow->pages->pages["root/"] = array();
$this->yellow->page = new YellowPage($this->yellow);
$this->yellow->page->setRequestInformation($serverScheme, $serverName, $base, $location, $fileName);
$this->yellow->page->parseData($this->getRawDataWelcome($fileName, $this->yellow->getRequestLanguage()), false, 404);
$this->yellow->page->parserSafeMode = false;
$this->yellow->page->parseContent();
$name = trim(preg_replace("/[^\pL\d\-\. ]/u", "-", $_REQUEST["name"]));
$email = trim($_REQUEST["email"]);
$password = trim($_REQUEST["password"]);
$language = trim($_REQUEST["language"]);
$status = trim($_REQUEST["status"]);
if($status == "install")
{
$status = "ok";
$fileNameHome = $this->yellow->lookup->findFileFromLocation("/");
$fileData = strreplaceu("\r\n", "\n", $this->yellow->toolbox->readFile($fileNameHome));
if($fileData==$this->getRawDataHome("en") && $language!="en")
{
$status = $this->yellow->toolbox->createFile($fileNameHome, $this->getRawDataHome($language)) ? "ok" : "error";
if($status == "error") $this->yellow->page->error(500, "Can't write file '$fileNameHome'!");
}
}
if($status == "ok")
{
if(!empty($email) && !empty($password))
{
$fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("webinterfaceUserFile");
$status = $this->yellow->plugins->get("webinterface")->users->update($fileNameUser, $email, $password, $name, $language) ? "ok" : "error";
if($status == "error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!");
}
}
if($status == "ok")
{
if($this->yellow->config->get("sitename") == "Yellow") $_REQUEST["sitename"] = $name;
$fileNameConfig = $this->yellow->config->get("configDir").$this->yellow->config->get("configFile");
$status = $this->yellow->config->update($fileNameConfig, $this->getConfigData()) ? "done" : "error";
if($status == "error") $this->yellow->page->error(500, "Can't write file '$fileNameConfig'!");
}
if($status == "done")
{
$statusCode = 303;
$location = $this->yellow->lookup->normaliseUrl($serverScheme, $serverName, $base, $location);
$this->yellow->sendStatus($statusCode, $location);
} else {
$statusCode = $this->yellow->sendPage();
}
}
return $statusCode;
}
// Return raw data for welcome page
function getRawDataWelcome($fileName, $language)
{
$rawData = $this->yellow->toolbox->readFile($fileName);
if(empty($rawData))
{
$this->yellow->text->setLanguage($language);
$rawData = "---\nTitle:".$this->yellow->text->get("webinterfaceInstallationTitle")."\nLanguage:$language\nNavigation:navigation\n---\n";
$rawData .= "<form class=\"installation-form\" action=\"".$this->yellow->page->getLocation()."\" method=\"post\">\n";
$rawData .= "<p><label for=\"name\">".$this->yellow->text->get("webinterfaceSignupName")."</label><br /><input class=\"form-control\" type=\"text\" maxlength=\"64\" name=\"name\" id=\"name\" value=\"\"></p>\n";
$rawData .= "<p><label for=\"email\">".$this->yellow->text->get("webinterfaceSignupEmail")."</label><br /><input class=\"form-control\" type=\"text\" maxlength=\"64\" name=\"email\" id=\"email\" value=\"\"></p>\n";
$rawData .= "<p><label for=\"password\">".$this->yellow->text->get("webinterfaceSignupPassword")."</label><br /><input class=\"form-control\" type=\"password\" maxlength=\"64\" name=\"password\" id=\"password\" value=\"\"></p>\n";
if(count($this->yellow->text->getLanguages()) > 1)
{
$rawData .= "<p>";
foreach($this->yellow->text->getLanguages() as $language)
{
$checked = $language==$this->yellow->text->language ? " checked=\"checked\"" : "";
$rawData .= "<label for=\"$language\"><input type=\"radio\" name=\"language\" id=\"$language\" value=\"$language\"$checked> ".$this->yellow->text->getTextHtml("languageDescription", $language)."</label><br />";
}
$rawData .= "</p>\n";
}
$rawData .= "<input class=\"btn\" type=\"submit\" value=\"".$this->yellow->text->get("webinterfaceOkButton")."\" />\n";
$rawData .= "<input type=\"hidden\" name=\"status\" value=\"install\" />\n";
$rawData .= "</form>\n";
}
return $rawData;
}
// Return raw data for home page
function getRawDataHome($language)
{
$rawData = "---\nTitle: Home\n---\n".strreplaceu("\\n", "\n", $this->yellow->text->getText("webinterfaceInstallationHomePage", $language));
return $rawData;
}
// Return configuration data
function getConfigData()
{
$data = array();
foreach($_REQUEST as $key=>$value)
{
if(!$this->yellow->config->isExisting($key)) continue;
$data[$key] = trim($value);
}
$data["# serverScheme"] = $this->yellow->toolbox->getServerScheme();
$data["# serverName"] = $this->yellow->toolbox->getServerName();
$data["# serverBase"] = $this->yellow->toolbox->getServerBase();
$data["# serverTime"] = $this->yellow->toolbox->getServerTime();
$data["installationMode"] = "0";
return $data;
}
}
// Yellow users
class YellowUsers
@ -1005,11 +881,12 @@ class YellowUsers
foreach($this->yellow->toolbox->getTextLines($fileData) as $line)
{
if(preg_match("/^\#/", $line)) continue;
preg_match("/^\s*(.*?)\s*:\s*(.*?),\s*(.*?),\s*(.*?),\s*(.*?),\s*(.*?)\s*$/", $line, $matches);
if(!empty($matches[1]) && !empty($matches[2]) && !empty($matches[3]) && !empty($matches[4]) &&
!empty($matches[5]) && !empty($matches[6]))
preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches);
if(!empty($matches[1]) && !empty($matches[2]))
{
$this->set($matches[1], $matches[2], $matches[3], $matches[4], $matches[5], $matches[6]);
list($hash, $name, $language, $status, $pending, $home) = explode(',', $matches[2]);
$home = empty($home) ? $pending : $home; //TODO: remove later, converts old file format
$this->set($matches[1], $hash, $name, $language, $status, $pending, $home);
if(defined("DEBUG") && DEBUG>=3) echo "YellowUsers::load email:$matches[1]<br/>\n";
}
}
@ -1021,9 +898,17 @@ class YellowUsers
$fileData = $this->yellow->toolbox->readFile($fileName);
foreach($this->yellow->toolbox->getTextLines($fileData) as $line)
{
preg_match("/^\s*(.*?)\s*:\s*(.*?),\s*(.*?),\s*(.*?),\s*(.*?),\s*(.*?)\s*$/", $line, $matches);
if(empty($matches[5]) || $matches[5]=="active" || $matches[5]=="inactive")
preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches);
if(!empty($matches[1]) && !empty($matches[2]))
{
list($hash, $name, $language, $status, $pending, $home) = explode(',', $matches[2]);
if($status=="active" || $status=="inactive")
{
$home = empty($home) ? $pending : $home; //TODO: remove later, converts old file format
$pending = $this->yellow->config->get("webinterfaceUserPending");
$fileDataNew .= "$matches[1]: $hash,$name,$language,$status,$pending,$home\n";
}
} else {
$fileDataNew .= $line;
}
}
@ -1031,7 +916,7 @@ class YellowUsers
}
// Update users in file
function update($fileName, $email, $password = "", $name = "", $language = "", $status = "", $home = "")
function update($fileName, $email, $password = "", $name = "", $language = "", $status = "", $pending = "", $home = "")
{
if(!empty($password))
{
@ -1047,6 +932,7 @@ class YellowUsers
$name = strreplaceu(',', '-', empty($name) ? $this->users[$email]["name"] : $name);
$language = strreplaceu(',', '-', empty($language) ? $this->users[$email]["language"] : $language);
$status = strreplaceu(',', '-', empty($status) ? $this->users[$email]["status"] : $status);
$pending = strreplaceu(',', '-', empty($pending) ? $this->users[$email]["pending"] : $pending);
$home = strreplaceu(',', '-', empty($home) ? $this->users[$email]["home"] : $home);
} else {
$email = strreplaceu(',', '-', empty($email) ? "none" : $email);
@ -1054,27 +940,28 @@ class YellowUsers
$name = strreplaceu(',', '-', empty($name) ? $this->yellow->config->get("sitename") : $name);
$language = strreplaceu(',', '-', empty($language) ? $this->yellow->config->get("language") : $language);
$status = strreplaceu(',', '-', empty($status) ? $this->yellow->config->get("webinterfaceUserStatus") : $status);
$pending = strreplaceu(',', '-', empty($pending) ? $this->yellow->config->get("webinterfaceUserPending") : $pending);
$home = strreplaceu(',', '-', empty($home) ? $this->yellow->config->get("webinterfaceUserHome") : $home);
}
$this->set($email, $hash, $name, $language, $status, $home);
$this->set($email, $hash, $name, $language, $status, $pending, $home);
$fileData = $this->yellow->toolbox->readFile($fileName);
foreach($this->yellow->toolbox->getTextLines($fileData) as $line)
{
preg_match("/^\s*(.*?)\s*:\s*(.*?),\s*(.*?),\s*(.*?),\s*(.*?),\s*(.*?)\s*$/", $line, $matches);
preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches);
if(!empty($matches[1]) && $matches[1]==$email)
{
$fileDataNew .= "$email: $hash,$name,$language,$status,$home\n";
$fileDataNew .= "$email: $hash,$name,$language,$status,$pending,$home\n";
$found = true;
} else {
$fileDataNew .= $line;
}
}
if(!$found) $fileDataNew .= "$email: $hash,$name,$language,$status,$home\n";
if(!$found) $fileDataNew .= "$email: $hash,$name,$language,$status,$pending,$home\n";
return $this->yellow->toolbox->createFile($fileName, $fileDataNew);
}
// Set user data
function set($email, $hash, $name, $language, $status, $home)
function set($email, $hash, $name, $language, $status, $pending, $home)
{
$this->users[$email] = array();
$this->users[$email]["email"] = $email;
@ -1082,6 +969,7 @@ class YellowUsers
$this->users[$email]["name"] = $name;
$this->users[$email]["language"] = $language;
$this->users[$email]["status"] = $status;
$this->users[$email]["pending"] = $pending;
$this->users[$email]["home"] = $home;
}
@ -1164,6 +1052,12 @@ class YellowUsers
return $this->isExisting($email) ? $this->users[$email]["status"] : "";
}
// Return user pending
function getPending($email = "")
{
return $this->isExisting($email) ? $this->users[$email]["pending"] : "";
}
// Return user home
function getHome($email = "")
{
@ -1179,7 +1073,7 @@ class YellowUsers
// Check if web master exists
function isWebmaster()
{
return strposu($this->yellow->config->get("email"), '@') !== false;
return substru($this->yellow->config->get("email"), 0, 7) != "noreply";
}
// Check if user exists