PageRenderTime 27ms CodeModel.GetById 28ms RepoModel.GetById 1ms app.codeStats 0ms

/core/libs/auth/auth.php

https://github.com/joanhey/KumbiaPHP
PHP | 318 lines | 165 code | 17 blank | 136 comment | 27 complexity | 3b9d8492265417901584bed664a9414e MD5 | raw file
Possible License(s): BSD-3-Clause
  1. <?php
  2. /**
  3. * KumbiaPHP web & app Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://wiki.kumbiaphp.com/Licencia
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@kumbiaphp.com so we can send you a copy immediately.
  14. *
  15. * @category extensions
  16. * @package Auth
  17. * @copyright Copyright (c) 2005-2014 Kumbia Team (http://www.kumbiaphp.com)
  18. * @license http://wiki.kumbiaphp.com/Licencia New BSD License
  19. */
  20. /**
  21. * @see AuthInterface
  22. */
  23. require_once CORE_PATH . 'libs/auth/auth_interface.php';
  24. /**
  25. * Esta clase permite autenticar usuarios
  26. *
  27. * @category extensions
  28. * @package Auth
  29. */
  30. class Auth
  31. {
  32. /**
  33. * Nombre del adaptador usado para autenticar
  34. *
  35. * @var string
  36. */
  37. private $adapter;
  38. /**
  39. * Objeto Adaptador actual
  40. *
  41. * @var mixed
  42. */
  43. private $adapter_object = null;
  44. /**
  45. * Indica si un usuario debe loguearse solo una vez en el sistema desde
  46. * cualquier parte
  47. *
  48. * @var boolean
  49. */
  50. private $active_session = false;
  51. /**
  52. * Tiempo en que expirara la sesion en caso de que no se termine con destroy_active_session
  53. *
  54. * @var integer
  55. */
  56. private $expire_time = 3600;
  57. /**
  58. * Argumentos extra enviados al Adaptador
  59. *
  60. * @var array
  61. */
  62. private $extra_args = array();
  63. /**
  64. * Tiempo que duerme la aplicacion cuando falla la autenticacion
  65. */
  66. private $sleep_time = 0;
  67. /**
  68. * Indica si el ultimo llamado a authenticate tuvo exito o no (persistente en sesion)
  69. *
  70. * @var boolean
  71. */
  72. private static $is_valid = null;
  73. /**
  74. * Ultima identidad obtenida por Authenticate (persistente en sesion)
  75. *
  76. * @var array
  77. */
  78. private static $active_identity = array();
  79. /**
  80. * Constructor del Autenticador
  81. *
  82. *
  83. */
  84. public function __construct()
  85. {
  86. $extra_args = Util::getParams(func_get_args());
  87. if (isset($extra_args[0])) {
  88. $adapter = $extra_args[0];
  89. unset($extra_args[0]);
  90. } else {
  91. $adapter = 'model';
  92. }
  93. $this->set_adapter($adapter, $this, $extra_args);
  94. }
  95. /**
  96. * @param Auth $auth
  97. */
  98. public function set_adapter($adapter, $auth = null, $extra_args = array())
  99. {
  100. if (!in_array($adapter, array('digest', 'http', 'model', 'kerberos5', 'radius'))) {
  101. throw new kumbiaException("Adaptador de autenticaci&oacute;n '$adapter' no soportado");
  102. }
  103. $this->adapter = Util::camelcase($adapter);
  104. require_once CORE_PATH . "libs/auth/adapters/{$adapter}_auth.php";
  105. $adapter_class = $this->adapter . 'Auth';
  106. $this->extra_args = $extra_args;
  107. $this->adapter_object = new $adapter_class($auth, $extra_args);
  108. }
  109. /**
  110. * Obtiene el nombre del adaptador actual
  111. * @return string
  112. */
  113. public function get_adapter_name()
  114. {
  115. return $this->adapter;
  116. }
  117. /**
  118. * Realiza el proceso de autenticacič´¸n
  119. *
  120. * @return array
  121. */
  122. public function authenticate()
  123. {
  124. $result = $this->adapter_object->authenticate();
  125. /**
  126. * Si es una sesion activa maneja un archivo persistente para control
  127. */
  128. if ($result && $this->active_session) {
  129. $user_hash = md5(serialize($this->extra_args));
  130. $filename = APP_PATH . 'temp/cache/' . base64_encode('auth');
  131. if (file_exists($filename)) {
  132. $fp = fopen($filename, 'r');
  133. while (!feof($fp)) {
  134. $line = fgets($fp);
  135. $user = explode(':', $line);
  136. if ($user_hash == $user[0]) {
  137. if ($user[1] + $user[2] > time()) {
  138. if ($this->sleep_time) {
  139. sleep($this->sleep_time);
  140. }
  141. self::$active_identity = array();
  142. self::$is_valid = false;
  143. return false;
  144. } else {
  145. fclose($fp);
  146. $this->destroy_active_session();
  147. file_put_contents($filename, $user_hash . ':' . time() . ':' . $this->expire_time . "\n");
  148. }
  149. }
  150. }
  151. fclose($fp);
  152. $fp = fopen($filename, 'a');
  153. fputs($fp, $user_hash . ':' . time() . ':' . $this->expire_time . "\n");
  154. fclose($fp);
  155. } else {
  156. file_put_contents($filename, $user_hash . ':' . time() . ':' . $this->expire_time . "\n");
  157. }
  158. }
  159. if (!$result) {
  160. if ($this->sleep_time) {
  161. sleep($this->sleep_time);
  162. }
  163. }
  164. $_SESSION['KUMBIA_AUTH_IDENTITY'][Config::get('config.application.namespace_auth')] = $this->adapter_object->get_identity();
  165. self::$active_identity = $this->adapter_object->get_identity();
  166. $_SESSION['KUMBIA_AUTH_VALID'][Config::get('config.application.namespace_auth')] = $result;
  167. self::$is_valid = $result;
  168. return $result;
  169. }
  170. /**
  171. * Realiza el proceso de autenticaci&oacute;n usando HTTP
  172. *
  173. * @return array
  174. */
  175. public function authenticate_with_http()
  176. {
  177. if (!$_SERVER['PHP_AUTH_USER']) {
  178. header('WWW-Authenticate: Basic realm="basic"');
  179. header('HTTP/1.0 401 Unauthorized');
  180. return false;
  181. } else {
  182. $options = array("username" => $_SERVER['PHP_AUTH_USER'], "password" => $_SERVER['PHP_AUTH_PW']);
  183. $this->adapter_object->set_params($options);
  184. return $this->authenticate();
  185. }
  186. }
  187. /**
  188. * Devuelve la identidad encontrada en caso de exito
  189. *
  190. * @return array
  191. */
  192. public function get_identity()
  193. {
  194. return $this->adapter_object->get_identity();
  195. }
  196. /**
  197. * Permite controlar que usuario no se loguee mas de una vez en el sistema desde cualquier parte
  198. *
  199. * @param string $value
  200. */
  201. public function set_active_session($value, $time = 3600)
  202. {
  203. $this->active_session = $value;
  204. $this->expire_time = $time;
  205. }
  206. /**
  207. * Destruir sesion activa del usuario autenticado
  208. *
  209. */
  210. public function destroy_active_session()
  211. {
  212. $user_hash = md5(serialize($this->extra_args));
  213. $filename = APP_PATH . 'temp/cache/' . base64_encode('auth');
  214. $lines = file($filename);
  215. $lines_out = array();
  216. foreach ($lines as $line) {
  217. if (substr($line, 0, 32) != $user_hash) {
  218. $lines_out[] = $line;
  219. }
  220. }
  221. file_put_contents($filename, join("\n", $lines_out));
  222. }
  223. /**
  224. * Devuelve la instancia del adaptador
  225. *
  226. * @return string
  227. */
  228. public function get_adapter_instance()
  229. {
  230. return $this->adapter_object;
  231. }
  232. /**
  233. * Determinar si debe dormir la aplicacion cuando falle la autenticacion y cuanto tiempo en segundos
  234. *
  235. * @param boolean $value
  236. * @param integer $time
  237. */
  238. public function sleep_on_fail($value, $time = 2)
  239. {
  240. $time = (int) $time;
  241. if ($time < 0) {
  242. $time = 0;
  243. }
  244. if ($value) {
  245. $this->sleep_time = $time;
  246. } else {
  247. $this->sleep_time = 0;
  248. }
  249. }
  250. /**
  251. * Devuelve el resultado del ultimo llamado a authenticate desde el ultimo objeto Auth instanciado
  252. *
  253. * @return boolean
  254. */
  255. static public function is_valid()
  256. {
  257. if (!is_null(self::$is_valid)) {
  258. return self::$is_valid;
  259. } else {
  260. self::$is_valid = isset($_SESSION['KUMBIA_AUTH_VALID'][Config::get('config.application.namespace_auth')]) ? $_SESSION['KUMBIA_AUTH_VALID'][Config::get('config.application.namespace_auth')] : null;
  261. return self::$is_valid;
  262. }
  263. }
  264. /**
  265. * Devuelve el resultado de la ultima identidad obtenida en authenticate desde el ultimo objeto Auth instanciado
  266. *
  267. * @return array
  268. */
  269. static public function get_active_identity()
  270. {
  271. if (count(self::$active_identity)) {
  272. return self::$active_identity;
  273. } else {
  274. self::$active_identity = $_SESSION['KUMBIA_AUTH_IDENTITY'][Config::get('config.application.namespace_auth')];
  275. return self::$active_identity;
  276. }
  277. }
  278. /**
  279. * Obtiene un valor de la identidad actual
  280. *
  281. * @param string $var
  282. * @return string
  283. */
  284. public static function get($var = null)
  285. {
  286. if ($var) {
  287. return $_SESSION['KUMBIA_AUTH_IDENTITY'][Config::get('config.application.namespace_auth')][$var];
  288. }
  289. }
  290. /**
  291. * Anula la identidad actual
  292. *
  293. */
  294. static public function destroy_identity()
  295. {
  296. self::$is_valid = null;
  297. unset($_SESSION['KUMBIA_AUTH_VALID'][Config::get('config.application.namespace_auth')]);
  298. self::$active_identity = null;
  299. unset($_SESSION['KUMBIA_AUTH_IDENTITY'][Config::get('config.application.namespace_auth')]);
  300. }
  301. }