--- /dev/null
+//
+// C++ Implementation: checkdlg
+//
+// Description:
+//
+//
+// Author: Konrad Rosenbaum <konrad@silmor.de>, (C) 2008
+//
+// Copyright: See README/COPYING files that come with this distribution
+//
+//
+
+#include "checkdlg.h"
+
+#include <QCheckBox>
+#include <QScrollArea>
+#include <QPushButton>
+#include <QBoxLayout>
+
+MCheckDialog::MCheckDialog(QWidget*parent,const MCheckList&checks,QString title)
+ :QDialog(parent),m_list(checks)
+{
+ setWindowTitle(title);
+ //basic layout
+ QVBoxLayout *vl=new QVBoxLayout;
+ setLayout(vl);
+ QScrollArea *sa=new QScrollArea;
+ vl->addWidget(sa,10);
+ QHBoxLayout *hl=new QHBoxLayout;
+ vl->addLayout(hl,0);
+ hl->addStretch(10);
+ QPushButton*p;
+ hl->addWidget(p=new QPushButton(tr("Ok")),0);
+ connect(p,SIGNAL(clicked()),this,SLOT(accept()));
+ hl->addWidget(p=new QPushButton(tr("Cancel")),0);
+ connect(p,SIGNAL(clicked()),this,SLOT(reject()));
+ //fill area
+ QWidget*w=new QWidget;
+ w->setLayout(vl=new QVBoxLayout);
+ for(int i=0;i<m_list.size();i++){
+ QCheckBox *cb=new QCheckBox(m_list[i].label());
+ cb->setChecked(m_list[i].isSet());
+ vl->addWidget(cb);
+ m_boxes.append(cb);
+ }
+ sa->setWidget(w);
+}
+
+MCheckList MCheckDialog::getCheckList()const
+{
+ for(int i=0;i<m_boxes.size();i++)
+ m_list[i].set(m_boxes[i]->isChecked());
+ return m_list;
+}
+
class QCheckBox;
-/**abstract base class for items that can be displayed in a MCheckDialog*/
+/**class for items that can be displayed in a MCheckDialog*/
class MCheckItem
{
public:
- /**constructs an empty check item*/
- MCheckItem();
- /**deletes the check item*/
- virtual ~MCheckItem();
+ /**constructs a check item*/
+ MCheckItem(QString key=QString(),bool isset=false,QString label=QString())
+ {m_key=key;m_set=isset;if(label!="")m_label=label;else m_label=m_key;}
/**overwrite this to return a label that can be displayed*/
- virtual QString label()const=0;
+ virtual QString label()const{return m_label;}
/**overwrite this to return a key string that identifies the item (default implementation returns the label)*/
- virtual QString key()const;
+ virtual QString key()const{return m_key;}
/**overwrite this to return whether the item is checked*/
- virtual bool isSet()const=0;
+ virtual bool isSet()const{return m_set;}
/**overwrite this to change the checking status of the item*/
- virtual void set(bool)=0;
+ virtual void set(bool b){m_set=b;}
protected:
- friend class MCheckList;
- /**overwrite this to creat an exact copy of the item (must be implemented and must return non-NULL)*/
- virtual MCheckItem* copy()const=0;
+ QString m_key,m_label;
+ bool m_set;
};
/**implements a list of checkable items*/
-class MCheckList
-{
- public:
- /**instantiate an empty list*/
- MCheckList();
- /**creates an exact copy of the list (uses MCheckItem::copy() )*/
- MCheckList(const MCheckList&);
- /**deletes the list*/
- ~MCheckList();
-
- /**adds an item to the list*/
- void addItem(MCheckItem*);
- /**returns the size of the list*/
- int size()const;
-
- /**returns a writable reference to an item*/
- MCheckItem& operator[](int);
- /**returns a const reference to an item*/
- const MCheckItem& operator[](int)const;
-
- /**makes this list an exact copy of the argument*/
- MCheckList& operator=(const MCheckList&);
- private:
- QList<MCheckItem*> m_items;
-};
+typedef QList<MCheckItem> MCheckList;
/**a dialog that consists of check boxes in a QScrollArea */
class MCheckDialog:public QDialog
dialogs/login.h \
dialogs/shipping.h \
dialogs/customerdlg.h \
+ dialogs/checkdlg.h \
dialogs/passwdchg.h
SOURCES += \
dialogs/login.cpp \
dialogs/shipping.cpp \
dialogs/customerdlg.cpp \
+ dialogs/checkdlg.cpp \
dialogs/passwdchg.cpp
INCLUDEPATH += ./dialogs
\ No newline at end of file
--- /dev/null
+//
+// C++ Interface: unabstract
+//
+// Description: removes abstract flag from classes that only need to be abstract in PHP
+//
+//
+// Author: Konrad Rosenbaum <konrad@silmor.de>, (C) 2009
+//
+// Copyright: See README/COPYING files that come with this distribution
+//
+//
+
+#ifndef MAGICSMOKE_MOROLE_H
+#define MAGICSMOKE_MOROLE_H
+
+#include "MORoleAbstract.h"
+typedef MORoleAbstract MORole;
+
+#endif
\ No newline at end of file
//
#include "checkdlg.h"
-// #include "main.h"
-// #include "misc.h"
#include "msinterface.h"
+#include "passwdchg.h"
#include "acltabs.h"
-// #include <QApplication>
#include <QBoxLayout>
-// #include <QCheckBox>
-// #include <QComboBox>
-// #include <QCryptographicHash>
-// #include <QDomDocument>
-// #include <QDomElement>
-// #include <QFile>
-// #include <QFileDialog>
-// #include <QFrame>
#include <QInputDialog>
#include <QLabel>
#include <QLineEdit>
-// #include <QMenu>
-// #include <QMenuBar>
#include <QMessageBox>
#include <QPushButton>
-// #include <QSettings>
-// #include <QSpinBox>
#include <QStandardItemModel>
-// #include <QStatusBar>
-// #include <QTabWidget>
#include <QTableView>
-// #include <QTextEdit>
#define req (MSInterface::instance())
hl->addLayout(vl=new QVBoxLayout,0);
vl->addWidget(p=new QPushButton(tr("New User...")),0);
connect(p,SIGNAL(clicked()),this,SLOT(newUser()));
- p->setEnabled(req->hasRole("adduser"));
+ p->setEnabled(req->hasRight(req->RCreateUser));
vl->addWidget(p=new QPushButton(tr("Delete User...")),0);
connect(p,SIGNAL(clicked()),this,SLOT(deleteUser()));
- p->setEnabled(req->hasRole("deleteuser"));
+ p->setEnabled(req->hasRight(req->RDeleteUser));
vl->addSpacing(20);
vl->addWidget(p=new QPushButton(tr("Description...")),0);
connect(p,SIGNAL(clicked()),this,SLOT(editUserDescription()));
- p->setEnabled(req->hasRole("setuserdescription"));
+ p->setEnabled(req->hasRight(req->RSetUserDescription));
vl->addWidget(p=new QPushButton(tr("Hosts...")),0);
connect(p,SIGNAL(clicked()),this,SLOT(editUserHosts()));
- p->setEnabled(req->hasRole("getuserhosts"));
+ p->setEnabled(req->hasRight(req->RGetUserHosts));
vl->addWidget(p=new QPushButton(tr("Roles...")),0);
connect(p,SIGNAL(clicked()),this,SLOT(editUserRoles()));
- p->setEnabled(req->hasRole("getuseracl"));
+ p->setEnabled(req->hasRight(req->RGetUserRoles));
vl->addWidget(p=new QPushButton(tr("Set Password...")),0);
connect(p,SIGNAL(clicked()),this,SLOT(setUserPassword()));
- p->setEnabled(req->hasRole("setpasswd"));
+ p->setEnabled(req->hasRight(req->RChangePassword));
vl->addStretch(10);
- //TODO: convert to right instead role
- if(req->hasRole("getusers")){
+ if(req->hasRight(req->RGetAllUsers)){
updateUsers();
}else{
setEnabled(false);
QString rp=QInputDialog::getItem(this,tr("Delete User"),tr("Select which user will inherit this users database objects:"),rplc,0,false,&ok);
if(!ok)return;
//delete
- MTDeleteUser ret=req->queryDeleteUser(name,rp);
+ MTDeleteUser ret=req->queryDeleteUser(name,rp[0]=='('?"":rp);
if(ret.hasError())
QMessageBox::warning(this,tr("Error"),tr("Cannot delete user: %1").arg(ret.errorString()));
updateUsers();
QString descr=usermodel->data(usermodel->index(sel.row(),1)).toString();
//edit descr
bool ok;
- descr=QInputDialog::getText(this,tr("Edit Description"),tr("Descriptionof user %1:").arg(name),QLineEdit::Normal,descr,&ok);
+ descr=QInputDialog::getText(this,tr("Edit Description"),tr("Description of user %1:").arg(name),QLineEdit::Normal,descr,&ok);
if(ok)
req->querySetUserDescription(name,descr);
//update
}
void MUserTab::editUserRoles()
-{/*TODO
+{
//get selection
QModelIndex sel=usertable->currentIndex();
if(!sel.isValid())return;
//get uname & descr
QString name=usermodel->data(usermodel->index(sel.row(),0)).toString();
//...
- MOUser 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());*/
+ MTGetUserRoles gr=req->queryGetUserRoles(name);
+ if(gr.hasError()){
+ QMessageBox::warning(this,tr("Warning"),tr("Cannot retrieve user roles: %1").arg(gr.errorString()));
+ return;
+ }
+ MTGetAllRoles ar=req->queryGetAllRoles();
+ if(ar.hasError()){
+ QMessageBox::warning(this,tr("Warning"),tr("Cannot retrieve role descriptions: %1").arg(ar.errorString()));
+ return;
+ }
+ MCheckList acl;
+ QStringList urole=gr.getroles();
+ QList<MORole>aroles=ar.getroles();
+ for(int i=0;i<aroles.size();i++){
+ QString nm=aroles[i].name();
+ QString lb=nm+": "+aroles[i].description();
+ acl<<MCheckItem(nm,urole.contains(nm),lb);
+ }
+ MCheckDialog cd(this,acl,"Edit Roles of user "+name);
+ if(cd.exec()==QDialog::Accepted);
+// usr.setRoles(cd.getCheckList());
}
void MUserTab::editUserHosts()
}
void MUserTab::setUserPassword()
-{/*TODO
+{
//get selection
QModelIndex sel=usertable->currentIndex();
if(!sel.isValid())return;
QMessageBox::warning(this,tr("Warning"),tr("The password must be non-empty and both lines must match"));
return;
}
- //...
- MUser usr(req,name);
- usr.changePassword(p);*/
+ //query
+ MTChangePassword cp=req->queryChangePassword(name,p);
+ if(cp.hasError()){
+ QMessageBox::warning(this,tr("Warning"),tr("Error while setting password: %1").arg(cp.errorString()));
+ }
}
/*****************************************************************************/
class QStandardItemModel;
class QTabWidget;
class QTableView;
+class QTextEdit;
class MSInterface;
if(!req->hasRole("getorderlist")){
tab->setTabEnabled(tab->indexOf(ordertab),false);
}
- if(!req->hasRole("getusers")){
+ if(!req->hasRight(req->RGetAllUsers)){
tab->setTabEnabled(tab->indexOf(usertab),false);
}
if(!req->hasRole("gethosts")){
+++ /dev/null
-//
-// C++ Implementation: checkdlg
-//
-// Description:
-//
-//
-// Author: Konrad Rosenbaum <konrad@silmor.de>, (C) 2008
-//
-// Copyright: See README/COPYING files that come with this distribution
-//
-//
-
-#include "checkdlg.h"
-
-#include <QCheckBox>
-#include <QScrollArea>
-#include <QPushButton>
-#include <QBoxLayout>
-
-MCheckDialog::MCheckDialog(QWidget*parent,const MCheckList&checks,QString title)
- :QDialog(parent),m_list(checks)
-{
- setWindowTitle(title);
- //basic layout
- QVBoxLayout *vl=new QVBoxLayout;
- setLayout(vl);
- QScrollArea *sa=new QScrollArea;
- vl->addWidget(sa,10);
- QHBoxLayout *hl=new QHBoxLayout;
- vl->addLayout(hl,0);
- hl->addStretch(10);
- QPushButton*p;
- hl->addWidget(p=new QPushButton(tr("Ok")),0);
- connect(p,SIGNAL(clicked()),this,SLOT(accept()));
- hl->addWidget(p=new QPushButton(tr("Cancel")),0);
- connect(p,SIGNAL(clicked()),this,SLOT(reject()));
- //fill area
- QWidget*w=new QWidget;
- w->setLayout(vl=new QVBoxLayout);
- for(int i=0;i<m_list.size();i++){
- QCheckBox *cb=new QCheckBox(m_list[i].label());
- cb->setChecked(m_list[i].isSet());
- vl->addWidget(cb);
- m_boxes.append(cb);
- }
- sa->setWidget(w);
-}
-
-MCheckList MCheckDialog::getCheckList()const
-{
- for(int i=0;i<m_boxes.size();i++)
- m_list[i].set(m_boxes[i]->isChecked());
- return m_list;
-}
-
-/**************************************************/
-
-MCheckItem::MCheckItem(){}
-MCheckItem::~MCheckItem(){}
-
-QString MCheckItem::key()const{qDebug("???????????");return label();}
-
-MCheckList::MCheckList(){}
-
-MCheckList::MCheckList(const MCheckList&l)
-{
- for(int i=0;i<m_items.size();i++)
- delete m_items[i];
- m_items.clear();
- for(int i=0;i<l.m_items.size();i++)
- m_items.append(l.m_items[i]->copy());
-}
-
-MCheckList& MCheckList::operator=(const MCheckList&l)
-{
- for(int i=0;i<l.m_items.size();i++)
- m_items.append(l.m_items[i]->copy());
-}
-
-MCheckList::~MCheckList()
-{
- for(int i=0;i<m_items.size();i++)
- delete m_items[i];
-}
-
-void MCheckList::addItem(MCheckItem*i)
-{
- if(i!=0)m_items.append(i);
-}
-
-int MCheckList::size()const
-{
- return m_items.size();
-}
-
-MCheckItem& MCheckList::operator[](int i)
-{
- return * m_items[i];
-}
-
-const MCheckItem& MCheckList::operator[](int i)const
-{
- return * m_items[i];
-}
HEADERS += \
widgets/waitcursor.h \
widgets/centbox.h \
- widgets/checkdlg.h \
widgets/listview.h \
widgets/treeview.h
SOURCES += \
widgets/waitcursor.cpp \
widgets/centbox.cpp \
- widgets/checkdlg.cpp \
widgets/listview.cpp \
widgets/treeview.cpp
</Transaction>
<Class name="User">
+ <Doc>This class represents the main information about users: login name plus description. Passwords are never carried towards the client, more detailed info is contained in other classes.</Doc>
<Property name="name" type="astring"/>
<Property name="description" type="string"/>
+ <Mapping table="user">
+ <Map column="uname" property="name"/>
+ <Map column="description"/>
+ </Mapping>
</Class>
<Class name="Host">
<Transaction name="GetAllUsers">
<Input/>
+ <Call lang="php" method="$this->setusers(WOUser::fromTableArrayuser(WTuser::selectFromDB()));"/>
<Output>
<Var name="users" type="List:User"/>
</Output>
<Var name="password" type="string"/>
<Var name="description" type="string"/>
</Input>
+ <Call lang="php" method="MachineUser::createUser($this);"/>
<Output>
<Var name="user" type="User"/>
</Output>
<Var name="username" type="astring"/>
<Var name="password" type="string"/>
</Input>
+ <Call lang="php" method="MachineUser::changePasswd($this);"/>
<Output/>
</Transaction>
<Var name="username" type="astring"/>
<Var name="mergewithuser" type="astring"/>
</Input>
+ <Call lang="php" method="MachineUser::deleteUser($this);"/>
</Transaction>
<Transaction name="SetUserDescription">
<Var name="username" type="astring"/>
<Var name="description" type="string"/>
</Input>
+ <Call lang="php" method="MachineUser::setUserDescription($this);"/>
</Transaction>
<Transaction name="GetUserRoles">
<Input>
<Var name="username" type="astring"/>
</Input>
+ <Call lang="php" method="MachineUser::getUserRoles($this);"/>
<Output>
<Var name="roles" type="List:string"/>
- <Var name="rights" type="List:astring"/>
</Output>
</Transaction>
<Var name="username" type="astring"/>
<Var name="roles" type="List:string"/>
</Input>
+ <Call lang="php" method="MachineUser::setUserRoles($this);"/>;
<Output/>
</Transaction>
+ <Class name="Role" abstract="yes">
+ <Property name="name" type="string"/>
+ <Property name="description" type="string"/>
+ <Property name="flags" type="string"/>
+ <Property name="rights" type="List:string"/>
+ <Mapping table="role">
+ <Map column="rolename" property="name"/>
+ <Map column="description"/>
+ <Map column="flags"/>
+ <Map property="rights">
+ <Call lang="php" method="$data->getRightsFromDB()"/>
+ </Map>
+ <!-- how about rights? -->
+ </Mapping>
+ </Class>
+
+ <Transaction name="GetAllRoles">
+ <Input/>
+ <Call lang="php" method="$this->setroles(WORole::fromTableArrayrole(WTrole::selectFromDB()));"/>
+ <Output>
+ <Var name="roles" type="List:Role"/>
+ </Output>
+ </Transaction>
+
+ <Transaction name="CreateRole"/>
+
<Transaction name="GetAllHostNames">
<Input/>
<Output>
//initializer
code+="protected function __construct(array $data,$isfromdb){parent::__construct($data,$isfromdb,\""+tbl.name()+"\");}\n\n";
+ //static new instance for insert only
+ code+="public static function newRow(){return new WT"+tbl.name()+"(array(),false);}\n\n";
+
//static get instance
QStringList cols=tbl.columns();
QStringList pcols=tbl.primaryColumns();
//load WOB data
include('./inc/wbase/autoload.php');
include('./inc/wob/autoload.php');
+include('./inc/wext/autoload.php');
//load DB drivers
include('./inc/db/autoload.php');
include('./config.php');
$AUTOCLASS["Template"]="./inc/machine/template.php";
$AUTOCLASS["Version"]="./inc/machine/version.php";
$AUTOCLASS["Translation"]="./inc/machine/translation.php";
+$AUTOCLASS["MachineUser"]="./inc/machine/muser.php";
?>
\ No newline at end of file
--- /dev/null
+<?
+//
+// PHP Implementation: muser
+//
+// Description: machine interface for user management
+//
+//
+// Author: Konrad Rosenbaum <konrad@silmor.de>, (C) 2009
+//
+// Copyright: See README/COPYING files that come with this distribution
+//
+//
+
+/**encapsulated machine user management in several static functions;
+it is called directly from the user centered transactions;
+DO NOT USE THIS CLASS OUTSIDE TRANSACTION CONTEXT!*/
+class MachineUser
+{
+ /**create a new user*/
+ static public function createUser($trans)
+ {
+ //check whether user exists
+ $usr=WTuser::getFromDB($trans->getusername());
+ if($usr!==false){
+ $trans->abortWithError(tr("User already exists."));
+ return;
+ }
+ //verify syntax
+ if(!ereg("^[a-zA-Z]([a-zA-Z_\\.-]*)$",$trans->getusername())){
+ $trans->abortWithError(tr("Username is invalid."));
+ return;
+ }
+ //create DB entry
+ $usr=WTuser::newRow();
+ $usr->uname=$trans->getusername();
+ $slt=getSalt();
+ $hsh=sha1($slt.$trans->getpassword());
+ $usr->passwd=$slt." ".$hsh;
+ $usr->insert();
+ $trans->setuser(MOUser::fromTableuser($usr));
+ }
+
+ static public function deleteUser($trans)
+ {
+ //sanity check: do users exist
+ $un=$trans->getusername();
+ $usr=WTuser::getFromDB($un);
+ if($usr===false){
+ $trans->abortWithError(tr("User does not exist."));
+ return;
+ }
+ $mun=$trans->getmergewithuser();
+ if($mun=="")$mun=false;
+ $mu=false;
+ if($mun!==false){
+ $mu=WTuser::getFromDB($mun);
+ if($mu===false){
+ $trans->abortWithError(tr("Merge target user does not exist!"));
+ return;
+ }
+ }
+ //check: are users identical?
+ if($un==$mun){
+ $trans->abortWithError(tr("User and merge target user are identical."));
+ return;
+ }
+ //perform merge
+ global $db;
+ if($mu!==false){
+ //TODO: merge users
+ }
+ //delete user
+ $usr->deleteFromDB();
+ }
+
+ static public function changePasswd($trans)
+ {
+ $usr=WTuser::getFromDB($trans->getusername());
+ }
+
+ static public function setUserDescription($trans)
+ {
+ $usr=WTuser::getFromDB($trans->getusername());
+ if($usr===false){
+ $trans->abortWithError(tr("User does not exist."));
+ return;
+ }
+ $usr->description=$trans->getdescription();
+ $usr->update();
+ }
+
+ static public function getUserRoles($trans)
+ {
+ //sanity check
+ $usr=WTuser::getFromDB($trans->getusername());
+ if($usr===false){
+ $trans->abortWithError(tr("User does not exist."));
+ return;
+ }
+ //get roles
+ global $db;
+ $rls=WTuserrole::selectFromDB("uname=".$db->escapeString($trans->getusername()));
+ $r=array();
+ foreach($rls as $rl){
+ $r[]=$rl->role;
+ }
+ $trans->setroles($r);
+ }
+
+ static public function setUserRoles($trans){}
+
+};
+
+?>
\ No newline at end of file
if(in_array("_admin",$this->roles))return true;
return in_array($transaction,$this->rights);
}
-
- /**called for GetMyRoles transaction*/
- public function getMyRoles()
- {
- global $db;
- header("X-MagicSmoke-Status: Ok");
- $res=$db->select("userrole","role","uname=".$db->escapeString($this->user));
- foreach($res as $rl)
- print($rl["role"]."\n");
- }
};
/**dummy class used by browsed pages to represent the virtual web user*/
/**insert the object under a new primary key value into the DB (implicitly calls newKey); returns true on success*/
public function insert()
{
- global $dbScheme;
+ global $dbScheme,$db;
$this->isfromdb=false;
//create new key
$this->newKey();
$this->isfromdb=true;
$this->data=$data;
$this->cdata=array();
- createAudit();
+ $this->createAudit();
//assign primary key if sequence (otherwise newKey has done it)
$seq=$dbScheme->hasSequence($this->table);
if($seq!==false)
/**generate a new primary key value for insert and marks the object as not yet in the DB; the default sets the primary key to NULL if it is a sequence; call the original first if you overwrite it*/
public function newKey()
{
+ global $dbScheme;
$this->isfromdb=false;
$pk=$dbScheme->hasSequence($this->table);
if($pk!==false){
if($succ){
foreach($this->cdata as $k=>$d)$this->data[$k]=$d;
$this->cdata=array();
- createAudit();
+ $this->createAudit();
}
return $succ;
}
--- /dev/null
+<?
+//
+// PHP Implementation: autoload
+//
+// Description:
+//
+//
+// Author: Konrad Rosenbaum <konrad@silmor.de>, (C) 2009
+//
+// Copyright: See README/COPYING files that come with this distribution
+//
+//
+
+$AUTOCLASS["WORole"]="inc/wext/role.php";
+?>
\ No newline at end of file
--- /dev/null
+<?
+//
+// PHP Implementation: role
+//
+// Description:
+//
+//
+// Author: Konrad Rosenbaum <konrad@silmor.de>, (C) 2009
+//
+// Copyright: See README/COPYING files that come with this distribution
+//
+//
+
+class WORole extends WORoleAbstract{
+ protected function getRightsFromDB()
+ {
+ global $db;
+ $rtl=$db->select("roleright","rolename=".$db->escapeString($this->prop_name));
+ $ret=array();
+ foreach($rtl as $rt){
+ $ret[]=$rt["rightname"];
+ }
+ return $ret;
+ }
+};
+
+?>
\ No newline at end of file