Skip to content

Instantly share code, notes, and snippets.

@Tyralion
Forked from samael500/handler.lua
Created May 2, 2018 10:32
Show Gist options
  • Select an option

  • Save Tyralion/8d3e68d8902eafa97e2d21fe2f157831 to your computer and use it in GitHub Desktop.

Select an option

Save Tyralion/8d3e68d8902eafa97e2d21fe2f157831 to your computer and use it in GitHub Desktop.

Revisions

  1. @samael500 samael500 revised this gist Apr 2, 2017. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion handler.lua
    Original file line number Diff line number Diff line change
    @@ -19,7 +19,7 @@ end
    local function const_eq (a, b)
    -- Check is string equals, constant time exec
    local equal = string.len(a) == string.len(b)
    for i = 1, math.min(string.len(a), string.len(b)) do
    for i = 1, math.max(string.len(a), string.len(b)) do
    equal = (a[i] == b[i]) and equal
    end
    return equal
  2. @samael500 samael500 revised this gist Apr 1, 2017. 1 changed file with 8 additions and 7 deletions.
    15 changes: 8 additions & 7 deletions handler.lua
    Original file line number Diff line number Diff line change
    @@ -11,17 +11,18 @@ local branch = 'refs/heads/master'
    ngx.header.content_type = "text/plain; charset=utf-8"


    getmetatable('').__index = function (str, i)
    return string.sub(str, i, i)
    end


    local function const_eq (a, b)
    -- Check is string equals, constant time exec
    getmetatable('').__index = function (str, i)
    return string.sub(str, i, i)
    end

    local diff = string.len(a) == string.len(b)
    local equal = string.len(a) == string.len(b)
    for i = 1, math.min(string.len(a), string.len(b)) do
    diff = (a[i] == b[i]) and diff
    equal = (a[i] == b[i]) and equal
    end
    return diff
    return equal
    end


  3. @samael500 samael500 revised this gist Mar 31, 2017. 1 changed file with 3 additions and 0 deletions.
    3 changes: 3 additions & 0 deletions nginx.conf
    Original file line number Diff line number Diff line change
    @@ -2,6 +2,9 @@ server {
    # ....

    location /deploy {
    client_body_buffer_size 3M;
    client_max_body_size 3M;

    content_by_lua_file /path/to/handler.lua;
    }
    }
  4. @samael500 samael500 created this gist Mar 31, 2017.
    93 changes: 93 additions & 0 deletions handler.lua
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,93 @@
    -- luarocks install JSON4Lua
    -- luarocks install luacrypto

    local json = require "json"
    local crypto = require "crypto"

    local secret = '<MY SUPER SECRET>'
    local event = 'push'
    local branch = 'refs/heads/master'

    ngx.header.content_type = "text/plain; charset=utf-8"


    local function const_eq (a, b)
    -- Check is string equals, constant time exec
    getmetatable('').__index = function (str, i)
    return string.sub(str, i, i)
    end

    local diff = string.len(a) == string.len(b)
    for i = 1, math.min(string.len(a), string.len(b)) do
    diff = (a[i] == b[i]) and diff
    end
    return diff
    end


    local function verify_signature (hub_sign, data)
    local sign = 'sha1=' .. crypto.hmac.digest('sha1', data, secret)
    return const_eq(hub_sign, sign)
    end


    local function validate_hook ()
    -- should be POST method
    if ngx.req.get_method() ~= "POST" then
    ngx.log(ngx.ERR, "wrong event request method: ", ngx.req.get_method())
    return ngx.exit (ngx.HTTP_NOT_ALLOWED)
    end

    local headers = ngx.req.get_headers()
    -- with correct header
    if headers['X-GitHub-Event'] ~= event then
    ngx.log(ngx.ERR, "wrong event type: ", headers['X-GitHub-Event'])
    return ngx.exit (ngx.HTTP_NOT_ACCEPTABLE)
    end

    -- should be json encoded request
    if headers['Content-Type'] ~= 'application/json' then
    ngx.log(ngx.ERR, "wrong content type header: ", headers['Content-Type'])
    return ngx.exit (ngx.HTTP_NOT_ACCEPTABLE)
    end

    -- read request body
    ngx.req.read_body()
    local data = ngx.req.get_body_data()

    if not data then
    ngx.log(ngx.ERR, "failed to get request body")
    return ngx.exit (ngx.HTTP_BAD_REQUEST)
    end

    -- validate GH signature
    if not verify_signature(headers['X-Hub-Signature'], data) then
    ngx.log(ngx.ERR, "wrong webhook signature")
    return ngx.exit (ngx.HTTP_FORBIDDEN)
    end

    data = json.decode(data)
    -- on master branch
    if data['ref'] ~= branch then
    ngx.say("Skip branch ", data['ref'])
    return ngx.exit (ngx.HTTP_OK)
    end

    return true
    end


    local function deploy ()
    -- run command for deploy
    local handle = io.popen("cd /path/to/repo && sudo -u username git pull")
    local result = handle:read("*a")
    handle:close()

    ngx.say (result)
    return ngx.exit (ngx.HTTP_OK)
    end


    if validate_hook() then
    deploy()
    end
    7 changes: 7 additions & 0 deletions nginx.conf
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,7 @@
    server {
    # ....

    location /deploy {
    content_by_lua_file /path/to/handler.lua;
    }
    }