show already uploaded asset
[pharext/pharext.org] / app / Github / API.php
1 <?php
2
3 namespace app\Github;
4
5 use app\Github\API;
6 use app\Github\Storage;
7 use app\Github\Exception;
8
9 use merry\Config;
10
11 use http\Client;
12 use http\QueryString;
13 use http\Url;
14
15 use Psr\Log\LoggerInterface;
16
17 class API
18 {
19 /**
20 * @var Client
21 */
22 private $client;
23
24 /**
25 * @var Storage
26 */
27 private $tokens;
28
29 /**
30 * @var Storage
31 */
32 private $cache;
33
34 /**
35 * @var merry\Config
36 */
37 private $config;
38
39 /**
40 * @var int
41 */
42 private $maxAge;
43
44 /**
45 * @var \Psr\Log\LoggerInterface;
46 */
47 private $logger;
48
49 function __construct(Config $config, LoggerInterface $logger, Storage $tokens = null, Storage $cache = null) {
50 $this->logger = $logger;
51 $this->config = $config;
52 $this->client = new Client;
53 $this->client->attach(new ClientObserver($logger));
54 $this->tokens = $tokens ?: new Storage\Session;
55 $this->cache = $cache;
56 }
57
58 /**
59 * Set maximum acceptable age of cache items
60 * @param int $seconds
61 */
62 function setMaxAge($seconds) {
63 $this->maxAge = $seconds;
64 return $this;
65 }
66
67 function getMaxAge() {
68 return $this->maxAge;
69 }
70
71 function getLogger() {
72 return $this->logger;
73 }
74
75 function getConfig() {
76 return $this->config;
77 }
78
79 function getClient() {
80 return $this->client;
81 }
82
83 function getTokenStorage() {
84 return $this->tokens;
85 }
86
87 function getCacheStorage() {
88 return $this->cache;
89 }
90
91 function getCacheKey($ident, $page = null) {
92 return sprintf("%s:%s:%s", $this->getToken(), $ident, $page ?: 1);
93 }
94
95 function hasToken() {
96 return $this->tokens->get("access_token");
97 }
98
99 function setToken($token) {
100 $this->tokens->set("access_token", new Storage\Item(
101 $token,
102 $this->config->storage->token->ttl
103 ));
104 }
105
106 function getToken() {
107 if ($this->tokens->get("access_token", $token, true)) {
108 return $token->getValue();
109 }
110 if (isset($token)) {
111 $this->logger->notice("Token expired", $token);
112 throw new Exception\TokenExpired($token->getLTL());
113 }
114 throw new Exception\TokenNotSet;
115 }
116
117 function dropToken() {
118 $this->tokens->del("access_token");
119 }
120
121 function getAuthUrl($callback_url) {
122 $state = base64_encode(openssl_random_pseudo_bytes(24));
123 $this->tokens->set("state", new Storage\Item($state, 5*60));
124 $param = [
125 "state" => $state,
126 "client_id" => $this->config->client->id,
127 "scope" => $this->config->client->scope,
128 "redirect_uri" => $callback_url,
129 ];
130 return new Url("https://github.com/login/oauth/authorize", [
131 "query" => new QueryString($param)
132 ], 0);
133 }
134
135 function fetchToken($code, $state, callable $callback) {
136 if (!$this->tokens->get("state", $orig_state, true)) {
137 if (isset($orig_state)) {
138 $this->logger->notice("State expired", $orig_state);
139 throw new Exception\StateExpired($orig_state->getLTL());
140 }
141 throw new Exception\StateNotSet;
142 }
143 if ($state !== $orig_state->getValue()) {
144 $this->logger->warning("State mismatch", compact("state", "orig_state"));
145 throw new Exception\StateMismatch($orig_state->getValue(), $state);
146 }
147
148 $call = new API\Users\ReadAuthToken($this, [
149 "code" => $code,
150 "client_id" => $this->config->client->id,
151 "client_secret" => $this->config->client->secret,
152 ]);
153 return $call($callback);
154 }
155
156 function readAuthUser(callable $callback) {
157 $call = new API\Users\ReadAuthUser($this);
158 return $call($callback);
159 }
160
161 function listRepos($page, callable $callback) {
162 $call = new API\Repos\ListRepos($this, compact("page"));
163 return $call($callback);
164 }
165
166 function readRepo($repo, callable $callback) {
167 $call = new API\Repos\ReadRepo($this, compact("repo"));
168 return $call($callback);
169 }
170
171 function listHooks($repo, callable $callback) {
172 $call = new API\Hooks\ListHooks($this, compact("repo"));
173 return $call($callback);
174 }
175
176 function listReleases($repo, $page, callable $callback) {
177 $call = new API\Releases\ListReleases($this, compact("repo", "page"));
178 return $call($callback);
179 }
180
181 function listTags($repo, $page, callable $callback) {
182 $call = new API\Tags\ListTags($this, compact("repo", "page"));
183 return $call($callback);
184 }
185
186 function readContents($repo, $path, callable $callback) {
187 $call = new API\Repos\ReadContents($this, compact("repo", "path"));
188 return $call($callback);
189 }
190
191 function createRepoHook($repo, $conf, callable $callback) {
192 $call = new API\Hooks\CreateHook($this, compact("repo", "conf"));
193 return $call($callback);
194 }
195
196 function updateRepoHook($repo, $id, $conf, callable $callback) {
197 $call = new API\Hooks\UpdateHook($this, compact("repo", "id", "conf"));
198 return $call($callback);
199 }
200
201 function deleteRepoHook($repo, $id, callable $callback) {
202 $call = new API\Hooks\DeleteHook($this, compact("repo", "id"));
203 return $call($callback);
204 }
205
206 function createRelease($repo, $tag, callable $callback) {
207 $call = new API\Releases\CreateRelease($this, compact("repo", "tag"));
208 return $call($callback);
209 }
210
211 function createReleaseAsset($url, $asset, $type, callable $callback) {
212 $call = new API\Releases\CreateReleaseAsset($this, compact("url", "asset", "type"));
213 return $call($callback);
214 }
215
216 function listReleaseAssets($repo, $id, callable $callback) {
217 $call = new API\Releases\ListReleaseAssets($this, compact("repo", "id"));
218 return $call($callback);
219 }
220 }