##// END OF EJS Templates
Anonymous users can now be allowed to create, edit, comment issues, comment news and post messages in the forums....
Jean-Philippe Lang -
r906:987a5aa22114
parent child
Show More
@@ -0,0 +1,10
1 class AddUsersType < ActiveRecord::Migration
2 def self.up
3 add_column :users, :type, :string
4 User.update_all "type = 'User'"
5 end
6
7 def self.down
8 remove_column :users, :type
9 end
10 end
@@ -23,10 +23,6 class ApplicationController < ActionController::Base
23 23 require_dependency "repository/#{scm.underscore}"
24 24 end
25 25
26 def logged_in_user
27 User.current.logged? ? User.current : nil
28 end
29
30 26 def current_role
31 27 @current_role ||= User.current.role_for_project(@project)
32 28 end
@@ -49,7 +49,7 class DocumentsController < ApplicationController
49 49 @attachments = []
50 50 params[:attachments].each { |file|
51 51 next unless file.size > 0
52 a = Attachment.create(:container => @document, :file => file, :author => logged_in_user)
52 a = Attachment.create(:container => @document, :file => file, :author => User.current)
53 53 @attachments << a unless a.new_record?
54 54 } if params[:attachments] and params[:attachments].is_a? Array
55 55 Mailer.deliver_attachments_added(@attachments) if !@attachments.empty? && Setting.notified_events.include?('document_added')
@@ -82,7 +82,7 class IssuesController < ApplicationController
82 82 def show
83 83 @custom_values = @issue.custom_values.find(:all, :include => :custom_field, :order => "#{CustomField.table_name}.position")
84 84 @journals = @issue.journals.find(:all, :include => [:user, :details], :order => "#{Journal.table_name}.created_on ASC")
85 @status_options = @issue.status.find_new_statuses_allowed_to(logged_in_user.role_for_project(@project), @issue.tracker) if logged_in_user
85 @status_options = @issue.status.find_new_statuses_allowed_to(User.current.role_for_project(@project), @issue.tracker)
86 86 respond_to do |format|
87 87 format.html { render :template => 'issues/show.rhtml' }
88 88 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
95 95 @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) }
96 96 else
97 97 begin
98 @issue.init_journal(self.logged_in_user)
98 @issue.init_journal(User.current)
99 99 # Retrieve custom fields and values
100 100 if params["custom_fields"]
101 101 @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
117 117 journal = @issue.init_journal(User.current, params[:notes])
118 118 params[:attachments].each { |file|
119 119 next unless file.size > 0
120 a = Attachment.create(:container => @issue, :file => file, :author => logged_in_user)
120 a = Attachment.create(:container => @issue, :file => file, :author => User.current)
121 121 journal.details << JournalDetail.new(:property => 'attachment',
122 122 :prop_key => a.id,
123 123 :value => a.filename) unless a.new_record?
@@ -132,17 +132,17 class IssuesController < ApplicationController
132 132 end
133 133
134 134 def change_status
135 @status_options = @issue.status.find_new_statuses_allowed_to(logged_in_user.role_for_project(@project), @issue.tracker) if logged_in_user
135 @status_options = @issue.status.find_new_statuses_allowed_to(User.current.role_for_project(@project), @issue.tracker)
136 136 @new_status = IssueStatus.find(params[:new_status_id])
137 137 if params[:confirm]
138 138 begin
139 journal = @issue.init_journal(self.logged_in_user, params[:notes])
139 journal = @issue.init_journal(User.current, params[:notes])
140 140 @issue.status = @new_status
141 141 if @issue.update_attributes(params[:issue])
142 142 # Save attachments
143 143 params[:attachments].each { |file|
144 144 next unless file.size > 0
145 a = Attachment.create(:container => @issue, :file => file, :author => logged_in_user)
145 a = Attachment.create(:container => @issue, :file => file, :author => User.current)
146 146 journal.details << JournalDetail.new(:property => 'attachment',
147 147 :prop_key => a.id,
148 148 :value => a.filename) unless a.new_record?
@@ -150,7 +150,7 class IssuesController < ApplicationController
150 150
151 151 # Log time
152 152 if current_role.allowed_to?(:log_time)
153 @time_entry ||= TimeEntry.new(:project => @project, :issue => @issue, :user => logged_in_user, :spent_on => Date.today)
153 @time_entry ||= TimeEntry.new(:project => @project, :issue => @issue, :user => User.current, :spent_on => Date.today)
154 154 @time_entry.attributes = params[:time_entry]
155 155 @time_entry.save
156 156 end
@@ -176,7 +176,7 class IssuesController < ApplicationController
176 176 def destroy_attachment
177 177 a = @issue.attachments.find(params[:attachment_id])
178 178 a.destroy
179 journal = @issue.init_journal(self.logged_in_user)
179 journal = @issue.init_journal(User.current)
180 180 journal.details << JournalDetail.new(:property => 'attachment',
181 181 :prop_key => a.id,
182 182 :old_value => a.filename)
@@ -225,12 +225,11 private
225 225 def retrieve_query
226 226 if params[:query_id]
227 227 @query = Query.find(params[:query_id], :conditions => {:project_id => (@project ? @project.id : nil)})
228 @query.executed_by = logged_in_user
229 228 session[:query] = @query
230 229 else
231 230 if params[:set_filter] or !session[:query] or session[:query].project != @project
232 231 # Give it a name, required to be valid
233 @query = Query.new(:name => "_", :executed_by => logged_in_user)
232 @query = Query.new(:name => "_")
234 233 @query.project = @project
235 234 if params[:fields] and params[:fields].is_a? Array
236 235 params[:fields].each do |field|
@@ -31,12 +31,12 class MessagesController < ApplicationController
31 31
32 32 def new
33 33 @message = Message.new(params[:message])
34 @message.author = logged_in_user
34 @message.author = User.current
35 35 @message.board = @board
36 36 if request.post? && @message.save
37 37 params[:attachments].each { |file|
38 38 next unless file.size > 0
39 Attachment.create(:container => @message, :file => file, :author => logged_in_user)
39 Attachment.create(:container => @message, :file => file, :author => User.current)
40 40 } if params[:attachments] and params[:attachments].is_a? Array
41 41 redirect_to :action => 'show', :id => @message
42 42 end
@@ -44,7 +44,7 class MessagesController < ApplicationController
44 44
45 45 def reply
46 46 @reply = Message.new(params[:reply])
47 @reply.author = logged_in_user
47 @reply.author = User.current
48 48 @reply.board = @board
49 49 @message.children << @reply
50 50 redirect_to :action => 'show', :id => @message
@@ -44,7 +44,7 class MyController < ApplicationController
44 44
45 45 # Show user's page
46 46 def page
47 @user = self.logged_in_user
47 @user = User.current
48 48 @blocks = @user.pref[:my_page_layout] || DEFAULT_LAYOUT
49 49 end
50 50
@@ -76,7 +76,7 class MyController < ApplicationController
76 76
77 77 # Manage user's password
78 78 def password
79 @user = self.logged_in_user
79 @user = User.current
80 80 flash[:error] = l(:notice_can_t_change_password) and redirect_to :action => 'account' and return if @user.auth_source_id
81 81 if request.post?
82 82 if @user.check_password?(params[:password])
@@ -102,7 +102,7 class MyController < ApplicationController
102 102
103 103 # User's page layout configuration
104 104 def page_layout
105 @user = self.logged_in_user
105 @user = User.current
106 106 @blocks = @user.pref[:my_page_layout] || DEFAULT_LAYOUT.dup
107 107 session[:page_layout] = @blocks
108 108 %w(top left right).each {|f| session[:page_layout][f] ||= [] }
@@ -116,7 +116,7 class MyController < ApplicationController
116 116 def add_block
117 117 block = params[:block]
118 118 render(:nothing => true) and return unless block && (BLOCKS.keys.include? block)
119 @user = self.logged_in_user
119 @user = User.current
120 120 # remove if already present in a group
121 121 %w(top left right).each {|f| (session[:page_layout][f] ||= []).delete block }
122 122 # add it on top
@@ -151,7 +151,7 class MyController < ApplicationController
151 151
152 152 # Save user's page layout
153 153 def page_layout_save
154 @user = self.logged_in_user
154 @user = User.current
155 155 @user.pref[:my_page_layout] = session[:page_layout] if session[:page_layout]
156 156 @user.pref.save
157 157 session[:page_layout] = nil
@@ -45,7 +45,7 class NewsController < ApplicationController
45 45
46 46 def add_comment
47 47 @comment = Comment.new(params[:comment])
48 @comment.author = logged_in_user
48 @comment.author = User.current
49 49 if @news.comments << @comment
50 50 flash[:notice] = l(:label_comment_added)
51 51 redirect_to :action => 'show', :id => @news
@@ -48,7 +48,7 class ProjectsController < ApplicationController
48 48 # Lists visible projects
49 49 def list
50 50 projects = Project.find :all,
51 :conditions => Project.visible_by(logged_in_user),
51 :conditions => Project.visible_by(User.current),
52 52 :include => :parent
53 53 @project_tree = projects.group_by {|p| p.parent || p}
54 54 @project_tree.each_key {|p| @project_tree[p] -= [p]}
@@ -176,7 +176,7 class ProjectsController < ApplicationController
176 176 if request.post? and @document.save
177 177 # Save the attachments
178 178 params[:attachments].each { |a|
179 Attachment.create(:container => @document, :file => a, :author => logged_in_user) unless a.size == 0
179 Attachment.create(:container => @document, :file => a, :author => User.current) unless a.size == 0
180 180 } if params[:attachments] and params[:attachments].is_a? Array
181 181 flash[:notice] = l(:notice_successful_create)
182 182 Mailer.deliver_document_added(@document) if Setting.notified_events.include?('document_added')
@@ -216,7 +216,7 class ProjectsController < ApplicationController
216 216 return
217 217 end
218 218 @issue.status = default_status
219 @allowed_statuses = ([default_status] + default_status.find_new_statuses_allowed_to(logged_in_user.role_for_project(@project), @issue.tracker))if logged_in_user
219 @allowed_statuses = ([default_status] + default_status.find_new_statuses_allowed_to(User.current.role_for_project(@project), @issue.tracker))
220 220
221 221 if request.get?
222 222 @issue.start_date ||= Date.today
@@ -321,10 +321,9 class ProjectsController < ApplicationController
321 321
322 322 # Add a news to @project
323 323 def add_news
324 @news = News.new(:project => @project)
324 @news = News.new(:project => @project, :author => User.current)
325 325 if request.post?
326 326 @news.attributes = params[:news]
327 @news.author_id = self.logged_in_user.id if self.logged_in_user
328 327 if @news.save
329 328 flash[:notice] = l(:notice_successful_create)
330 329 Mailer.deliver_news_added(@news) if Setting.notified_events.include?('news_added')
@@ -340,7 +339,7 class ProjectsController < ApplicationController
340 339 @attachments = []
341 340 params[:attachments].each { |file|
342 341 next unless file.size > 0
343 a = Attachment.create(:container => @version, :file => file, :author => logged_in_user)
342 a = Attachment.create(:container => @version, :file => file, :author => User.current)
344 343 @attachments << a unless a.new_record?
345 344 } if params[:attachments] and params[:attachments].is_a? Array
346 345 Mailer.deliver_attachments_added(@attachments) if !@attachments.empty? && Setting.notified_events.include?('file_added')
@@ -22,14 +22,13 class QueriesController < ApplicationController
22 22 def index
23 23 @queries = @project.queries.find(:all,
24 24 :order => "name ASC",
25 :conditions => ["is_public = ? or user_id = ?", true, (logged_in_user ? logged_in_user.id : 0)])
25 :conditions => ["is_public = ? or user_id = ?", true, (User.current.logged? ? User.current.id : 0)])
26 26 end
27 27
28 28 def new
29 29 @query = Query.new(params[:query])
30 30 @query.project = @project
31 @query.user = logged_in_user
32 @query.executed_by = logged_in_user
31 @query.user = User.current
33 32 @query.is_public = false unless current_role.allowed_to?(:manage_public_queries)
34 33 @query.column_names = nil if params[:default_columns]
35 34
@@ -71,9 +70,8 private
71 70 def find_project
72 71 if params[:id]
73 72 @query = Query.find(params[:id])
74 @query.executed_by = logged_in_user
75 73 @project = @query.project
76 render_403 unless @query.editable_by?(logged_in_user)
74 render_403 unless @query.editable_by?(User.current)
77 75 else
78 76 @project = Project.find(params[:project_id])
79 77 end
@@ -31,7 +31,7 class SearchController < ApplicationController
31 31 begin; offset = params[:offset].to_time if params[:offset]; rescue; end
32 32
33 33 # quick jump to an issue
34 if @question.match(/^#?(\d+)$/) && Issue.find_by_id($1, :include => :project, :conditions => Project.visible_by(logged_in_user))
34 if @question.match(/^#?(\d+)$/) && Issue.find_by_id($1, :include => :project, :conditions => Project.visible_by(User.current))
35 35 redirect_to :controller => "issues", :action => "show", :id => $1
36 36 return
37 37 end
@@ -87,7 +87,7 class SearchController < ApplicationController
87 87 end
88 88 else
89 89 operator = @all_words ? ' AND ' : ' OR '
90 Project.with_scope(:find => {:conditions => Project.visible_by(logged_in_user)}) do
90 Project.with_scope(:find => {:conditions => Project.visible_by(User.current)}) do
91 91 @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'
92 92 end
93 93 # if only one project is found, user is redirected to its overview
@@ -107,15 +107,15 class TimelogController < ApplicationController
107 107 @entries = (@issue ? @issue : @project).time_entries.find(:all, :include => [:activity, :user, {:issue => [:tracker, :assigned_to, :priority]}], :order => sort_clause)
108 108
109 109 @total_hours = @entries.inject(0) { |sum,entry| sum + entry.hours }
110 @owner_id = logged_in_user ? logged_in_user.id : 0
110 @owner_id = User.current.id
111 111
112 112 send_csv and return if 'csv' == params[:export]
113 113 render :action => 'details', :layout => false if request.xhr?
114 114 end
115 115
116 116 def edit
117 render_404 and return if @time_entry && @time_entry.user != logged_in_user
118 @time_entry ||= TimeEntry.new(:project => @project, :issue => @issue, :user => logged_in_user, :spent_on => Date.today)
117 render_404 and return if @time_entry && @time_entry.user != User.current
118 @time_entry ||= TimeEntry.new(:project => @project, :issue => @issue, :user => User.current, :spent_on => Date.today)
119 119 @time_entry.attributes = params[:time_entry]
120 120 if request.post? and @time_entry.save
121 121 flash[:notice] = l(:notice_successful_update)
@@ -19,7 +19,7 class WelcomeController < ApplicationController
19 19 layout 'base'
20 20
21 21 def index
22 @news = News.latest logged_in_user
23 @projects = Project.latest logged_in_user
22 @news = News.latest User.current
23 @projects = Project.latest User.current
24 24 end
25 25 end
@@ -69,7 +69,7 class WikiController < ApplicationController
69 69 #@content.text = params[:content][:text]
70 70 #@content.comments = params[:content][:comments]
71 71 @content.attributes = params[:content]
72 @content.author = logged_in_user
72 @content.author = User.current
73 73 # if page is new @page.save will also save content, but not if page isn't a new record
74 74 if (@page.new_record? ? @page.save : @content.save)
75 75 redirect_to :action => 'index', :id => @project, :page => @page.title
@@ -157,7 +157,7 class WikiController < ApplicationController
157 157 # Save the attachments
158 158 params[:attachments].each { |file|
159 159 next unless file.size > 0
160 a = Attachment.create(:container => @page, :file => file, :author => logged_in_user)
160 a = Attachment.create(:container => @page, :file => file, :author => User.current)
161 161 } if params[:attachments] and params[:attachments].is_a? Array
162 162 redirect_to :action => 'index', :page => @page.title
163 163 end
@@ -21,7 +21,7 class Attachment < ActiveRecord::Base
21 21 belongs_to :container, :polymorphic => true
22 22 belongs_to :author, :class_name => "User", :foreign_key => "author_id"
23 23
24 validates_presence_of :container, :filename
24 validates_presence_of :container, :filename, :author
25 25 validates_length_of :filename, :maximum => 255
26 26 validates_length_of :disk_filename, :maximum => 255
27 27
@@ -82,11 +82,6 class Attachment < ActiveRecord::Base
82 82 def increment_download
83 83 increment!(:downloads)
84 84 end
85
86 # returns last created projects
87 def self.most_downloaded
88 find(:all, :limit => 5, :order => "downloads DESC")
89 end
90 85
91 86 def project
92 87 container.is_a?(Project) ? container : container.project
@@ -112,11 +112,8 class Query < ActiveRecord::Base
112 112 def initialize(attributes = nil)
113 113 super attributes
114 114 self.filters ||= { 'status_id' => {:operator => "o", :values => [""]} }
115 end
116
117 def executed_by=(user)
118 @executed_by = user
119 set_language_if_valid(user.language) if user
115 @executed_by = User.current.logged? ? User.current : nil
116 set_language_if_valid(executed_by.language) if executed_by
120 117 end
121 118
122 119 def validate
@@ -19,6 +19,7 require "digest/sha1"
19 19
20 20 class User < ActiveRecord::Base
21 21 # Account statuses
22 STATUS_ANONYMOUS = 0
22 23 STATUS_ACTIVE = 1
23 24 STATUS_REGISTERED = 2
24 25 STATUS_LOCKED = 3
@@ -36,15 +37,15 class User < ActiveRecord::Base
36 37 # Prevents unauthorized assignments
37 38 attr_protected :login, :admin, :password, :password_confirmation, :hashed_password
38 39
39 validates_presence_of :login, :firstname, :lastname, :mail
40 validates_presence_of :login, :firstname, :lastname, :mail, :if => Proc.new { |user| !user.is_a?(AnonymousUser) }
40 41 validates_uniqueness_of :login, :mail
41 42 # Login must contain lettres, numbers, underscores only
42 validates_format_of :login, :with => /^[a-z0-9_\-@\.]+$/i
43 validates_format_of :login, :with => /^[a-z0-9_\-@\.]*$/i
43 44 validates_length_of :login, :maximum => 30
44 45 validates_format_of :firstname, :lastname, :with => /^[\w\s\'\-]*$/i
45 46 validates_length_of :firstname, :lastname, :maximum => 30
46 validates_format_of :mail, :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i
47 validates_length_of :mail, :maximum => 60
47 validates_format_of :mail, :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i, :allow_nil => true
48 validates_length_of :mail, :maximum => 60, :allow_nil => true
48 49 # Password length between 4 and 12
49 50 validates_length_of :password, :in => 4..12, :allow_nil => true
50 51 validates_confirmation_of :password, :allow_nil => true
@@ -216,11 +217,17 class User < ActiveRecord::Base
216 217 end
217 218
218 219 def self.current
219 @current_user ||= AnonymousUser.new
220 @current_user ||= User.anonymous
220 221 end
221 222
222 223 def self.anonymous
223 AnonymousUser.new
224 return @anonymous_user if @anonymous_user
225 anonymous_user = AnonymousUser.find(:first)
226 if anonymous_user.nil?
227 anonymous_user = AnonymousUser.create(:lastname => 'Anonymous', :firstname => '', :mail => '', :login => '', :status => 0)
228 raise 'Unable to create the anonymous user.' if anonymous_user.new_record?
229 end
230 @anonymous_user = anonymous_user
224 231 end
225 232
226 233 private
@@ -231,16 +238,17 private
231 238 end
232 239
233 240 class AnonymousUser < User
234 def logged?
235 false
236 end
237 241
238 def time_zone
239 nil
242 def validate_on_create
243 # There should be only one AnonymousUser in the database
244 errors.add_to_base 'An anonymous user already exists.' if AnonymousUser.find(:first)
240 245 end
241 246
242 # Anonymous user has no RSS key
243 def rss_key
244 nil
245 end
247 # Overrides a few properties
248 def logged?; false end
249 def admin; false end
250 def name; 'Anonymous' end
251 def mail; nil end
252 def time_zone; nil end
253 def rss_key; nil end
246 254 end
@@ -26,7 +26,7
26 26 <h3 class="icon22 icon22-comment"><%= l(:label_comment_plural) %></h3>
27 27 <% @news.comments.each do |comment| %>
28 28 <% next if comment.new_record? %>
29 <h4><%= format_time(comment.created_on) %> - <%= comment.author.name %></h4>
29 <h4><%= authoring comment.created_on, comment.author %></h4>
30 30 <div class="contextual">
31 31 <%= 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' %>
32 32 </div>
@@ -29,11 +29,11 Redmine::AccessControl.map do |map|
29 29 :issues => [:index, :changes, :show, :context_menu],
30 30 :queries => :index,
31 31 :reports => :issue_report}, :public => true
32 map.permission :add_issues, {:projects => :add_issue}, :require => :loggedin
32 map.permission :add_issues, {:projects => :add_issue}
33 33 map.permission :edit_issues, {:projects => :bulk_edit_issues,
34 :issues => [:edit, :destroy_attachment]}, :require => :loggedin
35 map.permission :manage_issue_relations, {:issue_relations => [:new, :destroy]}, :require => :loggedin
36 map.permission :add_issue_notes, {:issues => :add_note}, :require => :loggedin
34 :issues => [:edit, :destroy_attachment]}
35 map.permission :manage_issue_relations, {:issue_relations => [:new, :destroy]}
36 map.permission :add_issue_notes, {:issues => :add_note}
37 37 map.permission :change_issue_status, {:issues => :change_status}, :require => :loggedin
38 38 map.permission :move_issues, {:projects => :move_issues}, :require => :loggedin
39 39 map.permission :delete_issues, {:issues => :destroy}, :require => :member
@@ -53,7 +53,7 Redmine::AccessControl.map do |map|
53 53 map.project_module :news do |map|
54 54 map.permission :manage_news, {:projects => :add_news, :news => [:edit, :destroy, :destroy_comment]}, :require => :member
55 55 map.permission :view_news, {:news => [:index, :show]}, :public => true
56 map.permission :comment_news, {:news => :add_comment}, :require => :loggedin
56 map.permission :comment_news, {:news => :add_comment}
57 57 end
58 58
59 59 map.project_module :documents do |map|
@@ -83,7 +83,7 Redmine::AccessControl.map do |map|
83 83 map.project_module :boards do |map|
84 84 map.permission :manage_boards, {:boards => [:new, :edit, :destroy]}, :require => :member
85 85 map.permission :view_messages, {:boards => [:index, :show], :messages => [:show]}, :public => true
86 map.permission :add_messages, {:messages => [:new, :reply]}, :require => :loggedin
86 map.permission :add_messages, {:messages => [:new, :reply]}
87 87 end
88 88 end
89 89
@@ -60,7 +60,7 class UserTest < Test::Unit::TestCase
60 60 def test_validate
61 61 @admin.login = ""
62 62 assert !@admin.save
63 assert_equal 2, @admin.errors.count
63 assert_equal 1, @admin.errors.count
64 64 end
65 65
66 66 def test_password
@@ -87,6 +87,13 class UserTest < Test::Unit::TestCase
87 87 assert_equal nil, user
88 88 end
89 89
90 def test_create_anonymous
91 AnonymousUser.delete_all
92 anon = User.anonymous
93 assert !anon.new_record?
94 assert_kind_of AnonymousUser, anon
95 end
96
90 97 def test_rss_key
91 98 assert_nil @jsmith.rss_token
92 99 key = @jsmith.rss_key
General Comments 0
You need to be logged in to leave comments. Login now