lib/site_hook.rb in site_hook-0.6.8 vs lib/site_hook.rb in site_hook-0.6.9
- old
+ new
@@ -1,47 +1,27 @@
# frozen_string_literal: true
require 'site_hook/version'
require 'site_hook/sender'
+require 'site_hook/gem'
+require 'site_hook/log'
require 'site_hook/logger'
+require 'site_hook/spinner'
require 'recursive-open-struct'
require 'site_hook/cli'
require 'sinatra'
require 'haml'
require 'sass'
require 'json'
require 'sinatra/json'
require 'yaml'
+
module SiteHook
+ autoload :Logs, 'site_hook/log'
+ autoload :Gem, 'site_hook/gem'
+ autoload :Paths, 'site_hook/paths'
# rubocop:disable Metrics/ClassLength, Metrics/LineLength, MethodLength, BlockLength
- module Gem
- # class Info
- class Info
- def self.name
- 'site_hook'
- end
-
- def self.constant_name
- 'SiteHook'
- end
-
- def self.author
- 'Ken Spencer <me@iotaspencer.me>'
- end
- end
-
- # Paths: Paths to gem resources and things
- class Paths
- def self.config
- Pathname(Dir.home).join('.jph', 'config').to_s
- end
-
- def self.logs
- Pathname(Dir.home).join('.jph', 'logs')
- end
- end
- end
# class SassHandler (inherits from Sinatra::Base)
class SassHandler < Sinatra::Base
set :views, Pathname(app_file).dirname.join('site_hook', 'static', 'sass').to_s
get '/css/*.css' do
filename = params[:splat].first
@@ -55,162 +35,8 @@
filename = params[:splat].first
coffee filename.to_sym
end
end
# class Webhook (inherits from Sinatra::Base)
- class Webhook < Sinatra::Base
- HOOKLOG = SiteHook::HookLogger::HookLog.new(SiteHook.log_levels['hook']).log
- BUILDLOG = SiteHook::HookLogger::BuildLog.new(SiteHook.log_levels['build']).log
- APPLOG = SiteHook::HookLogger::AppLog.new(SiteHook.log_levels['app']).log
- JPHRC = YAML.load_file(Pathname(Dir.home).join('.jph', 'config'))
- set port: JPHRC.fetch('port', 9090)
- set bind: '127.0.0.1'
- set server: %w[thin]
- set quiet: true
- set raise_errors: true
- set views: Pathname(app_file).dirname.join('site_hook', 'views')
- set :public_folder, Pathname(app_file).dirname.join('site_hook', 'static')
- use SassHandler
- use CoffeeHandler
-#
- # @param [String] body JSON String of body
- # @param [String] sig Signature or token from git service
- # @param [String] secret User-defined verification token
- # @param [Boolean] plaintext Whether the verification is plaintext
- def self.verified?(body, sig, secret, plaintext:, service:)
- if plaintext
- sig == secret
- else
- case service
- when 'gogs'
- if sig == OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA256.new, secret, body)
- APPLOG.debug "Secret verified: #{sig} === #{OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA256.new, secret, body)}"
- true
- end
- when 'github'
- if sig == OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA1.new, secret, body)
- APPLOG.debug "Secret verified: #{sig} === #{OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA1.new, secret, body)}"
- true
- end
- end
-
- end
- end
-
- get '/' do
- halt 403, { 'Content-Type' => 'text/html' }, '<h1>See <a href="/webhooks/">here</a> for the active webhooks</h1>'
- end
-
- get '/webhooks.json', provides: :json do
- content_type 'application/json'
- public_projects = JPHRC['projects'].select do |_project, hsh|
- (hsh.fetch('private', nil) == false) || hsh.fetch('private', nil).nil?
- end
- result = {}
- public_projects.each do |project, hsh|
- result[project] = {}
- hsh.delete('hookpass')
- result[project].merge!(hsh)
- end
- headers 'Content-Type' => 'application/json', 'Accept' => 'application/json'
- json result, layout: false
- end
-
- get '/webhooks/?' do
- haml :webhooks, locals: { 'projects' => JPHRC['projects'] }
- end
-
- get '/webhook/*' do
- if params[:splat]
- pass
- else
- halt 405, { 'Content-Type' => 'application/json' }, { message: 'GET not allowed' }.to_json
- end
- end
- post '/webhook/:hook_name/?' do
- service = nil
- request.body.rewind
- req_body = request.body.read
- js = RecursiveOpenStruct.new(JSON.parse(req_body))
-
- projects = JPHRC['projects']
- begin
- project = projects.fetch(params[:hook_name])
- rescue KeyError => e
- halt 404, { 'Content-Type' => 'application/json' }, { message: 'no such project', status: 1 }.to_json
- end
- plaintext = false
- signature = nil
- event = nil
- github = request.env.fetch('HTTP_X_GITHUB_EVENT', nil)
- unless github.nil?
- event = 'push' if github == 'push'
- end
- gitlab = request.env.fetch('HTTP_X_GITLAB_EVENT', nil)
- unless gitlab.nil?
- event = 'push' if gitlab == 'push'
- end
- gogs = request.env.fetch('HTTP_X_GOGS_EVENT', nil)
- unless gogs.nil?
- event = 'push' if gogs == 'push'
- end
- events = { 'github' => github, 'gitlab' => gitlab, 'gogs' => gogs }
- events_m_e = events.values.one?
- case events_m_e
- when true
- event = 'push'
- service = events.select { |_key, value| value }.keys.first
- when false
- halt 400, { 'Content-Type': 'application/json' }, { message: 'events are mutually exclusive', status: 'failure' }.to_json
-
- else
- halt 400,
- { 'Content-Type': 'application/json' },
- 'status': 'failure', 'message': 'something weird happened'
- end
- if event != 'push'
- if event.nil?
- halt 400, { 'Content-Type': 'application/json' }, { message: 'no event header' }.to_json
- end
- end
- case service
- when 'gitlab'
- signature = request.env.fetch('HTTP_X_GITLAB_TOKEN', '')
- plaintext = true
- when 'github'
- signature = request.env.fetch('HTTP_X_HUB_SIGNATURE', '').sub!(/^sha1=/, '')
- plaintext = false
-
- when 'gogs'
- signature = request.env.fetch('HTTP_X_GOGS_SIGNATURE', '')
- plaintext = false
- end
- if Webhook.verified?(req_body.to_s, signature, project['hookpass'], plaintext: plaintext, service: service)
- BUILDLOG.info 'Building...'
-
- jekyllbuild = SiteHook::Senders::Jekyll.build(project['src'], project['dst'], BUILDLOG)
- jekyll_status = jekyllbuild.fetch(:status, 1)
- case jekyll_status
-
- when 0
- status 200
- headers 'Content-Type' => 'application/json'
- body { { 'status': 'success' }.to_json }
- when -1, -2, -3
- status 400
- headers 'Content-Type' => 'application/json'
- body do
- { 'status': 'exception', error: jekyll_status.fetch(:message).to_s }
- end
- end
-
- else
- halt 403, { 'Content-Type' => 'application/json' }, { message: 'incorrect secret', 'status': 'failure' }.to_json
- end
- end
- post '/webhook/?' do
- halt 403, { 'Content-Type' => 'application/json' }, { message: 'pick a hook', error: 'root webhook hit', 'status': 'failure' }.to_json
- end
- end
# rubocop:enable Metrics/ClassLength, Metrics/LineLength, MethodLength, BlockLength
end