Ver código fonte

Initial upload

Deben Oldert 6 anos atrás
pai
commit
08b91f29da
7 arquivos alterados com 384 adições e 0 exclusões
  1. 125 0
      AutoDeploy.class.php
  2. 31 0
      IAction.interface.php
  3. 137 0
      action.class.php
  4. 31 0
      base.class.php
  5. 42 0
      releaseaction.class.php
  6. 8 0
      routes.static.php
  7. 10 0
      settings.class.php

+ 125 - 0
AutoDeploy.class.php

@@ -0,0 +1,125 @@
+<?php
+
+namespace DebenOldert\AutoDeploy;
+
+use DebenOldert\PHPWork\Plugin;
+
+include_once 'settings.class.php';
+
+final class AutoDeploy extends Plugin
+{
+    private $headers = array();
+    private $IAction;
+
+    protected $settings;
+
+    protected $data;
+    protected $json;
+
+    private $token;
+
+    public function __construct(string $directory, string $namespace=Null)
+    {
+        parent::__construct($directory, $namespace);
+    }
+
+    public function processRequest()
+    {
+        global $PHPWORK;
+        $this->data = file_get_contents('php://input');
+
+        $this->parseHeaders();
+
+        if($this->hasHeader('X-Gogs-Event')
+        && $this->hasHeader('X-Gogs-Signature'))
+        {
+            $isAuthenticated = false;
+            foreach ($this->settings['keys'] as $secret)
+            {
+                if($this->authenticate($secret))
+                {
+                    $isAuthenticated = true;
+                    $this->token = $secret;
+                    break;
+                }
+            }
+
+            if($isAuthenticated)
+            {
+                $this->json = $this->parseData();
+                //var_dump($this->json);
+                switch (strtoupper($this->getHeader('X-Gogs-Event'))) {
+                    case 'RELEASE':
+                        include 'releaseaction.class.php';
+                        $this->IAction = new ReleaseAction($this->json, $this->settings, $this->token);
+                        break;
+                    case 'PUSH':
+                        //TODO: Implement PUSH event
+                        break;
+                    default:
+                        $PHPWORK->sendHttpCode(501);
+                }
+
+                $this->IAction->start();
+
+                if($this->IAction->isSuccess()){
+                    $PHPWORK->sendHttpCode(200);
+                }
+                else
+                {
+                    $PHPWORK->sendHttpCode(500);
+                }
+            }
+        }
+    }
+
+    private function authenticate($key)
+    {
+        global $PHPWORK;
+        if($PHPWORK->isProduction())
+        {
+            $hash = hash_hmac('SHA256', $this->data, $key);
+            return hash_equals($this->headers['X-Gogs-Signature'], $hash);
+        }
+        else
+        {
+            return true;
+        }
+    }
+
+
+    private function parseHeaders()
+    {
+        foreach($_SERVER as $key=>$value)
+        {
+            if (strpos($key, 'HTTP_') === 0)
+            {
+                $key=str_replace(' ','-',ucwords(strtolower(str_replace('_',' ',substr($key,5)))));
+                $this->headers[$key]=$value;
+            }
+        }
+    }
+
+    private function parseData()
+    {
+        return json_decode($this->data);
+    }
+
+    private function getHeader($key)
+    {
+        return $this->headers[$key] ?? Null;
+    }
+
+    private function hasHeader($key)
+    {
+        return $this->getHeader($key) !== Null;
+    }
+
+    public function route(string $key, array $match)
+    {
+        $this->processRequest();
+    }
+
+}
+
+return __NAMESPACE__;

+ 31 - 0
IAction.interface.php

@@ -0,0 +1,31 @@
+<?php
+
+
+namespace DebenOldert\AutoDeploy;
+
+
+interface IAction
+{
+    public function __construct(\stdClass $json, array $settings, string $key);
+
+    public function start() : bool;
+
+    public function download() : bool;
+
+    public function isSuccess() : bool;
+
+    public function unzip() : int;
+
+    public function move() : bool;
+
+    public function formatDownloadName() : string;
+
+    public function formatUnZipName() : string;
+
+    public function formatUrl() : string;
+
+    public function shouldDownload() : bool;
+
+    public function formatRealName() : string;
+
+}

+ 137 - 0
action.class.php

