# 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. class AttachmentsController < ApplicationController before_filter :find_project, :only => [:show, :download, :thumbnail, :destroy, :delete_homework]#, :except => [:upload, :autocomplete] before_filter :file_readable, :read_authorize, :only => [:show, :thumbnail]#Modified by young before_filter :delete_authorize, :only => :destroy before_filter :authorize_global, :only => :upload before_filter :login_without_softapplication, only: [:download] accept_api_auth :show, :download, :upload require 'iconv' def show respond_to do |format| format.html { if @attachment.is_diff? @diff = File.new(@attachment.diskfile, "rb").read @diff_type = params[:type] || User.current.pref[:diff_type] || 'inline' @diff_type = 'inline' unless %w(inline sbs).include?(@diff_type) # Save diff type as user preference if User.current.logged? && @diff_type != User.current.pref[:diff_type] User.current.pref[:diff_type] = @diff_type User.current.preference.save end render :action => 'diff' elsif @attachment.is_text? && @attachment.filesize <= Setting.file_max_size_displayed.to_i.kilobyte @content = File.new(@attachment.diskfile, "rb").read render :action => 'file' else download end } format.api end end def download # modify by nwb # 下载添加权限设置 candown = false if @attachment.container.has_attribute?(:project) && @attachment.container.project project = @attachment.container.project candown= User.current.member_of?(project) || (project.is_public==1 && @attachment.is_public == 1) elsif @attachment.container.is_a?(Project) project = @attachment.container candown= User.current.member_of?(project) || (project.is_public==1 && @attachment.is_public == 1) elsif @attachment.container.has_attribute?(:course) && @attachment.container.course course = @attachment.container.course candown= User.current.member_of_course?(course) || (course.is_public==1 && @attachment.is_public == 1) elsif @attachment.container.is_a?(Course) course = @attachment.container candown= User.current.member_of_course?(course) || (course.is_public==1 && @attachment.is_public == 1) elsif @attachment.container.class.to_s=="HomeworkAttach" && @attachment.container.bid.reward_type == 3 candown = true else candown = @attachment.is_public == 1 end if candown || User.current.admin? @attachment.increment_download if stale?(:etag => @attachment.digest) # images are sent inline send_file @attachment.diskfile, :filename => filename_for_content_disposition(@attachment.filename), :type => detect_content_type(@attachment), :disposition => (@attachment.image? ? 'inline' : 'attachment') end else render_403 :message => :notice_not_authorized end rescue => e redirect_to "http://" + (Setting.host_name.to_s) +"/file_not_found.html" end #更新资源文件类型 def updateType @attachment = Attachment.find(params[:attachmentid]) if @attachment != nil @attachment.attachtype = params[:newtype] @attachment.save render :text =>'success' else render :text=>'error' end end # 更新文件密级 def updateFileDense @attachment = Attachment.find(params[:attachmentid]) if @attachment != nil filedense = params[:newtype].to_s # d = Iconv.conv("unicodebig","utf-8",filedense) if filedense == "%E5%85%AC%E5%BC%80" #l(:field_is_public) @attachment.is_public = 1 else @attachment.is_public = 0 end @attachment.save @newfiledense = filedense end respond_to do |format| format.js end end def thumbnail if @attachment.thumbnailable? && thumbnail = @attachment.thumbnail(:size => params[:size]) if stale?(:etag => thumbnail) send_file thumbnail, :filename => filename_for_content_disposition(@attachment.filename), :type => detect_content_type(@attachment), :disposition => 'inline' end else # No thumbnail for the attachment or thumbnail could not be created render :nothing => true, :status => 404 end end def upload # Make sure that API users get used to set this content type # as it won't trigger Rails' automatic parsing of the request body for parameters unless request.content_type == 'application/octet-stream' render :nothing => true, :status => 406 return end @attachment = Attachment.new(:file => request.raw_post) @attachment.author = User.current @attachment.filename = params[:filename].presence || Redmine::Utils.random_hex(16) saved = @attachment.save respond_to do |format| format.js format.api { if saved render :action => 'upload', :status => :created else render_validation_errors(@attachment) end } end end def destroy if @attachment.container.respond_to?(:init_journal) @attachment.container.init_journal(User.current) end if @attachment.container # Make sure association callbacks are called @attachment.container.attachments.delete(@attachment) else @attachment.destroy end respond_to do |format| # modify by nwb if @attachment.container_type == 'Course' if @course.nil? format.html { redirect_to_referer_or forum_memo_path(@attachment.container.forum, @attachment.container) } else format.html { redirect_to_referer_or course_path(@course) } end else if @project.nil? format.html { redirect_to_referer_or forum_memo_path(@attachment.container.forum, @attachment.container) } else format.html { redirect_to_referer_or project_path(@project) } end end format.js end end def delete_homework @bid = @attachment.container.bid # Make sure association callbacks are called container = @attachment.container @attachment.container.attachments.delete(@attachment) #if container.attachments.empty? #container.delete #end respond_to do |format| format.html { redirect_to_referer_or respond_path(@bid) } format.js end end def autocomplete # modify by nwb if params[:project_id] @project = Project.find_by_id(params[:project_id]) elsif params[:course_id] @course = Course.find_by_id(params[:course_id]) end respond_to do |format| format.js end end def add_exist_file_to_project classname = params[:class_name] class_id = params[:class_id] attachments = params[:attachment][:attach] obj = Object.const_get(classname).find_by_id(class_id) attachments.collect do |attach_id| ori = Attachment.find_by_id(attach_id) next if ori.blank? attach_copied_obj = ori.copy attach_copied_obj.tag_list.add(ori.tag_list) # tag关联 attach_copied_obj.container = obj attach_copied_obj.created_on = Time.now attach_copied_obj.author_id = User.current.id @obj = obj @save_flag = attach_copied_obj.save @save_message = attach_copied_obj.errors.full_messages end respond_to do |format| format.js end rescue NoMethodError @save_flag = false @save_message = [] << l(:error_attachment_empty) respond_to do |format| format.js end end def add_exist_file_to_course class_id = params[:class_id] attachments = params[:attachment][:attach] obj = Course.find_by_id(class_id) attachments.collect do |attach_id| ori = Attachment.find_by_id(attach_id) next if ori.blank? attach_copied_obj = ori.copy attach_copied_obj.tag_list.add(ori.tag_list) # tag关联 attach_copied_obj.container = obj attach_copied_obj.created_on = Time.now attach_copied_obj.author_id = User.current.id @obj = obj @save_flag = attach_copied_obj.save @save_message = attach_copied_obj.errors.full_messages end respond_to do |format| format.js end rescue NoMethodError @save_flag = false @save_message = [] << l(:error_attachment_empty) respond_to do |format| format.js end end private def find_project @attachment = Attachment.find(params[:id]) # Show 404 if the filename in the url is wrong # modify by nwb raise ActiveRecord::RecordNotFound if params[:filename] && params[:filename] != @attachment.filename if @attachment.container_type == 'Course' @course = @attachment.course else unless @attachment.container_type == 'Bid' || @attachment.container_type == 'HomeworkAttach' || @attachment.container_type == 'Memo' || @attachment.container_type == 'Softapplication' @project = @attachment.project end end rescue ActiveRecord::RecordNotFound render_404 end # Checks that the file exists and is readable def file_readable if @attachment.readable? true else logger.error "Cannot send attachment, #{@attachment.diskfile} does not exist or is unreadable." render_404 end end def read_authorize if @attachment.container_type == "HomeworkAttach" || @attachment.container_type == 'Bid' true #User.current.allowed_to?(:view_homework_attaches, @attachment.project) ? true : deny_access else @attachment.visible? ? true : deny_access end end def delete_authorize @attachment.deletable? ? true : deny_access end def detect_content_type(attachment) content_type = attachment.content_type if content_type.blank? content_type = Redmine::MimeType.of(attachment.filename) end content_type.to_s end def login_without_softapplication referer = request.headers['Referer'] require_login unless referer =~ /softapplication/ end def renderTag @attachmentNew = Attachment.find(params[:attchmentId]) respond_to do |format| format.js end end end