access_token.class.php 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. /**
  4. * Definition of the AccessToken class
  5. * @package chamilo.library
  6. */
  7. /**
  8. * An access token. Can be passed between applications to grant access.
  9. *
  10. * The token aggregate several values together (key id, api key, user id). This
  11. * is useful to pass a single value between application and avoid passing
  12. * each value as a separate parameter.
  13. *
  14. * Note that values are aggregated but not crypted. An external application could
  15. * have access to individual components.
  16. *
  17. * @see /main/auth/key_auth.class.php
  18. * @see table user_api_key
  19. *
  20. * Usage:
  21. *
  22. * Validate token:
  23. *
  24. * $data = Request::get('access_token');
  25. * $token = AccessToken::parse($data);
  26. * $token->is_valid();
  27. *
  28. * Pass token
  29. *
  30. * $token = new AccessToken(1, 1, '+*ç*%ç*ç');
  31. * $url = '.....?access_token=' . $token;
  32. *
  33. * @author Laurent Opprecht <laurent@opprecht.info> for the Univesity of Geneva
  34. */
  35. class AccessToken
  36. {
  37. /**
  38. * Makes sure the static token exists and is a reference to an AccessToken
  39. * object
  40. * @assert () !== null
  41. */
  42. static function empty_token()
  43. {
  44. static $result = null;
  45. if (empty($result)) {
  46. $result = new self(0, 0, '');
  47. }
  48. return $result;
  49. }
  50. /**
  51. * Parses a given string to find a token
  52. * @param string A base64-encoded string
  53. * @return AccessToken
  54. * @assert ('') !== null
  55. * @assert (base64_encode('a/b')) !== null
  56. * @assert (base64_encode('a/b/c')) !== null
  57. */
  58. static function parse($string)
  59. {
  60. if (empty($string)) {
  61. return self::empty_token();
  62. }
  63. $data = base64_decode($string);
  64. $data = explode('/', $data);
  65. if (count($data) != 3) {
  66. return self::empty_token();
  67. }
  68. $id = $data[0];
  69. $user_id = $data[1];
  70. $key = $data[2];
  71. return new self($id, $user_id, $key);
  72. }
  73. /**
  74. * Creates a token based on an ID, an user ID and a key
  75. * @param int ID
  76. * @param int User id
  77. * @param string Key
  78. * @return AccessToken
  79. * @assert (0, 0, 'a') !== null
  80. */
  81. static function create($id, $user_id, $key)
  82. {
  83. $is_valid = !empty($id) && !empty($user_id) && !empty($key);
  84. return $is_valid ? new self($id, $user_id, $key) : self::empty_token();
  85. }
  86. protected $id = 0;
  87. protected $user_id = 0;
  88. protected $key = '';
  89. /**
  90. * Constructor
  91. * @param int ID
  92. * @param int User ID
  93. * @param string Key
  94. * @assert (1,1,1) === null
  95. */
  96. function __construct($id, $user_id, $key)
  97. {
  98. $this->id = $id;
  99. $this->user_id = $user_id;
  100. $this->key = $key;
  101. }
  102. /**
  103. * The user_api_key id.
  104. * @return int
  105. * @assert () > 0
  106. */
  107. function get_id()
  108. {
  109. return $this->id;
  110. }
  111. /**
  112. * User id
  113. * @return string
  114. * @assert () > 0
  115. */
  116. function get_user_id()
  117. {
  118. return $this->user_id;
  119. }
  120. /**
  121. * User api key.
  122. * @return string
  123. * @assert () !== null
  124. */
  125. function get_key()
  126. {
  127. return $this->key;
  128. }
  129. /**
  130. * True if the token is an empty token. I.e. a no access token.
  131. * @return bool
  132. * @assert () === true
  133. */
  134. function is_empty()
  135. {
  136. return empty($this->id) || empty($this->user_id) || empty($this->key);
  137. }
  138. /**
  139. * Validate token against the database. Returns true if token is valid,
  140. * false otherwise.
  141. * @return boolean
  142. * @assert () === false
  143. */
  144. function is_valid()
  145. {
  146. if ($this->is_empty()) {
  147. return false;
  148. }
  149. $key = UserApiKeyManager::get_by_id($this->id);
  150. if (empty($key)) {
  151. return false;
  152. }
  153. if ($key['api_key'] != $this->key) {
  154. return false;
  155. }
  156. if ($key['user_id'] != $this->user_id) {
  157. return false;
  158. }
  159. $time = time();
  160. $validity_start_date = $key['validity_start_date'] ? strtotime($key['validity_start_date']) : $time;
  161. $validity_end_date = $key['validity_end_date'] ? strtotime($key['validity_end_date']) : $time + 100000;
  162. return $validity_start_date <= $time && $time <= $validity_end_date;
  163. }
  164. /**
  165. * Returns a string representation of the token that can be passed in a url or a form.
  166. * The string representation can be parsed by calling AccessToken::parse();
  167. * @return string
  168. * @assert () !== null
  169. */
  170. function __toString()
  171. {
  172. $data[] = $this->id;
  173. $data[] = $this->user_id;
  174. $data[] = $this->key;
  175. $result = implode('/', $data);
  176. $result = base64_encode($result);
  177. return $result;
  178. }
  179. }