Example #1
0
 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("");
 }
Example #2
0
 /**
  * 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.");
     }
 }
Example #3
0
 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);
 }