##// END OF EJS Templates
Fixed: User#identity_url raises an error when invalid url is supplied (#2742)....
Jean-Philippe Lang -
r2415:d643d9a94c65
parent child
Show More
@@ -1,315 +1,319
1 # redMine - project management software
1 # redMine - project management software
2 # Copyright (C) 2006-2007 Jean-Philippe Lang
2 # Copyright (C) 2006-2007 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 < ActiveRecord::Base
20 class User < ActiveRecord::Base
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_many :memberships, :class_name => 'Member', :include => [ :project, :role ], :conditions => "#{Project.table_name}.status=#{Project::STATUS_ACTIVE}", :order => "#{Project.table_name}.name"
36 has_many :memberships, :class_name => 'Member', :include => [ :project, :role ], :conditions => "#{Project.table_name}.status=#{Project::STATUS_ACTIVE}", :order => "#{Project.table_name}.name"
37 has_many :members, :dependent => :delete_all
37 has_many :members, :dependent => :delete_all
38 has_many :projects, :through => :memberships
38 has_many :projects, :through => :memberships
39 has_many :issue_categories, :foreign_key => 'assigned_to_id', :dependent => :nullify
39 has_many :issue_categories, :foreign_key => 'assigned_to_id', :dependent => :nullify
40 has_many :changesets, :dependent => :nullify
40 has_many :changesets, :dependent => :nullify
41 has_one :preference, :dependent => :destroy, :class_name => 'UserPreference'
41 has_one :preference, :dependent => :destroy, :class_name => 'UserPreference'
42 has_one :rss_token, :dependent => :destroy, :class_name => 'Token', :conditions => "action='feeds'"
42 has_one :rss_token, :dependent => :destroy, :class_name => 'Token', :conditions => "action='feeds'"
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
53 attr_protected :login, :admin, :password, :password_confirmation, :hashed_password
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? }
56 validates_uniqueness_of :login, :if => Proc.new { |user| !user.login.blank? }
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_length_of :password, :minimum => 4, :allow_nil => true
65 validates_length_of :password, :minimum => 4, :allow_nil => true
66 validates_confirmation_of :password, :allow_nil => true
66 validates_confirmation_of :password, :allow_nil => true
67
67
68 def before_create
68 def before_create
69 self.mail_notification = false
69 self.mail_notification = false
70 true
70 true
71 end
71 end
72
72
73 def before_save
73 def before_save
74 # update hashed_password if password was set
74 # update hashed_password if password was set
75 self.hashed_password = User.hash_password(self.password) if self.password
75 self.hashed_password = User.hash_password(self.password) if self.password
76 end
76 end
77
77
78 def reload(*args)
78 def reload(*args)
79 @name = nil
79 @name = nil
80 super
80 super
81 end
81 end
82
82
83 def identity_url=(url)
83 def identity_url=(url)
84 begin
84 if url.blank?
85 self.write_attribute(:identity_url, OpenIdAuthentication.normalize_identifier(url))
85 write_attribute(:identity_url, '')
86 rescue InvalidOpenId
86 else
87 # Invlaid url, don't save
87 begin
88 write_attribute(:identity_url, OpenIdAuthentication.normalize_identifier(url))
89 rescue OpenIdAuthentication::InvalidOpenId
90 # Invlaid url, don't save
91 end
88 end
92 end
89 self.read_attribute(:identity_url)
93 self.read_attribute(:identity_url)
90 end
94 end
91
95
92 # Returns the user that matches provided login and password, or nil
96 # Returns the user that matches provided login and password, or nil
93 def self.try_to_login(login, password)
97 def self.try_to_login(login, password)
94 # Make sure no one can sign in with an empty password
98 # Make sure no one can sign in with an empty password
95 return nil if password.to_s.empty?
99 return nil if password.to_s.empty?
96 user = find(:first, :conditions => ["login=?", login])
100 user = find(:first, :conditions => ["login=?", login])
97 if user
101 if user
98 # user is already in local database
102 # user is already in local database
99 return nil if !user.active?
103 return nil if !user.active?
100 if user.auth_source
104 if user.auth_source
101 # user has an external authentication method
105 # user has an external authentication method
102 return nil unless user.auth_source.authenticate(login, password)
106 return nil unless user.auth_source.authenticate(login, password)
103 else
107 else
104 # authentication with local password
108 # authentication with local password
105 return nil unless User.hash_password(password) == user.hashed_password
109 return nil unless User.hash_password(password) == user.hashed_password
106 end
110 end
107 else
111 else
108 # user is not yet registered, try to authenticate with available sources
112 # user is not yet registered, try to authenticate with available sources
109 attrs = AuthSource.authenticate(login, password)
113 attrs = AuthSource.authenticate(login, password)
110 if attrs
114 if attrs
111 user = new(*attrs)
115 user = new(*attrs)
112 user.login = login
116 user.login = login
113 user.language = Setting.default_language
117 user.language = Setting.default_language
114 if user.save
118 if user.save
115 user.reload
119 user.reload
116 logger.info("User '#{user.login}' created from the LDAP") if logger
120 logger.info("User '#{user.login}' created from the LDAP") if logger
117 end
121 end
118 end
122 end
119 end
123 end
120 user.update_attribute(:last_login_on, Time.now) if user && !user.new_record?
124 user.update_attribute(:last_login_on, Time.now) if user && !user.new_record?
121 user
125 user
122 rescue => text
126 rescue => text
123 raise text
127 raise text
124 end
128 end
125
129
126 # Return user's full name for display
130 # Return user's full name for display
127 def name(formatter = nil)
131 def name(formatter = nil)
128 if formatter
132 if formatter
129 eval('"' + (USER_FORMATS[formatter] || USER_FORMATS[:firstname_lastname]) + '"')
133 eval('"' + (USER_FORMATS[formatter] || USER_FORMATS[:firstname_lastname]) + '"')
130 else
134 else
131 @name ||= eval('"' + (USER_FORMATS[Setting.user_format] || USER_FORMATS[:firstname_lastname]) + '"')
135 @name ||= eval('"' + (USER_FORMATS[Setting.user_format] || USER_FORMATS[:firstname_lastname]) + '"')
132 end
136 end
133 end
137 end
134
138
135 def active?
139 def active?
136 self.status == STATUS_ACTIVE
140 self.status == STATUS_ACTIVE
137 end
141 end
138
142
139 def registered?
143 def registered?
140 self.status == STATUS_REGISTERED
144 self.status == STATUS_REGISTERED
141 end
145 end
142
146
143 def locked?
147 def locked?
144 self.status == STATUS_LOCKED
148 self.status == STATUS_LOCKED
145 end
149 end
146
150
147 def check_password?(clear_password)
151 def check_password?(clear_password)
148 User.hash_password(clear_password) == self.hashed_password
152 User.hash_password(clear_password) == self.hashed_password
149 end
153 end
150
154
151 # Generate and set a random password. Useful for automated user creation
155 # Generate and set a random password. Useful for automated user creation
152 # Based on Token#generate_token_value
156 # Based on Token#generate_token_value
153 #
157 #
154 def random_password
158 def random_password
155 chars = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a
159 chars = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a
156 password = ''
160 password = ''
157 40.times { |i| password << chars[rand(chars.size-1)] }
161 40.times { |i| password << chars[rand(chars.size-1)] }
158 self.password = password
162 self.password = password
159 self.password_confirmation = password
163 self.password_confirmation = password
160 self
164 self
161 end
165 end
162
166
163 def pref
167 def pref
164 self.preference ||= UserPreference.new(:user => self)
168 self.preference ||= UserPreference.new(:user => self)
165 end
169 end
166
170
167 def time_zone
171 def time_zone
168 @time_zone ||= (self.pref.time_zone.blank? ? nil : ActiveSupport::TimeZone[self.pref.time_zone])
172 @time_zone ||= (self.pref.time_zone.blank? ? nil : ActiveSupport::TimeZone[self.pref.time_zone])
169 end
173 end
170
174
171 def wants_comments_in_reverse_order?
175 def wants_comments_in_reverse_order?
172 self.pref[:comments_sorting] == 'desc'
176 self.pref[:comments_sorting] == 'desc'
173 end
177 end
174
178
175 # Return user's RSS key (a 40 chars long string), used to access feeds
179 # Return user's RSS key (a 40 chars long string), used to access feeds
176 def rss_key
180 def rss_key
177 token = self.rss_token || Token.create(:user => self, :action => 'feeds')
181 token = self.rss_token || Token.create(:user => self, :action => 'feeds')
178 token.value
182 token.value
179 end
183 end
180
184
181 # Return an array of project ids for which the user has explicitly turned mail notifications on
185 # Return an array of project ids for which the user has explicitly turned mail notifications on
182 def notified_projects_ids
186 def notified_projects_ids
183 @notified_projects_ids ||= memberships.select {|m| m.mail_notification?}.collect(&:project_id)
187 @notified_projects_ids ||= memberships.select {|m| m.mail_notification?}.collect(&:project_id)
184 end
188 end
185
189
186 def notified_project_ids=(ids)
190 def notified_project_ids=(ids)
187 Member.update_all("mail_notification = #{connection.quoted_false}", ['user_id = ?', id])
191 Member.update_all("mail_notification = #{connection.quoted_false}", ['user_id = ?', id])
188 Member.update_all("mail_notification = #{connection.quoted_true}", ['user_id = ? AND project_id IN (?)', id, ids]) if ids && !ids.empty?
192 Member.update_all("mail_notification = #{connection.quoted_true}", ['user_id = ? AND project_id IN (?)', id, ids]) if ids && !ids.empty?
189 @notified_projects_ids = nil
193 @notified_projects_ids = nil
190 notified_projects_ids
194 notified_projects_ids
191 end
195 end
192
196
193 def self.find_by_rss_key(key)
197 def self.find_by_rss_key(key)
194 token = Token.find_by_value(key)
198 token = Token.find_by_value(key)
195 token && token.user.active? ? token.user : nil
199 token && token.user.active? ? token.user : nil
196 end
200 end
197
201
198 def self.find_by_autologin_key(key)
202 def self.find_by_autologin_key(key)
199 token = Token.find_by_action_and_value('autologin', key)
203 token = Token.find_by_action_and_value('autologin', key)
200 token && (token.created_on > Setting.autologin.to_i.day.ago) && token.user.active? ? token.user : nil
204 token && (token.created_on > Setting.autologin.to_i.day.ago) && token.user.active? ? token.user : nil
201 end
205 end
202
206
203 # Makes find_by_mail case-insensitive
207 # Makes find_by_mail case-insensitive
204 def self.find_by_mail(mail)
208 def self.find_by_mail(mail)
205 find(:first, :conditions => ["LOWER(mail) = ?", mail.to_s.downcase])
209 find(:first, :conditions => ["LOWER(mail) = ?", mail.to_s.downcase])
206 end
210 end
207
211
208 # Sort users by their display names
212 # Sort users by their display names
209 def <=>(user)
213 def <=>(user)
210 self.to_s.downcase <=> user.to_s.downcase
214 self.to_s.downcase <=> user.to_s.downcase
211 end
215 end
212
216
213 def to_s
217 def to_s
214 name
218 name
215 end
219 end
216
220
217 def logged?
221 def logged?
218 true
222 true
219 end
223 end
220
224
221 def anonymous?
225 def anonymous?
222 !logged?
226 !logged?
223 end
227 end
224
228
225 # Return user's role for project
229 # Return user's role for project
226 def role_for_project(project)
230 def role_for_project(project)
227 # No role on archived projects
231 # No role on archived projects
228 return nil unless project && project.active?
232 return nil unless project && project.active?
229 if logged?
233 if logged?
230 # Find project membership
234 # Find project membership
231 membership = memberships.detect {|m| m.project_id == project.id}
235 membership = memberships.detect {|m| m.project_id == project.id}
232 if membership
236 if membership
233 membership.role
237 membership.role
234 else
238 else
235 @role_non_member ||= Role.non_member
239 @role_non_member ||= Role.non_member
236 end
240 end
237 else
241 else
238 @role_anonymous ||= Role.anonymous
242 @role_anonymous ||= Role.anonymous
239 end
243 end
240 end
244 end
241
245
242 # Return true if the user is a member of project
246 # Return true if the user is a member of project
243 def member_of?(project)
247 def member_of?(project)
244 role_for_project(project).member?
248 role_for_project(project).member?
245 end
249 end
246
250
247 # Return true if the user is allowed to do the specified action on project
251 # Return true if the user is allowed to do the specified action on project
248 # action can be:
252 # action can be:
249 # * a parameter-like Hash (eg. :controller => 'projects', :action => 'edit')
253 # * a parameter-like Hash (eg. :controller => 'projects', :action => 'edit')
250 # * a permission Symbol (eg. :edit_project)
254 # * a permission Symbol (eg. :edit_project)
251 def allowed_to?(action, project, options={})
255 def allowed_to?(action, project, options={})
252 if project
256 if project
253 # No action allowed on archived projects
257 # No action allowed on archived projects
254 return false unless project.active?
258 return false unless project.active?
255 # No action allowed on disabled modules
259 # No action allowed on disabled modules
256 return false unless project.allows_to?(action)
260 return false unless project.allows_to?(action)
257 # Admin users are authorized for anything else
261 # Admin users are authorized for anything else
258 return true if admin?
262 return true if admin?
259
263
260 role = role_for_project(project)
264 role = role_for_project(project)
261 return false unless role
265 return false unless role
262 role.allowed_to?(action) && (project.is_public? || role.member?)
266 role.allowed_to?(action) && (project.is_public? || role.member?)
263
267
264 elsif options[:global]
268 elsif options[:global]
265 # authorize if user has at least one role that has this permission
269 # authorize if user has at least one role that has this permission
266 roles = memberships.collect {|m| m.role}.uniq
270 roles = memberships.collect {|m| m.role}.uniq
267 roles.detect {|r| r.allowed_to?(action)} || (self.logged? ? Role.non_member.allowed_to?(action) : Role.anonymous.allowed_to?(action))
271 roles.detect {|r| r.allowed_to?(action)} || (self.logged? ? Role.non_member.allowed_to?(action) : Role.anonymous.allowed_to?(action))
268 else
272 else
269 false
273 false
270 end
274 end
271 end
275 end
272
276
273 def self.current=(user)
277 def self.current=(user)
274 @current_user = user
278 @current_user = user
275 end
279 end
276
280
277 def self.current
281 def self.current
278 @current_user ||= User.anonymous
282 @current_user ||= User.anonymous
279 end
283 end
280
284
281 def self.anonymous
285 def self.anonymous
282 anonymous_user = AnonymousUser.find(:first)
286 anonymous_user = AnonymousUser.find(:first)
283 if anonymous_user.nil?
287 if anonymous_user.nil?
284 anonymous_user = AnonymousUser.create(:lastname => 'Anonymous', :firstname => '', :mail => '', :login => '', :status => 0)
288 anonymous_user = AnonymousUser.create(:lastname => 'Anonymous', :firstname => '', :mail => '', :login => '', :status => 0)
285 raise 'Unable to create the anonymous user.' if anonymous_user.new_record?
289 raise 'Unable to create the anonymous user.' if anonymous_user.new_record?
286 end
290 end
287 anonymous_user
291 anonymous_user
288 end
292 end
289
293
290 private
294 private
291 # Return password digest
295 # Return password digest
292 def self.hash_password(clear_password)
296 def self.hash_password(clear_password)
293 Digest::SHA1.hexdigest(clear_password || "")
297 Digest::SHA1.hexdigest(clear_password || "")
294 end
298 end
295 end
299 end
296
300
297 class AnonymousUser < User
301 class AnonymousUser < User
298
302
299 def validate_on_create
303 def validate_on_create
300 # There should be only one AnonymousUser in the database
304 # There should be only one AnonymousUser in the database
301 errors.add_to_base 'An anonymous user already exists.' if AnonymousUser.find(:first)
305 errors.add_to_base 'An anonymous user already exists.' if AnonymousUser.find(:first)
302 end
306 end
303
307
304 def available_custom_fields
308 def available_custom_fields
305 []
309 []
306 end
310 end
307
311
308 # Overrides a few properties
312 # Overrides a few properties
309 def logged?; false end
313 def logged?; false end
310 def admin; false end
314 def admin; false end
311 def name; 'Anonymous' end
315 def name; 'Anonymous' end
312 def mail; nil end
316 def mail; nil end
313 def time_zone; nil end
317 def time_zone; nil end
314 def rss_key; nil end
318 def rss_key; nil end
315 end
319 end
@@ -1,212 +1,223
1 # redMine - project management software
1 # redMine - project management software
2 # Copyright (C) 2006 Jean-Philippe Lang
2 # Copyright (C) 2006 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 File.dirname(__FILE__) + '/../test_helper'
18 require File.dirname(__FILE__) + '/../test_helper'
19
19
20 class UserTest < Test::Unit::TestCase
20 class UserTest < Test::Unit::TestCase
21 fixtures :users, :members, :projects
21 fixtures :users, :members, :projects
22
22
23 def setup
23 def setup
24 @admin = User.find(1)
24 @admin = User.find(1)
25 @jsmith = User.find(2)
25 @jsmith = User.find(2)
26 @dlopper = User.find(3)
26 @dlopper = User.find(3)
27 end
27 end
28
28
29 def test_truth
29 def test_truth
30 assert_kind_of User, @jsmith
30 assert_kind_of User, @jsmith
31 end
31 end
32
32
33 def test_create
33 def test_create
34 user = User.new(:firstname => "new", :lastname => "user", :mail => "newuser@somenet.foo")
34 user = User.new(:firstname => "new", :lastname => "user", :mail => "newuser@somenet.foo")
35
35
36 user.login = "jsmith"
36 user.login = "jsmith"
37 user.password, user.password_confirmation = "password", "password"
37 user.password, user.password_confirmation = "password", "password"
38 # login uniqueness
38 # login uniqueness
39 assert !user.save
39 assert !user.save
40 assert_equal 1, user.errors.count
40 assert_equal 1, user.errors.count
41
41
42 user.login = "newuser"
42 user.login = "newuser"
43 user.password, user.password_confirmation = "passwd", "password"
43 user.password, user.password_confirmation = "passwd", "password"
44 # password confirmation
44 # password confirmation
45 assert !user.save
45 assert !user.save
46 assert_equal 1, user.errors.count
46 assert_equal 1, user.errors.count
47
47
48 user.password, user.password_confirmation = "password", "password"
48 user.password, user.password_confirmation = "password", "password"
49 assert user.save
49 assert user.save
50 end
50 end
51
51
52 def test_mail_uniqueness_should_not_be_case_sensitive
52 def test_mail_uniqueness_should_not_be_case_sensitive
53 u = User.new(:firstname => "new", :lastname => "user", :mail => "newuser@somenet.foo")
53 u = User.new(:firstname => "new", :lastname => "user", :mail => "newuser@somenet.foo")
54 u.login = 'newuser1'
54 u.login = 'newuser1'
55 u.password, u.password_confirmation = "password", "password"
55 u.password, u.password_confirmation = "password", "password"
56 assert u.save
56 assert u.save
57
57
58 u = User.new(:firstname => "new", :lastname => "user", :mail => "newUser@Somenet.foo")
58 u = User.new(:firstname => "new", :lastname => "user", :mail => "newUser@Somenet.foo")
59 u.login = 'newuser2'
59 u.login = 'newuser2'
60 u.password, u.password_confirmation = "password", "password"
60 u.password, u.password_confirmation = "password", "password"
61 assert !u.save
61 assert !u.save
62 assert_equal 'activerecord_error_taken', u.errors.on(:mail)
62 assert_equal 'activerecord_error_taken', u.errors.on(:mail)
63 end
63 end
64
64
65 def test_update
65 def test_update
66 assert_equal "admin", @admin.login
66 assert_equal "admin", @admin.login
67 @admin.login = "john"
67 @admin.login = "john"
68 assert @admin.save, @admin.errors.full_messages.join("; ")
68 assert @admin.save, @admin.errors.full_messages.join("; ")
69 @admin.reload
69 @admin.reload
70 assert_equal "john", @admin.login
70 assert_equal "john", @admin.login
71 end
71 end
72
72
73 def test_destroy
73 def test_destroy
74 User.find(2).destroy
74 User.find(2).destroy
75 assert_nil User.find_by_id(2)
75 assert_nil User.find_by_id(2)
76 assert Member.find_all_by_user_id(2).empty?
76 assert Member.find_all_by_user_id(2).empty?
77 end
77 end
78
78
79 def test_validate
79 def test_validate
80 @admin.login = ""
80 @admin.login = ""
81 assert !@admin.save
81 assert !@admin.save
82 assert_equal 1, @admin.errors.count
82 assert_equal 1, @admin.errors.count
83 end
83 end
84
84
85 def test_password
85 def test_password
86 user = User.try_to_login("admin", "admin")
86 user = User.try_to_login("admin", "admin")
87 assert_kind_of User, user
87 assert_kind_of User, user
88 assert_equal "admin", user.login
88 assert_equal "admin", user.login
89 user.password = "hello"
89 user.password = "hello"
90 assert user.save
90 assert user.save
91
91
92 user = User.try_to_login("admin", "hello")
92 user = User.try_to_login("admin", "hello")
93 assert_kind_of User, user
93 assert_kind_of User, user
94 assert_equal "admin", user.login
94 assert_equal "admin", user.login
95 assert_equal User.hash_password("hello"), user.hashed_password
95 assert_equal User.hash_password("hello"), user.hashed_password
96 end
96 end
97
97
98 def test_name_format
98 def test_name_format
99 assert_equal 'Smith, John', @jsmith.name(:lastname_coma_firstname)
99 assert_equal 'Smith, John', @jsmith.name(:lastname_coma_firstname)
100 Setting.user_format = :firstname_lastname
100 Setting.user_format = :firstname_lastname
101 assert_equal 'John Smith', @jsmith.reload.name
101 assert_equal 'John Smith', @jsmith.reload.name
102 Setting.user_format = :username
102 Setting.user_format = :username
103 assert_equal 'jsmith', @jsmith.reload.name
103 assert_equal 'jsmith', @jsmith.reload.name
104 end
104 end
105
105
106 def test_lock
106 def test_lock
107 user = User.try_to_login("jsmith", "jsmith")
107 user = User.try_to_login("jsmith", "jsmith")
108 assert_equal @jsmith, user
108 assert_equal @jsmith, user
109
109
110 @jsmith.status = User::STATUS_LOCKED
110 @jsmith.status = User::STATUS_LOCKED
111 assert @jsmith.save
111 assert @jsmith.save
112
112
113 user = User.try_to_login("jsmith", "jsmith")
113 user = User.try_to_login("jsmith", "jsmith")
114 assert_equal nil, user
114 assert_equal nil, user
115 end
115 end
116
116
117 def test_create_anonymous
117 def test_create_anonymous
118 AnonymousUser.delete_all
118 AnonymousUser.delete_all
119 anon = User.anonymous
119 anon = User.anonymous
120 assert !anon.new_record?
120 assert !anon.new_record?
121 assert_kind_of AnonymousUser, anon
121 assert_kind_of AnonymousUser, anon
122 end
122 end
123
123
124 def test_rss_key
124 def test_rss_key
125 assert_nil @jsmith.rss_token
125 assert_nil @jsmith.rss_token
126 key = @jsmith.rss_key
126 key = @jsmith.rss_key
127 assert_equal 40, key.length
127 assert_equal 40, key.length
128
128
129 @jsmith.reload
129 @jsmith.reload
130 assert_equal key, @jsmith.rss_key
130 assert_equal key, @jsmith.rss_key
131 end
131 end
132
132
133 def test_role_for_project
133 def test_role_for_project
134 # user with a role
134 # user with a role
135 role = @jsmith.role_for_project(Project.find(1))
135 role = @jsmith.role_for_project(Project.find(1))
136 assert_kind_of Role, role
136 assert_kind_of Role, role
137 assert_equal "Manager", role.name
137 assert_equal "Manager", role.name
138
138
139 # user with no role
139 # user with no role
140 assert !@dlopper.role_for_project(Project.find(2)).member?
140 assert !@dlopper.role_for_project(Project.find(2)).member?
141 end
141 end
142
142
143 def test_mail_notification_all
143 def test_mail_notification_all
144 @jsmith.mail_notification = true
144 @jsmith.mail_notification = true
145 @jsmith.notified_project_ids = []
145 @jsmith.notified_project_ids = []
146 @jsmith.save
146 @jsmith.save
147 @jsmith.reload
147 @jsmith.reload
148 assert @jsmith.projects.first.recipients.include?(@jsmith.mail)
148 assert @jsmith.projects.first.recipients.include?(@jsmith.mail)
149 end
149 end
150
150
151 def test_mail_notification_selected
151 def test_mail_notification_selected
152 @jsmith.mail_notification = false
152 @jsmith.mail_notification = false
153 @jsmith.notified_project_ids = [1]
153 @jsmith.notified_project_ids = [1]
154 @jsmith.save
154 @jsmith.save
155 @jsmith.reload
155 @jsmith.reload
156 assert Project.find(1).recipients.include?(@jsmith.mail)
156 assert Project.find(1).recipients.include?(@jsmith.mail)
157 end
157 end
158
158
159 def test_mail_notification_none
159 def test_mail_notification_none
160 @jsmith.mail_notification = false
160 @jsmith.mail_notification = false
161 @jsmith.notified_project_ids = []
161 @jsmith.notified_project_ids = []
162 @jsmith.save
162 @jsmith.save
163 @jsmith.reload
163 @jsmith.reload
164 assert !@jsmith.projects.first.recipients.include?(@jsmith.mail)
164 assert !@jsmith.projects.first.recipients.include?(@jsmith.mail)
165 end
165 end
166
166
167 def test_comments_sorting_preference
167 def test_comments_sorting_preference
168 assert !@jsmith.wants_comments_in_reverse_order?
168 assert !@jsmith.wants_comments_in_reverse_order?
169 @jsmith.pref.comments_sorting = 'asc'
169 @jsmith.pref.comments_sorting = 'asc'
170 assert !@jsmith.wants_comments_in_reverse_order?
170 assert !@jsmith.wants_comments_in_reverse_order?
171 @jsmith.pref.comments_sorting = 'desc'
171 @jsmith.pref.comments_sorting = 'desc'
172 assert @jsmith.wants_comments_in_reverse_order?
172 assert @jsmith.wants_comments_in_reverse_order?
173 end
173 end
174
174
175 def test_find_by_mail_should_be_case_insensitive
175 def test_find_by_mail_should_be_case_insensitive
176 u = User.find_by_mail('JSmith@somenet.foo')
176 u = User.find_by_mail('JSmith@somenet.foo')
177 assert_not_nil u
177 assert_not_nil u
178 assert_equal 'jsmith@somenet.foo', u.mail
178 assert_equal 'jsmith@somenet.foo', u.mail
179 end
179 end
180
180
181 def test_random_password
181 def test_random_password
182 u = User.new
182 u = User.new
183 u.random_password
183 u.random_password
184 assert !u.password.blank?
184 assert !u.password.blank?
185 assert !u.password_confirmation.blank?
185 assert !u.password_confirmation.blank?
186 end
186 end
187
187
188 if Object.const_defined?(:OpenID)
188 if Object.const_defined?(:OpenID)
189
189
190 def test_setting_identity_url
190 def test_setting_identity_url
191 normalized_open_id_url = 'http://example.com/'
191 normalized_open_id_url = 'http://example.com/'
192 u = User.new( :identity_url => 'http://example.com/' )
192 u = User.new( :identity_url => 'http://example.com/' )
193 assert_equal normalized_open_id_url, u.identity_url
193 assert_equal normalized_open_id_url, u.identity_url
194 end
194 end
195
195
196 def test_setting_identity_url_without_trailing_slash
196 def test_setting_identity_url_without_trailing_slash
197 normalized_open_id_url = 'http://example.com/'
197 normalized_open_id_url = 'http://example.com/'
198 u = User.new( :identity_url => 'http://example.com' )
198 u = User.new( :identity_url => 'http://example.com' )
199 assert_equal normalized_open_id_url, u.identity_url
199 assert_equal normalized_open_id_url, u.identity_url
200 end
200 end
201
201
202 def test_setting_identity_url_without_protocol
202 def test_setting_identity_url_without_protocol
203 normalized_open_id_url = 'http://example.com/'
203 normalized_open_id_url = 'http://example.com/'
204 u = User.new( :identity_url => 'example.com' )
204 u = User.new( :identity_url => 'example.com' )
205 assert_equal normalized_open_id_url, u.identity_url
205 assert_equal normalized_open_id_url, u.identity_url
206 end
206 end
207
208 def test_setting_blank_identity_url
209 u = User.new( :identity_url => 'example.com' )
210 u.identity_url = ''
211 assert u.identity_url.blank?
212 end
213
214 def test_setting_invalid_identity_url
215 u = User.new( :identity_url => 'this is not an openid url' )
216 assert u.identity_url.blank?
217 end
207
218
208 else
219 else
209 puts "Skipping openid tests."
220 puts "Skipping openid tests."
210 end
221 end
211
222
212 end
223 end
General Comments 0
You need to be logged in to leave comments. Login now