新增:webhook service
This commit is contained in:
parent
d59e99feca
commit
17279c56f4
|
@ -1,42 +1,42 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: attachments
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# container_id :integer
|
||||
# container_type :string(30)
|
||||
# filename :string(255) default(""), not null
|
||||
# disk_filename :string(255) default(""), not null
|
||||
# filesize :integer default("0"), not null
|
||||
# content_type :string(255) default("")
|
||||
# digest :string(60) default(""), not null
|
||||
# downloads :integer default("0"), not null
|
||||
# author_id :integer default("0"), not null
|
||||
# created_on :datetime
|
||||
# description :text(65535)
|
||||
# disk_directory :string(255)
|
||||
# attachtype :integer default("1")
|
||||
# is_public :integer default("1")
|
||||
# copy_from :string(255)
|
||||
# quotes :integer default("0")
|
||||
# is_publish :integer default("1")
|
||||
# publish_time :datetime
|
||||
# resource_bank_id :integer
|
||||
# unified_setting :boolean default("1")
|
||||
# cloud_url :string(255) default("")
|
||||
# course_second_category_id :integer default("0")
|
||||
# delay_publish :boolean default("0")
|
||||
# link :string(255)
|
||||
# clone_id :integer
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_attachments_on_author_id (author_id)
|
||||
# index_attachments_on_clone_id (clone_id)
|
||||
# index_attachments_on_container_id_and_container_type (container_id,container_type)
|
||||
# index_attachments_on_created_on (created_on)
|
||||
#
|
||||
|
||||
# == Schema Information
|
||||
#
|
||||
# Table name: attachments
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# container_id :integer
|
||||
# container_type :string(30)
|
||||
# filename :string(255) default(""), not null
|
||||
# disk_filename :string(255) default(""), not null
|
||||
# filesize :integer default("0"), not null
|
||||
# content_type :string(255) default("")
|
||||
# digest :string(60) default(""), not null
|
||||
# downloads :integer default("0"), not null
|
||||
# author_id :integer default("0"), not null
|
||||
# created_on :datetime
|
||||
# description :text(65535)
|
||||
# disk_directory :string(255)
|
||||
# attachtype :integer default("1")
|
||||
# is_public :integer default("1")
|
||||
# copy_from :string(255)
|
||||
# quotes :integer default("0")
|
||||
# is_publish :integer default("1")
|
||||
# publish_time :datetime
|
||||
# resource_bank_id :integer
|
||||
# unified_setting :boolean default("1")
|
||||
# cloud_url :string(255) default("")
|
||||
# course_second_category_id :integer default("0")
|
||||
# delay_publish :boolean default("0")
|
||||
# link :string(255)
|
||||
# clone_id :integer
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_attachments_on_author_id (author_id)
|
||||
# index_attachments_on_clone_id (clone_id)
|
||||
# index_attachments_on_container_id_and_container_type (container_id,container_type)
|
||||
# index_attachments_on_created_on (created_on)
|
||||
#
|
||||
|
||||
|
||||
|
||||
class Attachment < ApplicationRecord
|
||||
|
@ -184,4 +184,14 @@ class Attachment < ApplicationRecord
|
|||
is_pdf
|
||||
end
|
||||
|
||||
def to_builder
|
||||
Jbuilder.new do |attachment|
|
||||
attachment.id self.id
|
||||
attachment.title self.title
|
||||
attachment.filesize self.filesize
|
||||
attachment.is_pdf self.is_pdf?
|
||||
attachment.created_on self.created_on.strftime("%Y-%m-%d %H:%M")
|
||||
attachment.content_type self.content_type
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
class Gitea::WebhookTask < Gitea::Base
|
||||
serialize :payload_content, JSON
|
||||
serialize :request_content, JSON
|
||||
serialize :response_content, JSON
|
||||
|
||||
self.inheritance_column = nil
|
||||
|
||||
|
@ -10,9 +11,4 @@ class Gitea::WebhookTask < Gitea::Base
|
|||
|
||||
enum type: {gogs: 1, slack: 2, gitea: 3, discord: 4, dingtalk: 5, telegram: 6, msteams: 7, feishu: 8, matrix: 9}
|
||||
|
||||
def response_content_json
|
||||
JSON.parse(response_content)
|
||||
rescue
|
||||
{}
|
||||
end
|
||||
end
|
|
@ -217,4 +217,30 @@ class Issue < ApplicationRecord
|
|||
SendTemplateMessageJob.perform_later('IssueExpire', self.id) if Site.has_notice_menu? && self.due_date == Date.today + 1.days
|
||||
end
|
||||
|
||||
def to_builder
|
||||
Jbuilder.new do |issue|
|
||||
issue.(self, :id, :project_issues_index, :subject, :description)
|
||||
issue.created_at self.created_on.strftime("%Y-%m-%d %H:%M")
|
||||
issue.updated_at self.updated_on.strftime("%Y-%m-%d %H:%M")
|
||||
issue.tags self.show_issue_tags.map{|t| t.to_builder}
|
||||
issue.status self.issue_status.to_builder
|
||||
if self.priority.present?
|
||||
issue.priority self.priority.to_builder
|
||||
else
|
||||
issue.priority nil
|
||||
end
|
||||
if self.version.present?
|
||||
issue.milestone self.version.to_builder
|
||||
else
|
||||
issue.milestone nil
|
||||
end
|
||||
issue.author self.user.to_builder
|
||||
issue.assigners self.show_assigners.map{|t| t.to_builder}
|
||||
issue.participants self.participants.distinct.map{|t| t.to_builder}
|
||||
issue.comment_journals_count self.comment_journals.size
|
||||
issue.operate_journals_count self.operate_journals.size
|
||||
issue.attachments self.attachments.map{|t| t.to_builder}
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -32,4 +32,10 @@ class IssuePriority < ApplicationRecord
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
def to_builder
|
||||
Jbuilder.new do |priority|
|
||||
priority.(self, :id, :name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -44,4 +44,10 @@ class IssueStatus < ApplicationRecord
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
def to_builder
|
||||
Jbuilder.new do |status|
|
||||
status.(self, :id, :name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -53,4 +53,11 @@ class IssueTag < ApplicationRecord
|
|||
self.update_column(:pull_requests_count, pull_request_issues.size)
|
||||
end
|
||||
|
||||
|
||||
def to_builder
|
||||
Jbuilder.new do |tag|
|
||||
tag.(self, :id, :name, :description)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -446,4 +446,59 @@ class Project < ApplicationRecord
|
|||
def del_project_issue_cache_delete_count
|
||||
$redis_cache.hdel("issue_cache_delete_count", self.id)
|
||||
end
|
||||
|
||||
def to_builder
|
||||
Jbuilder.new do |project|
|
||||
project.id self.id
|
||||
project.identifier self.identifier
|
||||
project.name self.name
|
||||
project.description Nokogiri::HTML(self.description).text
|
||||
project.visits self.visits
|
||||
project.praises_count self.praises_count.to_i
|
||||
project.watchers_count self.watchers_count.to_i
|
||||
project.issues_count self.issues_count.to_i
|
||||
project.pull_requests_count self.pull_requests_count.to_i
|
||||
project.forked_count self.forked_count.to_i
|
||||
project.is_public self.is_public
|
||||
project.mirror_url self.repository&.mirror_url
|
||||
project.type self&.project_type
|
||||
project.created_at self.created_on.strftime("%Y-%m-%d %H:%M")
|
||||
project.updated_at self.updated_on.strftime("%Y-%m-%d %H:%M")
|
||||
project.forked_from_project_id self.forked_from_project_id
|
||||
project.platform self.platform
|
||||
project.author do
|
||||
if self.educoder?
|
||||
project_educoder = self.project_educoder
|
||||
project.name project_educoder&.owner
|
||||
project.type 'Educoder'
|
||||
project.login project_educoder&.repo_name.split('/')[0]
|
||||
project.image_url render_educoder_avatar_url(self.project_educoder)
|
||||
else
|
||||
user = self.owner
|
||||
project.name user.try(:show_real_name)
|
||||
project.type user&.type
|
||||
project.login user.login
|
||||
project.image_url user.get_letter_avatar_url
|
||||
end
|
||||
end
|
||||
|
||||
project.category do
|
||||
if self.project_category.blank?
|
||||
project.nil!
|
||||
else
|
||||
project.id self.project_category.id
|
||||
project.name self.project_category.name
|
||||
end
|
||||
end
|
||||
project.language do
|
||||
if self.project_language.blank?
|
||||
project.nil!
|
||||
else
|
||||
project.id self.project_language.id
|
||||
project.name self.project_language.name
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -859,6 +859,16 @@ class User < Owner
|
|||
end
|
||||
end
|
||||
|
||||
def to_builder
|
||||
Jbuilder.new do |user|
|
||||
user.(self, :id, :login)
|
||||
user.name self.real_name
|
||||
user.email self.mail
|
||||
user.image_url self.get_letter_avatar_url
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
protected
|
||||
def validate_password_length
|
||||
# 管理员的初始密码是5位
|
||||
|
|
|
@ -55,6 +55,12 @@ class Version < ApplicationRecord
|
|||
User.select(:login, :lastname,:firstname, :nickname)&.find_by_id(self.user_id)
|
||||
end
|
||||
|
||||
def to_builder
|
||||
Jbuilder.new do |version|
|
||||
version.(self, :id, :name, :description, :effective_date)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def send_create_message_to_notice_system
|
||||
SendTemplateMessageJob.perform_later('ProjectMilestone', self.id, self.user_id) if Site.has_notice_menu?
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
module Webhook::Client
|
||||
|
||||
# uuid SecureRandom.uuid
|
||||
# hmac = OpenSSL::HMAC.new(secret, OpenSSL::Digest::SHA1.new)
|
||||
# message = Gitea::WebhookTask.last.read_attribute_before_type_cast("payload_content")
|
||||
# hmac.update(message)
|
||||
# sha1 = hmac.digest.unpack('H*').first
|
||||
|
||||
attr_reader :uuid, :event, :http_method, :content_type, :url, :secret, :payload_content
|
||||
attr_accessor :request_content, :response_content
|
||||
|
||||
def initialize(opts)
|
||||
@uuid = opts[:uuid]
|
||||
@event = opts[:event]
|
||||
@http_method = opts[:http_method]
|
||||
@content_type = opts[:content_type]
|
||||
@url = opts[:url]
|
||||
@secret = opts[:secret]
|
||||
@payload_content = opts[:payload_content]
|
||||
@request_content = {}
|
||||
@response_content = {}
|
||||
end
|
||||
|
||||
def do_request
|
||||
headers = {}
|
||||
headers['Content-Type'] = trans_content_type
|
||||
headers["X-Gitea-Delivery"] = @uuid
|
||||
headers["X-Gitea-Event"] = @event
|
||||
headers["X-Gitea-Event-Type"] = @event
|
||||
headers["X-Gitea-Signature"] = signatureSHA256
|
||||
headers["X-Gogs-Delivery"] = @uuid
|
||||
headers["X-Gogs-Event"] = @event
|
||||
headers["X-Gogs-Event-Type"] = @event
|
||||
headers["X-Gogs-Signature"] = signatureSHA256
|
||||
headers["X-Hub-Signature"] = "sha1=" + signatureSHA1
|
||||
headers["X-Hub-Signature-256"] = "sha256=" + signatureSHA256
|
||||
headers["X-GitHub-Delivery"] = @uuid
|
||||
headers["X-GitHub-Event"] = @event
|
||||
headers["X-GitHub-Event-Type"] = @event
|
||||
@request_content["url"] = @url
|
||||
@request_content["http_method"] = @http_method
|
||||
@request_content["headers"] = headers
|
||||
|
||||
response = RestClient::Request.execute(method: trans_http_method, url: @url, headers: headers, payload: payload_content) {|response, request, result| response }
|
||||
|
||||
@response_content["status"] = response.code
|
||||
@response_content["headers"] = response.headers
|
||||
@response_content["body"] = response.body.to_json
|
||||
|
||||
return @request_content, @response_content
|
||||
end
|
||||
|
||||
def request_content
|
||||
@request_content
|
||||
end
|
||||
|
||||
def response_content
|
||||
@response_content
|
||||
end
|
||||
|
||||
private
|
||||
def signatureSHA1
|
||||
hmac = OpenSSL::HMAC.new(@secret, OpenSSL::Digest::SHA1.new)
|
||||
message = @payload_content
|
||||
|
||||
hmac.digest.unpack('H*').first
|
||||
end
|
||||
|
||||
def signatureSHA256
|
||||
hmac = OpenSSL::HMAC.new(@secret, OpenSSL::Digest::SHA256.new)
|
||||
message = @payload_content
|
||||
|
||||
hmac.digest.unpack('H*').first
|
||||
end
|
||||
|
||||
def trans_content_type
|
||||
if @content_type == "form"
|
||||
return "application/x-www-form-urlencoded"
|
||||
else
|
||||
return "application/json"
|
||||
end
|
||||
end
|
||||
|
||||
def trans_http_method
|
||||
if @http_method == "GET"
|
||||
return :get
|
||||
else
|
||||
return :post
|
||||
end
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,53 @@
|
|||
class Webhook::IssueCreateClient
|
||||
|
||||
include Webhook::Client
|
||||
|
||||
attr_accessor :webhook, :issue, :sender
|
||||
attr_accessor :webhook_task
|
||||
|
||||
def initialize(webhook, issue, sender)
|
||||
@webhook = webhook
|
||||
@issue = issue
|
||||
@sender = sender
|
||||
# 创建webhook task
|
||||
@webhook_task = Gitea::WebhookTask.create(
|
||||
hook_id: @webhook.id,
|
||||
uuid: SecureRandom.uuid,
|
||||
payload_content: payload_content,
|
||||
event_type: "issues",
|
||||
is_delivered: true
|
||||
)
|
||||
|
||||
# 构建client参数
|
||||
super({
|
||||
uuid: @webhook_task.uuid,
|
||||
event: "issues",
|
||||
http_method: @webhook.http_method,
|
||||
content_type: @webhook.content_type,
|
||||
url: @webhook.url,
|
||||
secret: @webhook.secret,
|
||||
payload_content: @webhook_task.read_attribute_before_type_cast("payload_content")
|
||||
})
|
||||
end
|
||||
|
||||
def do_request
|
||||
request_content, response_content = super
|
||||
@webhook_task.update_attributes({
|
||||
delivered: Time.now.to_i * 1000000000,
|
||||
is_succeed: response_content["status"] < 300,
|
||||
request_content: request_content,
|
||||
response_content: response_content
|
||||
})
|
||||
end
|
||||
|
||||
def payload_content
|
||||
{
|
||||
"action": "opened",
|
||||
"number": @issue.project_issues_index,
|
||||
"issue": JSON.parse(@issue.to_builder.target!),
|
||||
"project": JSON.parse(@issue.project.to_builder.target!),
|
||||
"sender": JSON.parse(@sender.to_builder.target!)
|
||||
}
|
||||
end
|
||||
|
||||
end
|
Loading…
Reference in New Issue