[532] | 1 | #!/usr/bin/env php |
---|
[171] | 2 | <?php |
---|
[362] | 3 | /** |
---|
| 4 | * The Strangecode Codebase - a general application development framework for PHP |
---|
| 5 | * For details visit the project site: <http://trac.strangecode.com/codebase/> |
---|
[396] | 6 | * Copyright 2001-2012 Strangecode, LLC |
---|
[468] | 7 | * |
---|
[362] | 8 | * This file is part of The Strangecode Codebase. |
---|
| 9 | * |
---|
| 10 | * The Strangecode Codebase is free software: you can redistribute it and/or |
---|
| 11 | * modify it under the terms of the GNU General Public License as published by the |
---|
| 12 | * Free Software Foundation, either version 3 of the License, or (at your option) |
---|
| 13 | * any later version. |
---|
[468] | 14 | * |
---|
[362] | 15 | * The Strangecode Codebase is distributed in the hope that it will be useful, but |
---|
| 16 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
---|
| 17 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
---|
| 18 | * details. |
---|
[468] | 19 | * |
---|
[362] | 20 | * You should have received a copy of the GNU General Public License along with |
---|
| 21 | * The Strangecode Codebase. If not, see <http://www.gnu.org/licenses/>. |
---|
| 22 | */ |
---|
| 23 | |
---|
[171] | 24 | /* |
---|
| 25 | * acl.cli.php |
---|
[362] | 26 | * |
---|
[171] | 27 | * @author Quinn Comendant <quinn@strangecode.com> |
---|
[532] | 28 | * @version 1.1 |
---|
[171] | 29 | * @since 14 Jun 2006 23:10:45 |
---|
| 30 | */ |
---|
| 31 | |
---|
| 32 | /******************************************************************** |
---|
[532] | 33 | * CONFIG |
---|
[171] | 34 | ********************************************************************/ |
---|
| 35 | |
---|
[532] | 36 | require_once dirname(__FILE__) . '/_config.inc.php'; |
---|
[174] | 37 | |
---|
[171] | 38 | // Give them a fighting chance. Show the help message. ;P |
---|
| 39 | if ($_SERVER['argc'] <= 1) { |
---|
| 40 | help(); |
---|
| 41 | } |
---|
| 42 | |
---|
| 43 | // ACL! |
---|
[533] | 44 | require_once CODEBASE_PATH . '/lib/ACL.inc.php'; |
---|
[171] | 45 | $acl =& ACL::getInstance(); |
---|
[534] | 46 | $acl->setParam(array( |
---|
| 47 | 'create_table' => false, |
---|
| 48 | 'enable_cache' => false, |
---|
| 49 | )); |
---|
[171] | 50 | |
---|
| 51 | |
---|
| 52 | /******************************************************************** |
---|
| 53 | * MAIN |
---|
| 54 | ********************************************************************/ |
---|
| 55 | |
---|
[484] | 56 | if (!$db->tableExists('acl_tbl')) { |
---|
| 57 | printf("This project doesn't appear to be using ACL (there is no acl_tbl in the %s DB).\n", $app->getParam('db_name')); |
---|
[502] | 58 | $app->stop(); |
---|
[484] | 59 | die; |
---|
| 60 | } |
---|
| 61 | |
---|
[171] | 62 | $op = $_SERVER['argv'][1]; |
---|
| 63 | switch ($op) { |
---|
| 64 | case 'list' : |
---|
[174] | 65 | $type = isset($_SERVER['argv'][2]) ? $_SERVER['argv'][2] : null; |
---|
| 66 | switch ($type) { |
---|
| 67 | case 'aro' : |
---|
| 68 | case 'aco' : |
---|
| 69 | case 'axo' : |
---|
[534] | 70 | listObjects($type); |
---|
[174] | 71 | break; |
---|
| 72 | case 'all' : |
---|
[534] | 73 | listObjects('aro'); |
---|
| 74 | listObjects('aco'); |
---|
| 75 | listObjects('axo'); |
---|
[174] | 76 | break; |
---|
| 77 | case 'perms' : |
---|
[415] | 78 | default : |
---|
[174] | 79 | listPerms(); |
---|
| 80 | break; |
---|
| 81 | } |
---|
| 82 | break; |
---|
[171] | 83 | |
---|
| 84 | case 'addaro' : |
---|
| 85 | case 'addaco' : |
---|
| 86 | case 'addaxo' : |
---|
| 87 | $object = isset($_SERVER['argv'][2]) ? $_SERVER['argv'][2] : null; |
---|
| 88 | $parent = isset($_SERVER['argv'][3]) ? $_SERVER['argv'][3] : null; |
---|
| 89 | if (!isset($object)) { |
---|
| 90 | echo "'add*' commands require at least one argument. Try 'help' if you are lost.\n"; |
---|
[175] | 91 | break; |
---|
[171] | 92 | } |
---|
| 93 | echo $acl->add($object, $parent, str_replace('add', '', $op)) ? "Ok\n" : "Error!\n"; |
---|
| 94 | break; |
---|
| 95 | |
---|
[174] | 96 | case 'mvaro' : |
---|
| 97 | case 'mvaco' : |
---|
| 98 | case 'mvaxo' : |
---|
| 99 | $object = isset($_SERVER['argv'][2]) ? $_SERVER['argv'][2] : null; |
---|
| 100 | $parent = isset($_SERVER['argv'][3]) ? $_SERVER['argv'][3] : null; |
---|
| 101 | if (!isset($object)) { |
---|
| 102 | echo "'mv*' commands require at least one argument. Try 'help' if you are lost.\n"; |
---|
[175] | 103 | break; |
---|
[174] | 104 | } |
---|
| 105 | echo $acl->move($object, $parent, str_replace('mv', '', $op)) ? "Ok\n" : "Error!\n"; |
---|
| 106 | break; |
---|
| 107 | |
---|
[171] | 108 | case 'rmaro' : |
---|
| 109 | case 'rmaco' : |
---|
| 110 | case 'rmaxo' : |
---|
| 111 | $object = isset($_SERVER['argv'][2]) ? $_SERVER['argv'][2] : null; |
---|
| 112 | if (!isset($object)) { |
---|
| 113 | echo "'add*' commands require at least one argument. Try 'help' if you are lost.\n"; |
---|
[175] | 114 | break; |
---|
[171] | 115 | } |
---|
| 116 | echo $acl->remove($object, str_replace('rm', '', $op)) ? "Ok\n" : "Error!\n"; |
---|
| 117 | break; |
---|
| 118 | |
---|
[173] | 119 | case 'initdb' : |
---|
[172] | 120 | echo $acl->initDB(true) ? "Ok\n" : "Error!\n"; |
---|
| 121 | break; |
---|
| 122 | |
---|
[171] | 123 | case 'grant' : |
---|
| 124 | $aro = isset($_SERVER['argv'][2]) ? $_SERVER['argv'][2] : null; |
---|
| 125 | $aco = isset($_SERVER['argv'][3]) ? $_SERVER['argv'][3] : null; |
---|
| 126 | $axo = isset($_SERVER['argv'][4]) ? $_SERVER['argv'][4] : null; |
---|
| 127 | if (!isset($aro)) { |
---|
| 128 | echo "'grant' command require at least one argument. Try 'help' if you are lost.\n"; |
---|
[175] | 129 | break; |
---|
[171] | 130 | } |
---|
| 131 | echo $acl->grant($aro, $aco, $axo) ? "Ok\n" : "Error!\n"; |
---|
| 132 | break; |
---|
| 133 | |
---|
| 134 | case 'revoke' : |
---|
| 135 | $aro = isset($_SERVER['argv'][2]) ? $_SERVER['argv'][2] : null; |
---|
| 136 | $aco = isset($_SERVER['argv'][3]) ? $_SERVER['argv'][3] : null; |
---|
| 137 | $axo = isset($_SERVER['argv'][4]) ? $_SERVER['argv'][4] : null; |
---|
| 138 | if (!isset($aro)) { |
---|
| 139 | echo "'revoke' command require at least one argument. Try 'help' if you are lost.\n"; |
---|
[175] | 140 | break; |
---|
[171] | 141 | } |
---|
| 142 | echo $acl->revoke($aro, $aco, $axo) ? "Ok\n" : "Error!\n"; |
---|
| 143 | break; |
---|
| 144 | |
---|
[175] | 145 | case 'delete' : |
---|
| 146 | $aro = isset($_SERVER['argv'][2]) && 'null' != $_SERVER['argv'][2] ? $_SERVER['argv'][2] : null; |
---|
| 147 | $aco = isset($_SERVER['argv'][3]) && 'null' != $_SERVER['argv'][3] ? $_SERVER['argv'][3] : null; |
---|
| 148 | $axo = isset($_SERVER['argv'][4]) && 'null' != $_SERVER['argv'][4] ? $_SERVER['argv'][4] : null; |
---|
| 149 | if (!isset($_SERVER['argv'][2]) || !isset($_SERVER['argv'][3]) || !isset($_SERVER['argv'][4])) { |
---|
| 150 | echo "'delete' command require all three arguments to be specified. Try 'help' if you are lost.\n"; |
---|
| 151 | break; |
---|
| 152 | } |
---|
| 153 | echo $acl->delete($aro, $aco, $axo) ? "Ok\n" : "Error!\n"; |
---|
| 154 | break; |
---|
| 155 | |
---|
[171] | 156 | case 'check' : |
---|
| 157 | $aro = isset($_SERVER['argv'][2]) ? $_SERVER['argv'][2] : null; |
---|
| 158 | $aco = isset($_SERVER['argv'][3]) ? $_SERVER['argv'][3] : null; |
---|
| 159 | $axo = isset($_SERVER['argv'][4]) ? $_SERVER['argv'][4] : null; |
---|
| 160 | if (!isset($aro)) { |
---|
| 161 | echo "'check' command require at least one argument. Try 'help' if you are lost.\n"; |
---|
[175] | 162 | break; |
---|
[171] | 163 | } |
---|
| 164 | echo $acl->check($aro, $aco, $axo) ? "allow\n" : "deny\n"; |
---|
| 165 | break; |
---|
| 166 | |
---|
| 167 | case 'help' : |
---|
| 168 | help(); |
---|
| 169 | break; |
---|
| 170 | |
---|
| 171 | default : |
---|
| 172 | echo "'$op' is not an understood command. Try 'help' if you are lost.\n"; |
---|
| 173 | break; |
---|
| 174 | } |
---|
| 175 | |
---|
[502] | 176 | $app->stop(); |
---|
| 177 | die; |
---|
[171] | 178 | |
---|
[502] | 179 | |
---|
[171] | 180 | /******************************************************************** |
---|
| 181 | * FUNCTIONS |
---|
| 182 | ********************************************************************/ |
---|
| 183 | |
---|
| 184 | function help() |
---|
| 185 | { |
---|
[533] | 186 | global $cli_executed; |
---|
[174] | 187 | |
---|
[171] | 188 | ?> |
---|
| 189 | Access Control List command line tool. |
---|
| 190 | |
---|
| 191 | This script must be run in the common site directory (i.e. the parent |
---|
| 192 | directory of the document root). DB credentials are retrieved from: |
---|
[398] | 193 | global/db_auth.inc.php so this file must exist. Furthermore this script |
---|
[171] | 194 | must be executed as the owner of the db_auth.inc.php file. |
---|
| 195 | |
---|
[482] | 196 | Three types of objects are managed by this interface: |
---|
| 197 | |
---|
| 198 | ARO - Access Request Objects |
---|
| 199 | ACO - Access Control Objects |
---|
| 200 | AXO - Access Xtra Objects |
---|
| 201 | |
---|
| 202 | These are most often used as a USER -> ACTION -> OBJECT model, |
---|
[398] | 203 | but could just as easily be SPICES -> CUISINES -> DISHES. A privilege is |
---|
[171] | 204 | allowed if a user (ARO) can perform an action (ACO) on something (AXO). |
---|
[468] | 205 | For example, with an `ARO->ACO->AXO` of `Bob->edit->4`, Bob can edit article 4. |
---|
| 206 | If the AXO were omitted (i.e. just `Bob->edit`), this becomes "Bob can edit" |
---|
[398] | 207 | (he can edit any object). |
---|
[171] | 208 | |
---|
[484] | 209 | Each access object is stored as a node in hierarchical tree structure. |
---|
[398] | 210 | A permission granted to a node is applied to all its children. If a child |
---|
[484] | 211 | node is specified with a permission more specific than its ancestors, the |
---|
| 212 | child will take precedence. If no permission is specified, root is used, |
---|
| 213 | implying access to any object of that type. |
---|
[171] | 214 | |
---|
[533] | 215 | Usage: <?php echo $cli_executed; ?> command [args] |
---|
[171] | 216 | |
---|
[234] | 217 | Where command is any of the following (with arguments): |
---|
[468] | 218 | |
---|
[174] | 219 | initdb |
---|
| 220 | list [aro | aco | axo | all | perms] |
---|
[234] | 221 | check aro [aco] [axo] |
---|
| 222 | addaro aro [parent] |
---|
| 223 | addaco aco [parent] |
---|
| 224 | addaxo axo [parent] |
---|
| 225 | mvaro aro [parent] |
---|
| 226 | mvaco aco [parent] |
---|
| 227 | mvaxo axo [parent] |
---|
| 228 | rmaro aro |
---|
| 229 | rmaco aco |
---|
| 230 | rmaxo axo |
---|
| 231 | grant aro [aco] [axo] |
---|
| 232 | revoke aro [aco] [axo] |
---|
[482] | 233 | delete aro aco axo |
---|
[171] | 234 | |
---|
[468] | 235 | For the add*, mv*, grant, and revoke commands if any of the optional |
---|
[482] | 236 | args are not provided, 'root' is assumed. The delete command requires |
---|
| 237 | all object types to be specified; Passing the string 'null' will cause |
---|
| 238 | all matches in that column to be deleted. run with 'grants' to view what |
---|
| 239 | can be deleted. |
---|
[171] | 240 | <?php |
---|
| 241 | die; |
---|
| 242 | } |
---|
| 243 | |
---|
| 244 | |
---|
[174] | 245 | /* |
---|
| 246 | * Print the tree structure of a specified table (aro_tbl, aco_tbl, or axo_tbl). |
---|
| 247 | * |
---|
| 248 | * @access public |
---|
[534] | 249 | * @param string $type Table to call, one of: aro, aco, or axo. |
---|
[174] | 250 | * @param string $root Root node from which to begin calculating. |
---|
| 251 | * @return bool Returns false on error. |
---|
| 252 | * @author Quinn Comendant <quinn@strangecode.com> |
---|
| 253 | * @version 1.0 |
---|
| 254 | * @since 17 Jun 2006 23:41:22 |
---|
| 255 | */ |
---|
[534] | 256 | function listObjects($type, $root=null) |
---|
[171] | 257 | { |
---|
[534] | 258 | global $acl; |
---|
| 259 | |
---|
[171] | 260 | $app =& App::getInstance(); |
---|
| 261 | $db =& DB::getInstance(); |
---|
[468] | 262 | |
---|
[171] | 263 | switch ($type) { |
---|
| 264 | case 'aro' : |
---|
[534] | 265 | printf("\n%-45s %s\n", 'Request objects', 'Added'); |
---|
[171] | 266 | break; |
---|
| 267 | case 'aco' : |
---|
[534] | 268 | printf("\n%-45s %s\n", 'Control objects', 'Added'); |
---|
[171] | 269 | break; |
---|
| 270 | case 'axo' : |
---|
[534] | 271 | printf("\n%-45s %s\n", 'Xtra objects', 'Added'); |
---|
[171] | 272 | break; |
---|
| 273 | default : |
---|
| 274 | $app->logMsg(sprintf('Invalid access object type: %s', $type), LOG_ERR, __FILE__, __LINE__); |
---|
| 275 | return false; |
---|
| 276 | } |
---|
[174] | 277 | |
---|
[502] | 278 | echo "---------------------------------------------------------------------\n"; |
---|
[174] | 279 | |
---|
[534] | 280 | foreach ($acl->getList($type, $root) as $o) { |
---|
[171] | 281 | // Display indented node title. |
---|
[534] | 282 | printf("%-45s %s\n", str_repeat(' ', $o['depth']) . $o['name'], date($app->getParam('date_format') . ' ' . $app->getParam('time_format'), strtotime($o['added_datetime']))); |
---|
| 283 | } |
---|
[468] | 284 | |
---|
[534] | 285 | echo "\n"; |
---|
[171] | 286 | } |
---|
| 287 | |
---|
[174] | 288 | /* |
---|
| 289 | * List all entries in the acl_tbl. |
---|
| 290 | * |
---|
| 291 | * @access public |
---|
| 292 | * @author Quinn Comendant <quinn@strangecode.com> |
---|
| 293 | * @version 1.0 |
---|
| 294 | * @since 17 Jun 2006 15:11:53 |
---|
| 295 | */ |
---|
| 296 | function listPerms() |
---|
| 297 | { |
---|
| 298 | $app =& App::getInstance(); |
---|
| 299 | $db =& DB::getInstance(); |
---|
[468] | 300 | |
---|
[334] | 301 | // Retrieve access value from db. |
---|
[174] | 302 | $qid = $db->query(" |
---|
| 303 | SELECT aro_tbl.name AS aro, aco_tbl.name AS aco, axo_tbl.name AS axo, acl_tbl.access, acl_tbl.added_datetime |
---|
| 304 | FROM acl_tbl |
---|
| 305 | LEFT JOIN aro_tbl ON (acl_tbl.aro_id = aro_tbl.aro_id) |
---|
| 306 | LEFT JOIN aco_tbl ON (acl_tbl.aco_id = aco_tbl.aco_id) |
---|
| 307 | LEFT JOIN axo_tbl ON (acl_tbl.axo_id = axo_tbl.axo_id) |
---|
[208] | 308 | ORDER BY aro_tbl.lft ASC, aco_tbl.lft ASC, axo_tbl.lft ASC |
---|
[174] | 309 | "); |
---|
| 310 | echo "\n"; |
---|
[502] | 311 | printf("%-25s %-25s %-25s %-6s %-10s\n", 'Request objects', 'Control objects', 'Xtra objects', 'Grant', 'Added'); |
---|
[174] | 312 | echo "------------------------------------------------------------------------------------------------\n"; |
---|
| 313 | while ($p = mysql_fetch_assoc($qid)) { |
---|
| 314 | 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']))); |
---|
[468] | 315 | } |
---|
[174] | 316 | } |
---|
[171] | 317 | |
---|
[174] | 318 | |
---|