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
2020-04-28 15:43:09 +08:00
# 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
2020-04-28 15:43:09 +08:00
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 )
2021-11-03 13:50:38 +08:00
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
2023-08-22 13:59:02 +08:00
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
2021-10-27 17:01:16 +08:00
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 , " 该手机号码或邮箱已被注册 " )
2021-10-27 17:01:16 +08:00
elsif type . to_i == 2 && ! user_exist
2020-03-09 00:40:16 +08:00
tip_exception ( - 2 , " 该手机号码或邮箱未注册 " )
2021-10-27 17:01:16 +08:00
elsif type . to_i == 3 && user_exist
2020-03-09 00:40:16 +08:00
tip_exception ( - 2 , " 该手机号码或邮箱已绑定 " )
end
2021-10-27 17:01:16 +08:00
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内不能重复发送
2023-04-19 10:15:07 +08:00
# 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
2023-04-19 10:15:07 +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
2023-04-19 10:15:07 +08:00
# 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
2021-09-02 11:48:53 +08:00
def require_user_profile_completed ( user )
2023-05-12 15:20:14 +08:00
# tip_exception(412, "请用户完善资料后再操作") unless user.profile_is_completed?
2021-09-02 11:48:53 +08:00
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
2022-07-11 17:11:13 +08:00
User . current = find_current_user
uid_logger ( " user_setup: " + ( User . current . logged? ? " #{ User . current . try ( :login ) } (id= #{ User . current . try ( :id ) } ) " : " anonymous " ) )
2024-04-30 15:35:35 +08:00
# # 开放课程通过链接访问的用户
# 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
2022-07-11 17:11:13 +08:00
# 测试版前端需求
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
2022-07-11 17:11:13 +08:00
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 } " ]
2024-04-30 15:35:35 +08:00
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 )
2024-09-24 11:48:05 +08:00
set_autologin_cookie ( autologin_user ) if autologin_user . present?
2020-03-09 00:40:16 +08:00
end
2024-04-30 15:35:35 +08:00
autologin_user
2020-03-09 00:40:16 +08:00
end
def try_to_autologin
2025-11-25 13:46:38 +08:00
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 ( / * / , '' )
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
2023-03-24 14:37:42 +08:00
def kaminari_unlimit_paginate ( relation )
2023-03-24 14:34:42 +08:00
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
2022-06-20 16:37:59 +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
2022-10-14 14:52:25 +08:00
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
2020-11-03 18:37:47 +08:00
@repository || = load_project & . repository
2020-08-11 23:20:04 +08:00
end
2021-04-23 14:40:26 +08:00
def base_url
2021-06-22 15:05:10 +08:00
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
2023-03-09 15:37:38 +08:00
raise ApplicationService :: Error , resp_body [ 'message' ]
2023-03-02 13:49:50 +08:00
elsif resp_body [ 'status' ] != 0
2023-03-09 15:37:38 +08:00
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
2023-03-09 15:37:38 +08:00
raise ApplicationService :: Error , resp_body [ 'message' ]
2023-03-02 13:49:50 +08:00
elsif resp_body [ 'status' ] != 0
2023-03-09 15:37:38 +08:00
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信息
2023-03-09 15:37:38 +08:00
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?
2023-03-09 15:37:38 +08:00
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
2023-03-09 15:37:38 +08:00
raise ApplicationService :: Error , resp_body [ 'message' ]
2023-03-02 13:49:50 +08:00
elsif resp_body [ 'status' ] != 0
2023-03-09 15:37:38 +08:00
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信息
2023-03-09 15:37:38 +08:00
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?
2023-03-09 15:37:38 +08:00
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
2023-03-09 15:37:38 +08:00
raise ApplicationService :: Error , resp_body [ 'message' ]
2023-03-02 13:49:50 +08:00
elsif resp_body [ 'status' ] != 0
2023-03-09 15:37:38 +08:00
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
2023-03-09 15:37:38 +08:00
raise ApplicationService :: Error , resp_body [ 'message' ]
2023-03-02 13:49:50 +08:00
elsif resp_body [ 'status' ] != 0
2023-03-09 15:37:38 +08:00
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
2023-03-09 15:37:38 +08:00
raise ApplicationService :: Error , resp_body [ 'message' ]
2023-03-02 13:49:50 +08:00
elsif resp_body [ 'status' ] != 0
2023-03-09 15:37:38 +08:00
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