PageRenderTime 40ms CodeModel.GetById 6ms RepoModel.GetById 0ms app.codeStats 0ms

/src/lib/auth.php

http://textmotion.googlecode.com/
PHP | 433 lines | 326 code | 74 blank | 33 comment | 65 complexity | 62a10e186bfc7a22798fccb575cbeb0d MD5 | raw file
Possible License(s): MIT, CC0-1.0
  1. <?php
  2. /**
  3. * textMotion
  4. * ---
  5. * Written by Jose Carlos Nieto <xiam@menteslibres.org>
  6. * Copyright (c) 2007-2008, Jose Carlos Nieto <xiam@menteslibres.org>
  7. *
  8. * Licensed under The MIT License
  9. * Redistributions of files must retain the above copyright notice.
  10. *
  11. * @author Jose Carlos Nieto <xiam@menteslibres.org>
  12. * @package textMotion
  13. * @copyright Copyright (c) 2007-2008, J. Carlos Nieto <xiam@menteslibres.org>
  14. * @link http://www.textmotion.org
  15. * @version $Revision: $
  16. * @modifiedby $LastChangedBy: $
  17. * @lastmodified $Date: $
  18. * @license http://www.opensource.org/licenses/mit-license.php The MIT License
  19. *
  20. */
  21. class auth extends tm_object {
  22. private $cache = array();
  23. public function default_user() {
  24. $return = array(
  25. 'user' => array(
  26. 'id' => 0
  27. ),
  28. 'groups' => array(
  29. 'guest' => TM_GROUP_GUEST,
  30. 'all' => TM_GROUP_ALL
  31. )
  32. );
  33. return $return;
  34. }
  35. public function logout($user_id = null) {
  36. extract(
  37. $this->using(
  38. 'cookie',
  39. 'session',
  40. 'db'
  41. )
  42. );
  43. if (!$user_id) {
  44. // logging out the current user
  45. $cookie->clear('auth_key');
  46. $session->clear('auth_salt');
  47. }
  48. // database logout
  49. if (!is_integer($user_id)) {
  50. $user_id = $this->user['user']['id'];
  51. }
  52. if ($user_id) {
  53. $db->update(
  54. 'users',
  55. array(
  56. 'auth_key' => ''
  57. ),
  58. $db->bind('id = ?', $user_id)
  59. );
  60. }
  61. }
  62. public function __construct($user_id = null) {
  63. parent::__construct();
  64. $user = null;
  65. if (!defined('TM_STATIC')) {
  66. $session =& $this->using('session');
  67. $session->clear('user');
  68. extract(
  69. $this->using(
  70. 'db',
  71. 'cookie',
  72. 'env'
  73. )
  74. );
  75. if (TM_SIMULATE_USER > 0 || $user_id) {
  76. $user = $this->get_user(TM_SIMULATE_USER ? TM_SIMULATE_USER : $user_id);
  77. define('TM_AUTH', true);
  78. } else {
  79. $user = $this->check_auth_cookie();
  80. if ($user) {
  81. if ($user != -1) {
  82. define('TM_AUTH', true);
  83. }
  84. } else {
  85. $this->logout();
  86. $env->redirect('/');
  87. exit(0);
  88. }
  89. }
  90. $session->set('user', $user);
  91. }
  92. if (!defined('TM_AUTH')) {
  93. define('TM_AUTH', false);
  94. }
  95. if (!TM_AUTH) {
  96. $user = $this->default_user();
  97. }
  98. $this->user =& $user;
  99. }
  100. public function get_user($user_id) {
  101. if (!isset($this->cache['get_user'])) {
  102. $this->cache['get_user'] = array();
  103. }
  104. $cache =& $this->cache['get_user'][$user_id];
  105. if (!isset($cache)) {
  106. $db =& $this->using('db');
  107. // finding user
  108. $r = $db->find_one(
  109. array(
  110. 'user' => array(
  111. 'model' => 'users',
  112. 'has_many' => array(
  113. 'groups' => array(
  114. 'table' => 'groups_users',
  115. 'belongs_to' => array(
  116. 'group' => array(
  117. 'model' => 'groups',
  118. 'fields' => array('id', 'name'),
  119. 'foreign_key' => 'group_id'
  120. )
  121. )
  122. )
  123. ),
  124. 'where' => $db->bind(
  125. 'user.id = ?',
  126. $user_id
  127. )
  128. )
  129. )
  130. );
  131. if ($r) {
  132. // fetching additional user's groups
  133. $fetched = $queue = array();
  134. if (!empty($r['groups'])) {
  135. foreach ($r['groups'] as $g) {
  136. $queue[] = $g['group']['id'];
  137. $fetched[$g['group']['name']] = $g['group']['id'];
  138. }
  139. }
  140. while ($queue) {
  141. $groups = $db->find_all(
  142. array(
  143. 'group' => array(
  144. 'model' => 'groups',
  145. 'fields' => array('id'),
  146. 'assoc_key' => 'parent_id',
  147. 'many_to_many' => array(
  148. 'subgroup' => array(
  149. 'table' => 'groups',
  150. 'fields' => array('id', 'name'),
  151. 'join_table' => 'groups_groups',
  152. 'assoc_key' => 'related_id'
  153. )
  154. ),
  155. 'where' => "
  156. (groups_groups.parent_id = '".implode("' OR groups_groups.parent_id = '", $queue)."')
  157. ",
  158. 'trailing' => "GROUP BY (subgroup.id)"
  159. )
  160. )
  161. );
  162. $queue = array();
  163. if ($groups) {
  164. foreach ($groups as $g) {
  165. if (!isset($fetched[$g['subgroup']['name']])) {
  166. $fetched[$g['subgroup']['name']] = $g['subgroup']['id'];
  167. $queue[] = $g['subgroup']['id'];
  168. }
  169. }
  170. }
  171. }
  172. // automatic groups
  173. $fetched['user'] = TM_GROUP_USER;
  174. $fetched['all'] = TM_GROUP_ALL;
  175. /*
  176. foreach ($fetched as $name => $gid) {
  177. if ($gid == 1 || ($gid >= 6)) {
  178. $fetched['operator'] = TM_GROUP_OPERATOR;
  179. break;
  180. }
  181. }
  182. */
  183. $r['groups'] = $fetched;
  184. // associated privileges
  185. $r['privileges'] = array();
  186. $ps = $db->find_all(
  187. array(
  188. 'p' => array(
  189. 'table' => 'groups_privileges',
  190. 'where' => $db->bind('group_id in (\''.implode('\', \'', $r['groups']).'\')')
  191. )
  192. )
  193. );
  194. if ($ps) {
  195. foreach($ps as $p) {
  196. if (!isset($r['privileges'][$p['p']['module']])) {
  197. $r['privileges'][$p['p']['module']] = array(
  198. 'allow_write' => 0,
  199. 'allow_edit' => 0,
  200. 'allow_delete' => 0
  201. );
  202. }
  203. $r['privileges'][$p['p']['module']]['allow_write'] += $p['p']['allow_write'];
  204. $r['privileges'][$p['p']['module']]['allow_edit'] += $p['p']['allow_edit'];
  205. $r['privileges'][$p['p']['module']]['allow_delete'] += $p['p']['allow_delete'];
  206. if ($p['p']['allow_write'] || $p['p']['allow_edit'] || $p['p']['allow_delete']) {
  207. $r['groups']['operator'] = TM_GROUP_OPERATOR;
  208. }
  209. }
  210. }
  211. $cache = $r;
  212. } else {
  213. $cache = $this->default_user();
  214. }
  215. }
  216. return $cache;
  217. }
  218. public function get_current_user() {
  219. $session =& $this->using('session');
  220. $user = $session->get('user');
  221. if ($user) {
  222. $user_id = $user['user']['id'];
  223. } else {
  224. $user_id = 0;
  225. }
  226. return $this->get_user($user_id);
  227. }
  228. public function has_group($name, $user_id = null) {
  229. $session =& $this->using('session');
  230. if ($user_id == null) {
  231. $user = $session->get('user');
  232. if ($user) {
  233. $user_id = $user['user']['id'];
  234. } else {
  235. $user_id = 0;
  236. }
  237. }
  238. $user = $this->get_user($user_id);
  239. if ($user) {
  240. return isset($user['groups'][$name]);
  241. }
  242. return false;
  243. }
  244. public function is_editor($module, $user_id = null) {
  245. if ($this->has_group('admin', $user_id)) {
  246. return true;
  247. } else {
  248. return $this->has_group($module.'_editor', $user_id);
  249. }
  250. }
  251. public function allow_read($module) {
  252. if ($this->is_admin()) {
  253. return true;
  254. }
  255. return ($this->allow($module, 'write') || $this->allow($module, 'delete') || $this->allow($module, 'edit'));
  256. }
  257. public function allow_write($module) {
  258. return $this->allow($module, 'write');
  259. }
  260. public function allow_create($module) {
  261. return $this->allow($module, 'write');
  262. }
  263. public function allow_edit($module) {
  264. return $this->allow($module, 'edit');
  265. }
  266. public function allow_delete($module) {
  267. return $this->allow($module, 'delete');
  268. }
  269. public function allow($module, $action) {
  270. if ($this->is_admin()) {
  271. return true;
  272. } else {
  273. if ($action == 'read') {
  274. return $this->allow_read($module);
  275. } else {
  276. $user = $this->get_current_user();
  277. return !empty($user['privileges'][$module]['allow_'.$action]);
  278. }
  279. }
  280. }
  281. public function check_auth_cookie() {
  282. extract(
  283. $this->using(
  284. 'cookie',
  285. 'session'
  286. )
  287. );
  288. $key = $cookie->get('auth_key');
  289. $key = explode(':', preg_replace('/[^a-zA-Z0-9:]/', null, $key));
  290. if (isset($key[1])) {
  291. $user = $this->get_user($key[0]);
  292. if (!empty($user['user']['id'])) {
  293. if (TM_DEMO_MODE) {
  294. if (md5($user['user']['password']) == $key[1]) {
  295. return $user;
  296. }
  297. } else if (!empty($key[2])) {
  298. if ($user['user']['auth_key'] == md5($key[1].TM_UNIQUE_STR)) {
  299. if ($key[2] == $session->get('auth_salt')) {
  300. return $user;
  301. } else {
  302. debug('Possible cookie stealing.');
  303. }
  304. }
  305. }
  306. }
  307. } else {
  308. return -1;
  309. }
  310. return false;
  311. }
  312. public function set_auth_cookie($user, $secret = null) {
  313. extract(
  314. $this->using(
  315. 'cookie',
  316. 'session',
  317. 'misc'
  318. )
  319. );
  320. if ($secret) {
  321. $salt = $misc->random_string(rand(8, 16));
  322. $session->set('auth_salt', $salt);
  323. $cookie->set('auth_key', $user['id'].':'.$secret.':'.$salt);
  324. } else {
  325. $cookie->set('auth_key', $user['id'].':'.md5($user['password']));
  326. }
  327. }
  328. public function is_admin($user_id = null) {
  329. return $this->has_group('admin', $user_id);
  330. }
  331. public function is_user($user_id = null) {
  332. return $this->has_group('user', $user_id);
  333. }
  334. public function is_guest($user_id = null) {
  335. return $this->has_group('guest', $user_id);
  336. }
  337. public function is_operator($user_id = null) {
  338. if ($this->is_admin()) {
  339. return true;
  340. } else {
  341. return $this->has_group('operator', $user_id);
  342. }
  343. }
  344. public function get_modules() {
  345. $conf =& $this->using('conf');
  346. $modules = array();
  347. $dh = opendir(TM_MODULES_DIR);
  348. while (($file = readdir($dh)) !== false) {
  349. if ($file{0} != '.' && is_dir(TM_MODULES_DIR.$file)) {
  350. if ($conf->get($file.'/version')) {
  351. $modules[] = $file;
  352. }
  353. }
  354. }
  355. closedir($dh);
  356. return $modules;
  357. }
  358. }
  359. ?>