key_auth.class.php 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  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. *
  37. * @license see /license.txt
  38. * @author Laurent Opprecht <laurent@opprecht.info> for the Univesity of Geneva
  39. */
  40. class KeyAuth
  41. {
  42. const PARAM_ACCESS_TOKEN = 'access_token';
  43. protected static $services = [];
  44. protected function __construct()
  45. {
  46. }
  47. public static function create_temp_token($service = null, $duration = 60, $user_id = null)
  48. {
  49. return UserApiKeyManager::create_temp_token($service, $duration, $user_id);
  50. }
  51. /**
  52. * Returns enabled services.
  53. *
  54. * @return array
  55. */
  56. public static function get_services()
  57. {
  58. return self::$services;
  59. }
  60. /**
  61. * Name of the service for which we are goint to check the API Key.
  62. * If empty it disables authentication.
  63. *
  64. * !! 10 chars max !!
  65. *
  66. * @param string $_
  67. */
  68. public static function enable_services($_)
  69. {
  70. $args = func_get_args();
  71. $names = [];
  72. foreach ($args as $arg) {
  73. if (is_object($arg)) {
  74. $f = [$arg, 'get_service_name'];
  75. $name = call_user_func($f);
  76. } else {
  77. $name = $arg;
  78. }
  79. $name = substr($name, 0, 10);
  80. self::$services[$name] = $name;
  81. }
  82. }
  83. public static function disable_services($_)
  84. {
  85. $args = func_get_args();
  86. $names = [];
  87. foreach ($args as $name) {
  88. $name = substr($name, 0, 10);
  89. unset(self::$services[$name]);
  90. }
  91. }
  92. public static function is_service_enabled($service)
  93. {
  94. $services = self::get_services();
  95. foreach ($services as $s) {
  96. if ($s == $service) {
  97. return true;
  98. }
  99. }
  100. return false;
  101. }
  102. public static function clear_services()
  103. {
  104. self::$services[$name] = [];
  105. }
  106. /**
  107. * Enable key authentication for the default service - i.e. chamilo.
  108. */
  109. public static function enable()
  110. {
  111. self::enable_services(UserApiKeyManager::default_service());
  112. }
  113. public static function disable()
  114. {
  115. self::$services[$name] = [];
  116. }
  117. /**
  118. * Returns true if the key authentication method is enabled. False otherwise.
  119. * Default to false.
  120. *
  121. * @return bool
  122. */
  123. public static function is_enabled()
  124. {
  125. return !empty(self::$services);
  126. }
  127. /**
  128. * @return KeyAuth
  129. */
  130. public static function instance()
  131. {
  132. static $result = null;
  133. if (empty($result)) {
  134. $result = new self();
  135. }
  136. return $result;
  137. }
  138. /**
  139. * Returns true if authentication accepts to run otherwise returns false.
  140. *
  141. * @return bool
  142. */
  143. public function accept()
  144. {
  145. /**
  146. * Authentication method must be enabled.
  147. */
  148. if (!self::is_enabled()) {
  149. return false;
  150. }
  151. $token = $this->get_access_token();
  152. if ($token->is_empty()) {
  153. return false;
  154. }
  155. $key = UserApiKeyManager::get_by_id($token->get_id());
  156. if (empty($key)) {
  157. return false;
  158. }
  159. /**
  160. * The service corresponding to the key must be enabled.
  161. */
  162. $service = $key['api_service'];
  163. if (!self::is_service_enabled($service)) {
  164. return false;
  165. }
  166. /**
  167. * User associated with the key must be active.
  168. */
  169. $user = api_get_user_info($token->get_user_id());
  170. if (empty($user)) {
  171. return false;
  172. }
  173. if (!$user['active']) {
  174. return false;
  175. }
  176. /**
  177. * Token must be valid.
  178. */
  179. return $token->is_valid();
  180. }
  181. /**
  182. * If accepted tear down session, log in user and returns true.
  183. * If not accepted do nothing and returns false.
  184. *
  185. * @return bool
  186. */
  187. public function login()
  188. {
  189. if (!$this->accept()) {
  190. return false;
  191. }
  192. /**
  193. * ! important this is to ensure we don't grant access for other parts.
  194. */
  195. Session::destroy();
  196. /**
  197. * We don't allow redirection since access is granted only for this call.
  198. */
  199. global $no_redirection, $noredirection;
  200. $no_redirection = true;
  201. $noredirection = true;
  202. Session::write('noredirection', $noredirection);
  203. $user_id = $this->get_user_id();
  204. $course_code = $this->get_course_code();
  205. $group_id = $this->get_group_id();
  206. Login::init_user($user_id, true);
  207. Login::init_course($course_code, true);
  208. Login::init_group($group_id, true);
  209. return true;
  210. }
  211. /**
  212. * Returns the request access token.
  213. *
  214. * @return AccessToken
  215. */
  216. public function get_access_token()
  217. {
  218. $string = Request::get(self::PARAM_ACCESS_TOKEN);
  219. return AccessToken::parse($string);
  220. }
  221. public function get_user_id()
  222. {
  223. return $this->get_access_token()->get_user_id();
  224. }
  225. public function get_course_code()
  226. {
  227. return Request::get('cidReq', 0);
  228. }
  229. /**
  230. * @return int
  231. */
  232. public function get_group_id()
  233. {
  234. return Request::get('gidReq', 0);
  235. }
  236. }