source: trunk/bin/acl.cli.php @ 349

Last change on this file since 349 was 334, checked in by quinn, 16 years ago

Fixed lots of misplings. I'm so embarrassed! ;P

  • Property svn:executable set to *
File size: 11.7 KB
RevLine 
[208]1#!/usr/bin/php
[171]2<?php
3/*
4* acl.cli.php
5* Code by Strangecode :: www.strangecode.com :: This document contains copyrighted information.
6* @author   Quinn Comendant <quinn@strangecode.com>
7* @version  1.0
8* @since    14 Jun 2006 23:10:45
9*/
10
11
12/********************************************************************
13* STARTUP
14********************************************************************/
15
[174]16$this_script = basename($_SERVER['argv'][0]);
17
[171]18// Give them a fighting chance. Show the help message. ;P
19if ($_SERVER['argc'] <= 1) {
20    help();
21}
22
23// Make sure necessary files exist.
24define('COMMON_BASE', realpath('.'));
25$db_quth_file = COMMON_BASE . '/global/db_auth.inc.php';
26if (!file_exists($db_quth_file)) {
[174]27    die(sprintf("%s error: the current directory must be common site directory (i.e. the parent directory of the document root) AND the global/db_auth.inc.php file must exist.\n", $this_script));
[171]28}
29
30if (fileowner($db_quth_file) != getmyuid()) {
[174]31    die(sprintf("%s error: you must execute this script as the owner of the web files.\n", $this_script));
[171]32}
33
34// Set include path.
35ini_set('include_path', get_include_path()
36    . PATH_SEPARATOR . COMMON_BASE
37);
38
39
40/********************************************************************
41* CONFIG
42********************************************************************/
43
44// Include core libraries.
45require_once 'codebase/lib/App.inc.php';
46require_once 'codebase/lib/Utilities.inc.php';
47
48$app =& App::getInstance('module_maker');
49$app->setParam(array(
50    'site_name' => 'ACL cli',
51    'site_email' => 'codebase@strangecode.com',
52    'enable_session' => false,
53    'enable_db' => true,
54    'db_always_debug' => false,
55    'db_debug' => true,
56    'db_die_on_failure' => true,
57    'display_errors' => true,
58    'error_reporting' => E_ALL,
[174]59    'log_file_priority' => LOG_INFO,
60    'log_screen_priority' => LOG_ERR,
[171]61    'log_directory' => COMMON_BASE . '/log',
62    'log_filename' => 'site_log',
63));
64require_once 'global/db_auth.inc.php';
65
66// Start application-based functionality: database, session, environment, ini setup, etc.
67// Most configuration parameters must be set before starting the App.
68$app->start();
69
70// Global DB object. Automatically pre-configured by $app->start().
71$db =& DB::getInstance();
72
73// ACL!
74require_once 'codebase/lib/ACL.inc.php';
75$acl =& ACL::getInstance();
[173]76$acl->setParam(array('create_table' => false));
[171]77
78
79/********************************************************************
80* MAIN
81********************************************************************/
82
83$op = $_SERVER['argv'][1];
84switch ($op) {
85case 'list' :
[174]86    $type = isset($_SERVER['argv'][2]) ? $_SERVER['argv'][2] : null;
87    switch ($type) {
88    case 'aro' :
89    case 'aco' :
90    case 'axo' :
91        listObjects('root', $type);
92        break;
93    case 'all' :
94        listObjects('root', 'aro');                               
95        listObjects('root', 'aco');                               
96        listObjects('root', 'axo');
97        break;
98    case 'perms' :
99        default :
100        listPerms();
101        break;
102    }
103    break;
[171]104
105case 'addaro' :
106case 'addaco' :
107case 'addaxo' :
108    $object = isset($_SERVER['argv'][2]) ? $_SERVER['argv'][2] : null;
109    $parent = isset($_SERVER['argv'][3]) ? $_SERVER['argv'][3] : null;
110    if (!isset($object)) {
111        echo "'add*' commands require at least one argument. Try 'help' if you are lost.\n";
[175]112        break;
[171]113    }
114    echo $acl->add($object, $parent, str_replace('add', '', $op)) ? "Ok\n" : "Error!\n";
115    break;
116
[174]117case 'mvaro' :
118case 'mvaco' :
119case 'mvaxo' :
120    $object = isset($_SERVER['argv'][2]) ? $_SERVER['argv'][2] : null;
121    $parent = isset($_SERVER['argv'][3]) ? $_SERVER['argv'][3] : null;
122    if (!isset($object)) {
123        echo "'mv*' commands require at least one argument. Try 'help' if you are lost.\n";
[175]124        break;
[174]125    }
126    echo $acl->move($object, $parent, str_replace('mv', '', $op)) ? "Ok\n" : "Error!\n";
127    break;
128
[171]129case 'rmaro' :
130case 'rmaco' :
131case 'rmaxo' :
132    $object = isset($_SERVER['argv'][2]) ? $_SERVER['argv'][2] : null;
133    if (!isset($object)) {
134        echo "'add*' commands require at least one argument. Try 'help' if you are lost.\n";
[175]135        break;
[171]136    }
137    echo $acl->remove($object, str_replace('rm', '', $op)) ? "Ok\n" : "Error!\n";
138    break;
139
[173]140case 'initdb' :
[172]141    echo $acl->initDB(true) ? "Ok\n" : "Error!\n";
142    break;
143
[171]144case 'grant' :
145    $aro = isset($_SERVER['argv'][2]) ? $_SERVER['argv'][2] : null;
146    $aco = isset($_SERVER['argv'][3]) ? $_SERVER['argv'][3] : null;
147    $axo = isset($_SERVER['argv'][4]) ? $_SERVER['argv'][4] : null;
148    if (!isset($aro)) {
149        echo "'grant' command require at least one argument. Try 'help' if you are lost.\n";
[175]150        break;
[171]151    }
152    echo $acl->grant($aro, $aco, $axo) ? "Ok\n" : "Error!\n";
153    break;
154
155case 'revoke' :
156    $aro = isset($_SERVER['argv'][2]) ? $_SERVER['argv'][2] : null;
157    $aco = isset($_SERVER['argv'][3]) ? $_SERVER['argv'][3] : null;
158    $axo = isset($_SERVER['argv'][4]) ? $_SERVER['argv'][4] : null;
159    if (!isset($aro)) {
160        echo "'revoke' command require at least one argument. Try 'help' if you are lost.\n";
[175]161        break;
[171]162    }
163    echo $acl->revoke($aro, $aco, $axo) ? "Ok\n" : "Error!\n";
164    break;
165
[175]166case 'delete' :
167    $aro = isset($_SERVER['argv'][2]) && 'null' != $_SERVER['argv'][2] ? $_SERVER['argv'][2] : null;
168    $aco = isset($_SERVER['argv'][3]) && 'null' != $_SERVER['argv'][3] ? $_SERVER['argv'][3] : null;
169    $axo = isset($_SERVER['argv'][4]) && 'null' != $_SERVER['argv'][4] ? $_SERVER['argv'][4] : null;
170    if (!isset($_SERVER['argv'][2]) || !isset($_SERVER['argv'][3]) || !isset($_SERVER['argv'][4])) {
171        echo "'delete' command require all three arguments to be specified. Try 'help' if you are lost.\n";
172        break;
173    }
174    echo $acl->delete($aro, $aco, $axo) ? "Ok\n" : "Error!\n";
175    break;
176
[171]177case 'check' :
178    $aro = isset($_SERVER['argv'][2]) ? $_SERVER['argv'][2] : null;
179    $aco = isset($_SERVER['argv'][3]) ? $_SERVER['argv'][3] : null;
180    $axo = isset($_SERVER['argv'][4]) ? $_SERVER['argv'][4] : null;
181    if (!isset($aro)) {
182        echo "'check' command require at least one argument. Try 'help' if you are lost.\n";
[175]183        break;
[171]184    }
185    echo $acl->check($aro, $aco, $axo) ? "allow\n" : "deny\n";
186    break;
187
188case 'help' :
189    help();
190    break;
191
192default :
193    echo "'$op' is not an understood command. Try 'help' if you are lost.\n";
194    break;
195}
196
197
198/********************************************************************
199* FUNCTIONS
200********************************************************************/
201
202function help()
203{
[174]204    global $this_script;
205
[171]206    ?>
207Access Control List command line tool.
208
209This script must be run in the common site directory (i.e. the parent
210directory of the document root). DB credentials are retrieved from:
211global/db_auth.inc.php so this file must exist. Further more this script
212must be executed as the owner of the db_auth.inc.php file.
213
214Three types of objects are managed by this interface: ARO - Access
[174]215Request Objects, ACO - Access Control Objects, and AXO - Access Xtra
[171]216Objects. These are most often used as a USER -> ACTION -> OBJECT model,
217but can just as easily be SPICES -> CUISINES -> DISHES A privilege is
218allowed if a user (ARO) can perform an action (ACO) on something (AXO).
219For example, Bob can edit article 4. If the AXO if omitted, this becomes
220"Bob can edit" (period).
221
[334]222Each access object is stored as a node in hierarchical tree structures. A
223permission granted to a node is applied to all its children. If a child
[171]224node is specified a different permission that is more specific that
[334]225anything on the branch it will take precedence. If no permission is
[171]226specified, root is used for that object. Root, in this case, means
227"anything" since it is at the top of all branches.
228
[234]229Usage: <?php echo $this_script; ?> command [args]
[171]230
[234]231Where command is any of the following (with arguments):
[174]232   
233    initdb
234    list [aro | aco | axo | all | perms]
[234]235    check aro [aco] [axo]
236    addaro aro [parent]
237    addaco aco [parent]
238    addaxo axo [parent]
239    mvaro aro [parent]
240    mvaco aco [parent]
241    mvaxo axo [parent]
242    rmaro aro
243    rmaco aco
244    rmaxo axo
245    grant aro [aco] [axo]
246    revoke aro [aco] [axo]
247    delete [aro] [aco] [axo]
[175]248   
[171]249
[174]250For the add*, mv*, grant, and revoke commands if any of the optional
[175]251args are not provided, 'root' is assumed. For the delete command
[334]252'null' is considered a wild-card to delete all objects of that type.
[171]253
[175]254
[171]255Strangecode :: www.strangecode.com
256<?php
257    die;
258}
259
260
[174]261/*
262* Print the tree structure of a specified table (aro_tbl, aco_tbl, or axo_tbl).
263*
264* @access   public
265* @param    string $root Root node from which to begin calculating.
266* @param    string $type Table to call, one of: aro, aco, or axo.
267* @return   bool Returns false on error.
268* @author   Quinn Comendant <quinn@strangecode.com>
269* @version  1.0
270* @since    17 Jun 2006 23:41:22
271*/
272function listObjects($root, $type)
[171]273{
274    $app =& App::getInstance();
275    $db =& DB::getInstance();
[174]276    global $this_script;
[171]277   
[174]278    echo "\n";
279
[171]280    switch ($type) {
281    case 'aro' :
282        $tbl = 'aro_tbl';
[174]283        printf("%-35s %-5s %-5s %s\n", 'Request objects', 'lft', 'rgt', 'Added');
[171]284        break;
285    case 'aco' :
286        $tbl = 'aco_tbl';
[174]287        printf("%-35s %-5s %-5s %s\n", 'Control objects', 'lft', 'rgt', 'Added');
[171]288        break;
289    case 'axo' :
290        $tbl = 'axo_tbl';
[174]291        printf("%-35s %-5s %-5s %s\n", 'Xtra objects', 'lft', 'rgt', 'Added');
[171]292        break;
293    default :
294        $app->logMsg(sprintf('Invalid access object type: %s', $type), LOG_ERR, __FILE__, __LINE__);
295        return false;
296        break;
297    }
[174]298
299    echo "-----------------------------------------------------------\n";
300
[171]301    // Retrieve the left and right value of the $root node.
302    $qid = $db->query("SELECT lft, rgt FROM $tbl WHERE name = '" . $db->escapeString($root) . "'");
303    list($lft, $rgt) = mysql_fetch_row($qid);
304   
305    $depth = array();
306   
307    // Retrieve all descendants of the root node
308    $qid = $db->query("SELECT name, lft, rgt, added_datetime FROM $tbl WHERE lft BETWEEN $lft AND $rgt ORDER BY lft ASC");
309    while (list($name, $lft, $rgt, $added_datetime) = mysql_fetch_row($qid)) {
310        // If the last element of $depth is less than the current rgt it means we finished with a set of children nodes.
311        while (sizeof($depth) > 0 && end($depth) < $rgt) {
312            array_pop($depth);
313        }
314   
315        // Display indented node title.
[174]316        printf("%-35s %-5s %-5s %s\n", str_repeat('    ', sizeof($depth)) . $name, $lft, $rgt, date($app->getParam('date_format'), strtotime($added_datetime)));
[171]317       
318        // Add this node to the stack.
319        $depth[] = $rgt;
320    }
321}
322
[174]323/*
324* List all entries in the acl_tbl.
325*
326* @access   public
327* @author   Quinn Comendant <quinn@strangecode.com>
328* @version  1.0
329* @since    17 Jun 2006 15:11:53
330*/
331function listPerms()
332{
333    $app =& App::getInstance();
334    $db =& DB::getInstance();
335    global $this_script;
336   
[334]337    // Retrieve access value from db.
[174]338    $qid = $db->query("
339        SELECT aro_tbl.name AS aro, aco_tbl.name AS aco, axo_tbl.name AS axo, acl_tbl.access, acl_tbl.added_datetime
340        FROM acl_tbl
341        LEFT JOIN aro_tbl ON (acl_tbl.aro_id = aro_tbl.aro_id)
342        LEFT JOIN aco_tbl ON (acl_tbl.aco_id = aco_tbl.aco_id)
343        LEFT JOIN axo_tbl ON (acl_tbl.axo_id = axo_tbl.axo_id)
[208]344        ORDER BY aro_tbl.lft ASC, aco_tbl.lft ASC, axo_tbl.lft ASC
[174]345    ");
346    echo "\n";
347    printf("%-25s %-25s %-25s %-6s %-10s\n", 'Request objects', 'Control objects', 'Xtra objects', '', 'Added');
348    echo "------------------------------------------------------------------------------------------------\n";
349    while ($p = mysql_fetch_assoc($qid)) {
350        printf("%-25s %-25s %-25s \033[0;%sm%-6s\033[0m %-10s\n", $p['aro'], $p['aco'], $p['axo'], ('allow' == $p['access'] ? '32' : '31'), $p['access'], date($app->getParam('date_format'), strtotime($p['added_datetime'])));
351    }   
352}
[171]353
[174]354
[208]355?>
Note: See TracBrowser for help on using the repository browser.