3 namespace app\Controller\Github\Hook
;
7 use app\Github\Exception\TokenNotSet
;
8 use app\Model\Accounts
;
12 class Receive
implements Controller
18 function __construct(Web
$app, API
$github, Accounts
$accounts) {
20 $this->github
= $github;
21 $this->accounts
= $accounts;
24 function __invoke(array $args = null) {
25 $request = $this->app
->getRequest();
26 $response = $this->app
->getResponse();
28 if (!($sig = $request->getHeader("X-Hub-Signature")) ||
!($evt = $request->getHeader("X-Github-Event"))) {
29 $response->setResponseCode(400);
30 $response->setContentType("message/http");
31 $response->getBody()->append($request);
33 $key = $this->github
->getConfig()->client
->secret
;
34 foreach ((new Params($sig))->params
as $algo => $mac) {
35 if ($mac["value"] !== hash_hmac($algo, $request->getBody(), $key)) {
36 $response->setResponseCode(403);
37 $response->getBody()->append("Invalid signature");
45 $response->setResponseCode(202);
46 $response->getBody()->append("Not a configured event");
49 $response->setResponseCode(204);
50 $response->setResponseStatus("PONG");
54 if (($json = json_decode($request->getBody()))) {
55 if (($queue = $this->$evt($json))) {
56 $queue->done(function($result) use($response) {
57 list($created) = $result;
58 $response->setResponseCode(201);
59 $response->setHeader("Location", $created->url
);
61 $this->github
->drain();
64 $response->setResponseCode(415);
65 $response->setContentType($request->getHeader("Content-Type"));
66 $response->getBody()->append($request->getBody());
72 private function setTokenForUser($login) {
74 $this->accounts
->getTokens()->getRelation("accounts"),
75 $this->accounts
->getOwners()->getRelation("accounts")
77 $tokens = $this->accounts
->getTokens()->with($relations, [
79 "tokens.authority=" => "github",
83 $this->github
->setToken($tokens->current()->token
->get());
87 private function release($release) {
88 $response = $this->app
->getResponse();
90 if ($release->action
!== "published") {
91 $response->setResponseCode(202);
92 $response->getBody()->append("Not published");
93 } elseif (!empty($release->release
->assets
)) {
94 foreach ($release->release
->assets
as $asset) {
95 if ($asset->content_type
=== "application/phar") {
96 /* we've already uploaded the asset when we created the release */
97 $response->setResponseCode(202);
98 $response->getBody()->append("Already published");
104 $this->setTokenForUser($release->repository
->owner
->login
);
106 $this->github
->getToken();
107 } catch (TokenNotSet
$e) {
108 $this->setTokenForUser($release->sender
->login
);
110 return $this->github
->uploadAssetForRelease(
116 private function create($create) {
117 $response = $this->app
->getResponse();
119 if ($create->ref_type
!== "tag") {
120 $response->setResponseCode(202);
121 $response->getBody()->append("Not a tag");
124 $this->setTokenForUser($create->repository
->owner
->login
);
126 $this->github
->getToken();
127 } catch (TokenNotSet
$e) {
128 $this->setTokenForUser($create->sender
->login
);
130 return $this->github
->createReleaseFromTag(