This commit is contained in:
tomas 2004-07-23 00:22:13 +00:00
parent 2949dbe982
commit 13ecac28d0
29 changed files with 5181 additions and 0 deletions

View File

@ -0,0 +1,227 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/1999/REC-html401-19991224/strict.dtd">
<html>
<head>
<title>Auth library</title>
<meta content="Tomas Hlava" name="author">
<style type="text/css"><!--
* { font-family: 'Arial CE', 'Helvetica CE', Arial, sans-serif; font-size: 10pt; }
body { padding: 1em; }
h1 { font-size: 14pt; padding:1px; background-color: #66aaff; }
h2 { font-size: 11pt; padding:1px; padding-left:1ex; background-color: #aaccff; }
h3 { font-size: 10pt; padding:1px; padding-left:2ex; background-color: #aaffcc; }
p { width: 90%; text-indent: 1em; }
p#ps { clear: both; }
.center { text-align:center; }
.aart { width: 90%; font-family:monospace; }
.aart span{ font-family:monospace; padding:0ex 1ex; background-color: #eee; }
.aart div{ font-family:monospace; padding:0ex 1ex; }
code { font-family:monospace; font-weight:bold; background-color: #e4e4e4; }
.b { font-weight:bold; }
.ulg p { margin-bottom: 0px; }
.ulg ul,ol { margin-top: 0px; }
.ex { padding:1em; background-color:#f0f0f0; width:80%; overflow:auto; }
.bg { padding:2px 4px; background-color:#eaeaea; }
table { border: 2px solid black; border-collapse: collapse; }
table th { border: solid black; border-width: 2px 1px; }
table td { border: 1px solid black; text-align:center; }
hr { border:0px; border-bottom: 1px solid #66aaff; }
hr.hr2 { border:0px; border-bottom: 2px solid #66aaff; }
/*#date { float: left; width:30%; padding:1ex; }*/
/*#signature { float: right; width:30%; padding:1ex; text-align: right; }*/
#signature { float: left; width:30%; padding:1ex; }
--></style>
</head>
<body>
<h1>Auth library - request for comments</h1>
22.7.2004
<h2>Authentication &amp; authorization</h2>
<p> <span class="b">Authentication</span> - as user's identity
checking - login call create and return auth token, client sends this token
with all subsequent calls, logout call make this token invalid<br>
</p>
<p> <span class="b">Authorization</span> - as checking user's
permission for called action on some object - that's main solved problem.
</p>
<h2>Basic model</h2>
<div class="aart center"><span>Subject --- Action ---&gt; Object</span></div>
<div class="ulg">
<p>Where:</p>
<ul>
<li>Subject<br>
is one user or user group (or role - in this aproach group and role are the same)<br>
</li>
<li>Action<br>
is item from predefined action set
</li>
<li>Object<br>
is a object from tree or class of objects
</li>
</ul>
</div>
<h2>Subject implementation</h2>
<p> Subjects are divided into two types - users and groups. There is membership relation
(type N:M) from subjects table to itself with "linearization" feature - for
questions about it send me a mail please ;)<br>
This approach allows inserting user to group or group to group with quick
searching of direct and indirect membership.
</p>
<h2>Object implementation</h2>
<p> For simple use with existing projects, there would be a object tree
always separated from project's database tables. It would be implemented by
table of objects and information about parent/child (or other) relation
between objects.
</p>
<p>
There is also class table and N:M membership relation between objects and
classes.
</p>
<h3>Example:</h3>
<div class="ex">
<pre class="aart">
RootNode
|
|-&gt; Publication_A(publication)
| \-&gt; Issue_1(issue) &lt;--\
| |-&gt; Sport(section) | &lt;--\
| \-&gt; Politics(section) | |
\-&gt; Publication_B(publication) | |
|-&gt; Issue_1(issue) &lt;--| |
| |-&gt; Politics(section) | |
| |-&gt; Sport(section) | &lt;--|
| \-&gt; Culture(section) | |
\-&gt; Issue_2(issue) &lt;--| |
|-&gt; Culture(section) | |
\-&gt; Politics(section) | |
| |
Class &quot;Issues&quot; -------------------------------------------/ |
Class &quot;Sport sections&quot; -------------------------------------------/
</pre>
<!--
Object table structure:<br>
<code><span class="b">[</span> id, name, type, parid, lft, rgt, level <span class="b">]</span></code><br>
class table structure:<br>
<code><span class="b">[</span> id, cname <span class="b">]</span></code><br>
and class membership table structure:<br>
<code><span class="b">[</span> objid, cid <span class="b">]</span></code><br>
-->
</div>
<h2>Permissions for actions</h2>
<p> There are several ways to handle permissions - I've used this:<br>
<span class="b">allow/deny</span> - all without allow
permission is denied, but more specified setting may overcome less
specified<br>
(e.g. group of users is allowed to do smth., but one specified group-member is
denied)
</p>
<p> Permissions are stored as triple <code class="bg"><span
class="b">[</span>subject, action, object<span class="b">]</span></code>
and <span class="b">allow/deny</span> flag.<br>
</p>
<div class="ulg">
<p>Procedure of permission checking:</p>
<ul>
<li>Select all permissions on corresponding object + all objects in tree path<br>
for actual user + all groups, where user have direct or indirect membership.
</li>
<li>Sort it by:<ol>
<li>diference in tree levels for object
<li>membership level for subject
<li>record with '_all' action have lower priority
<li>'deny' records have higher priority then 'allow'
</ol></li>
<li>If no record found then repeat similar query with class table instead of object tree table. (+ similar sorting)</li>
<li>If record on the top of sorted sequence have 'allow' type then return allow else deny</li>
</ul>
</div>
<p>Rem.: Some cache system for authorization decisions would be good ...
</p>
<h2>Auth system usage</h2>
<div class="ulg">
<p>There are 3 main types of usage:</p>
<ol>
<li>authorization of called action</li>
<li>automatic modification of user interface in dependence on user
permissions</li>
<li>automatic generation of admin interface for permissions settings</li>
</ol>
</div>
<h2>Important part of API:</h2>
<div class="ulg">
<ul>
<li>function <code>Alib(&$dbc, $config)</code> returns object<br>
constructor
</li>
<li>function <code>login($login, $pass)</code> returns token<br>
</li>
<li>function <code>logout($sessid)</code> returns boolean<br>
</li>
<li>function <code>checkToken($sessid)</code> returns boolean<br>
check validity of the token
</li>
<li>function <code>addObj($name, $type, $parid, $aftid, $param)</code> returns int<br>
adds object to tree as child of object with id=$parid after object with id=$aftid
</li>
<li>function <code>removeObj($id)</code> returns boolean<br>
</li>
<li>function <code>addSubj($login, $pass)</code> returns int<br>
add user (or group - with $pass=null)
</li>
<li>function <code>removeSubj($login)</code> returns boolean<br>
</li>
<li>function <code>addPerm($sid, $action, $oid, $type)</code> returns int<br>
add permission record - type is A(allow) or D(deny)
</li>
<li>function <code>removePerm($permid, $subj, $obj)</code> returns null<br>
remove permission record
</li>
<li>function <code>checkPerm($sid, $action, $oid)</code> returns boolean<br>
check permission for action on object with id=$oid for subject with id=$sid
</li>
<li>function <code>copyObj($id, $newParid, $after)</code> returns int<br>
</li>
<li>function <code>renameObj($id, $newName)</code> returns boolean<br>
</li>
<li>function <code>getParent($oid)</code> returns string<br>
</li>
<li>function <code>getPath($id, $flds)</code> returns array<br>
</li>
<li>function <code>getDir($id, $flds, $order)</code> returns array<br>
</li>
<li>function <code>addClass($cname)</code> returns int<br>
</li>
<li>function <code>removeClass($cname)</code> returns boolean<br>
</li>
<li>function <code>addObj2Class($cid, $oid)</code> returns boolean<br>
</li>
<li>function <code>removeObjFromClass($oid, $cid)</code> returns boolean<br>
</li>
<li>function <code>addSubj2Gr($login, $gname)</code> returns int<br>
</li>
<li>function <code>removeSubjFromGr($login, $gname)</code> returns boolean<br>
</li>
<li>function <code>isGroup($gid)</code> returns boolean<br>
</li>
<li>function <code>listGroup($gid)</code> returns array<br>
</li>
</ul>
<p>All methods may return PEAR::error object if fails ...</p>
</div>
<h2>Connection to existing applications</h2>
<p> PHP applications could include Alib class and call API methods
directly.<br>
Other programming platforms should call XMLRPC or HTTP layer above this API.
</p>
<hr class="hr2">
<div id="footer">
<div id="signature"> Tomas Hlava<br>
<a href="mailto:th@red2head.com">th@red2head.com</a><br>
</div>
</div>
<p id="ps">P.S.: sorry for my English ... ;)</p>
</body>
</html>

View File

@ -0,0 +1,60 @@
<html><head>
<!-- $Id: reference.html,v 1.1 2004/07/23 00:22:13 tomas Exp $ -->
<title>Alib reference</title>
<style type="text/css">
<!--
* { font-family: 'Arial CE', 'Helvetica CE', Arial, sans-serif; font-size: 10pt; }
body { padding: 1em; }
h1 { font-size: 14pt; padding:1px; background-color: #66aaff; }
h2 { font-size: 11pt; padding:1px; padding-left:1ex; background-color: #aaccff; }
h3 { font-size: 10pt; padding:1px; padding-left:2ex; background-color: #aaffcc; }
p { width: 90%; text-indent: 1em; }
pre { border: 1px dashed grey; padding:1em; }
p:first-letter { padding-left:2em; }
.center { text-align:center; }
.aart { width: 90%; font-family:monospace; }
.aart span{ font-family:monospace; padding:0ex 1ex; background-color: #eee; }
.aart div{ font-family:monospace; padding:0ex 1ex; }
code { font-family:monospace; }
.b { font-weight:bold; }
-->
</style>
</head></body>
<h1>Alib reference</h1>
in construction - sorry ;)
<a name="contents"></a>
<h2>Contents</h2>
<ol>
<li><a href="#subjs">Subjects</a></li>
<li><a href="#perms">Perms</a></li>
<li><a href="#objs">Objects</a></li>
<li><a href="#classes">Classes</a></li>
<li><a href="#dbstr">DB structure</a></li>
</ol>
<a name="subjs"></a>
<h2>Subjects</h2>
<a name="perms"></a>
<h2>Perms</h2>
<a name="objects"></a>
<h2>Objects</h2>
<a name="classes"></a>
<h2>Classes</h2>
<p>Classes may be replaced by one branch in object tree ...</p>
<a name="dbstr"></a>
<h2>DB structure</h2>
<pre>
subjects &lt; perms &gt; objects/classes
&lt; smemb
cmemb &gt;
</pre>
</body></html>

View File

@ -0,0 +1,17 @@
$Id: todo.txt,v 1.1 2004/07/23 00:22:13 tomas Exp $
* delete old sessions
* if user have 'classes' permission:
-> create new class ('X')
-> add '_all' perm on class 'X' to himself
-> insert RootNode to class 'X'
=> user have all perms ;)
* complete xmlrpc layer
---
partialy done:
. actions would have priority order (or set lower priority to '_all' action only),
temp hack: '_all' action is in string sort after all act names => with ASC order have '_all' lower prio ...
---

View File

@ -0,0 +1,444 @@
<?php
// $Id: alib.php,v 1.1 2004/07/23 00:22:13 tomas Exp $
/**
* Alib class
*
* authentication/authorization class
**/
require_once 'subj.php';
define('ALIBERR_NOTLOGGED', 30);
define('ALIBERR_NOTEXISTS', 31);
class Alib extends Subjects{
var $permTable;
var $sessTable;
var $login=NULL;
var $userid=NULL;
var $sessid=NULL;
/** Alib - constructor
*
* @param object DB
* @param config array
* @return this
**/
function Alib(&$dbc, $config)
{
parent::Subjects(&$dbc, $config);
$this->permTable = $config['tblNamePrefix'].'perms';
$this->sessTable = $config['tblNamePrefix'].'sess';
}
/* ========== public methods: ========== */
/* --- session/authentication --- */
/**
* login
*
* @param login string
* @param pass string
* @return boolean/sessionId/err
**/
function login($login, $pass)
{
if(FALSE === $this->authenticate($login, $pass)) return FALSE;
for($c=1; $c>0;){
$sessid = md5(uniqid(rand()));
$c = $this->dbc->getOne("SELECT count(*) FROM {$this->sessTable} WHERE sessid='$sessid'");
if(PEAR::isError($c)) return $c;
}
$userid = $this->getSubjId($login);
$r = $this->dbc->query("INSERT INTO {$this->sessTable} (sessid, userid, login)
VALUES ('$sessid', '$userid', '$login')");
if(PEAR::isError($r)) return $r;
$this->login = $login;
$this->userid = $userid;
$this->sessid = $sessid;
return $sessid;
}
/**
* logout
*
* @param sessid string
* @return true/err
**/
function logout($sessid)
{
$ct = $this->checkToken($sessid);
if($ct === FALSE)
return PEAR::raiseError('Alib::logout: not logged ($ct)', ALIBERR_NOTLOGGED, PEAR_ERROR_RETURN);
elseif(PEAR::isError($ct))
return $ct;
else{
$r = $this->dbc->query("DELETE FROM {$this->sessTable} WHERE sessid='$sessid'");
if(PEAR::isError($r)) return $r;
$this->login = NULL;
$this->userid = NULL;
$this->sessid = NULL;
return TRUE;
}
}
/**
* checkToken
*
* @param sessid string
* @return boolean/err
**/
function checkToken($sessid)
{
$c = $this->dbc->getOne("SELECT count(*) as cnt FROM {$this->sessTable} WHERE sessid='$sessid'");
return ($c == 1 ? TRUE : (PEAR::isError($c) ? $c : FALSE ));
}
/**
* setToken
*
* @param sessid string
* @return boolean/err
**/
function setToken($sessid)
{
$r = checkToken($sessid);
if(PEAR::isError($r)) return $r;
if(!$r) return PEAR::raiseError("ALib::setToken: invalid token ($sessid)");
$this->sessid = $sessid;
return TRUE;
}
/* --- authorization --- */
/**
* addPerm
*
* @param sid int
* @param action string
* @param oid int
* @param type char
* @return int/err
**/
function addPerm($sid, $action, $oid, $type='A')
{
$permid = $this->dbc->nextId("{$this->permTable}_id_seq");
$r = $this->dbc->query($q = "
INSERT INTO {$this->permTable} (permid, subj, action, obj, type)
VALUES ($permid, $sid, '$action', $oid, '$type')
");
if(PEAR::isError($r)) return($r);
return $permid;
}
/**
* removePerm
*
* @param permid int OPT
* @param subj int OPT
* @param obj int OPT
* @return null/error
**/
function removePerm($permid=NULL, $subj=NULL, $obj=NULL)
{
return $this->dbc->query("DELETE FROM {$this->permTable} WHERE 1=1".
($permid ? " AND permid=$permid" : '').
($subj ? " AND subj=$subj" : '').
($obj ? " AND obj=$obj" : '')
);
}
/**
* checkPerm
*
* @param sid int
* @param action string
* @param oid int OPT
* @return boolean/err
**/
function checkPerm($sid, $action, $oid=NULL)
{
if(!is_numeric($sid)) return FALSE;
if(is_null($oid)) $oid = $this->getObjId($this->RootNode);
if(PEAR::isError($oid)) return $oid;
if(!is_numeric($oid)) return FALSE;
// query elements
$q_flds = "m.level as S_lvl, p.subj, s.login, action, p.type, p.obj";
$q_from = "{$this->subjTable} s, {$this->permTable} p";
$q_join = "LEFT JOIN {$this->smembTable} m ON p.subj=m.gid ";
$q_cond = "p.action in('_all', '$action') AND (m.uid=$sid OR p.subj=$sid) AND s.id=p.subj";
$q_ordb = "ORDER BY S_lvl, action, p.type DESC"; // action ASC order is hack for lower priority of '_all'
$qc0 = $q_cond;
// test if object is class:
$iscls = $this->isClass($oid); if(PEAR::isError($iscls)) return $iscls;
if($iscls){
$q_from .= ", {$this->classTable} c";
$q_cond .= " AND c.id=p.obj AND c.id=$oid";
}else{
// object is normal node => path search => retrieve L/R values for oid:
$r1 = $this->dbc->getRow("SELECT lft, rgt, level FROM {$this->treeTable} WHERE id=$oid");
if(is_null($r1))
return PEAR::raiseError('Alib::checkPerm: object not exists', ALIBERR_NOTEXISTS, PEAR_ERROR_RETURN);
if(PEAR::isError($r1)) return($r1);
// fetch all path to oid + join with perms
$q_flds .= ", t.name, ({$r1['level']}-t.level)as T_lvl";
$q_from = "{$this->treeTable} t, ".$q_from;
$q_cond .= " AND t.id=p.obj AND t.lft<={$r1['lft']} AND t.rgt>={$r1['rgt']}";
$q_ordb = "ORDER BY T_lvl, S_lvl, action, p.type DESC"; // action ASC order is hack for lower priority of '_all'
}
$query="SELECT $q_flds FROM $q_from $q_join WHERE $q_cond $q_ordb";
$r2 = $this->dbc->getAll($query);
if(PEAR::isError($r2)) return($r2);
if(!$iscls && !(is_array($r2) && count($r2)>0)){
// no perm found, search in classes:
$q_from = "{$this->cmembTable} cm, ".$q_from;
$q_cond = $qc0.
" AND t.lft<={$r1['lft']} AND t.rgt>={$r1['rgt']}".
" AND cm.cid=p.obj AND cm.objid=t.id";
$query="SELECT $q_flds FROM $q_from $q_join WHERE $q_cond $q_ordb";
$r2 = $this->dbc->getAll($query);
if(PEAR::isError($r2)) return($r2);
}
// if there is row with type='A' on the top => permit
return (is_array($r2) && count($r2)>0 && $r2[0]['type']=='A');
}
/* --- object tree --- */
/**
* removeObj
*
* @param id int
* @return void/error
**/
function removeObj($id)
{
$r = $this->removePerm(NULL, NULL, $id); if(PEAR::isError($r)) return $r;
return parent::removeObj($id);
}
/* --- users/groups --- */
/**
* removeSubj
*
* @param login string
* @return void/error
**/
function removeSubj($login)
{
$uid = $this->getSubjId($login); if(PEAR::isError($uid)) return $uid;
$r = $this->removePerm(NULL, $uid); if(PEAR::isError($r)) return $r;
return parent::removeSubj($login, $uid);
}
/* --- sessions --- */
/**
* getSessLogin
*
* @param sessid string
* @return string/error
**/
function getSessLogin($sessid)
{
return $this->dbc->getOne("
SELECT login FROM {$this->sessTable} WHERE sessid='$sessid'");
}
/**
* getSessUserId
*
* @param sessid string
* @return int/error
**/
function getSessUserId($sessid)
{
return $this->dbc->getOne("
SELECT userid FROM {$this->sessTable} WHERE sessid='$sessid'");
}
/* --- info methods: --- */
/**
* getObjPerms
*
* @param id int
* @return array/null/err
**/
function getObjPerms($id)
{
return $this->dbc->getAll("
SELECT s.login, p.* FROM {$this->permTable} p, {$this->subjTable} s
WHERE s.id=p.subj AND p.obj=$id");
}
/**
* getSubjPerms
*
* @param sid int
* @return array
**/
function getSubjPerms($sid)
{
$a1 = $this->dbc->getAll("
SELECT t.name, t.type as otype , p.* FROM {$this->permTable} p, {$this->treeTable} t
WHERE t.id=p.obj AND p.subj=$sid");
if(PEAR::isError($a1)) return $a1;
$a2 = $this->dbc->getAll("
SELECT c.cname as name, 'C'as otype, p.* FROM {$this->permTable} p, {$this->classTable} c
WHERE c.id=p.obj AND p.subj=$sid");
if(PEAR::isError($a2)) return $a2;
return array_merge($a1, $a2);
}
/* --- info methods related to application structure: --- */
/* (this part should be added/rewritten to allow defining/modifying/using application structure) */
/* (only very simple structure definition - in config - supported now) */
/**
* getAllActions
*
* @return array
**/
function getAllActions()
{
return $this->config['allActions'];
}
/**
* getAllowedActions
*
* @param type string
* @return array
**/
function getAllowedActions($type)
{
return $this->config['allowedActions'][$type];
}
/* ========== test and debug methods: ========== */
/**
* dumpPerms
*
* @param indstr string // indentation string
* @param ind string // aktual indentation
* @return string
**/
function dumpPerms($indstr=' ', $ind='')
{
$r = $ind.join(', ', array_map(create_function('$v', 'return "{$v[\'action\']}/{$v[\'type\']}";'),
$this->dbc->getAll("SELECT action, type FROM {$this->permTable}")
))."\n";
return $r;
}
/**
* deleteData
*
* @return void
**/
function deleteData()
{
$this->dbc->query("DELETE FROM {$this->permTable}");
parent::deleteData();
}
/**
* testData
*
* @return array
**/
function testData()
{
parent::testData();
$t =& $this->tdata['tree'];
$c =& $this->tdata['classes'];
$s =& $this->tdata['subjects'];
$o[] = $this->addPerm($s[0], '_all', $t[0], 'A');
$o[] = $this->addPerm($s[1], '_all', $t[4], 'A');
$o[] = $this->addPerm($s[1], '_all', $t[7], 'D');
# $o[] = $this->addPerm($s[2], 'addChilds', $t[6], 'A');
$o[] = $this->addPerm($s[2], 'read', $t[5], 'A');
$o[] = $this->addPerm($s[2], 'edit', $t[6], 'A');
$o[] = $this->addPerm($s[3], 'read', $c[0], 'A');
$o[] = $this->addPerm($s[4], 'editPerms', $c[1], 'A');
$o[] = $this->addPerm($s[4], 'editPerms', $t[7], 'D');
$o[] = $this->addPerm($s[1], 'addChilds', $t[3], 'A');
$o[] = $this->addPerm($s[1], 'addChilds', $t[1], 'A');
$o[] = $this->addPerm($s[5], 'addChilds', $t[3], 'A');
$o[] = $this->addPerm($s[5], 'addChilds', $t[1], 'A');
$o[] = $this->addPerm($s[6], 'addChilds', $t[3], 'A');
$o[] = $this->addPerm($s[6], 'addChilds', $t[1], 'A');
$o[] = $this->addPerm($s[7], 'addChilds', $t[3], 'A');
$o[] = $this->addPerm($s[7], 'addChilds', $t[1], 'A');
$this->tdata['perms'] = $o;
}
/**
* test
*
* @return boolean/error
**/
function test()
{
if(PEAR::isError($p = parent::test())) return $p;
$this->deleteData();
$this->testData();
$this->test_correct = "_all/A, _all/A, _all/D, read/A, edit/A, read/A, editPerms/A, editPerms/D, addChilds/A, addChilds/A, addChilds/A, addChilds/A, addChilds/A, addChilds/A, addChilds/A, addChilds/A\nno, yes\n";
$this->test_dump = $this->dumpPerms().
($this->checkPerm($this->tdata['subjects'][1], 'edit', $this->tdata['tree'][7])? 'yes':'no').", ".
($this->checkPerm($this->tdata['subjects'][2], 'read', $this->tdata['tree'][5])? 'yes':'no')."\n"
;
$this->removePerm($this->tdata['perms'][1]);
$this->removePerm($this->tdata['perms'][3]);
$this->test_correct .= "_all/A, _all/D, edit/A, read/A, editPerms/A, editPerms/D, addChilds/A, addChilds/A, addChilds/A, addChilds/A, addChilds/A, addChilds/A, addChilds/A, addChilds/A\n";
$this->test_dump .= $this->dumpPerms();
$this->deleteData();
if($this->test_dump==$this->test_correct){ $this->test_log.="alib: OK\n"; return TRUE; }
else return PEAR::raiseError('Alib::test', 1, PEAR_ERROR_DIE, '%s'.
"<pre>\ncorrect:\n{$this->test_correct}\ndump:\n{$this->test_dump}\n</pre>\n");
}
/**
* install - create tables + initialize
*
* @return void
**/
function install()
{
parent::install();
$this->dbc->query("CREATE TABLE {$this->permTable} (
permid int not null,
subj int,
action varchar(20),
obj int,
type char(1)
)");
$this->dbc->query("CREATE UNIQUE INDEX {$this->permTable}_permid_idx on {$this->permTable} (permid)");
$this->dbc->query("CREATE INDEX {$this->permTable}_subj_obj_idx on {$this->permTable} (subj, obj)");
$this->dbc->createSequence("{$this->permTable}_id_seq");
$this->dbc->query("CREATE TABLE {$this->sessTable} (
sessid char(32) not null,
userid int,
login varchar(255),
ts timestamp
)");
$this->dbc->query("CREATE UNIQUE INDEX {$this->sessTable}_sessid_idx on {$this->sessTable} (sessid)");
$this->dbc->query("CREATE INDEX {$this->sessTable}_userid_idx on {$this->sessTable} (userid)");
$this->dbc->query("CREATE INDEX {$this->sessTable}_login_idx on {$this->sessTable} (login)");
}
/**
* uninstall
*
* @return void
**/
function uninstall()
{
$this->dbc->query("DROP TABLE {$this->permTable}");
$this->dbc->dropSequence("{$this->permTable}_id_seq");
$this->dbc->query("DROP TABLE {$this->sessTable}");
parent::uninstall();
}
}
?>

View File

@ -0,0 +1,265 @@
<?php
// $Id: class.php,v 1.1 2004/07/23 00:22:13 tomas Exp $
/**
* ObjClass class
*
* class for 'object classes' handling - i.e. groups of object in tree
* @parent Mtree
**/
require_once"mtree.php";
class ObjClasses extends Mtree{
var $classTable;
var $cmembTable;
/** ObjClasses - constructor
*
* @param dbc object
* @param config array
* @return this
**/
function ObjClasses(&$dbc, $config)
{
parent::MTree(&$dbc, $config);
$this->classTable = $config['tblNamePrefix'].'classes';
$this->cmembTable = $config['tblNamePrefix'].'cmemb';
}
/* ========== public methods: ========== */
/**
* addClass
*
* @param cname string
* @return id/error
**/
function addClass($cname)
{
$id = $this->dbc->nextId("{$this->treeTable}_id_seq"); if(PEAR::isError($id)) return $id;
$r = $this->dbc->query("
INSERT INTO {$this->classTable} (id, cname)
VALUES ($id, '$cname')
");
if(PEAR::isError($r)) return $r;
return $id;
}
/**
* removeClass
*
* @param cname string
* @return boolean/err
**/
function removeClass($cname)
{
$cid = $this->getClassId($cname); if(PEAR::isError($cid)) return($cid);
return $this->removeClassById($cid);
}
/**
* removeClassById
*
* @param cid int
* @return boolean/err
**/
function removeClassById($cid)
{
$r = $this->dbc->query("DELETE FROM {$this->cmembTable} WHERE cid=$cid");
if(PEAR::isError($r)) return $r;
$r = $this->dbc->query("DELETE FROM {$this->classTable} WHERE id=$cid");
if(PEAR::isError($r)) return $r;
return TRUE;
}
/**
* addObj2Class
*
* @param cid int
* @param oid int
* @return boolean/err
**/
function addObj2Class($cid, $oid)
{
$r = $this->dbc->query("INSERT INTO {$this->cmembTable} (cid, objid) VALUES ($cid, $oid)");
if(PEAR::isError($r)) return $r;
return TRUE;
}
/**
* removeObjFromClass
*
* @param oid int
* @param cid int OPT // if not specified, remove obj from all classes
* @return boolean/err
**/
function removeObjFromClass($oid, $cid=NULL)
{
$r = $this->dbc->query("DELETE FROM {$this->cmembTable} WHERE objid=$oid".(is_null($cid)? '':" AND cid=$cid"));
if(PEAR::isError($r)) return $r;
return TRUE;
}
/* --- object tree --- */
/**
* removeObj
*
* @param id int
* @return boolean/err
**/
function removeObj($id)
{
$r = $this->removeObjFromClass($id); if(PEAR::isError($r)) return $r;
return parent::removeObj($id);
}
/* --- info methods: --- */
/**
* getClassId
*
* @param cname string
* @return int/err
**/
function getClassId($cname)
{
return $this->dbc->getOne($query = "SELECT id FROM {$this->classTable} WHERE cname='$cname'");
}
/**
* getClassName
*
* @param id int
* @return string/err
**/
function getClassName($id)
{
return $this->dbc->getOne($query = "SELECT cname FROM {$this->classTable} WHERE id=$id");
}
/**
* isClass
*
* @param id int
* @return boolean/err
**/
function isClass($id)
{
$r = $this->dbc->getOne("SELECT count(*) FROM {$this->classTable} WHERE id=$id");
if(PEAR::isError($r)) return $r;
return ($r > 0);
}
/**
* getClasses
*
* @return array/err
**/
function getClasses()
{
return $this->dbc->getAll("SELECT * FROM {$this->classTable}");
}
/**
* listClass
*
* @param id int
* @return array/err
**/
function listClass($id)
{
return $this->dbc->getAll("SELECT t.* FROM {$this->cmembTable} cm, {$this->treeTable} t
WHERE cm.cid=$id AND cm.objid=t.id");
}
/* ========== test and debug methods: ========== */
/**
* dumpClasses
*
* @param id int
* @param indstr string // indentation string
* @param ind string // aktual indentation
* @return string
**/
function dumpClasses($indstr=' ', $ind='')
{
$r = $ind.join(', ', array_map(create_function('$v', 'return "{$v[\'cname\']} ({$v[\'cnt\']})";'),
$this->dbc->getAll("
SELECT cname, count(cm.objid)as cnt FROM {$this->classTable} c
LEFT JOIN {$this->cmembTable} cm ON c.id=cm.cid
GROUP BY cname, c.id ORDER BY c.id
")
))."\n";
return $r;
}
/**
* testData
*
**/
function deleteData()
{
$this->dbc->query("DELETE FROM {$this->cmembTable}");
$this->dbc->query("DELETE FROM {$this->classTable}");
parent::deleteData();
}
function testData()
{
parent::testData();
$o[] = $this->addClass('Sections b');
$o[] = $this->addClass('Class 2');
$this->addObj2Class($o[1], $this->tdata['tree'][4]);
$this->addObj2Class($o[1], $this->tdata['tree'][9]);
$this->tdata['classes'] = $o;
}
/**
* test
*
**/
function test()
{
if(PEAR::isError($p = parent::test())) return $p;
$this->deleteData();
$this->testData();
$this->test_correct = "Sections b (0), Class 2 (2)\n";
$this->test_dump = $this->dumpClasses();
$this->removeClass('Sections b');
$this->removeObjFromClass($this->tdata['tree'][4], $this->tdata['classes'][1]);
$this->test_correct .= "Class 2 (1)\n";
$this->test_dump .= $this->dumpClasses();
$this->deleteData();
if($this->test_dump==$this->test_correct){ $this->test_log.="class: OK\n"; return TRUE; }
else return PEAR::raiseError('ObjClasses::test:', 1, PEAR_ERROR_DIE, '%s'.
"<pre>\ncorrect:\n{$this->test_correct}\ndump:\n{$this->test_dump}\n</pre>\n");
}
/**
* install - create tables + initialize
*
**/
function install()
{
parent::install();
$this->dbc->query("CREATE TABLE {$this->classTable} (
id int not null,
cname varchar(20)
)");
$this->dbc->query("CREATE UNIQUE INDEX {$this->classTable}_id_idx on {$this->classTable} (id)");
$this->dbc->query("CREATE UNIQUE INDEX {$this->classTable}_cname_idx on {$this->classTable} (cname)");
$this->dbc->query("CREATE TABLE {$this->cmembTable} (
objid int not null,
cid int not null
)");
$this->dbc->query("CREATE UNIQUE INDEX {$this->cmembTable}_idx on {$this->cmembTable} (objid, cid)");
}
function uninstall()
{
$this->dbc->query("DROP TABLE {$this->classTable}");
$this->dbc->query("DROP TABLE {$this->cmembTable}");
parent::uninstall();
}
}
?>

View File

@ -0,0 +1,126 @@
<?php
// $Id: alibExCls.php,v 1.1 2004/07/23 00:22:13 tomas Exp $
require_once"alib_h.php";
require_once"alibExTestAuth.php";
if(isset($_GET['id']) && is_numeric($_GET['id'])){ $id = $_GET['id']; $list=false; }
else $list=true;
// prefill data structure for template
if($list){
$d = array(
'cls' => $alib->getClasses(),
'loggedAs' => $login,
);
}else{
$d = array(
'rows' => $alib->listClass($id),
'id' => $id,
'loggedAs' => $login,
'cname' => $alib->getClassName($id),
'cls' => $alib->getClasses(),
'objs' => $alib->getSubTree(null, true)
);
}
$d['msg'] = $_SESSION['alertMsg']; unset($_SESSION['alertMsg']);
require_once"alib_f.php";
// template follows:
?>
<html><head>
<title>Alib - class editor</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="default.css">
<style type="text/css">
<!--
#menu { float:right; margin-right:1em; border:1px solid black; background-color:#ddd; padding:2px 1ex; }
#parent, #parent a { background-color:#888; font-weight:bold; color:white; }
#tree { width:60%; }
-->
</style>
</head><body>
<div id="menu">
Logged as: <span class="b"><?php echo$d['loggedAs']?></span><br>
<a href="alibHttp.php?act=logout">logout</a><br>
<a href="alibExTree.php">Tree editor</a><br>
<?php if(!$list){?>
<a href="alibExPerms.php?id=<?php echo$d['id']?>">Perm editor</a><br>
<?php }?>
<a href="alibExSubj.php">User/Group editor</a><br>
</div>
<h1>Class editor</h1>
<?php if($list){?>
<h3>All classes:</h3>
<table id="tree" border="0" cellpadding="5">
<?php if(is_array($d['cls'])&&count($d['cls'])>0) foreach($d['cls'] as $k=>$c) {?>
<tr class="<?php echo(($o=1-$o) ? 'odd' : 'ev')?>">
<td><?php echo$c['id']?></td>
<td class="b"><a href="alibExCls.php?id=<?php echo$c['id']?>"><?php echo$c['cname']?></a></td>
<?php # <td><?php echo$c['cond']? ></td>?>
<td>
<a class="lnkbutt" href="alibHttp.php?act=removeClass&id=<?php echo$c['id']?>">delete</a>
<a class="lnkbutt" href="alibExPerms.php?id=<?php echo$c['id']?>&reid=<?php echo$d['id']?>">permissions</a>
</td>
</tr>
<?php }else{?>
<tr class="odd"><td colspan="3">none</td></tr>
<?php }?>
</table>
<form action="alibHttp.php" method="post">
Add class with name
<input type="text" name="name" value="" size="10">
<input type="hidden" name="act" value="addClass">
<input type="submit" value="Do it!">
</form>
<?php }else{?>
<h2>Objects in class <?php echo$d['cname']?>:</h2>
<table id="tree" border="0" cellpadding="5">
<tr id="parent">
<td colspan="4">
<a href="alibExCls.php">All classes</a>
</td>
</tr>
<?php if(is_array($d['rows'])&&count($d['rows'])>0) foreach($d['rows'] as $k=>$row) {?>
<tr class="<?php echo(($o=1-$o) ? 'odd' : 'ev')?>">
<td><?php echo$row['id']?></td>
<td class="b"><a href="alibExTree.php?id=<?php echo$row['id']?>"><?php echo$row['name']?></a></td>
<td><?php echo$row['type']?></td>
<td>
<a class="lnkbutt" href="alibHttp.php?act=removeObjFromClass&oid=<?php echo$row['id']?>&id=<?php echo$d['id']?>">removeFromClass</a>
<?php /*?> <a class="lnkbutt" href="alibExPerms.php?id=<?php echo$row['id']?>&reid=<?php echo$d['id']?>">permissions</a><?php */?>
</td>
</tr>
<?php }else{?>
<tr class="odd"><td colspan="4">none</td></tr>
<?php }?>
</table>
<form action="alibHttp.php" method="post">
Add object
<select name="oid">
<?php if(is_array($d['objs'])) foreach($d['objs'] as $k=>$row) {?>
<option value="<?php echo$row['id']?>"><?php echo str_repeat('&nbsp;', $row['level'])?><?php echo$row['name']?></option>
<?php }?>
</select>
to class <?php echo$d['cname']?>
<input type="hidden" name="act" value="addObj2Class">
<input type="hidden" name="id" value="<?php echo$d['id']?>">
<input type="submit" value="Do it!">
</form>
<?php }?>
<?php if($d['msg']){?>
<script type="text/javascript">
<!--
alert('<?php echo$d['msg']?>');
-->
</script>
<?php }?>
</body></html>

View File

@ -0,0 +1,112 @@
<?php
// $Id: alibExLogin.php,v 1.1 2004/07/23 00:22:13 tomas Exp $
require_once"alib_h.php";
// prefill data structure for template
$d = array(
'users' => $alib->getSubjects(),
'actions' => $alib->getAllActions(),
'objects' => $alib->getAllObjects(),
'msg' => $_SESSION['alertMsg']
);
unset($_SESSION['alertMsg']);
// forms prefill:
if(is_array($_SESSION['lastPost'])) $d = array_merge($d, array(
'lastSubj' => $_SESSION['lastPost']['subj'],
'lastAction'=> $_SESSION['lastPost']['permAction'],
'lastObj' => $_SESSION['lastPost']['obj']
));
unset($_SESSION['lastPost']);
#header("Content-type: text/plain"); print_r($d); exit;
require_once"alib_f.php";
// template follows:
?>
<html><head>
<title>Alib - example login</title>
<link rel="stylesheet" type="text/css" href="default.css">
<style type="text/css">
<!--
#help { float:right; margin-right:1em; border:1px solid black; background-color:#ddd; padding:2px 1ex; }
-->
</style>
<script type="text/javascript">
<!--
function preloadLogin(u, p)
{
var f=document.getElementById('loginform');
f.login.value=u;
f.pass.value=p;
}
-->
</script>
</head><body>
<div id="help">
Test accounts/pass:
<ul style="margin:1px 0px">
<li><a href="javascript:preloadLogin('root', 'q')">root/q</a></li>
<li><a href="javascript:preloadLogin('test1', 'a')">test1/a</a></li>
<li><a href="javascript:preloadLogin('test2', 'a')">test2/a</a></li>
<li><a href="javascript:preloadLogin('test3', 'a')">test3/a</a></li>
<li><a href="javascript:preloadLogin('test4', 'a')">test4/a</a></li>
</ul>
</div>
<h1>ALib - tests/example</h1>
<form action="alibHttp.php" method="post" id="loginform">
<table>
<tr><td>Login:</td><td><input type="text" name="login"></td></tr>
<tr><td>Password:</td><td><input type="password" name="pass"></td></tr>
<tr><td colspan="2"><input type="hidden" name="act" value="login">
<input type="submit" value="Go!">
</td></tr>
</table>
</form>
<hr>
<form action="alibHttp.php" method="post">
Permission test:<br>
Subject: <select name="subj">
<?php if(is_array($d['users'])) foreach($d['users'] as $k=>$u) {?>
<option value="<?php echo$u['id']?>"<?php echo($d['lastSubj']==$u['id'] ? ' selected':'')?>><?php echo$u['login']?></option>
<?php }?>
</select>
action: <select name="permAction">
<?php if(is_array($d['actions'])) foreach($d['actions'] as $k=>$a) {?>
<option value="<?php echo$a?>"<?php echo($d['lastAction']==$a ? ' selected':'')?>><?php echo$a?></option>
<?php }?>
</select>
object: <select name="obj">
<?php if(is_array($d['objects'])) foreach($d['objects'] as $k=>$o) {?>
<option value="<?php echo$o['id']?>"<?php echo($d['lastObj']==$o['id'] ? ' selected':'')?>><?php echo$o['name']?></option>
<?php }?>
</select>
<input type="hidden" name="act" value="checkPerm">
<input type="submit" value="Go!">
</form>
<hr>
<form action="alibExPMatrix.php" method="get">
Permission matrix for subject: <select name="subj">
<?php if(is_array($d['users'])) foreach($d['users'] as $k=>$u) {?>
<option value="<?php echo$u['id']?>"<?php echo($d['lastSubj']==$u['id'] ? ' selected':'')?>><?php echo$u['login']?></option>
<?php }?>
</select>
<input type="submit" value="Go!">
</form>
<hr>
<a href="../install.php?ak=inst">reset db + test all</a><br/>
<?php if($d['msg']){ //error message printing: ?>
<script type="text/javascript">
<!--
alert('<?php echo$d['msg']?>');
-->
</script>
<?php }?>
<body></html>

View File

@ -0,0 +1,75 @@
<?php
// $Id: alibExPList.php,v 1.1 2004/07/23 00:22:13 tomas Exp $
require_once"alib_h.php";
require_once"alibExTestAuth.php";
if(isset($_GET['id']) && is_numeric($_GET['id'])){ $id = $_GET['id']; }
else $id=1;
// prefill data structure for template
$d = array(
'rows' => $alib->getSubjPerms($id),
'id' => $id,
'loggedAs' => $login,
'actions' => $alib->getAllActions(),
'name' => $alib->getSubjName($id)
);
$d['msg'] = $_SESSION['alertMsg']; unset($_SESSION['alertMsg']);
require_once"alib_f.php";
// template follows:
?>
<html><head>
<title>Alib - permission list</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="default.css">
<style type="text/css">
<!--
#menu { float:right; margin-right:1em; border:1px solid black; background-color:#ddd; padding:2px 1ex; }
#parent, #parent a { background-color:#888; font-weight:bold; color:white; }
#tree { width:60%; }
-->
</style>
</head><body>
<div id="menu">
Logged as: <span class="b"><?php echo$d['loggedAs']?></span><br>
<a href="alibHttp.php?act=logout">logout</a><br>
<a href="alibExTree.php">Tree editor</a><br>
<a href="alibExCls.php">Class editor</a><br>
<a href="alibExSubj.php">User/group editor</a><br>
</div>
<h1>Subject permission list</h1>
<h2>Permissions for subject <?php echo$d['name']?>:</h2>
<table id="tree" border="0" cellpadding="5">
<tr id="parent">
<td colspan="4">
<a href="alibExSubj.php">All subjects</a>
</td>
</tr>
<?php if(is_array($d['rows'])&&count($d['rows'])>0) foreach($d['rows'] as $k=>$row) {?>
<tr class="<?php echo(($o=1-$o) ? 'odd' : 'ev')?>">
<td><a class="b" href="alibExPerms.php?id=<?php echo$row['obj']?>"><?php echo$row['name']?></a>
(<?php echo($row['otype']=='C' ? 'class' : $row['otype'])?>)
</td
<td class="b"><?php echo$row['action']?></td>
<td><?php echo($row['type']=='A' ? 'allow' : ($row['type']=='D' ? '<b>deny</b>' : $row['type']))?></td>
<td>
<a class="lnkbutt" href="alibHttp.php?act=removePerm&permid=<?php echo$row['permid']?>&oid=<?php echo$row['obj']?>&reurl=plist&reid=<?php echo$d['id']?>">delete</a>
</td>
</tr>
<?php }else{?>
<tr class="odd"><td colspan="4">none</td></tr>
<?php }?>
</table>
<?php if($d['msg']){?>
<script type="text/javascript">
<!--
alert('<?php echo$d['msg']?>');
-->
</script>
<?php }?>
</body></html>

View File

@ -0,0 +1,44 @@
<?php
// $Id: alibExPMatrix.php,v 1.1 2004/07/23 00:22:13 tomas Exp $
require_once"alib_h.php";
$sid=$_GET['subj'];
foreach($alib->getAllObjects() as $it){
$aa=array();
foreach($alib->getAllActions() as $a){
$aa[$a]=$alib->checkPerm($sid, $a, $it['id']);
# if(PEAR::isError($aa[$a])){ errCallback($aa[$a]); }
}
$m[]=array($it['name'], $aa);
}
$u=$alib->getSubjName($sid);
?>
<html><head>
<title>ALib - permission matrix</title>
<link rel="stylesheet" type="text/css" href="default.css">
</head><body>
<h2>Permission matrix</h2>
<h2>User: <?php echo$u?></h2>
<table style="border:1px solid black">
<tr class="ev"><th>object</th>
<?php foreach($alib->getAllActions() as $a){?>
<th><?php echo$a?></th>
<?php }?>
</tr>
<?php if(is_array($m)) foreach($m as $k=>$v){ list($obj, $aa)=$v;?>
<tr class="<?php echo(($o=1-$o) ? 'odd' : 'ev')?>">
<td><?php echo$obj?></td>
<?php foreach($aa as $pr){?>
<td><?php echo($pr ? 'Y' : '-')?></td>
<?php }?>
</tr>
<?php }?>
</table>
<a href="javascript:back()">Back</a>
<hr>
Tree dump:
<pre><?php echo$alib->dumpTree()?></pre>
</body></html>

View File

@ -0,0 +1,118 @@
<?php
// $Id: alibExPerms.php,v 1.1 2004/07/23 00:22:13 tomas Exp $
require_once"alib_h.php";
require_once"alibExTestAuth.php";
if(isset($_GET['id']) && is_numeric($_GET['id'])){
$id = $_GET['id'];
}else{
$id = $alib->getRootNode();
}
// prefill data structure for template
if(!$alib->isClass($id)){
$d = array(
'path' => $alib->getPath($id, 'id,name'),
'perms' => $alib->getObjPerms($id),
'actions' => $alib->getAllowedActions($alib->getObjType($id)),
'subjects' => $alib->getSubjects(),
'id' => $id,
'loggedAs' => $login
);
}else{
$d = array(
'path' => '',
'name' => $alib->getClassName($id),
'perms' => $alib->getObjPerms($id),
'actions' => $alib->getAllowedActions('_class'),
'subjects' => $alib->getSubjects(),
'id' => $id,
'loggedAs' => $login
);
}
$d['msg'] = $_SESSION['alertMsg']; unset($_SESSION['alertMsg']);
require_once"alib_f.php";
// template follows:
?>
<html><head>
<title>Alib - permission editor</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="default.css">
<style type="text/css">
<!--
#menu { float:right; margin-right:1em; border:1px solid black; background-color:#ddd; padding:2px 1ex; }
#tbl { width:60%; }
-->
</style>
</head><body>
<div id="menu">
Logged as: <span class="b"><?php echo$d['loggedAs']?></span><br>
<a href="alibHttp.php?act=logout">Logout</a><br>
<?php if(is_array($d['path'])){?>
<a href="alibExTree.php?id=<?php echo$d['id']?>">Tree editor</a><br>
<?php }else{?>
<a href="alibExTree.php">Tree editor</a><br>
<?php }?>
<a href="alibExCls.php">Class editor</a><br>
<a href="alibExSubj.php">User/Group editor</a><br>
</div>
<h1>Permission editor</h1>
<?php if(is_array($d['path'])){?>
<h2><a href="alibExTree.php?id=<?php echo$d['id']?>" title="Tree editor">Path</a>:
<?php foreach($d['path'] as $k=>$it) {?>
<a <?php if($it["id"]!=$id){?>href="?id=<?php echo $it["id"]?>"<?php }?>><?php echo$it["name"]?></a><span class="slash">/</span>
<?php }?>
<?php }else{?>Class <a href="alibExCls.php?id=<?php echo$d['id']?>"><?php echo$d['name']?></a>
<?php }?>
</h2>
<table id="tbl" border="0" cellpadding="5">
<?php if(is_array($d['perms'])&&count($d['perms'])>0) foreach($d['perms'] as $k=>$row) {?>
<tr class="<?php echo(($o=1-$o) ? 'odd' : 'ev')?>">
<td class="b"><a href="alibExPList.php?id=<?php echo$row['subj']?>"><?php echo$row['login']?></a></td>
<td class="b"><?php echo$row['action']?></td>
<td><?php echo($row['type']=='A' ? 'allow' : ($row['type']=='D' ? '<b>deny</b>' : $row['type']))?></td>
<td>
<a class="lnkbutt" href="alibHttp.php?act=removePerm&permid=<?php echo$row['permid']?>&oid=<?php echo$d['id']?>&reid=<?php echo$d['id']?>">delete</a>
</td>
</tr>
<?php }else{?>
<tr class="odd"><td colspan="4">none</td></tr>
<?php }?>
</table>
<form action="alibHttp.php" method="post">
Add permission
<select name="allowDeny">
<option value="A">Allow</option>
<option value="D">Deny</option>
</select>
for action
<select name="permAction">
<option value="_all">all</option>
<?php if(is_array($d['actions'])) foreach($d['actions'] as $k=>$it) {?>
<option value="<?php echo$it?>"><?php echo$it?></option>
<?php }?>
</select>
to subject
<select name="subj">
<?php if(is_array($d['subjects'])) foreach($d['subjects'] as $k=>$it) {?>
<option value="<?php echo$it['id']?>"><?php echo$it['login']?></option>
<?php }?>
</select>
<input type="hidden" name="act" value="addPerm">
<input type="hidden" name="reid" value="<?php echo$d['id']?>">
<input type="hidden" name="id" value="<?php echo$d['id']?>">
<input type="submit" value="Do it!">
</form>
<?php if($d['msg']){?>
<script type="text/javascript">
<!--
alert('<?php echo$d['msg']?>');
-->
</script><noscript><hr><b><?php echo$d['msg']?></b></hr></noscript>
<?php }?>
</body></html>

View File

@ -0,0 +1,141 @@
<?php
// $Id: alibExSubj.php,v 1.1 2004/07/23 00:22:13 tomas Exp $
require_once"alib_h.php";
require_once"alibExTestAuth.php";
if(isset($_GET['id']) && is_numeric($_GET['id'])){ $id = $_GET['id']; $list=false; }
else $list=true;
// prefill data structure for template
if($list){
$d = array(
'subj' => $alib->getSubjectsWCnt(),
'loggedAs' => $login
);
}else{
$d = array(
'rows' => $alib->listGroup($id),
'id' => $id,
'loggedAs' => $login,
'gname' => $alib->getSubjName($id),
'subj' => $alib->getSubjects()
);
}
$d['msg'] = $_SESSION['alertMsg']; unset($_SESSION['alertMsg']);
require_once"alib_f.php";
// template follows:
?>
<html><head>
<title>Alib - subjects editor</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="default.css">
<style type="text/css">
<!--
#menu { float:right; margin-right:1em; border:1px solid black; background-color:#ddd; padding:2px 1ex; }
#parent, #parent a { background-color:#888; font-weight:bold; color:white; }
#tree { width:60%; }
-->
</style>
</head><body>
<div id="menu">
Logged as: <span class="b"><?php echo$d['loggedAs']?></span><br>
<a href="alibHttp.php?act=logout">logout</a><br>
<a href="alibExTree.php">Tree editor</a><br>
<?php if(!$list){?>
<a href="alibExPList.php?id=<?php echo$d['id']?>">Perms editor</a><br>
<?php }?>
<a href="alibExCls.php">Class editor</a><br>
</div>
<h1>User/Group editor</h1>
<?php if($list){?>
<h3>Subjects:</h3>
<table id="tree" border="0" cellpadding="5">
<?php if(is_array($d['subj'])&&count($d['subj'])>0) foreach($d['subj'] as $k=>$c) {?>
<tr class="<?php echo(($o=1-$o) ? 'odd':'ev')?>">
<td><?php echo$c['id']?></td>
<td class="b">
<?php if($c['type']=='G'){?>
<a href="alibExSubj.php?id=<?php echo$c['id']?>"><?php echo$c['login']?></a>
<?php }else{?><?php echo$c['login']?>
<?php }?>
</td
<td><?php if($c['type']=='G'){?>(G:<?php echo$c['cnt']?>)<?php }else{?> (U)<?php }?></td>
<td>
<a class="lnkbutt" href="alibHttp.php?act=removeSubj&login=<?php echo urlencode($c['login'])?>">delete</a>
<?php /*?> <a class="lnkbutt" href="alibExPerms.php?id=<?php echo$c['id']?>&reid=<?php echo$d['id']?>">permissions</a><?php */?>
<a class="lnkbutt" href="alibExPMatrix.php?subj=<?php echo$c['id']?>">permsMatrix</a>
<a class="lnkbutt" href="alibExPList.php?id=<?php echo$c['id']?>">permsList</a>
</td>
</tr>
<?php }else{?>
<tr class="odd"><td colspan="4">none</td></tr>
<?php }?>
</table>
<form action="alibHttp.php" method="post">
Add subject with name: <input type="text" name="login" value="" size="10">
[and password: <input type="password" name="pass" value="" size="10">]
<input type="hidden" name="act" value="addSubj">
<input type="submit" value="Do it!">
</form>
<?php }else{?>
<h2>Subjects in group <?php echo$d['gname']?>:</h2>
<table id="tree" border="0" cellpadding="5">
<tr id="parent">
<td colspan="5">
<a href="alibExSubj.php">All subjects</a>
</td>
</tr>
<?php if(is_array($d['rows'])&&count($d['rows'])>0) foreach($d['rows'] as $k=>$row) {?>
<tr class="<?php echo(($o=1-$o) ? 'odd':'ev')?>">
<td><?php echo$row['id']?></td>
<td class="b">
<?php if($row['type']=='G'){?>
<a href="alibExSubj.php?id=<?php echo$row['id']?>"><?php echo$row['login']?></a>
<?php }else{?><?php echo$row['login']?>
<?php }?>
</td
<td><?php if($row['type']=='G'){?> (G)<?php }else{?> (U)<?php }?></td>
<td>
<a class="lnkbutt"
href="alibHttp.php?act=removeSubjFromGr&login=<?php echo urlencode($row['login'])?>&gname=<?php echo urlencode($d['gname'])?>&reid=<?php echo$d['id']?>">
removeFromGroup
</a>
<?php /*?> <a class="lnkbutt" href="alibExPerms.php?id=<?php echo$row['id']?>&reid=<?php echo$d['id']?>">permissions</a><?php */?>
</td>
</tr>
<?php }else{?>
<tr class="odd"><td colspan="3">none</td></tr>
<?php }?>
</table>
<form action="alibHttp.php" method="post">
Add subject
<select name="login">
<?php if(is_array($d['subj'])) foreach($d['subj'] as $k=>$row) {?>
<option value="<?php echo$row['login']?>"><?php echo$row['login']?></option>
<?php }?>
</select>
to group <?php echo$d['gname']?>
<input type="hidden" name="act" value="addSubj2Gr">
<input type="hidden" name="reid" value="<?php echo$d['id']?>">
<input type="hidden" name="gname" value="<?php echo$d['gname']?>">
<input type="submit" value="Do it!">
</form>
<?php }?>
<?php if($d['msg']){?>
<script type="text/javascript">
<!--
alert('<?php echo$d['msg']?>');
-->
</script>
<?php }?>
</body></html>

View File

@ -0,0 +1,9 @@
<?php
// $Id: alibExTestAuth.php,v 1.1 2004/07/23 00:22:13 tomas Exp $
$login = $alib->getSessLogin($_REQUEST['alibsid']);
if(!isset($login)||$login==''){
$_SESSION['alertMsg'] = "Login required";
header("Location: alibExLogin.php");
exit;
}
?>

View File

@ -0,0 +1,111 @@
<?php
// $Id: alibExTree.php,v 1.1 2004/07/23 00:22:13 tomas Exp $
require_once"alib_h.php";
require_once"alibExTestAuth.php";
if(isset($_GET['id']) && is_numeric($_GET['id'])) $id = $_GET['id'];
else $id = $alib->getRootNode();
// prefill data structure for template
$d = array(
'parid' => $alib->getParent($id),
'oname' => $alib->getObjName($id),
'path' => $alib->getPath($id, 'id, name'),
'rows' => $alib->getDir($id, 'id, name, type'),
'addtypes' => $alib->getAllowedChildTypes($alib->getObjType($id)),
'dump' => $alib->dumpTree($id),
'id' => $id,
'loggedAs' => $login
);
$d['msg'] = $_SESSION['alertMsg']; unset($_SESSION['alertMsg']);
require_once"alib_f.php";
// template follows:
?>
<html><head>
<title>Alib - tree editor</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="default.css">
<style type="text/css">
<!--
#menu { float:right; margin-right:1em; border:1px solid black; background-color:#ddd; padding:2px 1ex; }
#current { background-color:#aaa; }
#parent, #parent a { background-color:#888; font-weight:bold; color:white; }
#tree { width:60%; }
-->
</style>
</head><body>
<div id="menu">
Logged as: <span class="b"><?php echo$d['loggedAs']?></span><br>
<a href="alibHttp.php?act=logout">logout</a><br>
<?php /*?> <a href="alibExPerms.php?id=<?php echo$d['id']?>">Permission editor</a><br><?php */?>
<a href="alibExCls.php">Class editor</a><br>
<a href="alibExSubj.php">User/Group editor</a><br>
</div>
<h1>Tree editor</h1>
<h3>Path:
<?php if(is_array($d['path'])) foreach($d['path'] as $k=>$it) {?>
<a <?php if($it["id"]!=$id){?>href="alibExTree.php?id=<?php echo $it["id"]?>"<?php }?>><?php echo$it["name"]?></a><span class="slash">/</span><?php }?>
</h3>
<table id="tree" border="0" cellpadding="5">
<tr id="current">
<td colspan="2">Current node: <b><?php echo $d['oname']?></b></dt>
<td>
<a class="lnkbutt" href="alibExPerms.php?id=<?php echo$d['id']?>&reid=<?php echo$d['id']?>">permissions</a>
</td>
</tr>
<tr id="parent">
<td colspan="3">
<?php if(is_numeric($d['parid'])){?><a href="alibExTree.php?id=<?php echo$d['parid']?>">Parent: ..</a>
<?php }else{?>/<?php }?>
</dt>
</tr>
<?php if(is_array($d['rows'])&&count($d['rows'])>0) foreach($d['rows'] as $k=>$row) {?>
<tr class="<?php echo(($o=1-$o) ? 'odd' : 'ev')?>">
<td><?php echo$row['id']?></td>
<td><a href="alibExTree.php?id=<?php echo$row['id']?>" class="b"><?php echo$row['name']?></a> (<?php echo$row['type']?>)</td>
<td>
<a class="lnkbutt" href="alibHttp.php?act=deleteNode&id=<?php echo$row['id']?>&reid=<?php echo$d['id']?>">delete</a>
<a class="lnkbutt" href="alibExPerms.php?id=<?php echo$row['id']?>&reid=<?php echo$d['id']?>">permissions</a>
</td>
</tr>
<?php }else{?>
<tr class="odd"><td colspan="3">none</td></tr>
<?php }?>
</table>
<form action="alibHttp.php" method="post">
Add object of type
<select name="type">
<?php if(is_array($d['addtypes'])) foreach($d['addtypes'] as $k=>$row) {?>
<option value="<?php echo$row?>"><?php echo$row?></option>
<?php }?>
</select>
with name
<input type="text" name="name" value="" size="10">
<select name="position">
<option value="<?php echo$d['id']?>">as first node</option>
<?php if(is_array($d['rows'])) foreach($d['rows'] as $k=>$row) {?>
<option value="<?php echo$row['id']?>">after <?php echo$row['name']?></option>
<?php }?>
<option value="<?php echo$row['id']?>" selected>as last node</option>
</select>
<input type="hidden" name="act" value="addNode">
<input type="hidden" name="id" value="<?php echo$d['id']?>">
<input type="hidden" name="reid" value="<?php echo$d['id']?>">
<input type="submit" value="Do it!">
</form>
<pre><b>Subtree dump:</b><br><?php echo$d['dump']?></pre>
<?php #php echo"pre">; print_r($d); echo"</pre>";?>
<?php if($d['msg']){?>
<script type="text/javascript">
<!--
alert('<?php echo$d['msg']?>');
-->
</script>
<?php }?>
</body></html>

View File

@ -0,0 +1,125 @@
<?php
// $Id: alibHttp.php,v 1.1 2004/07/23 00:22:13 tomas Exp $
require_once"alib_h.php";
#header("Content-type: text/plain"); echo"GET:\n"; print_r($_GET); echo"POST:\n"; print_r($_POST); exit;
function getPGval($vn, $dfl='')
{
return (isset($_POST[$vn])?$_POST[$vn]:(isset($_GET[$vn])?$_GET[$vn]:$dfl));
}
$userid = $alib->getSessUserId($_REQUEST['alibsid']);
$login = $alib->getSessLogin($_REQUEST['alibsid']);
$redirUrl="alibExTree.php".(($reid=getPGval('reid', '')) ? "?id=$reid":"");
$act = getPGval('act', 'nop');
switch($act)
{
case"login";
if($sessid = $alib->login($_POST['login'], $_POST['pass'])){
setcookie('alibsid', $sessid);
$redirUrl="alibExTree.php";
}else{ $redirUrl="alibExLogin.php"; $_SESSION['alertMsg']='Login failed.'; }
break;
case"logout";
$r = $alib->logout($_REQUEST['alibsid']);
if(PEAR::isError($r)) $_SESSION['alertMsg'] = $r->getMessage().", ".$r->getUserInfo();
setcookie('alibsid', '');
$redirUrl="alibExLogin.php";
break;
case"addNode";
if($alib->checkPerm($userid, 'addChilds', $_POST['id'])
&& $_POST['type']!=''
&& $_POST['name']!=''
){
$oid = $alib->addObj($_POST['name'], $_POST['type'], $_POST['id'], $_POST['position']);
$alib->addPerm($userid, '_all', $oid);
}else $_SESSION['alertMsg']='Access denied.';
break;
case"deleteNode";
if($alib->checkPerm($userid, 'delete', $_REQUEST['id']))
$alib->removeObj($_GET['id']);
else $_SESSION['alertMsg']='Access denied.';
break;
case"addPerm";
$a = $alib->isClass($_POST['id']) ? 'classes':'editPerms';
$id = $alib->isClass($_POST['id']) ? '':$_POST['id'];
if($alib->checkPerm($userid, $a, $id))
$alib->addPerm($_POST['subj'], $_POST['permAction'], $_POST['id'], $_POST['allowDeny']);
else $_SESSION['alertMsg']='Access denied.';
$redirUrl="alibExPerms.php".(($reid=getPGval('reid', '')) ? "?id=$reid":"");
break;
case"removePerm";
$a = $alib->isClass($_REQUEST['oid']) ? 'classes':'editPerms';
$oid = $alib->isClass($_REQUEST['oid']) ? '':$_REQUEST['oid'];
if($alib->checkPerm($userid, $a, $oid))
$alib->removePerm($_GET['permid']);
else $_SESSION['alertMsg']='Access denied.';
$redirUrl=($_REQUEST['reurl']==plist ? "alibExPList.php":"alibExPerms.php").(($reid=getPGval('reid', '')) ? "?id=$reid":"");
break;
case"checkPerm";
$res = $alib->checkPerm($_POST['subj'], $_POST['permAction'], $_POST['obj']);
$_SESSION['alertMsg'] = ($res ? "permitted: ":"DENIED: ").
" {$_POST['permAction']} for ".$alib->getSubjName($_POST['subj']).
" on ".$alib->getObjName($_POST['obj']);
$_SESSION['lastPost']=$_POST;
$redirUrl="alibExLogin.php";
break;
case"addClass";
if($alib->checkPerm($userid, 'classes'))
$alib->addClass($_POST['name']);
else $_SESSION['alertMsg']='Access denied.';
$redirUrl="alibExCls.php";
break;
case"removeClass";
if($alib->checkPerm($userid, 'classes'))
$alib->removeClassById($_GET['id']);
else $_SESSION['alertMsg']='Access denied.';
$redirUrl="alibExCls.php";
break;
case"addSubj";
if($alib->checkPerm($userid, 'subjects'))
$alib->addSubj($_POST['login'], $_POST['pass']);
else $_SESSION['alertMsg']='Access denied.';
$redirUrl="alibExSubj.php";
break;
case"removeSubj";
if($alib->checkPerm($userid, 'subjects'))
$alib->removeSubj($_GET['login']);
else $_SESSION['alertMsg']='Access denied.';
$redirUrl="alibExSubj.php";
break;
case"addSubj2Gr";
if($alib->checkPerm($userid, 'subjects'))
$alib->addSubj2Gr($_POST['login'], $_POST['gname']);
else $_SESSION['alertMsg']='Access denied.';
$redirUrl="alibExSubj.php".(($id=getPGval('reid', '')) ? "?id=$reid":"");
break;
case"removeSubjFromGr";
if($alib->checkPerm($userid, 'subjects'))
$alib->removeSubjFromGr($_GET['login'], $_GET['gname']);
else $_SESSION['alertMsg']='Access denied.';
$redirUrl="alibExSubj.php".(($id=getPGval('reid', '')) ? "?id=$reid":"");
break;
case"addObj2Class";
if($alib->checkPerm($userid, 'classes'))
$alib->addObj2Class($_POST['id'], $_POST['oid']);
else $_SESSION['alertMsg']='Access denied. X1';
$redirUrl="alibExCls.php".(($id=getPGval('id', '')) ? "?id=$id":"");
break;
case"removeObjFromClass";
$id=getPGval('id', '');
if($alib->checkPerm($userid, 'classes'))
$alib->removeObjFromClass($_GET['oid'], $id);
else $_SESSION['alertMsg']='Access denied.';
$redirUrl="alibExCls.php".($id ? "?id=$id":"");
break;
default:
$_SESSION['alertMsg']="Unknown method: $act";
}
require_once"alib_f.php";
header("Location: $redirUrl");
?>

View File

@ -0,0 +1,4 @@
<?
// $Id: alib_f.php,v 1.1 2004/07/23 00:22:13 tomas Exp $
$dbc->disconnect();
?>

View File

@ -0,0 +1,31 @@
<?
// $Id: alib_h.php,v 1.1 2004/07/23 00:22:13 tomas Exp $
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Pragma: no-cache");
session_start();
require_once 'conf.php';
require_once 'DB.php';
require_once '../alib.php';
#PEAR::setErrorHandling(PEAR_ERROR_RETURN);
#PEAR::setErrorHandling(PEAR_ERROR_PRINT, "%s<hr>\n");
#PEAR::setErrorHandling(PEAR_ERROR_TRIGGER, E_USER_WARNING);
PEAR::setErrorHandling(PEAR_ERROR_DIE);
PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, 'errCallback');
function errCallback($err)
{
if(assert_options(ASSERT_ACTIVE)==1) return;
echo "<pre>\n";
echo "request: "; print_r($_REQUEST);
echo "\ngm:\n".$err->getMessage()."\nui:\n".$err->getUserInfo()."\n";
echo "<hr>BackTrace:\n";
print_r($err->backtrace);
echo "</pre>\n";
exit;
}
$dbc = DB::connect($config['dsn'], TRUE);
$dbc->setFetchMode(DB_FETCHMODE_ASSOC);
$alib =& new Alib($dbc, $config);
?>

View File

@ -0,0 +1,32 @@
<?php
// $Id: conf.php,v 1.1 2004/07/23 00:22:13 tomas Exp $
$config = array(
'dsn' => array( // data source definition
'username' => 'tomash',
'password' => '',
'hostspec' => 'localhost',
'phptype' => 'pgsql',
'database' => 'mdlf'
),
'tblNamePrefix' => 'al_',
# 'tblNamePrefix' => 'gb_',
'RootNode' =>'RootNode',
'objtypes' => array(
'RootNode' => array('Publication'),
'Publication' => array('Issue'),
'Issue' => array('Title', 'Section'),
'Section' => array('Title', 'Image', 'Par')
),
'allowedActions'=> array(
'RootNode' => array('addChilds', 'editPerms', 'read', 'edit', 'delete', 'classes', 'subjects'),
'Publication' => array('addChilds', 'editPerms', 'read', 'edit', 'delete'),
'Issue' => array('addChilds', 'editPerms', 'read', 'edit', 'delete'),
'Section' => array('addChilds', 'editPerms', 'read', 'edit', 'delete'),
'Title' => array('editPerms', 'read', 'edit', 'delete'),
'Image' => array('editPerms', 'read', 'edit', 'delete'),
'Par' => array('editPerms', 'read', 'edit', 'delete'),
'_class' => array('addChilds', 'editPerms', 'read', 'edit', 'delete')
),
'allActions'=> array('editPerms', 'addChilds', 'read', 'edit', 'delete', 'classes', 'subjects')
);
?>

View File

@ -0,0 +1,15 @@
<!--
/* $Id: default.css,v 1.1 2004/07/23 00:22:13 tomas Exp $ */
body { font-family:'Arial CE', 'Helvetica CE', Arial, helvetica, sans-serif; background-color:#fff; }
h1 { border:0px solid black; margin-bottom:2px; font-size:x-large; }
h2 { border:0px solid black; margin-bottom:2px; margin-top:2px; font-size:large; }
h3 { border:0px solid black; margin-bottom:2px; margin-top:2px; font-size:medium; font-weight:bold; }
table { border-collapse:collapse; margin:1ex 0px; }
tr.odd { background-color:#ccc; }
tr.ev { background-color:#bbb; }
td { border:0px solid black; padding:2px 1em; }
pre { border:solid black; border-width:1px 0px; padding:1em 1px;}
.b { font-weight:bold; }
.slash { padding:0px 2px; font-weigt:bolder; }
.lnkbutt { padding:0px 4px; font-weigt:bolder; }
-->

View File

@ -0,0 +1,7 @@
<?php
// $Id: index.php,v 1.1 2004/07/23 00:22:13 tomas Exp $
header ("location: alibExLogin.php");
die;
?>

View File

@ -0,0 +1,7 @@
<?php
// $Id: index.php,v 1.1 2004/07/23 00:22:13 tomas Exp $
header ("location: install.php");
die;
?>

View File

@ -0,0 +1,65 @@
<?
// $Id: install.php,v 1.1 2004/07/23 00:22:13 tomas Exp $
require_once 'example/conf.php';
require_once 'DB.php';
require_once 'alib.php';
function errCallback($err)
{
if(assert_options(ASSERT_ACTIVE)==1) return;
echo "<pre>\n";
echo "request: "; print_r($_REQUEST);
echo "gm:\n".$err->getMessage()."\ndi:\n".$err->getDebugInfo()."\nui:\n".$err->getUserInfo()."\n</pre>\n";
exit;
}
PEAR::setErrorHandling(PEAR_ERROR_PRINT, "%s<hr>\n");
$dbc = DB::connect($config['dsn'], TRUE);
if(PEAR::isError($dbc)){
echo "Database connection problem.\n";
echo "Create database '{$config['dsn']['database']}' or change 'dsn' values in conf.php.\n";
exit;
}
$dbc->setFetchMode(DB_FETCHMODE_ASSOC);
$alib =& new Alib($dbc, $config);
?>
<html><head>
<title>ALib install</title>
</head><body>
<h3>Alib install</h3>
<pre>
<?
if($_REQUEST['ak']=='inst'){
$dbc->setErrorHandling(PEAR_ERROR_RETURN);
# $dbc->setErrorHandling(PEAR_ERROR_PRINT, "%s<hr>\n");
echo "Trying to uninstall all ...\n";
$alib->uninstall();
$dbc->setErrorHandling(PEAR_ERROR_PRINT, "%s<hr>\n");
# $dbc->setErrorHandling(PEAR_ERROR_CALLBACK, 'errCallback');
echo "Install ...\n";
$alib->install();
echo "Testing ...\n";
$alib->test();
$log = $alib->test_log;
echo "TESTS:\n$log\n---\n";
echo "Reinstall + testdata insert ...\n";
$alib->reinstall();
$alib->testData();
echo "TREE DUMP:\n";
echo $alib->dumpTree();
echo "\n<b>Alib is probably installed OK</b>\n\n\n";
}
$dbc->disconnect();
?>
</pre>
<a href="install.php?ak=inst">Install/reinstall !</a><br>
<br>
<a href="example/">Example</a><br>
<a href="xmlrpc/">XmlRpc test</a>
</body></html>

View File

@ -0,0 +1,521 @@
<?php
// $Id: mtree.php,v 1.1 2004/07/23 00:22:13 tomas Exp $
/**
* Mtree class
*
* class for tree hierarchy stored in db
*
* example config: example/conf.php
* example minimal config:
* $config = array(
* 'dsn' => array( // data source definition
* 'username' => DBUSER,
* 'password' => DBPASSWORD,
* 'hostspec' => 'localhost',
* 'phptype' => 'pgsql',
* 'database' => DBNAME
* ),
* 'tblNamePrefix' => 'al_',
* 'RootNode' =>'RootNode',
* );
* (mysql phptype is tested too, but psql is recommended)
**/
define('ALIBERR_MTREE', 10);
class Mtree{
var $dbc;
var $config;
var $treeTable;
var $rootNodeName;
/** Mtree - constructor
*
* @param dbc object
* @param config array
* @return this
**/
function Mtree(&$dbc, $config)
{
$this->dbc =& $dbc;
$this->config = $config;
$this->treeTable = $config['tblNamePrefix'].'tree';
$this->rootNodeName = $config['RootNode'];
}
/* ========== public methods: ========== */
/**
* addObj
*
* @param name string
* @param type string
* @param parid int OPT // parent id
* @param aftid int OPT // after id
* @param param string OPT
* @return int/err // new id of inserted object
**/
function addObj($name, $type, $parid=1, $aftid=NULL, $param='')
{
if($name=='' || $type=='') return PEAR::raiseError('Mtree::addObj: Wrong name or type', ALIBERR_MTREE);
$this->dbc->query("BEGIN");
$r = $this->dbc->query("LOCK TABLE {$this->treeTable}"); if(PEAR::isError($r)) return $r;
// position resolving:
if(is_null($aftid)){ // add object as last child
$after = $this->dbc->getOne("
SELECT max(rgt) FROM {$this->treeTable} WHERE parid='$parid'
");
}else{ // use 'aftid'
$after = $this->dbc->getOne("
SELECT ".($aftid == $parid ? 'lft' : 'rgt')."
FROM {$this->treeTable} WHERE id='$aftid'");
}
if(PEAR::isError($after)) return $this->_dbRollback($after);
if(is_null($after)){ // position not specified - add as first child
$after = $this->dbc->getOne("
SELECT lft FROM {$this->treeTable} WHERE id='$parid'
");
}
if(PEAR::isError($after)) return $this->_dbRollback($after);
$after = intval($after);
// tree level resolving:
$level = $this->dbc->getOne("SELECT level FROM {$this->treeTable} WHERE id='$parid'");
if(is_null($level)) return $this->_dbRollback('addObj: parent does not exist');
if(PEAR::isError($level)) return $this->_dbRollback($level);
$id = $this->dbc->nextId("{$this->treeTable}_id_seq");
if(PEAR::isError($id)) return $this->_dbRollback($id);
// creating space in rgt/lft sequencies:
$r = $this->dbc->query("UPDATE {$this->treeTable} SET rgt=rgt+2 WHERE rgt>$after");
if(PEAR::isError($r)) return $this->_dbRollback($r);
$r = $this->dbc->query("UPDATE {$this->treeTable} SET lft=lft+2 WHERE lft>$after");
if(PEAR::isError($r)) return $this->_dbRollback($r);
// inserting object:
$r = $this->dbc->query("
INSERT INTO {$this->treeTable} (id, name, type, parid, level, lft, rgt, param)
VALUES ('$id', '$name', '$type', $parid, ".($level+1).", ".($after+1).", ".($after+2).", '$param')
");
if(PEAR::isError($r)) return $this->_dbRollback($r);
$r = $this->dbc->query("COMMIT");
if(PEAR::isError($r)) return $this->_dbRollback($r);
return $id;
}
/**
* copyObj
*
* @param id int
* @param newParid int
* @param after int OPT
* @return int/err
**/
function copyObj($id, $newParid, $after=NULL)
{
$o = $this->dbc->getRow("SELECT * FROM {$this->treeTable} WHERE id='$id'");
if(PEAR::isError($o)) return $o;
$nid = $this->addObj($o['name'], $o['type'], $newParid, $after, $o['param']);
return $nid;
}
/**
* renameObj
*
* @param id int
* @param newName string
* @return int/err
**/
function renameObj($id, $newName)
{
$r = $this->dbc->query("UPDATE {$this->treeTable} SET name='$newName' WHERE id='$id'");
if(PEAR::isError($r)) return $r;
return TRUE;
}
/**
* removeObj
*
* @param id int
* @return boolean/err
**/
function removeObj($id)
{
$dirarr = $this->getDir($id); if(PEAR::isError($dirarr)) return $dirarr;
foreach($dirarr as $k=>$snod)
{
$this->removeObj($snod['id']);
}
$this->dbc->query("BEGIN");
$r = $this->dbc->query("LOCK TABLE {$this->treeTable}"); if(PEAR::isError($r)) return $r;
$rgt = $this->dbc->getOne("SELECT rgt FROM {$this->treeTable} WHERE id='$id'");
if(is_null($rgt)) return $this->_dbRollback('removeObj: object not exists');
// deleting object:
$r = $this->dbc->query("DELETE FROM {$this->treeTable} WHERE id='$id'");
if(PEAR::isError($r)) return $this->_dbRollback($r);
// closing the space in rgt/lft sequencies:
$r = $this->dbc->query("UPDATE {$this->treeTable} SET rgt=rgt-2 WHERE rgt>$rgt");
if(PEAR::isError($r)) return $this->_dbRollback($r);
$r = $this->dbc->query("UPDATE {$this->treeTable} SET lft=lft-2 WHERE lft>$rgt");
if(PEAR::isError($r)) return $this->_dbRollback($r);
$r = $this->dbc->query("COMMIT");
if(PEAR::isError($r)) return $this->_dbRollback($r);
return TRUE;
}
/* --- info methods: --- */
/**
* getObjId - search dir for object by name
*
* @param name string
* @param parId int OPT
* @return int/err
**/
function getObjId($name, $parId=NULL)
{
if($name=='' && is_null($parId)) $name = $this->rootNodeName;
return $this->dbc->getOne(
"SELECT id FROM {$this->treeTable} WHERE name='$name' and ".($parId ? "parid='$parId'":"parid is null")
);
}
/**
* getObjName - get one value for object (default: get name)
*
* @param oid int
* @param fld string OPT
* @return string/err
**/
function getObjName($oid, $fld='name')
{
return $this->dbc->getOne("SELECT $fld FROM {$this->treeTable} WHERE id='$oid'");
}
/**
* getObjType
*
* @param oid int
* @return string/err
**/
function getObjType($oid)
{
return $this->getObjName($oid, 'type');
}
/**
* getParent
*
* @param id int
* @return string/err
**/
function getParent($oid)
{
return $this->getObjName($oid, 'parid');
}
/**
* getPath - get array of nodes in object's path
*
* @param id int
* @param flds string OPT
* @return array/err
**/
function getPath($id, $flds='id')
{
$this->dbc->query("BEGIN");
$a = $this->dbc->getRow("SELECT name, lft, rgt FROM {$this->treeTable} WHERE id='$id'");
$res = $this->dbc->getAll("
SELECT $flds FROM {$this->treeTable} WHERE lft<={$a['lft']} AND rgt>={$a['rgt']}
ORDER by lft
");
$this->dbc->query("COMMIT");
return $res;
}
/**
* getDir - get array of childnodes
*
* @param id int
* @param flds string OPT
* @param order string OPT
* @return array/err
**/
function getDir($id, $flds='id', $order='lft')
{
return $this->dbc->getAll("
SELECT $flds FROM {$this->treeTable} WHERE parid='$id' ORDER BY $order
");
}
/**
* getSubTree
*
* @param id int OPT
* @param withRoot boolean OPT
* @return array/err
**/
function getSubTree($id=NULL, $withRoot=FALSE)
{
if(is_null($id)) $id = $this->getRootNode();
$r = array();
if($withRoot) $r[] = $re = $this->dbc->getRow("SELECT id, name, level FROM {$this->treeTable} WHERE id='$id'");
if(PEAR::isError($re)) return $re;
$dirarr = $this->getDir($id); if(PEAR::isError($dirarr)) return $dirarr;
foreach($dirarr as $k=>$snod)
{
$r[] = $re = $this->dbc->getRow("SELECT id, name, level FROM {$this->treeTable} WHERE id={$snod['id']}");
if(PEAR::isError($re)) return $re;
$r = array_merge($r, $this->getSubTree($snod['id']));
}
return $r;
}
/**
* getRootNode - get id of root node
*
* @return int/err
**/
function getRootNode()
{
return $this->getObjId($this->rootNodeName);
}
/**
* getAllObjects
*
* @return array/err
**/
function getAllObjects()
{
return $this->dbc->getAll("SELECT * FROM {$this->treeTable} ORDER BY lft");
}
/* --- info methods related to application structure: --- */
/* (this part should be added/rewritten to allow defining/modifying/using application structure) */
/* (only very simple structure definition - in config - supported now) */
/**
* getAllowedChildTypes
*
* @param type string
* @return array
**/
function getAllowedChildTypes($type)
{
return $this->config['objtypes'][$type];
}
/* ========== "private" methods: ========== */
/**
* _dbRollback
*
* @param r object/string
* @return err
**/
function _dbRollback($r)
{
$this->dbc->query("ROLLBACK");
if(PEAR::isError($r)) return $r;
elseif(is_string($r)) return PEAR::raiseError("ERROR: ".get_class($this).": $r", ALIBERR_MTREE, PEAR_ERROR_RETURN);
else return PEAR::raiseError("ERROR: ".get_class($this).": unknown error", ALIBERR_MTREE, PEAR_ERROR_RETURN);
}
/**
* _relocateSubtree - move subtree to another node without removing/adding
*
* @param id int
* @param newParid int
* @param after int
* @return boolean/err
**/
function _relocateSubtree($id, $newParid, $after=NULL)
{
$this->dbc->query("BEGIN");
$r = $this->dbc->query("LOCK TABLE {$this->treeTable}"); if(PEAR::isError($r)) return $r;
// obtain values for source node:
$a1 = $this->dbc->getRow("SELECT lft, rgt, level FROM {$this->treeTable} WHERE id='$id'");
if(is_null($a1)) return $this->_dbRollback('_relocateSubtree: object not exists');
extract($a1);
// values for destination node:
$a2 = $this->dbc->getRow("SELECT rgt, level FROM {$this->treeTable} WHERE id='$newParid'");
if(is_null($a2)) return $this->_dbRollback('_relocateSubtree: new parent not exists');
$nprgt = $a2['rgt']; $newLevel = $a2['level'];
// calculate differencies:
if(is_null($after)) $after = $nprgt-1;
$dif1 = $rgt-$lft+1;
$dif2 = $after-$lft+1;
$dif3 = $newLevel-$level+1;
// relocate the object"
$r = $this->dbc->query("UPDATE {$this->treeTable} SET parid='$newParid' WHERE id='$id'");
if(PEAR::isError($r)) return $this->_dbRollback($r);
if($after>$rgt){
// relocate subtree to the right:
$r = $this->dbc->query("UPDATE {$this->treeTable} SET rgt=rgt+$dif1 WHERE rgt>$after");
if(PEAR::isError($r)) return $this->_dbRollback($r);
$r = $this->dbc->query("UPDATE {$this->treeTable} SET lft=lft+$dif1 WHERE lft>$after");
if(PEAR::isError($r)) return $this->_dbRollback($r);
$r = $this->dbc->query("UPDATE {$this->treeTable}
SET lft=lft+$dif2, rgt=rgt+$dif2, level=level+$dif3
WHERE lft>=$lft AND rgt <=$rgt");
if(PEAR::isError($r)) return $this->_dbRollback($r);
$r = $this->dbc->query("UPDATE {$this->treeTable} SET rgt=rgt-$dif1 WHERE rgt>$rgt");
if(PEAR::isError($r)) return $this->_dbRollback($r);
$r = $this->dbc->query("UPDATE {$this->treeTable} SET lft=lft-$dif1 WHERE lft>$rgt");
if(PEAR::isError($r)) return $this->_dbRollback($r);
}else{
// relocate subtree to the left:
$r = $this->dbc->query("UPDATE {$this->treeTable} SET rgt=rgt+$dif1 WHERE rgt>$after");
if(PEAR::isError($r)) return $this->_dbRollback($r);
$r = $this->dbc->query("UPDATE {$this->treeTable} SET lft=lft+$dif1 WHERE lft>$after");
if(PEAR::isError($r)) return $this->_dbRollback($r);
$r = $this->dbc->query("UPDATE {$this->treeTable}
SET lft=lft+$dif2-$dif1, rgt=rgt+$dif2-$dif1, level=level+$dif3
WHERE lft>=$lft+$dif1 AND rgt <=$rgt+$dif1");
if(PEAR::isError($r)) return $this->_dbRollback($r);
$r = $this->dbc->query("UPDATE {$this->treeTable} SET rgt=rgt-$dif1 WHERE rgt>$rgt+$dif1");
if(PEAR::isError($r)) return $this->_dbRollback($r);
$r = $this->dbc->query("UPDATE {$this->treeTable} SET lft=lft-$dif1 WHERE lft>$rgt+$dif1");
if(PEAR::isError($r)) return $this->_dbRollback($r);
}
$r = $this->dbc->query("COMMIT");
if(PEAR::isError($r)) return $this->_dbRollback($r);
return TRUE;
}
/**
* _copySubtree - recursive copyObj
*
* @param id int
* @param newParid int
* @param after int
* @return array
**/
function _copySubtree($id, $newParid, $after=NULL)
{
$nid = $this->copyObj($id, $newParid, $after);
if(PEAR::isError($nid)) return $nid;
$dirarr = $this->getDir($id); if(PEAR::isError($dirarr)) return $dirarr;
foreach($dirarr as $k=>$snod)
{
$r = $this->_copySubtree($snod['id'], $nid);
if(PEAR::isError($r)) return $r;
}
}
/* ========== test and debug methods: ========== */
/**
* dumpTree
*
* @param id int
* @param indstr string // indentation string
* @param ind string // aktual indentation
* @return string
**/
function dumpTree($id=NULL, $indstr=' ', $ind='', $format='{name}', $withRoot=TRUE)
{
$r='';
foreach($this->getSubTree($id, $withRoot) as $o)
$r .= str_repeat($indstr, intval($o['level'])).
preg_replace(array('|\{name\}|', '|\{id\}|'), array($o['name'], $o['id']), $format).
"\n";
return $r;
}
/**
* deleteData
*
**/
function deleteData()
{
$this->dbc->query("DELETE FROM {$this->treeTable} WHERE parid is not null");
}
/**
* testData
*
* @param id int OPT
* @return array
**/
function testData()
{
$o[] = $rootId = $this->getRootNode();
$o[] = $p1 = $this->addObj('Publication A', 'Publication', $rootId); // 1
$o[] = $p2 = $this->addObj('Publication B', 'Publication', $rootId); // 2
$o[] = $i1 = $this->addObj('Issue 1', 'Issue', $p1); // 3
$o[] = $i2 = $this->addObj('Issue 2', 'Issue', $p1); // 4
$o[] = $s1 = $this->addObj('Section a', 'Section', $i2);
$o[] = $s2 = $this->addObj('Section b', 'Section', $i2); // 6
$o[] = $s3 = $this->addObj('Section c', 'Section', $i2);
$o[] = $t1 = $this->addObj('Title', 'Title', $s2);
$o[] = $s4 = $this->addObj('Section a', 'Section', $i1);
$o[] = $s5 = $this->addObj('Section b', 'Section', $i1);
$this->tdata['tree'] = $o;
}
/**
* test
*
**/
function test()
{
$this->deleteData();
$this->testData();
$rootId = $this->getRootNode();
$this->test_correct ="RootNode\n Publication A\n Issue 1\n Section a\n Section b\n Issue 2\n Section a\n Section b\n Title\n Section c\n Publication B\nRootNode\n";
$this->test_dump = $this->dumpTree();
$this->removeObj($this->tdata['tree'][1]);
$this->removeObj($this->tdata['tree'][2]);
$this->test_dump .= $this->dumpTree();
$this->deleteData();
if($this->test_dump == $this->test_correct){ $this->test_log.="tree: OK\n"; return TRUE; }
else return PEAR::raiseError('Mtree::test:', 1, PEAR_ERROR_DIE, '%s'.
"<pre>\ncorrect:\n.{$this->test_correct}.\ndump:\n.{$this->test_dump}.\n</pre>\n");
}
/**
* install - create tables + initialize
*
**/
function install()
{
$this->dbc->query("CREATE TABLE {$this->treeTable} (
id int not null,
name varchar(255) not null default'',
parid int,
lft int,
rgt int,
level int,
type varchar(255) not null default'',
param varchar(255)
)");
$this->dbc->query("CREATE UNIQUE INDEX {$this->treeTable}_id_idx on {$this->treeTable} (id)");
$this->dbc->query("CREATE INDEX {$this->treeTable}_name_idx on {$this->treeTable} (name)");
$this->dbc->createSequence("{$this->treeTable}_id_seq");
$id = $this->dbc->nextId("{$this->treeTable}_id_seq");
$this->dbc->query("INSERT INTO {$this->treeTable} (id, name, parid, level, lft, rgt, type)
VALUES ($id, '{$this->rootNodeName}', NULL, 0, 1, 2, 'RootNode')");
}
/**
* uninstall
*
**/
function uninstall()
{
$this->dbc->query("DROP TABLE {$this->treeTable}");
$this->dbc->dropSequence("{$this->treeTable}_id_seq");
}
/**
* reinstall
*
**/
function reinstall()
{
$this->uninstall();
$this->install();
}
}
?>

View File

@ -0,0 +1,441 @@
<?php
// $Id: subj.php,v 1.1 2004/07/23 00:22:13 tomas Exp $
/**
* Subj class
*
* users + groups
* with "linearized recursive membership" ;)
* (allow adding users to groups or groups to groups)
*
**/
require_once"class.php";
define('ALIBERR_NOTGR', 20);
define('ALIBERR_BADSMEMB', 21);
class Subjects extends ObjClasses{
var $subjTable;
var $smembTable;
/** Subjects - constructor
*
* @param dbc object
* @param config array
* @return this
**/
function Subjects(&$dbc, $config)
{
parent::ObjClasses(&$dbc, $config);
$this->subjTable = $config['tblNamePrefix'].'subjs';
$this->smembTable = $config['tblNamePrefix'].'smemb';
}
/* ========== public methods: ========== */
/**
* addSubj
*
* @param login string
* @param pass string OPT
* @return int/err
**/
function addSubj($login, $pass=NULL)
{
$id = $this->dbc->nextId("{$this->subjTable}_id_seq"); if(PEAR::isError($id)) return $id;
$r = $this->dbc->query("
INSERT INTO {$this->subjTable} (id, login, pass, type)
VALUES ($id, '$login', ".(is_null($pass) ? "'!', 'G'" : "'".md5($pass)."', 'U'").")
");
if(PEAR::isError($r)) return $r;
return $id;
}
/**
* removeSubj
*
* @param login string
* @param uid int OPT
* @return boolean/err
**/
function removeSubj($login, $uid=NULL)
{
if(is_null($uid)) $uid = $this->getSubjId($login);
if(PEAR::isError($uid)) return $uid;
$r = $this->dbc->query("DELETE FROM {$this->smembTable} WHERE (uid='$uid' OR gid='$uid') AND mid is null");
if(PEAR::isError($r)) return $r;
$r = $this->dbc->query("DELETE FROM {$this->subjTable} WHERE login='$login'");
if(PEAR::isError($r)) return $r;
return $this->_rebuildRels();
}
/**
* authenticate
*
* @param login string
* @param pass string OPT
* @return boolean/int/err
**/
function authenticate($login, $pass='')
{
$cpass = md5($pass);
$id = $this->dbc->getOne("
SELECT id FROM {$this->subjTable}
WHERE login='$login' AND pass='$cpass' AND type='U'
");
if(PEAR::isError($id)) return $id;
return (is_null($id) ? FALSE : $id);
}
/* --- groups --- */
/**
* addSubj2Gr - add {login} and direct/indirect members to {gname} and to groups, where {gname} is [in]direct member
*
* @param login string
* @param gname string
* @return int/err
**/
function addSubj2Gr($login, $gname)
{
$uid = $this->getSubjId($login); if(PEAR::isError($uid)) return $uid;
$gid = $this->getSubjId($gname); if(PEAR::isError($gid)) return $gid;
$isgr = $this->isGroup($gid); if(PEAR::isError($isgr)) return $isgr;
if(!$isgr) return PEAR::raiseError("Subjects::addSubj2Gr: Not a group ($gname)", ALIBERR_NOTGR);
// add subject and all [in]direct members to group $gname:
$mid = $this->_plainAddSubj2Gr($uid, $gid); if(PEAR::isError($mid)) return $mid;
// add it to all groups where $gname is [in]direct member:
$marr = $this->_listRMemb($gid); if(PEAR::isError($marr)) return $marr;
foreach($marr as $k=>$v){
$r = $this->_plainAddSubj2Gr($uid, $v['gid'], intval($v['level'])+1, $v['id']);
if(PEAR::isError($r)) return $r;
}
return $mid;
}
/**
* removeSubjFromGr
*
* @param login string
* @param gname string
* @return boolean/err
**/
function removeSubjFromGr($login, $gname)
{
$uid = $this->getSubjId($login); if(PEAR::isError($uid)) return $uid;
$gid = $this->getSubjId($gname); if(PEAR::isError($gid)) return $gid;
$mid = $this->dbc->getOne($q = "SELECT id FROM {$this->smembTable} WHERE uid='$uid' AND gid='$gid' AND mid is null");
if(is_null($mid)) return FALSE;
if(PEAR::isError($mid)) return $mid;
// remove it:
$r = $this->_removeMemb($mid); if(PEAR::isError($r)) return $r;
// and rebuild indirect memberships:
$r = $this->_rebuildRels(); if(PEAR::isError($r)) return $r;
return TRUE;
}
/* --- info methods: --- */
/**
* getSubjId
*
* @param login string
* @return int/err
**/
function getSubjId($login)
{
return $this->dbc->getOne("SELECT id FROM {$this->subjTable} WHERE login='$login'");
}
/**
* getSubjName
*
* @param id int
* @param fld string
* @return string/err
**/
function getSubjName($id, $fld='login')
{
return $this->dbc->getOne("SELECT $fld FROM {$this->subjTable} WHERE id='$id'");
}
/**
* getSubjects
*
* @param flds string OPT
* @return array/err
**/
function getSubjects($flds='id, login')
{
return $this->dbc->getAll("SELECT $flds FROM {$this->subjTable}");
}
/**
* getSubjectsWCnt - get subjects with count of direct members
*
* @return array/err
**/
function getSubjectsWCnt()
{
return $this->dbc->getAll("SELECT count(m.uid)as cnt, s.id, s.login, s.type
FROM {$this->subjTable} s LEFT JOIN {$this->smembTable} m ON m.gid=s.id
WHERE m.mid is null GROUP BY s.id, s.login, s.type ORDER BY s.id");
}
/**
* isGroup
*
* @param gid int
* @return boolean/err
**/
function isGroup($gid)
{
$r = $this->dbc->getOne("SELECT type FROM {$this->subjTable} WHERE id='$gid'");
if(PEAR::isError($r)) return $r;
return ($r === 'G' );
}
/**
* listGroup - list direct members of group
*
* @param gid int
* @return array/err
**/
function listGroup($gid)
{
return $this->dbc->getAll("SELECT s.id, s.login, s.type FROM {$this->smembTable} m, {$this->subjTable} s
WHERE m.uid=s.id AND m.mid is null AND m.gid='$gid'");
}
/* ========== "private" methods: ========== */
/**
* _addMemb - create membership record
*
* @param uid int
* @param gid int
* @param level int OPT
* @param mid int OPT
* @return int/err
**/
function _addMemb($uid, $gid, $level=0, $mid='null')
{
if($uid == $gid) return PEAR::raiseError("Subjects::_addMemb: uid==gid ($uid)", ALIBERR_BADSMEMB);
$a = $this->dbc->getAll("SELECT id, level, mid FROM {$this->smembTable} WHERE uid='$uid' AND gid='$gid' ORDER BY level ASC");
if(PEAR::isError($a)) return $a;
if(count($a)>0){
$a0 = $a[0];
$id = $a0['id'];
if($level < intval($a0['level'])){
$r = $this->dbc->query("UPDATE {$this->smembTable} SET level='$level', mid='$mid' WHERE id='{$a0['id']}'");
if(PEAR::isError($r)) return $r;
}
}else{
$id = $this->dbc->nextId("{$this->smembTable}_id_seq"); if(PEAR::isError($id)) return $id;
$r = $this->dbc->query("
INSERT INTO {$this->smembTable} (id, uid, gid, level, mid) VALUES ($id, $uid, $gid, $level, $mid)
");
if(PEAR::isError($r)) return $r;
}
return $id;
}
/**
* _removeMemb
*
* @param mid int
* @return null/err
**/
function _removeMemb($mid)
{
return $this->dbc->query("DELETE FROM {$this->smembTable} WHERE id='$mid'");
}
/**
* _listMemb - list [in]direct members of group
*
* @param gid int
* @param uid int OPT
* @return array/err
**/
function _listMemb($gid, $uid=NULL)
{
return $this->dbc->getAll("SELECT id, uid, level FROM {$this->smembTable} WHERE gid='$gid'".(is_null($uid) ? '' : " AND uid='$uid'"));
}
/**
* _listRMemb - list groups where uid is [in]direct member
*
* @param gid int
* @param uid int OPT
* @return array/err
**/
function _listRMemb($uid, $gid=NULL)
{
return $this->dbc->getAll("SELECT id, gid, level FROM {$this->smembTable} WHERE uid='$uid'".(is_null($gid) ? '' : " AND gid='$gid'"));
}
/**
* _plainAddSubj2Gr - add uid and its [in]direct members to gid
*
* @param uid int
* @param gid int
* @param level int
* @param rmid int //
* @return int/err
**/
function _plainAddSubj2Gr($uid, $gid, $level=0, $rmid='null')
{
$mid = $this->_addMemb($uid, $gid, $level, $rmid); if(PEAR::isError($mid)) return $mid;
$marr = $this->_listMemb($uid); if(PEAR::isError($marr)) return $marr;
foreach($marr as $k=>$v){
$r = $this->_addMemb($v['uid'], $gid, intval($v['level'])+$level+1, $mid);
if(PEAR::isError($r)) return $r;
}
return $mid;
}
/**
* _rebuildRels - rebuild indirect membership records
*
* @return true/err
**/
function _rebuildRels()
{
$this->dbc->query("BEGIN");
$r = $this->dbc->query("LOCK TABLE {$this->smembTable}"); if(PEAR::isError($r)) return $r;
$r = $this->dbc->query("DELETE FROM {$this->smembTable} WHERE mid is not null");
if(PEAR::isError($r)) return $r;
$arr = $this->dbc->getAll("SELECT uid, gid FROM {$this->smembTable}"); // WHERE mid is null
if(PEAR::isError($arr)) return $arr;
foreach($arr as $it){
$marr = $this->_listRMemb($it['gid']); if(PEAR::isError($marr)) return $marr;
foreach($marr as $k=>$v){
$r = $this->_plainAddSubj2Gr($it['uid'], $v['gid'], intval($v['level'])+1, $v['id']);
if(PEAR::isError($r)) return $r;
}
}
$r = $this->dbc->query("COMMIT"); if(PEAR::isError($r)) return $r;
return TRUE;
}
/* ========== test and debug methods: ========== */
/**
* dumpSubjects
*
* @param indstr string // indentation string
* @param ind string // aktual indentation
* @return string
**/
function dumpSubjects($indstr=' ', $ind='')
{
# $r = $ind.join(', ', $this->dbc->getCol("SELECT login FROM {$this->subjTable}"))."\n";
$r = $ind.join(', ', array_map(create_function('$v', 'return "{$v[\'login\']}({$v[\'cnt\']})";'), $this->getSubjectsWCnt()))."\n";
return $r;
}
/**
* deleteData
*
* @return void
**/
function deleteData()
{
$this->dbc->query("DELETE FROM {$this->subjTable}");
$this->dbc->query("DELETE FROM {$this->smembTable}");
parent::deleteData();
}
/**
* testData
*
* @return array
**/
function testData()
{
parent::testData();
$o[] = $this->addSubj('root', 'q');
$o[] = $this->addSubj('test1', 'a');
$o[] = $this->addSubj('test2', 'a');
$o[] = $this->addSubj('test3', 'a');
$o[] = $this->addSubj('test4', 'a');
$o[] = $this->addSubj('gr1');
$o[] = $this->addSubj('gr2');
# $this->addSubj2Gr('test1', 'gr1');
$this->addSubj2Gr('test2', 'gr1');
$this->addSubj2Gr('test3', 'gr1');
$this->addSubj2Gr('test4', 'gr2');
$this->addSubj2Gr('gr2', 'gr1');
$o[] = $this->addSubj('gr3');
$this->addSubj2Gr('test3', 'gr3');
$this->addSubj2Gr('test1', 'gr3');
$this->addSubj2Gr('gr3', 'gr2');
return $this->tdata['subjects'] = $o;
}
/**
* test
*
**/
function test()
{
if(PEAR::isError($p = parent::test())) return $p;
$this->deleteData();
$this->testData();
$this->test_correct = "root(0), test1(0), test2(0), test3(0), test4(0), gr1(3), gr2(2), gr3(2)\n";
$this->test_dump = $this->dumpSubjects();
$this->removeSubj('test1');
$this->removeSubj('test3');
$this->removeSubjFromGr('test2', 'gr1');
$this->removeSubjFromGr('gr3', 'gr2');
$this->test_correct .= "root(0), test2(0), test4(0), gr1(1), gr2(1), gr3(0)\n";
$this->test_dump .= $this->dumpSubjects();
$this->deleteData();
if($this->test_dump == $this->test_correct){ $this->test_log.="subj: OK\n"; return TRUE; }
else return PEAR::raiseError('Subjects::test:', 1, PEAR_ERROR_DIE, '%s'.
"<pre>\ncorrect:\n{$this->test_correct}\ndump:\n{$this->test_dump}\n</pre>\n");
}
/**
* install - create tables + initialize
*
**/
function install()
{
parent::install();
$this->dbc->query("CREATE TABLE {$this->subjTable} (
id int not null,
login varchar(255) not null default'',
pass varchar(255) not null default'',
type char(1) not null default 'U'
)");
$this->dbc->query("CREATE UNIQUE INDEX {$this->subjTable}_id_idx on {$this->subjTable} (id)");
$this->dbc->query("CREATE UNIQUE INDEX {$this->subjTable}_login_idx on {$this->subjTable} (login)");
$this->dbc->createSequence("{$this->subjTable}_id_seq");
$this->dbc->query("CREATE TABLE {$this->smembTable} (
id int not null,
uid int not null default 0,
gid int not null default 0,
level int not null default 0,
mid int
)");
$this->dbc->query("CREATE UNIQUE INDEX {$this->smembTable}_id_idx on {$this->smembTable} (id)");
$this->dbc->createSequence("{$this->smembTable}_id_seq");
}
/**
* uninstall
*
* @return void
**/
function uninstall()
{
$this->dbc->query("DROP TABLE {$this->subjTable}");
$this->dbc->dropSequence("{$this->subjTable}_id_seq");
$this->dbc->query("DROP TABLE {$this->smembTable}");
$this->dbc->dropSequence("{$this->smembTable}_id_seq");
parent::uninstall();
}
}
?>

View File

@ -0,0 +1,99 @@
<?php
// $Id: alib_xr.php,v 1.1 2004/07/23 00:22:13 tomas Exp $
include_once"xmlrpc.inc";
include_once"xmlrpcs.inc";
require_once"../example/alib_h.php";
function v2xr($var, $struct=true){
if(is_array($var)){
$r = array();
foreach($var as $k=>$v) if($struct) $r[$k]=v2xr($v); else $r[]=v2xr($v);
return new xmlrpcval($r, ($struct?"struct":"array"));
}else if(is_int($var)){
return new xmlrpcval($var, "int");
}else{
return new xmlrpcval($var, "string");
}
}
class XR_Alib extends alib{
function xr_test($input){
$p1=$input->getParam(0);
if(isset($p1) && $p1->scalartyp()=="string") $s=$p1->scalarval();
else return new xmlrpcresp(0, 801, "xr_login: wrong 1st parameter, string expected.");
$p2=$input->getParam(1);
if(isset($p2) && $p2->scalartyp()=="string") $sessid=$p2->scalarval();
else return new xmlrpcresp(0, 801, "xr_login: wrong 2nd parameter, string expected.");
return new xmlrpcresp(v2xr(strtoupper($s)."_".$this->getSessLogin($sessid)."_".$sessid, false));
}
function xr_login($input){
$p1=$input->getParam(0);
if(isset($p1) && $p1->scalartyp()=="string") $login=$p1->scalarval();
else return new xmlrpcresp(0, 801, "xr_login: wrong 1st parameter, string expected.");
$p2=$input->getParam(1);
if(isset($p2) && $p2->scalartyp()=="string") $pass=$p2->scalarval();
else return new xmlrpcresp(0, 801, "xr_login: wrong 2nd parameter, string expected.");
if(!($res = $this->login($login, $pass)))
return new xmlrpcresp(0, 802, "xr_login: login failed - incorrect username or password.");
else
return new xmlrpcresp(v2xr($res, false));
}
function xr_logout($input){
$p1=$input->getParam(0);
if(isset($p1) && $p1->scalartyp()=="string") $sessid=$p1->scalarval();
else return new xmlrpcresp(0, 801, "xr_login: wrong 2nd parameter, string expected.");
$res = $this->logout($sessid);
if(!PEAR::isError($res)) return new xmlrpcresp(v2xr('Bye', false));
else return new xmlrpcresp(0, 803, "xr_logout: logout failed - not logged.");
}
function xr_getDir($input){
$p1=$input->getParam(0);
if(isset($p1) && ($p1->scalartyp()=="int") && is_numeric($id=$p1->scalarval()));
else return new xmlrpcresp(0, 801, "xr_getDir: wrong 1st parameter, int expected.");
$res = $this->getDir($id, 'name');
return new xmlrpcresp(v2xr($res, false));
}
function xr_getPath($input){
$p1=$input->getParam(0);
if(isset($p1) && ($p1->scalartyp()=="int") && is_numeric($id=$p1->scalarval()));
else return new xmlrpcresp(0, 801, "xr_getPath: wrong 1st parameter, int expected.");
$res = $this->getPath($id, 'id, name');
return new xmlrpcresp(v2xr($res, false));
}
}
$alib = &new XR_Alib($dbc, $config);
$s=new xmlrpc_server( array(
"alib.xrTest" => array(
"function" => array(&$alib, 'xr_test'),
"signature" => array(array($xmlrpcString, $xmlrpcString, $xmlrpcString)),
"docstring" => ""
),
"alib.login" => array(
"function" => array(&$alib, 'xr_login'),
"signature" => array(array($xmlrpcString, $xmlrpcString, $xmlrpcString)),
"docstring" => ""
),
"alib.logout" => array(
"function" => array(&$alib, 'xr_logout'),
"signature" => array(array($xmlrpcString, $xmlrpcString)),
"docstring" => ""
),
"alib.getDir" => array(
"function" => array(&$alib, 'xr_getDir'),
"signature" => array(array($xmlrpcArray, $xmlrpcInt)),
"docstring" => "returns directory listing of object with given id"
),
"alib.getPath" => array(
"function" => array(&$alib, 'xr_getPath'),
"signature" => array(array($xmlrpcArray, $xmlrpcInt)),
"docstring" => "returns listing of object in path from rootnode to object with given id"
)
));
#header("Content-type: text/plain");
#print_r($dirlist = getDir());
require_once"../example/alib_f.php";
?>

View File

@ -0,0 +1,7 @@
<?php
// $Id: index.php,v 1.1 2004/07/23 00:22:13 tomas Exp $
header ("location: xr_cli_test.php");
die;
?>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,450 @@
<?php
// by Edd Dumbill (C) 1999-2002
// <edd@usefulinc.com>
// $Id: xmlrpcs.inc,v 1.1 2004/07/23 00:22:13 tomas Exp $
// Copyright (c) 1999,2000,2002 Edd Dumbill.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
//
// * Neither the name of the "XML-RPC for PHP" nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
// XML RPC Server class
// requires: xmlrpc.inc
// listMethods: either a string, or nothing
$_xmlrpcs_listMethods_sig=array(array($xmlrpcArray, $xmlrpcString), array($xmlrpcArray));
$_xmlrpcs_listMethods_doc='This method lists all the methods that the XML-RPC server knows how to dispatch';
function _xmlrpcs_listMethods($server, $m)
{
global $xmlrpcerr, $xmlrpcstr, $_xmlrpcs_dmap;
$v=new xmlrpcval();
$dmap=$server->dmap;
$outAr=array();
for(reset($dmap); list($key, $val)=each($dmap); )
{
$outAr[]=new xmlrpcval($key, 'string');
}
$dmap=$_xmlrpcs_dmap;
for(reset($dmap); list($key, $val)=each($dmap); )
{
$outAr[]=new xmlrpcval($key, 'string');
}
$v->addArray($outAr);
return new xmlrpcresp($v);
}
$_xmlrpcs_methodSignature_sig=array(array($xmlrpcArray, $xmlrpcString));
$_xmlrpcs_methodSignature_doc='Returns an array of known signatures (an array of arrays) for the method name passed. If no signatures are known, returns a none-array (test for type != array to detect missing signature)';
function _xmlrpcs_methodSignature($server, $m)
{
global $xmlrpcerr, $xmlrpcstr, $_xmlrpcs_dmap;
$methName=$m->getParam(0);
$methName=$methName->scalarval();
if (ereg("^system\.", $methName))
{
$dmap=$_xmlrpcs_dmap; $sysCall=1;
}
else
{
$dmap=$server->dmap; $sysCall=0;
}
// print "<!-- ${methName} -->\n";
if (isset($dmap[$methName]))
{
if ($dmap[$methName]['signature'])
{
$sigs=array();
$thesigs=$dmap[$methName]['signature'];
for($i=0; $i<sizeof($thesigs); $i++)
{
$cursig=array();
$inSig=$thesigs[$i];
for($j=0; $j<sizeof($inSig); $j++)
{
$cursig[]=new xmlrpcval($inSig[$j], 'string');
}
$sigs[]=new xmlrpcval($cursig, 'array');
}
$r=new xmlrpcresp(new xmlrpcval($sigs, 'array'));
}
else
{
$r=new xmlrpcresp(new xmlrpcval('undef', 'string'));
}
}
else
{
$r=new xmlrpcresp(0,$xmlrpcerr['introspect_unknown'], $xmlrpcstr['introspect_unknown']);
}
return $r;
}
$_xmlrpcs_methodHelp_sig=array(array($xmlrpcString, $xmlrpcString));
$_xmlrpcs_methodHelp_doc='Returns help text if defined for the method passed, otherwise returns an empty string';
function _xmlrpcs_methodHelp($server, $m)
{
global $xmlrpcerr, $xmlrpcstr, $_xmlrpcs_dmap;
$methName=$m->getParam(0);
$methName=$methName->scalarval();
if (ereg("^system\.", $methName))
{
$dmap=$_xmlrpcs_dmap; $sysCall=1;
}
else
{
$dmap=$server->dmap; $sysCall=0;
}
// print "<!-- ${methName} -->\n";
if (isset($dmap[$methName]))
{
if ($dmap[$methName]['docstring'])
{
$r=new xmlrpcresp(new xmlrpcval($dmap[$methName]["docstring"]), 'string');
}
else
{
$r=new xmlrpcresp(new xmlrpcval('', 'string'));
}
}
else
{
$r=new xmlrpcresp(0, $xmlrpcerr['introspect_unknown'], $xmlrpcstr['introspect_unknown']);
}
return $r;
}
$_xmlrpcs_multicall_sig = array(array($xmlrpcArray, $xmlrpcArray));
$_xmlrpcs_multicall_doc = 'Boxcar multiple RPC calls in one request. See http://www.xmlrpc.com/discuss/msgReader$1208 for details';
function _xmlrpcs_multicall_error($err)
{
if (is_string($err))
{
global $xmlrpcerr, $xmlrpcstr;
$str = $xmlrpcstr["multicall_${err}"];
$code = $xmlrpcerr["multicall_${err}"];
}
else
{
$code = $err->faultCode();
$str = $err->faultString();
}
$struct['faultCode'] = new xmlrpcval($code, 'int');
$struct['faultString'] = new xmlrpcval($str, 'string');
return new xmlrpcval($struct, 'struct');
}
function _xmlrpcs_multicall_do_call($server, $call)
{
if ($call->kindOf() != 'struct')
return _xmlrpcs_multicall_error('notstruct');
$methName = $call->structmem('methodName');
if (!$methName)
return _xmlrpcs_multicall_error('nomethod');
if ($methName->kindOf() != 'scalar' || $methName->scalartyp() != 'string')
return _xmlrpcs_multicall_error('notstring');
if ($methName->scalarval() == 'system.multicall')
return _xmlrpcs_multicall_error('recursion');
$params = $call->structmem('params');
if (!$params)
return _xmlrpcs_multicall_error('noparams');
if ($params->kindOf() != 'array')
return _xmlrpcs_multicall_error('notarray');
$numParams = $params->arraysize();
$msg = new xmlrpcmsg($methName->scalarval());
for ($i = 0; $i < $numParams; $i++)
$msg->addParam($params->arraymem($i));
$result = $server->execute($msg);
if ($result->faultCode() != 0)
return _xmlrpcs_multicall_error($result); // Method returned fault.
return new xmlrpcval(array($result->value()), "array");
}
function _xmlrpcs_multicall($server, $m)
{
$calls = $m->getParam(0);
$numCalls = $calls->arraysize();
$result = array();
for ($i = 0; $i < $numCalls; $i++)
{
$call = $calls->arraymem($i);
$result[$i] = _xmlrpcs_multicall_do_call($server, $call);
}
return new xmlrpcresp(new xmlrpcval($result, 'array'));
}
$_xmlrpcs_dmap=array(
'system.listMethods' => array(
'function' => '_xmlrpcs_listMethods',
'signature' => $_xmlrpcs_listMethods_sig,
'docstring' => $_xmlrpcs_listMethods_doc),
'system.methodHelp' => array(
'function' => '_xmlrpcs_methodHelp',
'signature' => $_xmlrpcs_methodHelp_sig,
'docstring' => $_xmlrpcs_methodHelp_doc),
'system.methodSignature' => array(
'function' => '_xmlrpcs_methodSignature',
'signature' => $_xmlrpcs_methodSignature_sig,
'docstring' => $_xmlrpcs_methodSignature_doc),
'system.multicall' => array(
'function' => '_xmlrpcs_multicall',
'signature' => $_xmlrpcs_multicall_sig,
'docstring' => $_xmlrpcs_multicall_doc
)
);
$_xmlrpc_debuginfo='';
function xmlrpc_debugmsg($m)
{
global $_xmlrpc_debuginfo;
$_xmlrpc_debuginfo=$_xmlrpc_debuginfo . $m . "\n";
}
class xmlrpc_server
{
var $dmap=array();
function xmlrpc_server($dispMap='', $serviceNow=1)
{
global $HTTP_RAW_POST_DATA;
// dispMap is a dispatch array of methods
// mapped to function names and signatures
// if a method
// doesn't appear in the map then an unknown
// method error is generated
/* milosch - changed to make passing dispMap optional.
* instead, you can use the class add_to_map() function
* to add functions manually (borrowed from SOAPX4)
*/
if($dispMap)
{
$this->dmap = $dispMap;
if($serviceNow)
{
$this->service();
}
}
}
function serializeDebug()
{
global $_xmlrpc_debuginfo;
if ($_xmlrpc_debuginfo!='')
{
return "<!-- DEBUG INFO:\n\n" . $_xmlrpc_debuginfo . "\n-->\n";
}
else
{
return '';
}
}
function service()
{
global $xmlrpc_defencoding;
$r=$this->parseRequest();
$payload='<?xml version="1.0" encoding="' . $xmlrpc_defencoding . '"?>' . "\n"
. $this->serializeDebug()
. $r->serialize();
Header("Content-type: text/xml\r\nContent-length: " .
strlen($payload));
print $payload;
}
/*
add a method to the dispatch map
*/
function add_to_map($methodname,$function,$sig,$doc)
{
$this->dmap[$methodname] = array(
'function' => $function,
'signature' => $sig,
'docstring' => $doc
);
}
function verifySignature($in, $sig)
{
for($i=0; $i<sizeof($sig); $i++)
{
// check each possible signature in turn
$cursig=$sig[$i];
if (sizeof($cursig)==$in->getNumParams()+1)
{
$itsOK=1;
for($n=0; $n<$in->getNumParams(); $n++)
{
$p=$in->getParam($n);
// print "<!-- $p -->\n";
if ($p->kindOf() == 'scalar')
{
$pt=$p->scalartyp();
}
else
{
$pt=$p->kindOf();
}
// $n+1 as first type of sig is return type
if ($pt != $cursig[$n+1])
{
$itsOK=0;
$pno=$n+1; $wanted=$cursig[$n+1]; $got=$pt;
break;
}
}
if ($itsOK)
{
return array(1);
}
}
}
return array(0, "Wanted ${wanted}, got ${got} at param ${pno})");
}
function parseRequest($data='')
{
global $_xh,$HTTP_RAW_POST_DATA;
global $xmlrpcerr, $xmlrpcstr, $xmlrpcerrxml, $xmlrpc_defencoding,
$_xmlrpcs_dmap;
if ($data=="")
{
$data=$HTTP_RAW_POST_DATA;
}
$parser = xml_parser_create($xmlrpc_defencoding);
$_xh[$parser]=array();
$_xh[$parser]['st']='';
$_xh[$parser]['cm']=0;
$_xh[$parser]['isf']=0;
$_xh[$parser]['params']=array();
$_xh[$parser]['method']='';
// decompose incoming XML into request structure
xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, true);
xml_set_element_handler($parser, 'xmlrpc_se', 'xmlrpc_ee');
xml_set_character_data_handler($parser, 'xmlrpc_cd');
xml_set_default_handler($parser, 'xmlrpc_dh');
if (!xml_parse($parser, $data, 1))
{
// return XML error as a faultCode
$r=new xmlrpcresp(0,
$xmlrpcerrxml+xml_get_error_code($parser),
sprintf("XML error: %s at line %d",
xml_error_string(xml_get_error_code($parser)),
xml_get_current_line_number($parser)));
xml_parser_free($parser);
}
else
{
xml_parser_free($parser);
$m=new xmlrpcmsg($_xh[$parser]['method']);
// now add parameters in
$plist="";
for($i=0; $i<sizeof($_xh[$parser]['params']); $i++)
{
//print "<!-- " . $_xh[$parser]['params'][$i]. "-->\n";
$plist.="$i - " . $_xh[$parser]['params'][$i]. " \n";
eval('$m->addParam(' . $_xh[$parser]['params'][$i]. ");");
}
// uncomment this to really see what the server's getting!
// xmlrpc_debugmsg($plist);
$r = $this->execute($m);
}
return $r;
}
function execute ($m)
{
global $xmlrpcerr, $xmlrpcstr, $_xmlrpcs_dmap;
// now to deal with the method
$methName = $m->method();
$sysCall = ereg("^system\.", $methName);
$dmap = $sysCall ? $_xmlrpcs_dmap : $this->dmap;
if (!isset($dmap[$methName]['function']))
{
// No such method
return new xmlrpcresp(0,
$xmlrpcerr['unknown_method'],
$xmlrpcstr['unknown_method']);
}
// Check signature.
if (isset($dmap[$methName]['signature']))
{
$sig = $dmap[$methName]['signature'];
list ($ok, $errstr) = $this->verifySignature($m, $sig);
if (!$ok)
{
// Didn't match.
return new xmlrpcresp(0,
$xmlrpcerr['incorrect_params'],
$xmlrpcstr['incorrect_params'] . ": ${errstr}");
}
}
$func = $dmap[$methName]['function'];
if ($sysCall)
{
return call_user_func($func, $this, $m);
}
else
{
return call_user_func($func, $m);
}
}
function echoInput()
{
global $HTTP_RAW_POST_DATA;
// a debugging routine: just echos back the input
// packet as a string value
$r=new xmlrpcresp;
$r->xv=new xmlrpcval( "'Aha said I: '" . $HTTP_RAW_POST_DATA, 'string');
print $r->serialize();
}
}
?>

View File

@ -0,0 +1,55 @@
#!/usr/bin/python
# $Id: xr_cli_pok.py,v 1.1 2004/07/23 00:22:13 tomas Exp $
from xmlrpclib import *
import sys
if len(sys.argv)<3:
print """
Usage: xr_cli_pok.py http://<server>/<path>/xmlrpc/alib_xr.php <command> <args>
commands and args:
test <teststring> [<sessin_id>]
login <username> <password>
logout <session_id>
"""
sys.exit(1)
elif sys.argv[2]=="test":
if len(sys.argv)>3:
tstr=sys.argv[3]
if len(sys.argv)>4:
sessid=sys.argv[4]
else:
sessid=''
path=sys.argv[1]
server = Server(path)
try:
r = server.alib.xrTest(tstr, sessid)
print r
except Error, v:
print "XML-RPC Error:",v
elif sys.argv[2]=="login":
login=sys.argv[3]
passwd=sys.argv[4]
path=sys.argv[1]
server = Server(path)
try:
r = server.alib.login(login, passwd)
print r
except Error, v:
print "XML-RPC Error:",v
elif sys.argv[2]=="logout":
sessid=sys.argv[3]
path=sys.argv[1]
server = Server(path)
try:
r = server.alib.logout(sessid)
print r
except Error, v:
print "XML-RPC Error:",v
else:
print "Unknown command: "+sys.argv[2]
sys.exit(1)

View File

@ -0,0 +1,84 @@
<?php
// $Id: xr_cli_test.php,v 1.1 2004/07/23 00:22:13 tomas Exp $
include("xmlrpc.inc");
$host = "localhost";
$port = 80;
$serverscript = dirname($_SERVER['PHP_SELF'])."/alib_xr.php";
$log = '';
$ak = $_REQUEST['ak'];
$sessid = $_REQUEST['sessid'];
switch($ak){
case"test":
$f=new xmlrpcmsg('alib.xrTest',
array(new xmlrpcval($_REQUEST['str'], "string"),
new xmlrpcval($_REQUEST['sessid'], "string")));
break;
case"login":
$f=new xmlrpcmsg('alib.login', array(new xmlrpcval($_REQUEST['login'], "string"),
new xmlrpcval($_REQUEST['pass'], "string")));
break;
case"logout":
$f=new xmlrpcmsg('alib.logout', array(new xmlrpcval($_REQUEST['sessid'], "string")));
break;
}
switch($ak){
case"test":
case"login":
case"logout":
$c=new xmlrpc_client($serverscript, $host, $port);
#$c->setDebug(1);
$r=$c->send($f);
if (!($r->faultCode()>0)) {
$v=$r->value();
$log = $v->serialize();
if($ak=='test')
{ $log = split('_',$log); $log="{$log[0]}\nusername: {$log[1]}\ntoken: {$log[2]}"; }
if($ak=='login') $sessid = $v->scalarval();
if($ak=='logout') $sessid = '';
} else {
$log = "Fault:\n Code: ".$r->faultCode()."\nReason:'".$r->faultString()."'<BR>\n";
}
break;
}
?>
<html><head>
<title>Alib XMLRPC test client</title>
</head><body>
<h2>Alib XMLRPC test client</h2>
XMLRPC server: <b><?="http://$host:$port$serverscript"?></b><br>
<?=($log?'<h3>Output:</h3>':'')?>
<pre style="background-color:#ddd"><?=$log?></pre>
<hr>
<h3>test</h3>
flip teststring to uppercase and print username and session token<br>
<form method="post">
test string: <input type="text" name="str" value="abCDef"><br>
token: <input type="text" name="sessid" value="<?=$sessid?>" size="34"><br>
<input type="hidden" name="ak" value="test">
<input type="submit" value="Test">
</form>
<hr>
<h3>login</h3>
<form method="post">
username: <input type="text" name="login" value="test1"><br>
password: <input type="password" name="pass" value="a"><br>
<input type="hidden" name="ak" value="login">
<input type="submit" value="Login">
</form>
<hr>
<h3>logout</h3>
<form method="post">
token: <input type="text" name="sessid" value="<?=$sessid?>" size="34"><br>
<input type="hidden" name="ak" value="logout">
<input type="submit" value="Logout">
</form>
<hr>
<a href="../">Back</a>
</body></html>