PageRenderTime 41ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/core/Services/OAuthServer/Controller.php

https://gitlab.com/ElvisAns/tiki
PHP | 270 lines | 198 code | 46 blank | 26 comment | 27 complexity | fc1c3a9dab814de47ecb1491fd3cc29b MD5 | raw file
  1. <?php
  2. // (c) Copyright by authors of the Tiki Wiki CMS Groupware Project
  3. //
  4. // All Rights Reserved. See copyright.txt for details and a complete list of authors.
  5. // Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details.
  6. // $Id$
  7. use Services_OAuthServer_JsonResponse as JsonResponse;
  8. class Services_OAuthServer_Controller
  9. {
  10. public function setUp()
  11. {
  12. $this->utilities = new Services_OAuthServer_Utilities();
  13. }
  14. /*
  15. * OAuth protocol actions
  16. */
  17. /**
  18. * It return an access_token in Implicit Grant or Client Credentials Grant flows
  19. * or an authorization code for other grants. The authorization code can be
  20. * exchanged for an access token using action_access_token method.
  21. *
  22. * On AuthCode grant method, it may throw an exception in case
  23. * of wrong CSRF token.
  24. *
  25. * Other flows different than ImplicitGrant, AuthCodeGrant, RefreshTokenGrant,
  26. * and ClientCredentialsGrant are not supported and will raise an exception.
  27. *
  28. * @param JitFilter $request
  29. * @return void
  30. */
  31. public function action_authorize($request)
  32. {
  33. global $user;
  34. $accesslib = TikiLib::lib('access');
  35. $oauthserverlib = TikiLib::lib('oauthserver');
  36. $servicelib = TikiLib::lib('service');
  37. $params = $request->getStored();
  38. if ($params['response_type'] === 'code') {
  39. if (empty($user)) {
  40. $params['action'] = 'consent';
  41. $params['controller'] = 'oauthserver';
  42. TikiLib::setExternalContext(true);
  43. $consent_url = $servicelib->getUrl($params);
  44. $accesslib->redirect($consent_url);
  45. exit;
  46. }
  47. // this should throw exception on failure
  48. // TODO If this is a POST then second parameter should be false
  49. $accesslib->checkCsrf(null, true, 'ticket', null, null, 'services');
  50. }
  51. $oauthserverlib->determineServerGrant();
  52. $server = $oauthserverlib->getServer();
  53. $userEntity = $oauthserverlib->getUserEntity();
  54. // The oauth library give the default for "not set" info
  55. foreach ($request as $key => $value) {
  56. if (empty($value)) {
  57. unset($request[$key]);
  58. }
  59. }
  60. $params = $request->getStored();
  61. $request = $this->utilities->tiki2Psr7Request($request);
  62. $authRequest = $server->validateAuthorizationRequest($request);
  63. $authRequest->setUser($userEntity);
  64. $authRequest->setAuthorizationApproved(true);
  65. $response = new JsonResponse();
  66. $response = $server->completeAuthorizationRequest($authRequest, $response);
  67. $this->utilities->processPsr7Response($response);
  68. }
  69. public function action_access_token($request)
  70. {
  71. $accesslib = TikiLib::lib('access');
  72. $oauthserverlib = TikiLib::lib('oauthserver');
  73. $oauthserverlib->determineServerGrant();
  74. $request = $this->utilities->tiki2Psr7Request($request);
  75. $response = new JsonResponse();
  76. $server = $oauthserverlib->getServer();
  77. $server->respondToAccessTokenRequest($request, $response);
  78. $this->utilities->processPsr7Response($response);
  79. }
  80. public function action_consent($request)
  81. {
  82. global $user;
  83. $params = $request->getQueryParams();
  84. /** @var OAuthServerLib $oauthserverlib */
  85. $oauthserverlib = TikiLib::lib('oauthserver');
  86. $accesslib = TikiLib::lib('access');
  87. $servicelib = TikiLib::lib('service');
  88. $form = array();
  89. if (empty($user)) {
  90. unset($_SESSION['loginfrom']);
  91. $_SESSION['loginfrom'] = $servicelib->getUrl($params);
  92. $accesslib->redirect('tiki-login_scr.php');
  93. exit;
  94. }
  95. if (empty($params['response_type'])) {
  96. header('400 Bad Request');
  97. throw new Services_Exception_NotAvailable(tr('Missing %0 parameter', 'response_type'));
  98. }
  99. $form['response_type'] = $params['response_type'];
  100. if (empty($params['client_id'])) {
  101. header('400 Bad Request');
  102. throw new Services_Exception_NotAvailable(tr('Missing %0 parameter', 'client_id'));
  103. }
  104. $client = $oauthserverlib->getClient($params['client_id']);
  105. if (empty($client)) {
  106. header('400 Bad Request');
  107. throw new Services_Exception_NotAvailable(tr('Not Found'));
  108. }
  109. $form['redirect_uri'] = $client->getRedirectUri();
  110. if (! empty('redirect_uri')) {
  111. $form['redirect_uri'] = $params['redirect_uri'];
  112. }
  113. $form['scope'] = '';
  114. if (! empty('scope')) {
  115. $form['scope'] = $params['scope'];
  116. }
  117. $form = array_map('htmlspecialchars', $form);
  118. $smarty = TikiLib::lib('smarty');
  119. $smarty->assign('metatag_robots', 'NOINDEX, NOFOLLOW');
  120. $smarty->assign('authorize_url', $servicelib->getUrl([
  121. 'action' => 'authorize',
  122. 'controller' => 'oauthserver',
  123. 'response_type' => 'code'
  124. ]));
  125. $smarty->assign('response_type', $form['response_type']);
  126. $smarty->assign('client', $client);
  127. $smarty->assign('redirect_uri', $form['redirect_uri']);
  128. $smarty->assign('scope', $form['scope']);
  129. $smarty->assign('mid', 'oauthserver/consent.tpl');
  130. $smarty->display("tiki.tpl");
  131. exit;
  132. }
  133. public function action_client_modify($request)
  134. {
  135. $access = TikiLib::lib('access');
  136. $request = $this->utilities->tiki2Psr7Request($request);
  137. $access->check_permission('tiki_p_admin');
  138. $params = array('delete' => null);
  139. if ($request->getMethod() !== 'POST') {
  140. $response = new JsonResponse(405, [], '');
  141. return $this->utilities->processPsr7Response($response);
  142. }
  143. $oauthserverlib = TikiLib::lib('oauthserver');
  144. $repo = $oauthserverlib->getClientRepository();
  145. $params = array_merge($params, $request->getQueryParams());
  146. $client = ClientEntity::build($params);
  147. $response_content = null;
  148. $response_code = null;
  149. $validation_errors = $repo->validate($client);
  150. if ($client->getId()) {
  151. if ($repo->exists($client)) {
  152. if ($params['delete'] === '1') {
  153. $repo->delete($client);
  154. $response_code = 200;
  155. $response_content = true;
  156. } elseif (empty($validation_errors)) {
  157. $repo->update($client);
  158. $response_code = 200;
  159. $response_content = $client->toArray();
  160. } else {
  161. $response_code = 400;
  162. $response_content = $validation_errors;
  163. }
  164. } else {
  165. $response_code = 404;
  166. $response_content = ['error' => 'Client not found'];
  167. }
  168. } elseif ($params['delete'] !== '1' && empty($validation_errors)) {
  169. $client->setClientId($repo::generateSecret(32));
  170. $client->setClientSecret($repo::generateSecret(64));
  171. $repo->create($client);
  172. $response_content = $client->toArray();
  173. $response_code = 201;
  174. } else {
  175. $response_code = 400;
  176. $response_content = $validation_errors;
  177. }
  178. $response = new JsonResponse($response_code, [], $response_content);
  179. return $this->utilities->processPsr7Response($response);
  180. }
  181. public function action_check($request)
  182. {
  183. $request = $this->utilities->tiki2Psr7Request($request);
  184. $params = $request->getQueryParams();
  185. $oauthserverlib = TikiLib::lib('oauthserver');
  186. if ($request->getMethod() !== 'GET') {
  187. $response = new JsonResponse(405, [], '');
  188. return $this->utilities->processPsr7Response($response);
  189. }
  190. $authorization = $request->getHeaderLine('Authorization') ?: '';
  191. $authorization = preg_split('/ */', $authorization);
  192. $valid = ! empty($params['auth_token'])
  193. && count($authorization) === 2
  194. && strcasecmp($authorization[0], 'Basic') === 0
  195. && ! empty($authorization = base64_decode($authorization[1]));
  196. if (! $valid) {
  197. $response = new JsonResponse(400, [], 'Missing content');
  198. return $this->utilities->processPsr7Response($response);
  199. }
  200. list($client_id, $client_secret) = explode(':', $authorization);
  201. $repo = $oauthserverlib->getClientRepository();
  202. $client = $repo->get($client_id);
  203. if (! $client || $client->getClientSecret() !== trim($client_secret)) {
  204. $response = new JsonResponse(403, [], 'Invalid client');
  205. return $this->utilities->processPsr7Response($response);
  206. }
  207. $repo = $oauthserverlib->getAccessTokenRepository();
  208. $token = $repo->get($params['auth_token']);
  209. $valid = ! empty($token);
  210. $valid = $valid
  211. && $token->getClient()->getIdentifier() == $client->getIdentifier();
  212. if (! $valid) {
  213. $response = new JsonResponse(403, [], 'Invalid token');
  214. return $this->utilities->processPsr7Response($response);
  215. }
  216. $response = new JsonResponse(200, [], 'ok');
  217. return $this->utilities->processPsr7Response($response);
  218. }
  219. public function action_public_key()
  220. {
  221. global $prefs;
  222. return ['key' => TikiLib::lib('oauthserver')->getPublicKey()];
  223. }
  224. }