apioauthrequesttoken.php 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. <?php
  2. /**
  3. * StatusNet, the distributed open-source microblogging tool
  4. *
  5. * Issue temporary OAuth credentials (a request token)
  6. *
  7. * PHP version 5
  8. *
  9. * LICENCE: This program is free software: you can redistribute it and/or modify
  10. * it under the terms of the GNU Affero General Public License as published by
  11. * the Free Software Foundation, either version 3 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU Affero General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Affero General Public License
  20. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  21. *
  22. * @category API
  23. * @package StatusNet
  24. * @author Zach Copley <zach@status.net>
  25. * @copyright 2010 StatusNet, Inc.
  26. * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
  27. * @link http://status.net/
  28. */
  29. if (!defined('STATUSNET')) {
  30. exit(1);
  31. }
  32. /**
  33. * Issue temporary OAuth credentials (a request token)
  34. *
  35. * @category API
  36. * @package StatusNet
  37. * @author Zach Copley <zach@status.net>
  38. * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
  39. * @link http://status.net/
  40. */
  41. class ApiOAuthRequestTokenAction extends ApiOAuthAction
  42. {
  43. /**
  44. * Take arguments for running
  45. *
  46. * @param array $args $_REQUEST args
  47. *
  48. * @return boolean success flag
  49. */
  50. function prepare(array $args = array())
  51. {
  52. parent::prepare($args);
  53. // XXX: support "force_login" parameter like Twitter? (Forces the user to enter
  54. // their credentials to ensure the correct users account is authorized.)
  55. return true;
  56. }
  57. /**
  58. * Handle a request for temporary OAuth credentials
  59. *
  60. * Make sure the request is kosher, then emit a set of temporary
  61. * credentials -- AKA an unauthorized request token.
  62. *
  63. * @param array $args array of arguments
  64. *
  65. * @return void
  66. */
  67. function handle()
  68. {
  69. parent::handle();
  70. $datastore = new ApiGNUsocialOAuthDataStore();
  71. $server = new OAuthServer($datastore);
  72. $hmac_method = new OAuthSignatureMethod_HMAC_SHA1();
  73. $server->add_signature_method($hmac_method);
  74. try {
  75. $req = OAuthRequest::from_request();
  76. // verify callback
  77. if (!$this->verifyCallback($req->get_parameter('oauth_callback'))) {
  78. throw new OAuthException(
  79. "You must provide a valid URL or 'oob' in oauth_callback.",
  80. 400
  81. );
  82. }
  83. // check signature and issue a new request token
  84. $token = $server->fetch_request_token($req);
  85. common_log(
  86. LOG_INFO,
  87. sprintf(
  88. "API OAuth - Issued request token %s for consumer %s with oauth_callback %s",
  89. $token->key,
  90. $req->get_parameter('oauth_consumer_key'),
  91. "'" . $req->get_parameter('oauth_callback') ."'"
  92. )
  93. );
  94. // return token to the client
  95. $this->showRequestToken($token);
  96. } catch (OAuthException $e) {
  97. common_log(LOG_WARNING, 'API OAuthException - ' . $e->getMessage());
  98. // Return 401 for for bad credentials or signature problems,
  99. // and 400 for missing or unsupported parameters
  100. $code = $e->getCode();
  101. $this->clientError($e->getMessage(), empty($code) ? 401 : $code, 'text');
  102. }
  103. }
  104. /*
  105. * Display temporary OAuth credentials
  106. */
  107. function showRequestToken($token)
  108. {
  109. header('Content-Type: application/x-www-form-urlencoded');
  110. print $token;
  111. print '&oauth_callback_confirmed=true';
  112. }
  113. /* Make sure the callback parameter contains either a real URL
  114. * or the string 'oob'.
  115. *
  116. * @todo Check for evil/banned URLs here
  117. *
  118. * @return boolean true or false
  119. */
  120. function verifyCallback($callback)
  121. {
  122. if ($callback == "oob") {
  123. common_debug("OAuth request token requested for out of band client.");
  124. // XXX: Should we throw an error if a client is registered as a
  125. // web application but requests the pin based workflow? For now I'm
  126. // allowing the workflow to proceed and issuing a pin. --Zach
  127. return true;
  128. } else {
  129. return filter_var($callback, FILTER_VALIDATE_URL);
  130. }
  131. }
  132. }