key_auth.class.php 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. <?php
  2. use ChamiloSession as Session;
  3. /**
  4. * Used to authenticate user with an access token. By default this method is disabled.
  5. * Method used primarily to make API calls: Rss, file upload.
  6. *
  7. * Access is granted only for the services that are enabled.
  8. *
  9. * To be secured this method must
  10. *
  11. * 1) be called through httpS to avoid sniffing (note that this is the case anyway with other methods such as cookies)
  12. * 2) the url/access token must be secured
  13. *
  14. * This authentication method is session less. This is to ensure that the navigator
  15. * do not receive an access cookie that will grant it access to other parts of the
  16. * application.
  17. *
  18. *
  19. * Usage:
  20. *
  21. * Enable KeyAuth for a specific service. Add the following lines so that
  22. * the key authentication method is enabled for a specific service before
  23. * calling global.inc.php.
  24. *
  25. * include_once '.../main/inc/autoload.inc.php';
  26. * KeyAuth::enable_services('my_service');
  27. * include_once '.../main/inc/global.inc.php';
  28. *
  29. *
  30. * Enable url access for a short period of time:
  31. *
  32. * token = KeyAuth::create_temp_token();
  33. * url = '...?access_token=' . $token ;
  34. *
  35. * @see AccessToken
  36. * @license see /license.txt
  37. * @author Laurent Opprecht <laurent@opprecht.info> for the Univesity of Geneva
  38. */
  39. class KeyAuth
  40. {
  41. const PARAM_ACCESS_TOKEN = 'access_token';
  42. protected static $services = array();
  43. public static function create_temp_token($service = null, $duration = 60, $user_id = null)
  44. {
  45. return UserApiKeyManager::create_temp_token($service, $duration, $user_id);
  46. }
  47. /**
  48. * Returns enabled services
  49. *
  50. * @return array
  51. */
  52. public static function get_services()
  53. {
  54. return self::$services;
  55. }
  56. /**
  57. * Name of the service for which we are goint to check the API Key.
  58. * If empty it disables authentication.
  59. *
  60. * !! 10 chars max !!
  61. * @param string $_
  62. */
  63. public static function enable_services($_)
  64. {
  65. $args = func_get_args();
  66. $names = array();
  67. foreach ($args as $arg) {
  68. if (is_object($arg)) {
  69. $f = array($arg, 'get_service_name');
  70. $name = call_user_func($f);
  71. } else {
  72. $name = $arg;
  73. }
  74. $name = substr($name, 0, 10);
  75. self::$services[$name] = $name;
  76. }
  77. }
  78. public static function disable_services($_)
  79. {
  80. $args = func_get_args();
  81. $names = array();
  82. foreach ($args as $name) {
  83. $name = substr($name, 0, 10);
  84. unset(self::$services[$name]);
  85. }
  86. }
  87. public static function is_service_enabled($service)
  88. {
  89. $services = self::get_services();
  90. foreach ($services as $s) {
  91. if ($s == $service) {
  92. return true;
  93. }
  94. }
  95. return false;
  96. }
  97. public static function clear_services()
  98. {
  99. self::$services[$name] = array();
  100. }
  101. /**
  102. * Enable key authentication for the default service - i.e. chamilo
  103. */
  104. public static function enable()
  105. {
  106. self::enable_services(UserApiKeyManager::default_service());
  107. }
  108. public static function disable()
  109. {
  110. self::$services[$name] = array();
  111. }
  112. /**
  113. * Returns true if the key authentication method is enabled. False otherwise.
  114. * Default to false.
  115. *
  116. * @return bool
  117. */
  118. public static function is_enabled()
  119. {
  120. return !empty(self::$services);
  121. }
  122. /**
  123. * @return KeyAuth
  124. */
  125. public static function instance()
  126. {
  127. static $result = null;
  128. if (empty($result)) {
  129. $result = new self();
  130. }
  131. return $result;
  132. }
  133. protected function __construct()
  134. {
  135. }
  136. /**
  137. * Returns true if authentication accepts to run otherwise returns false.
  138. *
  139. * @return boolean
  140. */
  141. public function accept()
  142. {
  143. /**
  144. * Authentication method must be enabled
  145. */
  146. if (!self::is_enabled()) {
  147. return false;
  148. }
  149. $token = $this->get_access_token();
  150. if ($token->is_empty()) {
  151. return false;
  152. }
  153. $key = UserApiKeyManager::get_by_id($token->get_id());
  154. if (empty($key)) {
  155. return false;
  156. }
  157. /**
  158. * The service corresponding to the key must be enabled.
  159. */
  160. $service = $key['api_service'];
  161. if (!self::is_service_enabled($service)) {
  162. return false;
  163. }
  164. /**
  165. * User associated with the key must be active
  166. */
  167. $user = api_get_user_info($token->get_user_id());
  168. if (empty($user)) {
  169. return false;
  170. }
  171. if (!$user['active']) {
  172. return false;
  173. }
  174. /**
  175. * Token must be valid.
  176. */
  177. return $token->is_valid();
  178. }
  179. /**
  180. * If accepted tear down session, log in user and returns true.
  181. * If not accepted do nothing and returns false.
  182. *
  183. * @return boolean
  184. */
  185. public function login()
  186. {
  187. if (!$this->accept()) {
  188. return false;
  189. }
  190. /**
  191. * ! important this is to ensure we don't grant access for other parts
  192. */
  193. Session::destroy();
  194. /**
  195. * We don't allow redirection since access is granted only for this call
  196. */
  197. global $no_redirection, $noredirection;
  198. $no_redirection = true;
  199. $noredirection = true;
  200. Session::write('noredirection', $noredirection);
  201. $user_id = $this->get_user_id();
  202. $course_code = $this->get_course_code();
  203. $group_id = $this->get_group_id();
  204. Login::init_user($user_id, true);
  205. Login::init_course($course_code, true);
  206. Login::init_group($group_id, true);
  207. return true;
  208. }
  209. /**
  210. * Returns the request access token
  211. *
  212. * @return AccessToken
  213. */
  214. public function get_access_token()
  215. {
  216. $string = Request::get(self::PARAM_ACCESS_TOKEN);
  217. return AccessToken::parse($string);
  218. }
  219. public function get_user_id()
  220. {
  221. return $this->get_access_token()->get_user_id();
  222. }
  223. public function get_course_code()
  224. {
  225. return Request::get('cidReq', 0);
  226. }
  227. /**
  228. * @return integer
  229. */
  230. public function get_group_id()
  231. {
  232. return Request::get('gidReq', 0);
  233. }
  234. }