Friendica Communications Platform (please note that this is a clone of the repository at github, issues are handled there) https://friendi.ca
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

177 lines
4.0KB

  1. <?php
  2. /**
  3. * @file src/Network/FKOAuthDataStore.php
  4. * OAuth server
  5. * Based on oauth2-php <http://code.google.com/p/oauth2-php/>
  6. *
  7. */
  8. namespace Friendica\Network;
  9. use Friendica\Core\Config;
  10. use Friendica\Core\Logger;
  11. use Friendica\Database\DBA;
  12. use OAuthConsumer;
  13. use OAuthDataStore;
  14. use OAuthToken;
  15. define('REQUEST_TOKEN_DURATION', 300);
  16. define('ACCESS_TOKEN_DURATION', 31536000);
  17. /**
  18. * @brief OAuthDataStore class
  19. */
  20. class FKOAuthDataStore extends OAuthDataStore
  21. {
  22. /**
  23. * @return string
  24. */
  25. private static function genToken()
  26. {
  27. return md5(base64_encode(pack('N6', mt_rand(), mt_rand(), mt_rand(), mt_rand(), mt_rand(), uniqid())));
  28. }
  29. /**
  30. * @param string $consumer_key key
  31. * @return mixed
  32. */
  33. public function lookup_consumer($consumer_key)
  34. {
  35. Logger::log(__function__ . ":" . $consumer_key);
  36. $s = DBA::select('clients', ['client_id', 'pw', 'redirect_uri'], ['client_id' => $consumer_key]);
  37. $r = DBA::toArray($s);
  38. if (DBA::isResult($r)) {
  39. return new OAuthConsumer($r[0]['client_id'], $r[0]['pw'], $r[0]['redirect_uri']);
  40. }
  41. return null;
  42. }
  43. /**
  44. * @param string $consumer consumer
  45. * @param string $token_type type
  46. * @param string $token token
  47. * @return mixed
  48. */
  49. public function lookup_token($consumer, $token_type, $token)
  50. {
  51. Logger::log(__function__ . ":" . $consumer . ", " . $token_type . ", " . $token);
  52. $s = DBA::select('tokens', ['id', 'secret', 'scope', 'expires', 'uid'], ['client_id' => $consumer->key, 'scope' => $token_type, 'id' => $token]);
  53. $r = DBA::toArray($s);
  54. if (DBA::isResult($r)) {
  55. $ot = new OAuthToken($r[0]['id'], $r[0]['secret']);
  56. $ot->scope = $r[0]['scope'];
  57. $ot->expires = $r[0]['expires'];
  58. $ot->uid = $r[0]['uid'];
  59. return $ot;
  60. }
  61. return null;
  62. }
  63. /**
  64. * @param string $consumer consumer
  65. * @param string $token token
  66. * @param string $nonce nonce
  67. * @param string $timestamp timestamp
  68. * @return mixed
  69. */
  70. public function lookup_nonce($consumer, $token, $nonce, $timestamp)
  71. {
  72. $token = DBA::selectFirst('tokens', ['id', 'secret'], ['client_id' => $consumer->key, 'id' => $nonce, 'expires' => $timestamp]);
  73. if (DBA::isResult($token)) {
  74. return new OAuthToken($token['id'], $token['secret']);
  75. }
  76. return null;
  77. }
  78. /**
  79. * @param string $consumer consumer
  80. * @param string $callback optional, default null
  81. * @return mixed
  82. */
  83. public function new_request_token($consumer, $callback = null)
  84. {
  85. Logger::log(__function__ . ":" . $consumer . ", " . $callback);
  86. $key = self::genToken();
  87. $sec = self::genToken();
  88. if ($consumer->key) {
  89. $k = $consumer->key;
  90. } else {
  91. $k = $consumer;
  92. }
  93. $r = DBA::insert(
  94. 'tokens',
  95. [
  96. 'id' => $key,
  97. 'secret' => $sec,
  98. 'client_id' => $k,
  99. 'scope' => 'request',
  100. 'expires' => time() + REQUEST_TOKEN_DURATION]
  101. );
  102. if (!$r) {
  103. return null;
  104. }
  105. return new OAuthToken($key, $sec);
  106. }
  107. /**
  108. * @param string $token token
  109. * @param string $consumer consumer
  110. * @param string $verifier optional, defult null
  111. * @return object
  112. */
  113. public function new_access_token($token, $consumer, $verifier = null)
  114. {
  115. Logger::log(__function__ . ":" . $token . ", " . $consumer . ", " . $verifier);
  116. // return a new access token attached to this consumer
  117. // for the user associated with this token if the request token
  118. // is authorized
  119. // should also invalidate the request token
  120. $ret = null;
  121. // get user for this verifier
  122. $uverifier = Config::get("oauth", $verifier);
  123. Logger::log(__function__ . ":" . $verifier . "," . $uverifier);
  124. if (is_null($verifier) || ($uverifier !== false)) {
  125. $key = self::genToken();
  126. $sec = self::genToken();
  127. $r = DBA::insert(
  128. 'tokens',
  129. [
  130. 'id' => $key,
  131. 'secret' => $sec,
  132. 'client_id' => $consumer->key,
  133. 'scope' => 'access',
  134. 'expires' => time() + ACCESS_TOKEN_DURATION,
  135. 'uid' => $uverifier]
  136. );
  137. if ($r) {
  138. $ret = new OAuthToken($key, $sec);
  139. }
  140. }
  141. DBA::delete('tokens', ['id' => $token->key]);
  142. if (!is_null($ret) && !is_null($uverifier)) {
  143. Config::delete("oauth", $verifier);
  144. }
  145. return $ret;
  146. }
  147. }