public function doLogIn(Request $request, Response $response, array $args) { $session = (yield (new Session($request))->read()); $provider = $this->getProviderFromString($args["provider"]); $token = $session->get("token:oauth"); $get = $request->getQueryVars(); $code = isset($get["code"]) && is_string($get["code"]) ? $get["code"] : ""; $state = isset($get["state"]) && is_string($get["state"]) ? $get["state"] : ""; if (empty($code) || empty($state) || empty($token) || !hash_equals($token, $state)) { $response->setStatus(400); $response->setHeader("aerys-generic-response", "enable"); $response->send(""); return; } try { $accessToken = (yield resolve($provider->getAccessTokenFromCode($code))); } catch (OAuthException $e) { // TODO pretty error page $response->setStatus(403); $response->setHeader("aerys-generic-response", "enable"); $response->send(""); return; } catch (ResolutionException $e) { // TODO pretty error page $response->setStatus(503); $response->setHeader("aerys-generic-response", "enable"); $response->send(""); return; } $identity = (yield resolve($provider->getIdentity($accessToken))); if (!$identity) { $response->setStatus(403); $response->setHeader("aerys-generic-response", "enable"); $response->send(""); return; } $query = (yield $this->db->prepare("SELECT user_id FROM oauth WHERE provider = ? AND identity = ?", [$args["provider"], $identity["id"]])); $response->setStatus(302); $user = (yield $query->fetchObject()); $query = (yield $this->db->prepare("SELECT id, name, avatar FROM user WHERE id = ?", [$user->user_id])); $user = (yield $query->fetchObject()); (yield $session->open()); if ($user) { $session->set("login", $user->id); $session->set("login:name", $user->name); $session->set("login:avatar", $user->avatar); $session->set("login:time", time()); $response->setHeader("location", "/"); } else { $session->set("auth:provider", $args["provider"]); $session->set("auth:identity:id", $identity["id"]); $session->set("auth:identity:name", $identity["name"]); $session->set("auth:identify:avatar", $identity["avatar"]); $response->setHeader("location", "/join"); } (yield $session->save()); $response->send(""); }
/** * Handles all hooks. * * @param Request $request HTTP request * @param Response $response HTTP response * @param array $args URL args */ public function handle(Request $request, Response $response, array $args) { $response->setHeader("content-type", "text/plain"); $token = $request->getQueryVars()["token"] ?? ""; if (!$token || !is_string($token)) { $response->setStatus(401); $response->send("Failure: No token was provided."); return; } // use @ so we don't have to check for invalid strings manually $token = (string) @hex2bin($token); $hook = (yield $this->hookRepository->get($args["id"])); if (!$hook) { $response->setStatus(404); $response->send("Failure: Hook does not exist."); return; } if (!hash_equals($hook->token, $token)) { $response->setStatus(403); $response->send("Failure: Provided token doesn't match."); return; } $name = $args["service"]; if (!isset($this->services[$name])) { $response->setStatus(404); $response->send("Failure: Unknown service."); return; } $contentType = strtok($request->getHeader("content-type"), ";"); $body = (yield $request->getBody()); switch ($contentType) { case "application/json": $payload = json_decode($body); break; case "application/x-www-form-urlencoded": parse_str($body, $payload); $payload = json_decode(json_encode($payload)); break; default: $response->setStatus(415); $response->send("Failure: Content-type not supported."); return; } $service = $this->services[$name]; $headers = $request->getAllHeaders(); $event = $service->getEventName($headers, $payload); if (!isset($this->schemas[$name][$event])) { $response->setStatus(400); $response->send("Failure: Event not supported."); return; } $schema = $this->schemas[$name][$event]; $this->validator->reset(); $this->validator->check($payload, $schema); if (!$this->validator->isValid()) { $errors = $this->validator->getErrors(); $errors = array_reduce($errors, function (string $carry, array $item) : string { if ($item["property"]) { return $carry . sprintf("\n%s: %s", $item["property"], $item["message"]); } else { return $carry . "\n" . $item["message"]; } }, ""); $response->setStatus(400); $response->send("Failure: Payload validation failed." . $errors); return; } $message = $service->handle($headers, $payload); try { if ($message) { $req = (new HttpRequest())->setMethod("PUT")->setUri($this->config["api"] . "/messages")->setHeader("authorization", "Basic " . base64_encode("{$this->config['user_id']}:{$this->config['token']}"))->setBody(json_encode(["room_id" => $hook->room_id, "text" => $message->getText(), "data" => $message->getData()])); $resp = (yield $this->http->request($req)); if (intval($resp->getStatus() / 100) !== 2) { $message = "API request failed: " . $resp->getStatus(); if ($resp->getBody()) { $message .= "\n" . $resp->getBody(); } throw new Exception($message); } } $response->send("Success: " . ($message ? "Message sent." : "Message skipped.")); } catch (Exception $e) { $response->setStatus(500); $response->send("Failure: Couldn't persist message."); } }
public function handle(Request $request, Response $response, array $args) { $endpoint = $request->getLocalVar("chat.api.endpoint"); $user = $request->getLocalVar("chat.api.user"); if (!$endpoint || !$user) { // if this happens, something's really wrong, e.g. wrong order of callables $response->setStatus(500); $response->send(""); } foreach ($args as $key => $arg) { if (is_numeric($arg)) { $args[$key] = (int) $arg; } } foreach ($request->getQueryVars() as $key => $value) { // Don't allow overriding URL parameters if (isset($args[$key])) { continue; } if (is_numeric($value)) { $args[$key] = (int) $value; } else { if (is_string($value)) { $args[$key] = $value; } else { $result = new Error("bad_request", "invalid query parameter types", 400); $this->writeResponse($request, $response, $result); return; } } } $args = $args ? (object) $args : new stdClass(); $body = (yield $request->getBody()); $payload = $body ? json_decode($body) : null; $result = (yield $this->chat->process(new StandardRequest($endpoint, $args, $payload), $user)); $this->writeResponse($request, $response, $result); }