These permissions need to be explicitly given to the Anonymous role (Admin -> Roles & Permissions -> Anonymous). git-svn-id: http://redmine.rubyforge.org/svn/trunk@919 e93f8b46-1217-0410-a6f0-8f06a7374b81tags/0.6.1
@@ -23,10 +23,6 @@ class ApplicationController < ActionController::Base | |||
require_dependency "repository/#{scm.underscore}" | |||
end | |||
def logged_in_user | |||
User.current.logged? ? User.current : nil | |||
end | |||
def current_role | |||
@current_role ||= User.current.role_for_project(@project) | |||
end |
@@ -49,7 +49,7 @@ class DocumentsController < ApplicationController | |||
@attachments = [] | |||
params[:attachments].each { |file| | |||
next unless file.size > 0 | |||
a = Attachment.create(:container => @document, :file => file, :author => logged_in_user) | |||
a = Attachment.create(:container => @document, :file => file, :author => User.current) | |||
@attachments << a unless a.new_record? | |||
} if params[:attachments] and params[:attachments].is_a? Array | |||
Mailer.deliver_attachments_added(@attachments) if !@attachments.empty? && Setting.notified_events.include?('document_added') |
@@ -82,7 +82,7 @@ class IssuesController < ApplicationController | |||
def show | |||
@custom_values = @issue.custom_values.find(:all, :include => :custom_field, :order => "#{CustomField.table_name}.position") | |||
@journals = @issue.journals.find(:all, :include => [:user, :details], :order => "#{Journal.table_name}.created_on ASC") | |||
@status_options = @issue.status.find_new_statuses_allowed_to(logged_in_user.role_for_project(@project), @issue.tracker) if logged_in_user | |||
@status_options = @issue.status.find_new_statuses_allowed_to(User.current.role_for_project(@project), @issue.tracker) | |||
respond_to do |format| | |||
format.html { render :template => 'issues/show.rhtml' } | |||
format.pdf { send_data(render(:template => 'issues/show.rfpdf', :layout => false), :type => 'application/pdf', :filename => "#{@project.identifier}-#{@issue.id}.pdf") } | |||
@@ -95,7 +95,7 @@ class IssuesController < ApplicationController | |||
@custom_values = @project.custom_fields_for_issues(@issue.tracker).collect { |x| @issue.custom_values.find_by_custom_field_id(x.id) || CustomValue.new(:custom_field => x, :customized => @issue) } | |||
else | |||
begin | |||
@issue.init_journal(self.logged_in_user) | |||
@issue.init_journal(User.current) | |||
# Retrieve custom fields and values | |||
if params["custom_fields"] | |||
@custom_values = @project.custom_fields_for_issues(@issue.tracker).collect { |x| CustomValue.new(:custom_field => x, :customized => @issue, :value => params["custom_fields"][x.id.to_s]) } | |||
@@ -117,7 +117,7 @@ class IssuesController < ApplicationController | |||
journal = @issue.init_journal(User.current, params[:notes]) | |||
params[:attachments].each { |file| | |||
next unless file.size > 0 | |||
a = Attachment.create(:container => @issue, :file => file, :author => logged_in_user) | |||
a = Attachment.create(:container => @issue, :file => file, :author => User.current) | |||
journal.details << JournalDetail.new(:property => 'attachment', | |||
:prop_key => a.id, | |||
:value => a.filename) unless a.new_record? | |||
@@ -132,17 +132,17 @@ class IssuesController < ApplicationController | |||
end | |||
def change_status | |||
@status_options = @issue.status.find_new_statuses_allowed_to(logged_in_user.role_for_project(@project), @issue.tracker) if logged_in_user | |||
@status_options = @issue.status.find_new_statuses_allowed_to(User.current.role_for_project(@project), @issue.tracker) | |||
@new_status = IssueStatus.find(params[:new_status_id]) | |||
if params[:confirm] | |||
begin | |||
journal = @issue.init_journal(self.logged_in_user, params[:notes]) | |||
journal = @issue.init_journal(User.current, params[:notes]) | |||
@issue.status = @new_status | |||
if @issue.update_attributes(params[:issue]) | |||
# Save attachments | |||
params[:attachments].each { |file| | |||
next unless file.size > 0 | |||
a = Attachment.create(:container => @issue, :file => file, :author => logged_in_user) | |||
a = Attachment.create(:container => @issue, :file => file, :author => User.current) | |||
journal.details << JournalDetail.new(:property => 'attachment', | |||
:prop_key => a.id, | |||
:value => a.filename) unless a.new_record? | |||
@@ -150,7 +150,7 @@ class IssuesController < ApplicationController | |||
# Log time | |||
if current_role.allowed_to?(:log_time) | |||
@time_entry ||= TimeEntry.new(:project => @project, :issue => @issue, :user => logged_in_user, :spent_on => Date.today) | |||
@time_entry ||= TimeEntry.new(:project => @project, :issue => @issue, :user => User.current, :spent_on => Date.today) | |||
@time_entry.attributes = params[:time_entry] | |||
@time_entry.save | |||
end | |||
@@ -176,7 +176,7 @@ class IssuesController < ApplicationController | |||
def destroy_attachment | |||
a = @issue.attachments.find(params[:attachment_id]) | |||
a.destroy | |||
journal = @issue.init_journal(self.logged_in_user) | |||
journal = @issue.init_journal(User.current) | |||
journal.details << JournalDetail.new(:property => 'attachment', | |||
:prop_key => a.id, | |||
:old_value => a.filename) | |||
@@ -225,12 +225,11 @@ private | |||
def retrieve_query | |||
if params[:query_id] | |||
@query = Query.find(params[:query_id], :conditions => {:project_id => (@project ? @project.id : nil)}) | |||
@query.executed_by = logged_in_user | |||
session[:query] = @query | |||
else | |||
if params[:set_filter] or !session[:query] or session[:query].project != @project | |||
# Give it a name, required to be valid | |||
@query = Query.new(:name => "_", :executed_by => logged_in_user) | |||
@query = Query.new(:name => "_") | |||
@query.project = @project | |||
if params[:fields] and params[:fields].is_a? Array | |||
params[:fields].each do |field| |
@@ -31,12 +31,12 @@ class MessagesController < ApplicationController | |||
def new | |||
@message = Message.new(params[:message]) | |||
@message.author = logged_in_user | |||
@message.author = User.current | |||
@message.board = @board | |||
if request.post? && @message.save | |||
params[:attachments].each { |file| | |||
next unless file.size > 0 | |||
Attachment.create(:container => @message, :file => file, :author => logged_in_user) | |||
Attachment.create(:container => @message, :file => file, :author => User.current) | |||
} if params[:attachments] and params[:attachments].is_a? Array | |||
redirect_to :action => 'show', :id => @message | |||
end | |||
@@ -44,7 +44,7 @@ class MessagesController < ApplicationController | |||
def reply | |||
@reply = Message.new(params[:reply]) | |||
@reply.author = logged_in_user | |||
@reply.author = User.current | |||
@reply.board = @board | |||
@message.children << @reply | |||
redirect_to :action => 'show', :id => @message |
@@ -44,7 +44,7 @@ class MyController < ApplicationController | |||
# Show user's page | |||
def page | |||
@user = self.logged_in_user | |||
@user = User.current | |||
@blocks = @user.pref[:my_page_layout] || DEFAULT_LAYOUT | |||
end | |||
@@ -76,7 +76,7 @@ class MyController < ApplicationController | |||
# Manage user's password | |||
def password | |||
@user = self.logged_in_user | |||
@user = User.current | |||
flash[:error] = l(:notice_can_t_change_password) and redirect_to :action => 'account' and return if @user.auth_source_id | |||
if request.post? | |||
if @user.check_password?(params[:password]) | |||
@@ -102,7 +102,7 @@ class MyController < ApplicationController | |||
# User's page layout configuration | |||
def page_layout | |||
@user = self.logged_in_user | |||
@user = User.current | |||
@blocks = @user.pref[:my_page_layout] || DEFAULT_LAYOUT.dup | |||
session[:page_layout] = @blocks | |||
%w(top left right).each {|f| session[:page_layout][f] ||= [] } | |||
@@ -116,7 +116,7 @@ class MyController < ApplicationController | |||
def add_block | |||
block = params[:block] | |||
render(:nothing => true) and return unless block && (BLOCKS.keys.include? block) | |||
@user = self.logged_in_user | |||
@user = User.current | |||
# remove if already present in a group | |||
%w(top left right).each {|f| (session[:page_layout][f] ||= []).delete block } | |||
# add it on top | |||
@@ -151,7 +151,7 @@ class MyController < ApplicationController | |||
# Save user's page layout | |||
def page_layout_save | |||
@user = self.logged_in_user | |||
@user = User.current | |||
@user.pref[:my_page_layout] = session[:page_layout] if session[:page_layout] | |||
@user.pref.save | |||
session[:page_layout] = nil |
@@ -45,7 +45,7 @@ class NewsController < ApplicationController | |||
def add_comment | |||
@comment = Comment.new(params[:comment]) | |||
@comment.author = logged_in_user | |||
@comment.author = User.current | |||
if @news.comments << @comment | |||
flash[:notice] = l(:label_comment_added) | |||
redirect_to :action => 'show', :id => @news |
@@ -48,7 +48,7 @@ class ProjectsController < ApplicationController | |||
# Lists visible projects | |||
def list | |||
projects = Project.find :all, | |||
:conditions => Project.visible_by(logged_in_user), | |||
:conditions => Project.visible_by(User.current), | |||
:include => :parent | |||
@project_tree = projects.group_by {|p| p.parent || p} | |||
@project_tree.each_key {|p| @project_tree[p] -= [p]} | |||
@@ -176,7 +176,7 @@ class ProjectsController < ApplicationController | |||
if request.post? and @document.save | |||
# Save the attachments | |||
params[:attachments].each { |a| | |||
Attachment.create(:container => @document, :file => a, :author => logged_in_user) unless a.size == 0 | |||
Attachment.create(:container => @document, :file => a, :author => User.current) unless a.size == 0 | |||
} if params[:attachments] and params[:attachments].is_a? Array | |||
flash[:notice] = l(:notice_successful_create) | |||
Mailer.deliver_document_added(@document) if Setting.notified_events.include?('document_added') | |||
@@ -216,7 +216,7 @@ class ProjectsController < ApplicationController | |||
return | |||
end | |||
@issue.status = default_status | |||
@allowed_statuses = ([default_status] + default_status.find_new_statuses_allowed_to(logged_in_user.role_for_project(@project), @issue.tracker))if logged_in_user | |||
@allowed_statuses = ([default_status] + default_status.find_new_statuses_allowed_to(User.current.role_for_project(@project), @issue.tracker)) | |||
if request.get? | |||
@issue.start_date ||= Date.today | |||
@@ -321,10 +321,9 @@ class ProjectsController < ApplicationController | |||
# Add a news to @project | |||
def add_news | |||
@news = News.new(:project => @project) | |||
@news = News.new(:project => @project, :author => User.current) | |||
if request.post? | |||
@news.attributes = params[:news] | |||
@news.author_id = self.logged_in_user.id if self.logged_in_user | |||
if @news.save | |||
flash[:notice] = l(:notice_successful_create) | |||
Mailer.deliver_news_added(@news) if Setting.notified_events.include?('news_added') | |||
@@ -340,7 +339,7 @@ class ProjectsController < ApplicationController | |||
@attachments = [] | |||
params[:attachments].each { |file| | |||
next unless file.size > 0 | |||
a = Attachment.create(:container => @version, :file => file, :author => logged_in_user) | |||
a = Attachment.create(:container => @version, :file => file, :author => User.current) | |||
@attachments << a unless a.new_record? | |||
} if params[:attachments] and params[:attachments].is_a? Array | |||
Mailer.deliver_attachments_added(@attachments) if !@attachments.empty? && Setting.notified_events.include?('file_added') |
@@ -22,14 +22,13 @@ class QueriesController < ApplicationController | |||
def index | |||
@queries = @project.queries.find(:all, | |||
:order => "name ASC", | |||
:conditions => ["is_public = ? or user_id = ?", true, (logged_in_user ? logged_in_user.id : 0)]) | |||
:conditions => ["is_public = ? or user_id = ?", true, (User.current.logged? ? User.current.id : 0)]) | |||
end | |||
def new | |||
@query = Query.new(params[:query]) | |||
@query.project = @project | |||
@query.user = logged_in_user | |||
@query.executed_by = logged_in_user | |||
@query.user = User.current | |||
@query.is_public = false unless current_role.allowed_to?(:manage_public_queries) | |||
@query.column_names = nil if params[:default_columns] | |||
@@ -71,9 +70,8 @@ private | |||
def find_project | |||
if params[:id] | |||
@query = Query.find(params[:id]) | |||
@query.executed_by = logged_in_user | |||
@project = @query.project | |||
render_403 unless @query.editable_by?(logged_in_user) | |||
render_403 unless @query.editable_by?(User.current) | |||
else | |||
@project = Project.find(params[:project_id]) | |||
end |
@@ -31,7 +31,7 @@ class SearchController < ApplicationController | |||
begin; offset = params[:offset].to_time if params[:offset]; rescue; end | |||
# quick jump to an issue | |||
if @question.match(/^#?(\d+)$/) && Issue.find_by_id($1, :include => :project, :conditions => Project.visible_by(logged_in_user)) | |||
if @question.match(/^#?(\d+)$/) && Issue.find_by_id($1, :include => :project, :conditions => Project.visible_by(User.current)) | |||
redirect_to :controller => "issues", :action => "show", :id => $1 | |||
return | |||
end | |||
@@ -87,7 +87,7 @@ class SearchController < ApplicationController | |||
end | |||
else | |||
operator = @all_words ? ' AND ' : ' OR ' | |||
Project.with_scope(:find => {:conditions => Project.visible_by(logged_in_user)}) do | |||
Project.with_scope(:find => {:conditions => Project.visible_by(User.current)}) do | |||
@results += Project.find(:all, :limit => limit, :conditions => [ (["(LOWER(name) like ? OR LOWER(description) like ?)"] * like_tokens.size).join(operator), * (like_tokens * 2).sort] ) if @scope.include? 'projects' | |||
end | |||
# if only one project is found, user is redirected to its overview |
@@ -107,15 +107,15 @@ class TimelogController < ApplicationController | |||
@entries = (@issue ? @issue : @project).time_entries.find(:all, :include => [:activity, :user, {:issue => [:tracker, :assigned_to, :priority]}], :order => sort_clause) | |||
@total_hours = @entries.inject(0) { |sum,entry| sum + entry.hours } | |||
@owner_id = logged_in_user ? logged_in_user.id : 0 | |||
@owner_id = User.current.id | |||
send_csv and return if 'csv' == params[:export] | |||
render :action => 'details', :layout => false if request.xhr? | |||
end | |||
def edit | |||
render_404 and return if @time_entry && @time_entry.user != logged_in_user | |||
@time_entry ||= TimeEntry.new(:project => @project, :issue => @issue, :user => logged_in_user, :spent_on => Date.today) | |||
render_404 and return if @time_entry && @time_entry.user != User.current | |||
@time_entry ||= TimeEntry.new(:project => @project, :issue => @issue, :user => User.current, :spent_on => Date.today) | |||
@time_entry.attributes = params[:time_entry] | |||
if request.post? and @time_entry.save | |||
flash[:notice] = l(:notice_successful_update) |
@@ -19,7 +19,7 @@ class WelcomeController < ApplicationController | |||
layout 'base' | |||
def index | |||
@news = News.latest logged_in_user | |||
@projects = Project.latest logged_in_user | |||
@news = News.latest User.current | |||
@projects = Project.latest User.current | |||
end | |||
end |
@@ -69,7 +69,7 @@ class WikiController < ApplicationController | |||
#@content.text = params[:content][:text] | |||
#@content.comments = params[:content][:comments] | |||
@content.attributes = params[:content] | |||
@content.author = logged_in_user | |||
@content.author = User.current | |||
# if page is new @page.save will also save content, but not if page isn't a new record | |||
if (@page.new_record? ? @page.save : @content.save) | |||
redirect_to :action => 'index', :id => @project, :page => @page.title | |||
@@ -157,7 +157,7 @@ class WikiController < ApplicationController | |||
# Save the attachments | |||
params[:attachments].each { |file| | |||
next unless file.size > 0 | |||
a = Attachment.create(:container => @page, :file => file, :author => logged_in_user) | |||
a = Attachment.create(:container => @page, :file => file, :author => User.current) | |||
} if params[:attachments] and params[:attachments].is_a? Array | |||
redirect_to :action => 'index', :page => @page.title | |||
end |
@@ -21,7 +21,7 @@ class Attachment < ActiveRecord::Base | |||
belongs_to :container, :polymorphic => true | |||
belongs_to :author, :class_name => "User", :foreign_key => "author_id" | |||
validates_presence_of :container, :filename | |||
validates_presence_of :container, :filename, :author | |||
validates_length_of :filename, :maximum => 255 | |||
validates_length_of :disk_filename, :maximum => 255 | |||
@@ -82,11 +82,6 @@ class Attachment < ActiveRecord::Base | |||
def increment_download | |||
increment!(:downloads) | |||
end | |||
# returns last created projects | |||
def self.most_downloaded | |||
find(:all, :limit => 5, :order => "downloads DESC") | |||
end | |||
def project | |||
container.is_a?(Project) ? container : container.project |
@@ -112,11 +112,8 @@ class Query < ActiveRecord::Base | |||
def initialize(attributes = nil) | |||
super attributes | |||
self.filters ||= { 'status_id' => {:operator => "o", :values => [""]} } | |||
end | |||
def executed_by=(user) | |||
@executed_by = user | |||
set_language_if_valid(user.language) if user | |||
@executed_by = User.current.logged? ? User.current : nil | |||
set_language_if_valid(executed_by.language) if executed_by | |||
end | |||
def validate |
@@ -19,6 +19,7 @@ require "digest/sha1" | |||
class User < ActiveRecord::Base | |||
# Account statuses | |||
STATUS_ANONYMOUS = 0 | |||
STATUS_ACTIVE = 1 | |||
STATUS_REGISTERED = 2 | |||
STATUS_LOCKED = 3 | |||
@@ -36,15 +37,15 @@ class User < ActiveRecord::Base | |||
# Prevents unauthorized assignments | |||
attr_protected :login, :admin, :password, :password_confirmation, :hashed_password | |||
validates_presence_of :login, :firstname, :lastname, :mail | |||
validates_presence_of :login, :firstname, :lastname, :mail, :if => Proc.new { |user| !user.is_a?(AnonymousUser) } | |||
validates_uniqueness_of :login, :mail | |||
# Login must contain lettres, numbers, underscores only | |||
validates_format_of :login, :with => /^[a-z0-9_\-@\.]+$/i | |||
validates_format_of :login, :with => /^[a-z0-9_\-@\.]*$/i | |||
validates_length_of :login, :maximum => 30 | |||
validates_format_of :firstname, :lastname, :with => /^[\w\s\'\-]*$/i | |||
validates_length_of :firstname, :lastname, :maximum => 30 | |||
validates_format_of :mail, :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i | |||
validates_length_of :mail, :maximum => 60 | |||
validates_format_of :mail, :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i, :allow_nil => true | |||
validates_length_of :mail, :maximum => 60, :allow_nil => true | |||
# Password length between 4 and 12 | |||
validates_length_of :password, :in => 4..12, :allow_nil => true | |||
validates_confirmation_of :password, :allow_nil => true | |||
@@ -216,11 +217,17 @@ class User < ActiveRecord::Base | |||
end | |||
def self.current | |||
@current_user ||= AnonymousUser.new | |||
@current_user ||= User.anonymous | |||
end | |||
def self.anonymous | |||
AnonymousUser.new | |||
return @anonymous_user if @anonymous_user | |||
anonymous_user = AnonymousUser.find(:first) | |||
if anonymous_user.nil? | |||
anonymous_user = AnonymousUser.create(:lastname => 'Anonymous', :firstname => '', :mail => '', :login => '', :status => 0) | |||
raise 'Unable to create the anonymous user.' if anonymous_user.new_record? | |||
end | |||
@anonymous_user = anonymous_user | |||
end | |||
private | |||
@@ -231,16 +238,17 @@ private | |||
end | |||
class AnonymousUser < User | |||
def logged? | |||
false | |||
end | |||
def time_zone | |||
nil | |||
def validate_on_create | |||
# There should be only one AnonymousUser in the database | |||
errors.add_to_base 'An anonymous user already exists.' if AnonymousUser.find(:first) | |||
end | |||
# Anonymous user has no RSS key | |||
def rss_key | |||
nil | |||
end | |||
# Overrides a few properties | |||
def logged?; false end | |||
def admin; false end | |||
def name; 'Anonymous' end | |||
def mail; nil end | |||
def time_zone; nil end | |||
def rss_key; nil end | |||
end |
@@ -26,7 +26,7 @@ | |||
<h3 class="icon22 icon22-comment"><%= l(:label_comment_plural) %></h3> | |||
<% @news.comments.each do |comment| %> | |||
<% next if comment.new_record? %> | |||
<h4><%= format_time(comment.created_on) %> - <%= comment.author.name %></h4> | |||
<h4><%= authoring comment.created_on, comment.author %></h4> | |||
<div class="contextual"> | |||
<%= link_to_if_authorized l(:button_delete), {:controller => 'news', :action => 'destroy_comment', :id => @news, :comment_id => comment}, :confirm => l(:text_are_you_sure), :method => :post, :class => 'icon icon-del' %> | |||
</div> |
@@ -0,0 +1,10 @@ | |||
class AddUsersType < ActiveRecord::Migration | |||
def self.up | |||
add_column :users, :type, :string | |||
User.update_all "type = 'User'" | |||
end | |||
def self.down | |||
remove_column :users, :type | |||
end | |||
end |
@@ -29,11 +29,11 @@ Redmine::AccessControl.map do |map| | |||
:issues => [:index, :changes, :show, :context_menu], | |||
:queries => :index, | |||
:reports => :issue_report}, :public => true | |||
map.permission :add_issues, {:projects => :add_issue}, :require => :loggedin | |||
map.permission :add_issues, {:projects => :add_issue} | |||
map.permission :edit_issues, {:projects => :bulk_edit_issues, | |||
:issues => [:edit, :destroy_attachment]}, :require => :loggedin | |||
map.permission :manage_issue_relations, {:issue_relations => [:new, :destroy]}, :require => :loggedin | |||
map.permission :add_issue_notes, {:issues => :add_note}, :require => :loggedin | |||
:issues => [:edit, :destroy_attachment]} | |||
map.permission :manage_issue_relations, {:issue_relations => [:new, :destroy]} | |||
map.permission :add_issue_notes, {:issues => :add_note} | |||
map.permission :change_issue_status, {:issues => :change_status}, :require => :loggedin | |||
map.permission :move_issues, {:projects => :move_issues}, :require => :loggedin | |||
map.permission :delete_issues, {:issues => :destroy}, :require => :member | |||
@@ -53,7 +53,7 @@ Redmine::AccessControl.map do |map| | |||
map.project_module :news do |map| | |||
map.permission :manage_news, {:projects => :add_news, :news => [:edit, :destroy, :destroy_comment]}, :require => :member | |||
map.permission :view_news, {:news => [:index, :show]}, :public => true | |||
map.permission :comment_news, {:news => :add_comment}, :require => :loggedin | |||
map.permission :comment_news, {:news => :add_comment} | |||
end | |||
map.project_module :documents do |map| | |||
@@ -83,7 +83,7 @@ Redmine::AccessControl.map do |map| | |||
map.project_module :boards do |map| | |||
map.permission :manage_boards, {:boards => [:new, :edit, :destroy]}, :require => :member | |||
map.permission :view_messages, {:boards => [:index, :show], :messages => [:show]}, :public => true | |||
map.permission :add_messages, {:messages => [:new, :reply]}, :require => :loggedin | |||
map.permission :add_messages, {:messages => [:new, :reply]} | |||
end | |||
end | |||
@@ -60,7 +60,7 @@ class UserTest < Test::Unit::TestCase | |||
def test_validate | |||
@admin.login = "" | |||
assert !@admin.save | |||
assert_equal 2, @admin.errors.count | |||
assert_equal 1, @admin.errors.count | |||
end | |||
def test_password | |||
@@ -87,6 +87,13 @@ class UserTest < Test::Unit::TestCase | |||
assert_equal nil, user | |||
end | |||
def test_create_anonymous | |||
AnonymousUser.delete_all | |||
anon = User.anonymous | |||
assert !anon.new_record? | |||
assert_kind_of AnonymousUser, anon | |||
end | |||
def test_rss_key | |||
assert_nil @jsmith.rss_token | |||
key = @jsmith.rss_key |