inbound webhoooks

This commit is contained in:
Celina Lopez
2024-09-25 16:21:22 -07:00
parent 6abdaa2830
commit 2231d235f8
12 changed files with 132 additions and 25 deletions

4
.env.test Normal file
View File

@@ -0,0 +1,4 @@
APP_HOST=canine.example.com
OMNIAUTH_GITHUB_WEBHOOK_SECRET=1234567890
OMNIAUTH_GITHUB_PUBLIC_KEY=1234567890
OMNIAUTH_GITHUB_PRIVATE_KEY=1234567890

1
.gitignore vendored
View File

@@ -10,6 +10,7 @@
# Ignore all environment files (except templates).
/.env*
!/.env*.erb
!/.env.test
# Ignore all logfiles and tempfiles.
/log/*

View File

@@ -0,0 +1,9 @@
module InboundWebhooks
class ApplicationController < ActionController::API
private
def payload
@payload ||= request.form_data? ? request.request_parameters.to_json : request.raw_post
end
end
end

View File

@@ -0,0 +1,29 @@
module InboundWebhooks
class GithubController < ApplicationController
before_action :verify_event
def create
# Save webhook to database
record = InboundWebhook.create(body: payload)
# Queue webhook for processing
InboundWebhooks::GithubJob.perform_later(record)
# Tell service we received the webhook successfully
head :ok
end
private
def verify_event
payload = request.body.read
# TODO: Verify the event was sent from the service
# Render `head :bad_request` if verification fails
secret = ENV["OMNIAUTH_GITHUB_WEBHOOK_SECRET"]
signature = "sha256=" + OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new("sha256"), secret, payload)
unless Rack::Utils.secure_compare(signature, request.headers["HTTP_X_HUB_SIGNATURE_256"])
head :bad_request
end
end
end
end

View File

@@ -1,7 +1,7 @@
module Users
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
before_action :set_service, except: [:failure]
before_action :set_user, except: [:failure]
before_action :set_service, except: [ :failure ]
before_action :set_user, except: [ :failure ]
attr_reader :service, :user
@@ -40,7 +40,7 @@ module Users
end
def auth
request.env['omniauth.auth']
request.env["omniauth.auth"]
end
def set_service
@@ -68,17 +68,16 @@ module Users
uid: auth.uid,
expires_at: expires_at,
access_token: auth.credentials.token,
access_token_secret: auth.credentials.secret,
access_token_secret: auth.credentials.secret
}
end
def create_user
User.create(
email: auth.info.email,
#name: auth.info.name,
password: Devise.friendly_token[0,20]
# name: auth.info.name,
password: Devise.friendly_token[0, 20]
)
end
end
end

View File

@@ -0,0 +1,20 @@
# == Schema Information
#
# Table name: inbound_webooks
#
# id :bigint not null, primary key
# body :text
# status :integer default("pending")
# created_at :datetime not null
# updated_at :datetime not null
#
class InboundWebook < ApplicationRecord
cattr_accessor :incinerate_after, default: 7.days
enum status: %i[pending processing processed failed]
after_update_commit :incinerate_later, if: -> { status_previously_changed? && processed? }
def incinerate_later
InboundWebhooks::IncinerationJob.set(wait: incinerate_after).perform_later(self)
end
end

View File

@@ -18,8 +18,6 @@
<%= link_to "Didn't receive unlock instructions?", new_unlock_path(resource_name) %><br />
<% end %>
<%- if devise_mapping.omniauthable? %>
<%- resource_class.omniauth_providers.each do |provider| %>
<%= link_to "Sign in with #{OmniAuth::Utils.camelize(provider)}", omniauth_authorize_path(resource_name, provider), method: :post %><br />
<% end %>
<%- resource_class.omniauth_providers.each do |provider| %>
<%= link_to "Sign in with #{OmniAuth::Utils.camelize(provider)}", omniauth_authorize_path(resource_name, provider), method: :post %><br />
<% end %>

View File

@@ -24,7 +24,7 @@ Devise.setup do |config|
# Configure the e-mail address which will be shown in Devise::Mailer,
# note that it will be overwritten if you use your own mailer class
# with default "from" parameter.
config.mailer_sender = 'please-change-me-at-config-initializers-devise@example.com'
config.mailer_sender = "please-change-me-at-config-initializers-devise@example.com"
# Configure the class responsible to send e-mails.
# config.mailer = 'Devise::Mailer'
@@ -36,7 +36,7 @@ Devise.setup do |config|
# Load and configure the ORM. Supports :active_record (default) and
# :mongoid (bson_ext recommended) by default. Other ORMs may be
# available as additional gems.
require 'devise/orm/active_record'
require "devise/orm/active_record"
# ==> Configuration for any authentication mechanism
# Configure which keys are used when authenticating a user. The default is
@@ -58,12 +58,12 @@ Devise.setup do |config|
# Configure which authentication keys should be case-insensitive.
# These keys will be downcased upon creating or modifying a user and when used
# to authenticate or find a user. Default is :email.
config.case_insensitive_keys = [:email]
config.case_insensitive_keys = [ :email ]
# Configure which authentication keys should have whitespace stripped.
# These keys will have whitespace before and after removed upon creating or
# modifying a user and when used to authenticate or find a user. Default is :email.
config.strip_whitespace_keys = [:email]
config.strip_whitespace_keys = [ :email ]
# Tell if authentication through request.params is enabled. True by default.
# It can be set to an array that will enable params authentication only for the
@@ -97,7 +97,7 @@ Devise.setup do |config|
# Notice that if you are skipping storage for all authentication paths, you
# may want to disable generating routes to Devise's sessions controller by
# passing skip: :sessions to `devise_for` in your config/routes.rb
config.skip_session_storage = [:http_auth]
config.skip_session_storage = [ :http_auth ]
# By default, Devise cleans up the CSRF token on authentication to
# avoid CSRF token fixation attacks. This means that, when using AJAX
@@ -271,14 +271,8 @@ Devise.setup do |config|
# ==> OmniAuth
# Add a new OmniAuth provider. Check the wiki for more information on setting
# up on your models and hooks.
# config.omniauth :github, 'APP_ID', 'APP_SECRET', scope: 'user,public_repo'
env_creds = Rails.application.credentials[Rails.env.to_sym] || {}
%i{ facebook twitter github }.each do |provider|
if options = env_creds[provider]
config.omniauth provider, options[:app_id], options[:app_secret], options.fetch(:options, {})
end
end
# TODO (chris): add digital ocean?
config.omniauth :github, ENV["OMNIAUTH_GITHUB_PRIVATE_KEY"], ENV["OMNIAUTH_GITHUB_PRIVATE_KEY"], scope: "user,repo,write:packages", webhook_secret: ENV["OMNIAUTH_GITHUB_WEBHOOK_SECRET"]
# ==> Warden configuration
# If you want to use other strategies, that are not supported by Devise, or

View File

@@ -0,0 +1,9 @@
class CreateInboundWebooks < ActiveRecord::Migration[7.2]
def change
create_table :inbound_webooks do |t|
t.text :body
t.integer :status, default: 0
t.timestamps
end
end
end

9
db/schema.rb generated
View File

@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[7.2].define(version: 2024_09_25_222027) do
ActiveRecord::Schema[7.2].define(version: 2024_09_25_230423) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -143,6 +143,13 @@ ActiveRecord::Schema[7.2].define(version: 2024_09_25_222027) do
t.index ["sluggable_type", "sluggable_id"], name: "index_friendly_id_slugs_on_sluggable_type_and_sluggable_id"
end
create_table "inbound_webooks", force: :cascade do |t|
t.text "body"
t.integer "status", default: 0
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "log_outputs", force: :cascade do |t|
t.bigint "loggable_id", null: false
t.string "loggable_type", null: false

20
test/fixtures/inbound_webooks.yml vendored Normal file
View File

@@ -0,0 +1,20 @@
# == Schema Information
#
# Table name: inbound_webooks
#
# id :bigint not null, primary key
# body :text
# status :integer default("pending")
# created_at :datetime not null
# updated_at :datetime not null
#
# This model initially had no columns defined. If you add columns to the
# model remove the "{}" from the fixture names and add the columns immediately
# below each fixture, per the syntax in the comments below
#
one: {}
# column: value
#
two: {}
# column: value

View File

@@ -0,0 +1,17 @@
# == Schema Information
#
# Table name: inbound_webooks
#
# id :bigint not null, primary key
# body :text
# status :integer default("pending")
# created_at :datetime not null
# updated_at :datetime not null
#
require "test_helper"
class InboundWebookTest < ActiveSupport::TestCase
# test "the truth" do
# assert true
# end
end