user management for client interface
authorkonrad <konrad@6e3c4bff-ac9f-4ac1-96c5-d2ea494d3e33>
Sat, 1 Mar 2008 11:29:00 +0000 (11:29 +0000)
committerkonrad <konrad@6e3c4bff-ac9f-4ac1-96c5-d2ea494d3e33>
Sat, 1 Mar 2008 11:29:00 +0000 (11:29 +0000)
git-svn-id: https://silmor.de/svn/softmagic/smoke/trunk@97 6e3c4bff-ac9f-4ac1-96c5-d2ea494d3e33

doc/prog_protocol.html
src/overview.cpp
src/smoke.pro
src/smoke_de.ts
src/smoke_de_SAX.ts
src/user.cpp
src/user.h
www/inc/machine/session.php
www/machine.php

index 2f5205c..e296e47 100644 (file)
@@ -268,6 +268,14 @@ Both calls use this structure for the request:<p>
 
 The <tt>adduser</tt> call also uses it for the response, leaving out any user name that already existed or does not conform to the syntax requirements.
 
+<h3>Deleting a User</h3>
+
+The <tt>deleteuser</tt> transaction deletes one single user. The request contains only the user name to be deleted. The response is empty.<p>
+
+FIXME: this call can fail silently if the user is still referenced somewhere. The client program must refresh its list of users to find out whether the user still exists.<p>
+
+FIXME 2: currently this transaction is not atomic for a reason: if it fails to delete the user it will at least succeed in deleting its access rights.
+
 <h3>Getting User ACLs</h3>
 
 The <tt>getuseracl</tt> transaction returns the ACL of a specific user. The request contains only the login name of the user. The response looks like:<p>
@@ -280,3 +288,28 @@ The <tt>getuseracl</tt> transaction returns the ACL of a specific user. The requ
 </pre>
 
 All setable roles must be listed, so that the client can use these for displaying in a dialog.
+
+<h3>Setting User ACLs</h3>
+
+The <tt>setuseracl</tt> transaction can be used to update a users ACL. The request is identical to the response of <tt>getuseracl</tt>, while the response is an empty document on success - only the status "OK" counts.<p>
+
+Any role listed in the request is changed accordingly, non-existant roles are ignored, roles not listed are left unchanged.<p>
+
+<h3>Getting a Users Hosts</h3>
+
+The <tt>getuserhosts</tt> transaction returns the allowed client hosts of a specific user. The request contains only the login name of the user. The response looks like:<p>
+
+<pre>
+&lt;Hosts user="username">
+  &lt;Host name="hostname" set="1|0"/>
+  ...
+&lt;/Hosts>
+</pre>
+
+All setable hosts must be listed, so that the client can use these for displaying in a dialog.
+
+<h3>Setting User Hosts</h3>
+
+The <tt>setuserhosts</tt> transaction can be used to update a users allowed client hosts. The request is identical to the response of <tt>getuserhosts</tt>, while the response is an empty document on success - only the status "OK" counts.<p>
+
+Any host listed in the request is changed accordingly, non-existant hosts are ignored, hosts not listed are left unchanged.<p>
index 34c71c4..86f3018 100644 (file)
@@ -13,6 +13,7 @@
 #include "overview.h"
 #include "webrequest.h"
 #include "eventedit.h"
+#include "checkdlg.h"
 
 #include <QSettings>
 #include <QMessageBox>
@@ -44,10 +45,9 @@ MOverview::MOverview(MWebRequest*mw,QString pk)
        m->addAction(tr("&Close Session"),this,SLOT(close()));
        
        m=mb->addMenu(tr("&Event"));
-       m->addAction(tr("&Update Event List"),this,SLOT(updateEvents()))->setEnabled(req->hasRole("geteventlist"));
-       m->addAction(tr("&Show details..."));
+       m->addAction(tr("&Update Event List"),this,SLOT(updateEvents())) ->setEnabled(req->hasRole("geteventlist"));
+       m->addAction(tr("&Show/Edit details..."),this,SLOT(editEvent())) ->setEnabled(req->hasRole("geteventdata"));
        m->addAction(tr("&New Event..."),this,SLOT(newEvent()))->setEnabled(req->hasRole("createevent"));
-       m->addAction(tr("&Cancel Event..."));
        
        m=mb->addMenu(tr("&Customer"));
        m->addAction(tr("&Show all customers"));
@@ -265,7 +265,19 @@ void MOverview::newUser()
        updateUsers();
 }
 
-void MOverview::deleteUser(){}
+void MOverview::deleteUser()
+{
+       //get selection
+       QModelIndex sel=usertable->currentIndex();
+       if(!sel.isValid())return;
+       //get uname & descr
+       QString name=usermodel->data(usermodel->index(sel.row(),0)).toString();
+       //make sure user wants this
+       if(QMessageBox::question(this,tr("Delete User?"),tr("Really delete user '%1'?").arg(name),QMessageBox::Yes|QMessageBox::No)!=QMessageBox::Yes)return;
+       //delete
+       MUser(req,name).deleteUser();
+       updateUsers();
+}
 
 void MOverview::editUserDescription()
 {
@@ -284,8 +296,35 @@ void MOverview::editUserDescription()
        updateUsers();
 }
 
