bd28f3ababa56d1bb711a4c32d18e8c69791cc35
6 use app\Github\Storage
;
7 use app\Github\Exception
;
16 use Psr\Log\LoggerInterface
;
46 * @var \Psr\Log\LoggerInterface;
50 function __construct(Config
$config, LoggerInterface
$logger, Storage
$tokens = null, Storage
$cache = null) {
51 $this->logger
= $logger;
52 $this->config
= $config;
53 $this->client
= new Client("curl", "github");
54 $this->client
->configure($config->http
->configure
->toArray());
55 $this->client
->attach(new ClientObserver($logger));
56 $this->tokens
= $tokens ?
: new Storage\Session
;
57 $this->cache
= $cache;
61 * Set maximum acceptable age of cache items
64 function setMaxAge($seconds) {
65 $this->maxAge
= $seconds;
69 function getMaxAge() {
73 function getLogger() {
77 function getConfig() {
81 function getClient() {
85 function getTokenStorage() {
89 function getCacheStorage() {
93 function getCacheKey($ident, $page = null) {
94 return sprintf("%s:%s:%s", $this->getToken(), $ident, $page ?
: 1);
98 return $this->tokens
->get("access_token");
101 function setToken($token) {
102 $this->tokens
->set("access_token", new Storage\
Item(
104 $this->config
->storage
->token
->ttl
108 function getToken() {
109 if ($this->tokens
->get("access_token", $token, true)) {
110 return $token->getValue();
113 $this->logger
->notice("Token expired", $token);
114 throw new Exception\
TokenExpired($token->getLTL());
116 throw new Exception\TokenNotSet
;
119 function dropToken() {
120 $this->tokens
->del("access_token");
123 function getAuthUrl($callback_url) {
124 $state = base64_encode(openssl_random_pseudo_bytes(24));
125 $this->tokens
->set("state", new Storage\
Item($state, 5*60));
128 "client_id" => $this->config
->client
->id
,
129 "scope" => $this->config
->client
->scope
,
130 "redirect_uri" => $callback_url,
132 return new Url("https://github.com/login/oauth/authorize", [
133 "query" => new QueryString($param)
137 function fetchToken($code, $state, callable
$callback) {
138 if (!$this->tokens
->get("state", $orig_state, true)) {
139 if (isset($orig_state)) {
140 $this->logger
->notice("State expired", $orig_state);
141 throw new Exception\
StateExpired($orig_state->getLTL());
143 throw new Exception\StateNotSet
;
145 if ($state !== $orig_state->getValue()) {
146 $this->logger
->warning("State mismatch", compact("state", "orig_state"));
147 throw new Exception\
StateMismatch($orig_state->getValue(), $state);
150 $call = new API\Users\
ReadAuthToken($this, [
152 "client_id" => $this->config
->client
->id
,
153 "client_secret" => $this->config
->client
->secret
,
155 return $call($callback);
158 function readAuthUser(callable
$callback) {
159 $call = new API\Users\
ReadAuthUser($this);
160 return $call($callback);
163 function listRepos($page, callable
$callback) {
164 $call = new API\Repos\
ListRepos($this, compact("page"));
165 return $call($callback);
168 function readRepo($repo, callable
$callback) {
169 $call = new API\Repos\
ReadRepo($this, compact("repo"));
170 return $call($callback);
174 * Check if the pharext webhook is set for the repo and return it
175 * @param object $repo
176 * @return stdClass hook
178 function checkRepoHook($repo) {
180 foreach ($repo->hooks
as $hook) {
181 if ($hook->name
=== "web" && $hook->config
->url
=== $this->config
->hook
->url
) {
189 function listHooks($repo, callable
$callback) {
190 $call = new API\Hooks\
ListHooks($this, compact("repo"));
191 return $call($callback);
194 function listReleases($repo, $page, callable
$callback) {
195 $call = new API\Releases\
ListReleases($this, compact("repo", "page"));
196 return $call($callback);
199 function listTags($repo, $page, callable
$callback) {
200 $call = new API\Tags\
ListTags($this, compact("repo", "page"));
201 return $call($callback);
204 function readContents($repo, $path, callable
$callback) {
205 $call = new API\Repos\
ReadContents($this, compact("repo", "path"));
206 return $call($callback);
209 function createRepoHook($repo, $conf, callable
$callback) {
210 $call = new API\Hooks\
CreateHook($this, compact("repo", "conf"));
211 return $call($callback);
214 function updateRepoHook($repo, $id, $conf, callable
$callback) {
215 $call = new API\Hooks\
UpdateHook($this, compact("repo", "id", "conf"));
216 return $call($callback);
219 function deleteRepoHook($repo, $id, callable
$callback) {
220 $call = new API\Hooks\
DeleteHook($this, compact("repo", "id"));
221 return $call($callback);
224 function createRelease($repo, $tag, callable
$callback) {
225 $call = new API\Releases\
CreateRelease($this, compact("repo", "tag"));
226 return $call($callback);
229 function publishRelease($repo, $id, $tag, callable
$callback) {
230 $call = new API\Releases\
PublishRelease($this, compact("repo", "id", "tag"));
231 return $call($callback);
234 function createReleaseAsset($url, $asset, $type, callable
$callback) {
235 $call = new API\Releases\
CreateReleaseAsset($this, compact("url", "asset", "type"));
236 return $call($callback);
239 function listReleaseAssets($repo, $id, callable
$callback) {
240 $call = new API\Releases\
ListReleaseAssets($this, compact("repo", "id"));
241 return $call($callback);
244 function uploadAssetForRelease($repo, $release, callable
$callback) {
245 return $this->listHooks($repo->full_name
, function($hooks) use($release, $repo, $callback) {
246 $repo->hooks
= $hooks;
247 $hook = $this->checkRepoHook($repo);
248 $phar = new Pharext\
Package($repo->clone_url
, $release->tag_name
, $repo->name
, $hook ?
$hook->config
: null);
249 $name = sprintf("%s-%s.ext.phar", $repo->name
, $release->tag_name
);
250 $url = uri_template($release->upload_url
, compact("name"));
251 $this->createReleaseAsset($url, $phar, "application/phar", function($json) use($release, $repo, $callback) {
252 if ($release->draft
) {
253 $this->publishRelease($repo->full_name
, $release->id
, $release->tag_name
, function($json) use($callback) {
263 function createReleaseFromTag($repo, $tag_name, callable
$callback) {
264 return $this->createRelease($repo->full_name
, $tag_name, function($json) use($repo, $callback) {
265 $this->uploadAssetForRelease($repo, $json, $callback);