diff --git a/.gitignore b/.gitignore index 6f7528fc..0b625b2e 100644 --- a/.gitignore +++ b/.gitignore @@ -26,4 +26,5 @@ doc/app /.bundle /Gemfile.lock +/Gemfile.local /.rvmrc* diff --git a/Gemfile b/Gemfile index befa9d28..7b02dfa5 100644 --- a/Gemfile +++ b/Gemfile @@ -11,6 +11,9 @@ group :test do gem 'shoulda', '~> 2.10.3' gem 'edavis10-object_daddy', :require => 'object_daddy' gem 'mocha' + + platforms :mri_18 do gem 'ruby-debug' end + platforms :mri_19 do gem 'ruby-debug19', :require => 'ruby-debug' end end group :openid do @@ -36,15 +39,22 @@ platforms :mri do group :mysql2 do gem "mysql2", "~> 0.2.7" end - + group :postgres do gem "pg", "~> 0.9.0" # gem "postgres-pr" end - +end + +platforms :mri_18 do group :sqlite do gem "sqlite3-ruby", "< 1.3", :require => "sqlite3" - # please tell me, if you are fond of a pure ruby sqlite3 binding + end +end + +platforms :mri_19 do + group :sqlite do + gem "sqlite3" end end @@ -54,16 +64,23 @@ platforms :jruby do group :mysql do gem "activerecord-jdbcmysql-adapter" end - + group :postgres do gem "activerecord-jdbcpostgresql-adapter" end - + group :sqlite do gem "activerecord-jdbcsqlite3-adapter" end end +# Load a "local" Gemfile +gemfile_local = File.join(File.dirname(__FILE__), "Gemfile.local") +if File.readable?(gemfile_local) + puts "Loading #{gemfile_local} ..." if $DEBUG + instance_eval(File.read(gemfile_local)) +end + # Load plugins' Gemfiles Dir.glob File.expand_path("../vendor/plugins/*/Gemfile", __FILE__) do |file| puts "Loading #{file} ..." if $DEBUG # `ruby -d` or `bundle -v` diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 45b1261c..57d77f54 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -24,6 +24,12 @@ class ApplicationController < ActionController::Base layout 'base' exempt_from_layout 'builder', 'rsb' + protect_from_forgery + def handle_unverified_request + super + cookies.delete(:autologin) + end + # Remove broken cookie after upgrade from 0.8.x (#4292) # See https://rails.lighthouseapp.com/projects/8994/tickets/3360 # TODO: remove it when Rails is fixed @@ -38,7 +44,6 @@ class ApplicationController < ActionController::Base before_filter :user_setup, :check_if_login_required, :set_localization filter_parameter_logging :password - protect_from_forgery rescue_from ActionController::InvalidAuthenticityToken, :with => :invalid_authenticity_token diff --git a/app/controllers/issues_controller.rb b/app/controllers/issues_controller.rb index 5a698d7a..8294586e 100644 --- a/app/controllers/issues_controller.rb +++ b/app/controllers/issues_controller.rb @@ -286,7 +286,7 @@ private render_error l(:error_no_tracker_in_project) return false end - @issue.start_date ||= Date.today + @issue.start_date ||= User.current.today if params[:issue].is_a?(Hash) @issue.safe_attributes = params[:issue] if User.current.allowed_to?(:add_issue_watchers, @project) && @issue.new_record? diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 133a18cb..44f68340 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -16,10 +16,12 @@ class ProjectsController < ApplicationController menu_item :roadmap, :only => :roadmap menu_item :settings, :only => :settings - before_filter :find_project, :except => [ :index, :list, :new, :create, :copy ] - before_filter :authorize, :except => [ :index, :list, :new, :create, :copy, :archive, :unarchive, :destroy] + before_filter :find_project, :except => [ :index, :new, :create, :copy ] + before_filter :authorize, :only => [ :show, :settings, :edit, :update, :modules ] before_filter :authorize_global, :only => [:new, :create] before_filter :require_admin, :only => [ :copy, :archive, :unarchive, :destroy ] + before_filter :jump_to_project_menu_item, :only => :show + before_filter :load_project_settings, :only => :settings accept_key_auth :index, :show, :create, :update, :destroy after_filter :only => [:create, :edit, :update, :archive, :unarchive, :destroy] do |controller| @@ -68,12 +70,7 @@ class ProjectsController < ApplicationController if validate_parent_id && @project.save @project.set_allowed_parent!(params[:project]['parent_id']) if params[:project].has_key?('parent_id') - # Add current user as a project member if he is not admin - unless User.current.admin? - r = Role.givable.find_by_id(Setting.new_project_user_role_id.to_i) || Role.givable.first - m = Member.new(:user => User.current, :roles => [r]) - @project.members << m - end + add_current_user_to_project_if_not_admin(@project) respond_to do |format| format.html { flash[:notice] = l(:notice_successful_create) @@ -128,11 +125,6 @@ class ProjectsController < ApplicationController # Show @project def show - if params[:jump] - # try to redirect to the requested menu item - redirect_to_project_menu_item(@project, params[:jump]) && return - end - @users_by_role = @project.users_by_role @subprojects = @project.children.visible.all @news = @project.news.find(:all, :limit => 5, :include => [ :author, :project ], :order => "#{News.table_name}.created_on DESC") @@ -151,8 +143,6 @@ class ProjectsController < ApplicationController @total_hours = TimeEntry.visible.sum(:hours, :include => :project, :conditions => cond).to_f end - @key = User.current.rss_key - respond_to do |format| format.html format.api @@ -160,12 +150,6 @@ class ProjectsController < ApplicationController end def settings - @issue_custom_fields = IssueCustomField.find(:all, :order => "#{CustomField.table_name}.position") - @issue_category ||= IssueCategory.new - @member ||= @project.members.new - @trackers = Tracker.all - @repository ||= @project.repository - @wiki ||= @project.wiki end def edit @@ -187,7 +171,7 @@ class ProjectsController < ApplicationController else respond_to do |format| format.html { - settings + load_project_settings render :action => 'settings' } format.api { render_validation_errors(@project) } @@ -230,8 +214,7 @@ class ProjectsController < ApplicationController end end end - # hide project in layout - @project = nil + hide_project_in_layout end private @@ -257,4 +240,33 @@ private end true end + + def jump_to_project_menu_item + if params[:jump] + # try to redirect to the requested menu item + redirect_to_project_menu_item(@project, params[:jump]) && return + end + end + + def load_project_settings + @issue_custom_fields = IssueCustomField.find(:all, :order => "#{CustomField.table_name}.position") + @issue_category ||= IssueCategory.new + @member ||= @project.members.new + @trackers = Tracker.all + @repository ||= @project.repository + @wiki ||= @project.wiki + end + + def hide_project_in_layout + @project = nil + end + + def add_current_user_to_project_if_not_admin(project) + unless User.current.admin? + r = Role.givable.find_by_id(Setting.new_project_user_role_id.to_i) || Role.givable.first + m = Member.new(:user => User.current, :roles => [r]) + project.members << m + end + end + end diff --git a/app/controllers/repositories_controller.rb b/app/controllers/repositories_controller.rb index 14054eb9..ad190145 100644 --- a/app/controllers/repositories_controller.rb +++ b/app/controllers/repositories_controller.rb @@ -143,7 +143,12 @@ class RepositoriesController < ApplicationController return true if Redmine::MimeType.is_type?('text', path) # Ruby 1.8.6 has a bug of integer divisions. # http://apidock.com/ruby/v1_8_6_287/String/is_binary_data%3F - return false if ent.is_binary_data? + if ent.respond_to?("is_binary_data?") && ent.is_binary_data? # Ruby 1.8.x and <1.9.2 + return false + elsif ent.respond_to?(:force_encoding) && (ent.dup.force_encoding("UTF-8") != ent.dup.force_encoding("BINARY") ) # Ruby 1.9.2 + # TODO: need to handle edge cases of non-binary content that isn't UTF-8 + return false + end true end private :is_entry_text_data? diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 57d450c6..10dcb3b8 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -81,7 +81,7 @@ module ApplicationHelper subject = truncate(subject, :length => options[:truncate]) end end - s = link_to "#{issue.tracker} ##{issue.id}", {:controller => "issues", :action => "show", :id => issue}, + s = link_to "#{h(issue.tracker)} ##{issue.id}", {:controller => "issues", :action => "show", :id => issue}, :class => issue.css_classes, :title => title s << ": #{h subject}" if subject diff --git a/app/helpers/issues_helper.rb b/app/helpers/issues_helper.rb index 78c97ba6..84b5a63b 100644 --- a/app/helpers/issues_helper.rb +++ b/app/helpers/issues_helper.rb @@ -129,82 +129,6 @@ module IssuesHelper out end - def show_detail(detail, no_html=false) - case detail.property - when 'attr' - field = detail.prop_key.to_s.gsub(/\_id$/, "") - label = l(("field_" + field).to_sym) - case - when ['due_date', 'start_date'].include?(detail.prop_key) - value = format_date(detail.value.to_date) if detail.value - old_value = format_date(detail.old_value.to_date) if detail.old_value - - when ['project_id', 'status_id', 'tracker_id', 'assigned_to_id', 'priority_id', 'category_id', 'fixed_version_id'].include?(detail.prop_key) - value = find_name_by_reflection(field, detail.value) - old_value = find_name_by_reflection(field, detail.old_value) - - when detail.prop_key == 'estimated_hours' - value = "%0.02f" % detail.value.to_f unless detail.value.blank? - old_value = "%0.02f" % detail.old_value.to_f unless detail.old_value.blank? - - when detail.prop_key == 'parent_id' - label = l(:field_parent_issue) - value = "##{detail.value}" unless detail.value.blank? - old_value = "##{detail.old_value}" unless detail.old_value.blank? - end - when 'cf' - custom_field = CustomField.find_by_id(detail.prop_key) - if custom_field - label = custom_field.name - value = format_value(detail.value, custom_field.field_format) if detail.value - old_value = format_value(detail.old_value, custom_field.field_format) if detail.old_value - end - when 'attachment' - label = l(:label_attachment) - end - call_hook(:helper_issues_show_detail_after_setting, {:detail => detail, :label => label, :value => value, :old_value => old_value }) - - label ||= detail.prop_key - value ||= detail.value - old_value ||= detail.old_value - - unless no_html - label = content_tag('strong', label) - old_value = content_tag("i", h(old_value)) if detail.old_value - old_value = content_tag("strike", old_value) if detail.old_value and (!detail.value or detail.value.empty?) - if detail.property == 'attachment' && !value.blank? && a = Attachment.find_by_id(detail.prop_key) - # Link to the attachment if it has not been removed - value = link_to_attachment(a) - else - value = content_tag("i", h(value)) if value - end - end - - if detail.property == 'attr' && detail.prop_key == 'description' - s = l(:text_journal_changed_no_detail, :label => label) - unless no_html - diff_link = link_to 'diff', - {:controller => 'journals', :action => 'diff', :id => detail.journal_id, :detail_id => detail.id}, - :title => l(:label_view_diff) - s << " (#{ diff_link })" - end - s - elsif !detail.value.blank? - case detail.property - when 'attr', 'cf' - if !detail.old_value.blank? - l(:text_journal_changed, :label => label, :old => old_value, :new => value) - else - l(:text_journal_set_to, :label => label, :value => value) - end - when 'attachment' - l(:text_journal_added, :label => label, :value => value) - end - else - l(:text_journal_deleted, :label => label, :old => old_value) - end - end - # Find the name of an associated record stored in the field attribute def find_name_by_reflection(field, id) association = Issue.reflect_on_association(field.to_sym) diff --git a/app/helpers/journals_helper.rb b/app/helpers/journals_helper.rb index 5a9f4770..e16f7a4c 100644 --- a/app/helpers/journals_helper.rb +++ b/app/helpers/journals_helper.rb @@ -48,7 +48,7 @@ module JournalsHelper if d = journal.render_detail(detail) content_tag("li", d) end - end.compact + end.compact.join(' ') end end diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb index 414e4391..98fc27fa 100644 --- a/app/helpers/search_helper.rb +++ b/app/helpers/search_helper.rb @@ -57,4 +57,14 @@ module SearchHelper end ('
<%=l(:field_status)%>: | <%= @issue.status.name %> | +<%=l(:field_status)%>: | <%= h(@issue.status.name) %> | <%=l(:field_start_date)%>: | <%= format_date(@issue.start_date) %> | |||||
---|---|---|---|---|---|---|---|---|---|---|
<%=l(:field_priority)%>: | <%= @issue.priority.name %> | +<%=l(:field_priority)%>: | <%= h(@issue.priority.name) %> | <%=l(:field_due_date)%>: | <%= format_date(@issue.due_date) %> | |||||
<%=l(:field_done_ratio)%>: | <%= progress_bar @issue.done_ratio, :width => '80px', :legend => "#{@issue.done_ratio}%" %> | |||||||||
<%=l(:field_category)%>: | <%=h @issue.category ? @issue.category.name : "-" %> | +<%=l(:field_category)%>: | <%=h(@issue.category ? @issue.category.name : "-") %> | <% if User.current.allowed_to?(:view_time_entries, @project) %><%=l(:label_spent_time)%>: | <%= @issue.spent_hours > 0 ? (link_to l_hours(@issue.spent_hours), {:controller => 'timelog', :action => 'index', :project_id => @project, :issue_id => @issue}) : "-" %> | diff --git a/app/views/repositories/_dir_list_content.rhtml b/app/views/repositories/_dir_list_content.rhtml index fd9dd7af..f6833c89 100644 --- a/app/views/repositories/_dir_list_content.rhtml +++ b/app/views/repositories/_dir_list_content.rhtml @@ -22,6 +22,6 @@<%= link_to_revision(changeset, @project) if changeset %> | <%= distance_of_time_in_words(entry.lastrev.time, Time.now) if entry.lastrev && entry.lastrev.time %> | <%= changeset.nil? ? h(replace_invalid_utf8(entry.lastrev.author.to_s.split('<').first)) : changeset.author if entry.lastrev %> | -<%=h truncate(changeset.comments, :length => 50) unless changeset.nil? %> | +<%=h truncate(Changeset.to_utf8(changeset.comments, changeset.repository.repo_log_encoding), :length => 50) unless changeset.nil? %> | <%= radio_button_tag('rev_to', changeset.identifier, (line_num==2), :id => "cbto-#{line_num}", :onclick => "if ($('cb-#{line_num}').checked==true) {$('cb-#{line_num-1}').checked=true;}") if show_diff && (line_num > 1) %> | <%= format_time(changeset.committed_on) %> | <%=h changeset.author %> | -<%= textilizable(truncate_at_line_break(changeset.comments)) %> | +<%= textilizable(truncate_at_line_break(Changeset.to_utf8(changeset.comments, changeset.repository.repo_log_encoding))) %> | <% line_num += 1 %> <% end %> diff --git a/app/views/search/_pagination.html.erb b/app/views/search/_pagination.html.erb new file mode 100644 index 00000000..d06fe8eb --- /dev/null +++ b/app/views/search/_pagination.html.erb @@ -0,0 +1,10 @@ +