ApiController.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403
  1. <?php
  2. namespace Opentalent\OtAdmin\Http;
  3. use Opentalent\OtAdmin\Controller\ScanController;
  4. use Opentalent\OtAdmin\Controller\SiteController;
  5. use Psr\Log\LoggerAwareInterface;
  6. use Psr\Log\LoggerAwareTrait;
  7. use TYPO3\CMS\Core\Http\JsonResponse;
  8. use TYPO3\CMS\Core\Http\ServerRequest;
  9. use TYPO3\CMS\Core\Utility\GeneralUtility;
  10. use TYPO3\CMS\Extbase\Object\ObjectManager;
  11. /**
  12. * Actions for Http API calls
  13. *
  14. * @package Opentalent\OtAdmin\Http
  15. */
  16. class ApiController implements LoggerAwareInterface
  17. {
  18. use LoggerAwareTrait;
  19. const ALLOWED_IPS = [
  20. '/^127\.0\.0\.[0-1]$/',
  21. '/^localhost$/',
  22. '/^10\.8\.0\.\d{1,3}$/',
  23. '/^80\.245\.24\.68$/', // prod-front
  24. '/^80\.245\.24\.70$/', // prod-back
  25. '/^80\.245\.24\.72$/', // test
  26. '/^80\.245\.24\.74$/' // preprod
  27. ];
  28. /**
  29. * Returns true if the client Ip is allowed
  30. *
  31. * @param string $clientIp
  32. * @return bool
  33. */
  34. public static function isIpAllowed(string $clientIp): bool
  35. {
  36. foreach (self::ALLOWED_IPS as $ipRule) {
  37. if (preg_match($ipRule, $clientIp)) {
  38. return true;
  39. }
  40. }
  41. return false;
  42. }
  43. /**
  44. * Check that the client Ip is allowed, else throw a Runtime error
  45. *
  46. * @return bool
  47. */
  48. private function assertIpAllowed(): bool
  49. {
  50. $clientIp = $_SERVER['REMOTE_ADDR'];
  51. if (!self::isIpAllowed($clientIp)){
  52. $route = $_REQUEST['route'];
  53. $this->logger->error(sprintf(
  54. "OtAdmin API: an attempt was made to call the route " .
  55. $route . " from an non-allowed IP (" . $clientIp . ")"));
  56. throw new \RuntimeException("Not allowed");
  57. }
  58. return true;
  59. }
  60. /**
  61. * Retrieve the organization's id from the given request parameters
  62. *
  63. * @param ServerRequest $request
  64. * @return int
  65. */
  66. private function getOrganizationId(ServerRequest $request): int
  67. {
  68. $params = $request->getQueryParams();
  69. $organizationId = $params['organization-id'];
  70. if (!$organizationId) {
  71. throw new \RuntimeException("Missing parameter: 'organization-id'");
  72. }
  73. return (int)$organizationId;
  74. }
  75. /**
  76. * -- Target of the route 'site_infos' --
  77. *
  78. * Return the main informations about the organization's website
  79. *
  80. * @param ServerRequest $request
  81. * @return JsonResponse
  82. * @throws \Exception
  83. */
  84. public function getSiteInfosAction(ServerRequest $request): JsonResponse
  85. {
  86. $this->assertIpAllowed();
  87. $organizationId = $this->getOrganizationId($request);
  88. $controller = GeneralUtility::makeInstance(ObjectManager::class)->get(SiteController::class);
  89. $infos = $controller->getSiteInfosAction($organizationId);
  90. return new JsonResponse($infos);
  91. }
  92. /**
  93. * -- Target of the route 'site_create' --
  94. * >> Requires a query param named 'organization-id' (int)
  95. *
  96. * Create the organization's website
  97. *
  98. * @param ServerRequest $request
  99. * @return JsonResponse
  100. * @throws \Exception
  101. */
  102. public function createSiteAction(ServerRequest $request): JsonResponse
  103. {
  104. $this->assertIpAllowed();
  105. $organizationId = $this->getOrganizationId($request);
  106. $controller = GeneralUtility::makeInstance(ObjectManager::class)->get(SiteController::class);
  107. $rootUid = $controller->createSiteAction($organizationId);
  108. $this->logger->info(sprintf(
  109. "OtAdmin API: A new website has been created with root page uid=" . $rootUid .
  110. " for the organization " . $organizationId));
  111. return new JsonResponse(
  112. [
  113. 'organization_id' => $organizationId,
  114. 'msg' => "A new website has been created with root page uid=" . $rootUid,
  115. 'root_uid' => $rootUid
  116. ]
  117. );
  118. }
  119. /**
  120. * -- Target of the route 'site_update' --
  121. * >> Requires a query param named 'organization-id' (int)
  122. *
  123. * Update the settings of the organization's website
  124. *
  125. * @param ServerRequest $request
  126. * @return JsonResponse
  127. * @throws \Exception
  128. */
  129. public function updateSiteConstantsAction(ServerRequest $request): JsonResponse
  130. {
  131. $this->assertIpAllowed();
  132. $organizationId = $this->getOrganizationId($request);
  133. $deep = (isset($queryParams['deep']) && $queryParams['deep']);
  134. $controller = GeneralUtility::makeInstance(ObjectManager::class)->get(SiteController::class);
  135. $rootUid = $controller->updateSiteAction($organizationId, $deep);
  136. $this->logger->info(sprintf(
  137. "OtAdmin API: The website with root uid " . $rootUid . " has been updated " .
  138. " (organization: " . $organizationId . ")"));
  139. return new JsonResponse(
  140. [
  141. 'organization_id' => $organizationId,
  142. 'msg' => "The website with root uid " . $rootUid . " has been updated",
  143. 'root_uid' => $rootUid
  144. ]
  145. );
  146. }
  147. /**
  148. * -- Target of the route 'site_delete' --
  149. * >> Requires a query param named 'organization-id' (int)
  150. *
  151. * Proceeds to a soft-deletion of the organization's website
  152. *
  153. * @param ServerRequest $request
  154. * @return JsonResponse
  155. * @throws \Exception
  156. */
  157. public function deleteSiteAction(ServerRequest $request): JsonResponse
  158. {
  159. $this->assertIpAllowed();
  160. $organizationId = $this->getOrganizationId($request);
  161. $params = $request->getQueryParams();
  162. $redirectTo = isset($params['redirect-to']) ? $params['redirect-to'] : null;
  163. $controller = GeneralUtility::makeInstance(ObjectManager::class)->get(SiteController::class);
  164. $rootUid = $controller->deleteSiteAction($organizationId, false, $redirectTo);
  165. $this->logger->info(sprintf(
  166. "OtAdmin API: The website with root uid " . $rootUid . " has been soft-deleted " .
  167. " (organization: " . $organizationId . ")"));
  168. return new JsonResponse(
  169. [
  170. 'organization_id' => $organizationId,
  171. 'msg' => "The website with root uid " . $rootUid . " has been soft-deleted. Use the /site/undelete route to restore it.",
  172. 'root_uid' => $rootUid
  173. ]
  174. );
  175. }
  176. /**
  177. * -- Target of the route 'site_undelete' --
  178. * >> Requires a query param named 'organization-id' (int)
  179. *
  180. * Restore a soft-deleted organization's website
  181. *
  182. * @param ServerRequest $request
  183. * @return JsonResponse
  184. * @throws \Exception
  185. */
  186. public function undeleteSiteAction(ServerRequest $request): JsonResponse
  187. {
  188. $this->assertIpAllowed();
  189. $organizationId = $this->getOrganizationId($request);
  190. $controller = GeneralUtility::makeInstance(ObjectManager::class)->get(SiteController::class);
  191. $rootUid = $controller->undeleteSiteAction($organizationId);
  192. $this->logger->info(sprintf(
  193. "OtAdmin API: The website with root uid " . $rootUid . " has been restored " .
  194. " (organization: " . $organizationId . ")"));
  195. return new JsonResponse(
  196. [
  197. 'organization_id' => $organizationId,
  198. 'msg' => "The website with root uid " . $rootUid . " has been restored",
  199. 'root_uid' => $rootUid
  200. ]
  201. );
  202. }
  203. /**
  204. * -- Target of the route 'site_clearcache' --
  205. * >> Requires a query param named 'organization-id' (int)
  206. *
  207. * Clear the cache of the organization's website
  208. *
  209. * @param ServerRequest $request
  210. * @return JsonResponse
  211. * @throws \Exception
  212. */
  213. public function clearSiteCacheAction(ServerRequest $request): JsonResponse
  214. {
  215. $this->assertIpAllowed();
  216. $organizationId = $this->getOrganizationId($request);
  217. $controller = GeneralUtility::makeInstance(ObjectManager::class)->get(SiteController::class);
  218. $rootUid = $controller->clearSiteCacheAction($organizationId);
  219. return new JsonResponse(
  220. [
  221. 'organization_id' => $organizationId,
  222. 'msg' => "The cache has been cleared for the website with root uid " . $rootUid . "",
  223. 'root_uid' => $rootUid
  224. ]
  225. );
  226. }
  227. /**
  228. * -- Target of the route 'site_setdomain' --
  229. * >> Requires a query param named 'organization-id' (int)
  230. *
  231. * Set a new domain for the organization website
  232. *
  233. * @param ServerRequest $request
  234. * @return JsonResponse
  235. * @throws \Exception
  236. */
  237. public function setSiteCustomDomainAction(ServerRequest $request): JsonResponse
  238. {
  239. $this->assertIpAllowed();
  240. $organizationId = $this->getOrganizationId($request);
  241. $queryParams = $request->getQueryParams();
  242. $domain = $queryParams['domain'];
  243. if (!$domain) {
  244. throw new \RuntimeException("Missing 'domain' parameter");
  245. }
  246. $redirect = (isset($queryParams['redirect']) && $queryParams['redirect']);
  247. $controller = GeneralUtility::makeInstance(ObjectManager::class)->get(SiteController::class);
  248. $rootUid = $controller->setSiteCustomDomainAction($organizationId, $domain, $redirect);
  249. return new JsonResponse(
  250. [
  251. 'organization_id' => $organizationId,
  252. 'msg' => "The cache has been cleared for the website with root uid " . $rootUid . "",
  253. 'root_uid' => $rootUid
  254. ]
  255. );
  256. }
  257. /**
  258. * -- Target of the route 'site_resetperms' --
  259. * >> Requires a query param named 'organization-id' (int)
  260. *
  261. * Reset the permissions of the website be users (admin, editors...)
  262. *
  263. * @param ServerRequest $request
  264. * @return JsonResponse
  265. * @throws \Exception
  266. */
  267. public function resetBeUserPermsAction(ServerRequest $request): JsonResponse
  268. {
  269. $this->assertIpAllowed();
  270. $organizationId = $this->getOrganizationId($request);
  271. $controller = GeneralUtility::makeInstance(ObjectManager::class)->get(SiteController::class);
  272. $rootUid = $controller->resetBeUserPermsAction($organizationId);
  273. return new JsonResponse(
  274. [
  275. 'organization_id' => $organizationId,
  276. 'msg' => "The website with root uid " . $rootUid . " had its be users permissions reset",
  277. 'root_uid' => $rootUid
  278. ]
  279. );
  280. }
  281. /**
  282. * -- Target of the route 'site_reindex' --
  283. * >> Requires a query param named 'organization-id' (int)
  284. *
  285. * Update the routing index for the given website
  286. *
  287. * @param ServerRequest $request
  288. * @return JsonResponse
  289. * @throws \Exception
  290. */
  291. public function updateRoutingIndexAction(ServerRequest $request): JsonResponse
  292. {
  293. $this->assertIpAllowed();
  294. $organizationId = $this->getOrganizationId($request);
  295. $controller = GeneralUtility::makeInstance(ObjectManager::class)->get(SiteController::class);
  296. $rootUid = $controller->updateRoutingIndexAction($organizationId);
  297. return new JsonResponse(
  298. [
  299. 'organization_id' => $organizationId,
  300. 'msg' => "The website with root uid " . $rootUid . " routing index has been updated",
  301. 'root_uid' => $rootUid
  302. ]
  303. );
  304. }
  305. /**
  306. * -- Target of the route 'site_status' --
  307. * >> Requires a query param named 'organization-id' (int)
  308. *
  309. * Returns the current status of the website
  310. *
  311. * @param ServerRequest $request
  312. * @return JsonResponse
  313. * @throws \Exception
  314. */
  315. public function getSiteStatusAction(ServerRequest $request): JsonResponse
  316. {
  317. $this->assertIpAllowed();
  318. $organizationId = $this->getOrganizationId($request);
  319. $controller = GeneralUtility::makeInstance(ObjectManager::class)->get(SiteController::class);
  320. $queryParams = $request->getQueryParams();
  321. $full = (isset($queryParams['full']) && $queryParams['full']);
  322. $status = $controller->getSiteStatusAction($organizationId, $full);
  323. return new JsonResponse($status->toArray());
  324. }
  325. /**
  326. * -- Target of the route 'scan' --
  327. *
  328. * Scan the whole Typo3 database and return the results
  329. *
  330. * @param ServerRequest $request
  331. * @return JsonResponse
  332. * @throws \Exception
  333. */
  334. public function scanAllAction(ServerRequest $request): JsonResponse
  335. {
  336. $this->assertIpAllowed();
  337. $controller = GeneralUtility::makeInstance(ObjectManager::class)->get(ScanController::class);
  338. $queryParams = $request->getQueryParams();
  339. $full = (isset($queryParams['full']) && $queryParams['full']);
  340. $results = $controller->scanAllAction($full);
  341. return new JsonResponse($results);
  342. }
  343. }