PageRenderTime 52ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/api/oauth.php

https://gitlab.com/craftbynick/Circular
PHP | 243 lines | 160 code | 52 blank | 31 comment | 21 complexity | 8c394575e8df945f2d431d23f5d0fbfc MD5 | raw file
  1. <?php
  2. /**
  3. * @see tmhOAuth/examples/oauth_flow.php
  4. *
  5. * If the user doesn't already have an active session, we use `authenticate` instead of `authorize`
  6. * so that a user having already authorized the app doesn't have to do it again.
  7. * If on the other hand, the user already has an active session, we use `authorize`
  8. * so that he can log out from his current Twitter account and log in as somebody else if needed.
  9. */
  10. require 'config.php';
  11. require '../extlib/tmhOAuth/tmhOAuth.php';
  12. require '../extlib/tmhOAuth/tmhUtilities.php';
  13. $tmhOAuth = new tmhOAuth(array(
  14. 'consumer_key' => CONSUMER_KEY,
  15. 'consumer_secret' => CONSUMER_SECRET,
  16. ));
  17. header('Content-type: application/json');
  18. session_set_cookie_params(60*60*24*30);
  19. ini_set('session.gc_maxlifetime', 60*60*24*30);
  20. session_start();
  21. function outputError($tmhOAuth) {
  22. header('HTTP/1.1 500 Internal Server Error');
  23. echo json_encode($tmhOAuth->response['response']);
  24. }
  25. function wipe() {
  26. session_destroy();
  27. echo json_encode(array('wiped' => "success"));
  28. }
  29. // Step 1: Request a temporary token
  30. function request_token($tmhOAuth) {
  31. $code = $tmhOAuth->request(
  32. 'POST',
  33. $tmhOAuth->url('oauth/request_token', ''),
  34. array(
  35. 'oauth_callback' => tmhUtilities::php_self()
  36. )
  37. );
  38. if ($code == 200) {
  39. $_SESSION['oauth'] = $tmhOAuth->extract_params($tmhOAuth->response['response']);
  40. if (isset($_SESSION['account']['id'])) {
  41. // We already have a logged in user account
  42. authorize($tmhOAuth);
  43. }
  44. else {
  45. authenticate($tmhOAuth);
  46. }
  47. }
  48. else {
  49. outputError($tmhOAuth);
  50. }
  51. }
  52. // Step 2: Direct the user to the authenticate web page
  53. function authenticate($tmhOAuth) {
  54. $authurl = $tmhOAuth->url("oauth/authenticate", '') . "?oauth_token={$_SESSION['oauth']['oauth_token']}";
  55. echo json_encode(array('authurl' => $authurl));
  56. }
  57. function authorize($tmhOAuth) {
  58. $authurl = $tmhOAuth->url("oauth/authorize", '') . "?oauth_token={$_SESSION['oauth']['oauth_token']}";
  59. echo json_encode(array('authurl' => $authurl));
  60. }
  61. // Step 3: This is the code that runs when Twitter redirects the user to the callback. Exchange the temporary token for a permanent access token
  62. function access_token($tmhOAuth) {
  63. $tmhOAuth->config['user_token'] = $_SESSION['oauth']['oauth_token'];
  64. $tmhOAuth->config['user_secret'] = $_SESSION['oauth']['oauth_token_secret'];
  65. $code = $tmhOAuth->request(
  66. 'POST',
  67. $tmhOAuth->url('oauth/access_token', ''),
  68. array(
  69. 'oauth_verifier' => $_REQUEST['oauth_verifier']
  70. )
  71. );
  72. if ($code == 200) {
  73. unset($_SESSION['oauth']);
  74. $access_token = $tmhOAuth->extract_params($tmhOAuth->response['response']);
  75. $user_id = (int) $access_token['user_id'];
  76. $m = new Mongo();
  77. $user = $m->circular->users->findOne(array('user_id' => $user_id));
  78. if ($user) {
  79. // This Twitter user has already logged in before.
  80. }
  81. else {
  82. // This Twitter user has never logged in before, add him to our users.
  83. $user = array(
  84. 'user_id' => (int) $access_token['user_id'],
  85. 'user_screen_name' => $access_token['screen_name'],
  86. 'user_token' => $access_token['oauth_token'],
  87. 'user_secret' => $access_token['oauth_token_secret']
  88. );
  89. $m->circular->users->insert($user, array('safe' => true));
  90. }
  91. // We now have our $user, including $user['_id'] (the user's MongoId in our system).
  92. // Now let's figure out which account manages this user:
  93. if (isset($_SESSION['account']['id'])) {
  94. // We already have a logged in user account
  95. $m->circular->accounts->update(
  96. array('_id' => new MongoId($_SESSION['account']['id'])),
  97. array('$addToSet' => array('users' => $user['_id'])),
  98. array('safe' => true)
  99. );
  100. $account = $m->circular->accounts->findOne(array('_id' => new MongoId($_SESSION['account']['id'])));
  101. // Is there a way to do the previous two operations in one operation?
  102. // Remove the user from any other account (we don't want any user to be managed by several accounts)
  103. // This enables "merging" accounts.
  104. $m->circular->accounts->update(
  105. array(
  106. '_id' => array('$ne' => new MongoId($_SESSION['account']['id'])),
  107. 'users' => $user['_id']
  108. ),
  109. array(
  110. '$pull' => array('users' => $user['_id'])
  111. )
  112. );
  113. // Should we remove accounts that have no more users?
  114. }
  115. else {
  116. // No account's logged in right now
  117. $account = $m->circular->accounts->findOne(array('users' => $user['_id']));
  118. if ($account) {
  119. // We have retrieved an existing account for this user.
  120. }
  121. else {
  122. // We don't have an account for this user, let's create one:
  123. $account = array('users' => array($user['_id']));
  124. $m->circular->accounts->insert(
  125. $account,
  126. array('safe' => true)
  127. );
  128. }
  129. }
  130. // At this point, we have our $account, containing MongoId references to several users.
  131. $_SESSION['account']['id'] = (string) $account['_id'];
  132. $_SESSION['account']['users'] = array();
  133. foreach ($account['users'] as $user) {
  134. $_SESSION['account']['users'][(string) $user] = array();
  135. }
  136. header('Location: ' . APP_URL);
  137. }
  138. else {
  139. outputError($tmhOAuth);
  140. }
  141. }
  142. // Step 4: Now the user has authenticated, do something with the permanent token and secret we received
  143. function verify_credentials($tmhOAuth, $id) {
  144. $m = new Mongo();
  145. $user = $m->circular->users->findOne(array('_id' => new MongoId($id)));
  146. $tmhOAuth->config['user_token'] = $user['user_token'];
  147. $tmhOAuth->config['user_secret'] = $user['user_secret'];
  148. $code = $tmhOAuth->request(
  149. 'GET',
  150. $tmhOAuth->url('1.1/account/verify_credentials')
  151. );
  152. if ($code == 200) {
  153. $response = json_decode($tmhOAuth->response['response']);
  154. $_SESSION['account']['users'][$id] = array(
  155. 'user_id' => $response->id,
  156. 'user_screen_name' => $response->screen_name,
  157. 'profile_image_url' => $response->profile_image_url,
  158. 'name' => $response->name,
  159. 'id' => $id
  160. );
  161. }
  162. else {
  163. outputError($tmhOAuth);
  164. }
  165. }
  166. /* Auth Flow */
  167. if (isset($_REQUEST['wipe'])) {
  168. // Logging out
  169. wipe();
  170. return;
  171. }
  172. if (isset($_REQUEST['start'])) {
  173. // Let's start the OAuth dance
  174. request_token($tmhOAuth);
  175. }
  176. elseif (isset($_REQUEST['oauth_verifier'])) {
  177. access_token($tmhOAuth);
  178. }
  179. elseif (isset($_SESSION['account'])) {
  180. // Some credentials already stored in this browser session.
  181. foreach ($_SESSION['account']['users'] as $id => $user) {
  182. if (!isset($user['profile_image_url'])) {
  183. verify_credentials($tmhOAuth, $id);
  184. }
  185. }
  186. echo json_encode($_SESSION['account']);
  187. }
  188. else {
  189. // User's not logged in.
  190. echo json_encode(array('loggedin' => false));
  191. }