/** * Dispatch class hook and render result * * @param string $className * @param string $hookName * @param array $body JSON decoded body params */ private function dispatchHook($className, $hookName, $body) { $verified = false; if (strpos($hookName, "before") === 0) { $verified = Client::verifyHookSign("__before_for_{$className}", $body["object"]["__before"]); } else { $verified = Client::verifyHookSign("__after_for_{$className}", $body["object"]["__after"]); } if (!$verified) { error_log("Invalid hook sign for {$hookName} {$className}" . " from {$this->env['REMOTE_ADDR']}"); $this->renderError("Unauthorized.", 401, 401); } $json = $body["object"]; $json["__type"] = "Object"; $json["className"] = $className; $obj = Client::decode($json, null); // set hook marks to prevent infinite loop. For example if user // invokes `$obj->save` in an afterSave hook, API will not again // invoke afterSave if we set hook marks. if (strpos($hookName, "before") === 0) { if (isset($json["__before"])) { $obj->set("__before", $json["__before"]); } else { $obj->disableBeforeHook(); } } else { if (isset($json["__after"])) { $obj->set("__after", $json["__after"]); } else { $obj->disableAfterHook(); } } // in beforeUpdate hook, attach updatedKeys to object so user // can detect changed keys in hook. if (isset($json["_updatedKeys"])) { $obj->updatedKeys = $json["_updatedKeys"]; } $meta["remoteAddress"] = $this->env["REMOTE_ADDR"]; try { $result = Cloud::runHook($className, $hookName, $obj, User::getCurrentUser(), $meta); } catch (FunctionError $err) { $this->renderError($err->getMessage(), $err->getCode()); } if ($hookName == "beforeDelete") { $this->renderJSON(array()); } else { if (strpos($hookName, "after") === 0) { $this->renderJSON(array("result" => "ok")); } else { $outObj = $result; // Encode result object to type-less literal JSON $this->renderJSON($outObj->toJSON()); } } }
public function testCircularGetCurrentUser() { // ensure getCurrentUser neither run indefinetely, nor throw maximum // function call error $avatar = File::createWithUrl("alice.png", "https://leancloud.cn/favicon.png"); $user = User::logIn("alice", "blabla"); $user->set("avatar", $avatar); $user->save(); $token = User::getCurrentSessionToken(); $user->logOut(); User::setCurrentSessionToken($token); $user2 = User::getCurrentUser(); $this->assertEquals($user2->getUsername(), "alice"); }