diff options
Diffstat (limited to 'app')
-rw-r--r-- | app/Controller/Webhook.php | 61 | ||||
-rw-r--r-- | app/Core/Request.php | 2 | ||||
-rw-r--r-- | app/Model/Acl.php | 3 | ||||
-rw-r--r-- | app/Model/Action.php | 1 | ||||
-rw-r--r-- | app/Model/GithubWebhook.php | 81 | ||||
-rw-r--r-- | app/Model/Task.php | 18 | ||||
-rw-r--r-- | app/functions.php | 4 |
7 files changed, 168 insertions, 2 deletions
diff --git a/app/Controller/Webhook.php b/app/Controller/Webhook.php new file mode 100644 index 00000000..8a81a0c4 --- /dev/null +++ b/app/Controller/Webhook.php @@ -0,0 +1,61 @@ +<?php + +namespace Controller; + +/** + * Webhook controller + * + * @package controller + * @author Frederic Guillot + */ +class Webhook extends Base +{ + /** + * Webhook to create a task + * + * @access public + */ + public function task() + { + if ($this->config->get('webhooks_token') !== $this->request->getStringParam('token')) { + $this->response->text('Not Authorized', 401); + } + + $defaultProject = $this->project->getFirst(); + + $values = array( + 'title' => $this->request->getStringParam('title'), + 'description' => $this->request->getStringParam('description'), + 'color_id' => $this->request->getStringParam('color_id'), + 'project_id' => $this->request->getIntegerParam('project_id', $defaultProject['id']), + 'owner_id' => $this->request->getIntegerParam('owner_id'), + 'column_id' => $this->request->getIntegerParam('column_id'), + 'category_id' => $this->request->getIntegerParam('category_id'), + ); + + list($valid,) = $this->taskValidator->validateCreation($values); + + if ($valid && $this->task->create($values)) { + $this->response->text('OK'); + } + + $this->response->text('FAILED'); + } + + /** + * Handle Github webhooks + * + * @access public + */ + public function github() + { + if ($this->config->get('webhooks_token') !== $this->request->getStringParam('token')) { + $this->response->text('Not Authorized', 401); + } + + $this->githubWebhook->parsePayload( + $this->request->getHeader('X-Github-Event'), + $this->request->getBody() + ); + } +} diff --git a/app/Core/Request.php b/app/Core/Request.php index e86cf609..09792013 100644 --- a/app/Core/Request.php +++ b/app/Core/Request.php @@ -145,7 +145,7 @@ class Request */ public function getQueryString() { - return $_SERVER['QUERY_STRING']; + return isset($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : ''; } } diff --git a/app/Model/Acl.php b/app/Model/Acl.php index aea13e8c..f92b3021 100644 --- a/app/Model/Acl.php +++ b/app/Model/Acl.php @@ -18,9 +18,10 @@ class Acl extends Base */ private $public_actions = array( 'user' => array('login', 'check', 'google', 'github'), - 'task' => array('add', 'readonly'), + 'task' => array('readonly'), 'board' => array('readonly'), 'project' => array('feed'), + 'webhook' => array('task', 'github'), ); /** diff --git a/app/Model/Action.php b/app/Model/Action.php index a318c5b0..a0c992aa 100644 --- a/app/Model/Action.php +++ b/app/Model/Action.php @@ -65,6 +65,7 @@ class Action extends Base Task::EVENT_CLOSE => t('Closing a task'), Task::EVENT_CREATE_UPDATE => t('Task creation or modification'), Task::EVENT_ASSIGNEE_CHANGE => t('Task assignee change'), + GithubWebhook::EVENT_COMMIT => t('Github commit received'), ); } diff --git a/app/Model/GithubWebhook.php b/app/Model/GithubWebhook.php new file mode 100644 index 00000000..688ab601 --- /dev/null +++ b/app/Model/GithubWebhook.php @@ -0,0 +1,81 @@ +<?php + +namespace Model; + +/** + * Github Webhook model + * + * @package model + * @author Frederic Guillot + */ +class GithubWebhook extends Base +{ + /** + * Events + * + * @var string + */ + const EVENT_ISSUE_OPENED = 'github.webhook.issue.opened'; + const EVENT_ISSUE_CLOSED = 'github.webhook.issue.closed'; + const EVENT_ISSUE_LABELED = 'github.webhook.issue.labeled'; + const EVENT_ISSUE_COMMENT = 'github.webhook.issue.commented'; + const EVENT_COMMIT = 'github.webhook.commit'; + + /** + * Parse Github events + * + * @access public + * @param string $type Github event type + * @param string $payload Raw Github event (JSON) + */ + public function parsePayload($type, $payload) + { + $payload = json_decode($payload, true); + + switch ($type) { + case 'push': + return $this->parsePushEvent($payload); + case 'issues': + return $this->parseIssueEvent($payload); + } + } + + /** + * Parse Push events (list of commits) + * + * @access public + * @param array $payload Event data + */ + public function parsePushEvent(array $payload) + { + foreach ($payload['commits'] as $commit) { + + $task_id = $this->task->getTaskIdFromText($commit['message']); + + if (! $task_id) { + continue; + } + + $task = $this->task->getById($task_id); + + if (! $task) { + continue; + } + + if ($task['is_active'] == Task::STATUS_OPEN) { + $this->event->trigger(self::EVENT_COMMIT, array('task_id' => $task_id) + $task); + } + } + } + + /** + * Parse issue events + * + * @access public + * @param array $payload Event data + */ + public function parseIssueEvent(array $payload) + { + + } +} diff --git a/app/Model/Task.php b/app/Model/Task.php index 262e8d76..8708f128 100644 --- a/app/Model/Task.php +++ b/app/Model/Task.php @@ -696,4 +696,22 @@ class Task extends Base return false; } + + /** + * Get a the task id from a text + * + * Example: "Fix bug #1234" will return 1234 + * + * @access public + * @param string $message Text + * @return integer + */ + public function getTaskIdFromText($message) + { + if (preg_match('!#(\d+)!i', $message, $matches) && isset($matches[1])) { + return $matches[1]; + } + + return 0; + } } diff --git a/app/functions.php b/app/functions.php index 4cbbbbfe..dc6431b9 100644 --- a/app/functions.php +++ b/app/functions.php @@ -6,6 +6,10 @@ use PicoDb\Database; function debug($message) { + if (! is_string($message)) { + $message = var_export($message, true); + } + error_log($message.PHP_EOL, 3, 'data/debug.log'); } |