-void MOverview::editUserRoles(){}
-void MOverview::editUserHosts(){}
+void MOverview::editUserRoles()
+{
+       //get selection
+       QModelIndex sel=usertable->currentIndex();
+       if(!sel.isValid())return;
+       //get uname & descr
+       QString name=usermodel->data(usermodel->index(sel.row(),0)).toString();
+       //...
+       MUser usr(req,name);
+       MCheckList acl=usr.getRoles();
+       MCheckDialog cd(this,acl,"Edit ACL of user "+name);
+       if(cd.exec()==QDialog::Accepted)
+               usr.setRoles(cd.getCheckList());
+}
+
+void MOverview::editUserHosts()
+{
+       //get selection
+       QModelIndex sel=usertable->currentIndex();
+       if(!sel.isValid())return;
+       //get uname & descr
+       QString name=usermodel->data(usermodel->index(sel.row(),0)).toString();
+       //...
+       MUser usr(req,name);
+       MCheckList acl=usr.getHosts();
+       MCheckDialog cd(this,acl,"Edit hosts of user "+name);
+       if(cd.exec()==QDialog::Accepted)
+               usr.setHosts(cd.getCheckList());
+}
 
 
 void MOverview::updateHosts(){}
index c0d7e71..0203a0f 100644 (file)
@@ -32,7 +32,8 @@ SOURCES = \
        eventedit.cpp \
        event.cpp \
        room.cpp \
-       user.cpp
+       user.cpp \
+       checkdlg.cpp
 HEADERS = \
        keygen.h \
        mainwindow.h \
@@ -42,7 +43,10 @@ HEADERS = \
        eventedit.h \
        event.h \
        room.h \
-       user.h
+       user.h \
+       checkdlg.h \
+       ../www/machine.php \
+       ../www/inc/machine/session.php
 
 RESOURCES += files.qrc
 
index 48bce52..ecee680 100644 (file)
@@ -1,5 +1,141 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!DOCTYPE TS><TS version="1.1" language="de">
+<!DOCTYPE TS><TS version="1.1">
+<context>
+    <name>@default</name>
+    <message>
+        <location filename="../www/machine.php" line="16"/>
+        <source>serverinfo</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../www/machine.php" line="17"/>
+        <source>startsession</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../www/machine.php" line="17"/>
+        <source>sessionauth</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../www/machine.php" line="17"/>
+        <source>closesession</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../www/machine.php" line="19"/>
+        <source>getmyroles</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../www/machine.php" line="21"/>
+        <source>getusers</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../www/machine.php" line="21"/>
+        <source>setuserdescription</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../www/machine.php" line="21"/>
+        <source>getuseracl</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../www/machine.php" line="21"/>
+        <source>setuseracl</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../www/machine.php" line="21"/>
+        <source>getuserhosts</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../www/machine.php" line="21"/>
+        <source>setuserhosts</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../www/machine.php" line="21"/>
+        <source>adduser</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../www/machine.php" line="21"/>
+        <source>deleteuser</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../www/machine.php" line="22"/>
+        <source>gethosts</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../www/machine.php" line="22"/>
+        <source>sethost</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../www/machine.php" line="22"/>
+        <source>addhost</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../www/machine.php" line="22"/>
+        <source>deletehost</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../www/machine.php" line="23"/>
+        <source>geteventlist</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../www/machine.php" line="23"/>
+        <source>geteventdata</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../www/machine.php" line="23"/>
+        <source>seteventdata</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../www/machine.php" line="24"/>
+        <source>getroomdata</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../www/machine.php" line="24"/>
+        <source>setroomdata</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../www/machine.php" line="26"/>
+        <source>getcustomerlist</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../www/inc/machine/session.php" line="287"/>
+        <source>_admin</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
+    <name>MCheckDialog</name>
+    <message>
+        <location filename="checkdlg.cpp" line="33"/>
+        <source>Ok</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="checkdlg.cpp" line="35"/>
+        <source>Cancel</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>MEvent</name>
     <message>
@@ -327,186 +463,274 @@ At least %1 Bits of random are required.</source>
 <context>
     <name>MOverview</name>
     <message>
-        <location filename="overview.cpp" line="39"/>
+        <location filename="overview.cpp" line="41"/>
         <source>&amp;Session</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="40"/>
+        <location filename="overview.cpp" line="42"/>
         <source>&amp;Re-Login</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="43"/>
+        <location filename="overview.cpp" line="45"/>
         <source>&amp;Close Session</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="45"/>
+        <location filename="overview.cpp" line="47"/>
         <source>&amp;Event</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="51"/>
+        <location filename="overview.cpp" line="52"/>
         <source>&amp;Customer</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="62"/>
+        <location filename="overview.cpp" line="63"/>
         <source>C&amp;onfigure</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="66"/>
+        <location filename="overview.cpp" line="67"/>
         <source>Events</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="165"/>
+        <location filename="overview.cpp" line="209"/>
         <source>Warning</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="165"/>
+        <location filename="overview.cpp" line="209"/>
         <source>I was unable to renew the login at the server, the error was: %1</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="41"/>
+        <location filename="overview.cpp" line="43"/>
         <source>&amp;Offline mode</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="47"/>
-        <source>&amp;Show details...</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
-        <location filename="overview.cpp" line="48"/>
+        <location filename="overview.cpp" line="50"/>
         <source>&amp;New Event...</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="49"/>
-        <source>&amp;Cancel Event...</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
-        <location filename="overview.cpp" line="52"/>
+        <location filename="overview.cpp" line="53"/>
         <source>&amp;Show all customers</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="54"/>
+        <location filename="overview.cpp" line="55"/>
         <source>C&amp;art</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="55"/>
+        <location filename="overview.cpp" line="56"/>
         <source>Add &amp;Ticket</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="56"/>
+        <location filename="overview.cpp" line="57"/>
         <source>Add &amp;Voucher</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="57"/>
+        <location filename="overview.cpp" line="58"/>
         <source>&amp;Remove Item</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="58"/>
