summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRoland Stigge <stigge@antcom.de>2018-01-10 22:42:44 +0100
committerRoland Stigge <stigge@antcom.de>2018-01-10 22:42:44 +0100
commitfa910b8e62f27e54312dff6d4445baabd34d805d (patch)
tree34e6c98d231fb75d88d9f0a6fd64af4ce87ef7d2
parent42573fe80d35d4cb411944ae80bea6e582f5b249 (diff)
Add read only mode
-rw-r--r--TODO1
-rw-r--r--debian/README.Debian10
-rw-r--r--html/index.html8
-rw-r--r--html/webbox.js32
-rw-r--r--src/webbox.cpp69
5 files changed, 93 insertions, 27 deletions
diff --git a/TODO b/TODO
index 0e8f8c0..8f0cdb7 100644
--- a/TODO
+++ b/TODO
@@ -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);