From: Michael Wallner Date: Mon, 11 May 2015 09:38:17 +0000 (+0200) Subject: fix saveToCache() usage; move hook controllers around X-Git-Url: https://git.m6w6.name/?p=pharext%2Fpharext.org;a=commitdiff_plain;h=25b99959b9e66d00681092977c23b5df32ead5f4 fix saveToCache() usage; move hook controllers around --- diff --git a/app/Controller/Github.php b/app/Controller/Github.php index 5933fcd..0c38bd7 100644 --- a/app/Controller/Github.php +++ b/app/Controller/Github.php @@ -58,7 +58,7 @@ abstract class Github implements Controller if ($repo->hooks) { foreach ($repo->hooks as $hook) { if ($hook->name === "web" && $hook->config->url === $this->github->getConfig()->hook->url) { - return $hook->id; + return $hook; } } } diff --git a/app/Controller/Github/Hook.php b/app/Controller/Github/Hook.php deleted file mode 100644 index bbfab2a..0000000 --- a/app/Controller/Github/Hook.php +++ /dev/null @@ -1,146 +0,0 @@ -app = $app; - $this->github = $github; - $this->accounts = $accounts; - } - - function __invoke(array $args = []) { - $request = $this->app->getRequest(); - $response = $this->app->getResponse(); - - if (!($sig = $request->getHeader("X-Hub-Signature")) || !($evt = $request->getHeader("X-Github-Event"))) { - $response->setResponseCode(400); - $response->setContentType("message/http"); - $response->getBody()->append($request); - } else { - $key = $this->github->getConfig()->client->secret; - foreach ((new Params($sig))->params as $algo => $mac) { - if ($mac["value"] !== hash_hmac($algo, $request->getBody(), $key)) { - $response->setResponseCode(403); - $response->getBody()->append("Invalid signature"); - return; - } - } - } - - switch ($evt) { - default: - $response->setResponseCode(202); - $response->getBody()->append("Not a configured event"); - break; - case "ping"; - $response->setResponseCode(204); - $response->setResponseStatus("PONG"); - break; - case "create": - case "release": - if (($json = json_decode($request->getBody()))) { - $this->$evt($json); - } else { - $response->setResponseCode(415); - $response->setContentType($request->getHeader("Content-Type")); - $response->getBody()->append($request->getBody()); - } - break; - } - } - - function release($release) { - if ($release->action !== "published") { - $response = $this->app->getResponse(); - - $response->setResponseCode(202); - $response->getBody()->append("Not published"); - return; - } - - $this->uploadAssetForRelease($release->release, $release->repository); - } - - private function uploadAssetForRelease($release, $repo) { - $this->setTokenForUser($repo->owner->login); - $asset = $this->createReleaseAsset($release, $repo); - // FIXME: use uri_template extension - $name = sprintf("%s-%s.ext.phar", $repo->name, $release->tag_name); - $url = str_replace("{?name}", "?name=$name", $release->upload_url); - $this->github->createReleaseAsset($url, $asset, "application/phar", function($json) { - $response = $this->app->getResponse(); - $response->setResponseCode(201); - $response->setHeader("Location", $json->url); - })->send(); - } - - private function createReleaseAsset($release, $repo) { - define("STDERR", fopen("/var/log/apache2/php_errors.log", "a")); - $source = (new Task\GitClone($repo->clone_url, $release->tag_name))->run(); - $iterator = new Git($source); - $meta = [ - "header" => sprintf("pharext v%s (c) Michael Wallner ", \pharext\VERSION), - "version" => \pharext\VERSION, - "date" => date("Y-m-d"), - "name" => $repo->name, - "release" => $release->tag_name, - "license" => @file_get_contents(current(glob($iterator->getBaseDir()."/LICENSE*"))), - "stub" => "pharext_installer.php", - "type" => false ? "zend_extension" : "extension", - ]; - $file = (new Task\PharBuild($iterator, $meta))->run(); - return $file; - } - - function create($create) { - if ($create->ref_type !== "tag") { - $response = $this->app->getResponse(); - - $response->setResponseCode(202); - $response->getBody()->append("Not a tag"); - return; - } - - $this->createReleaseFromTag($create->ref, $create->repository); - } - - private function setTokenForUser($login) { - $relations = [ - $this->accounts->getTokens()->getRelation("accounts"), - $this->accounts->getOwners()->getRelation("accounts") - ]; - $tokens = $this->accounts->getTokens()->with($relations, [ - "login=" => $login, - "tokens.authority=" => "github", - ]); - - if (count($tokens)) { - $this->github->setToken($tokens->current()->token->get()); - } - } - - private function createReleaseFromTag($tag, $repo) { - $this->setTokenForUser($repo->owner->login); - $this->github->createRelease($repo->full_name, $tag, function($json) { - $response = $this->app->getResponse(); - $response->setResponseCode(201); - $response->setHeader("Location", $json->url); - })->send(); - } -} diff --git a/app/Controller/Github/Hook/Receive.php b/app/Controller/Github/Hook/Receive.php new file mode 100644 index 0000000..48e10ae --- /dev/null +++ b/app/Controller/Github/Hook/Receive.php @@ -0,0 +1,146 @@ +app = $app; + $this->github = $github; + $this->accounts = $accounts; + } + + function __invoke(array $args = []) { + $request = $this->app->getRequest(); + $response = $this->app->getResponse(); + + if (!($sig = $request->getHeader("X-Hub-Signature")) || !($evt = $request->getHeader("X-Github-Event"))) { + $response->setResponseCode(400); + $response->setContentType("message/http"); + $response->getBody()->append($request); + } else { + $key = $this->github->getConfig()->client->secret; + foreach ((new Params($sig))->params as $algo => $mac) { + if ($mac["value"] !== hash_hmac($algo, $request->getBody(), $key)) { + $response->setResponseCode(403); + $response->getBody()->append("Invalid signature"); + return; + } + } + } + + switch ($evt) { + default: + $response->setResponseCode(202); + $response->getBody()->append("Not a configured event"); + break; + case "ping"; + $response->setResponseCode(204); + $response->setResponseStatus("PONG"); + break; + case "create": + case "release": + if (($json = json_decode($request->getBody()))) { + $this->$evt($json); + } else { + $response->setResponseCode(415); + $response->setContentType($request->getHeader("Content-Type")); + $response->getBody()->append($request->getBody()); + } + break; + } + } + + function release($release) { + if ($release->action !== "published") { + $response = $this->app->getResponse(); + + $response->setResponseCode(202); + $response->getBody()->append("Not published"); + return; + } + + $this->uploadAssetForRelease($release->release, $release->repository); + } + + private function uploadAssetForRelease($release, $repo) { + $this->setTokenForUser($repo->owner->login); + $asset = $this->createReleaseAsset($release, $repo); + // FIXME: use uri_template extension + $name = sprintf("%s-%s.ext.phar", $repo->name, $release->tag_name); + $url = str_replace("{?name}", "?name=$name", $release->upload_url); + $this->github->createReleaseAsset($url, $asset, "application/phar", function($json) { + $response = $this->app->getResponse(); + $response->setResponseCode(201); + $response->setHeader("Location", $json->url); + })->send(); + } + + private function createReleaseAsset($release, $repo) { + define("STDERR", fopen("/var/log/apache2/php_errors.log", "a")); + $source = (new Task\GitClone($repo->clone_url, $release->tag_name))->run(); + $iterator = new Git($source); + $meta = [ + "header" => sprintf("pharext v%s (c) Michael Wallner ", \pharext\VERSION), + "version" => \pharext\VERSION, + "date" => date("Y-m-d"), + "name" => $repo->name, + "release" => $release->tag_name, + "license" => @file_get_contents(current(glob($iterator->getBaseDir()."/LICENSE*"))), + "stub" => "pharext_installer.php", + "type" => false ? "zend_extension" : "extension", + ]; + $file = (new Task\PharBuild($iterator, $meta))->run(); + return $file; + } + + function create($create) { + if ($create->ref_type !== "tag") { + $response = $this->app->getResponse(); + + $response->setResponseCode(202); + $response->getBody()->append("Not a tag"); + return; + } + + $this->createReleaseFromTag($create->ref, $create->repository); + } + + private function setTokenForUser($login) { + $relations = [ + $this->accounts->getTokens()->getRelation("accounts"), + $this->accounts->getOwners()->getRelation("accounts") + ]; + $tokens = $this->accounts->getTokens()->with($relations, [ + "login=" => $login, + "tokens.authority=" => "github", + ]); + + if (count($tokens)) { + $this->github->setToken($tokens->current()->token->get()); + } + } + + private function createReleaseFromTag($tag, $repo) { + $this->setTokenForUser($repo->owner->login); + $this->github->createRelease($repo->full_name, $tag, function($json) { + $response = $this->app->getResponse(); + $response->setResponseCode(201); + $response->setHeader("Location", $json->url); + })->send(); + } +} diff --git a/app/Controller/Github/Repo/Hook.php b/app/Controller/Github/Repo/Hook.php deleted file mode 100644 index fac6450..0000000 --- a/app/Controller/Github/Repo/Hook.php +++ /dev/null @@ -1,66 +0,0 @@ -checkToken()) { - if ($this->app->getRequest()->getRequestMethod() != "POST") { - // user had to re-authenticate, and was redirected here - $this->app->redirect($this->app->getBaseUrl()->mod([ - "path" => "./github/repo/" . $args["owner"] ."/". $args["name"], - "query" => "modal=hook&hook=" . $args["action"] - ])); - } else switch ($args["action"]) { - case "upd": - $this->updateHook($args["owner"], $args["name"]); - break; - - case "add": - $this->addHook($args["owner"], $args["name"]); - break; - - case "del": - $this->delHook($args["owner"], $args["name"]); - break; - } - } - } - - function addHook($owner, $repo) { - $hook_conf = $this->app->getRequest()->getForm(); - $this->github->createRepoHook("$owner/$repo", $hook_conf, function($hook) use($owner, $repo) { - if (($cache = $this->github->getCacheStorage())) { - $cache->del($this->github->getCacheKey("hooks:$owner/$repo")); - } - if (($back = $this->app->getRequest()->getForm("returnback")) && isset($this->session->previous)) { - $this->app->redirect($this->app->getBaseUrl()->mod($this->session->previous)); - } else { - $this->app->redirect($this->app->getBaseUrl()->mod("./github/repo/$owner/$repo")); - } - })->send(); - } - - function delHook($owner, $repo) { - $this->github->fetchRepo("$owner/$repo", function($repo) { - $this->github->fetchHooks($repo->full_name, function($hooks) use($repo) { - $repo->hooks = $hooks; - if (($id = $this->checkRepoHook($repo))) { - $this->github->deleteRepoHook($repo->full_name, $id, function() use($repo) { - if (($cache = $this->github->getCacheStorage())) { - $cache->del($this->github->getCacheKey("hooks:" . $repo->full_name)); - } - if (($back = $this->app->getRequest()->getForm("returnback")) && isset($this->session->previous)) { - $this->app->redirect($this->app->getBaseUrl()->mod($this->session->previous)); - } else { - $this->app->redirect($this->app->getBaseUrl()->mod("./github/repo/" . $repo->full_name)); - } - }); - } - }); - })->send(); - } -} diff --git a/app/Controller/Github/RepoHook.php b/app/Controller/Github/RepoHook.php new file mode 100644 index 0000000..8ab1eed --- /dev/null +++ b/app/Controller/Github/RepoHook.php @@ -0,0 +1,68 @@ +checkToken()) { + if ($this->app->getRequest()->getRequestMethod() != "POST") { + // user had to re-authenticate, and was redirected here + $this->app->redirect($this->app->getBaseUrl()->mod([ + "path" => "./github/repo/" . $args["owner"] ."/". $args["name"], + "query" => "modal=hook&hook=" . $args["action"] + ])); + } else { + switch ($args["action"]) { + case "upd": + $this->updateHook($args["owner"], $args["name"]); + break; + + case "add": + $this->addHook($args["owner"], $args["name"]); + break; + + case "del": + $this->delHook($args["owner"], $args["name"]); + break; + } + } + } + } + + function addHook($owner, $repo) { + $hook_conf = $this->app->getRequest()->getForm(); + $this->github->createRepoHook("$owner/$repo", $hook_conf, function($hook) use($owner, $repo) { + if (($cache = $this->github->getCacheStorage())) { + $cache->del($this->github->getCacheKey("hooks:$owner/$repo")); + } + if (($back = $this->app->getRequest()->getForm("returnback")) && isset($this->session->previous)) { + $this->app->redirect($this->app->getBaseUrl()->mod($this->session->previous)); + } else { + $this->app->redirect($this->app->getBaseUrl()->mod("./github/repo/$owner/$repo")); + } + })->send(); + } + + function delHook($owner, $repo) { + $this->github->fetchRepo("$owner/$repo", function($repo) { + $this->github->fetchHooks($repo->full_name, function($hooks) use($repo) { + $repo->hooks = $hooks; + if (($hook = $this->checkRepoHook($repo))) { + $this->github->deleteRepoHook($repo->full_name, $hook->id, function() use($repo) { + if (($cache = $this->github->getCacheStorage())) { + $cache->del($this->github->getCacheKey("hooks:" . $repo->full_name)); + } + if (($back = $this->app->getRequest()->getForm("returnback")) && isset($this->session->previous)) { + $this->app->redirect($this->app->getBaseUrl()->mod($this->session->previous)); + } else { + $this->app->redirect($this->app->getBaseUrl()->mod("./github/repo/" . $repo->full_name)); + } + }); + } + }); + })->send(); + } +} diff --git a/app/Github/API/Call.php b/app/Github/API/Call.php index f40e486..3615851 100644 --- a/app/Github/API/Call.php +++ b/app/Github/API/Call.php @@ -96,7 +96,7 @@ abstract class Call new QueryString($this->args)); } - function readFromCache(&$cached = null, &$ttl = null) { + function readFromCache(array &$cached = null, &$ttl = null) { if (empty($this->args["fresh"]) && ($cache = $this->api->getCacheStorage())) { $key = $this->getCacheKey(); return $cache->get($key, $cached, $ttl); @@ -104,7 +104,7 @@ abstract class Call return false; } - function saveToCache($fresh) { + function saveToCache(array $fresh) { if (($cache = $this->api->getCacheStorage())) { if (isset($this->config->storage->cache->{$this}->ttl)) { $ttl = $this->config->storage->cache->{$this}->ttl; diff --git a/app/Github/API/Repos/ReadContents.php b/app/Github/API/Repos/ReadContents.php index 02b28fb..fde19b8 100644 --- a/app/Github/API/Repos/ReadContents.php +++ b/app/Github/API/Repos/ReadContents.php @@ -18,7 +18,7 @@ class ReadContents extends Call if ($response->getResponseCode() >= 400 || null === ($json = json_decode($response->getBody()))) { throw new RequestException($response); } - $this->saveToCache($json); + $this->saveToCache([$json]); $callback($json); return true; }); diff --git a/app/Github/API/Repos/ReadRepo.php b/app/Github/API/Repos/ReadRepo.php index e432d2a..775a9ee 100644 --- a/app/Github/API/Repos/ReadRepo.php +++ b/app/Github/API/Repos/ReadRepo.php @@ -18,7 +18,7 @@ class ReadRepo extends Call if ($response->getResponseCode() >= 400 || null === ($json = json_decode($response->getBody()))) { throw new RequestException($response); } - $this->saveToCache($json); + $this->saveToCache([$json]); $callback($json); return true; }); diff --git a/app/Github/API/Users/ReadAuthUser.php b/app/Github/API/Users/ReadAuthUser.php index 5feb7c8..6cb6de0 100644 --- a/app/Github/API/Users/ReadAuthUser.php +++ b/app/Github/API/Users/ReadAuthUser.php @@ -18,7 +18,7 @@ class ReadAuthUser extends Call if ($response->getResponseCode() >= 400 || null === ($json = json_decode($response->getBody()))) { throw new RequestException($response); } - $this->saveToCache($json); + $this->saveToCache([$json]); $callback($json); return true; }); diff --git a/app/views/github/repo.phtml b/app/views/github/repo.phtml index 1b7a640..6000cf7 100644 --- a/app/views/github/repo.phtml +++ b/app/views/github/repo.phtml @@ -120,13 +120,13 @@
diff --git a/config/routes.ini b/config/routes.ini index ad01201..cb28b1e 100644 --- a/config/routes.ini +++ b/config/routes.ini @@ -7,7 +7,7 @@ GET[] = /pages/{page} [Github\Callback] GET[] = /github/callback -[Github\Hook] +[Github\Hook\Receive] POST[] = /github/hook [Github\Index] @@ -17,7 +17,7 @@ GET[] = /github GET[] = /github/repo/{owner}/{name} GET[] = /github/repo/{owner}/{name}/{page} -[Github\Repo\Hook] +[Github\RepoHook] POST[] = /github/repo/{owner}/{name}/hook/{action} ; if the user has to re-authenticate, we'll receive a GET because of a redirect GET[] = /github/repo/{owner}/{name}/hook/{action}