acl.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548
  1. <?php
  2. /* SVN FILE: $Id$ */
  3. /**
  4. * Short description for file.
  5. *
  6. * Long description for file
  7. *
  8. * PHP versions 4 and 5
  9. *
  10. * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
  11. * Copyright 2005-2007, Cake Software Foundation, Inc.
  12. * 1785 E. Sahara Avenue, Suite 490-204
  13. * Las Vegas, Nevada 89104
  14. *
  15. * Licensed under The MIT License
  16. * Redistributions of files must retain the above copyright notice.
  17. *
  18. * @filesource
  19. * @copyright Copyright 2005-2007, Cake Software Foundation, Inc.
  20. * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
  21. * @package cake
  22. * @subpackage cake.cake.scripts
  23. * @since CakePHP(tm) v 0.10.0.1232
  24. * @version $Revision$
  25. * @modifiedby $LastChangedBy$
  26. * @lastmodified $Date$
  27. * @license http://www.opensource.org/licenses/mit-license.php The MIT License
  28. */
  29. uses ('controller'.DS.'components'.DS.'acl', 'model'.DS.'db_acl');
  30. /**
  31. * @package cake
  32. * @subpackage cake.cake.scripts
  33. */
  34. class AclScript extends CakeScript {
  35. /**
  36. * Enter description here...
  37. *
  38. * @var unknown_type
  39. */
  40. var $acl;
  41. /**
  42. * Enter description here...
  43. *
  44. * @var unknown_type
  45. */
  46. var $args;
  47. /**
  48. * Enter description here...
  49. *
  50. * @var unknown_type
  51. */
  52. var $dataSource = 'default';
  53. /**
  54. * override intialize of the CakeScript
  55. *
  56. */
  57. function initialize () {
  58. $this->dataSource = 'default';
  59. if (isset($this->params['datasource'])) {
  60. $this->dataSource = $this->params['datasource'];
  61. }
  62. if (ACL_CLASSNAME != 'DB_ACL') {
  63. $out = "--------------------------------------------------\n";
  64. $out .= "Error: Your current Cake configuration is set to \n";
  65. $out .= "an ACL implementation other than DB. Please change \n";
  66. $out .= "your core config to reflect your decision to use \n";
  67. $out .= "DB_ACL before attempting to use this script.\n";
  68. $out .= "--------------------------------------------------\n";
  69. $out .= "Current ACL Classname: " . ACL_CLASSNAME . "\n";
  70. $out .= "--------------------------------------------------\n";
  71. $this->err($out);
  72. exit();
  73. }
  74. //$this->Dispatch->shiftArgs();
  75. if($this->command && !in_array($this->command, array('help'))) {
  76. if(!file_exists(CONFIGS.'database.php')) {
  77. $this->out('');
  78. $this->out('Your database configuration was not found.');
  79. $this->out('Take a moment to create one:');
  80. $this->__doDbConfig();
  81. }
  82. require_once (CONFIGS.'database.php');
  83. if(!in_array($this->command, array('initdb'))) {
  84. $this->Acl = new AclComponent();
  85. $this->db =& ConnectionManager::getDataSource($this->dataSource);
  86. }
  87. }
  88. }
  89. /**
  90. * Enter description here...
  91. *
  92. */
  93. function create() {
  94. $this->_checkArgs(4, 'create');
  95. $this->checkNodeType();
  96. extract($this->__dataVars());
  97. if (preg_match('/^([\w]+)\.(.*)$/', $this->args[2], $matches)) {
  98. pr($matches);
  99. die();
  100. } else {
  101. $parent = $this->args[2];
  102. }
  103. /*if (!empty($parent)) {
  104. $parent = $this->{$class}->node($model, $parent);
  105. } else {
  106. $parent = null;
  107. }*/
  108. $this->Acl->{$class}->create();
  109. if($this->Acl->{$class}->save(array(
  110. 'parent_id' => Set::extract($parent, "0.{$class}.id"),
  111. 'model' => null,
  112. 'foreign_key' => null
  113. ))) {
  114. $this->displayError("Parent Node Not Found", "There was an error creating the ".$class.", probably couldn't find the parent node.\n If you wish to create a new root node, specify the <parent_id> as '0'.");
  115. }
  116. $this->out("New $class '".$this->args[3]."' created.\n\n");
  117. }
  118. /**
  119. * Enter description here...
  120. *
  121. */
  122. function delete() {
  123. $this->_checkArgs(2, 'delete');
  124. $this->checkNodeType();
  125. extract($this->__dataVars());
  126. if(!$this->Acl->{$class}->delete($this->args[1])) {
  127. $this->displayError("Node Not Deleted", "There was an error deleting the ".$class.". Check that the node exists.\n");
  128. }
  129. $this->out("{$class} deleted.\n\n");
  130. }
  131. /**
  132. * Enter description here...
  133. *
  134. */
  135. function setParent() {
  136. $this->_checkArgs(3, 'setParent');
  137. $this->checkNodeType();
  138. extract($this->__dataVars());
  139. if (!$this->Acl->{$class}->setParent($this->args[2], $this->args[1])){
  140. $this->out("Error in setting new parent. Please make sure the parent node exists, and is not a descendant of the node specified.\n");
  141. } else {
  142. $this->out("Node parent set to ".$this->args[2]."\n\n");
  143. }
  144. }
  145. /**
  146. * Enter description here...
  147. *
  148. */
  149. function getPath() {
  150. $this->_checkArgs(2, 'getPath');
  151. $this->checkNodeType();
  152. extract($this->__dataVars());
  153. $id = (is_numeric($this->args[2])) ? intval($this->args[1]) : $this->args[1];
  154. $nodes = $this->Acl->{$class}->getPath($id);
  155. if (empty($nodes)) {
  156. $this->displayError("Supplied Node '".$this->args[1]."' not found", "No tree returned.");
  157. }
  158. for ($i = 0; $i < count($nodes); $i++) {
  159. $this->out(str_repeat(' ', $i) . "[" . $nodes[$i][$class]['id'] . "]" . $nodes[$i][$class]['alias'] . "\n");
  160. }
  161. }
  162. /**
  163. * Enter description here...
  164. *
  165. */
  166. function grant() {
  167. $this->_checkArgs(3, 'grant');
  168. //add existence checks for nodes involved
  169. $aro = (is_numeric($this->args[0])) ? intval($this->args[0]) : $this->args[0];
  170. $aco = (is_numeric($this->args[1])) ? intval($this->args[1]) : $this->args[1];
  171. $this->Acl->allow($aro, $aco, $this->args[2]);
  172. $this->out("Permission granted.\n");
  173. }
  174. /**
  175. * Enter description here...
  176. *
  177. */
  178. function deny() {
  179. $this->_checkArgs(3, 'deny');
  180. //add existence checks for nodes involved
  181. $aro = (is_numeric($this->args[0])) ? intval($this->args[0]) : $this->args[0];
  182. $aco = (is_numeric($this->args[1])) ? intval($this->args[1]) : $this->args[1];
  183. $this->Acl->deny($aro, $aco, $this->args[2]);
  184. $this->out("Requested permission successfully denied.\n");
  185. }
  186. /**
  187. * Enter description here...
  188. *
  189. */
  190. function inherit() {
  191. $this->_checkArgs(3, 'inherit');
  192. $aro = (is_numeric($this->args[0])) ? intval($this->args[0]) : $this->args[0];
  193. $aco = (is_numeric($this->args[1])) ? intval($this->args[1]) : $this->args[1];
  194. $this->Acl->inherit($aro, $aco, $this->args[2]);
  195. $this->out("Requested permission successfully inherited.\n");
  196. }
  197. /**
  198. * Enter description here...
  199. *
  200. */
  201. function view() {
  202. $this->_checkArgs(1, 'view');
  203. $this->checkNodeType();
  204. extract($this->__dataVars());
  205. if (!is_null($this->args[1])) {
  206. $conditions = $this->Acl->{$class}->_resolveID($this->args[1]);
  207. } else {
  208. $conditions = null;
  209. }
  210. $nodes = $this->Acl->{$class}->findAll($conditions, null, 'lft ASC');
  211. if (empty($nodes)) {
  212. $this->displayError($this->args[1]." not found", "No tree returned.");
  213. }
  214. $right = array();
  215. $this->out($class . " tree:");
  216. $this->hr(true);
  217. for($i = 0; $i < count($nodes); $i++){
  218. if (count($right) > 0){
  219. while ($right[count($right)-1] < $nodes[$i][$class]['rght']){
  220. if ($right[count($right)-1]){
  221. array_pop($right);
  222. } else {
  223. break;
  224. }
  225. }
  226. }
  227. $this->out(str_repeat(' ',count($right)) . "[" . $nodes[$i][$class]['id'] . "]" . $nodes[$i][$class]['alias']."\n");
  228. $right[] = $nodes[$i][$class]['rght'];
  229. }
  230. $this->hr(true);
  231. }
  232. /**
  233. * Enter description here...
  234. *
  235. */
  236. function initdb() {
  237. $db =& ConnectionManager::getDataSource($this->dataSource);
  238. $this->out("Initializing Database...\n");
  239. $this->out("Creating access control objects table (acos)...\n");
  240. $sql = " CREATE TABLE ".$db->fullTableName('acos')." (
  241. ".$db->name('id')." ".$db->column($db->columns['primary_key']).",
  242. ".$db->name('parent_id')." ".$db->column($db->columns['integer'])." default NULL,
  243. ".$db->name('model')." ".$db->column($db->columns['string'])." default '' NOT NULL,
  244. ".$db->name('foreign_key')." ".$db->column($db->columns['integer'])." default NULL,
  245. ".$db->name('alias')." ".$db->column($db->columns['string'])." default '' NOT NULL,
  246. ".$db->name('lft')." ".$db->column($db->columns['integer'])." default NULL,
  247. ".$db->name('rght')." ".$db->column($db->columns['integer'])." default NULL,
  248. PRIMARY KEY (".$db->name('id').")
  249. )";
  250. if ($db->query($sql) === false) {
  251. die("Error: " . $db->lastError() . "\n\n");
  252. }
  253. $this->out("Creating access request objects table (aros)...\n");
  254. $sql2 = "CREATE TABLE ".$db->fullTableName('aros')." (
  255. ".$db->name('id')." ".$db->column($db->columns['primary_key']).",
  256. ".$db->name('parent_id')." ".$db->column($db->columns['integer'])." default NULL,
  257. ".$db->name('model')." ".$db->column($db->columns['string'])." default '' NOT NULL,
  258. ".$db->name('foreign_key')." ".$db->column($db->columns['integer'])." default NULL,
  259. ".$db->name('alias')." ".$db->column($db->columns['string'])." default '' NOT NULL,
  260. ".$db->name('lft')." ".$db->column($db->columns['integer'])." default NULL,
  261. ".$db->name('rght')." ".$db->column($db->columns['integer'])." default NULL,
  262. PRIMARY KEY (".$db->name('id').")
  263. )";
  264. if ($db->query($sql2) === false) {
  265. die("Error: " . $db->lastError() . "\n\n");
  266. }
  267. $this->out("Creating relationships table (aros_acos)...\n");
  268. $sql3 = "CREATE TABLE ".$db->fullTableName('aros_acos')." (
  269. ".$db->name('id')." ".$db->column($db->columns['primary_key']).",
  270. ".$db->name('aro_id')." ".$db->column($db->columns['integer'])." default NULL,
  271. ".$db->name('aco_id')." ".$db->column($db->columns['integer'])." default NULL,
  272. ".$db->name('_create')." ".$db->column($db->columns['integer'])." default '0' NOT NULL,
  273. ".$db->name('_read')." ".$db->column($db->columns['integer'])." default '0' NOT NULL,
  274. ".$db->name('_update')." ".$db->column($db->columns['integer'])." default '0' NOT NULL,
  275. ".$db->name('_delete')." ".$db->column($db->columns['integer'])." default '0' NOT NULL,
  276. PRIMARY KEY (".$db->name('id').")
  277. )";
  278. if ($db->query($sql3) === false) {
  279. die("Error: " . $db->lastError() . "\n\n");
  280. }
  281. $this->out("\nDone.\n");
  282. }
  283. /**
  284. * Enter description here...
  285. *
  286. */
  287. function help() {
  288. $out = "Usage: cake acl <command> <arg1> <arg2>...\n";
  289. $out .= "-----------------------------------------------\n";
  290. $out .= "Commands:\n";
  291. $out .= "\n";
  292. $out .= "\tcreate aro|aco <parent> <node>\n";
  293. $out .= "\t\tCreates a new ACL object <node> under the parent specified by <parent>, an id/alias.\n";
  294. $out .= "\t\tThe <parent> and <node> references can be in one of the following formats:\n";
  295. $out .= "\t\t\t- <model>.<id> - The node will be bound to a specific record of the given model\n";
  296. $out .= "\t\t\t- <alias> - The node will be given a string alias (or path, in the case of <parent>),\n";
  297. $out .= "\t\t\t i.e. 'John'. When used with <parent>, this takes the form of an alias path,\n";
  298. $out .= "\t\t\t i.e. <group>/<subgroup>/<parent>.\n";
  299. $out .= "\n";
  300. $out .= "\n";
  301. $out .= "\tdelete aro|aco <node>\n";
  302. $out .= "\t\tDeletes the ACL object with the given <node> reference (see 'create' for info on node references).\n";
  303. $out .= "\n";
  304. $out .= "\n";
  305. $out .= "\tsetParent aro|aco <node> <parent>\n";
  306. $out .= "\t\tMoves the ACL object specified by <node> beneath the parent ACL object specified by <parent>.\n";
  307. $out .= "\n";
  308. $out .= "\n";
  309. $out .= "\tgetPath aro|aco <node>\n";
  310. $out .= "\t\tReturns the path to the ACL object specified by <node>. This command is\n";
  311. $out .= "\t\tis useful in determining the inhertiance of permissions for a certain\n";
  312. $out .= "\t\tobject in the tree.\n";
  313. $out .= "\n";
  314. $out .= "\n";
  315. $out .= "\tgrant <aro_id> <aco_id> [<aco_action>]\n";
  316. $out .= "\t\tUse this command to grant ACL permissions. Once executed, the ARO\n";
  317. $out .= "\t\tspecified (and its children, if any) will have ALLOW access to the\n";
  318. $out .= "\t\tspecified ACO action (and the ACO's children, if any).\n";
  319. $out .= "\n";
  320. $out .= "\n";
  321. $out .= "\tdeny <aro_id> <aco_id> [<aco_action>]\n";
  322. $out .= "\t\tUse this command to deny ACL permissions. Once executed, the ARO\n";
  323. $out .= "\t\tspecified (and its children, if any) will have DENY access to the\n";
  324. $out .= "\t\tspecified ACO action (and the ACO's children, if any).\n";
  325. $out .= "\n";
  326. $out .= "\n";
  327. $out .= "\tinherit <aro_id> <aco_id> [<aco_action>]\n";
  328. $out .= "\t\tUse this command to force a child ARO object to inherit its\n";
  329. $out .= "\t\tpermissions settings from its parent.\n";
  330. $out .= "\n";
  331. $out .= "\n";
  332. $out .= "\tview aro|aco [<node>]\n";
  333. $out .= "\t\tThe view command will return the ARO or ACO tree. The optional\n";
  334. $out .= "\t\tid/alias parameter allows you to return only a portion of the requested\n";
  335. $out .= "\t\ttree.\n";
  336. $out .= "\n";
  337. $out .= "\n";
  338. $out .= "\tinitdb\n";
  339. $out .= "\t\tUse this command to create the database tables needed to use DB ACL.\n";
  340. $out .= "\n";
  341. $out .= "\n";
  342. $out .= "\thelp\n";
  343. $out .= "\t\tDisplays this help message.\n";
  344. $out .= "\n";
  345. $out .= "\n";
  346. $this->out($out);
  347. }
  348. /**
  349. * Enter description here...
  350. *
  351. */
  352. function checkNodeType() {
  353. if ($this->args[0] != 'aco' && $this->args[0] != 'aro') {
  354. $this->displayError("Missing/Unknown node type: '".$this->args[0]."'", 'Please specify which ACL object type you wish to create.');
  355. }
  356. }
  357. /**
  358. * Enter description here...
  359. *
  360. * @param unknown_type $type
  361. * @param unknown_type $id
  362. * @return unknown
  363. */
  364. function nodeExists($type, $id) {
  365. //$this->out("Check to see if $type with ID = $id exists...\n");
  366. extract($this->__dataVars($type));
  367. $conditions = $this->Acl->{$class}->_resolveID($id);
  368. $possibility = $this->Acl->{$class}->findAll($conditions);
  369. return $possibility;
  370. }
  371. /**
  372. * Enter description here...
  373. *
  374. * @param unknown_type $type
  375. * @return unknown
  376. */
  377. function __dataVars($type = null) {
  378. if ($type == null) {
  379. $type = $this->args[0];
  380. }
  381. $vars = array();
  382. $class = ucwords($type);
  383. $vars['secondary_id'] = ($class == 'aro' ? 'foreign_key' : 'object_id');
  384. $vars['data_name'] = $type;
  385. $vars['table_name'] = $type . 's';
  386. $vars['class'] = $class;
  387. return $vars;
  388. }
  389. /**
  390. * Database configuration setup.
  391. *
  392. */
  393. function __doDbConfig() {
  394. $this->hr(true);
  395. $this->out('Database Configuration:');
  396. $this->hr(true);
  397. $driver = '';
  398. while ($driver == '') {
  399. $driver = $this->in('What database driver would you like to use?', array('mysql','mysqli','mssql','sqlite','postgres', 'odbc', 'oracle'), 'mysql');
  400. if ($driver == '') {
  401. $this->out('The database driver supplied was empty. Please supply a database driver.');
  402. }
  403. }
  404. switch($driver) {
  405. case 'mysql':
  406. $connect = 'mysql_connect';
  407. break;
  408. case 'mysqli':
  409. $connect = 'mysqli_connect';
  410. break;
  411. case 'mssql':
  412. $connect = 'mssql_connect';
  413. break;
  414. case 'sqlite':
  415. $connect = 'sqlite_open';
  416. break;
  417. case 'postgres':
  418. $connect = 'pg_connect';
  419. break;
  420. case 'odbc':
  421. $connect = 'odbc_connect';
  422. break;
  423. case 'oracle':
  424. $connect = 'ocilogon';
  425. break;
  426. default:
  427. $this->out('The connection parameter could not be set.');
  428. break;
  429. }
  430. $host = '';
  431. while ($host == '') {
  432. $host = $this->in('What is the hostname for the database server?', null, 'localhost');
  433. if ($host == '') {
  434. $this->out('The host name you supplied was empty. Please supply a hostname.');
  435. }
  436. }
  437. $login = '';
  438. while ($login == '') {
  439. $login = $this->in('What is the database username?', null, 'root');
  440. if ($login == '') {
  441. $this->out('The database username you supplied was empty. Please try again.');
  442. }
  443. }
  444. $password = '';
  445. $blankPassword = false;
  446. while ($password == '' && $blankPassword == false) {
  447. $password = $this->in('What is the database password?');
  448. if ($password == '') {
  449. $blank = $this->in('The password you supplied was empty. Use an empty password?', array('y', 'n'), 'n');
  450. if($blank == 'y')
  451. {
  452. $blankPassword = true;
  453. }
  454. }
  455. }
  456. $database = '';
  457. while ($database == '') {
  458. $database = $this->in('What is the name of the database you will be using?', null, 'cake');
  459. if ($database == '') {
  460. $this->out('The database name you supplied was empty. Please try again.');
  461. }
  462. }
  463. $prefix = '';
  464. while ($prefix == '') {
  465. $prefix = $this->in('Enter a table prefix?', null, 'n');
  466. }
  467. if(low($prefix) == 'n') {
  468. $prefix = '';
  469. }
  470. $this->hr(true);
  471. $this->out('The following database configuration will be created:');
  472. $this->hr(true);
  473. $this->out("Driver: $driver");
  474. $this->out("Connection: $connect");
  475. $this->out("Host: $host");
  476. $this->out("User: $login");
  477. $this->out("Pass: " . str_repeat('*', strlen($password)));
  478. $this->out("Database: $database");
  479. $this->out("Table prefix: $prefix");
  480. $this->hr(true);
  481. $looksGood = $this->in('Look okay?', array('y', 'n'), 'y');
  482. if (low($looksGood) == 'y' || low($looksGood) == 'yes') {
  483. $this->bakeDbConfig($driver, $connect, $host, $login, $password, $database, $prefix);
  484. } else {
  485. $this->out('Bake Aborted.');
  486. }
  487. }
  488. /**
  489. * Creates a database configuration file for Bake.
  490. *
  491. * @param string $host
  492. * @param string $login
  493. * @param string $password
  494. * @param string $database
  495. */
  496. function bakeDbConfig( $driver, $connect, $host, $login, $password, $database, $prefix) {
  497. $out = "<?php\n";
  498. $out .= "class DATABASE_CONFIG {\n\n";
  499. $out .= "\tvar \$default = array(\n";
  500. $out .= "\t\t'driver' => '{$driver}',\n";
  501. $out .= "\t\t'connect' => '{$connect}',\n";
  502. $out .= "\t\t'host' => '{$host}',\n";
  503. $out .= "\t\t'login' => '{$login}',\n";
  504. $out .= "\t\t'password' => '{$password}',\n";
  505. $out .= "\t\t'database' => '{$database}', \n";
  506. $out .= "\t\t'prefix' => '{$prefix}' \n";
  507. $out .= "\t);\n";
  508. $out .= "}\n";
  509. $out .= "?>";
  510. $filename = CONFIGS.'database.php';
  511. $this->createFile($filename, $out);
  512. }
  513. }
  514. ?>