diff options
| author | Roland Stigge <stigge@antcom.de> | 2018-01-10 22:42:44 +0100 | 
|---|---|---|
| committer | Roland Stigge <stigge@antcom.de> | 2018-01-10 22:42:44 +0100 | 
| commit | fa910b8e62f27e54312dff6d4445baabd34d805d (patch) | |
| tree | 34e6c98d231fb75d88d9f0a6fd64af4ce87ef7d2 | |
| parent | 42573fe80d35d4cb411944ae80bea6e582f5b249 (diff) | |
Add read only mode
| -rw-r--r-- | TODO | 1 | ||||
| -rw-r--r-- | debian/README.Debian | 10 | ||||
| -rw-r--r-- | html/index.html | 8 | ||||
| -rw-r--r-- | html/webbox.js | 32 | ||||
| -rw-r--r-- | src/webbox.cpp | 69 | 
5 files changed, 93 insertions, 27 deletions
| @@ -1,7 +1,6 @@  Prio 1 (for next version)  ====== -handle writability  rename function  gallery diff --git a/debian/README.Debian b/debian/README.Debian index f24b3b8..fac423e 100644 --- a/debian/README.Debian +++ b/debian/README.Debian @@ -48,14 +48,20 @@ Environment Variables  The following environment variables are supported: -WEBBOX_PATH +WEBBOX_PATH <path>    Directory with the payload files to be served by a webbox. -WEBBOX_NAME +WEBBOX_NAME <title>    Title of the webbox. Will be written on top of the Web UI. +WEBBOX_READONLY On|Off + +  If present and set to On, the whole webbox will not provide write/changes +  to the contents of the box. + +  Authentication  -------------- diff --git a/html/index.html b/html/index.html index 43ef009..580e415 100644 --- a/html/index.html +++ b/html/index.html @@ -39,11 +39,11 @@  		<div class="menuwindow" id="menuwindow" hidden>  			<div class="menudiv">  				<table class="menudialog"> -					<tr><td class="entry" onclick="hideMenu(); createDir();">New Folder</td></tr> +					<tr class="writecommand"><td class="entry" onclick="hideMenu(); createDir();">New Folder</td></tr>  					<tr><td class="entry" onclick="hideMenu(); download();">Download</td></tr> -					<tr><td class="entry" onclick="hideMenu(); upload();">Upload</td></tr> -					<tr><td class="entry" onclick="hideMenu(); deleteItems();">Delete</td></tr> -					<tr><td class="entry" onclick="hideMenu(); move();">Move</td></tr> +					<tr class="writecommand"><td class="entry" onclick="hideMenu(); upload();">Upload</td></tr> +					<tr class="writecommand"><td class="entry" onclick="hideMenu(); deleteItems();">Delete</td></tr> +					<tr class="writecommand"><td class="entry" onclick="hideMenu(); move();">Move</td></tr>  					<tr><td class="entry" onclick="hideMenu(); info();">Info</td></tr>  					<tr><td class="entry" onclick="hideMenu(); selectAll();">Select/Unselect All</td></tr>  					<tr><td class="entry" onclick="hideMenu();">Close Menu</td></tr> diff --git a/html/webbox.js b/html/webbox.js index 296429b..40a7a1a 100644 --- a/html/webbox.js +++ b/html/webbox.js @@ -31,9 +31,9 @@ function loadContents(dir) {  				}  				result += "<tr " + -					"onmousedown=\"entryMouseDown('" + listElements[i].childNodes[0].nodeValue + "')\" " + -					"onmouseup=\"entryMouseUp('" + listElements[i].childNodes[0].nodeValue + "')\"" + -				"><td class=\"type\">" + type + "</td><td class=\"name\">" + listElements[i].childNodes[0].nodeValue + "</td></tr>"; +					"onmousedown=\"entryMouseDown('" + listElements[i].textContent + "')\" " + +					"onmouseup=\"entryMouseUp('" + listElements[i].textContent + "')\"" + +				"><td class=\"type\">" + type + "</td><td class=\"name\">" + listElements[i].textContent + "</td></tr>";  			}  		} @@ -224,6 +224,16 @@ function hideMenu() {  	document.getElementById("menuwindow").style.display = 'none';  } +// if readOnly = "1", disable respective controls since this setting is global and constant +function prepareReadOnly(readOnly) { +	if (readOnly == "1") { +		var writecommands = document.getElementsByClassName("writecommand"); +		for (var i = 0; i < writecommands.length; i++) { +			writecommands[i].style.display = "none"; +		} +	} +} +  function initMainpage() {  	setCurrentDir("/"); @@ -248,13 +258,23 @@ function initMainpage() {  	var xhrTitle = new XMLHttpRequest();  	xhrTitle.onreadystatechange = function() { -		if (this.readyState != 4 || this.status != 200) { +		if (this.readyState != 4) {  			return;  		} -		document.getElementsByClassName("title")[0].innerHTML = xhrTitle.responseText; +		if (this.status != 200) { +			document.getElementsByClassName("title")[0].innerHTML = "HTTP error"; +			return; +		} + +		var serverInfo = xhrTitle.responseXML; +		var title = serverInfo.getElementsByTagName("title")[0].textContent; +		document.getElementsByClassName("title")[0].innerHTML = title; + +		var readOnly = serverInfo.getElementsByTagName("readonly")[0].textContent; +		prepareReadOnly(readOnly);  	} -	xhrTitle.open("GET", "/bin/query?command=title", true); +	xhrTitle.open("GET", "/bin/query?command=server-info", true);  	xhrTitle.send();  	// load footer diff --git a/src/webbox.cpp b/src/webbox.cpp index c3f03e2..d0cfebc 100644 --- a/src/webbox.cpp +++ b/src/webbox.cpp @@ -72,22 +72,31 @@ struct CommandParameters {  	QHash<QString, QString> paramHash; // derived from urlQuery  	int count; // request count for this instance + +	// Webbox parameters, constant and set globally in Web server config +	QString webboxPath; +	QString webboxName; +	bool webboxReadOnly;  };  class Command {  	public:  		// call interface  		void execute(CommandParameters& p) { +			// check if this webbox is writable and enforce this +			if (p.webboxReadOnly && m_isWriteCommand) { +				printHttpError(400, QString("Webbox is Read-Only"), p); +				return; +			} + +			// check for correct method GET/POST  			QString requestMethod(FCGX_GetParam("REQUEST_METHOD", p.request.envp));  			if (requestMethod != m_requestMethod) {  				printHttpError(403, QString("Bad request method"), p);  				return;  			} -			// process environment -			QString webboxPath(getenv("WEBBOX_PATH")); - -			// FastCGI request environment +			// Set parameters from FastCGI request environment  			m_pathInfo = FCGX_GetParam("PATH_INFO", p.request.envp);  			if (m_pathInfo == "") {  				m_pathInfo = "/"; @@ -97,7 +106,7 @@ class Command {  				return;  			} -			m_path = webboxPath + m_pathInfo; +			m_path = p.webboxPath + m_pathInfo;  			this->start(p);  		} @@ -118,6 +127,7 @@ class Command {  		// Implementation class constants  		QString m_commandName;  		QString m_requestMethod; +		bool m_isWriteCommand; // if true, command must be prevented if p.webboxReadOnly  		// calculated during start of execute()  		QString m_pathInfo; // path inside webbox, derived from request @@ -169,6 +179,7 @@ class DiagCommand: public GetCommand {  	public:  		DiagCommand() {  			m_commandName = "diag"; +			m_isWriteCommand = false;  		}  	protected: @@ -193,7 +204,7 @@ class DiagCommand: public GetCommand {  				tmp++;  			} -			FCGX_PutS(QString("<br/>WEBBOX_PATH=%1<br/>\r\n").arg(getenv("WEBBOX_PATH")).toUtf8().data(), p.request.out); +			FCGX_PutS(QString("<br/>WEBBOX_PATH=%1<br/>\r\n").arg(p.webboxPath).toUtf8().data(), p.request.out);  			FCGX_PutS(QString("<br/>URL Query=%1<br/>\r\n").arg(p.urlQuery.toString()).toUtf8().data(), p.request.out); @@ -206,6 +217,7 @@ class ListCommand: public GetCommand {  	public:  		ListCommand() {  			m_commandName = "list"; +			m_isWriteCommand = false;  		}  	protected: @@ -233,16 +245,32 @@ class ListCommand: public GetCommand {  		}  }; -class TitleCommand: public GetCommand { +// Retrieve from Server: +//   Title +//   ReadOnly flag +class ServerInfoCommand: public GetCommand {  	public: -		TitleCommand() { -			m_commandName = "title"; +		ServerInfoCommand() { +			m_commandName = "server-info"; +			m_isWriteCommand = false;  		}  	protected:  		virtual void start(CommandParameters& p) { -			FCGX_PutS("Content-Type: text/plain\r\n\r\n", p.request.out); -			FCGX_PutS(getenv("WEBBOX_NAME"), p.request.out); +			FCGX_PutS("Content-Type: text/xml\r\n\r\n", p.request.out); + +			QByteArray xmlData; +			QXmlStreamWriter xmlWriter(&xmlData); +			xmlWriter.writeStartDocument(); +			xmlWriter.writeStartElement("serverinfo"); + +			xmlWriter.writeTextElement("title", p.webboxName); +			 +			xmlWriter.writeTextElement("readonly", p.webboxReadOnly ? "1" : "0"); + +			xmlWriter.writeEndElement(); // serverinfo +			xmlWriter.writeEndDocument(); +			FCGX_PutS(xmlData.data(), p.request.out);  		}  }; @@ -250,12 +278,13 @@ class VersionCommand: public GetCommand {  	public:  		VersionCommand() {  			m_commandName = "version"; +			m_isWriteCommand = false;  		}  	protected:  		virtual void start(CommandParameters& p) {  			FCGX_PutS("Content-Type: text/plain\r\n\r\n", p.request.out); -			FCGX_PutS(QString("webbox %1<br/>(C) 2017 <a href=\"https://www.reichwein.it/\">Reichwein.IT</a>\r\n").arg(PROGRAMVERSION).toUtf8().data(), p.request.out); +			FCGX_PutS(QString("webbox %1<br/>(C) 2018 <a href=\"https://www.reichwein.it/\">Reichwein.IT</a>\r\n").arg(PROGRAMVERSION).toUtf8().data(), p.request.out);  		}  }; @@ -263,6 +292,7 @@ class NewDirCommand: public PostCommand {  	public:  		NewDirCommand() {  			m_commandName = "newdir"; +			m_isWriteCommand = true;  		}  	protected: @@ -293,6 +323,7 @@ class InfoCommand: public PostCommand {  	public:  		InfoCommand() {  			m_commandName = "info"; +			m_isWriteCommand = false;  		}  	protected: @@ -413,6 +444,7 @@ class DeleteCommand: public PostCommand {  	public:  		DeleteCommand() {  			m_commandName = "delete"; +			m_isWriteCommand = true;  		}  	protected: @@ -464,6 +496,7 @@ class MoveCommand: public PostCommand {  	public:  		MoveCommand() {  			m_commandName = "move"; +			m_isWriteCommand = true;  		}  	protected: @@ -518,6 +551,7 @@ class UploadCommand: public PostCommand {  	public:  		UploadCommand() {  			m_commandName = "upload"; +			m_isWriteCommand = true;  		}  	protected: @@ -590,6 +624,7 @@ class DownloadCommand: public GetCommand {  	public:  		DownloadCommand() {  			m_commandName = ""; // default command w/o explict "command=" query argument +			m_isWriteCommand = false;  		}  	protected: @@ -642,6 +677,12 @@ int main(int argc, char* argv[]) {  	commandParameters.count = 0; +	// values constant to this instance: +	commandParameters.webboxPath = getenv("WEBBOX_PATH"); +	commandParameters.webboxName = getenv("WEBBOX_NAME"); +	char* WEBBOX_READONLY = getenv("WEBBOX_READONLY"); +	commandParameters.webboxReadOnly = ((WEBBOX_READONLY != NULL) && !strcmp(WEBBOX_READONLY, "On")); +  	Commands commands;  	DiagCommand diagCommand; @@ -650,8 +691,8 @@ int main(int argc, char* argv[]) {  	ListCommand listCommand;  	commands.registerCommand(listCommand); -	TitleCommand titleCommand; -	commands.registerCommand(titleCommand); +	ServerInfoCommand serverInfoCommand; +	commands.registerCommand(serverInfoCommand);  	VersionCommand versionCommand;  	commands.registerCommand(versionCommand); | 
