You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
pgfqe6ch8/app/controllers/application_controller.rb

1180 lines
37 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# encoding: utf-8
# Redmine - project management software
# Copyright (C) 2006-2013 Jean-Philippe Lang
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
require 'uri'
require 'cgi'
class Unauthorized < Exception; end
class ApplicationController < ActionController::Base
include Redmine::I18n
include Redmine::Pagination
include RoutesHelper
helper :routes
#added by william
helper :watchers
class_attribute :accept_api_auth_actions
class_attribute :accept_rss_auth_actions
class_attribute :model_object
#before_filter :update_system
# skip_before_filter :verify_authenticity_token,
# :if => Proc.new { |c| c.request.format == 'application/json' }
layout 'base'
# 这行代码的作用:所有表单和 Ajax 请求中都会包含安全权标
# 非 GET 请求中没有 CSRF 权标就会调用这个方法
protect_from_forgery
def handle_unverified_request
super
if session[:user_id].blank?
redirect_to signin_url(:back_url => request.original_url)
else
raise(ActionController::InvalidAuthenticityToken)
end
# cookies.delete(autologin_cookie_name)
end
before_filter :session_expiration, :user_setup, :check_if_login_required, :set_localization
before_filter :user_agent
# rescue_from ActionController::InvalidAuthenticityToken, :with => :invalid_authenticity_token
rescue_from ::Unauthorized, :with => :deny_access
rescue_from ::ActionView::MissingTemplate, :with => :missing_template
include Redmine::Search::Controller
include Redmine::MenuManager::MenuController
helper Redmine::MenuManager::MenuHelper
# 云启训练场EduCoder个人版 产品编码appId 9200108
# 产品名称 计费类型 套餐编码
# 云启训练场EduCoder个人版 固定包月 9200108001
# 固定包月 9200108002
# 固定包月 9200108003
# ---------------------------------------------------
# 产品名称 计费类型 套餐编码
# 云启训练场EduCoder院校版 包月+按license 9200109001
# 包月+按license 9200109002
# 云启训练场EduCoder院校版 产品编码appId 9200109
# 如果不是Ecloud过来的用户则不改变用户的使用状态及权限按现有模式即可
def ecloud_auth
euser = EcloudUser.where("userid =? and opttype not in(3, 5)", User.current.id).first
if euser.present? # 开通过业务
# 获取用户的套餐信息
e_services = euser.ecloud_services.where("opttype != 1").order("ecloud_services.code desc")
# 如果用户开通过服务
if e_services.present?
if e_services.count > 1 # 说明有重复开通过业务
# 开通多业务的话以最大的套餐排序如果最大套餐还可以用则直接返回true如果最大套餐不能用则轮询返回直到找到可用的套餐
e_services.each do |e_service|
# 使用期限内套餐才有效
ecloud_services_auth(e_service.code, e_service.begintime, e_service.endtime)
end
else
# 先看套餐,再看时间区间
e_service = e_services.first
ecloud_services_auth(e_service.code, e_service.begintime, e_service.endtime)
end
else
false # 没开通过服务,或者服务被禁用则不允许访问
end
end
end
# 根据业务确定权限
def ecloud_services_auth code, begintime, endtime
# 如果当前实训不在实训课堂等级体系中,则不允许访问
subject_id = @shixun.stage_shixuns.map(&:subject_id)
if subject_id.blank?
render_403
end
subject_level = Subject.find(subject_id).subject_level_system.try(:level)
# 当前时间转毫秒
current_time = DateTime.now.strftime('%Q').to_i
if current_time - begintime > 0 && endtime - current_time > 0
case code
when "9200108001"
subject_level.to_i == 1 ? true : false
when "9200108002"
subject_level.to_i == 2 ? true : false
when "9200108003"
subject_level.to_i == 3 ? true : false
when "9200109001" # 企业用户
subject_level.to_i < 3 ? true : false
when "9200109002" # 企业用户
subject_level.to_i <= 3 ? true : false
end
else
false
end
end
def ec_public_auth major_school
unless User.current.admin? || major_school.template_major || major_school.school.users.where(:id => User.current.id).count > 0 ||
major_school.ec_major_school_users.where(:user_id => User.current.id).count > 0 ||
EcCourseUser.where(:user_id => User.current.id, :ec_course_id => EcCourse.where(:ec_year_id => major_school.ec_years.pluck(:id)).pluck(:id)).count > 0
render_403
else
true
end
end
def user_agent
logger.info "HTTP_USER_AGENT #{request.env["HTTP_USER_AGENT"]}"
end
def session_expiration
if session[:user_id]
if session_expired? && !try_to_autologin
reset_session
flash[:error] = l(:error_session_expired)
redirect_to signin_url
else
session[:atime] = Time.now.utc.to_i
end
end
end
def session_expired?
if Setting.session_lifetime?
unless session[:ctime] && (Time.now.utc.to_i - session[:ctime].to_i <= Setting.session_lifetime.to_i * 60)
return true
end
end
if Setting.session_timeout?
unless session[:atime] && (Time.now.utc.to_i - session[:atime].to_i <= Setting.session_timeout.to_i * 60)
return true
end
end
false
end
def start_user_session(user)
session[:user_id] = user.id
session[:ctime] = Time.now.utc.to_i
session[:atime] = Time.now.utc.to_i
end
def user_setup
# Check the settings cache for each request
Setting.check_cache
# Find the current user
User.current = find_current_user
#logger.info(" Current user: " + (User.current.logged? ? "#{User.current.login} (id=#{User.current.id})" : "anonymous")) if logger
end
# Returns the current user or nil if no user is logged in
# and starts a session if needed
def current_user
find_current_user
end
def set_autologin_cookie(user)
token = Token.get_or_create_permanent_login_token(user)
cookie_options = {
:value => token.value,
:expires => 1.month.from_now,
:path => (Redmine::Configuration['autologin_cookie_path'] || '/'),
:secure => (Redmine::Configuration['autologin_cookie_secure'] ? true : false),
:httponly => true
}
if Redmine::Configuration['cookie_domain'].present?
cookie_options = cookie_options.merge(domain: Redmine::Configuration['cookie_domain'])
end
cookies[autologin_cookie_name] = cookie_options
end
def find_current_user
user = nil
unless api_request?
if session[:user_id]
# existing session
user = (User.active.find(session[:user_id]) rescue nil)
elsif autologin_user = try_to_autologin
user = autologin_user
elsif params[:format] == 'atom' && params[:key] && request.get? && accept_rss_auth?
# RSS key authentication does not start a session
user = User.find_by_rss_key(params[:key])
elsif session[:wechat_openid]
uw = UserWechat.find_by_openid(session[:wechat_openid])
user = uw.user if uw
elsif params[:authToken]
user = Token.find_by_value(params[:authToken]).user
set_autologin_cookie(user)
session[:user_id] = user.id
end
end
if user.nil? && Setting.rest_api_enabled? && accept_api_auth?
if (key = api_key_from_request)
# Use API key
user = User.find_by_api_key(key)
else
# HTTP Basic, either username/password or API key/random
authenticate_with_http_basic do |username, password|
user = User.try_to_login(username, password)[0] || User.find_by_api_key(username)
end
end
# Switch user if requested by an admin user
if user && user.admin? && (username = api_switch_user_from_request)
su = User.find_by_login(username)
if su && su.active?
logger.info(" User switched by: #{user.login} (id=#{user.id})") if logger
user = su
else
render_error :message => 'Invalid X-Redmine-Switch-User header', :status => 412
end
end
end
user
end
def autologin_cookie_name
Redmine::Configuration['autologin_cookie_name'].presence || 'autologin'
end
def try_to_autologin
if cookies[autologin_cookie_name] && Setting.autologin?
# auto-login feature starts a new session
user = User.try_to_autologin(cookies[autologin_cookie_name])
if user
reset_session
start_user_session(user)
end
user
end
end
def try_to_autologin1
user = User.try_to_autologin(params[:token])
if user
logout_user if User.current.id != user.id
start_user_session(user)
end
user
Rails.logger.info("##auth_login1 end")
end
# Sets the logged in user
def logged_user=(user)
reset_session
if user && user.is_a?(User)
User.current = user
start_user_session(user)
else
User.current = User.anonymous
end
end
def logged_user_by_apptoken
#从手机端传来apptoken则将当前登陆用户变为对应的用户
if params[:apptoken]
token = ApiKey.where(access_token: params[:apptoken]).first
if token.expired?
return
end
if token && !token.expired?
@current_user = User.find(token.user_id)
end
unless @current_user.nil?
self.logged_user = @current_user
if @current_user
@current_user.update_column(:last_login_on, Time.now)
end
end
end
end
# Logs out current user
def logout_user
if User.current.logged?
if Redmine::Configuration['cookie_domain'].present?
logger.info("##########################{Redmine::Configuration['cookie_domain']}")
cookies.delete(autologin_cookie_name, domain: Redmine::Configuration['cookie_domain'])
else
cookies.delete autologin_cookie_name
end
# Token.delete_all(["user_id = ? AND action = ?", User.current.id, 'autologin'])
self.logged_user = nil
end
end
# check if login is globally required to access the application
def check_if_login_required
# no check needed if user is already logged in
if User.current.logged?
if User.current.last_login_on && User.current.last_login_on.strftime('%Y-%m-%d') < Time.now.strftime('%Y-%m-%d')
User.current.update_column(:last_login_on, Time.now)
end
return true
end
require_login if Setting.login_required?
end
def set_localization
lang = nil
if User.current.logged?
lang = find_language(User.current.language)
end
if lang.nil? && request.env['HTTP_ACCEPT_LANGUAGE']
accept_lang = parse_qvalues(request.env['HTTP_ACCEPT_LANGUAGE']).first
if !accept_lang.blank?
accept_lang = accept_lang.downcase
lang = find_language(accept_lang) || find_language(accept_lang.split('-').first)
end
end
lang ||= Setting.default_language
set_language_if_valid(lang)
end
def require_login
if !User.current.logged?
# Extract only the basic url parameters on non-GET requests
if request.get?
url = request.original_url
else
url = url_for(:controller => params[:controller], :action => params[:action], :id => params[:id], :project_id => params[:project_id])
end
respond_to do |format|
format.html { redirect_to signin_url(:back_url => url) }
format.atom { redirect_to signin_url }
format.xml { head :unauthorized, 'WWW-Authenticate' => 'Basic realm="Redmine API"' }
format.js { redirect_to signin_url(:back_url => url) }
format.json { redirect_to signin_url(:back_url => url) }
end
return false
end
true
end
def require_admin
return unless require_login
if !User.current.admin?
render_403
return false
end
true
end
# 运营人员
def require_business
unless (User.current.business? || User.current.admin?)
render_403
end
end
def deny_access
User.current.logged? ? render_403 : require_login
end
# Authorize the user for the requested action
def authorize(ctrl = params[:controller], action = params[:action], global = false)
#modify by NWB
allowed = authorize_allowed(params[:controller], params[:action],global)
if allowed
true
else
if @project && @project.archived?
render_403 :message => :notice_not_authorized_archived_project
else
deny_access
end
end
end
def authorize1(ctrl = params[:controller], action = params[:action],token = params[:token], global = false)
if(!User.current.logged? && !token.nil?)
User.current =try_to_autologin1
end
allowed = authorize_allowed(params[:controller], params[:action],global)
if allowed
true
else
if @project && @project.archived?
render_403 :message => :notice_not_authorized_archived_project
else
deny_access
end
end
end
def auth_login1(token = params[:token])
Rails.logger.info("##auth_login1 start")
if(!User.current.logged? && !token.nil?)
User.current =try_to_autologin1
end
end
def authorize_allowed(ctrl = params[:controller], action = params[:action], global = false)
#modify by NWB
if @project
if ctrl == "repositories" && action == "show" && @project.hidden_repo
allowed = User.current.admin? || (User.current.member_of?(@project) && !(role_of_members_in_project(@project.id, User.current.id) == "Reporter"))
else
allowed = User.current.allowed_to?({:controller => ctrl, :action => action}, @project || @projects, :global => global)
end
elsif @course
allowed = User.current.allowed_to?({:controller => ctrl, :action => action}, @course || @courses, :global => global)
else
# allowed = User.current.allowed_to?({:controller => ctrl, :action => action}, @project || @projects, :global => global)
allowed = true
end
allowed
end
def authorize_attachment_download(ctrl = params[:controller], action = params[:action], global = false)
case @attachment.container_type
when "Memo"
allowed = User.current.allowed_to?(:memos_attachments_download,nil,:global => true)
when "Message"
if @project
allowed = User.current.allowed_to?(:projects_attachments_download,@project,:global => false)
elsif @course
allowed = User.current.allowed_to?(:course_attachments_download, @course, :global => false)
end
when "contest"
return true
when "Course"
allowed = User.current.allowed_to?(:course_attachments_download, @course, :global => false)
else
return true
end
if allowed
true
else
if @project && @project.archived?
render_403 :message => :notice_not_authorized_archived_project
else
deny_access
end
end
end
def authorize_attachment_download1(ctrl = params[:controller], action = params[:action],token = params[:token], global = false)
if(!User.current.logged? && !token.nil?)
User.current = try_to_autologin1
end
case @attachment.container_type
when "Memo"
allowed = User.current.allowed_to?(:memos_attachments_download,nil,:global => true)
when "Message"
if @project
allowed = User.current.allowed_to?(:projects_attachments_download,@project,:global => false)
elsif @course
allowed = User.current.allowed_to?(:course_attachments_download, @course, :global => false)
elsif @contest
allowed = User.current.member_of_contest?(@contest)
end
when "contest"
return true
when "Course"
if @attachment.get_status_by_attach(User.current.id) == 2
return true
else
allowed = User.current.allowed_to?(:course_attachments_download, @course, :global => false)
end
else
return true
end
if allowed || (params[:type] && params[:type] == "wechat" )
true
else
if @project && @project.archived?
render_403 :message => :notice_not_authorized_archived_project
else
deny_access
end
end
end
def authorize_course(ctrl = params[:controller], action = params[:action], global = false)
allowed = User.current.allowed_to?({:controller => ctrl, :action => action}, @course || @course, :global => global)
if allowed
true
else
if params[:action] == 'show'
#更新申请结果反馈消息的状态
messages = CourseMessage.where("course_message_type =? and course_id =? and user_id =? and viewed =?", 'CourseRequestDealResult', @course.id, User.current.id, false)
messages.update_all(:viewed => true)
end
if @course && @course.archived?
render_403 :message => :notice_not_authorized_archived_project
else
deny_access
end
end
end
def authorize_course_global(ctrl = params[:controller], action = params[:action], global = true)
authorize_course(ctrl, action, global)
end
# Authorize the user for the requested action outside a project
def authorize_global(ctrl = params[:controller], action = params[:action], global = true)
authorize(ctrl, action, global)
end
# Find project of id params[:id]
def find_project
@project = Project.find(params[:id])
rescue ActiveRecord::RecordNotFound
render_404
end
# Find project of id params[:project_id]
def find_project_by_project_id
if params[:project_id]
@project = Project.find(params[:project_id])
elsif params[:shixun_id]
@shixun = Shixun.find_by_identifier(params[:shixun_id])
elsif params[:course_id]
@course = Course.find(params[:course_id])
elsif params[:org_subfield_id]
@org_subfield = OrgSubfield.find(params[:org_subfield_id])
elsif params[:contest_id]
@contest = Contest.find(params[:contest_id])
end
rescue ActiveRecord::RecordNotFound
render_404
end
def find_contest_by_contest_id
@contest = Contest.find(params[:contest_id])
rescue ActiveRecord::RecordNotFound
render_404
end
#<23><><EFBFBD>course_id<69><64>project
def find_project_by_course_id
@bid = Bid.find params[:course_id]
@project = @bid.courses[0]
rescue ActiveRecord::RecordNotFound
render_404
end
# Find a project based on params[:project_id]
# TODO: some subclasses override this, see about merging their logic
def find_optional_project
@project = Project.find(params[:project_id]) unless params[:project_id].blank?
allowed = User.current.allowed_to?({:controller => params[:controller], :action => params[:action]}, @project, :global => true)
allowed ? true : deny_access
rescue ActiveRecord::RecordNotFound
render_404
end
def find_optional_contest
@contest = Contest.find(params[:contest_id]) unless params[:contest_id].blank?
allowed = User.current.allowed_to?({:controller => params[:controller], :action => params[:action]}, @contest, :global => true)
allowed ? true : deny_access
rescue ActiveRecord::RecordNotFound
render_404
end
# Finds and sets @project based on @object.project
def find_project_from_association
render_404 unless @object.present?
@project = @object.project
if @project == nil && @object.has_attribute?('course_id')
@course = @object.course
if @course.nil? && @object.has_attribute?('contest_id')
@contest = @object.contest
end
end
end
def find_contest_from_association
render_404 unless @object.present?
@contest =@object.contest
end
def find_model_object
model = self.class.model_object
if model
@object = model.find(params[:id])
self.instance_variable_set('@' + controller_name.singularize, @object) if @object
end
rescue ActiveRecord::RecordNotFound
render_404
end
#added by nwb
#<23><>ȡ<EFBFBD>γ<EFBFBD>
def find_course
@course= Course.find(params[:id])
rescue ActiveRecord::RecordNotFound
render_404
end
# def find_model_object_contest
# model = self.class.model_object
# if model
# @object = model.find(params[:id])
# self.instance_variable_set('@' + controller_name.singularize, @object) if @object
# end
# rescue ActiveRecord::RecordNotFound
# render_404
# end
def self.model_object(model)
self.model_object = model
end
# Find the issue whose id is the :id parameter
# Raises a Unauthorized exception if the issue is not visible
def find_issue
# Issue.visible.find(...) can not be used to redirect user to the login form
# if the issue actually exists but requires authentication
@issue = Issue.find(params[:id])
raise Unauthorized unless @issue.visible?
@project = @issue.project
rescue ActiveRecord::RecordNotFound
render_404
end
# Find issues with a single :id param or :ids array param
# Raises a Unauthorized exception if one of the issues is not visible
def find_issues
@issues = Issue.find_all_by_id(params[:id] || params[:ids])
raise ActiveRecord::RecordNotFound if @issues.empty?
raise Unauthorized unless @issues.all?(&:visible?)
@projects = @issues.collect(&:project).compact.uniq
@project = @projects.first if @projects.size == 1
rescue ActiveRecord::RecordNotFound
render_404
end
def find_attachments
if (attachments = params[:attachments]).present?
att = attachments.values.collect do |attachment|
Attachment.find_by_token( attachment[:token] ) if attachment[:token].present?
end
att.compact!
end
@attachments = att || []
end
# make sure that the user is a member of the project (or admin) if project is private
# used as a before_filter for actions that do not require any particular permission on the project
def check_project_privacy
if @project && !@project.archived?
if @project.visible?
true
else
deny_access
end
else
@project = nil
render_404
false
end
end
def back_url
url = params[:back_url]
if url.nil? && referer = request.env['HTTP_REFERER']
url = CGI.unescape(referer.to_s)
end
url
end
def redirect_back_or_default(default, options={})
back_url = params[:back_url].to_s
if back_url.present?
begin
uri = URI.parse(back_url)
logger.warn("-----back URL #{uri}")
# do not redirect user to another host or to the login or register page
if (uri.relative? || (uri.host == request.host)) && !uri.path.match(%r{/(login|account/register)})
# back_url = back_url.gsub(%r{\/users\/(\w+)},"/users/"+default.to_s) if default.is_a?(:User)
redirect_to(back_url)
return
end
rescue URI::InvalidURIError
logger.warn("Could not redirect to invalid URL #{back_url}")
#redirect to default
end
end
redirect_to default
false
end
# Redirects to the request referer if present, redirects to args or call block otherwise.
def redirect_to_referer_or(*args, &block)
redirect_to :back
rescue ::ActionController::RedirectBackError
if args.any?
redirect_to *args
elsif block_given?
block.call
else
raise "#redirect_to_referer_or takes arguments or a block"
end
end
def render_403(options={})
if User.current.id == 2
redirect_to signin_url
return
end
@project = nil
render_error({:message => :notice_not_authorized, :status => 403}.merge(options),'common/403')
#render :template => 'common/403'
return false
end
def render_404(options={})
if User.current.id == 2
redirect_to signin_url
return
end
render_error({:message => :notice_file_not_found, :status => 404}.merge(options),'common/404')
#render :template => 'common/404'
return false
end
# Renders an error response
def render_error(arg,template = 'common/error')
arg = {:message => arg} unless arg.is_a?(Hash)
@message = arg[:message]
@lay = arg[:layout]
@message = l(@message) if @message.is_a?(Symbol)
@status = arg[:status] || 500
respond_to do |format|
format.html {
if @lay
render :template => template, :layout => @lay,:status => @status
else
render :template => template, :layout => use_layout, :status => @status
end
}
format.any { head @status }
end
end
# Handler for ActionView::MissingTemplate exception
def missing_template
logger.warn "Missing template, responding with 404"
@project = nil
render_404
end
# Filter for actions that provide an API response
# but have no HTML representation for non admin users
def require_admin_or_api_request
return true if api_request?
if User.current.admin?
true
elsif User.current.logged?
render_error(:status => 406)
else
deny_access
end
end
# Picks which layout to use based on the request
#
# @return [boolean, string] name of the layout to use or false for no layout
def use_layout
request.xhr? ? false : 'users_base'
end
def invalid_authenticity_token
if api_request?
logger.error "Form authenticity token is missing or is invalid. API calls must include a proper Content-type header (text/xml or text/json)."
end
Rails.logger.info("##invalid_authenticity_token")
#render_error "Invalid form authenticity token."
redirect_to signin_path(:login=>true)
end
def render_feed(items, options={})
@items = items || []
@items.sort! {|x,y| y.event_datetime <=> x.event_datetime }
@items = @items.slice(0, Setting.feeds_limit.to_i)
@title = options[:title] || Setting.app_title
render :template => "common/feed", :formats => [:atom], :layout => false,
:content_type => 'application/atom+xml'
end
def issue_ratio_change done_ratio, status_id
if done_ratio == 100 || status_id == 3
"已完成"
else
done_ratio.to_s + "%"
end
end
def issue_priority_change priority_id
case priority_id
when 1
""
when 2
"正常"
when 3
""
when 4
"紧急"
when 5
"立即"
end
end
def issue_status_change status_id
case status_id
when 1
"新增"
when 2
"正在解决"
when 3
"已解决"
when 4
"反馈"
when 5
"关闭"
when 6
"拒绝"
end
end
def issue_tracker_change tracker_id
case tracker_id
when 1
"缺陷"
when 2
"功能"
when 3
"支持"
when 4
"任务"
when 5
"周报"
end
end
def self.accept_rss_auth(*actions)
if actions.any?
self.accept_rss_auth_actions = actions
else
self.accept_rss_auth_actions || []
end
end
def accept_rss_auth?(action=action_name)
self.class.accept_rss_auth.include?(action.to_sym)
end
def self.accept_api_auth(*actions)
if actions.any?
self.accept_api_auth_actions = actions
else
self.accept_api_auth_actions || []
end
end
def accept_api_auth?(action=action_name)
self.class.accept_api_auth.include?(action.to_sym)
end
# Returns the number of objects that should be displayed
# on the paginated list
def per_page_option
per_page = nil
if params[:per_page] && Setting.per_page_options_array.include?(params[:per_page].to_s.to_i)
per_page = params[:per_page].to_s.to_i
session[:per_page] = per_page
elsif session[:per_page]
per_page = session[:per_page]
else
per_page = Setting.per_page_options_array.first || 25
end
per_page
end
# Returns offset and limit used to retrieve objects
# for an API response based on offset, limit and page parameters
def api_offset_and_limit(options=params)
if options[:offset].present?
offset = options[:offset].to_i
if offset < 0
offset = 0
end
end
limit = options[:limit].to_i
if limit < 1
limit = 25
elsif limit > 100
limit = 100
end
if offset.nil? && options[:page].present?
offset = (options[:page].to_i - 1) * limit
offset = 0 if offset < 0
offset ||= 0
end
[offset, limit]
end
# qvalues http header parser
# code taken from webrick
def parse_qvalues(value)
tmp = []
if value
parts = value.split(/,\s*/)
parts.each {|part|
if m = %r{^([^\s,]+?)(?:;\s*q=(\d+(?:\.\d+)?))?$}.match(part)
val = m[1]
q = (m[2] or 1).to_f
tmp.push([val, q])
end
}
tmp = tmp.sort_by{|val, q| -q}
tmp.collect!{|val, q| val}
end
return tmp
rescue
nil
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 api_request?
return false if params[:controller] == 'at'
%w(xml json).include? params[:format]
end
# Returns the API key present in the request
def api_key_from_request
if params[:key].present?
params[:key].to_s
elsif request.headers["X-Redmine-API-Key"].present?
request.headers["X-Redmine-API-Key"].to_s
end
end
# Returns the API 'switch user' value if present
def api_switch_user_from_request
request.headers["X-Redmine-Switch-User"].to_s.presence
end
# Renders a warning flash if obj has unsaved attachments
def render_attachment_warning_if_needed(obj)
flash[:warning] = l(:warning_attachments_not_saved, obj.unsaved_attachments.size) if obj.unsaved_attachments.present?
end
# Sets the `flash` notice or error based the number of issues that did not save
#
# @param [Array, Issue] issues all of the saved and unsaved Issues
# @param [Array, Integer] unsaved_issue_ids the issue ids that were not saved
def set_flash_from_bulk_issue_save(issues, unsaved_issue_ids)
if unsaved_issue_ids.empty?
flash[:notice] = l(:notice_successful_update) unless issues.empty?
else
flash[:error] = l(:notice_failed_to_save_issues,
:count => unsaved_issue_ids.size,
:total => issues.size,
:ids => '#' + unsaved_issue_ids.join(', #'))
end
end
# Rescues an invalid query statement. Just in case...
def query_statement_invalid(exception)
logger.error "Query::StatementInvalid: #{exception.message}" if logger
session.delete(:query)
sort_clear if respond_to?(:sort_clear)
render_error "An error occurred while executing the query and has been logged. Please report this error to your Redmine administrator."
end
# Renders a 200 response for successfull updates or deletions via the API
def render_api_ok
render_api_head :ok
end
# Renders a head API response
def render_api_head(status)
# #head would return a response body with one space
render :text => '', :status => status, :layout => nil
end
# Renders API response on validation failure
def render_validation_errors(objects)
if objects.is_a?(Array)
@error_messages = objects.map {|object| object.errors.full_messages}.flatten
else
@error_messages = objects.errors.full_messages
end
render :template => 'common/error_messages.api', :status => :unprocessable_entity, :layout => nil
end
# Overrides #_include_layout? so that #render with no arguments
# doesn't use the layout for api requests
def _include_layout?(*args)
api_request? ? false : super
end
## Please added code in html.
# <div class="pagination"><%= pagination_links_full @obj_pages, @obj_count, :per_page_links => false %></div>
def paginateHelper obj, pre_size=20
@obj_count = obj.count
@obj_pages = Paginator.new @obj_count, pre_size, params['page']
if obj.kind_of? ActiveRecord::Base or obj.kind_of? ActiveRecord::Relation
obj.limit(@obj_pages.per_page).offset(@obj_pages.offset)
elsif obj.kind_of? Array
obj[@obj_pages.offset, @obj_pages.per_page]
else
logger.error "[ApplicationController] Error : application_controller#paginateHelper ===> unknow category: #{obj.class}"
raise RuntimeError, 'unknow type, Please input you type into this helper.'
end
end
def paginateHelper_for_members obj, pre_size=10
@obj_count = StudentsForCourse.find_by_sql("select count(id) as mem_count from students_for_courses where course_id = #{@course.id}")[0][:mem_count].to_s.to_i
@obj_pages = Paginator.new @obj_count, pre_size, params['page']
if obj.kind_of? ActiveRecord::Base or obj.kind_of? ActiveRecord::Relation
obj.limit(@obj_pages.per_page).offset(0)
elsif obj.kind_of? Array
obj[0, @obj_pages.per_page]
else
logger.error "[ApplicationController] Error : application_controller#paginateHelper ===> unknow category: #{obj.class}"
raise RuntimeError, 'unknow type, Please input you type into this helper.'
end
end
# gitlab分页定制
def paginateHelperForGitlab obj, pre_size=15
@obj_count = obj.count
@obj_pages = Paginator.new @obj_count, pre_size, params['page']
if obj.kind_of? ActiveRecord::Base or obj.kind_of? ActiveRecord::Relation
obj.limit(@obj_pages.per_page).offset(@obj_pages.offset)
elsif obj.kind_of? Array
obj[0, @obj_pages.per_page]
else
logger.error "[ApplicationController] Error : application_controller#paginateHelper ===> unknow category: #{obj.class}"
raise RuntimeError, 'unknow type, Please input you type into this helper.'
end
end
#查找首页相关信息
def find_first_page
@first_page = FirstPage.find_by_page_type('project')
if @first_page.nil?
@first_page = FirstPage.new
@first_page.page_type = 'project'
@first_page.description = ""
@first_page.save()
end
@show_course = @first_page.show_course
@show_contest = @first_page.show_contest
end
# def find_web_footer
# @organizer = WebFooterOranizer.first
# @companies = WebFooterCompany.all
# end
def password_authentication
user, last_login_on = User.try_to_login(params[:user_name], params[:password])
successful_authentication(user, last_login_on)
end
def successful_authentication(user, last_login_on)
logger.info "Successful authentication for '#{user.login}' from #{request.remote_ip} at #{Time.now.utc}"
# Valid user
self.logged_user = user
# generate a key and set cookie if autologin
if params[:autologin] && Setting.autologin?
set_autologin_cookie(user)
end
call_hook(:controller_account_success_authentication_after, {:user => user })
end
def user_unlogged_check
if !User.current.logged?
redirect_to signin_url
return false
end
true
end
def update_system
redirect_to "https://www.educoder.net/update.html" if Time.now > Time.new(2019, 4, 23) &&
Time.now < Time.new(2019, 4, 23, 2)
end
# 获取Oauth Client
def get_client(site)
client_id = Redmine::Configuration['client_id']
client_secret = Redmine::Configuration['client_secret']
OAuth2::Client.new(client_id, client_secret, site: site)
end
def handle_openi_request
site = Redmine::Configuration['openi_domain']
root_url = Redmine::Configuration['educoder_domain']
get_code_url = "/oauth/get_code"
original_url = request.original_url
client = get_client(site)
redirect_uri = "#{root_url}#{get_code_url}"
authorize_url = client.auth_code.authorize_url(redirect_uri: redirect_uri)
authorize_url = authorize_url + "&gen_code=true&state=1&original_url=#{original_url}"
redirect_to authorize_url
end
def user_login_and_from_openi?
url = request.referer.nil? ? Redmine::Configuration['educoder_domain'] : request.referer
flag = URI(url).host == URI(Redmine::Configuration['openi_domain']).host && !current_user.logged?
logger.info "----------------------- request referer: #{request.referer} -------------------------"
logger.info "----------------------- url after processed: #{url} -------------------------"
logger.info "----------------------- host: #{URI(url).host} --------------------------"
logger.info "----------------------- handle_flag: #{flag} -------------------------"
flag
end
end