diff --git a/app/controllers/application.rb b/app/controllers/application.rb index 991b3fff7..e186455a3 100644 --- a/app/controllers/application.rb +++ b/app/controllers/application.rb @@ -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 diff --git a/app/controllers/documents_controller.rb b/app/controllers/documents_controller.rb index 63ee96134..94532b65b 100644 --- a/app/controllers/documents_controller.rb +++ b/app/controllers/documents_controller.rb @@ -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') diff --git a/app/controllers/issues_controller.rb b/app/controllers/issues_controller.rb index 92443441c..cca3fe623 100644 --- a/app/controllers/issues_controller.rb +++ b/app/controllers/issues_controller.rb @@ -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| diff --git a/app/controllers/messages_controller.rb b/app/controllers/messages_controller.rb index 74a957d6c..645aadf1c 100644 --- a/app/controllers/messages_controller.rb +++ b/app/controllers/messages_controller.rb @@ -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 diff --git a/app/controllers/my_controller.rb b/app/controllers/my_controller.rb index 2fa5a9d9c..cb326bc93 100644 --- a/app/controllers/my_controller.rb +++ b/app/controllers/my_controller.rb @@ -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 diff --git a/app/controllers/news_controller.rb b/app/controllers/news_controller.rb index c41c5844e..109afe454 100644 --- a/app/controllers/news_controller.rb +++ b/app/controllers/news_controller.rb @@ -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 diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 289b34e24..0f50cd780 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -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') diff --git a/app/controllers/queries_controller.rb b/app/controllers/queries_controller.rb index 7feafd35b..69bad345a 100644 --- a/app/controllers/queries_controller.rb +++ b/app/controllers/queries_controller.rb @@ -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 diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb index 2c00b3d74..7c50d4dcb 100644 --- a/app/controllers/search_controller.rb +++ b/app/controllers/search_controller.rb @@ -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 diff --git a/app/controllers/timelog_controller.rb b/app/controllers/timelog_controller.rb index 68c0edefa..1a1bace3a 100644 --- a/app/controllers/timelog_controller.rb +++ b/app/controllers/timelog_controller.rb @@ -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) diff --git a/app/controllers/welcome_controller.rb b/app/controllers/welcome_controller.rb index 2eac2268f..b4be7fb1c 100644 --- a/app/controllers/welcome_controller.rb +++ b/app/controllers/welcome_controller.rb @@ -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 diff --git a/app/controllers/wiki_controller.rb b/app/controllers/wiki_controller.rb index 7609323f4..37a36bf56 100644 --- a/app/controllers/wiki_controller.rb +++ b/app/controllers/wiki_controller.rb @@ -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 diff --git a/app/models/attachment.rb b/app/models/attachment.rb index d2bcab33f..7262498c4 100644 --- a/app/models/attachment.rb +++ b/app/models/attachment.rb @@ -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 diff --git a/app/models/query.rb b/app/models/query.rb index 30df55b96..f869f648b 100644 --- a/app/models/query.rb +++ b/app/models/query.rb @@ -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 diff --git a/app/models/user.rb b/app/models/user.rb index 2543bed19..93b73dd7a 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -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 + + 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 - def time_zone - nil - 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 diff --git a/app/views/news/show.rhtml b/app/views/news/show.rhtml index ef5bbcd4c..2b51c1fee 100644 --- a/app/views/news/show.rhtml +++ b/app/views/news/show.rhtml @@ -26,7 +26,7 @@

<%= l(:label_comment_plural) %>

<% @news.comments.each do |comment| %> <% next if comment.new_record? %> -

<%= format_time(comment.created_on) %> - <%= comment.author.name %>

+

<%= authoring comment.created_on, comment.author %>

<%= 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' %>
diff --git a/db/migrate/080_add_users_type.rb b/db/migrate/080_add_users_type.rb new file mode 100644 index 000000000..c907b472e --- /dev/null +++ b/db/migrate/080_add_users_type.rb @@ -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 diff --git a/lib/redmine.rb b/lib/redmine.rb index 959cfc0c8..8a79b265a 100644 --- a/lib/redmine.rb +++ b/lib/redmine.rb @@ -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 diff --git a/test/unit/user_test.rb b/test/unit/user_test.rb index 82cbbdaa7..9f58d278f 100644 --- a/test/unit/user_test.rb +++ b/test/unit/user_test.rb @@ -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