Skip to content

Commit

Permalink
Merge remote branch 'redmine/master' into upstream-int
Browse files Browse the repository at this point in the history
  • Loading branch information
nicksieger committed Mar 14, 2011
2 parents fa9e2f9 + d317aec commit 1168aab
Show file tree
Hide file tree
Showing 654 changed files with 38,643 additions and 14,954 deletions.
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
/.bundle
/.project
/.loadpath
/config/additional_environment.rb
/config/configuration.yml
/config/database.yml
/config/email.yml
/config/initializers/session_store.rb
Expand All @@ -8,6 +10,8 @@
/db/*.sqlite3
/db/schema.rb
/files/*
/lib/redmine/scm/adapters/mercurial/redminehelper.pyc
/lib/redmine/scm/adapters/mercurial/redminehelper.pyo
/log/*.log*
/log/mongrel_debug
/public/dispatch.*
Expand Down
27 changes: 27 additions & 0 deletions .hgignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
syntax: glob

.project
.loadpath
config/additional_environment.rb
config/configuration.yml
config/database.yml
config/email.yml
config/initializers/session_store.rb
coverage
db/*.db
db/*.sqlite3
db/schema.rb
files/*
lib/redmine/scm/adapters/mercurial/redminehelper.pyc
lib/redmine/scm/adapters/mercurial/redminehelper.pyo
log/*.log*
log/mongrel_debug
public/dispatch.*
public/plugin_assets
tmp/*
tmp/cache/*
tmp/sessions/*
tmp/sockets/*
tmp/test/*
vendor/rails
*.rbc
16 changes: 14 additions & 2 deletions app/controllers/account_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -203,12 +203,24 @@ def successful_authentication(user)
self.logged_user = user
# generate a key and set cookie if autologin
if params[:autologin] && Setting.autologin?
token = Token.create(:user => user, :action => 'autologin')
cookies[:autologin] = { :value => token.value, :expires => 1.year.from_now }
set_autologin_cookie(user)
end
call_hook(:controller_account_success_authentication_after, {:user => user })
redirect_back_or_default :controller => 'my', :action => 'page'
end

def set_autologin_cookie(user)
token = Token.create(:user => user, :action => 'autologin')
cookie_name = Redmine::Configuration['autologin_cookie_name'] || 'autologin'
cookie_options = {
:value => token.value,
:expires => 1.year.from_now,
:path => (Redmine::Configuration['autologin_cookie_path'] || '/'),
:secure => (Redmine::Configuration['autologin_cookie_secure'] ? true : false),
:httponly => true
}
cookies[cookie_name] = cookie_options
end

# Onthefly creation failed, display the registration form to fill/fix attributes
def onthefly_creation_failed(user, auth_source_options = { })
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/activities_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def index

events = @activity.events(@date_from, @date_to)

if events.empty? || stale?(:etag => [events.first, User.current])
if events.empty? || stale?(:etag => [@activity.scope, @date_to, @date_from, @with_subprojects, @author, events.first, User.current, current_language])
respond_to do |format|
@events_by_day = events.group_by(&:event_date)
format.html {
Expand Down
149 changes: 113 additions & 36 deletions app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class ApplicationController < ActionController::Base
include Redmine::I18n

layout 'base'
exempt_from_layout 'builder'
exempt_from_layout 'builder', 'rsb'

# Remove broken cookie after upgrade from 0.8.x (#4292)
# See https://rails.lighthouseapp.com/projects/8994/tickets/3360
Expand Down Expand Up @@ -71,10 +71,10 @@ def find_current_user
elsif params[:format] == 'atom' && params[:key] && accept_key_auth_actions.include?(params[:action])
# RSS key authentication does not start a session
User.find_by_rss_key(params[:key])
elsif Setting.rest_api_enabled? && ['xml', 'json'].include?(params[:format])
if params[:key].present? && accept_key_auth_actions.include?(params[:action])
elsif Setting.rest_api_enabled? && api_request?
if (key = api_key_from_request) && accept_key_auth_actions.include?(params[:action])
# Use API key
User.find_by_api_key(params[:key])
User.find_by_api_key(key)
else
# HTTP Basic, either username/password or API key/random
authenticate_with_http_basic do |username, password|
Expand Down Expand Up @@ -153,8 +153,16 @@ def deny_access

# Authorize the user for the requested action
def authorize(ctrl = params[:controller], action = params[:action], global = false)
allowed = User.current.allowed_to?({:controller => ctrl, :action => action}, @project, :global => global)
allowed ? true : deny_access
allowed = User.current.allowed_to?({:controller => ctrl, :action => action}, @project || @projects, :global => global)
if allowed
true
else
if @project && @project.archived?
render_403 :message => :notice_not_authorized_archived_project
else
deny_access
end
end
end

# Authorize the user for the requested action outside a project
Expand All @@ -169,6 +177,13 @@ def find_project
render_404
end

# Find project of id params[:project_id]
def find_project_by_project_id
@project = Project.find(params[:project_id])
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
Expand Down Expand Up @@ -206,16 +221,19 @@ def self.model_object(model)
def find_issues
@issues = Issue.find_all_by_id(params[:id] || params[:ids])
raise ActiveRecord::RecordNotFound if @issues.empty?
projects = @issues.collect(&:project).compact.uniq
if projects.size == 1
@project = projects.first
else
@projects = @issues.collect(&:project).compact.uniq
@project = @projects.first if @projects.size == 1
rescue ActiveRecord::RecordNotFound
render_404
end

# Check if project is unique before bulk operations
def check_project_uniqueness
unless @project
# TODO: let users bulk edit/move/destroy issues from different projects
render_error 'Can not bulk edit/move/destroy issues from different projects'
return false
end
rescue ActiveRecord::RecordNotFound
render_404
end

# make sure that the user is a member of the project (or admin) if project is private
Expand Down Expand Up @@ -255,39 +273,33 @@ def redirect_back_or_default(default)
redirect_to default
end

def render_403
def render_403(options={})
@project = nil
respond_to do |format|
format.html { render :template => "common/403", :layout => use_layout, :status => 403 }
format.atom { head 403 }
format.xml { head 403 }
format.js { head 403 }
format.json { head 403 }
end
render_error({:message => :notice_not_authorized, :status => 403}.merge(options))
return false
end

def render_404
respond_to do |format|
format.html { render :template => "common/404", :layout => use_layout, :status => 404 }
format.atom { head 404 }
format.xml { head 404 }
format.js { head 404 }
format.json { head 404 }
end
def render_404(options={})
render_error({:message => :notice_file_not_found, :status => 404}.merge(options))
return false
end

def render_error(msg)
# Renders an error response
def render_error(arg)
arg = {:message => arg} unless arg.is_a?(Hash)

@message = arg[:message]
@message = l(@message) if @message.is_a?(Symbol)
@status = arg[:status] || 500

respond_to do |format|
format.html {
flash.now[:error] = msg
render :text => '', :layout => use_layout, :status => 500
format.html {
render :template => 'common/error', :layout => use_layout, :status => @status
}
format.atom { head 500 }
format.xml { head 500 }
format.js { head 500 }
format.json { head 500 }
format.atom { head @status }
format.xml { head @status }
format.js { head @status }
format.json { head @status }
end
end

Expand Down Expand Up @@ -337,6 +349,30 @@ def per_page_option
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
end
offset ||= 0

[offset, limit]
end

# qvalues http header parser
# code taken from webrick
def parse_qvalues(value)
Expand Down Expand Up @@ -366,6 +402,15 @@ def filename_for_content_disposition(name)
def api_request?
%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]
elsif request.headers["X-Redmine-API-Key"].present?
request.headers["X-Redmine-API-Key"]
end
end

# Renders a warning flash if obj has unsaved attachments
def render_attachment_warning_if_needed(obj)
Expand Down Expand Up @@ -401,5 +446,37 @@ def object_errors_to_json(object)
{ attribute => error }
end.to_json
end

# Renders API response on validation failure
def render_validation_errors(object)
options = { :status => :unprocessable_entity, :layout => false }
options.merge!(case params[:format]
when 'xml'; { :xml => object.errors }
when 'json'; { :json => {'errors' => object.errors} } # ActiveResource client compliance
else
raise "Unknown format #{params[:format]} in #render_validation_errors"
end
)
render options
end

# Overrides #default_template so that the api template
# is used automatically if it exists
def default_template(action_name = self.action_name)
if api_request?
begin
return self.view_paths.find_template(default_template_name(action_name), 'api')
rescue ::ActionView::MissingTemplate
# the api template was not found
# fallback to the default behaviour
end
end
super
end

# Overrides #pick_layout so that #render with no arguments
# doesn't use the layout for api requests
def pick_layout(*args)
api_request? ? nil : super
end
end
6 changes: 4 additions & 2 deletions app/controllers/auto_completes_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ class AutoCompletesController < ApplicationController
def issues
@issues = []
q = params[:q].to_s
query = (params[:scope] == "all" && Setting.cross_project_issue_relations?) ? Issue : @project.issues
if q.match(/^\d+$/)
@issues << @project.issues.visible.find_by_id(q.to_i)
@issues << query.visible.find_by_id(q.to_i)
end
unless q.blank?
@issues += @project.issues.visible.find(:all, :conditions => ["LOWER(#{Issue.table_name}.subject) LIKE ?", "%#{q.downcase}%"], :limit => 10)
@issues += query.visible.find(:all, :conditions => ["LOWER(#{Issue.table_name}.subject) LIKE ?", "%#{q.downcase}%"], :limit => 10)
end
@issues.compact!
render :layout => false
end

Expand Down
2 changes: 2 additions & 0 deletions app/controllers/calendars_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ class CalendarsController < ApplicationController
helper :projects
helper :queries
include QueriesHelper
helper :sort
include SortHelper

def show
if params[:year] and params[:year].to_i > 1900
Expand Down
36 changes: 36 additions & 0 deletions app/controllers/comments_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
class CommentsController < ApplicationController
default_search_scope :news
model_object News
before_filter :find_model_object
before_filter :find_project_from_association
before_filter :authorize

verify :method => :post, :only => :create, :render => {:nothing => true, :status => :method_not_allowed }
def create
@comment = Comment.new(params[:comment])
@comment.author = User.current
if @news.comments << @comment
flash[:notice] = l(:label_comment_added)
end

redirect_to :controller => 'news', :action => 'show', :id => @news
end

verify :method => :delete, :only => :destroy, :render => {:nothing => true, :status => :method_not_allowed }
def destroy
@news.comments.find(params[:comment_id]).destroy
redirect_to :controller => 'news', :action => 'show', :id => @news
end

private

# ApplicationController's find_model_object sets it based on the controller
# name so it needs to be overriden and set to @news instead
def find_model_object
super
@news = @object
@comment = nil
@news
end

end
Loading

0 comments on commit 1168aab

Please sign in to comment.