Merge branch 'standalone_develop' into pre_trustie_server
This commit is contained in:
commit
b3de601527
|
@ -205,9 +205,10 @@ class AccountsController < ApplicationController
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
LimitForbidControl::UserLogin.new(@user).clear
|
||||||
successful_authentication(@user)
|
successful_authentication(@user)
|
||||||
sync_pwd_to_gitea!(@user, {password: params[:password].to_s}) # TODO用户密码未同步
|
sync_pwd_to_gitea!(@user, {password: params[:password].to_s}) # TODO用户密码未同步
|
||||||
|
|
||||||
# session[:user_id] = @user.id
|
# session[:user_id] = @user.id
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
module Api::ProjectHelper
|
module Api::ProjectHelper
|
||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
def load_project
|
def load_project
|
||||||
namespace = params[:owner]
|
namespace = params[:owner]
|
||||||
repo = params[:repo]
|
repo = params[:repo]
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ module Api::ProjectHelper
|
||||||
else
|
else
|
||||||
logger.info "###########:project not found"
|
logger.info "###########:project not found"
|
||||||
@project = nil
|
@project = nil
|
||||||
render_not_found and return
|
tip_exception(404, '您访问的页面不存在或已被删除')
|
||||||
end
|
end
|
||||||
@project
|
@project
|
||||||
end
|
end
|
||||||
|
|
|
@ -8,15 +8,20 @@ class InstallationsController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@install_bots = BotInstall.where(:installer_id => current_user.id)
|
@install_bots = BotInstall.where(bot_id: get_bot_id).group(:installer_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def show
|
def show
|
||||||
@install_bot = BotInstall.find params[:id]
|
@install_bot = BotInstall.find_by(bot_id: get_bot_id, installer_id: params[:id]) || BotInstall.find_by(id: params[:id])
|
||||||
|
tip_exception "参数installer_id错误" if @install_bot.blank?
|
||||||
end
|
end
|
||||||
|
|
||||||
def repositories
|
def repositories
|
||||||
@install_bots = BotInstall.where(:installer_id => current_user.id)
|
# 与github差异,所以取安装用户和bot对应所有的仓库
|
||||||
|
# 必须使用access_tokens获取到bot的token才能查询
|
||||||
|
tip_exception "无效Token" if current_user.platform != "bot"
|
||||||
|
bot = Bot.find_by(uid: current_user.id)
|
||||||
|
@install_bots = BotInstall.where(bot_id: bot.id).where(installer_id: params[:id])
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_secret
|
def update_secret
|
||||||
|
@ -57,11 +62,13 @@ class InstallationsController < ApplicationController
|
||||||
@install_bot.update_attributes!(state: 0)
|
@install_bot.update_attributes!(state: 0)
|
||||||
render_ok
|
render_ok
|
||||||
end
|
end
|
||||||
|
|
||||||
def unsuspended
|
def unsuspended
|
||||||
@install_bot = BotInstall.find params[:id]
|
@install_bot = BotInstall.find params[:id]
|
||||||
@install_bot.update_attributes!(state: 1)
|
@install_bot.update_attributes!(state: 1)
|
||||||
render_ok
|
render_ok
|
||||||
end
|
end
|
||||||
|
|
||||||
def auth_active
|
def auth_active
|
||||||
begin
|
begin
|
||||||
@bot = Bot.find params[:id]
|
@bot = Bot.find params[:id]
|
||||||
|
@ -86,7 +93,8 @@ class InstallationsController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def access_tokens
|
def access_tokens
|
||||||
@install_bot = BotInstall.find params[:id]
|
@install_bot = BotInstall.find_by(bot_id: get_bot_id, installer_id: params[:id]) || BotInstall.find_by(id: params[:id])
|
||||||
|
tip_exception "参数installer_id错误" if @install_bot.blank?
|
||||||
@bot = @install_bot.bot
|
@bot = @install_bot.bot
|
||||||
@application = Doorkeeper::Application.find_by(uid: @bot.client_id, secret: @bot.client_secret)
|
@application = Doorkeeper::Application.find_by(uid: @bot.client_id, secret: @bot.client_secret)
|
||||||
tip_exception("该Bot未激活") if @application.blank?
|
tip_exception("该Bot未激活") if @application.blank?
|
||||||
|
@ -101,5 +109,19 @@ class InstallationsController < ApplicationController
|
||||||
render_ok(token: @access_token.token)
|
render_ok(token: @access_token.token)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def get_bot_id
|
||||||
|
header = request.authorization
|
||||||
|
pattern = /^Bearer /i
|
||||||
|
token = header.gsub(pattern, "")
|
||||||
|
decoded_token = JWT.decode token, nil, false
|
||||||
|
# 前面已验证token有效期和正确性
|
||||||
|
decoded_token[0]["iss"]
|
||||||
|
rescue JWT::DecodeError
|
||||||
|
Rails.logger.error "jwt token decode error:#{token}"
|
||||||
|
tip_exception("无效Token")
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -235,9 +235,9 @@ class RepositoriesController < ApplicationController
|
||||||
|
|
||||||
def readme
|
def readme
|
||||||
if params[:filepath].present?
|
if params[:filepath].present?
|
||||||
result = Gitea::Repository::Readme::DirService.call(@owner.login, @repository.identifier, params[:filepath], params[:ref], current_user&.gitea_token)
|
result = Gitea::Repository::Readme::DirService.call(@owner.login, @repository.identifier, params[:filepath], params[:ref], @owner&.gitea_token)
|
||||||
else
|
else
|
||||||
result = Gitea::Repository::Readme::GetService.call(@owner.login, @repository.identifier, params[:ref], current_user&.gitea_token)
|
result = Gitea::Repository::Readme::GetService.call(@owner.login, @repository.identifier, params[:ref], @owner&.gitea_token)
|
||||||
end
|
end
|
||||||
@path = GiteaService.gitea_config[:domain]+"/#{@owner.login}/#{@repository.identifier}/raw/branch/#{params[:ref]}/"
|
@path = GiteaService.gitea_config[:domain]+"/#{@owner.login}/#{@repository.identifier}/raw/branch/#{params[:ref]}/"
|
||||||
@readme = result[:status] === :success ? result[:body] : nil
|
@readme = result[:status] === :success ? result[:body] : nil
|
||||||
|
|
|
@ -4,7 +4,7 @@ class Projects::CreateForm < BaseForm
|
||||||
:blockchain, :blockchain_token_all, :blockchain_init_token
|
:blockchain, :blockchain_token_all, :blockchain_init_token
|
||||||
|
|
||||||
validates :user_id, :name, :repository_name, presence: true
|
validates :user_id, :name, :repository_name, presence: true
|
||||||
validates :repository_name, format: { with: CustomRegexp::REPOSITORY_NAME_REGEX, multiline: true, message: "只能含有数字、字母、下划线且不能以下划线开头和结尾" }
|
validates :repository_name, format: { with: CustomRegexp::REPOSITORY_NAME_REGEX, multiline: true, message: "项目标识只能包含数字,字母,下划线(_),中划线(-),英文句号(.),必须以数字和字母开头,不能以下划线/中划线开头和结尾" }
|
||||||
|
|
||||||
validates :name, length: { maximum: 50 }
|
validates :name, length: { maximum: 50 }
|
||||||
validates :repository_name, length: { maximum: 100 }
|
validates :repository_name, length: { maximum: 100 }
|
||||||
|
|
|
@ -3,7 +3,7 @@ class Projects::MigrateForm < BaseForm
|
||||||
:project_language_id, :clone_addr, :private, :is_mirror, :auth_username, :auth_password, :owner
|
:project_language_id, :clone_addr, :private, :is_mirror, :auth_username, :auth_password, :owner
|
||||||
|
|
||||||
validates :user_id, :name, :repository_name, :clone_addr, presence: true
|
validates :user_id, :name, :repository_name, :clone_addr, presence: true
|
||||||
validates :repository_name, format: { with: CustomRegexp::REPOSITORY_NAME_REGEX, multiline: true, message: "只能含有数字、字母、下划线且不能以下划线开头和结尾" }
|
validates :repository_name, format: { with: CustomRegexp::REPOSITORY_NAME_REGEX, multiline: true, message: "项目标识只能包含数字,字母,下划线(_),中划线(-),英文句号(.),必须以数字和字母开头,不能以下划线/中划线开头和结尾" }
|
||||||
validates :clone_addr, format: { with: CustomRegexp::URL_REGEX, multiline: true, message: "地址格式不正确" }
|
validates :clone_addr, format: { with: CustomRegexp::URL_REGEX, multiline: true, message: "地址格式不正确" }
|
||||||
validates :name, length: { maximum: 50 }
|
validates :name, length: { maximum: 50 }
|
||||||
validates :repository_name, length: { maximum: 100 }
|
validates :repository_name, length: { maximum: 100 }
|
||||||
|
|
|
@ -3,7 +3,7 @@ class Projects::UpdateForm < BaseForm
|
||||||
validates :name, presence: true
|
validates :name, presence: true
|
||||||
validates :name, length: { maximum: 50 }
|
validates :name, length: { maximum: 50 }
|
||||||
validates :description, length: { maximum: 200 }
|
validates :description, length: { maximum: 200 }
|
||||||
validates :identifier, format: { with: CustomRegexp::REPOSITORY_NAME_REGEX, multiline: true, message: "只能含有数字、字母、下划线且不能以下划线开头和结尾" }
|
validates :identifier, format: { with: CustomRegexp::REPOSITORY_NAME_REGEX, multiline: true, message: '项目标识只能包含数字,字母,下划线(_),中划线(-),英文句号(.),必须以数字和字母开头,不能以下划线/中划线开头和结尾' }
|
||||||
|
|
||||||
validate do
|
validate do
|
||||||
check_project_category(project_category_id)
|
check_project_category(project_category_id)
|
||||||
|
|
|
@ -25,7 +25,7 @@ module Gitea
|
||||||
def run
|
def run
|
||||||
Contents::CreateForm.new(valid_params).validate!
|
Contents::CreateForm.new(valid_params).validate!
|
||||||
result = Gitea::Repository::Entries::CreateService.call(token,
|
result = Gitea::Repository::Entries::CreateService.call(token,
|
||||||
owner, @params[:identifier], @params[:filepath], file_params)
|
owner, @params[:identifier], file_path, file_params)
|
||||||
|
|
||||||
if result[:status] == :success
|
if result[:status] == :success
|
||||||
@result = result[:body]
|
@result = result[:body]
|
||||||
|
@ -50,9 +50,17 @@ module Gitea
|
||||||
@result = response
|
@result = response
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def file_path
|
||||||
|
if @params[:base64_filepath].present?
|
||||||
|
Base64.decode64(params[:base64_filepath])
|
||||||
|
else
|
||||||
|
@params[:filepath]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def valid_params
|
def valid_params
|
||||||
{
|
{
|
||||||
filepath: @params[:filepath],
|
filepath: file_path,
|
||||||
branch: @params[:branch],
|
branch: @params[:branch],
|
||||||
new_branch: @params[:new_branch]
|
new_branch: @params[:new_branch]
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ module Gitea
|
||||||
|
|
||||||
def run
|
def run
|
||||||
Contents::DeleteForm.new(valid_params).validate!
|
Contents::DeleteForm.new(valid_params).validate!
|
||||||
response = Gitea::Repository::Entries::DeleteService.new(token, owner, @params[:identifier], @params[:filepath], file_params).call
|
response = Gitea::Repository::Entries::DeleteService.new(token, owner, @params[:identifier], file_path, file_params).call
|
||||||
render_result(response)
|
render_result(response)
|
||||||
rescue Exception => exception
|
rescue Exception => exception
|
||||||
fail!(exception.message)
|
fail!(exception.message)
|
||||||
|
@ -45,9 +45,17 @@ module Gitea
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def file_path
|
||||||
|
if @params[:base64_filepath].present?
|
||||||
|
Base64.decode64(params[:base64_filepath])
|
||||||
|
else
|
||||||
|
@params[:filepath]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def valid_params
|
def valid_params
|
||||||
{
|
{
|
||||||
filepath: @params[:filepath],
|
filepath: file_path,
|
||||||
sha: @params[:sha]
|
sha: @params[:sha]
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
|
@ -24,7 +24,7 @@ module Gitea
|
||||||
|
|
||||||
def run
|
def run
|
||||||
Contents::UpdateForm.new(valid_params).validate!
|
Contents::UpdateForm.new(valid_params).validate!
|
||||||
response = Gitea::Repository::Entries::UpdateService.new(token, owner, @params[:identifier], @params[:filepath], file_params).call
|
response = Gitea::Repository::Entries::UpdateService.new(token, owner, @params[:identifier], file_path, file_params).call
|
||||||
render_result(response)
|
render_result(response)
|
||||||
rescue Exception => exception
|
rescue Exception => exception
|
||||||
fail!(exception.message)
|
fail!(exception.message)
|
||||||
|
@ -45,9 +45,25 @@ module Gitea
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def file_path
|
||||||
|
if @params[:base64_filepath].present?
|
||||||
|
Base64.decode64(params[:base64_filepath])
|
||||||
|
else
|
||||||
|
@params[:filepath]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def from_file_path
|
||||||
|
if @params[:base64_from_path].present?
|
||||||
|
Base64.decode64(params[:base64_from_path])
|
||||||
|
else
|
||||||
|
@params[:from_path]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def valid_params
|
def valid_params
|
||||||
{
|
{
|
||||||
filepath: @params[:filepath],
|
filepath: file_path,
|
||||||
branch: @params[:branch],
|
branch: @params[:branch],
|
||||||
new_branch: @params[:new_branch],
|
new_branch: @params[:new_branch],
|
||||||
sha: @params[:sha]
|
sha: @params[:sha]
|
||||||
|
@ -59,7 +75,7 @@ module Gitea
|
||||||
branch: @params[:branch],
|
branch: @params[:branch],
|
||||||
sha: @params[:sha],
|
sha: @params[:sha],
|
||||||
new_branch: @params[:new_branch],
|
new_branch: @params[:new_branch],
|
||||||
from_path: @params[:from_path],
|
from_path: from_file_path,
|
||||||
message: @params[:message],
|
message: @params[:message],
|
||||||
content: Base64.encode64(@params[:content])
|
content: Base64.encode64(@params[:content])
|
||||||
).compact
|
).compact
|
||||||
|
|
|
@ -10,6 +10,6 @@ module CustomRegexp
|
||||||
IP = /^((\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])\.){3}(\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])$/
|
IP = /^((\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])\.){3}(\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])$/
|
||||||
|
|
||||||
URL_REGEX = /\A(?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d{1,3}){3})(?!127(?:\.\d{1,3}){3})(?!169\.254(?:\.\d{1,3}){2})(?!192\.168(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:\/[^\s]*)?\z/i
|
URL_REGEX = /\A(?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d{1,3}){3})(?!127(?:\.\d{1,3}){3})(?!169\.254(?:\.\d{1,3}){2})(?!192\.168(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:\/[^\s]*)?\z/i
|
||||||
REPOSITORY_NAME_REGEX = /^(?!_)(?!.*?_$)[a-zA-Z0-9_-]+$/ #只含有数字、字母、下划线不能以下划线开头和结尾
|
REPOSITORY_NAME_REGEX = /^[a-zA-Z0-9][a-zA-Z0-9\-\_\.]+$/ #只含有数字、字母、下划线不能以下划线开头和结尾
|
||||||
MD_REGEX = /^.+(\.[m|M][d|D])$/
|
MD_REGEX = /^.+(\.[m|M][d|D])$/
|
||||||
end
|
end
|
||||||
|
|
|
@ -36,7 +36,7 @@ class Bot < ApplicationRecord
|
||||||
|
|
||||||
def self.decode_jwt_token(token)
|
def self.decode_jwt_token(token)
|
||||||
decoded_token = JWT.decode token, nil, false
|
decoded_token = JWT.decode token, nil, false
|
||||||
return [nil, "Token已过期"] if Time.now.to_i - 60 - decoded_token[0]["exp"].to_i > 0
|
return [nil, "Token已过期"] if Time.now.to_i - 10*60 - decoded_token[0]["exp"].to_i > 0
|
||||||
bot = Bot.find_by(id: decoded_token[0]["iss"])
|
bot = Bot.find_by(id: decoded_token[0]["iss"])
|
||||||
return [nil, "Token不存在"] if bot.blank?
|
return [nil, "Token不存在"] if bot.blank?
|
||||||
rsa_private = OpenSSL::PKey::RSA.new(bot.private_key)
|
rsa_private = OpenSSL::PKey::RSA.new(bot.private_key)
|
||||||
|
|
|
@ -93,9 +93,14 @@ module ProjectOperable
|
||||||
team_user.destroy! if team_user
|
team_user.destroy! if team_user
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# 安装bot后的权限
|
||||||
|
def is_install_bot?(user)
|
||||||
|
user.platform == "bot" && BotInstall.joins(:bot).where(bot: { uid: user.id }).where(store_id: self.id).exists?
|
||||||
|
end
|
||||||
|
|
||||||
def member?(user_id)
|
def member?(user_id)
|
||||||
if owner.is_a?(User)
|
if owner.is_a?(User)
|
||||||
members.exists?(user_id: user_id)
|
members.exists?(user_id: user_id) || is_install_bot?(User.find_by(id: user_id))
|
||||||
elsif owner.is_a?(Organization)
|
elsif owner.is_a?(Organization)
|
||||||
members.exists?(user_id: user_id) || team_projects.joins(team: :team_users).where(team_users: {user_id: user_id}).present?
|
members.exists?(user_id: user_id) || team_projects.joins(team: :team_users).where(team_users: {user_id: user_id}).present?
|
||||||
else
|
else
|
||||||
|
|
|
@ -380,7 +380,13 @@ class Project < ApplicationRecord
|
||||||
|
|
||||||
user = Owner.find_by_login namespace_path
|
user = Owner.find_by_login namespace_path
|
||||||
user = User.new(login: namespace_path) if user.nil?
|
user = User.new(login: namespace_path) if user.nil?
|
||||||
project = user&.projects&.find_by(identifier: identifier) || Project.find_by(identifier: "#{namespace_path}/#{identifier}")
|
if identifier.end_with?('.json')
|
||||||
|
project = user&.projects&.find_by(identifier: identifier) || Project.find_by(identifier: "#{namespace_path}/#{identifier}")
|
||||||
|
identifier = identifier.sub(/.*\K.json/, '')
|
||||||
|
project = user&.projects&.find_by(identifier: identifier) || Project.find_by(identifier: "#{namespace_path}/#{identifier}")
|
||||||
|
else
|
||||||
|
project = user&.projects&.find_by(identifier: identifier) || Project.find_by(identifier: "#{namespace_path}/#{identifier}")
|
||||||
|
end
|
||||||
return nil if project.blank?
|
return nil if project.blank?
|
||||||
|
|
||||||
[project, user]
|
[project, user]
|
||||||
|
|
|
@ -3,7 +3,12 @@ json.type webhook["type"]
|
||||||
json.content_type webhook['config']['content_type']
|
json.content_type webhook['config']['content_type']
|
||||||
json.http_method webhook['config']['http_method']
|
json.http_method webhook['config']['http_method']
|
||||||
json.url webhook['config']['url']
|
json.url webhook['config']['url']
|
||||||
json.events webhook['events']
|
event = webhook.events
|
||||||
|
if event["send_everything"]
|
||||||
|
json.events event["events"].keys.collect{|i| %w(pull_request issues).include?(i) ? i + "_only" : i}
|
||||||
|
else
|
||||||
|
json.events event["events"].select{|k, v| v}.keys.collect{|i| %w(pull_request issues).include?(i) ? i + "_only" : i}
|
||||||
|
end
|
||||||
json.active webhook['active']
|
json.active webhook['active']
|
||||||
json.branch_filter webhook['branch_filter']
|
json.branch_filter webhook['branch_filter']
|
||||||
json.created_at format_time(webhook['created_at'].to_time)
|
json.created_at format_time(webhook['created_at'].to_time)
|
|
@ -2,10 +2,15 @@ json.status 0
|
||||||
json.message "success"
|
json.message "success"
|
||||||
json.data do
|
json.data do
|
||||||
json.array! @install_bots do |install_bot|
|
json.array! @install_bots do |install_bot|
|
||||||
json.installation_id install_bot.id
|
json.extract! install_bot, :id, :bot_id, :installer_id, :create_time, :update_time
|
||||||
json.extract! install_bot.bot, :id, :name
|
json.bot_name install_bot&.bot&.name
|
||||||
json.bot_id install_bot.bot.id
|
json.account do
|
||||||
json.bot_name install_bot.bot.name
|
user = User.find_by(id: install_bot.installer_id)
|
||||||
|
if user.present?
|
||||||
|
json.partial! "api/v1/users/simple_user", locals: {user: user}
|
||||||
|
else
|
||||||
|
json.nil!
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
|
@ -1,5 +1,13 @@
|
||||||
json.partial! "commons/success"
|
json.partial! "commons/success"
|
||||||
|
|
||||||
json.extract! @install_bot, :id, :bot_id, :installer_id, :state, :create_time, :update_time
|
json.extract! @install_bot, :id, :bot_id, :installer_id, :create_time, :update_time
|
||||||
json.bot_name @install_bot.bot.name
|
json.bot_name @install_bot&.bot&.name
|
||||||
|
json.account do
|
||||||
|
user = User.find_by(id: @install_bot.installer_id)
|
||||||
|
if user.present?
|
||||||
|
json.partial! "api/v1/users/simple_user", locals: { user: user }
|
||||||
|
else
|
||||||
|
json.nil!
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ json.create_time Time.at(@webhook.created_unix).strftime("%Y-%m-%d %H:%M:%S")
|
||||||
event = @webhook.events
|
event = @webhook.events
|
||||||
json.branch_filter event["branch_filter"]
|
json.branch_filter event["branch_filter"]
|
||||||
if event["send_everything"]
|
if event["send_everything"]
|
||||||
json.events event["events"].keys.collect{|i| i == "pull_request" ? i + "_only" : i}
|
json.events event["events"].keys.collect{|i| %w(pull_request issues).include?(i) ? i + "_only" : i}
|
||||||
else
|
else
|
||||||
json.events event["events"].select{|k, v| v}.keys.collect{|i| i == "pull_request" ? i + "_only" : i}
|
json.events event["events"].select{|k, v| v}.keys.collect{|i| %w(pull_request issues).include?(i) ? i + "_only" : i}
|
||||||
end
|
end
|
||||||
|
|
|
@ -54,7 +54,7 @@ if @project.forge?
|
||||||
json.submodule_git_url entry['submodule_git_url'].nil? ? nil : repo_git_submodule_url(@owner, @repository, entry['submodule_git_url'])
|
json.submodule_git_url entry['submodule_git_url'].nil? ? nil : repo_git_submodule_url(@owner, @repository, entry['submodule_git_url'])
|
||||||
json.size entry['size']
|
json.size entry['size']
|
||||||
json.is_readme_file is_readme?(entry['type'], entry['name'])
|
json.is_readme_file is_readme?(entry['type'], entry['name'])
|
||||||
json.content decode64_content(entry, @owner, @repository, @ref, @path)
|
json.content nil #decode64_content(entry, @owner, @repository, @ref, @path)
|
||||||
json.target entry['target']
|
json.target entry['target']
|
||||||
json.commit do
|
json.commit do
|
||||||
json.partial! 'last_commit', latest_commit: entry['latest_commit']
|
json.partial! 'last_commit', latest_commit: entry['latest_commit']
|
||||||
|
|
|
@ -467,7 +467,7 @@ Rails.application.routes.draw do
|
||||||
|
|
||||||
namespace :traces do
|
namespace :traces do
|
||||||
resources :trace_users, only: [:create]
|
resources :trace_users, only: [:create]
|
||||||
scope "/:owner/:repo" do
|
scope "/:owner/:repo", constraints: { repo: /[^\/]+/ } do
|
||||||
resource :projects, path: '/', only: [:index] do
|
resource :projects, path: '/', only: [:index] do
|
||||||
member do
|
member do
|
||||||
post :tasks
|
post :tasks
|
||||||
|
@ -480,7 +480,7 @@ Rails.application.routes.draw do
|
||||||
end
|
end
|
||||||
|
|
||||||
# Project Area START
|
# Project Area START
|
||||||
scope "/:owner/:repo" do
|
scope "/:owner/:repo",constraints: { repo: /[^\/]+/ } do
|
||||||
scope do
|
scope do
|
||||||
get(
|
get(
|
||||||
'/activity',
|
'/activity',
|
||||||
|
@ -1080,7 +1080,7 @@ Rails.application.routes.draw do
|
||||||
end
|
end
|
||||||
|
|
||||||
resources :installations, only: [] do
|
resources :installations, only: [] do
|
||||||
get :repositories, on: :collection
|
get :repositories, on: :member
|
||||||
end
|
end
|
||||||
|
|
||||||
root 'main#index'
|
root 'main#index'
|
||||||
|
|
|
@ -18,7 +18,7 @@ defaults format: :json do
|
||||||
resources :feedbacks, only: [:create]
|
resources :feedbacks, only: [:create]
|
||||||
end
|
end
|
||||||
|
|
||||||
scope ':repo' do
|
scope ':repo', constraints: { repo: /[^\/]+/ } do
|
||||||
# projects
|
# projects
|
||||||
resource :projects, path: '/', only: [:show, :update, :edit, :destroy] do
|
resource :projects, path: '/', only: [:show, :update, :edit, :destroy] do
|
||||||
collection do
|
collection do
|
||||||
|
|
|
@ -719,7 +719,7 @@
|
||||||
http://localhost:3000/api/licenses
|
http://localhost:3000/api/licenses
|
||||||
</code></pre></div><div class="highlight"><pre class="highlight javascript tab-javascript"><code><span class="k">await</span> <span class="nx">octokit</span><span class="p">.</span><span class="nx">request</span><span class="p">(</span><span class="dl">'</span><span class="s1">GET /api/licenses</span><span class="dl">'</span><span class="p">)</span>
|
</code></pre></div><div class="highlight"><pre class="highlight javascript tab-javascript"><code><span class="k">await</span> <span class="nx">octokit</span><span class="p">.</span><span class="nx">request</span><span class="p">(</span><span class="dl">'</span><span class="s1">GET /api/licenses</span><span class="dl">'</span><span class="p">)</span>
|
||||||
</code></pre></div><h3 id='http-request'>HTTP Request</h3>
|
</code></pre></div><h3 id='http-request'>HTTP Request</h3>
|
||||||
<p><code>GET https://forgeplus.trustie.net/api/licenses.json</code></p>
|
<p><code>GET https://www.gitlink.org.cn/api/licenses.json</code></p>
|
||||||
<h3 id='1f9ac54b15'>请求参数</h3>
|
<h3 id='1f9ac54b15'>请求参数</h3>
|
||||||
<table><thead>
|
<table><thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
require 'openssl'
|
||||||
|
require 'jwt' # https://rubygems.org/gems/jwt
|
||||||
|
|
||||||
|
# Private key contents
|
||||||
|
private_pem = File.read("/Users/xxq/Documents/gitlink-webhook.2022-06-09.private-key.pem")
|
||||||
|
private_key = OpenSSL::PKey::RSA.new(private_pem)
|
||||||
|
|
||||||
|
# Generate the JWT
|
||||||
|
payload = {
|
||||||
|
# issued at time, 60 seconds in the past to allow for clock drift
|
||||||
|
iat: Time.now.to_i - 60,
|
||||||
|
# JWT expiration time (10 minute maximum)
|
||||||
|
exp: Time.now.to_i + (10 * 60),
|
||||||
|
# GitHub App's identifier
|
||||||
|
iss: "209248"
|
||||||
|
}
|
||||||
|
|
||||||
|
jwt = JWT.encode(payload, private_key, "RS256")
|
||||||
|
puts jwt
|
||||||
|
# puts OpenSSL::PKey::RSA.new(private_key33).public_key.to_s
|
||||||
|
#
|
||||||
|
# rsa_private = OpenSSL::PKey::RSA.new(private_key33)
|
||||||
|
# rsa_public = rsa_private.public_key
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
# puts decoded_token[0]
|
||||||
|
# puts decoded_token[0]["iss"]
|
||||||
|
|
||||||
|
# serialized_private_key = OpenSSL::PKey::RSA::generate(2048).to_s
|
||||||
|
|
||||||
|
|
|
@ -2,12 +2,35 @@ require 'openssl'
|
||||||
require 'jwt' # https://rubygems.org/gems/jwt
|
require 'jwt' # https://rubygems.org/gems/jwt
|
||||||
|
|
||||||
# Private key contents
|
# Private key contents
|
||||||
private_pem = File.read("/Users/xxq/Documents/gitlink-webhook.2022-06-09.private-key.pem")
|
# private_pem = File.read("/Users/xxq/Documents/gitlink-webhook.2022-06-09.private-key.pem")
|
||||||
|
private_pem = "-----BEGIN RSA PRIVATE KEY-----
|
||||||
private_key22="-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEApOebWmRV/ooNq5Ks04YnDU7pEezGShGvaiF0cIvn9jvmYHu0\nFialojvJV3VpB6xE6QBPXZ0Pi1lokZ9dMx8F5UWNx9WA7wf7xK3hAJLNml+GeewF\nou8vk/Ry7n6diLxETNVd7YzPvztn5qaMp/DXa+65i11H8a/XXqR7kCVnCevVlufh\nNr/Dp6dW31W8TInnDQasJFMZ8GY7f+tCwLXNc0M8p+TeDp9xmXHOrEB+S/mgbUOF\nXgRr6icbMmlT9bsAxYHrrDkcVxJhs0hq5vD3BaoK06gcZEnN7/HVNzgVSOYNsVNh\n9006cMgDSOwc9F8aulP7cr8k74INq1xswoGs9wIDAQABAoIBAHayc2NkF3YJXv+h\nqx7yUEfHBgKuAKiuBCqLfCnKuqPFx/So9h5/oPeeuzVlwL0SJePlIjuK4vZ128v9\n/vLeILtADmbJ6m2jvHh8hBmKkc3Ndplp50C5k/CWoufCYZhbk3oOlvZ3Rc4rb4VZ\nWqNDu3voMMv8z91KqeZo1LwUAA/l9mU++zLkRA6qOuWGBJFsM8YpshzxL5lzRUb3\n7y+YJDyUZztfzKwr6pqm1n9B2e6e+znCw1vMZXp2TbUrpvrrXSxlgdNuK68SkZX6\nTdZUD8y0viwaioRVf3vR+e/Bf7yZannGdvcmVGs0A7dq9QgHkakqNHiRkQgwviSq\nbjBo7dECgYEAzekeP5j/dAPkv9X4qnmZ4du/+ZgrQrJckDD/JuNIBmQT9m286l4P\nmb2TBcWkswVOZaS5Qy2bN/69rwIbcdvbaROGBCabn3ATK4fSzmUk31M2rRKYZqaU\nMi0W2g2YtSRg+bV6S7aFXa98j5+JlqJeDZQoRuvL68ooq5WzFWmfYnkCgYEAzQTi\n4USqz2z66BfU+v2rchzK8URxnv7EW/CG3XFRsG+1UXCyEIct2L7rzvC7r7+jjS4s\ngmV3Civ1sckGMwikLzxFtUZ1LUBakZp/mmipIzxcHOeBsRdHei8BFvMNqveg1JpO\ncY/Fp+wEkSNLhfkb/IXRw0iwFalBRnyo4BJbLu8CgYBrQ7E6OB169jxHotNzGv2K\npssO3rJKgFev1ZZVT7jJe4Dasrfi7zT5RcQ9EYSGrZD1aiYIVM2zEcUGUfayDXHy\n/vSlXOdc2ylhV9P9KLtYiyTEbBdwAf7ZVJu+465VTqol6t/WaTJ4Z15gAx/NlK+i\nKzgAGf2Uyy78k3NDCE67IQKBgFwM0pUUEKEbLDhi4uRiWsTcep4C/gTGHIGvJ85r\nH6NZNI7BS6GyH/qOFjAO1CYfpB4yWhed2Om/PQw61sa5HYZ7yEyQuvG7UC7JsHsy\nfKZuZmkv5IIPkq8gRZv5OuzFS/fI5GmGhNdVV+OWdkVLyK4Do1/L1guTt9QfCm+4\nrioPAoGBALGr8aUAbz/A611M/bLnk04UYfV+M34/hCf6/rKiBHdQoIHOriSC9Nv7\nyhE5axTdmIWMxfbyb3vHJ5MizZkD/Qj0VDuMkyS2+3TepI6tySQE3YQeWnCMJI9i\nuoCZ31GBui4+W5udbx8NOVsJfXUQn/OAoOn6WuMNPdgB45KXcktj\n-----END RSA PRIVATE KEY-----\n"
|
MIIEowIBAAKCAQEAy3rJwhzC9K5f4Rc6KwYQKvdsUsbzrKdENBCjGq0kZ8LJltw+
|
||||||
private_key33= "-----BEGIN RSA PRIVATE KEY-----\nMIIEogIBAAKCAQEAq/wUH8N+5fzj3hArKY7ChC591R/uKyeNM/BbsR2OGxO5F1CE\nozy6thtPult96Gm9oK3sMpLdYCze2YgozgteFO1Ft0o1GEJ1A4SinOKzeixLpFy0\n5N9t+iz7Xa7jC/1E3uy/s2WvSYCS9NnK2Uj3DQOH8BUWfkvyTtt91a2pplbPCV3T\nw1PykAcDWIFXVJJCMtYd2x+DukSWKHRsYbBCMtVZhEVuKmTE3FBTDVu9sN3b7uLL\n5RzHUg13QZZr9OvMNR3nUZl6yDxw+wD4anDrtpL9C+tFjhMyqsyYpYWwcJm65YiD\ny7Ps24IdcLB4iOxJE91fu+MnicvyBrtEjoBP/wIDAQABAoIBAAcKc9x1CW3q8300\n1j+GS6pTqO0fuIVlwh8dOPPATQAIx6wPrM5t/wrThWkQs8/e/Fdmp2POpWd5jsoD\nDACbcIeUyyTc0d2jYtz5AhtAIK7gv1wEO5efGgaC7ut/7GWiQb6KnLKAeDOfIuUJ\nQYexuAN9YIRQqLIU89+MltM3n9liZTMuPWRFJcitaDytXa10TCe5RUqHGZf49pi7\njCgk0x7jDYqbIzsqOu741P8My/gkAjKPkRnjaj3o6MrwHzIlc4t/6mKbaPnywywk\n6roYMqmytgueA9wxFcj74ekBQAaXsu4xRkbZXxjcBtIvTId5IHHK5Z/r3fgE9K3J\nOuzzJ1kCgYEA3uu/pUjJbKegOsgSdu3cO/NvRV2YsRD4NUgtiMCEakE4VQXRK5pf\nV8xqQeH/rLjZf5aP5xe8n25krh/c+m0ezOMyu5MmhoxaWCPWIezsaKJXOcvsOxIu\n2sJ9GRMXabyuDuSdL7ZGYMpLhRclXYLyPCz7wzN445IluTHuD3lJ2qUCgYEAxYFh\ncVD73yNZn9BN1DSGWpfPtLqOKIdG+xi/ypCSGpJG0QCJRFi7R1qJOxFtJNI8DRiD\nZapPEGLVd/KY5NzBGZBfNQt4DQH9qR4l43c6NNkisWA9rvXvCDqXKmBq7wfpnkYr\n4Ul2hXYmsPJjP8e0BfG54PaSu3BDBMJMtcgDktMCgYBvzyDdnwdgVyc3tHgGbMFk\n1HHAAfT/ArrrxpsIFz+TJ8lAY92JGDGwENhO2TLrCAAXTYY5657w/GbFKzgj5y1m\nqKIekOzm2WjLApZ5h6L/zEUhuRVwf2s+0AP82qWIpFlNIP9yGeNs0qpUQ8q6/13O\nLuXL/3on8nq3S8LSwgv3/QKBgDfM+g7d5ouAnU29uH9/54Wo5pIVMxzYO4Gt2GIO\nvnirYz6hfCbHOwJJ3gPGRKPmkfjROC59E6F5iv48mF3w0M28MGn4N47VRSmGzwWZ\nJeTQhDDBFCxeZ45Xn2Xln9Cw15xUDwmzi7zhSMUtdkUK0x3q0a1xfLtgWE775lhl\njjzpAoGAdUXFW1elfjXpfIYZf7vUV7MPquKL7qAcopd96XBszhOn7g+ibzem+wgt\n1UTSeOBESYANHeJk2MuWPSRXk/FlQETVIcPAEp0kxbwQE+7YEdrMVeDcIe5lPwGD\n+WuS3kg0MPgUrXZXn74gcwWmSIOyHfqXULqOxWE25uU2icdV+2w=\n-----END RSA PRIVATE KEY-----\n"
|
TRuLVp0hwrWXS9msadjBnzatYneBrqnggj87pU0Mf/f6KkTmIsFH2gDKNMN6hRg/
|
||||||
private_key = OpenSSL::PKey::RSA.new(private_key33)
|
JW5XXveexGa9dZIQHPKOmp9dC+YpLHOPRO0NsYJM/JoQ4rWRhtMvq0zR/fJDuXyt
|
||||||
# puts private_key.to_json
|
xLehfH4N4ppVbdRGaK+FIKNCjHTmL/3jZ0b2J9D4Al9R5QWlEmRPa4ZFCOZNUMXK
|
||||||
|
nplNu2FE/ZjyKjE+f0MAn8hcSVR25XiQZ6StnxdyPvhXYNNU7yVJGTfCK/oTchTr
|
||||||
|
Tfk4bKIkct38datffjlhKM45VabhUfIStNr5uwIDAQABAoIBADSMgGBmBx8jjVVX
|
||||||
|
J0mHJlPCVDJIeROkmuOLTGQORPGbB26zcE9/houWxuo+9VS8YV9wgAh7GWntjQsr
|
||||||
|
ifR5GhFFha3iv7N82aYuHj05qP7ZYOHQcjZbearn7hOwqMsdLpYbOiLKd0Akb4uw
|
||||||
|
SFa3laq7CODPdP7nfy6/iXcGvtCC84E8XwDuUcFbzX8lLq0UI6HvdnySYOvglO3P
|
||||||
|
txqr76dc61nLEIu945uVKndzu65sWRfC397JG+hgYFUwikbiFPAVVH4jsiCzMAW0
|
||||||
|
oaTp6zQiE+h7HTGGHhnxFmnynmuq01E+wfxNvf8NHteBIMJA8g/gGHdpp+8E85V7
|
||||||
|
bcF8+fECgYEA5cs8nZHfrTdjqZB6vgY1sCVsuuHtmEACu3zbJu9dr21ps6bomnDW
|
||||||
|
Lw9Dx4tYSHPcL3zlu913qvXCnXsUGtjKeIVTHCdnwCnDTEam6GsDZab9zcmJ8Gkn
|
||||||
|
wqsjr/Cy7pjwxqT3nFRUGaJmrFUUfPQuNmSYWQbRiRIQirGY2JlZLvMCgYEA4q9Q
|
||||||
|
j8cwq5i1blWuyam8bx3efHBHMiMpJL/clc03//ddpsiae8GXZgRySJx9YPAYS+X/
|
||||||
|
ApVfnB/en+xidCIg8P2rRjRW/GgW3Y6rjLUMIFMD/0ObezX/dp2AVHUdOdlZ7z+k
|
||||||
|
4Ba8TZ8u5sfUO7USTxFl+fextLdBDSetOw/GDBkCgYAsYSjuwYpyWJ0t1VJvOqHJ
|
||||||
|
yCCMoy+Q1OPyM7XbeiUcyUO9x4FquloTMp6DfjzpmT6wCS4RLz96TAZvBaMnYDES
|
||||||
|
P6WCbXXTHf2y0H5RqsE4M50WzlKOlLByHz1AMHtOK0ltA9UyYvLvFHdB1xii3UHD
|
||||||
|
jYACyZdUIqIBNzVut4cK0wKBgBNbHOnp/EHqvDM7pb0afTiPuFuvyqSBVBYLO+6e
|
||||||
|
o1V77cc8AdTnZuITJx8EHcCVP73bWbcCwjM2lW/aY12/PEjXoDRSa8sJqEoq0IMn
|
||||||
|
Qm3QKNs3DqOqrLGYKUkM5v31jTRcnttzlYibOwoBriGbCIEv3yFFASuJKkjRRn1w
|
||||||
|
j1yhAoGBALqwZzRAle7t2jEWOyLaJeHUoSiZJv5dHOMRog7k5H24uTEKf3JCovQO
|
||||||
|
wZd4cIA4oXD/3b5cK3H2e5YjhBunsMRhRBLgz8FD4y69cKxbcgPvtjhkwYRB0/cy
|
||||||
|
21dHe2o7HfuZgUuh0kOlT0e326gQPIIlwuCBEAq6LzWrg8nd9Loz
|
||||||
|
-----END RSA PRIVATE KEY-----"
|
||||||
|
private_key = OpenSSL::PKey::RSA.new(private_pem)
|
||||||
|
|
||||||
# Generate the JWT
|
# Generate the JWT
|
||||||
payload = {
|
payload = {
|
||||||
|
@ -16,27 +39,15 @@ payload = {
|
||||||
# JWT expiration time (10 minute maximum)
|
# JWT expiration time (10 minute maximum)
|
||||||
exp: Time.now.to_i + (10 * 60),
|
exp: Time.now.to_i + (10 * 60),
|
||||||
# GitHub App's identifier
|
# GitHub App's identifier
|
||||||
iss: "782"
|
iss: "803"
|
||||||
}
|
}
|
||||||
|
|
||||||
jwt = JWT.encode(payload, private_key, "RS256")
|
jwt = JWT.encode(payload, private_key, "RS256")
|
||||||
puts jwt
|
puts jwt
|
||||||
# puts OpenSSL::PKey::RSA.new(private_key33).public_key.to_s
|
|
||||||
#
|
|
||||||
rsa_private = OpenSSL::PKey::RSA.new(private_key33)
|
decoded_token = JWT.decode "eyJhbGciOiJSUzI1NiJ9.eyJpYXQiOjE2ODA1OTkzNDAsImV4cCI6MTY4MDYwMDAwMCwiaXNzIjoiODAzIn0.wOCCMVbrulTVCIKDvmLtxCkTLtWJMGmY2mIZgfdJcKcixqZek1y_9YD7wF07wqP6qTjQaNiSDjdJSDGzO_Qi3qQT_2BaR6EWBUIcbaNz5GTHKLcOW4SFWj13OFJwjom6egz489b6qA3MPXmliWYR6F5zlLu1jlXjaWVvUZAy0AuAdmWiSocdjurt_giEIDefiRcPu_NbccWG-mAwa9wV9ja2PoZUJyHlzXR6rioLIO1rtw5bIX3E4YNPde9EkEK1eYLmedmhKfwlgX2CgdGodSHPg5Vro09XWiGaJkBwoi1T41BLVsb5hxqQc3DLrz1ZFFY1vXEkxIw4BIXitpk3kg", nil, false
|
||||||
rsa_public = rsa_private.public_key
|
puts decoded_token
|
||||||
|
puts Time.now.to_i - 60 - decoded_token[0]["exp"].to_i > 0
|
||||||
# decoded_token = JWT.decode jwt, nil, false
|
|
||||||
begin
|
|
||||||
decoded_token = JWT.decode jwt, rsa_private, true, { algorithm: 'RS256' }
|
|
||||||
rescue JWT::DecodeError
|
|
||||||
puts "jwt is not mmmmmm"
|
|
||||||
end
|
|
||||||
|
|
||||||
#
|
|
||||||
puts decoded_token[0]
|
|
||||||
puts decoded_token[0]["iss"]
|
|
||||||
|
|
||||||
# serialized_private_key = OpenSSL::PKey::RSA::generate(2048).to_s
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue