forgeplus/app/controllers/application_controller.rb

1134 lines
35 KiB
Ruby
Raw Permalink Normal View History

2020-03-09 00:40:16 +08:00
require 'oauth2'
2023-02-15 18:37:36 +08:00
# require 'openssl'
# require 'jwt'
2020-03-09 00:40:16 +08:00
class ApplicationController < ActionController::Base
include CodeExample
include RenderExpand
include RenderHelper
include ControllerRescueHandler
2020-03-14 00:17:18 +08:00
include LaboratoryHelper
2020-03-09 00:40:16 +08:00
include GitHelper
include LoggerHelper
include LoginHelper
2020-08-14 18:19:00 +08:00
include RegisterHelper
2020-09-23 16:58:22 +08:00
2020-03-09 00:40:16 +08:00
protect_from_forgery prepend: true, unless: -> { request.format.json? }
before_action :check_sign
before_action :user_setup
#before_action :check_account
# TODO
# check sql query time
before_action do
2022-07-26 16:32:53 +08:00
# if request.subdomain === 'testforgeplus' || request.subdomain === "profiler"
# Rack::MiniProfiler.authorize_request
# end
end
2020-03-09 00:40:16 +08:00
DCODES = %W(2 3 4 5 6 7 8 9 a b c f e f g h i j k l m n o p q r s t u v w x y z)
OPENKEY = Rails.application.config_for(:configuration)['sign_key'] || "79e33abd4b6588941ab7622aed1e67e8"
2020-03-09 00:40:16 +08:00
2021-04-23 14:40:26 +08:00
helper_method :current_user, :base_url
2020-03-09 00:40:16 +08:00
# 所有请求必须合法签名
def check_sign
2020-03-14 16:25:50 +08:00
# if !Rails.env.development?
# Rails.logger.info("66666 #{params}")
# # suffix = request.url.split(".").last.split("?").first
# # suffix_arr = ["xls", "xlsx", "pdf", "zip"] # excel文件先注释
# # unless suffix_arr.include?(suffix)
# if params[:client_key].present?
# randomcode = params[:randomcode]
# # tip_exception(501, "请求不合理") unless (Time.now.to_i - randomcode.to_i).between?(0,5)
#
# sign = Digest::MD5.hexdigest("#{OPENKEY}#{randomcode}")
# Rails.logger.info("2222 #{sign}")
# tip_exception(501, "请求不合理") if sign != params[:client_key]
# else
# tip_exception(501, "请求不合理")
# end
# # end
# end
2020-03-09 00:40:16 +08:00
end
# 全局配置参数
# 返回name对应的value
def edu_setting(name)
EduSetting.get(name)
end
# 平台身份权限判断(学生用户无权限)
def identity_auth
ue = current_user.user_extension
tip_exception(403, "..") unless current_user.admin_or_business? || ue.teacher? || ue.professional?
end
# 平台已认证身份判断(已认证的老师和专业人士)
def certi_identity_auth
ue = current_user.user_extension
tip_exception(403, "..") unless current_user.admin_or_business? ||
(current_user.professional_certification && (ue.teacher? || ue.professional?))
end
def admin_or_business?
2024-07-01 09:55:20 +08:00
User.current.admin? || User.current.business?
end
def admin_or_glcc_admin?
User.current.admin? || User.current.glcc_admin?
2020-03-09 00:40:16 +08:00
end
# 判断用户的邮箱或者手机是否可用
# params[:type] 1: 注册2忘记密码3绑定
def check_mail_and_phone_valid login, type
unless login =~ /\A[a-zA-Z0-9]+([._\-\\]*[a-zA-Z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+\z/ || login =~ /^1\d{10}$/
2020-03-09 00:40:16 +08:00
tip_exception(-2, "请输入正确的手机号或邮箱")
end
user_exist = Owner.exists?(phone: login) || Owner.exists?(mail: login)
if user_exist && type.to_i == 1
2020-03-09 00:40:16 +08:00
tip_exception(-2, "该手机号码或邮箱已被注册")
elsif type.to_i == 2 && !user_exist
2020-03-09 00:40:16 +08:00
tip_exception(-2, "该手机号码或邮箱未注册")
elsif type.to_i == 3 && user_exist
2020-03-09 00:40:16 +08:00
tip_exception(-2, "该手机号码或邮箱已绑定")
end
render_ok
2020-03-09 00:40:16 +08:00
end
2025-07-29 16:21:01 +08:00
def check_mail_valid mail, type
2025-07-29 16:30:11 +08:00
unless mail =~ /\A[a-zA-Z0-9]+([._\-\\]*[a-zA-Z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+\z/
2025-07-29 16:21:01 +08:00
tip_exception(-2, "请输入正确的邮箱")
end
2025-07-29 16:30:11 +08:00
user_exist = Owner.exists?(mail: mail)
2025-07-29 16:21:01 +08:00
if user_exist && type.to_i == 1
tip_exception(-2, "该邮箱已被注册")
elsif type.to_i == 2 && !user_exist
tip_exception(-2, "该邮箱未注册")
elsif type.to_i == 3 && user_exist
2025-07-31 13:55:00 +08:00
tip_exception(-2, "该邮箱已被注册")
2025-07-29 16:21:01 +08:00
end
render_ok
end
2025-07-29 16:30:11 +08:00
def check_phone_valid phone, type
unless phone =~ /^1\d{10}$/
2025-07-29 16:21:01 +08:00
tip_exception(-2, "请输入正确的手机号")
end
2025-07-29 16:30:11 +08:00
user_exist = Owner.exists?(phone: phone)
2025-07-29 16:21:01 +08:00
if user_exist && type.to_i == 1
tip_exception(-2, "该手机号码已被注册")
elsif type.to_i == 2 && !user_exist
tip_exception(-2, "该手机号码未注册")
elsif type.to_i == 3 && user_exist
2025-07-31 13:55:00 +08:00
tip_exception(-2, "该手机号码已被注册")
2025-07-29 16:21:01 +08:00
end
render_ok
end
2020-03-09 00:40:16 +08:00
# 发送及记录激活码
# 发送验证码type 1注册手机验证码 2找回密码手机验证码 3找回密码邮箱验证码 4绑定手机 5绑定邮箱
# 6手机验证码登录 7邮箱验证码登录 8邮箱注册验证码 9验证手机号有效
def check_verification_code(code, send_type, value)
case send_type
when 1, 2, 4, 9
# 手机类型的发送
sigle_para = {phone: value}
2022-11-15 10:03:01 +08:00
# status = Gitlink::Sms.send(mobile: value, code: code)
# tip_exception(-2, code_msg(status)) if status != 0
2022-11-24 11:09:58 +08:00
status = Sms::UcloudService.call(value, code, send_type)
2022-11-15 10:03:01 +08:00
tip_exception(-2, ucloud_code_msg(status)) if status != 0
2020-03-09 00:40:16 +08:00
when 8, 3, 5
# 邮箱类型的发送
sigle_para = {email: value}
# 60s内不能重复发送
# send_email_limit_cache_key = "send_email_60_second_limit:#{value}"
# tip_exception(-1, '请勿频繁操作') if Rails.cache.exist?(send_email_limit_cache_key)
2020-03-09 00:40:16 +08:00
# # 短时间内不能大量发送
# send_email_control = LimitForbidControl::SendEmailCode.new(value)
# tip_exception(-1, '邮件发送太频繁,请稍后再试') if send_email_control.forbid?
2020-03-09 00:40:16 +08:00
begin
2022-11-15 14:31:18 +08:00
if send_type == 3
UserMailer.find_password(value, code).deliver_now
elsif send_type == 5
UserMailer.bind_email(value, code).deliver_now
else
UserMailer.register_email(value, code).deliver_now
end
# Rails.cache.write(send_email_limit_cache_key, 1, expires_in: 1.minute)
# send_email_control.increment!
2020-03-09 00:40:16 +08:00
# Mailer.run.email_register(code, value)
rescue Exception => e
logger_error(e)
tip_exception(-2,"邮件发送失败,请稍后重试")
end
end
ver_params = {code_type: send_type, code: code}.merge(sigle_para)
VerificationCode.create!(ver_params)
end
def code_msg status
case status
when 0
"验证码已经发送到您的手机,请注意查收"
when 8
"同一手机号30秒内重复提交相同的内容"
when 9
"同一手机号5分钟内重复提交相同的内容超过3次"
when 22
"1小时内同一手机号发送次数超过限制"
when 33
"验证码发送次数超过频率"
when 43
"一天内同一手机号发送次数超过限制"
when 53
"手机号接收超过频率限制"
end
end
2022-11-15 10:03:01 +08:00
def ucloud_code_msg status
case status
when 0
"验证码已经发送到您的手机,请注意查收"
when 171
"API签名错误"
when 18014
"无效手机号码"
when 18017
"无效模板"
when 18018
"短信模板参数与短信模板不匹配"
when 18023
"短信内容中含有运营商拦截的关键词"
when 18033
"变量内容不符合规范"
else
"错误码#{status}"
end
end
2020-03-09 00:40:16 +08:00
def validate_type(object_type)
normal_status(2, "参数") if params.has_key?(:sort_type) && !SORT_TYPE.include?(params[:sort_type].strip)
end
def set_pagination
@page = params[:page] || 1
@page_size = params[:page_size] || 15
end
def require_admin
normal_status(403, "") unless User.current.admin?
end
def require_business
normal_status(403, "") unless admin_or_business?
end
2024-07-01 09:55:20 +08:00
def require_glcc_admin
normal_status(403, "") unless admin_or_glcc_admin?
end
2020-03-09 00:40:16 +08:00
# 前端会捕捉401,弹登录弹框
# 未授权的捕捉407弹试用申请弹框
def require_login
#6.13 -hs
tip_exception(401, "请登录后再操作") unless User.current.logged?
end
2024-10-22 09:27:53 +08:00
def require_referer
tip_exception(403, "你没有权限访问") if request.host.present? && !request.referer.to_s.include?(request.host.to_s.gsub("www.",""))
end
2022-10-21 09:42:21 +08:00
def require_login_or_token
if params[:token].present?
user = User.try_to_autologin(params[:token])
User.current = user
end
tip_exception(401, "请登录后再操作") unless User.current.logged?
end
2022-10-25 11:19:59 +08:00
def require_login_cloud_ide_saas
if params[:sign].present? && params[:email].present?
sign = Digest::MD5.hexdigest("#{OPENKEY}#{params[:email]}")
if params[:sign].to_s == sign
user = User.find_by(mail: params[:email])
User.current = user
end
end
tip_exception(401, "请登录后再操作") unless User.current.logged?
end
2021-08-31 18:00:54 +08:00
def require_profile_completed
2023-05-12 15:20:14 +08:00
# tip_exception(411, "请完善资料后再操作") unless User.current.profile_is_completed?
2021-08-31 18:00:54 +08:00
end
def require_user_profile_completed(user)
2023-05-12 15:20:14 +08:00
# tip_exception(412, "请用户完善资料后再操作") unless user.profile_is_completed?
end
2020-03-09 00:40:16 +08:00
# 异常提醒
def tip_exception(status = -1, message)
2021-11-11 18:03:30 +08:00
raise Gitlink::TipException.new(status, message)
2020-03-09 00:40:16 +08:00
end
def missing_template
tip_exception(404, "...")
end
# 弹框提醒
def tip_show_exception(status = -2, message)
2021-11-11 18:03:30 +08:00
raise Gitlink::TipException.new(status, message)
2020-03-09 00:40:16 +08:00
end
def normal_status(status = 0, message)
case status
when 403
message = "您没有权限进行该操作"
when 404
message = "您访问的页面不存在或已被删除"
end
render :json => { status: status, message: message }
end
# 资料是否完善
def check_account
2021-09-29 10:39:50 +08:00
if !current_user. profile_is_completed?
2020-03-09 00:40:16 +08:00
#info_url = '/account/profile'
tip_exception(402, nil)
end
end
# 系统全局认证(暂时隐藏试用申请的判断)
def check_auth
# day_cer = UserDayCertification.find_by(user_id: current_user.id)
# # 如果注册超过24小时则需要完善资料及授权
# if (Time.now.to_i - day_cer.try(:created_at).to_i) > 86400
# if !current_user.profile_completed?
# info_url = '/account/profile'
# tip_exception(402, info_url)
# elsif current_user.certification != 1
# if current_user.apply_actions.exists?(container_type: 'TrialAuthorization', status: 0)
# tip_exception(408, "您的试用申请正在审核中,请耐心等待")
# end
# tip_exception(407, "系统未授权")
# end
# end
# if current_user.certification != 1 && current_user.apply_actions.exists?(container_type: 'TrialAuthorization', status: 0)
# tip_exception(408, "您的试用申请正在审核中,请耐心等待")
# elsif (Time.now.to_i - day_cer.try(:created_at).to_i) < 86400
# if !current_user.profile_completed?
# info_url = '/account/profile'
# tip_exception(402, info_url)
# elsif current_user.certification != 1
# day_cer = UserDayCertification.find_by(user_id: current_user.id)
# tip_exception(407, "系统未授权") unless (Time.now.to_i - day_cer.try(:created_at).to_i) < 86400
# end
# end
end
def user_setup
# # reacct静态资源加载不需要走这一步
#return if params[:controller] == "main"
# Find the current user
#Rails.logger.info("current_laboratory is #{current_laboratory} domain is #{request.subdomain}")
2022-07-13 12:47:39 +08:00
if request.headers["Authorization"].present? && request.headers["Authorization"].start_with?('Bearer')
2023-02-15 18:37:36 +08:00
if !valid_doorkeeper_token?
header = request.authorization
pattern = /^Bearer /i
token = header.gsub(pattern, "")
User.current, message = Bot.decode_jwt_token(token)
tip_exception(401, message) if message.present?
else
if @doorkeeper_token.present?
# client方法对接需要一直带着用户标识uid
if @doorkeeper_token.resource_owner_id.blank?
tip_exception(-1, "缺少用户标识!") if params[:uid].nil?
User.current = User.find(params[:uid])
else
User.current = User.find_by(id: @doorkeeper_token.resource_owner_id)
end
2022-07-11 18:19:08 +08:00
end
end
2023-02-15 18:37:36 +08:00
else
User.current = find_current_user
uid_logger("user_setup: " + (User.current.logged? ? "#{User.current.try(:login)} (id=#{User.current.try(:id)})" : "anonymous"))
# # 开放课程通过链接访问的用户
# if !User.current.logged? && !params[:chinaoocTimestamp].blank? && !params[:websiteName].blank? && !params[:chinaoocKey].blank?
# content = "#{OPENKEY}#{params[:websiteName]}#{params[:chinaoocTimestamp]}"
#
# if Digest::MD5.hexdigest(content) == params[:chinaoocKey]
# user = open_class_user
# if user
# start_user_session(user)
# set_autologin_cookie(user)
# end
# User.current = user
# end
# end
2020-03-09 00:40:16 +08:00
2022-08-30 18:10:27 +08:00
if !User.current.logged? && Rails.env.development?
user = User.find 1
User.current = user
start_user_session(user)
end
# 测试版前端需求
logger.info("subdomain:#{request.subdomain}")
if request.subdomain != "www"
if params[:debug] == 'teacher' #todo 为了测试,记得讲debug删除
User.current = User.find 81403
elsif params[:debug] == 'student'
User.current = User.find 8686
elsif params[:debug] == 'admin'
logger.info "@@@@@@@@@@@@@@@@@@@@@@ debug mode....."
2025-06-12 16:06:51 +08:00
user = User.find 1
User.current = user
cookies.signed[:user_id] = user.id
end
2021-12-29 14:23:51 +08:00
end
end
2020-03-09 00:40:16 +08:00
# User.current = User.find 81403
end
# Returns the current user or nil if no user is logged in
# and starts a session if needed
def find_current_user
uid_logger("user setup start: session[:user_id] is #{session[:user_id]}")
uid_logger("0000000000000user setup start: default_yun_session is #{default_yun_session}, session[:current_user_id] is #{session[:"#{default_yun_session}"]}")
current_domain_session = session[:"#{default_yun_session}"]
autologin_user = try_to_autologin
uid_logger("user setup start: autologin_user is #{autologin_user}")
# 多浏览器退出账号时token不存在处理
if current_domain_session && autologin_user.nil?
autologin_user = (User.active.find(current_domain_session) rescue nil)
set_autologin_cookie(autologin_user) if autologin_user.present?
2020-03-09 00:40:16 +08:00
end
autologin_user
2020-03-09 00:40:16 +08:00
end
def try_to_autologin
if cookies[autologin_cookie_name]
# auto-login feature starts a new session
user = nil
Rails.logger.info("111111111111111111#{default_yun_session}, session is #{session[:"#{default_yun_session}"]} ")
user = User.try_to_autologin(cookies[autologin_cookie_name])
# start_user_session(user) if user # TODO 解决sso退出不同步的问题
user
elsif params[:token].present?
User.try_to_autologin(params[:token])
elsif request.headers["Authorization-token"].present?
User.try_to_autologin(request.headers["Authorization-token"])
end
end
2020-03-09 00:40:16 +08:00
def api_request?
%w(xml json).include? params[:format]
end
def current_user
2020-10-30 15:47:09 +08:00
User.current
2020-03-09 00:40:16 +08:00
end
## 默认输出json
def render_json
respond_to do |format|
format.json
end
end
## 输出错误信息
def error_status(message = nil)
@status = -1
@message = message
end
def repo_url(repo_path)
"#{edu_setting('git_address_domain')}/#{repo_path}"
end
# Post请求
def uri_post(uri, params)
begin
uid_logger_dubug("--uri_exec: params is #{params}, url is #{uri}")
uri = URI.parse(URI.encode(uri.strip))
res = Net::HTTP.post_form(uri, params).body
uid_logger_dubug("--uri_exec: .....res is #{res}")
JSON.parse(res)
rescue Exception => e
uid_logger_error("--uri_exec: exception #{e.message}")
2021-11-11 18:03:30 +08:00
raise Gitlink::TipException.new("实训平台繁忙繁忙等级84")
2020-03-09 00:40:16 +08:00
end
end
# 处理返回非0就报错的请求
def interface_post(uri, params, status, message)
begin
uid_logger_dubug("--uri_exec: params is #{params}, url is #{uri}")
uri = URI.parse(URI.encode(uri.strip))
res = Net::HTTP.post_form(uri, params).body
uid_logger_dubug("--uri_exec: .....res is #{res}")
res = JSON.parse(res)
if (res && res['code'] != 0)
tip_exception(status, message)
else
res
end
rescue Exception => e
uid_logger("--uri_exec: exception #{e.message}")
2021-11-11 18:03:30 +08:00
raise Gitlink::TipException.new(message)
2020-03-09 00:40:16 +08:00
end
end
# json格式请求
def interface_json_post(uri, params, status, message)
begin
uid_logger_dubug("--uri_exec: params is #{params}, url is #{uri}")
uri = URI.parse(URI.encode(uri.strip))
res = Net::HTTP.start(uri.host, uri.port) do |http|
req = Net::HTTP::Post.new(uri)
req['Content-Type'] = 'application/json'
req.body = params.to_json
http.request(req)
end
uid_logger_dubug("--uri_exec: .....res is #{res.body}")
res = JSON.parse(res.body)
if (res && res['code'] != 0)
tip_exception(status, message)
else
res
end
rescue Exception => e
uid_logger("--uri_exec: exception #{e.message}")
2021-11-11 18:03:30 +08:00
raise Gitlink::TipException.new("服务器繁忙")
2020-03-09 00:40:16 +08:00
end
end
# 适用与已经用url_safe编码后回调字符串形式
def tran_base64_decode64(str)
s_size = str.size % 4
if s_size != 0
str += "=" * (4 - s_size)
end
if str.blank?
str
else
Base64.decode64(str.tr("-_", "+/")).force_encoding("utf-8")
end
end
def sucess_status(message = 'success')
render :json => { status: 1, message: message }
end
# 随机生成字符
def generate_identifier(container, num, pre='')
code = DCODES.sample(num).join
if container == User
while container.exists?(login: pre+code) do
code = DCODES.sample(num).join
end
else
while container.exists?(identifier: code) do
code = DCODES.sample(num).join
end
end
code
end
def strip_html(text, len=0, endss="...")
ss = ""
if !text.nil? && text.length>0
ss=text.gsub(/<\/?.*?>/, '').strip
ss = ss.gsub(/&nbsp;*/, '')
ss = ss.gsub(/\r\n/,'') #新增
ss = ss.gsub(/\n/,'') #新增
if len > 0 && ss.length > len
ss = ss[0, len] + endss
elsif len > 0 && ss.length <= len
ss = ss
#ss = truncate(ss, :length => len)
end
end
ss
end
# Returns a string that can be used as filename value in Content-Disposition header
def filename_for_content_disposition(name)
request.env['HTTP_USER_AGENT'] =~ %r{MSIE|Trident|Edge} ? ERB::Util.url_encode(name) : name
end
def format_time(time)
time.blank? ? '' : time.strftime("%Y-%m-%d %H:%M")
end
# 获取Oauth Client
def get_client(site)
2021-11-11 18:03:30 +08:00
client_id = Rails.configuration.Gitlink['client_id']
client_secret = Rails.configuration.Gitlink['client_secret']
2020-03-09 00:40:16 +08:00
OAuth2::Client.new(client_id, client_secret, site: site)
end
def paginate(relation)
limit = params[:limit] || params[:per_page]
limit = (limit.to_i.zero? || limit.to_i > 20) ? 20 : limit.to_i
page = params[:page].to_i.zero? ? 1 : params[:page].to_i
offset = (page - 1) * limit
if relation.is_a?(Array)
relation[offset, limit]
else
relation.limit(limit).offset(offset)
end
end
2020-05-09 15:51:40 +08:00
def kaminari_paginate(relation)
limit = params[:limit] || params[:per_page]
2023-01-05 15:40:03 +08:00
limit = (limit.to_i.zero? || limit.to_i > 50) ? 50 : limit.to_i
2020-05-09 15:51:40 +08:00
page = params[:page].to_i.zero? ? 1 : params[:page].to_i
2020-03-09 00:40:16 +08:00
2020-05-09 15:51:40 +08:00
relation.page(page).per(limit)
end
2020-03-09 00:40:16 +08:00
def kaminari_unlimit_paginate(relation)
limit = params[:limit] || params[:per_page]
limit = (limit.to_i.zero? || limit.to_i > 9999) ? 9999 : limit.to_i
page = params[:page].to_i.zero? ? 1 : params[:page].to_i
relation.page(page).per(limit)
end
2021-01-15 14:55:52 +08:00
def kaminari_array_paginate(relation)
2021-01-13 15:43:30 +08:00
limit = params[:limit] || params[:per_page]
2021-11-03 11:38:47 +08:00
limit = (limit.to_i.zero? || limit.to_i > 20) ? 20 : limit.to_i
2021-01-13 15:43:30 +08:00
page = params[:page].to_i.zero? ? 1 : params[:page].to_i
Kaminari.paginate_array(relation).page(page).per(limit)
end
2020-03-09 00:40:16 +08:00
def strf_time(time)
time.blank? ? '' : time.strftime("%Y-%m-%d %H:%M:%S")
end
def strf_date(date)
date.blank? ? '' : date.to_date.strftime("%Y-%m-%d")
end
def logger_error(error)
Rails.logger.error(error.message)
error.backtrace.each { |msg| Rails.logger.error(msg) }
end
def find_user
@user = User.find_by_login params[:login]
render_not_found("未找到’#{params[:login]}’相关的用户") unless @user
end
def find_user_with_id
2024-03-22 08:49:26 +08:00
@user = User.find_by(type: 'User', id: params[:user_id])
2020-03-30 11:55:45 +08:00
# render_not_found("未找到’#{params[:login]}’相关的用户") unless @user
render_error("未找到相关的用户") unless @user
2020-03-09 00:40:16 +08:00
end
def find_repository
@repo = @user.repositories.find_by_identifier params[:repo_identifier]
render_not_found("未找到’#{params[:repo_identifier]}’相关的项目") unless @repo
end
2020-05-29 15:33:17 +08:00
def find_repository_by_id
@repo = Repository.find params[:id]
end
2020-03-09 00:40:16 +08:00
def find_project
project_id = params[:project_id] ? params[:project_id] : params[:id]
project = Project.where(identifier: project_id)
if project.exists?
@project = project.first
else
@project = Project.find project_id
end
render_not_found("未找到’#{project}’相关的项目") unless @project
end
def find_project_with_id
@project = Project.find(params[:project_id] || params[:id])
rescue Exception => e
logger_error(e.message)
tip_exception(e.message)
end
def render_response(interactor)
interactor.success? ? render_ok : render_error(interactor.error)
end
2020-08-11 23:20:04 +08:00
# projects
def load_project
2020-08-12 10:35:19 +08:00
namespace = params[:owner]
id = params[:repo] || params[:id]
2020-08-11 23:20:04 +08:00
2020-10-30 15:47:09 +08:00
@project, @owner = Project.find_with_namespace(namespace, id)
2020-08-11 23:20:04 +08:00
if @project and (current_user.can_read_project?(@project) || controller_path == "projects/project_invite_links")
2020-08-11 23:20:04 +08:00
logger.info "########### has project and can read project"
2020-08-24 14:19:32 +08:00
@project
2021-09-07 15:17:52 +08:00
# elsif @project && current_user.is_a?(AnonymousUser)
# logger.info "###########This is AnonymousUser"
# @project = nil if !@project.is_public?
# render_forbidden and return
2020-08-11 23:20:04 +08:00
else
if @project.present?
logger.info "########### has project and but can't read project"
@project = nil
render_forbidden and return
else
logger.info "###########project not found"
@project = nil
render_not_found and return
end
2020-08-11 23:20:04 +08:00
end
2020-08-24 14:19:32 +08:00
@project
2020-08-11 23:20:04 +08:00
end
def load_repository
@repository ||= load_project&.repository
2020-08-11 23:20:04 +08:00
end
2021-04-23 14:40:26 +08:00
def base_url
Rails.application.config_for(:configuration)['platform_url'] || request.base_url
2021-04-23 14:40:26 +08:00
end
2021-06-01 10:07:01 +08:00
2022-01-04 22:44:39 +08:00
def image_type?(str)
default_type = %w(png jpg gif tif psd svg bmp webp jpeg ico psd)
default_type.include?(str&.downcase)
end
2021-06-01 10:07:01 +08:00
def convert_image!
2021-08-10 17:08:51 +08:00
@image = params[:image]
@image = @image.nil? && params[:user].present? ? params[:user][:image] : @image
2021-06-01 10:07:01 +08:00
return unless @image.present?
max_size = EduSetting.get('upload_avatar_max_size') || 2 * 1024 * 1024 # 2M
if @image.class == ActionDispatch::Http::UploadedFile
2022-01-04 22:44:39 +08:00
return render_error('请上传文件') if @image.size.zero?
return render_error('文件大小超过限制') if @image.size > max_size.to_i
return render_error('头像格式不正确!') unless image_type?(File.extname(@image.original_filename.to_s)[1..-1])
2021-06-01 10:07:01 +08:00
else
image = @image.to_s.strip
return render_error('请上传正确的图片') if image.blank?
@image = Util.convert_base64_image(image, max_size: max_size.to_i)
end
rescue Base64ImageConverter::Error => ex
render_error(ex.message)
end
2021-04-23 14:40:26 +08:00
2021-06-01 10:07:01 +08:00
def avatar_path(object)
ApplicationController.helpers.disk_filename(object.class, object.id)
end
2021-04-23 14:40:26 +08:00
2020-03-09 00:40:16 +08:00
private
def object_not_found
uid_logger("Missing template or cant't find record, responding with 404")
render json: {message: "您访问的页面不存在或已被删除", status: 404}
false
end
def tip_show(exception)
uid_logger("Tip show status is #{exception.status}, message is #{exception.message}")
render json: exception.tip_json
end
def set_export_cookies
cookies[:fileDownload] = true
end
# 记录热门搜索关键字
def record_search_keyword
keyword = params[:keyword].to_s.strip
return if keyword.blank? || keyword.size <= 1
return unless HotSearchKeyword.available?
HotSearchKeyword.add(keyword)
end
2023-03-02 13:49:50 +08:00
# author: zxh
# blockchain相关项目活动调用函数
# return true: 表示上链操作成功; return false: 表示上链操作失败
def push_activity_2_blockchain(activity_type, model)
if activity_type == "issue_create"
project_id = model['project_id']
project = Project.find(project_id)
if project['use_blockchain'] == 0 || project['use_blockchain'] == false
# 无需执行上链操作
return true
end
id = model['id']
owner_id = project['user_id']
owner = User.find(owner_id)
ownername = owner['login']
identifier = project['identifier']
author_id = project['user_id']
author = User.find(author_id)
username = author['login']
action = 'opened'
title = model['subject']
content = model['description']
created_at = model['created_on']
updated_at = model['updated_on']
# 调用区块链接口
params = {
"request-type": "upload issue info",
"issue_id": "gitlink-" + id.to_s,
"repo_id": "gitlink-" + project_id.to_s,
"issue_number": 0, # 暂时不需要改字段
"reponame": identifier,
"ownername": ownername,
"username": username,
"action": action,
"title": title,
"content": content,
"created_at": created_at,
"updated_at": updated_at
}.to_json
resp_body = Blockchain::InvokeBlockchainApi.call(params)
if resp_body['status'] == 10
raise ApplicationService::Error, resp_body['message']
2023-03-02 13:49:50 +08:00
elsif resp_body['status'] != 0
raise ApplicationService::Error, "区块链接口请求失败."
2023-03-02 13:49:50 +08:00
end
elsif activity_type == "issue_comment_create"
issue_comment_id = model['id']
issue_id = model['journalized_id']
parent_id = model['parent_id'].nil? ? "" : model['parent_id']
issue = Issue.find(issue_id)
issue_classify = issue['issue_classify'] # issue或pull_request
project_id = issue['project_id']
project = Project.find(project_id)
if project['use_blockchain'] == 0 || project['use_blockchain'] == false
# 无需执行上链操作
return
end
identifier = project['identifier']
owner_id = project['user_id']
owner = User.find(owner_id)
ownername = owner['login']
author_id = model['user_id']
author = User.find(author_id)
username = author['login']
action = 'created'
content = model['notes']
created_at = model['created_on']
if issue_classify == "issue"
params = {
"request-type": "upload issue comment info",
"issue_comment_id": "gitlink-" + issue_comment_id.to_s,
"issue_comment_number": 0, # 暂时不需要
"issue_number": 0, # 暂时不需要
"issue_id": "gitlink-" + issue_id.to_s,
"repo_id": "gitlink-" + project.id.to_s,
"parent_id": parent_id.to_s,
"reponame": identifier,
"ownername": ownername,
"username": username,
"action": action,
"content": content,
"created_at": created_at,
}.to_json
elsif issue_classify == "pull_request"
params = {
"request-type": "upload pull request comment info",
"pull_request_comment_id": "gitlink-" + issue_comment_id.to_s,
"pull_request_comment_number": 0, # 不考虑该字段
"pull_request_number": 0, # 不考虑该字段
"pull_request_id": "gitlink-" + issue_id.to_s,
"parent_id": parent_id.to_s,
"repo_id": "gitlink-" + project.id.to_s,
"reponame": identifier,
"ownername": ownername,
"username": username,
"action": action,
"content": content,
"created_at": created_at,
}.to_json
end
# 调用区块链接口
resp_body = Blockchain::InvokeBlockchainApi.call(params)
if resp_body['status'] == 10
raise ApplicationService::Error, resp_body['message']
2023-03-02 13:49:50 +08:00
elsif resp_body['status'] != 0
raise ApplicationService::Error, "区块链接口请求失败."
2023-03-02 13:49:50 +08:00
end
elsif activity_type == "pull_request_create"
# 调用区块链接口
project_id = model['project_id']
project = Project.find(project_id)
if project['use_blockchain'] == 0 || project['use_blockchain'] == false
# 无需执行上链操作
return
end
pull_request_id = model['id']
identifier = project['identifier']
owner_id = project['user_id']
owner = User.find(owner_id)
ownername = owner['login']
action = 'opened'
title = model['title']
content = model['body']
source_branch = model['head']
source_repo_id = model['fork_project_id'].nil? ? project_id : model['fork_project_id']
target_branch = model['base']
target_repo_id = project_id
author_id = model['user_id']
author = User.find(author_id)
username = author['login']
created_at = model['created_at']
updated_at = model['updated_at']
# 查询pull request对应的commit信息
commits = Gitea::PullRequest::CommitsService.call(ownername, identifier, model['gitea_number'], current_user&.gitea_token)
2023-03-02 13:49:50 +08:00
if commits.nil?
raise ApplicationService::Error, "区块链接口请求失败" # 获取pr中变更的commit信息失败
2023-03-02 13:49:50 +08:00
end
commit_shas = []
commits.each do |c|
commit_shas << c["Sha"]
end
params = {
"request-type": "upload pull request info",
"pull_request_id": "gitlink-" + pull_request_id.to_s,
"pull_request_number": 0, # trustie没有该字段
"repo_id": "gitlink-" + project_id.to_s,
"ownername": ownername,
"reponame": identifier,
"username": username,
"action": action,
"title": title,
"content": content,
"source_branch": source_branch,
"target_branch": target_branch,
"reviewers": [], # trustie没有该字段
"commit_shas": commit_shas,
"merge_user": "", # trustie没有该字段
"created_at": created_at,
"updated_at": updated_at
}.to_json
resp_body = Blockchain::InvokeBlockchainApi.call(params)
if resp_body['status'] == 9
raise ApplicationService::Error, resp_body['message']
2023-03-02 13:49:50 +08:00
elsif resp_body['status'] != 0
raise ApplicationService::Error, "区块链接口请求失败."
2023-03-02 13:49:50 +08:00
end
elsif activity_type == "pull_request_merge"
# 调用区块链接口
project_id = model['project_id']
project = Project.find(project_id)
if project['use_blockchain'] == 0 || project['use_blockchain'] == false
# 无需执行上链操作
return
end
pull_request_id = model['id']
identifier = project['identifier']
owner_id = project['user_id']
owner = User.find(owner_id)
ownername = owner['login']
action = 'merged'
created_at = model['created_at']
updated_at = model['updated_at']
# 查询pull request对应的commit信息
commits = Gitea::PullRequest::CommitsService.call(ownername, identifier, model['gitea_number'], current_user&.gitea_token)
2023-03-02 13:49:50 +08:00
if commits.nil?
raise ApplicationService::Error, "区块链接口请求失败" # 获取pr中变更的commit信息失败
2023-03-02 13:49:50 +08:00
end
commit_shas = []
commits.each do |c|
commit_shas << c["Sha"]
end
# 将pull request相关信息写入链上
params = {
"request-type": "upload pull request info",
"pull_request_id": "gitlink-" + pull_request_id.to_s,
"pull_request_number": 0, # trustie没有该字段
"repo_id": "gitlink-" + project_id.to_s,
"ownername": ownername,
"reponame": identifier,
"username": username,
"action": action,
"title": title,
"content": content,
"source_branch": source_branch,
"target_branch": target_branch,
"reviewers": [], # trustie没有该字段
"commit_shas": commit_shas,
"merge_user": "", # trustie没有该字段
"created_at": created_at,
"updated_at": updated_at
}.to_json
resp_body = Blockchain::InvokeBlockchainApi.call(params)
if resp_body['status'] == 9
raise ApplicationService::Error, resp_body['message']
2023-03-02 13:49:50 +08:00
elsif resp_body['status'] != 0
raise ApplicationService::Error, "区块链接口请求失败."
2023-03-02 13:49:50 +08:00
end
# 将commit相关信息写入链上
commit_shas.each do |commit_sha|
2023-03-09 16:18:56 +08:00
commit_diff = Gitea::Commit::DiffService.call(ownername, identifier, commit_sha, owner['gitea_token'])
commit = Gitea::Commit::InfoService.call(ownername, identifier, commit_sha, owner['gitea_token'])
2023-03-02 13:49:50 +08:00
params = {
"request-type": "upload commit info",
"commit_hash": commit_sha,
"repo_id": "gitlink-" + project_id.to_s,
"author": commit['commit']['author']['name'],
"author_email": commit['commit']['author']['email'],
"committer": commit['commit']['committer']['name'],
"committer_email": commit['commit']['committer']['email'],
"author_time": commit['commit']['author']['date'],
"committer_time": commit['commit']['committer']['date'],
"content": commit['commit']['message'],
2023-07-11 17:06:04 +08:00
"commit_diff": commit_diff.present? ? commit_diff['Files'].to_s : ""
2023-03-02 13:49:50 +08:00
}.to_json
resp_body = Blockchain::InvokeBlockchainApi.call(params)
if resp_body['status'] == 7
raise ApplicationService::Error, resp_body['message']
2023-03-02 13:49:50 +08:00
elsif resp_body['status'] != 0
raise ApplicationService::Error, "区块链接口请求失败."
2023-03-02 13:49:50 +08:00
end
end
elsif activity_type == "pull_request_refuse"
# 调用区块链接口
project_id = model['project_id']
project = Project.find(project_id)
if project['use_blockchain'] == 0 || project['use_blockchain'] == false
# 无需执行上链操作
return true
end
pull_request_id = model['id']
identifier = project['identifier']
owner_id = project['user_id']
owner = User.find(owner_id)
ownername = owner['login']
action = 'refused'
# 将pull request相关信息写入链上
params = {
"request-type": "upload pull request info",
"pull_request_id": "gitlink-" + pull_request_id.to_s,
"pull_request_number": 0, # trustie没有该字段
"repo_id": "gitlink-" + project_id.to_s,
"ownername": ownername,
"reponame": identifier,
"username": username,
"action": action,
"title": title,
"content": content,
"source_branch": source_branch,
"target_branch": target_branch,
"reviewers": [], # trustie没有该字段
"commit_shas": commit_shas,
"merge_user": "", # trustie没有该字段
"created_at": created_at,
"updated_at": updated_at
}.to_json
resp_body = Blockchain::InvokeBlockchainApi.call(params)
if resp_body['status'] == 9
raise ApplicationService::Error, resp_body['message']
2023-03-02 13:49:50 +08:00
elsif resp_body['status'] != 0
raise ApplicationService::Error, "区块链接口请求失败."
2023-03-02 13:49:50 +08:00
end
end
end
2021-10-20 09:39:21 +08:00
def find_atme_receivers
@atme_receivers = User.where(login: params[:receivers_login])
2023-06-08 11:25:03 +08:00
end
# 接口限流,请求量大有性能问题
def request_limit
2025-03-04 14:26:12 +08:00
white_list_ip = ["106.75.110.152"]
unless white_list_ip.include?(request.remote_ip)
record_count = Rails.cache.read("request/#{controller_name}/#{Time.now.strftime('%Y%m%d%H')}/#{request.remote_ip}")
if record_count.present?
record_count = record_count + 1
else
record_count = 1
end
Rails.logger.info("请求太快,请稍后再试。#{controller_name}::#{request.remote_ip}") if record_count > 200
tip_exception("请求太快,请稍后再试。") if record_count > 200
2023-06-08 14:00:06 +08:00
2025-03-04 14:26:12 +08:00
Rails.cache.write("request/#{controller_name}/#{Time.now.strftime('%Y%m%d%H')}/#{request.remote_ip}", record_count, expires_in: 1.hour)
end
2025-02-28 21:58:16 +08:00
end
def check_batch_requests
check_key = "request.remote_ip:#{request.remote_ip}"
result = Rails.cache.read(check_key)
if result.present?
if result.to_i > 100
tip_exception(401, '暂时无法请求,请稍后再试')
else
Rails.cache.write(check_key, result.to_i + 1)
end
else
Rails.cache.write(check_key, 1, expires_in: 1.hour)
end
2023-06-08 11:25:03 +08:00
end
2021-10-20 09:39:21 +08:00
2025-02-28 22:23:43 +08:00
def request_raw_limit
record_count = Rails.cache.read("request/#{request.path}/#{Time.now.strftime('%Y%m%d%H')}}")
2023-06-08 14:00:06 +08:00
if record_count.present?
record_count = record_count + 1
else
record_count = 1
2023-06-08 11:25:03 +08:00
end
2025-02-28 22:23:43 +08:00
Rails.logger.info("请求太快,请稍后再试。#{request.path}") if record_count > 1000
tip_exception("请求太快,请稍后再试。") if record_count > 1000
2023-06-08 14:00:06 +08:00
2025-02-28 22:23:43 +08:00
Rails.cache.write("request/#{request.path}/#{Time.now.strftime('%Y%m%d%H')}}", record_count, expires_in: 1.hour)
2023-06-08 11:25:03 +08:00
end
2021-10-20 09:39:21 +08:00
2020-03-09 00:40:16 +08:00
end