OCSMiddleware.php 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. <?php
  2. /**
  3. * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
  4. * SPDX-License-Identifier: AGPL-3.0-or-later
  5. */
  6. namespace OC\AppFramework\Middleware;
  7. use OC\AppFramework\Http;
  8. use OC\AppFramework\OCS\BaseResponse;
  9. use OC\AppFramework\OCS\V1Response;
  10. use OC\AppFramework\OCS\V2Response;
  11. use OCP\AppFramework\Controller;
  12. use OCP\AppFramework\Http\DataResponse;
  13. use OCP\AppFramework\Http\JSONResponse;
  14. use OCP\AppFramework\Http\Response;
  15. use OCP\AppFramework\Middleware;
  16. use OCP\AppFramework\OCS\OCSException;
  17. use OCP\AppFramework\OCSController;
  18. use OCP\IRequest;
  19. class OCSMiddleware extends Middleware {
  20. /** @var IRequest */
  21. private $request;
  22. /** @var int */
  23. private $ocsVersion;
  24. /**
  25. * @param IRequest $request
  26. */
  27. public function __construct(IRequest $request) {
  28. $this->request = $request;
  29. }
  30. /**
  31. * @param Controller $controller
  32. * @param string $methodName
  33. */
  34. public function beforeController($controller, $methodName) {
  35. if ($controller instanceof OCSController) {
  36. if (substr_compare($this->request->getScriptName(), '/ocs/v2.php', -strlen('/ocs/v2.php')) === 0) {
  37. $this->ocsVersion = 2;
  38. } else {
  39. $this->ocsVersion = 1;
  40. }
  41. $controller->setOCSVersion($this->ocsVersion);
  42. }
  43. }
  44. /**
  45. * @param Controller $controller
  46. * @param string $methodName
  47. * @param \Exception $exception
  48. * @throws \Exception
  49. * @return BaseResponse
  50. */
  51. public function afterException($controller, $methodName, \Exception $exception) {
  52. if ($controller instanceof OCSController && $exception instanceof OCSException) {
  53. $code = $exception->getCode();
  54. if ($code === 0) {
  55. $code = \OCP\AppFramework\OCSController::RESPOND_UNKNOWN_ERROR;
  56. }
  57. return $this->buildNewResponse($controller, $code, $exception->getMessage());
  58. }
  59. throw $exception;
  60. }
  61. /**
  62. * @param Controller $controller
  63. * @param string $methodName
  64. * @param Response $response
  65. * @return \OCP\AppFramework\Http\Response
  66. */
  67. public function afterController($controller, $methodName, Response $response) {
  68. /*
  69. * If a different middleware has detected that a request unauthorized or forbidden
  70. * we need to catch the response and convert it to a proper OCS response.
  71. */
  72. if ($controller instanceof OCSController && !($response instanceof BaseResponse)) {
  73. if ($response->getStatus() === Http::STATUS_UNAUTHORIZED) {
  74. $message = '';
  75. if ($response instanceof JSONResponse) {
  76. /** @var DataResponse $response */
  77. $message = $response->getData()['message'];
  78. }
  79. return $this->buildNewResponse($controller, OCSController::RESPOND_UNAUTHORISED, $message);
  80. }
  81. if ($response->getStatus() === Http::STATUS_FORBIDDEN) {
  82. $message = '';
  83. if ($response instanceof JSONResponse) {
  84. /** @var DataResponse $response */
  85. $message = $response->getData()['message'];
  86. }
  87. return $this->buildNewResponse($controller, Http::STATUS_FORBIDDEN, $message);
  88. }
  89. }
  90. return $response;
  91. }
  92. /**
  93. * @param Controller $controller
  94. * @param int $code
  95. * @param string $message
  96. * @return V1Response|V2Response
  97. */
  98. private function buildNewResponse(Controller $controller, $code, $message) {
  99. $format = $this->getFormat($controller);
  100. $data = new DataResponse();
  101. $data->setStatus($code);
  102. if ($this->ocsVersion === 1) {
  103. $response = new V1Response($data, $format, $message);
  104. } else {
  105. $response = new V2Response($data, $format, $message);
  106. }
  107. return $response;
  108. }
  109. /**
  110. * @param Controller $controller
  111. * @return string
  112. */
  113. private function getFormat(Controller $controller) {
  114. // get format from the url format or request format parameter
  115. $format = $this->request->getParam('format');
  116. // if none is given try the first Accept header
  117. if ($format === null) {
  118. $headers = $this->request->getHeader('Accept');
  119. $format = $controller->getResponderByHTTPHeader($headers, 'xml');
  120. }
  121. return $format;
  122. }
  123. }