From 69632d99ea8bd2d0550eb8bface92407ec990b78 Mon Sep 17 00:00:00 2001 From: otegami Date: Thu, 12 Dec 2024 11:40:05 +0900 Subject: [PATCH] release: authorize webhook request using webhook secret token GitHub: GH-43 In this PR, we set up the authorization flow for webhook requests. At the following PRs, we will implement the logic of deoployments. --- .../home/deployer/webhook/lib/deployer/app.rb | 31 ++++++++++++++++++- .../deployer/webhook/lib/deployer/response.rb | 27 ++++++++++++++++ 2 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 ansible/files/home/deployer/webhook/lib/deployer/response.rb diff --git a/ansible/files/home/deployer/webhook/lib/deployer/app.rb b/ansible/files/home/deployer/webhook/lib/deployer/app.rb index 85f0af6..55edc17 100644 --- a/ansible/files/home/deployer/webhook/lib/deployer/app.rb +++ b/ansible/files/home/deployer/webhook/lib/deployer/app.rb @@ -1,3 +1,4 @@ +# Copyright (C) 2024 Horimoto Yasuhiro # Copyright (C) 2024 Takuya Kodama # # This program is free software: you can redistribute it and/or modify @@ -13,10 +14,38 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +require "openssl" +require_relative "response" + module Deployer class App def call(env) - [200, {}, ["Hello deployer"]] + request = Rack::Request.new(env) + response = Response.new + process(request, response) or response.finish + end + + private + + def process(request, response) + unless request.post? + response.set(:method_not_allowed, "must POST") + return nil + end + + unless verify_signature(request) + response.set(:unauthorized, "Authorization failed") + return nil + end + + response.finish + end + + def verify_signature(request) + signature = 'sha256=' + OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), + ENV['SECRET_TOKEN'], + request.body.read) + Rack::Utils.secure_compare(signature, request.env['HTTP_X_HUB_SIGNATURE_256']) end end end diff --git a/ansible/files/home/deployer/webhook/lib/deployer/response.rb b/ansible/files/home/deployer/webhook/lib/deployer/response.rb new file mode 100644 index 0000000..65fc6b9 --- /dev/null +++ b/ansible/files/home/deployer/webhook/lib/deployer/response.rb @@ -0,0 +1,27 @@ +# Copyright (C) 2010-2019 Sutou Kouhei +# Copyright (C) 2015 Kenji Okimoto +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +require "rack/response" + +module Deployer + class Response < Rack::Response + def set(status_keyword, message) + self.status = Rack::Utils.status_code(status_keyword) + self["Content-Type"] = "text/plain" + write(message) + end + end +end