/** * @param Oxygen_Http_Request $request * * @return null|Oxygen_Http_Response|Oxygen_Util_HookedClosure */ public function handle(Oxygen_Http_Request $request) { $dispatcher = $this->container->getDispatcher(); if (!$request->accepts('application/oxygen')) { // Public request. $publicRequestEvent = new Oxygen_Event_PublicRequestEvent($request); $dispatcher->dispatch(Oxygen_Event_Events::PUBLIC_REQUEST, $publicRequestEvent); if ($publicRequestEvent->hasDeferredResponse()) { return $publicRequestEvent->getDeferredResponse(); } return $publicRequestEvent->getResponse(); } try { // Master request. $requestData = json_decode($request->getContent(), true); if (!is_array($requestData)) { throw new RuntimeException('The request does not contain valid JSON.'); } /** @var Oxygen_Util_RequestData $requestData */ $requestData = (object) $requestData; $masterRequestEvent = new Oxygen_Event_MasterRequestEvent($request, $requestData); $dispatcher->dispatch(Oxygen_Event_Events::MASTER_REQUEST, $masterRequestEvent); $result = $this->container->getActionKernel()->handle($request, $requestData); if ($result instanceof Oxygen_Http_Response) { return $this->notifyResponse($request, $requestData, $result); } else { $callback = new Oxygen_Util_Closure(array($this, 'wrapResponse'), $request, $requestData, $result->getCallable()); return new Oxygen_Util_HookedClosure($result->getHookName(), $callback->getCallable()); } } catch (Exception $e) { return $this->handleException($request, isset($requestData) ? $requestData : null, $e); } }
/** * @param Oxygen_Http_Request $request * @param Oxygen_Util_RequestData $requestData * * @return Oxygen_Util_HookedClosure|Oxygen_Http_Response * @throws Oxygen_Exception */ public function handle(Oxygen_Http_Request $request, $requestData) { $actionDefinition = $this->actionRegistry->getDefinition($requestData->actionName); $hookName = $actionDefinition->getOption('hook_name'); if ($hookName === null) { return $this->handleRaw($request, $requestData, $actionDefinition->getClass(), $actionDefinition->getMethod(), $requestData->actionParameters); } $actionClosure = new Oxygen_Util_Closure(array($this, 'handleRaw'), $request, $requestData, $actionDefinition->getClass(), $actionDefinition->getMethod(), $requestData->actionParameters); return new Oxygen_Util_HookedClosure($hookName, $actionClosure->getCallable()); }
public function onPublicRequest(Oxygen_Event_PublicRequestEvent $event) { $params = $event->getRequest()->query; // @TODO: Move the logic below to kernel? We need at least one more action for that, or else it's an overkill. if (!isset($params['oxygenRequestId'])) { return; } if (!is_string($params['oxygenRequestId'])) { throw new Oxygen_Exception(Oxygen_Exception::PROTOCOL_REQUEST_ID_NOT_VALID); } if (!isset($params['actionName'])) { throw new Oxygen_Exception(Oxygen_Exception::PROTOCOL_ACTION_NAME_NOT_PROVIDED); } if (!is_string($params['actionName'])) { throw new Oxygen_Exception(Oxygen_Exception::PROTOCOL_ACTION_NAME_NOT_VALID); } if ($params['actionName'] !== 'site.login') { return; } if (!isset($params['requestExpiresAt'])) { throw new Oxygen_Exception(Oxygen_Exception::PROTOCOL_EXPIRATION_NOT_PROVIDED); } // The "is_numeric" check with more predictable behavior. if ((string) (int) $params['requestExpiresAt'] !== (string) $params['requestExpiresAt']) { throw new Oxygen_Exception(Oxygen_Exception::PROTOCOL_EXPIRATION_NOT_VALID); } if (!isset($params['signature'])) { throw new Oxygen_Exception(Oxygen_Exception::PROTOCOL_SIGNATURE_NOT_PROVIDED); } if (!is_string($params['signature'])) { throw new Oxygen_Exception(Oxygen_Exception::PROTOCOL_SIGNATURE_NOT_VALID); } if (!isset($params['userName'])) { throw new Oxygen_Exception(Oxygen_Exception::PROTOCOL_USER_NAME_NOT_PROVIDED); } if (!is_string($params['userName'])) { throw new Oxygen_Exception(Oxygen_Exception::PROTOCOL_USER_NAME_NOT_VALID); } if (!isset($params['userUid'])) { throw new Oxygen_Exception(Oxygen_Exception::PROTOCOL_USER_UID_NOT_PROVIDED); } if (!is_string($params['userUid']) || !preg_match('{^U\\d{10}$}', $params['userUid'])) { throw new Oxygen_Exception(Oxygen_Exception::PROTOCOL_USER_UID_NOT_VALID); } $params['requestExpiresAt'] = (int) $params['requestExpiresAt']; $publicKey = $this->state->get('oxygen_public_key'); if (!$publicKey) { throw new Oxygen_Exception(Oxygen_Exception::PUBLIC_KEY_MISSING); } if (!$this->rsaVerifier->verify($publicKey, sprintf('%s|%d|%s|%s', $params['oxygenRequestId'], $params['requestExpiresAt'], $params['userUid'], $params['userName']), $params['signature'])) { throw new Oxygen_Exception(Oxygen_Exception::HANDSHAKE_VERIFY_FAILED); } $this->nonceManager->useNonce($params['oxygenRequestId'], $params['requestExpiresAt']); $closure = new Oxygen_Util_Closure(array($this, 'loginUser'), $params['userUid'], $params['userName']); $event->setDeferredResponse(new Oxygen_Util_HookedClosure('init', $closure->getCallable())); }