+        <location filename="overview.cpp" line="59"/>
         <source>&amp;Abort Shopping</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="60"/>
+        <location filename="overview.cpp" line="61"/>
         <source>&amp;Show all orders</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="76"/>
+        <location filename="overview.cpp" line="77"/>
         <source>New Event...</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="79"/>
+        <location filename="overview.cpp" line="80"/>
         <source>Details...</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="83"/>
+        <location filename="overview.cpp" line="84"/>
         <source>Order Ticket...</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="86"/>
+        <location filename="overview.cpp" line="87"/>
         <source>Shopping Cart</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="95"/>
+        <location filename="overview.cpp" line="96"/>
         <source>Add Ticket</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="96"/>
+        <location filename="overview.cpp" line="97"/>
         <source>Add Voucher</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="97"/>
+        <location filename="overview.cpp" line="98"/>
         <source>Remove Item</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="102"/>
+        <location filename="overview.cpp" line="103"/>
         <source>Customer:</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="107"/>
+        <location filename="overview.cpp" line="108"/>
         <source>Delivery Address:</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="110"/>
+        <location filename="overview.cpp" line="111"/>
         <source>Comments:</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="117"/>
+        <location filename="overview.cpp" line="118"/>
         <source>Save Order</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="118"/>
+        <location filename="overview.cpp" line="119"/>
         <source>Clear</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="137"/>
+        <location filename="overview.cpp" line="181"/>
         <source>Start Time</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="137"/>
+        <location filename="overview.cpp" line="181"/>
         <source>Title</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="140"/>
+        <location filename="overview.cpp" line="184"/>
         <source>ddd MMMM d yyyy, h:mm ap</source>
         <comment>time format</comment>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="46"/>
+        <location filename="overview.cpp" line="48"/>
         <source>&amp;Update Event List</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <location filename="overview.cpp" line="49"/>
+        <source>&amp;Show/Edit details...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="overview.cpp" line="122"/>
+        <source>Users</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="overview.cpp" line="130"/>
+        <source>New User...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="overview.cpp" line="133"/>
+        <source>Delete User...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="overview.cpp" line="137"/>
+        <source>Description...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="overview.cpp" line="140"/>
+        <source>Hosts...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="overview.cpp" line="143"/>
+        <source>Roles...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="overview.cpp" line="149"/>
+        <source>Hosts</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="overview.cpp" line="239"/>
+        <source>Login Name</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="overview.cpp" line="239"/>
+        <source>Description</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="overview.cpp" line="254"/>
+        <source>New User</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="overview.cpp" line="254"/>
+        <source>Please enter new user name (only letters, digits, and underscore allowed):</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="overview.cpp" line="259"/>
+        <source>Error</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="overview.cpp" line="259"/>
+        <source>The user name must contain only letters, digits, and underscores and must be at least one character long!</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="overview.cpp" line="280"/>
+        <source>Edit Description</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="overview.cpp" line="280"/>
+        <source>Descriptionof user %1:</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
+    <name>MUserHost</name>
+    <message>
+        <location filename="user.cpp" line="235"/>
+        <source>_any</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="user.cpp" line="235"/>
+        <source>_online</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="user.cpp" line="235"/>
+        <source>_anon</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>MWebRequest</name>
@@ -566,7 +790,7 @@ At least %1 Bits of random are required.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="webrequest.cpp" line="332"/>
+        <location filename="webrequest.cpp" line="355"/>
         <source>Error parsing EventList XML data (line %1 column %2): %3</source>
         <translation type="unfinished"></translation>
     </message>