@@ -0,0 +1,137 @@
+<?php
+
+
+namespace DebenOldert\AutoDeploy;
+
+include_once 'IAction.interface.php';
+
+use ZipArchive;
+
+class Action implements IAction
+{
+    protected $settings;
+    protected $key;
+
+    protected $json;
+
+    protected $downloadUrl;
+
+    protected $zipName;
+    protected $unzipName;
+
+    protected $pluginName;
+
+    protected $success = false;
+
+    public function __construct(\stdClass $json, array $settings, string $key)
+    {
+        $this->json = $json;
+        $this->settings = $settings;
+        $this->key = $key;
+
+        var_dump($this->json);
+    }
+
+    public function start(): bool
+    {
+        global $PHPWORK;
+        if($this->shouldDownload())
+        {
+            $this->downloadUrl = $this->formatUrl();
+            $this->zipName = $this->formatDownloadName();
+            $this->unzipName = $this->formatUnZipName();
+
+            if($this->download() && $this->unzip() > 0)
+            {
+                $this->pluginName = $this->formatRealName();
+                $this->success = $this->move();
+                return $this->isSuccess();
+            }
+            else
+            {
+                $PHPWORK->sendHttpCode(500);
+            }
+        }
+        else
+        {
+            $PHPWORK->sendHttpCode(412);
+        }
+    }
+
+    public function isSuccess(): bool
+    {
+        return $this->success;
+    }
+
+    public function move(): bool
+    {
+        $plugindir = \DebenOldert\PHPWork\Base::PLUGIN_DIR;
+        $dest = "{$plugindir}/{$this->pluginName}";
+
+        if(is_dir($dest))
+        {
+            return rename($this->unzipName, $dest);
+        }
+        return false;
+    }
+
+    public function unzip(): int
+    {
+        $zip = new ZipArchive();
+        if($zip->open($this->zipName) !== 'true'){
+            return false;
+        }
+
+        $zip->extractTo($this->unzipName);
+        $zip->close();
+
+        return $zip->numFiles;
+    }
+
+    public function formatDownloadName(): string
+    {
+        return Null;
+    }
+
+    public function formatUnZipName(): string
+    {
+        return Null;
+    }
+
+    public function formatUrl() : string
+    {
+        return Null;
+    }
+
+    public function shouldDownload(): bool
+    {
+        return false;
+    }
+
+    public function download(): bool
+    {
+        $file = fopen($this->zipName, 'wb');
+
+        $ch = curl_init();
+        curl_setopt($ch, CURLOPT_URL, $this->downloadUrl);
+        curl_setopt($ch, CURLOPT_FAILONERROR, false);
+        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
+        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+        curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
+        curl_setopt($ch, CURLOPT_FILE, $file);
+
+        fclose($file);
+
+        return file_exists($this->zipName);
+    }
+
+    public function formatRealName(): string
+    {
+        return Null;
+    }
+
+    public function  createFolder($path) : bool
+    {
+        return mkdir($path, 0777, true);
+    }
+}

+ 31 - 0
base.class.php

@@ -0,0 +1,31 @@
+<?php
+
+
+namespace DebenOldert\AutoDeploy;
+
+###################################
+#                                 #
+#      DO NOT EDIT THIS FILE      #
+# Use the settings.class.php file #
+#                                 #
+###################################
+
+abstract class Base
+{
+    const name          = "AutoDeploy";
+    const title         = "Automated Version Deploy";
+    const author        = "Deben Oldert";
+
+    const autostart     = false;
+
+    const version       = "0.1";
+
+    const keys          = array();
+
+    const download_dir  = 'download';
+
+    const acceptDraft   = false;
+    const acceptPre     = false;
+}
+
+return Base::name;

+ 42 - 0
releaseaction.class.php

@@ -0,0 +1,42 @@
+<?php
+
+
+namespace DebenOldert\AutoDeploy;
+
+include 'action.class.php';
+
+class ReleaseAction extends Action
+{
+    public function shouldDownload() : bool
+    {
+        return (!$this->json->release->draft
+                && !$this->json->release->prerelease)
+            || ($this->settings['acceptDraft']
+                && $this->json->release->draft)
+            || ($this->settings['acceptPre']
+                && $this->json->release->prerelease);
+    }
+
+    public function formatDownloadName() : string
+    {
+        return "{$this->settings['download_dir']}/{$this->json->repository->name}-{$this->json->release->tag_name}.zip";
+    }
+
+    public function formatUnZipName() : string
+    {
+        return "{$this->settings['download_dir']}/{$this->json->repository->name}-{$this->json->release->tag_name}";
+    }
+
+    public function formatUrl() : string
+    {
+        $parsed = parse_url($this->json->repository->html_url);
+        $domain = "{$parsed['scheme']}://{$parsed['host']}";
+
+        return "{$domain}/api/v1/repos/{$this->json->repository->owner->username}/{$this->json->repository->name}/archive/{$this->json->release->tag_name}.zip?token={$this->key}";
+    }
+
+    public function formatRealName() : string
+    {
+        return include_once "{$this->unzipName}/base.class.php";
+    }
+}

+ 8 - 0
routes.static.php

@@ -0,0 +1,8 @@
+<?php
+namespace DebenOldert\PHPWork;
+
+global $ROUTE;
+
+$ROUTE = array(
+    'gogs-webhook' => ''
+);

+ 10 - 0
settings.class.php

@@ -0,0 +1,10 @@
+<?php
+
+namespace DebenOldert\AutoDeploy;
+
+include 'base.class.php';
+
+class Settings extends Base
+{
+    #Configure your own settings here by overwriting variables from base.class.php
+}