##// END OF EJS Templates
Add User#allowed_to_globally? which wraps User#allowed_to?...
Eric Davis -
r4050:6a76aef37520
parent child
Show More
@@ -1,410 +1,416
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2009 Jean-Philippe Lang
2 # Copyright (C) 2006-2009 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 require "digest/sha1"
18 require "digest/sha1"
19
19
20 class User < Principal
20 class User < Principal
21
21
22 # Account statuses
22 # Account statuses
23 STATUS_ANONYMOUS = 0
23 STATUS_ANONYMOUS = 0
24 STATUS_ACTIVE = 1
24 STATUS_ACTIVE = 1
25 STATUS_REGISTERED = 2
25 STATUS_REGISTERED = 2
26 STATUS_LOCKED = 3
26 STATUS_LOCKED = 3
27
27
28 USER_FORMATS = {
28 USER_FORMATS = {
29 :firstname_lastname => '#{firstname} #{lastname}',
29 :firstname_lastname => '#{firstname} #{lastname}',
30 :firstname => '#{firstname}',
30 :firstname => '#{firstname}',
31 :lastname_firstname => '#{lastname} #{firstname}',
31 :lastname_firstname => '#{lastname} #{firstname}',
32 :lastname_coma_firstname => '#{lastname}, #{firstname}',
32 :lastname_coma_firstname => '#{lastname}, #{firstname}',
33 :username => '#{login}'
33 :username => '#{login}'
34 }
34 }
35
35
36 has_and_belongs_to_many :groups, :after_add => Proc.new {|user, group| group.user_added(user)},
36 has_and_belongs_to_many :groups, :after_add => Proc.new {|user, group| group.user_added(user)},
37 :after_remove => Proc.new {|user, group| group.user_removed(user)}
37 :after_remove => Proc.new {|user, group| group.user_removed(user)}
38 has_many :issue_categories, :foreign_key => 'assigned_to_id', :dependent => :nullify
38 has_many :issue_categories, :foreign_key => 'assigned_to_id', :dependent => :nullify
39 has_many :changesets, :dependent => :nullify
39 has_many :changesets, :dependent => :nullify
40 has_one :preference, :dependent => :destroy, :class_name => 'UserPreference'
40 has_one :preference, :dependent => :destroy, :class_name => 'UserPreference'
41 has_one :rss_token, :dependent => :destroy, :class_name => 'Token', :conditions => "action='feeds'"
41 has_one :rss_token, :dependent => :destroy, :class_name => 'Token', :conditions => "action='feeds'"
42 has_one :api_token, :dependent => :destroy, :class_name => 'Token', :conditions => "action='api'"
42 has_one :api_token, :dependent => :destroy, :class_name => 'Token', :conditions => "action='api'"
43 belongs_to :auth_source
43 belongs_to :auth_source
44
44
45 # Active non-anonymous users scope
45 # Active non-anonymous users scope
46 named_scope :active, :conditions => "#{User.table_name}.status = #{STATUS_ACTIVE}"
46 named_scope :active, :conditions => "#{User.table_name}.status = #{STATUS_ACTIVE}"
47
47
48 acts_as_customizable
48 acts_as_customizable
49
49
50 attr_accessor :password, :password_confirmation
50 attr_accessor :password, :password_confirmation
51 attr_accessor :last_before_login_on
51 attr_accessor :last_before_login_on
52 # Prevents unauthorized assignments
52 # Prevents unauthorized assignments
53 attr_protected :login, :admin, :password, :password_confirmation, :hashed_password, :group_ids
53 attr_protected :login, :admin, :password, :password_confirmation, :hashed_password, :group_ids
54
54
55 validates_presence_of :login, :firstname, :lastname, :mail, :if => Proc.new { |user| !user.is_a?(AnonymousUser) }
55 validates_presence_of :login, :firstname, :lastname, :mail, :if => Proc.new { |user| !user.is_a?(AnonymousUser) }
56 validates_uniqueness_of :login, :if => Proc.new { |user| !user.login.blank? }, :case_sensitive => false
56 validates_uniqueness_of :login, :if => Proc.new { |user| !user.login.blank? }, :case_sensitive => false
57 validates_uniqueness_of :mail, :if => Proc.new { |user| !user.mail.blank? }, :case_sensitive => false
57 validates_uniqueness_of :mail, :if => Proc.new { |user| !user.mail.blank? }, :case_sensitive => false
58 # Login must contain lettres, numbers, underscores only
58 # Login must contain lettres, numbers, underscores only
59 validates_format_of :login, :with => /^[a-z0-9_\-@\.]*$/i
59 validates_format_of :login, :with => /^[a-z0-9_\-@\.]*$/i
60 validates_length_of :login, :maximum => 30
60 validates_length_of :login, :maximum => 30
61 validates_format_of :firstname, :lastname, :with => /^[\w\s\'\-\.]*$/i
61 validates_format_of :firstname, :lastname, :with => /^[\w\s\'\-\.]*$/i
62 validates_length_of :firstname, :lastname, :maximum => 30
62 validates_length_of :firstname, :lastname, :maximum => 30
63 validates_format_of :mail, :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i, :allow_nil => true
63 validates_format_of :mail, :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i, :allow_nil => true
64 validates_length_of :mail, :maximum => 60, :allow_nil => true
64 validates_length_of :mail, :maximum => 60, :allow_nil => true
65 validates_confirmation_of :password, :allow_nil => true
65 validates_confirmation_of :password, :allow_nil => true
66
66
67 def before_create
67 def before_create
68 self.mail_notification = false
68 self.mail_notification = false
69 true
69 true
70 end
70 end
71
71
72 def before_save
72 def before_save
73 # update hashed_password if password was set
73 # update hashed_password if password was set
74 self.hashed_password = User.hash_password(self.password) if self.password && self.auth_source_id.blank?
74 self.hashed_password = User.hash_password(self.password) if self.password && self.auth_source_id.blank?
75 end
75 end
76
76
77 def reload(*args)
77 def reload(*args)
78 @name = nil
78 @name = nil
79 super
79 super
80 end
80 end
81
81
82 def mail=(arg)
82 def mail=(arg)
83 write_attribute(:mail, arg.to_s.strip)
83 write_attribute(:mail, arg.to_s.strip)
84 end
84 end
85
85
86 def identity_url=(url)
86 def identity_url=(url)
87 if url.blank?
87 if url.blank?
88 write_attribute(:identity_url, '')
88 write_attribute(:identity_url, '')
89 else
89 else
90 begin
90 begin
91 write_attribute(:identity_url, OpenIdAuthentication.normalize_identifier(url))
91 write_attribute(:identity_url, OpenIdAuthentication.normalize_identifier(url))
92 rescue OpenIdAuthentication::InvalidOpenId
92 rescue OpenIdAuthentication::InvalidOpenId
93 # Invlaid url, don't save
93 # Invlaid url, don't save
94 end
94 end
95 end
95 end
96 self.read_attribute(:identity_url)
96 self.read_attribute(:identity_url)
97 end
97 end
98
98
99 # Returns the user that matches provided login and password, or nil
99 # Returns the user that matches provided login and password, or nil
100 def self.try_to_login(login, password)
100 def self.try_to_login(login, password)
101 # Make sure no one can sign in with an empty password
101 # Make sure no one can sign in with an empty password
102 return nil if password.to_s.empty?
102 return nil if password.to_s.empty?
103 user = find_by_login(login)
103 user = find_by_login(login)
104 if user
104 if user
105 # user is already in local database
105 # user is already in local database
106 return nil if !user.active?
106 return nil if !user.active?
107 if user.auth_source
107 if user.auth_source
108 # user has an external authentication method
108 # user has an external authentication method
109 return nil unless user.auth_source.authenticate(login, password)
109 return nil unless user.auth_source.authenticate(login, password)
110 else
110 else
111 # authentication with local password
111 # authentication with local password
112 return nil unless User.hash_password(password) == user.hashed_password
112 return nil unless User.hash_password(password) == user.hashed_password
113 end
113 end
114 else
114 else
115 # user is not yet registered, try to authenticate with available sources
115 # user is not yet registered, try to authenticate with available sources
116 attrs = AuthSource.authenticate(login, password)
116 attrs = AuthSource.authenticate(login, password)
117 if attrs
117 if attrs
118 user = new(attrs)
118 user = new(attrs)
119 user.login = login
119 user.login = login
120 user.language = Setting.default_language
120 user.language = Setting.default_language
121 if user.save
121 if user.save
122 user.reload
122 user.reload
123 logger.info("User '#{user.login}' created from external auth source: #{user.auth_source.type} - #{user.auth_source.name}") if logger && user.auth_source
123 logger.info("User '#{user.login}' created from external auth source: #{user.auth_source.type} - #{user.auth_source.name}") if logger && user.auth_source
124 end
124 end
125 end
125 end
126 end
126 end
127 user.update_attribute(:last_login_on, Time.now) if user && !user.new_record?
127 user.update_attribute(:last_login_on, Time.now) if user && !user.new_record?
128 user
128 user
129 rescue => text
129 rescue => text
130 raise text
130 raise text
131 end
131 end
132
132
133 # Returns the user who matches the given autologin +key+ or nil
133 # Returns the user who matches the given autologin +key+ or nil
134 def self.try_to_autologin(key)
134 def self.try_to_autologin(key)
135 tokens = Token.find_all_by_action_and_value('autologin', key)
135 tokens = Token.find_all_by_action_and_value('autologin', key)
136 # Make sure there's only 1 token that matches the key
136 # Make sure there's only 1 token that matches the key
137 if tokens.size == 1
137 if tokens.size == 1
138 token = tokens.first
138 token = tokens.first
139 if (token.created_on > Setting.autologin.to_i.day.ago) && token.user && token.user.active?
139 if (token.created_on > Setting.autologin.to_i.day.ago) && token.user && token.user.active?
140 token.user.update_attribute(:last_login_on, Time.now)
140 token.user.update_attribute(:last_login_on, Time.now)
141 token.user
141 token.user
142 end
142 end
143 end
143 end
144 end
144 end
145
145
146 # Return user's full name for display
146 # Return user's full name for display
147 def name(formatter = nil)
147 def name(formatter = nil)
148 if formatter
148 if formatter
149 eval('"' + (USER_FORMATS[formatter] || USER_FORMATS[:firstname_lastname]) + '"')
149 eval('"' + (USER_FORMATS[formatter] || USER_FORMATS[:firstname_lastname]) + '"')
150 else
150 else
151 @name ||= eval('"' + (USER_FORMATS[Setting.user_format] || USER_FORMATS[:firstname_lastname]) + '"')
151 @name ||= eval('"' + (USER_FORMATS[Setting.user_format] || USER_FORMATS[:firstname_lastname]) + '"')
152 end
152 end
153 end
153 end
154
154
155 def active?
155 def active?
156 self.status == STATUS_ACTIVE
156 self.status == STATUS_ACTIVE
157 end
157 end
158
158
159 def registered?
159 def registered?
160 self.status == STATUS_REGISTERED
160 self.status == STATUS_REGISTERED
161 end
161 end
162
162
163 def locked?
163 def locked?
164 self.status == STATUS_LOCKED
164 self.status == STATUS_LOCKED
165 end
165 end
166
166
167 def activate
167 def activate
168 self.status = STATUS_ACTIVE
168 self.status = STATUS_ACTIVE
169 end
169 end
170
170
171 def register
171 def register
172 self.status = STATUS_REGISTERED
172 self.status = STATUS_REGISTERED
173 end
173 end
174
174
175 def lock
175 def lock
176 self.status = STATUS_LOCKED
176 self.status = STATUS_LOCKED
177 end
177 end
178
178
179 def activate!
179 def activate!
180 update_attribute(:status, STATUS_ACTIVE)
180 update_attribute(:status, STATUS_ACTIVE)
181 end
181 end
182
182
183 def register!
183 def register!
184 update_attribute(:status, STATUS_REGISTERED)
184 update_attribute(:status, STATUS_REGISTERED)
185 end
185 end
186
186
187 def lock!
187 def lock!
188 update_attribute(:status, STATUS_LOCKED)
188 update_attribute(:status, STATUS_LOCKED)
189 end
189 end
190
190
191 def check_password?(clear_password)
191 def check_password?(clear_password)
192 if auth_source_id.present?
192 if auth_source_id.present?
193 auth_source.authenticate(self.login, clear_password)
193 auth_source.authenticate(self.login, clear_password)
194 else
194 else
195 User.hash_password(clear_password) == self.hashed_password
195 User.hash_password(clear_password) == self.hashed_password
196 end
196 end
197 end
197 end
198
198
199 # Does the backend storage allow this user to change their password?
199 # Does the backend storage allow this user to change their password?
200 def change_password_allowed?
200 def change_password_allowed?
201 return true if auth_source_id.blank?
201 return true if auth_source_id.blank?
202 return auth_source.allow_password_changes?
202 return auth_source.allow_password_changes?
203 end
203 end
204
204
205 # Generate and set a random password. Useful for automated user creation
205 # Generate and set a random password. Useful for automated user creation
206 # Based on Token#generate_token_value
206 # Based on Token#generate_token_value
207 #
207 #
208 def random_password
208 def random_password
209 chars = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a
209 chars = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a
210 password = ''
210 password = ''
211 40.times { |i| password << chars[rand(chars.size-1)] }
211 40.times { |i| password << chars[rand(chars.size-1)] }
212 self.password = password
212 self.password = password
213 self.password_confirmation = password
213 self.password_confirmation = password
214 self
214 self
215 end
215 end
216
216
217 def pref
217 def pref
218 self.preference ||= UserPreference.new(:user => self)
218 self.preference ||= UserPreference.new(:user => self)
219 end
219 end
220
220
221 def time_zone
221 def time_zone
222 @time_zone ||= (self.pref.time_zone.blank? ? nil : ActiveSupport::TimeZone[self.pref.time_zone])
222 @time_zone ||= (self.pref.time_zone.blank? ? nil : ActiveSupport::TimeZone[self.pref.time_zone])
223 end
223 end
224
224
225 def wants_comments_in_reverse_order?
225 def wants_comments_in_reverse_order?
226 self.pref[:comments_sorting] == 'desc'
226 self.pref[:comments_sorting] == 'desc'
227 end
227 end
228
228
229 # Return user's RSS key (a 40 chars long string), used to access feeds
229 # Return user's RSS key (a 40 chars long string), used to access feeds
230 def rss_key
230 def rss_key
231 token = self.rss_token || Token.create(:user => self, :action => 'feeds')
231 token = self.rss_token || Token.create(:user => self, :action => 'feeds')
232 token.value
232 token.value
233 end
233 end
234
234
235 # Return user's API key (a 40 chars long string), used to access the API
235 # Return user's API key (a 40 chars long string), used to access the API
236 def api_key
236 def api_key
237 token = self.api_token || self.create_api_token(:action => 'api')
237 token = self.api_token || self.create_api_token(:action => 'api')
238 token.value
238 token.value
239 end
239 end
240
240
241 # Return an array of project ids for which the user has explicitly turned mail notifications on
241 # Return an array of project ids for which the user has explicitly turned mail notifications on
242 def notified_projects_ids
242 def notified_projects_ids
243 @notified_projects_ids ||= memberships.select {|m| m.mail_notification?}.collect(&:project_id)
243 @notified_projects_ids ||= memberships.select {|m| m.mail_notification?}.collect(&:project_id)
244 end
244 end
245
245
246 def notified_project_ids=(ids)
246 def notified_project_ids=(ids)
247 Member.update_all("mail_notification = #{connection.quoted_false}", ['user_id = ?', id])
247 Member.update_all("mail_notification = #{connection.quoted_false}", ['user_id = ?', id])
248 Member.update_all("mail_notification = #{connection.quoted_true}", ['user_id = ? AND project_id IN (?)', id, ids]) if ids && !ids.empty?
248 Member.update_all("mail_notification = #{connection.quoted_true}", ['user_id = ? AND project_id IN (?)', id, ids]) if ids && !ids.empty?
249 @notified_projects_ids = nil
249 @notified_projects_ids = nil
250 notified_projects_ids
250 notified_projects_ids
251 end
251 end
252
252
253 # Find a user account by matching the exact login and then a case-insensitive
253 # Find a user account by matching the exact login and then a case-insensitive
254 # version. Exact matches will be given priority.
254 # version. Exact matches will be given priority.
255 def self.find_by_login(login)
255 def self.find_by_login(login)
256 # force string comparison to be case sensitive on MySQL
256 # force string comparison to be case sensitive on MySQL
257 type_cast = (ActiveRecord::Base.connection.adapter_name == 'MySQL') ? 'BINARY' : ''
257 type_cast = (ActiveRecord::Base.connection.adapter_name == 'MySQL') ? 'BINARY' : ''
258
258
259 # First look for an exact match
259 # First look for an exact match
260 user = first(:conditions => ["#{type_cast} login = ?", login])
260 user = first(:conditions => ["#{type_cast} login = ?", login])
261 # Fail over to case-insensitive if none was found
261 # Fail over to case-insensitive if none was found
262 user ||= first(:conditions => ["#{type_cast} LOWER(login) = ?", login.to_s.downcase])
262 user ||= first(:conditions => ["#{type_cast} LOWER(login) = ?", login.to_s.downcase])
263 end
263 end
264
264
265 def self.find_by_rss_key(key)
265 def self.find_by_rss_key(key)
266 token = Token.find_by_value(key)
266 token = Token.find_by_value(key)
267 token && token.user.active? ? token.user : nil
267 token && token.user.active? ? token.user : nil
268 end
268 end
269
269
270 def self.find_by_api_key(key)
270 def self.find_by_api_key(key)
271 token = Token.find_by_action_and_value('api', key)
271 token = Token.find_by_action_and_value('api', key)
272 token && token.user.active? ? token.user : nil
272 token && token.user.active? ? token.user : nil
273 end
273 end
274
274
275 # Makes find_by_mail case-insensitive
275 # Makes find_by_mail case-insensitive
276 def self.find_by_mail(mail)
276 def self.find_by_mail(mail)
277 find(:first, :conditions => ["LOWER(mail) = ?", mail.to_s.downcase])
277 find(:first, :conditions => ["LOWER(mail) = ?", mail.to_s.downcase])
278 end
278 end
279
279
280 def to_s
280 def to_s
281 name
281 name
282 end
282 end
283
283
284 # Returns the current day according to user's time zone
284 # Returns the current day according to user's time zone
285 def today
285 def today
286 if time_zone.nil?
286 if time_zone.nil?
287 Date.today
287 Date.today
288 else
288 else
289 Time.now.in_time_zone(time_zone).to_date
289 Time.now.in_time_zone(time_zone).to_date
290 end
290 end
291 end
291 end
292
292
293 def logged?
293 def logged?
294 true
294 true
295 end
295 end
296
296
297 def anonymous?
297 def anonymous?
298 !logged?
298 !logged?
299 end
299 end
300
300
301 # Return user's roles for project
301 # Return user's roles for project
302 def roles_for_project(project)
302 def roles_for_project(project)
303 roles = []
303 roles = []
304 # No role on archived projects
304 # No role on archived projects
305 return roles unless project && project.active?
305 return roles unless project && project.active?
306 if logged?
306 if logged?
307 # Find project membership
307 # Find project membership
308 membership = memberships.detect {|m| m.project_id == project.id}
308 membership = memberships.detect {|m| m.project_id == project.id}
309 if membership
309 if membership
310 roles = membership.roles
310 roles = membership.roles
311 else
311 else
312 @role_non_member ||= Role.non_member
312 @role_non_member ||= Role.non_member
313 roles << @role_non_member
313 roles << @role_non_member
314 end
314 end
315 else
315 else
316 @role_anonymous ||= Role.anonymous
316 @role_anonymous ||= Role.anonymous
317 roles << @role_anonymous
317 roles << @role_anonymous
318 end
318 end
319 roles
319 roles
320 end
320 end
321
321
322 # Return true if the user is a member of project
322 # Return true if the user is a member of project
323 def member_of?(project)
323 def member_of?(project)
324 !roles_for_project(project).detect {|role| role.member?}.nil?
324 !roles_for_project(project).detect {|role| role.member?}.nil?
325 end
325 end
326
326
327 # Return true if the user is allowed to do the specified action on project
327 # Return true if the user is allowed to do the specified action on project
328 # action can be:
328 # action can be:
329 # * a parameter-like Hash (eg. :controller => 'projects', :action => 'edit')
329 # * a parameter-like Hash (eg. :controller => 'projects', :action => 'edit')
330 # * a permission Symbol (eg. :edit_project)
330 # * a permission Symbol (eg. :edit_project)
331 def allowed_to?(action, project, options={})
331 def allowed_to?(action, project, options={})
332 if project
332 if project
333 # No action allowed on archived projects
333 # No action allowed on archived projects
334 return false unless project.active?
334 return false unless project.active?
335 # No action allowed on disabled modules
335 # No action allowed on disabled modules
336 return false unless project.allows_to?(action)
336 return false unless project.allows_to?(action)
337 # Admin users are authorized for anything else
337 # Admin users are authorized for anything else
338 return true if admin?
338 return true if admin?
339
339
340 roles = roles_for_project(project)
340 roles = roles_for_project(project)
341 return false unless roles
341 return false unless roles
342 roles.detect {|role| (project.is_public? || role.member?) && role.allowed_to?(action)}
342 roles.detect {|role| (project.is_public? || role.member?) && role.allowed_to?(action)}
343
343
344 elsif options[:global]
344 elsif options[:global]
345 # Admin users are always authorized
345 # Admin users are always authorized
346 return true if admin?
346 return true if admin?
347
347
348 # authorize if user has at least one role that has this permission
348 # authorize if user has at least one role that has this permission
349 roles = memberships.collect {|m| m.roles}.flatten.uniq
349 roles = memberships.collect {|m| m.roles}.flatten.uniq
350 roles.detect {|r| r.allowed_to?(action)} || (self.logged? ? Role.non_member.allowed_to?(action) : Role.anonymous.allowed_to?(action))
350 roles.detect {|r| r.allowed_to?(action)} || (self.logged? ? Role.non_member.allowed_to?(action) : Role.anonymous.allowed_to?(action))
351 else
351 else
352 false
352 false
353 end
353 end
354 end
354 end
355
356 # Is the user allowed to do the specified action on any project?
357 # See allowed_to? for the actions and valid options.
358 def allowed_to_globally?(action, options)
359 allowed_to?(action, nil, options.reverse_merge(:global => true))
360 end
355
361
356 def self.current=(user)
362 def self.current=(user)
357 @current_user = user
363 @current_user = user
358 end
364 end
359
365
360 def self.current
366 def self.current
361 @current_user ||= User.anonymous
367 @current_user ||= User.anonymous
362 end
368 end
363
369
364 # Returns the anonymous user. If the anonymous user does not exist, it is created. There can be only
370 # Returns the anonymous user. If the anonymous user does not exist, it is created. There can be only
365 # one anonymous user per database.
371 # one anonymous user per database.
366 def self.anonymous
372 def self.anonymous
367 anonymous_user = AnonymousUser.find(:first)
373 anonymous_user = AnonymousUser.find(:first)
368 if anonymous_user.nil?
374 if anonymous_user.nil?
369 anonymous_user = AnonymousUser.create(:lastname => 'Anonymous', :firstname => '', :mail => '', :login => '', :status => 0)
375 anonymous_user = AnonymousUser.create(:lastname => 'Anonymous', :firstname => '', :mail => '', :login => '', :status => 0)
370 raise 'Unable to create the anonymous user.' if anonymous_user.new_record?
376 raise 'Unable to create the anonymous user.' if anonymous_user.new_record?
371 end
377 end
372 anonymous_user
378 anonymous_user
373 end
379 end
374
380
375 protected
381 protected
376
382
377 def validate
383 def validate
378 # Password length validation based on setting
384 # Password length validation based on setting
379 if !password.nil? && password.size < Setting.password_min_length.to_i
385 if !password.nil? && password.size < Setting.password_min_length.to_i
380 errors.add(:password, :too_short, :count => Setting.password_min_length.to_i)
386 errors.add(:password, :too_short, :count => Setting.password_min_length.to_i)
381 end
387 end
382 end
388 end
383
389
384 private
390 private
385
391
386 # Return password digest
392 # Return password digest
387 def self.hash_password(clear_password)
393 def self.hash_password(clear_password)
388 Digest::SHA1.hexdigest(clear_password || "")
394 Digest::SHA1.hexdigest(clear_password || "")
389 end
395 end
390 end
396 end
391
397
392 class AnonymousUser < User
398 class AnonymousUser < User
393
399
394 def validate_on_create
400 def validate_on_create
395 # There should be only one AnonymousUser in the database
401 # There should be only one AnonymousUser in the database
396 errors.add_to_base 'An anonymous user already exists.' if AnonymousUser.find(:first)
402 errors.add_to_base 'An anonymous user already exists.' if AnonymousUser.find(:first)
397 end
403 end
398
404
399 def available_custom_fields
405 def available_custom_fields
400 []
406 []
401 end
407 end
402
408
403 # Overrides a few properties
409 # Overrides a few properties
404 def logged?; false end
410 def logged?; false end
405 def admin; false end
411 def admin; false end
406 def name(*args); I18n.t(:label_user_anonymous) end
412 def name(*args); I18n.t(:label_user_anonymous) end
407 def mail; nil end
413 def mail; nil end
408 def time_zone; nil end
414 def time_zone; nil end
409 def rss_key; nil end
415 def rss_key; nil end
410 end
416 end
General Comments 0
You need to be logged in to leave comments. Login now