index 4699ce8..0157dd1 100644 (file)
@@ -1,5 +1,142 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!DOCTYPE TS><TS version="1.1" language="de">
+<defaultcodec></defaultcodec>
+<context>
+    <name>@default</name>
+    <message>
+        <location filename="../www/machine.php" line="16"/>
+        <source>serverinfo</source>
+        <translation>Informadschjon&apos; übern Sörvor.</translation>
+    </message>
+    <message>
+        <location filename="../www/machine.php" line="17"/>
+        <source>startsession</source>
+        <translation>&apos;Ne Seschon anfang&apos;</translation>
+    </message>
+    <message>
+        <location filename="../www/machine.php" line="17"/>
+        <source>sessionauth</source>
+        <translation>Am Sörvor anmeld&apos;n</translation>
+    </message>
+    <message>
+        <location filename="../www/machine.php" line="17"/>
+        <source>closesession</source>
+        <translation>Dsum Sörvor gude Nachd sachn</translation>
+    </message>
+    <message>
+        <location filename="../www/machine.php" line="19"/>
+        <source>getmyroles</source>
+        <translation>Rausfinden was isch machn darf</translation>
+    </message>
+    <message>
+        <location filename="../www/machine.php" line="21"/>
+        <source>getusers</source>
+        <translation>Guggn welche Nudsor es gibd</translation>
+    </message>
+    <message>
+        <location filename="../www/machine.php" line="21"/>
+        <source>setuserdescription</source>
+        <translation>Nen bleeden Gommendar über jemand andres machn</translation>
+    </message>
+    <message>
+        <location filename="../www/machine.php" line="21"/>
+        <source>getuseracl</source>
+        <translation>Rausfinden was een andror darf</translation>
+    </message>
+    <message>
+        <location filename="../www/machine.php" line="21"/>
+        <source>setuseracl</source>
+        <translation>Dem Andorn was vorbiedn dürfen</translation>
+    </message>
+    <message>
+        <location filename="../www/machine.php" line="21"/>
+        <source>getuserhosts</source>
+        <translation>Rausfinden von wo ä Nudsor arbäden darf</translation>
+    </message>
+    <message>
+        <location filename="../www/machine.php" line="21"/>
+        <source>setuserhosts</source>
+        <translation>Fesdleechn von wo ä Nudsor arbäden darf</translation>
+    </message>
+    <message>
+        <location filename="../www/machine.php" line="21"/>
+        <source>adduser</source>
+        <translation>&apos;Nen neuen Nudsor anlechen</translation>
+    </message>
+    <message>
+        <location filename="../www/machine.php" line="21"/>
+        <source>deleteuser</source>
+        <translation>&apos;Nen Nudsor löschen. Eefach so.</translation>
+    </message>
+    <message>
+        <location filename="../www/machine.php" line="22"/>
+        <source>gethosts</source>
+        <translation>Rausfinden von wo mor alles arbäden gönnde.</translation>
+    </message>
+    <message>
+        <location filename="../www/machine.php" line="22"/>
+        <source>sethost</source>
+        <translation>&apos;Ne Arbedsschdelle ändorn</translation>
+    </message>
+    <message>
+        <location filename="../www/machine.php" line="22"/>
+        <source>addhost</source>
+        <translation>&apos;Ne neue Arbedsschdelle einrischdn</translation>
+    </message>
+    <message>
+        <location filename="../www/machine.php" line="22"/>
+        <source>deletehost</source>
+        <translation>&apos;Ne Arbedsschdelle dichd machn</translation>
+    </message>
+    <message>
+        <location filename="../www/machine.php" line="23"/>
+        <source>geteventlist</source>
+        <translation>Lisde dor Veranschdaldungen holen</translation>
+    </message>
+    <message>
+        <location filename="../www/machine.php" line="23"/>
+        <source>geteventdata</source>
+        <translation>Dedails zu eener Veranschdaldung holen</translation>
+    </message>
+    <message>
+        <location filename="../www/machine.php" line="23"/>
+        <source>seteventdata</source>
+        <translation>Dedails zu eener Veranschdaldung ändorn</translation>
+    </message>
+    <message>
+        <location filename="../www/machine.php" line="24"/>
+        <source>getroomdata</source>
+        <translation>Räumlischgeden anzeichen</translation>
+    </message>
+    <message>
+        <location filename="../www/machine.php" line="24"/>
+        <source>setroomdata</source>
+        <translation>Räumlischgeden ändorn</translation>
+    </message>
+    <message>
+        <location filename="../www/machine.php" line="26"/>
+        <source>getcustomerlist</source>
+        <translation>Lisde dor Gunden anguggn</translation>
+    </message>
+    <message>
+        <location filename="../www/inc/machine/session.php" line="287"/>
+        <source>_admin</source>
+        <translation>Godd. Darf alles, gann alles, wees alles bessor.</translation>
+    </message>
+</context>
+<context>
+    <name>MCheckDialog</name>
+    <message>
+        <location filename="checkdlg.cpp" line="33"/>
+        <source>Ok</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="checkdlg.cpp" line="35"/>
+        <source>Cancel</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>MEvent</name>
     <message>
@@ -327,186 +464,279 @@ At least %1 Bits of random are required.</source>
 <context>
     <name>MOverview</name>
     <message>
-        <location filename="overview.cpp" line="39"/>
+        <location filename="overview.cpp" line="41"/>
         <source>&amp;Session</source>
         <translation>&amp;Sidsung</translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="40"/>
+        <location filename="overview.cpp" line="42"/>
         <source>&amp;Re-Login</source>
         <translation>&amp;Noch&apos;ma einloggn</translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="43"/>
+        <location filename="overview.cpp" line="45"/>
         <source>&amp;Close Session</source>
         <translation>Sidsung &amp;Zumachn</translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="45"/>
+        <location filename="overview.cpp" line="47"/>
         <source>&amp;Event</source>
         <translation>&amp;Veranschdaldung</translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="51"/>
+        <location filename="overview.cpp" line="52"/>
         <source>&amp;Customer</source>
         <translation>&amp;Gunde</translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="62"/>
+        <location filename="overview.cpp" line="63"/>
         <source>C&amp;onfigure</source>
         <translation>G&amp;onfiguriern</translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="66"/>
+        <location filename="overview.cpp" line="67"/>
         <source>Events</source>
         <translation>Veranschdaldungen</translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="165"/>
+        <location filename="overview.cpp" line="209"/>
         <source>Warning</source>
         <translation>Dumm gelaufen</translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="165"/>
+        <location filename="overview.cpp" line="209"/>
         <source>I was unable to renew the login at the server, the error was: %1</source>
         <translation>Isch gann de&apos; Verbindung off&apos;n gross&apos;n Reschner nisch erneuern. Der will nisch weil: %1</translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="41"/>
+        <location filename="overview.cpp" line="43"/>
         <source>&amp;Offline mode</source>
         <translation>&amp;Ohne Neds und Dobbelden Boden</translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="47"/>
+        <location filename="" line="6065"/>
         <source>&amp;Show details...</source>
-        <translation>&amp;Dedails anzeigen...</translation>
+        <translation type="obsolete">&amp;Dedails anzeigen...</translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="48"/>
+        <location filename="overview.cpp" line="50"/>
         <source>&amp;New Event...</source>
-        <translation>&amp;Neue Veranschdaldung...</translation>
+        <translation type="unfinished">Veranschdaldung &amp;absach&apos;n...</translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="49"/>
-        <source>&amp;Cancel Event...</source>
-        <translation>Veranschdaldung &amp;absach&apos;n...</translation>
-    </message>
-    <message>
-        <location filename="overview.cpp" line="52"/>
+        <location filename="overview.cpp" line="53"/>
         <source>&amp;Show all customers</source>
         <translation>&amp;Alle Gunden anzeigen</translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="54"/>
