| @@ -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 | |||