+        <location filename="overview.cpp" line="55"/>
         <source>C&amp;art</source>
         <translation>Eing&amp;aufswagen</translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="55"/>
+        <location filename="overview.cpp" line="56"/>
         <source>Add &amp;Ticket</source>
         <translation>Ein&amp;driddsgarde hinzufüchen</translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="56"/>
+        <location filename="overview.cpp" line="57"/>
         <source>Add &amp;Voucher</source>
         <translation>&amp;Gudschein hinzufüchen</translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="57"/>
+        <location filename="overview.cpp" line="58"/>
         <source>&amp;Remove Item</source>
         <translation>Doch &amp;ni&apos; nehm&apos;</translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="58"/>
+        <location filename="overview.cpp" line="59"/>
         <source>&amp;Abort Shopping</source>
         <translation>&amp;Eingauf Abbrechen</translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="60"/>
+        <location filename="overview.cpp" line="61"/>
         <source>&amp;Show all orders</source>
         <translation>&amp;Alle Beschdellungen anzeichen</translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="76"/>
+        <location filename="overview.cpp" line="77"/>
         <source>New Event...</source>
         <translation>Neue Veranschdaldung...</translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="79"/>
+        <location filename="overview.cpp" line="80"/>
         <source>Details...</source>
         <translation>Dedails anzeichen...</translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="83"/>
+        <location filename="overview.cpp" line="84"/>
         <source>Order Ticket...</source>
         <translation>Eindriddsgarde beschdellen...</translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="86"/>
+        <location filename="overview.cpp" line="87"/>
         <source>Shopping Cart</source>
         <translation>Eingaufswagen</translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="95"/>
+        <location filename="overview.cpp" line="96"/>
         <source>Add Ticket</source>
         <translation>Eindriddsgarde hinzufüchen</translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="96"/>
+        <location filename="overview.cpp" line="97"/>
         <source>Add Voucher</source>
         <translation>Gudschein hinzufüchen</translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="97"/>
+        <location filename="overview.cpp" line="98"/>
         <source>Remove Item</source>
         <translation>Doch ni&apos; nehm&apos;</translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="102"/>
+        <location filename="overview.cpp" line="103"/>
         <source>Customer:</source>
         <translation>Gunde:</translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="107"/>
+        <location filename="overview.cpp" line="108"/>
         <source>Delivery Address:</source>
         <translation>Adresse wo&apos;s Zeuch hin soll:</translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="110"/>
+        <location filename="overview.cpp" line="111"/>
         <source>Comments:</source>
         <translation>Wischdiches Gelaber und Gerede:</translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="117"/>
+        <location filename="overview.cpp" line="118"/>
         <source>Save Order</source>
         <translation>Beschdellung abschbeichern</translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="118"/>
+        <location filename="overview.cpp" line="119"/>
         <source>Clear</source>
         <translation>Wechwerfen und von vorne!</translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="137"/>
+        <location filename="overview.cpp" line="181"/>
         <source>Start Time</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="137"/>
+        <location filename="overview.cpp" line="181"/>
         <source>Title</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="140"/>
+        <location filename="overview.cpp" line="184"/>
         <source>ddd MMMM d yyyy, h:mm ap</source>
         <comment>time format</comment>
         <translation>ddd, d.M.yyyy hh:mm</translation>
     </message>
     <message>
-        <location filename="overview.cpp" line="46"/>
+        <location filename="overview.cpp" line="48"/>
         <source>&amp;Update Event List</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <location filename="overview.cpp" line="49"/>
+        <source>&amp;Show/Edit details...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="overview.cpp" line="122"/>
+        <source>Users</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="overview.cpp" line="130"/>
+        <source>New User...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="overview.cpp" line="133"/>
+        <source>Delete User...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="overview.cpp" line="137"/>
+        <source>Description...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="overview.cpp" line="140"/>
+        <source>Hosts...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="overview.cpp" line="143"/>
+        <source>Roles...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="overview.cpp" line="149"/>
+        <source>Hosts</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="overview.cpp" line="239"/>
+        <source>Login Name</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="overview.cpp" line="239"/>
+        <source>Description</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="overview.cpp" line="254"/>
+        <source>New User</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="overview.cpp" line="254"/>
+        <source>Please enter new user name (only letters, digits, and underscore allowed):</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="overview.cpp" line="259"/>
+        <source>Error</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="overview.cpp" line="259"/>
+        <source>The user name must contain only letters, digits, and underscores and must be at least one character long!</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="overview.cpp" line="280"/>
+        <source>Edit Description</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="overview.cpp" line="280"/>
+        <source>Descriptionof user %1:</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
+    <name>MUserHost</name>
+    <message>
+        <location filename="user.cpp" line="235"/>
+        <source>_any</source>
+        <translation>Irschendeen Gombjudor</translation>
+    </message>
+    <message>
+        <location filename="user.cpp" line="235"/>
+        <source>_online</source>
+        <translation>De Webseidn</translation>
+    </message>
+    <message>
+        <location filename="user.cpp" line="235"/>
+        <source>_anon</source>
+        <translation>Annonühm</translation>
+    </message>
 </context>
 <context>
     <name>MWebRequest</name>
@@ -566,7 +796,7 @@ At least %1 Bits of random are required.</source>
         <translation>Isch gann misch ned anmälden.</translation>
     </message>
     <message>
-        <location filename="webrequest.cpp" line="332"/>
+        <location filename="webrequest.cpp" line="355"/>
         <source>Error parsing EventList XML data (line %1 column %2): %3</source>
         <translation type="unfinished"></translation>
     </message>
index 549de5c..f364241 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <QRegExp>
 #include <QDomElement>
+#include <QCoreApplication>
 
 MUser::MUser(MWebRequest*r,QDomElement&e)
 {
@@ -79,6 +80,12 @@ bool MUser::create()
        }
 }
 
+void MUser::deleteUser()
+{
+       if(!isValid())return;
+       req->request("deleteuser",m_userid.toUtf8());
+}
+
 bool MUser::setDescription(QString d)
 {
        m_descr=d;
@@ -101,3 +108,196 @@ bool MUser::setDescription(QString d)
                return false;
        }
 }
+
+MCheckList MUser::getRoles()
+{
+       //call
+       req->request("getuseracl",m_userid.toUtf8());
+       //check success
+       MCheckList ret;
+       if(req->responseStatus()==MWebRequest::Ok){
+               QDomDocument doc;
+               if(!doc.setContent(req->responseBody()))return ret;
+               QDomNodeList nl=doc.documentElement().elementsByTagName("Role");
+               for(int i=0;i<nl.size();i++){
+                       QDomElement el=nl.at(i).toElement();
+                       if(el.isNull())continue;
+                       QString name=el.attribute("name");
+                       bool set=el.attribute("set","0").toInt();
+                       ret.addItem(new MAcl(name,set));
+               }
+       }
+       return ret;
+}
+
+bool MUser::setRoles(const MCheckList&cl)
+{
+       //create DOM
+       QDomDocument doc;
+       QDomElement root=doc.createElement("ACL");
+       root.setAttribute("user",m_userid);
+       for(int i=0;i<cl.size();i++){
+               QDomElement el=doc.createElement("Role");
+               el.setAttribute("name",cl[i].key());
+               el.setAttribute("set",cl[i].isSet()?"1":"0");
+               root.appendChild(el);
+       }
+       doc.appendChild(root);
+       //request
+       req->request("setuseracl",doc.toByteArray());
+       if(req->responseStatus()==MWebRequest::Ok)return true;
+       else return false;
+}
+
+MCheckList MUser::getHosts()
+{
+       //call
+       req->request("getuserhosts",m_userid.toUtf8());
+       //check success
+       MCheckList ret;
+       if(req->responseStatus()==MWebRequest::Ok){
+               QDomDocument doc;
+               if(!doc.setContent(req->responseBody()))return ret;
+               QDomNodeList nl=doc.documentElement().elementsByTagName("Host");
+               for(int i=0;i<nl.size();i++){
+                       QDomElement el=nl.at(i).toElement();
+                       if(el.isNull())continue;
+                       QString name=el.attribute("name");
+                       bool set=el.attribute("set","0").toInt();
+                       ret.addItem(new MAcl(name,set));
+               }
+       }
+       return ret;
+}
+
+bool MUser::setHosts(const MCheckList&cl)
+{
+       //create DOM
+       QDomDocument doc;
+       QDomElement root=doc.createElement("Hosts");
+       root.setAttribute("user",m_userid);
+       for(int i=0;i<cl.size();i++){
+               QDomElement el=doc.createElement("Host");
+               el.setAttribute("name",cl[i].key());
+               el.setAttribute("set",cl[i].isSet()?"1":"0");
+               root.appendChild(el);
+       }
+       doc.appendChild(root);
+       //request
+       req->request("setuserhosts",doc.toByteArray());
+       if(req->responseStatus()==MWebRequest::Ok)return true;
+       else return false;
+}
+
+/********************************************************/
+
+MAcl::MAcl()
+{
+       m_set=false;
+}
+
+MAcl::MAcl(const MAcl&a)
+       :MCheckItem()
+{
+       m_role=a.m_role;
+       m_set=a.m_set;
+}
+
+MAcl::MAcl(QString r,bool s)
+{
+       m_role=r;
+       m_set=s;
+}
+
+QString MAcl::role()const
+{
+       return m_role;
+}
+
+QString MAcl::key()const
+{
+       return m_role;
+}
+
+QString MAcl::description()const
+{
+       return QCoreApplication::translate("@default",m_role.toAscii().data());
+}
+
+QString MAcl::label()const
+{
+       QString d=description();
+       if(d==m_role)return m_role;
+       else return m_role+": "+d;
+}
+
+bool MAcl::isSet()const
+{
+       return m_set;
+}
+
+void MAcl::set(bool b)
+{
+       m_set=b;
+}
+
+MCheckItem* MAcl::copy()const
+{
+       return new MAcl(*this);
+}
+
+/**************************************************/
+
+MUserHost::MUserHost()
+{
+       m_set=false;
+}
+
+MUserHost::MUserHost(const MUserHost&h)
+       :MCheckItem()
+{
+       m_host=h.m_host;
+       m_set=h.m_set;
+}
+
+MUserHost::MUserHost(QString h,bool s)
+{
+       m_host=h;
+       m_set=s;
+}
+
+QString MUserHost::host()const
+{
+       return m_host;
+}
+
+QString MUserHost::key()const
+{
+       return m_host;
+}
+
+QString MUserHost::label()const
+{
+       QStringList special;
+       special<<QT_TR_NOOP("_any")<<QT_TR_NOOP("_online")<<QT_TR_NOOP("_anon");
+       if(special.contains(m_host)){
+               QString d=QCoreApplication::translate("MUserHost",m_host.toAscii().data());
+               if(d!=m_host)return m_host+": "+d;
+       }
+       return m_host;
+}
+
+bool MUserHost::isSet()const
+{
+       return m_set;
+}
+
+void MUserHost::set(bool b)
+{
+       m_set=b;
+}
+
+MCheckItem* MUserHost::copy()const
+{
+       return new MUserHost(*this);
+}
index 71eed7f..8db084d 100644 (file)
@@ -15,6 +15,8 @@
 
 #include <QString>
 
+#include "checkdlg.h"
+
 class MWebRequest;
 class QDomElement;
 
@@ -41,13 +43,81 @@ class MUser
                /**creates user in database; returns true on success*/
                bool create();
                
+               /**deletes user from database*/
+               void deleteUser();
+               
                /**sets new description, both locally and on server*/
                bool setDescription(QString);
                
+               /**returns roles of this user (queries server); returns empty list if call fails, returns filled list if call succeeds, the bool will contain whether the user has the role*/
+               MCheckList getRoles();
+               
+               /**sends the updated roles to the server; returns true on success*/
+               bool setRoles(const MCheckList&);
+               
+               /**returns hosts that a user may connect from*/
+               MCheckList getHosts();
+               
+               /**send the updated host list of the user to the server; returns true on success*/
+               bool setHosts(const MCheckList&);
+               
        private:
                MWebRequest*req;
                QString m_userid,m_descr;
 };
 
+/**overwrites MCheckItem to represent an ACL item for the user*/
+class MAcl:public MCheckItem
+{
+       public:
+               MAcl();
+               MAcl(const MAcl&);
+               MAcl(QString,bool);
+               
+               /**returns the role this ACL represents*/
+               virtual QString role()const;
+               /**returns the role this ACL represents*/
+               virtual QString key()const;
+               /**attempts to translate the role using the currently active language, this should yield a description of the role if successful or the role name if it fails*/
+               virtual QString description()const;
+               /**returns a usable label (role name + description) for the MCheckDialog */
+               virtual QString label()const;
+               /**returns whether the role is set for this user*/
+               virtual bool isSet()const;
+               /**changes the role setting (used by MCheckDialog)*/
+               virtual void set(bool);
+               
+       protected:
+               virtual MCheckItem* copy()const;
+       private:
+               QString m_role;
+               bool m_set;
+};
+
+/**overwrites MCheckItem to represent a host item for the user*/
+class MUserHost:public MCheckItem
+{
+       public:
+               MUserHost();
+               MUserHost(const MUserHost&);
+               MUserHost(QString,bool);
+               
+               /**returns the host this item represents*/
+               virtual QString host()const;
+               /**returns the host this item represents*/
+               virtual QString key()const;
+               /**returns a usable label (host name + opt. description for special hosts) for the MCheckDialog */
+               virtual QString label()const;
+               /**returns whether the host is allowed for this user*/
+               virtual bool isSet()const;
+               /**changes the host setting (used by MCheckDialog)*/
+               virtual void set(bool);
+               
+       protected:
+               virtual MCheckItem* copy()const;
+       private:
+               QString m_host;
+               bool m_set;
+};
 
 #endif
index 1deec2d..8a3b4f9 100644 (file)
@@ -248,7 +248,7 @@ function getUserAclXml($user)
        header("X-MagicSmoke-Status: Ok");
        //create list of roles
        $roles=$ALLOWEDREQUESTS;
-       $roles[]="_admin";
+       $roles[]=tr("_admin");
        //get roles from DB
        $res=$db->select("userrole","role","uname=".$db->escapeString($user));
        $acl=array();
@@ -267,6 +267,138 @@ function getUserAclXml($user)
        print($dom->saveXML());
 }
 
+//set the ACL of a user
+function setUserAclXml($txt)
+{
+       //DOM
+       $xml=new DOMDocument;
+       if(!$xml->loadXML($txt)){
+               header("X-MagicSmoke-Status: SyntaxError");
+               die("unable to parse XML data");
+       }
+       //get user name
+       $acl=$xml->getElementsByTagName("ACL");
+       if($acl->length != 1){
+               header("X-MagicSmoke-Status: SyntaxError");
+               die("expected exactly 1 ACL element");
+       }
+       global $db,$ALLOWEDREQUESTS;
+       $roles=$ALLOWEDREQUESTS;
+       $roles[]=tr("_admin");
+       $usr=$acl->item(0)->getAttribute("user");
+       //check user name
+       $db->beginTransaction();
+       $res=$db->select("users","count(uname)","uname=".$db->escapeString($usr));
+       if($res[0][0]!=1){
+               header("X-MagicSmoke-Status: SyntaxError");
+               $db->rollbackTransaction();
+               die("unknown user name");
+       }
+       //update roles
+       $acl=$xml->getElementsByTagName("Role");
+       for($i=0;$i<$acl->length;$i++){
+               //does role exist?
+               $name=$acl->item($i)->getAttribute("name");
+               if(array_search($name,$roles)===false)continue;
+               $isset=$acl->item($i)->getAttribute("set")+0;
+               if($isset){
+                       $res=$db->select("userrole","count(role)","uname=".$db->escapeString($usr)." AND role=".$db->escapeString($name));
+                       if($res[0][0]!=0)continue;
+                       $db->insert("userrole",array("uname"=>$usr,"role"=>$name));
+               }else{
+                       $db->deleteRows("userrole","uname=".$db->escapeString($usr)." AND role=".$db->escapeString($name));
+               }
+       }
+       $db->commitTransaction();
+       header("X-MagicSmoke-Status: Ok");
+}
+
+//return the hosts of a specific user
+function getUserHostsXml($user)
+{
+       //sanity check
+       $user=trim($user);
+       if(ereg("^[A-Za-z0-9_]+$",$user)===false){
+               header("X-MagicSmoke-Status: SyntaxError");
+               die("invalid user name");
+       }
+       //go on...
+       global $db;
+       header("X-MagicSmoke-Status: Ok");
+       //create list of hosts
+       $hosts=array();
+       $res=$db->select("host","hostname","");
+       for($i=0;$i<count($res);$i++){
+               $hosts[]=$res[$i]["hostname"];
+       }
+       //get roles from DB
+       $res=$db->select("userhosts","host","uname=".$db->escapeString($user));
+       $acl=array();
+       foreach($res as $rl)$acl[]=$rl["host"];
+       $dom=new DOMDocument;
+       $root=$dom->createElement("Hosts");
+       $root->setAttributeNode(new DOMAttr("user",$user));
+       foreach($hosts as $hs){
+               $re=$dom->createElement("Host");
+               $re->setAttributeNode(new DOMAttr("name",$hs));
+               if(array_search($hs,$acl)===false)$re->setAttributeNode(new DOMAttr("set","0"));
+               else $re->setAttributeNode(new DOMAttr("set","1"));
+               $root->appendChild($re);
+       }
+       $dom->appendChild($root);
+       print($dom->saveXML());
+}
+
+//set the Hosts of a user
+function setUserHostsXml($txt)
+{
+       //DOM
+       $xml=new DOMDocument;
+       if(!$xml->loadXML($txt)){
+               header("X-MagicSmoke-Status: SyntaxError");
+               die("unable to parse XML data");
+       }
+       //get user name
+       $acl=$xml->getElementsByTagName("Hosts");
+       if($acl->length != 1){
+               header("X-MagicSmoke-Status: SyntaxError");
+               die("expected exactly 1 Hosts element");
+       }
+       global $db;
+       //create list of hosts
+       $hosts=array();
+       $res=$db->select("host","hostname","");
+       for($i=0;$i<count($res);$i++){
+               $hosts[]=$res[$i]["hostname"];
+       }
+       $usr=$acl->item(0)->getAttribute("user");
+       //check user name
+       $db->beginTransaction();
+       $res=$db->select("users","count(uname)","uname=".$db->escapeString($usr));
+       if($res[0][0]!=1){
+               header("X-MagicSmoke-Status: SyntaxError");
+               $db->rollbackTransaction();
+               die("unknown user name");
+       }
+       //update roles
+       $acl=$xml->getElementsByTagName("Host");
+       for($i=0;$i<$acl->length;$i++){
+               //does role exist?
+               $name=$acl->item($i)->getAttribute("name");
+               if(array_search($name,$hosts)===false)continue;
+               $isset=$acl->item($i)->getAttribute("set")+0;
+               if($isset){
+                       $res=$db->select("userhosts","count(host)","uname=".$db->escapeString($usr)." AND host=".$db->escapeString($name));
+                       if($res[0][0]!=0)continue;
+                       $db->insert("userhosts",array("uname"=>$usr,"host"=>$name));
+               }else{
+                       $db->deleteRows("userhosts","uname=".$db->escapeString($usr)." AND host=".$db->escapeString($name));
+               }
+       }
+       $db->commitTransaction();
+       header("X-MagicSmoke-Status: Ok");
+}
+
 //helper function: parse User-XML-structure
 function parseUserXml($txt)
 {
@@ -323,6 +455,24 @@ function addUserXml($txt)
        }
        $dom->appendChild($root);
        print($dom->saveXML());
+       header("X-MagicSmoke-Status: Ok");
+}
+
+//delete a user
+function deleteUserXml($txt)
+{
+       global $db;
+       $usr=trim($txt);
+       //delete ACL
+       $db->deleteRows("userroles","uname=".$db->escapeString($usr));
+       //delete Hosts
+       $db->deleteRows("userhosts","uname=".$db->escapeString($usr));
+       //delete open sessions
+       $db->deleteRows("session","user=".$db->escapeString($usr));
+       //attempt to delete User itself
+       $db->deleteRows("users","uname=".$db->escapeString($usr));
+       //say OK anyway; FIXME: check for success above
+       header("X-MagicSmoke-Status: Ok");
 }
 
 ?>
\ No newline at end of file
index 3e99118..9f92709 100644 (file)
@@ -158,16 +158,28 @@ if($SMOKEREQUEST=="getuseracl"){
        exit();
 }
 
-if($SMOKEREQUEST=="setuseracl"){}
-if($SMOKEREQUEST=="getuserhosts"){}
-if($SMOKEREQUEST=="setuserhosts"){}
+if($SMOKEREQUEST=="setuseracl"){
+       setUserAclXml($REQUESTDATA);
+       exit();
+}
+if($SMOKEREQUEST=="getuserhosts"){
+       getUserHostsXml($REQUESTDATA);
+       exit();
+}
+if($SMOKEREQUEST=="setuserhosts"){
+       setUserHostsXml($REQUESTDATA);
+       exit();
+}
 
 if($SMOKEREQUEST=="adduser"){
        addUserXml($REQUESTDATA);
        exit();
 }
 
-if($SMOKEREQUEST=="deleteuser"){}
+if($SMOKEREQUEST=="deleteuser"){
+       deleteUserXml($REQUESTDATA);
+       exit();
+}
 if($SMOKEREQUEST=="gethosts"){}
 if($SMOKEREQUEST=="sethost"){}
 if($SMOKEREQUEST=="addhost"){}