##// END OF EJS Templates
replace depricated Net::LDAP::LdapError by Net::LDAP::Error (#24970)...
Toshi MARUYAMA -
r15940:d37125dfe98b
parent child
Show More
@@ -1,116 +1,116
1 source 'https://rubygems.org'
1 source 'https://rubygems.org'
2
2
3 if Gem::Version.new(Bundler::VERSION) < Gem::Version.new('1.5.0')
3 if Gem::Version.new(Bundler::VERSION) < Gem::Version.new('1.5.0')
4 abort "Redmine requires Bundler 1.5.0 or higher (you're using #{Bundler::VERSION}).\nPlease update with 'gem update bundler'."
4 abort "Redmine requires Bundler 1.5.0 or higher (you're using #{Bundler::VERSION}).\nPlease update with 'gem update bundler'."
5 end
5 end
6
6
7 gem "rails", "4.2.7.1"
7 gem "rails", "4.2.7.1"
8 gem "addressable", "2.4.0" if RUBY_VERSION < "2.0"
8 gem "addressable", "2.4.0" if RUBY_VERSION < "2.0"
9 gem "jquery-rails", "~> 3.1.4"
9 gem "jquery-rails", "~> 3.1.4"
10 gem "coderay", "~> 1.1.1"
10 gem "coderay", "~> 1.1.1"
11 gem "request_store", "1.0.5"
11 gem "request_store", "1.0.5"
12 gem "mime-types", (RUBY_VERSION >= "2.0" ? "~> 3.0" : "~> 2.99")
12 gem "mime-types", (RUBY_VERSION >= "2.0" ? "~> 3.0" : "~> 2.99")
13 gem "protected_attributes"
13 gem "protected_attributes"
14 gem "actionpack-xml_parser"
14 gem "actionpack-xml_parser"
15 gem "roadie-rails"
15 gem "roadie-rails"
16 gem "mimemagic"
16 gem "mimemagic"
17
17
18 gem "nokogiri", "~> 1.6.8"
18 gem "nokogiri", "~> 1.6.8"
19
19
20 # Request at least rails-html-sanitizer 1.0.3 because of security advisories
20 # Request at least rails-html-sanitizer 1.0.3 because of security advisories
21 gem "rails-html-sanitizer", ">= 1.0.3"
21 gem "rails-html-sanitizer", ">= 1.0.3"
22
22
23 # Windows does not include zoneinfo files, so bundle the tzinfo-data gem
23 # Windows does not include zoneinfo files, so bundle the tzinfo-data gem
24 gem 'tzinfo-data', platforms: [:mingw, :x64_mingw, :mswin, :jruby]
24 gem 'tzinfo-data', platforms: [:mingw, :x64_mingw, :mswin, :jruby]
25 gem "rbpdf", "~> 1.19.0"
25 gem "rbpdf", "~> 1.19.0"
26
26
27 # Optional gem for LDAP authentication
27 # Optional gem for LDAP authentication
28 group :ldap do
28 group :ldap do
29 gem "net-ldap", "~> 0.12.0"
29 gem "net-ldap", "~> 0.12.1"
30 end
30 end
31
31
32 # Optional gem for OpenID authentication
32 # Optional gem for OpenID authentication
33 group :openid do
33 group :openid do
34 gem "ruby-openid", "~> 2.3.0", :require => "openid"
34 gem "ruby-openid", "~> 2.3.0", :require => "openid"
35 gem "rack-openid"
35 gem "rack-openid"
36 end
36 end
37
37
38 platforms :mri, :mingw, :x64_mingw do
38 platforms :mri, :mingw, :x64_mingw do
39 # Optional gem for exporting the gantt to a PNG file, not supported with jruby
39 # Optional gem for exporting the gantt to a PNG file, not supported with jruby
40 group :rmagick do
40 group :rmagick do
41 gem "rmagick", ">= 2.14.0"
41 gem "rmagick", ">= 2.14.0"
42 end
42 end
43
43
44 # Optional Markdown support, not for JRuby
44 # Optional Markdown support, not for JRuby
45 group :markdown do
45 group :markdown do
46 gem "redcarpet", "~> 3.3.2"
46 gem "redcarpet", "~> 3.3.2"
47 end
47 end
48 end
48 end
49
49
50 platforms :jruby do
50 platforms :jruby do
51 # jruby-openssl is bundled with JRuby 1.7.0
51 # jruby-openssl is bundled with JRuby 1.7.0
52 gem "jruby-openssl" if Object.const_defined?(:JRUBY_VERSION) && JRUBY_VERSION < '1.7.0'
52 gem "jruby-openssl" if Object.const_defined?(:JRUBY_VERSION) && JRUBY_VERSION < '1.7.0'
53 gem "activerecord-jdbc-adapter", "~> 1.3.2"
53 gem "activerecord-jdbc-adapter", "~> 1.3.2"
54 end
54 end
55
55
56 # Include database gems for the adapters found in the database
56 # Include database gems for the adapters found in the database
57 # configuration file
57 # configuration file
58 require 'erb'
58 require 'erb'
59 require 'yaml'
59 require 'yaml'
60 database_file = File.join(File.dirname(__FILE__), "config/database.yml")
60 database_file = File.join(File.dirname(__FILE__), "config/database.yml")
61 if File.exist?(database_file)
61 if File.exist?(database_file)
62 database_config = YAML::load(ERB.new(IO.read(database_file)).result)
62 database_config = YAML::load(ERB.new(IO.read(database_file)).result)
63 adapters = database_config.values.map {|c| c['adapter']}.compact.uniq
63 adapters = database_config.values.map {|c| c['adapter']}.compact.uniq
64 if adapters.any?
64 if adapters.any?
65 adapters.each do |adapter|
65 adapters.each do |adapter|
66 case adapter
66 case adapter
67 when 'mysql2'
67 when 'mysql2'
68 gem "mysql2", "~> 0.3.11", :platforms => [:mri, :mingw, :x64_mingw]
68 gem "mysql2", "~> 0.3.11", :platforms => [:mri, :mingw, :x64_mingw]
69 gem "activerecord-jdbcmysql-adapter", :platforms => :jruby
69 gem "activerecord-jdbcmysql-adapter", :platforms => :jruby
70 when 'mysql'
70 when 'mysql'
71 gem "activerecord-jdbcmysql-adapter", :platforms => :jruby
71 gem "activerecord-jdbcmysql-adapter", :platforms => :jruby
72 when /postgresql/
72 when /postgresql/
73 gem "pg", "~> 0.18.1", :platforms => [:mri, :mingw, :x64_mingw]
73 gem "pg", "~> 0.18.1", :platforms => [:mri, :mingw, :x64_mingw]
74 gem "activerecord-jdbcpostgresql-adapter", :platforms => :jruby
74 gem "activerecord-jdbcpostgresql-adapter", :platforms => :jruby
75 when /sqlite3/
75 when /sqlite3/
76 gem "sqlite3", :platforms => [:mri, :mingw, :x64_mingw]
76 gem "sqlite3", :platforms => [:mri, :mingw, :x64_mingw]
77 gem "jdbc-sqlite3", ">= 3.8.10.1", :platforms => :jruby
77 gem "jdbc-sqlite3", ">= 3.8.10.1", :platforms => :jruby
78 gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby
78 gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby
79 when /sqlserver/
79 when /sqlserver/
80 gem "tiny_tds", (RUBY_VERSION >= "2.0" ? "~> 1.0.5" : "~> 0.7.0"), :platforms => [:mri, :mingw, :x64_mingw]
80 gem "tiny_tds", (RUBY_VERSION >= "2.0" ? "~> 1.0.5" : "~> 0.7.0"), :platforms => [:mri, :mingw, :x64_mingw]
81 gem "activerecord-sqlserver-adapter", :platforms => [:mri, :mingw, :x64_mingw]
81 gem "activerecord-sqlserver-adapter", :platforms => [:mri, :mingw, :x64_mingw]
82 else
82 else
83 warn("Unknown database adapter `#{adapter}` found in config/database.yml, use Gemfile.local to load your own database gems")
83 warn("Unknown database adapter `#{adapter}` found in config/database.yml, use Gemfile.local to load your own database gems")
84 end
84 end
85 end
85 end
86 else
86 else
87 warn("No adapter found in config/database.yml, please configure it first")
87 warn("No adapter found in config/database.yml, please configure it first")
88 end
88 end
89 else
89 else
90 warn("Please configure your config/database.yml first")
90 warn("Please configure your config/database.yml first")
91 end
91 end
92
92
93 group :development do
93 group :development do
94 gem "rdoc", "~> 4.3"
94 gem "rdoc", "~> 4.3"
95 gem "yard"
95 gem "yard"
96 end
96 end
97
97
98 group :test do
98 group :test do
99 gem "minitest"
99 gem "minitest"
100 gem "rails-dom-testing"
100 gem "rails-dom-testing"
101 gem "mocha"
101 gem "mocha"
102 gem "simplecov", "~> 0.9.1", :require => false
102 gem "simplecov", "~> 0.9.1", :require => false
103 # For running UI tests
103 # For running UI tests
104 gem "capybara"
104 gem "capybara"
105 gem "selenium-webdriver", "~> 2.53.4"
105 gem "selenium-webdriver", "~> 2.53.4"
106 end
106 end
107
107
108 local_gemfile = File.join(File.dirname(__FILE__), "Gemfile.local")
108 local_gemfile = File.join(File.dirname(__FILE__), "Gemfile.local")
109 if File.exists?(local_gemfile)
109 if File.exists?(local_gemfile)
110 eval_gemfile local_gemfile
110 eval_gemfile local_gemfile
111 end
111 end
112
112
113 # Load plugins' Gemfiles
113 # Load plugins' Gemfiles
114 Dir.glob File.expand_path("../plugins/*/{Gemfile,PluginGemfile}", __FILE__) do |file|
114 Dir.glob File.expand_path("../plugins/*/{Gemfile,PluginGemfile}", __FILE__) do |file|
115 eval_gemfile file
115 eval_gemfile file
116 end
116 end
@@ -1,209 +1,209
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2016 Jean-Philippe Lang
2 # Copyright (C) 2006-2016 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 'net/ldap'
18 require 'net/ldap'
19 require 'net/ldap/dn'
19 require 'net/ldap/dn'
20 require 'timeout'
20 require 'timeout'
21
21
22 class AuthSourceLdap < AuthSource
22 class AuthSourceLdap < AuthSource
23 NETWORK_EXCEPTIONS = [
23 NETWORK_EXCEPTIONS = [
24 Net::LDAP::LdapError,
24 Net::LDAP::Error,
25 Errno::ECONNABORTED, Errno::ECONNREFUSED, Errno::ECONNRESET,
25 Errno::ECONNABORTED, Errno::ECONNREFUSED, Errno::ECONNRESET,
26 Errno::EHOSTDOWN, Errno::EHOSTUNREACH,
26 Errno::EHOSTDOWN, Errno::EHOSTUNREACH,
27 SocketError
27 SocketError
28 ]
28 ]
29
29
30 validates_presence_of :host, :port, :attr_login
30 validates_presence_of :host, :port, :attr_login
31 validates_length_of :name, :host, :maximum => 60, :allow_nil => true
31 validates_length_of :name, :host, :maximum => 60, :allow_nil => true
32 validates_length_of :account, :account_password, :base_dn, :maximum => 255, :allow_blank => true
32 validates_length_of :account, :account_password, :base_dn, :maximum => 255, :allow_blank => true
33 validates_length_of :attr_login, :attr_firstname, :attr_lastname, :attr_mail, :maximum => 30, :allow_nil => true
33 validates_length_of :attr_login, :attr_firstname, :attr_lastname, :attr_mail, :maximum => 30, :allow_nil => true
34 validates_numericality_of :port, :only_integer => true
34 validates_numericality_of :port, :only_integer => true
35 validates_numericality_of :timeout, :only_integer => true, :allow_blank => true
35 validates_numericality_of :timeout, :only_integer => true, :allow_blank => true
36 validate :validate_filter
36 validate :validate_filter
37
37
38 before_validation :strip_ldap_attributes
38 before_validation :strip_ldap_attributes
39
39
40 def initialize(attributes=nil, *args)
40 def initialize(attributes=nil, *args)
41 super
41 super
42 self.port = 389 if self.port == 0
42 self.port = 389 if self.port == 0
43 end
43 end
44
44
45 def authenticate(login, password)
45 def authenticate(login, password)
46 return nil if login.blank? || password.blank?
46 return nil if login.blank? || password.blank?
47
47
48 with_timeout do
48 with_timeout do
49 attrs = get_user_dn(login, password)
49 attrs = get_user_dn(login, password)
50 if attrs && attrs[:dn] && authenticate_dn(attrs[:dn], password)
50 if attrs && attrs[:dn] && authenticate_dn(attrs[:dn], password)
51 logger.debug "Authentication successful for '#{login}'" if logger && logger.debug?
51 logger.debug "Authentication successful for '#{login}'" if logger && logger.debug?
52 return attrs.except(:dn)
52 return attrs.except(:dn)
53 end
53 end
54 end
54 end
55 rescue *NETWORK_EXCEPTIONS => e
55 rescue *NETWORK_EXCEPTIONS => e
56 raise AuthSourceException.new(e.message)
56 raise AuthSourceException.new(e.message)
57 end
57 end
58
58
59 # Test the connection to the LDAP
59 # Test the connection to the LDAP
60 def test_connection
60 def test_connection
61 with_timeout do
61 with_timeout do
62 ldap_con = initialize_ldap_con(self.account, self.account_password)
62 ldap_con = initialize_ldap_con(self.account, self.account_password)
63 ldap_con.open { }
63 ldap_con.open { }
64
64
65 if self.account.present? && !self.account.include?("$login") && self.account_password.present?
65 if self.account.present? && !self.account.include?("$login") && self.account_password.present?
66 ldap_auth = authenticate_dn(self.account, self.account_password)
66 ldap_auth = authenticate_dn(self.account, self.account_password)
67 raise AuthSourceException.new(l(:error_ldap_bind_credentials)) if !ldap_auth
67 raise AuthSourceException.new(l(:error_ldap_bind_credentials)) if !ldap_auth
68 end
68 end
69 end
69 end
70 rescue *NETWORK_EXCEPTIONS => e
70 rescue *NETWORK_EXCEPTIONS => e
71 raise AuthSourceException.new(e.message)
71 raise AuthSourceException.new(e.message)
72 end
72 end
73
73
74 def auth_method_name
74 def auth_method_name
75 "LDAP"
75 "LDAP"
76 end
76 end
77
77
78 # Returns true if this source can be searched for users
78 # Returns true if this source can be searched for users
79 def searchable?
79 def searchable?
80 !account.to_s.include?("$login") && %w(login firstname lastname mail).all? {|a| send("attr_#{a}?")}
80 !account.to_s.include?("$login") && %w(login firstname lastname mail).all? {|a| send("attr_#{a}?")}
81 end
81 end
82
82
83 # Searches the source for users and returns an array of results
83 # Searches the source for users and returns an array of results
84 def search(q)
84 def search(q)
85 q = q.to_s.strip
85 q = q.to_s.strip
86 return [] unless searchable? && q.present?
86 return [] unless searchable? && q.present?
87
87
88 results = []
88 results = []
89 search_filter = base_filter & Net::LDAP::Filter.begins(self.attr_login, q)
89 search_filter = base_filter & Net::LDAP::Filter.begins(self.attr_login, q)
90 ldap_con = initialize_ldap_con(self.account, self.account_password)
90 ldap_con = initialize_ldap_con(self.account, self.account_password)
91 ldap_con.search(:base => self.base_dn,
91 ldap_con.search(:base => self.base_dn,
92 :filter => search_filter,
92 :filter => search_filter,
93 :attributes => ['dn', self.attr_login, self.attr_firstname, self.attr_lastname, self.attr_mail],
93 :attributes => ['dn', self.attr_login, self.attr_firstname, self.attr_lastname, self.attr_mail],
94 :size => 10) do |entry|
94 :size => 10) do |entry|
95 attrs = get_user_attributes_from_ldap_entry(entry)
95 attrs = get_user_attributes_from_ldap_entry(entry)
96 attrs[:login] = AuthSourceLdap.get_attr(entry, self.attr_login)
96 attrs[:login] = AuthSourceLdap.get_attr(entry, self.attr_login)
97 results << attrs
97 results << attrs
98 end
98 end
99 results
99 results
100 rescue *NETWORK_EXCEPTIONS => e
100 rescue *NETWORK_EXCEPTIONS => e
101 raise AuthSourceException.new(e.message)
101 raise AuthSourceException.new(e.message)
102 end
102 end
103
103
104 private
104 private
105
105
106 def with_timeout(&block)
106 def with_timeout(&block)
107 timeout = self.timeout
107 timeout = self.timeout
108 timeout = 20 unless timeout && timeout > 0
108 timeout = 20 unless timeout && timeout > 0
109 Timeout.timeout(timeout) do
109 Timeout.timeout(timeout) do
110 return yield
110 return yield
111 end
111 end
112 rescue Timeout::Error => e
112 rescue Timeout::Error => e
113 raise AuthSourceTimeoutException.new(e.message)
113 raise AuthSourceTimeoutException.new(e.message)
114 end
114 end
115
115
116 def ldap_filter
116 def ldap_filter
117 if filter.present?
117 if filter.present?
118 Net::LDAP::Filter.construct(filter)
118 Net::LDAP::Filter.construct(filter)
119 end
119 end
120 rescue Net::LDAP::LdapError, Net::LDAP::FilterSyntaxInvalidError
120 rescue Net::LDAP::Error, Net::LDAP::FilterSyntaxInvalidError
121 nil
121 nil
122 end
122 end
123
123
124 def base_filter
124 def base_filter
125 filter = Net::LDAP::Filter.eq("objectClass", "*")
125 filter = Net::LDAP::Filter.eq("objectClass", "*")
126 if f = ldap_filter
126 if f = ldap_filter
127 filter = filter & f
127 filter = filter & f
128 end
128 end
129 filter
129 filter
130 end
130 end
131
131
132 def validate_filter
132 def validate_filter
133 if filter.present? && ldap_filter.nil?
133 if filter.present? && ldap_filter.nil?
134 errors.add(:filter, :invalid)
134 errors.add(:filter, :invalid)
135 end
135 end
136 end
136 end
137
137
138 def strip_ldap_attributes
138 def strip_ldap_attributes
139 [:attr_login, :attr_firstname, :attr_lastname, :attr_mail].each do |attr|
139 [:attr_login, :attr_firstname, :attr_lastname, :attr_mail].each do |attr|
140 write_attribute(attr, read_attribute(attr).strip) unless read_attribute(attr).nil?
140 write_attribute(attr, read_attribute(attr).strip) unless read_attribute(attr).nil?
141 end
141 end
142 end
142 end
143
143
144 def initialize_ldap_con(ldap_user, ldap_password)
144 def initialize_ldap_con(ldap_user, ldap_password)
145 options = { :host => self.host,
145 options = { :host => self.host,
146 :port => self.port,
146 :port => self.port,
147 :encryption => (self.tls ? :simple_tls : nil)
147 :encryption => (self.tls ? :simple_tls : nil)
148 }
148 }
149 options.merge!(:auth => { :method => :simple, :username => ldap_user, :password => ldap_password }) unless ldap_user.blank? && ldap_password.blank?
149 options.merge!(:auth => { :method => :simple, :username => ldap_user, :password => ldap_password }) unless ldap_user.blank? && ldap_password.blank?
150 Net::LDAP.new options
150 Net::LDAP.new options
151 end
151 end
152
152
153 def get_user_attributes_from_ldap_entry(entry)
153 def get_user_attributes_from_ldap_entry(entry)
154 {
154 {
155 :dn => entry.dn,
155 :dn => entry.dn,
156 :firstname => AuthSourceLdap.get_attr(entry, self.attr_firstname),
156 :firstname => AuthSourceLdap.get_attr(entry, self.attr_firstname),
157 :lastname => AuthSourceLdap.get_attr(entry, self.attr_lastname),
157 :lastname => AuthSourceLdap.get_attr(entry, self.attr_lastname),
158 :mail => AuthSourceLdap.get_attr(entry, self.attr_mail),
158 :mail => AuthSourceLdap.get_attr(entry, self.attr_mail),
159 :auth_source_id => self.id
159 :auth_source_id => self.id
160 }
160 }
161 end
161 end
162
162
163 # Return the attributes needed for the LDAP search. It will only
163 # Return the attributes needed for the LDAP search. It will only
164 # include the user attributes if on-the-fly registration is enabled
164 # include the user attributes if on-the-fly registration is enabled
165 def search_attributes
165 def search_attributes
166 if onthefly_register?
166 if onthefly_register?
167 ['dn', self.attr_firstname, self.attr_lastname, self.attr_mail]
167 ['dn', self.attr_firstname, self.attr_lastname, self.attr_mail]
168 else
168 else
169 ['dn']
169 ['dn']
170 end
170 end
171 end
171 end
172
172
173 # Check if a DN (user record) authenticates with the password
173 # Check if a DN (user record) authenticates with the password
174 def authenticate_dn(dn, password)
174 def authenticate_dn(dn, password)
175 if dn.present? && password.present?
175 if dn.present? && password.present?
176 initialize_ldap_con(dn, password).bind
176 initialize_ldap_con(dn, password).bind
177 end
177 end
178 end
178 end
179
179
180 # Get the user's dn and any attributes for them, given their login
180 # Get the user's dn and any attributes for them, given their login
181 def get_user_dn(login, password)
181 def get_user_dn(login, password)
182 ldap_con = nil
182 ldap_con = nil
183 if self.account && self.account.include?("$login")
183 if self.account && self.account.include?("$login")
184 ldap_con = initialize_ldap_con(self.account.sub("$login", Net::LDAP::DN.escape(login)), password)
184 ldap_con = initialize_ldap_con(self.account.sub("$login", Net::LDAP::DN.escape(login)), password)
185 else
185 else
186 ldap_con = initialize_ldap_con(self.account, self.account_password)
186 ldap_con = initialize_ldap_con(self.account, self.account_password)
187 end
187 end
188 attrs = {}
188 attrs = {}
189 search_filter = base_filter & Net::LDAP::Filter.eq(self.attr_login, login)
189 search_filter = base_filter & Net::LDAP::Filter.eq(self.attr_login, login)
190 ldap_con.search( :base => self.base_dn,
190 ldap_con.search( :base => self.base_dn,
191 :filter => search_filter,
191 :filter => search_filter,
192 :attributes=> search_attributes) do |entry|
192 :attributes=> search_attributes) do |entry|
193 if onthefly_register?
193 if onthefly_register?
194 attrs = get_user_attributes_from_ldap_entry(entry)
194 attrs = get_user_attributes_from_ldap_entry(entry)
195 else
195 else
196 attrs = {:dn => entry.dn}
196 attrs = {:dn => entry.dn}
197 end
197 end
198 logger.debug "DN found for #{login}: #{attrs[:dn]}" if logger && logger.debug?
198 logger.debug "DN found for #{login}: #{attrs[:dn]}" if logger && logger.debug?
199 end
199 end
200 attrs
200 attrs
201 end
201 end
202
202
203 def self.get_attr(entry, attr_name)
203 def self.get_attr(entry, attr_name)
204 if !attr_name.blank?
204 if !attr_name.blank?
205 value = entry[attr_name].is_a?(Array) ? entry[attr_name].first : entry[attr_name]
205 value = entry[attr_name].is_a?(Array) ? entry[attr_name].first : entry[attr_name]
206 value.to_s.force_encoding('UTF-8')
206 value.to_s.force_encoding('UTF-8')
207 end
207 end
208 end
208 end
209 end
209 end
@@ -1,160 +1,160
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2016 Jean-Philippe Lang
2 # Copyright (C) 2006-2016 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.expand_path('../../test_helper', __FILE__)
18 require File.expand_path('../../test_helper', __FILE__)
19
19
20 class AuthSourcesControllerTest < Redmine::ControllerTest
20 class AuthSourcesControllerTest < Redmine::ControllerTest
21 fixtures :users, :auth_sources
21 fixtures :users, :auth_sources
22
22
23 def setup
23 def setup
24 @request.session[:user_id] = 1
24 @request.session[:user_id] = 1
25 end
25 end
26
26
27 def test_index
27 def test_index
28 get :index
28 get :index
29 assert_response :success
29 assert_response :success
30 end
30 end
31
31
32 def test_new
32 def test_new
33 get :new
33 get :new
34 assert_response :success
34 assert_response :success
35
35
36 assert_select 'form#auth_source_form' do
36 assert_select 'form#auth_source_form' do
37 assert_select 'input[name=type][value=AuthSourceLdap]'
37 assert_select 'input[name=type][value=AuthSourceLdap]'
38 assert_select 'input[name=?]', 'auth_source[host]'
38 assert_select 'input[name=?]', 'auth_source[host]'
39 end
39 end
40 end
40 end
41
41
42 def test_new_with_invalid_type_should_respond_with_404
42 def test_new_with_invalid_type_should_respond_with_404
43 get :new, :type => 'foo'
43 get :new, :type => 'foo'
44 assert_response 404
44 assert_response 404
45 end
45 end
46
46
47 def test_create
47 def test_create
48 assert_difference 'AuthSourceLdap.count' do
48 assert_difference 'AuthSourceLdap.count' do
49 post :create, :type => 'AuthSourceLdap', :auth_source => {:name => 'Test', :host => '127.0.0.1', :port => '389', :attr_login => 'cn'}
49 post :create, :type => 'AuthSourceLdap', :auth_source => {:name => 'Test', :host => '127.0.0.1', :port => '389', :attr_login => 'cn'}
50 assert_redirected_to '/auth_sources'
50 assert_redirected_to '/auth_sources'
51 end
51 end
52
52
53 source = AuthSourceLdap.order('id DESC').first
53 source = AuthSourceLdap.order('id DESC').first
54 assert_equal 'Test', source.name
54 assert_equal 'Test', source.name
55 assert_equal '127.0.0.1', source.host
55 assert_equal '127.0.0.1', source.host
56 assert_equal 389, source.port
56 assert_equal 389, source.port
57 assert_equal 'cn', source.attr_login
57 assert_equal 'cn', source.attr_login
58 end
58 end
59
59
60 def test_create_with_failure
60 def test_create_with_failure
61 assert_no_difference 'AuthSourceLdap.count' do
61 assert_no_difference 'AuthSourceLdap.count' do
62 post :create, :type => 'AuthSourceLdap',
62 post :create, :type => 'AuthSourceLdap',
63 :auth_source => {:name => 'Test', :host => '',
63 :auth_source => {:name => 'Test', :host => '',
64 :port => '389', :attr_login => 'cn'}
64 :port => '389', :attr_login => 'cn'}
65 assert_response :success
65 assert_response :success
66 end
66 end
67 assert_select_error /host cannot be blank/i
67 assert_select_error /host cannot be blank/i
68 end
68 end
69
69
70 def test_edit
70 def test_edit
71 get :edit, :id => 1
71 get :edit, :id => 1
72 assert_response :success
72 assert_response :success
73
73
74 assert_select 'form#auth_source_form' do
74 assert_select 'form#auth_source_form' do
75 assert_select 'input[name=?]', 'auth_source[host]'
75 assert_select 'input[name=?]', 'auth_source[host]'
76 end
76 end
77 end
77 end
78
78
79 def test_edit_should_not_contain_password
79 def test_edit_should_not_contain_password
80 AuthSource.find(1).update_column :account_password, 'secret'
80 AuthSource.find(1).update_column :account_password, 'secret'
81
81
82 get :edit, :id => 1
82 get :edit, :id => 1
83 assert_response :success
83 assert_response :success
84 assert_select 'input[value=secret]', 0
84 assert_select 'input[value=secret]', 0
85 assert_select 'input[name=dummy_password][value^=xxxxxx]'
85 assert_select 'input[name=dummy_password][value^=xxxxxx]'
86 end
86 end
87
87
88 def test_edit_invalid_should_respond_with_404
88 def test_edit_invalid_should_respond_with_404
89 get :edit, :id => 99
89 get :edit, :id => 99
90 assert_response 404
90 assert_response 404
91 end
91 end
92
92
93 def test_update
93 def test_update
94 put :update, :id => 1,
94 put :update, :id => 1,
95 :auth_source => {:name => 'Renamed', :host => '192.168.0.10',
95 :auth_source => {:name => 'Renamed', :host => '192.168.0.10',
96 :port => '389', :attr_login => 'uid'}
96 :port => '389', :attr_login => 'uid'}
97 assert_redirected_to '/auth_sources'
97 assert_redirected_to '/auth_sources'
98 source = AuthSourceLdap.find(1)
98 source = AuthSourceLdap.find(1)
99 assert_equal 'Renamed', source.name
99 assert_equal 'Renamed', source.name
100 assert_equal '192.168.0.10', source.host
100 assert_equal '192.168.0.10', source.host
101 end
101 end
102
102
103 def test_update_with_failure
103 def test_update_with_failure
104 put :update, :id => 1,
104 put :update, :id => 1,
105 :auth_source => {:name => 'Renamed', :host => '',
105 :auth_source => {:name => 'Renamed', :host => '',
106 :port => '389', :attr_login => 'uid'}
106 :port => '389', :attr_login => 'uid'}
107 assert_response :success
107 assert_response :success
108 assert_select_error /host cannot be blank/i
108 assert_select_error /host cannot be blank/i
109 end
109 end
110
110
111 def test_destroy
111 def test_destroy
112 assert_difference 'AuthSourceLdap.count', -1 do
112 assert_difference 'AuthSourceLdap.count', -1 do
113 delete :destroy, :id => 1
113 delete :destroy, :id => 1
114 assert_redirected_to '/auth_sources'
114 assert_redirected_to '/auth_sources'
115 end
115 end
116 end
116 end
117
117
118 def test_destroy_auth_source_in_use
118 def test_destroy_auth_source_in_use
119 User.find(2).update_attribute :auth_source_id, 1
119 User.find(2).update_attribute :auth_source_id, 1
120
120
121 assert_no_difference 'AuthSourceLdap.count' do
121 assert_no_difference 'AuthSourceLdap.count' do
122 delete :destroy, :id => 1
122 delete :destroy, :id => 1
123 assert_redirected_to '/auth_sources'
123 assert_redirected_to '/auth_sources'
124 end
124 end
125 end
125 end
126
126
127 def test_test_connection
127 def test_test_connection
128 AuthSourceLdap.any_instance.stubs(:test_connection).returns(true)
128 AuthSourceLdap.any_instance.stubs(:test_connection).returns(true)
129
129
130 get :test_connection, :id => 1
130 get :test_connection, :id => 1
131 assert_redirected_to '/auth_sources'
131 assert_redirected_to '/auth_sources'
132 assert_not_nil flash[:notice]
132 assert_not_nil flash[:notice]
133 assert_match /successful/i, flash[:notice]
133 assert_match /successful/i, flash[:notice]
134 end
134 end
135
135
136 def test_test_connection_with_failure
136 def test_test_connection_with_failure
137 AuthSourceLdap.any_instance.stubs(:initialize_ldap_con).raises(Net::LDAP::LdapError.new("Something went wrong"))
137 AuthSourceLdap.any_instance.stubs(:initialize_ldap_con).raises(Net::LDAP::Error.new("Something went wrong"))
138
138
139 get :test_connection, :id => 1
139 get :test_connection, :id => 1
140 assert_redirected_to '/auth_sources'
140 assert_redirected_to '/auth_sources'
141 assert_not_nil flash[:error]
141 assert_not_nil flash[:error]
142 assert_include 'Something went wrong', flash[:error]
142 assert_include 'Something went wrong', flash[:error]
143 end
143 end
144
144
145 def test_autocomplete_for_new_user
145 def test_autocomplete_for_new_user
146 AuthSource.expects(:search).with('foo').returns([
146 AuthSource.expects(:search).with('foo').returns([
147 {:login => 'foo1', :firstname => 'John', :lastname => 'Smith', :mail => 'foo1@example.net', :auth_source_id => 1},
147 {:login => 'foo1', :firstname => 'John', :lastname => 'Smith', :mail => 'foo1@example.net', :auth_source_id => 1},
148 {:login => 'Smith', :firstname => 'John', :lastname => 'Doe', :mail => 'foo2@example.net', :auth_source_id => 1}
148 {:login => 'Smith', :firstname => 'John', :lastname => 'Doe', :mail => 'foo2@example.net', :auth_source_id => 1}
149 ])
149 ])
150
150
151 get :autocomplete_for_new_user, :term => 'foo'
151 get :autocomplete_for_new_user, :term => 'foo'
152 assert_response :success
152 assert_response :success
153 assert_equal 'application/json', response.content_type
153 assert_equal 'application/json', response.content_type
154 json = ActiveSupport::JSON.decode(response.body)
154 json = ActiveSupport::JSON.decode(response.body)
155 assert_kind_of Array, json
155 assert_kind_of Array, json
156 assert_equal 2, json.size
156 assert_equal 2, json.size
157 assert_equal 'foo1', json.first['value']
157 assert_equal 'foo1', json.first['value']
158 assert_equal 'foo1 (John Smith)', json.first['label']
158 assert_equal 'foo1 (John Smith)', json.first['label']
159 end
159 end
160 end
160 end
@@ -1,234 +1,234
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2016 Jean-Philippe Lang
2 # Copyright (C) 2006-2016 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.expand_path('../../test_helper', __FILE__)
18 require File.expand_path('../../test_helper', __FILE__)
19
19
20 class AuthSourceLdapTest < ActiveSupport::TestCase
20 class AuthSourceLdapTest < ActiveSupport::TestCase
21 include Redmine::I18n
21 include Redmine::I18n
22 fixtures :auth_sources
22 fixtures :auth_sources
23
23
24 def setup
24 def setup
25 end
25 end
26
26
27 def test_initialize
27 def test_initialize
28 auth_source = AuthSourceLdap.new
28 auth_source = AuthSourceLdap.new
29 assert_nil auth_source.id
29 assert_nil auth_source.id
30 assert_equal "AuthSourceLdap", auth_source.type
30 assert_equal "AuthSourceLdap", auth_source.type
31 assert_equal "", auth_source.name
31 assert_equal "", auth_source.name
32 assert_nil auth_source.host
32 assert_nil auth_source.host
33 assert_nil auth_source.port
33 assert_nil auth_source.port
34 assert_nil auth_source.account
34 assert_nil auth_source.account
35 assert_equal "", auth_source.account_password
35 assert_equal "", auth_source.account_password
36 assert_nil auth_source.base_dn
36 assert_nil auth_source.base_dn
37 assert_nil auth_source.attr_login
37 assert_nil auth_source.attr_login
38 assert_nil auth_source.attr_firstname
38 assert_nil auth_source.attr_firstname
39 assert_nil auth_source.attr_lastname
39 assert_nil auth_source.attr_lastname
40 assert_nil auth_source.attr_mail
40 assert_nil auth_source.attr_mail
41 assert_equal false, auth_source.onthefly_register
41 assert_equal false, auth_source.onthefly_register
42 assert_equal false, auth_source.tls
42 assert_equal false, auth_source.tls
43 assert_nil auth_source.filter
43 assert_nil auth_source.filter
44 assert_nil auth_source.timeout
44 assert_nil auth_source.timeout
45 end
45 end
46
46
47 def test_create
47 def test_create
48 a = AuthSourceLdap.new(:name => 'My LDAP', :host => 'ldap.example.net', :port => 389, :base_dn => 'dc=example,dc=net', :attr_login => 'sAMAccountName')
48 a = AuthSourceLdap.new(:name => 'My LDAP', :host => 'ldap.example.net', :port => 389, :base_dn => 'dc=example,dc=net', :attr_login => 'sAMAccountName')
49 assert a.save
49 assert a.save
50 end
50 end
51
51
52 def test_should_strip_ldap_attributes
52 def test_should_strip_ldap_attributes
53 a = AuthSourceLdap.new(:name => 'My LDAP', :host => 'ldap.example.net', :port => 389, :base_dn => 'dc=example,dc=net', :attr_login => 'sAMAccountName',
53 a = AuthSourceLdap.new(:name => 'My LDAP', :host => 'ldap.example.net', :port => 389, :base_dn => 'dc=example,dc=net', :attr_login => 'sAMAccountName',
54 :attr_firstname => 'givenName ')
54 :attr_firstname => 'givenName ')
55 assert a.save
55 assert a.save
56 assert_equal 'givenName', a.reload.attr_firstname
56 assert_equal 'givenName', a.reload.attr_firstname
57 end
57 end
58
58
59 def test_replace_port_zero_to_389
59 def test_replace_port_zero_to_389
60 a = AuthSourceLdap.new(
60 a = AuthSourceLdap.new(
61 :name => 'My LDAP', :host => 'ldap.example.net', :port => 0,
61 :name => 'My LDAP', :host => 'ldap.example.net', :port => 0,
62 :base_dn => 'dc=example,dc=net', :attr_login => 'sAMAccountName',
62 :base_dn => 'dc=example,dc=net', :attr_login => 'sAMAccountName',
63 :attr_firstname => 'givenName ')
63 :attr_firstname => 'givenName ')
64 assert a.save
64 assert a.save
65 assert_equal 389, a.port
65 assert_equal 389, a.port
66 end
66 end
67
67
68 def test_filter_should_be_validated
68 def test_filter_should_be_validated
69 set_language_if_valid 'en'
69 set_language_if_valid 'en'
70
70
71 a = AuthSourceLdap.new(:name => 'My LDAP', :host => 'ldap.example.net', :port => 389, :attr_login => 'sn')
71 a = AuthSourceLdap.new(:name => 'My LDAP', :host => 'ldap.example.net', :port => 389, :attr_login => 'sn')
72 a.filter = "(mail=*@redmine.org"
72 a.filter = "(mail=*@redmine.org"
73 assert !a.valid?
73 assert !a.valid?
74 assert_include "LDAP filter is invalid", a.errors.full_messages
74 assert_include "LDAP filter is invalid", a.errors.full_messages
75
75
76 a.filter = "(mail=*@redmine.org)"
76 a.filter = "(mail=*@redmine.org)"
77 assert a.valid?
77 assert a.valid?
78 end
78 end
79
79
80 if ldap_configured?
80 if ldap_configured?
81 test '#authenticate with a valid LDAP user should return the user attributes' do
81 test '#authenticate with a valid LDAP user should return the user attributes' do
82 auth = AuthSourceLdap.find(1)
82 auth = AuthSourceLdap.find(1)
83 auth.update_attribute :onthefly_register, true
83 auth.update_attribute :onthefly_register, true
84
84
85 attributes = auth.authenticate('example1','123456')
85 attributes = auth.authenticate('example1','123456')
86 assert attributes.is_a?(Hash), "An hash was not returned"
86 assert attributes.is_a?(Hash), "An hash was not returned"
87 assert_equal 'Example', attributes[:firstname]
87 assert_equal 'Example', attributes[:firstname]
88 assert_equal 'One', attributes[:lastname]
88 assert_equal 'One', attributes[:lastname]
89 assert_equal 'example1@redmine.org', attributes[:mail]
89 assert_equal 'example1@redmine.org', attributes[:mail]
90 assert_equal auth.id, attributes[:auth_source_id]
90 assert_equal auth.id, attributes[:auth_source_id]
91 attributes.keys.each do |attribute|
91 attributes.keys.each do |attribute|
92 assert User.new.respond_to?("#{attribute}="), "Unexpected :#{attribute} attribute returned"
92 assert User.new.respond_to?("#{attribute}="), "Unexpected :#{attribute} attribute returned"
93 end
93 end
94 end
94 end
95
95
96 test '#authenticate with an invalid LDAP user should return nil' do
96 test '#authenticate with an invalid LDAP user should return nil' do
97 auth = AuthSourceLdap.find(1)
97 auth = AuthSourceLdap.find(1)
98 assert_nil auth.authenticate('nouser','123456')
98 assert_nil auth.authenticate('nouser','123456')
99 end
99 end
100
100
101 test '#authenticate without a login should return nil' do
101 test '#authenticate without a login should return nil' do
102 auth = AuthSourceLdap.find(1)
102 auth = AuthSourceLdap.find(1)
103 assert_nil auth.authenticate('','123456')
103 assert_nil auth.authenticate('','123456')
104 end
104 end
105
105
106 test '#authenticate without a password should return nil' do
106 test '#authenticate without a password should return nil' do
107 auth = AuthSourceLdap.find(1)
107 auth = AuthSourceLdap.find(1)
108 assert_nil auth.authenticate('edavis','')
108 assert_nil auth.authenticate('edavis','')
109 end
109 end
110
110
111 test '#authenticate without filter should return any user' do
111 test '#authenticate without filter should return any user' do
112 auth = AuthSourceLdap.find(1)
112 auth = AuthSourceLdap.find(1)
113 assert auth.authenticate('example1','123456')
113 assert auth.authenticate('example1','123456')
114 assert auth.authenticate('edavis', '123456')
114 assert auth.authenticate('edavis', '123456')
115 end
115 end
116
116
117 test '#authenticate with filter should return user who matches the filter only' do
117 test '#authenticate with filter should return user who matches the filter only' do
118 auth = AuthSourceLdap.find(1)
118 auth = AuthSourceLdap.find(1)
119 auth.filter = "(mail=*@redmine.org)"
119 auth.filter = "(mail=*@redmine.org)"
120
120
121 assert auth.authenticate('example1','123456')
121 assert auth.authenticate('example1','123456')
122 assert_nil auth.authenticate('edavis', '123456')
122 assert_nil auth.authenticate('edavis', '123456')
123 end
123 end
124
124
125 def test_authenticate_should_timeout
125 def test_authenticate_should_timeout
126 auth_source = AuthSourceLdap.find(1)
126 auth_source = AuthSourceLdap.find(1)
127 auth_source.timeout = 1
127 auth_source.timeout = 1
128 def auth_source.initialize_ldap_con(*args); sleep(5); end
128 def auth_source.initialize_ldap_con(*args); sleep(5); end
129
129
130 assert_raise AuthSourceTimeoutException do
130 assert_raise AuthSourceTimeoutException do
131 auth_source.authenticate 'example1', '123456'
131 auth_source.authenticate 'example1', '123456'
132 end
132 end
133 end
133 end
134
134
135 def test_search_should_return_matching_entries
135 def test_search_should_return_matching_entries
136 results = AuthSource.search("exa")
136 results = AuthSource.search("exa")
137 assert_equal 1, results.size
137 assert_equal 1, results.size
138 result = results.first
138 result = results.first
139 assert_kind_of Hash, result
139 assert_kind_of Hash, result
140 assert_equal "example1", result[:login]
140 assert_equal "example1", result[:login]
141 assert_equal "Example", result[:firstname]
141 assert_equal "Example", result[:firstname]
142 assert_equal "One", result[:lastname]
142 assert_equal "One", result[:lastname]
143 assert_equal "example1@redmine.org", result[:mail]
143 assert_equal "example1@redmine.org", result[:mail]
144 assert_equal 1, result[:auth_source_id]
144 assert_equal 1, result[:auth_source_id]
145 end
145 end
146
146
147 def test_search_with_no_match_should_return_an_empty_array
147 def test_search_with_no_match_should_return_an_empty_array
148 results = AuthSource.search("wro")
148 results = AuthSource.search("wro")
149 assert_equal [], results
149 assert_equal [], results
150 end
150 end
151
151
152 def test_search_with_exception_should_return_an_empty_array
152 def test_search_with_exception_should_return_an_empty_array
153 Net::LDAP.stubs(:new).raises(Net::LDAP::LdapError, 'Cannot connect')
153 Net::LDAP.stubs(:new).raises(Net::LDAP::Error, 'Cannot connect')
154
154
155 results = AuthSource.search("exa")
155 results = AuthSource.search("exa")
156 assert_equal [], results
156 assert_equal [], results
157 end
157 end
158
158
159 def test_test_connection_with_correct_host_and_port
159 def test_test_connection_with_correct_host_and_port
160 auth_source = AuthSourceLdap.find(1)
160 auth_source = AuthSourceLdap.find(1)
161
161
162 assert_nothing_raised Net::LDAP::Error do
162 assert_nothing_raised Net::LDAP::Error do
163 auth_source.test_connection
163 auth_source.test_connection
164 end
164 end
165 end
165 end
166
166
167 def test_test_connection_with_incorrect_host
167 def test_test_connection_with_incorrect_host
168 auth_source = AuthSourceLdap.find(1)
168 auth_source = AuthSourceLdap.find(1)
169 auth_source.host = "badhost"
169 auth_source.host = "badhost"
170 auth_source.save!
170 auth_source.save!
171
171
172 assert_raise Net::LDAP::Error do
172 assert_raise Net::LDAP::Error do
173 auth_source.test_connection
173 auth_source.test_connection
174 end
174 end
175 end
175 end
176
176
177 def test_test_connection_with_incorrect_port
177 def test_test_connection_with_incorrect_port
178 auth_source = AuthSourceLdap.find(1)
178 auth_source = AuthSourceLdap.find(1)
179 auth_source.port = 1234
179 auth_source.port = 1234
180 auth_source.save!
180 auth_source.save!
181
181
182 assert_raise Net::LDAP::Error do
182 assert_raise Net::LDAP::Error do
183 auth_source.test_connection
183 auth_source.test_connection
184 end
184 end
185 end
185 end
186
186
187 def test_test_connection_bind_with_account_and_password
187 def test_test_connection_bind_with_account_and_password
188 auth_source = AuthSourceLdap.find(1)
188 auth_source = AuthSourceLdap.find(1)
189 auth_source.account = "cn=admin,dc=redmine,dc=org"
189 auth_source.account = "cn=admin,dc=redmine,dc=org"
190 auth_source.account_password = "secret"
190 auth_source.account_password = "secret"
191 auth_source.save!
191 auth_source.save!
192
192
193 assert_equal "cn=admin,dc=redmine,dc=org", auth_source.account
193 assert_equal "cn=admin,dc=redmine,dc=org", auth_source.account
194 assert_equal "secret", auth_source.account_password
194 assert_equal "secret", auth_source.account_password
195 assert_nil auth_source.test_connection
195 assert_nil auth_source.test_connection
196 end
196 end
197
197
198 def test_test_connection_bind_without_account_and_password
198 def test_test_connection_bind_without_account_and_password
199 auth_source = AuthSourceLdap.find(1)
199 auth_source = AuthSourceLdap.find(1)
200
200
201 assert_nil auth_source.account
201 assert_nil auth_source.account
202 assert_equal "", auth_source.account_password
202 assert_equal "", auth_source.account_password
203 assert_nil auth_source.test_connection
203 assert_nil auth_source.test_connection
204 end
204 end
205
205
206 def test_test_connection_bind_with_incorrect_account
206 def test_test_connection_bind_with_incorrect_account
207 auth_source = AuthSourceLdap.find(1)
207 auth_source = AuthSourceLdap.find(1)
208 auth_source.account = "cn=baduser,dc=redmine,dc=org"
208 auth_source.account = "cn=baduser,dc=redmine,dc=org"
209 auth_source.account_password = "secret"
209 auth_source.account_password = "secret"
210 auth_source.save!
210 auth_source.save!
211
211
212 assert_equal "cn=baduser,dc=redmine,dc=org", auth_source.account
212 assert_equal "cn=baduser,dc=redmine,dc=org", auth_source.account
213 assert_equal "secret", auth_source.account_password
213 assert_equal "secret", auth_source.account_password
214 assert_raise AuthSourceException do
214 assert_raise AuthSourceException do
215 auth_source.test_connection
215 auth_source.test_connection
216 end
216 end
217 end
217 end
218
218
219 def test_test_connection_bind_with_incorrect_password
219 def test_test_connection_bind_with_incorrect_password
220 auth_source = AuthSourceLdap.find(1)
220 auth_source = AuthSourceLdap.find(1)
221 auth_source.account = "cn=admin,dc=redmine,dc=org"
221 auth_source.account = "cn=admin,dc=redmine,dc=org"
222 auth_source.account_password = "badpassword"
222 auth_source.account_password = "badpassword"
223 auth_source.save!
223 auth_source.save!
224
224
225 assert_equal "cn=admin,dc=redmine,dc=org", auth_source.account
225 assert_equal "cn=admin,dc=redmine,dc=org", auth_source.account
226 assert_equal "badpassword", auth_source.account_password
226 assert_equal "badpassword", auth_source.account_password
227 assert_raise AuthSourceException do
227 assert_raise AuthSourceException do
228 auth_source.test_connection
228 auth_source.test_connection
229 end
229 end
230 end
230 end
231 else
231 else
232 puts '(Test LDAP server not configured)'
232 puts '(Test LDAP server not configured)'
233 end
233 end
234 end
234 end
@@ -1,1238 +1,1238
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2016 Jean-Philippe Lang
2 # Copyright (C) 2006-2016 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.expand_path('../../test_helper', __FILE__)
18 require File.expand_path('../../test_helper', __FILE__)
19
19
20 class UserTest < ActiveSupport::TestCase
20 class UserTest < ActiveSupport::TestCase
21 fixtures :users, :email_addresses, :members, :projects, :roles, :member_roles, :auth_sources,
21 fixtures :users, :email_addresses, :members, :projects, :roles, :member_roles, :auth_sources,
22 :trackers, :issue_statuses,
22 :trackers, :issue_statuses,
23 :projects_trackers,
23 :projects_trackers,
24 :watchers,
24 :watchers,
25 :issue_categories, :enumerations, :issues,
25 :issue_categories, :enumerations, :issues,
26 :journals, :journal_details,
26 :journals, :journal_details,
27 :groups_users,
27 :groups_users,
28 :enabled_modules,
28 :enabled_modules,
29 :tokens
29 :tokens
30
30
31 include Redmine::I18n
31 include Redmine::I18n
32
32
33 def setup
33 def setup
34 @admin = User.find(1)
34 @admin = User.find(1)
35 @jsmith = User.find(2)
35 @jsmith = User.find(2)
36 @dlopper = User.find(3)
36 @dlopper = User.find(3)
37 end
37 end
38
38
39 def test_sorted_scope_should_sort_user_by_display_name
39 def test_sorted_scope_should_sort_user_by_display_name
40 # Use .active to ignore anonymous with localized display name
40 # Use .active to ignore anonymous with localized display name
41 assert_equal User.active.map(&:name).map(&:downcase).sort,
41 assert_equal User.active.map(&:name).map(&:downcase).sort,
42 User.active.sorted.map(&:name).map(&:downcase)
42 User.active.sorted.map(&:name).map(&:downcase)
43 end
43 end
44
44
45 def test_generate
45 def test_generate
46 User.generate!(:firstname => 'Testing connection')
46 User.generate!(:firstname => 'Testing connection')
47 User.generate!(:firstname => 'Testing connection')
47 User.generate!(:firstname => 'Testing connection')
48 assert_equal 2, User.where(:firstname => 'Testing connection').count
48 assert_equal 2, User.where(:firstname => 'Testing connection').count
49 end
49 end
50
50
51 def test_truth
51 def test_truth
52 assert_kind_of User, @jsmith
52 assert_kind_of User, @jsmith
53 end
53 end
54
54
55 def test_should_validate_status
55 def test_should_validate_status
56 user = User.new
56 user = User.new
57 user.status = 0
57 user.status = 0
58
58
59 assert !user.save
59 assert !user.save
60 assert_include I18n.translate('activerecord.errors.messages.invalid'), user.errors[:status]
60 assert_include I18n.translate('activerecord.errors.messages.invalid'), user.errors[:status]
61 end
61 end
62
62
63 def test_mail_should_be_stripped
63 def test_mail_should_be_stripped
64 u = User.new
64 u = User.new
65 u.mail = " foo@bar.com "
65 u.mail = " foo@bar.com "
66 assert_equal "foo@bar.com", u.mail
66 assert_equal "foo@bar.com", u.mail
67 end
67 end
68
68
69 def test_should_create_email_address
69 def test_should_create_email_address
70 u = User.new(:firstname => "new", :lastname => "user")
70 u = User.new(:firstname => "new", :lastname => "user")
71 u.login = "create_email_address"
71 u.login = "create_email_address"
72 u.mail = "defaultemail@somenet.foo"
72 u.mail = "defaultemail@somenet.foo"
73 assert u.save
73 assert u.save
74 u.reload
74 u.reload
75 assert u.email_address
75 assert u.email_address
76 assert_equal "defaultemail@somenet.foo", u.email_address.address
76 assert_equal "defaultemail@somenet.foo", u.email_address.address
77 assert_equal true, u.email_address.is_default
77 assert_equal true, u.email_address.is_default
78 assert_equal true, u.email_address.notify
78 assert_equal true, u.email_address.notify
79 end
79 end
80
80
81 def test_should_not_create_user_without_mail
81 def test_should_not_create_user_without_mail
82 set_language_if_valid 'en'
82 set_language_if_valid 'en'
83 u = User.new(:firstname => "new", :lastname => "user")
83 u = User.new(:firstname => "new", :lastname => "user")
84 u.login = "user_without_mail"
84 u.login = "user_without_mail"
85 assert !u.save
85 assert !u.save
86 assert_equal ["Email #{I18n.translate('activerecord.errors.messages.blank')}"], u.errors.full_messages
86 assert_equal ["Email #{I18n.translate('activerecord.errors.messages.blank')}"], u.errors.full_messages
87 end
87 end
88
88
89 def test_should_not_create_user_with_blank_mail
89 def test_should_not_create_user_with_blank_mail
90 set_language_if_valid 'en'
90 set_language_if_valid 'en'
91 u = User.new(:firstname => "new", :lastname => "user")
91 u = User.new(:firstname => "new", :lastname => "user")
92 u.login = "user_with_blank_mail"
92 u.login = "user_with_blank_mail"
93 u.mail = ''
93 u.mail = ''
94 assert !u.save
94 assert !u.save
95 assert_equal ["Email #{I18n.translate('activerecord.errors.messages.blank')}"], u.errors.full_messages
95 assert_equal ["Email #{I18n.translate('activerecord.errors.messages.blank')}"], u.errors.full_messages
96 end
96 end
97
97
98 def test_should_not_update_user_with_blank_mail
98 def test_should_not_update_user_with_blank_mail
99 set_language_if_valid 'en'
99 set_language_if_valid 'en'
100 u = User.find(2)
100 u = User.find(2)
101 u.mail = ''
101 u.mail = ''
102 assert !u.save
102 assert !u.save
103 assert_equal ["Email #{I18n.translate('activerecord.errors.messages.blank')}"], u.errors.full_messages
103 assert_equal ["Email #{I18n.translate('activerecord.errors.messages.blank')}"], u.errors.full_messages
104 end
104 end
105
105
106 def test_login_length_validation
106 def test_login_length_validation
107 user = User.new(:firstname => "new", :lastname => "user", :mail => "newuser@somenet.foo")
107 user = User.new(:firstname => "new", :lastname => "user", :mail => "newuser@somenet.foo")
108 user.login = "x" * (User::LOGIN_LENGTH_LIMIT+1)
108 user.login = "x" * (User::LOGIN_LENGTH_LIMIT+1)
109 assert !user.valid?
109 assert !user.valid?
110
110
111 user.login = "x" * (User::LOGIN_LENGTH_LIMIT)
111 user.login = "x" * (User::LOGIN_LENGTH_LIMIT)
112 assert user.valid?
112 assert user.valid?
113 assert user.save
113 assert user.save
114 end
114 end
115
115
116 def test_generate_password_should_respect_minimum_password_length
116 def test_generate_password_should_respect_minimum_password_length
117 with_settings :password_min_length => 15 do
117 with_settings :password_min_length => 15 do
118 user = User.generate!(:generate_password => true)
118 user = User.generate!(:generate_password => true)
119 assert user.password.length >= 15
119 assert user.password.length >= 15
120 end
120 end
121 end
121 end
122
122
123 def test_generate_password_should_not_generate_password_with_less_than_10_characters
123 def test_generate_password_should_not_generate_password_with_less_than_10_characters
124 with_settings :password_min_length => 4 do
124 with_settings :password_min_length => 4 do
125 user = User.generate!(:generate_password => true)
125 user = User.generate!(:generate_password => true)
126 assert user.password.length >= 10
126 assert user.password.length >= 10
127 end
127 end
128 end
128 end
129
129
130 def test_generate_password_on_create_should_set_password
130 def test_generate_password_on_create_should_set_password
131 user = User.new(:firstname => "new", :lastname => "user", :mail => "newuser@somenet.foo")
131 user = User.new(:firstname => "new", :lastname => "user", :mail => "newuser@somenet.foo")
132 user.login = "newuser"
132 user.login = "newuser"
133 user.generate_password = true
133 user.generate_password = true
134 assert user.save
134 assert user.save
135
135
136 password = user.password
136 password = user.password
137 assert user.check_password?(password)
137 assert user.check_password?(password)
138 end
138 end
139
139
140 def test_generate_password_on_update_should_update_password
140 def test_generate_password_on_update_should_update_password
141 user = User.find(2)
141 user = User.find(2)
142 hash = user.hashed_password
142 hash = user.hashed_password
143 user.generate_password = true
143 user.generate_password = true
144 assert user.save
144 assert user.save
145
145
146 password = user.password
146 password = user.password
147 assert user.check_password?(password)
147 assert user.check_password?(password)
148 assert_not_equal hash, user.reload.hashed_password
148 assert_not_equal hash, user.reload.hashed_password
149 end
149 end
150
150
151 def test_create
151 def test_create
152 user = User.new(:firstname => "new", :lastname => "user", :mail => "newuser@somenet.foo")
152 user = User.new(:firstname => "new", :lastname => "user", :mail => "newuser@somenet.foo")
153
153
154 user.login = "jsmith"
154 user.login = "jsmith"
155 user.password, user.password_confirmation = "password", "password"
155 user.password, user.password_confirmation = "password", "password"
156 # login uniqueness
156 # login uniqueness
157 assert !user.save
157 assert !user.save
158 assert_equal 1, user.errors.count
158 assert_equal 1, user.errors.count
159
159
160 user.login = "newuser"
160 user.login = "newuser"
161 user.password, user.password_confirmation = "password", "pass"
161 user.password, user.password_confirmation = "password", "pass"
162 # password confirmation
162 # password confirmation
163 assert !user.save
163 assert !user.save
164 assert_equal 1, user.errors.count
164 assert_equal 1, user.errors.count
165
165
166 user.password, user.password_confirmation = "password", "password"
166 user.password, user.password_confirmation = "password", "password"
167 assert user.save
167 assert user.save
168 end
168 end
169
169
170 def test_user_before_create_should_set_the_mail_notification_to_the_default_setting
170 def test_user_before_create_should_set_the_mail_notification_to_the_default_setting
171 @user1 = User.generate!
171 @user1 = User.generate!
172 assert_equal 'only_my_events', @user1.mail_notification
172 assert_equal 'only_my_events', @user1.mail_notification
173 with_settings :default_notification_option => 'all' do
173 with_settings :default_notification_option => 'all' do
174 @user2 = User.generate!
174 @user2 = User.generate!
175 assert_equal 'all', @user2.mail_notification
175 assert_equal 'all', @user2.mail_notification
176 end
176 end
177 end
177 end
178
178
179 def test_user_login_should_be_case_insensitive
179 def test_user_login_should_be_case_insensitive
180 u = User.new(:firstname => "new", :lastname => "user", :mail => "newuser@somenet.foo")
180 u = User.new(:firstname => "new", :lastname => "user", :mail => "newuser@somenet.foo")
181 u.login = 'newuser'
181 u.login = 'newuser'
182 u.password, u.password_confirmation = "password", "password"
182 u.password, u.password_confirmation = "password", "password"
183 assert u.save
183 assert u.save
184 u = User.new(:firstname => "Similar", :lastname => "User",
184 u = User.new(:firstname => "Similar", :lastname => "User",
185 :mail => "similaruser@somenet.foo")
185 :mail => "similaruser@somenet.foo")
186 u.login = 'NewUser'
186 u.login = 'NewUser'
187 u.password, u.password_confirmation = "password", "password"
187 u.password, u.password_confirmation = "password", "password"
188 assert !u.save
188 assert !u.save
189 assert_include I18n.translate('activerecord.errors.messages.taken'), u.errors[:login]
189 assert_include I18n.translate('activerecord.errors.messages.taken'), u.errors[:login]
190 end
190 end
191
191
192 def test_mail_uniqueness_should_not_be_case_sensitive
192 def test_mail_uniqueness_should_not_be_case_sensitive
193 set_language_if_valid 'en'
193 set_language_if_valid 'en'
194 u = User.new(:firstname => "new", :lastname => "user", :mail => "newuser@somenet.foo")
194 u = User.new(:firstname => "new", :lastname => "user", :mail => "newuser@somenet.foo")
195 u.login = 'newuser1'
195 u.login = 'newuser1'
196 u.password, u.password_confirmation = "password", "password"
196 u.password, u.password_confirmation = "password", "password"
197 assert u.save
197 assert u.save
198
198
199 u = User.new(:firstname => "new", :lastname => "user", :mail => "newUser@Somenet.foo")
199 u = User.new(:firstname => "new", :lastname => "user", :mail => "newUser@Somenet.foo")
200 u.login = 'newuser2'
200 u.login = 'newuser2'
201 u.password, u.password_confirmation = "password", "password"
201 u.password, u.password_confirmation = "password", "password"
202 assert !u.save
202 assert !u.save
203 assert_include "Email #{I18n.translate('activerecord.errors.messages.taken')}", u.errors.full_messages
203 assert_include "Email #{I18n.translate('activerecord.errors.messages.taken')}", u.errors.full_messages
204 end
204 end
205
205
206 def test_update
206 def test_update
207 assert_equal "admin", @admin.login
207 assert_equal "admin", @admin.login
208 @admin.login = "john"
208 @admin.login = "john"
209 assert @admin.save, @admin.errors.full_messages.join("; ")
209 assert @admin.save, @admin.errors.full_messages.join("; ")
210 @admin.reload
210 @admin.reload
211 assert_equal "john", @admin.login
211 assert_equal "john", @admin.login
212 end
212 end
213
213
214 def test_update_should_not_fail_for_legacy_user_with_different_case_logins
214 def test_update_should_not_fail_for_legacy_user_with_different_case_logins
215 u1 = User.new(:firstname => "new", :lastname => "user", :mail => "newuser1@somenet.foo")
215 u1 = User.new(:firstname => "new", :lastname => "user", :mail => "newuser1@somenet.foo")
216 u1.login = 'newuser1'
216 u1.login = 'newuser1'
217 assert u1.save
217 assert u1.save
218
218
219 u2 = User.new(:firstname => "new", :lastname => "user", :mail => "newuser2@somenet.foo")
219 u2 = User.new(:firstname => "new", :lastname => "user", :mail => "newuser2@somenet.foo")
220 u2.login = 'newuser1'
220 u2.login = 'newuser1'
221 assert u2.save(:validate => false)
221 assert u2.save(:validate => false)
222
222
223 user = User.find(u2.id)
223 user = User.find(u2.id)
224 user.firstname = "firstname"
224 user.firstname = "firstname"
225 assert user.save, "Save failed"
225 assert user.save, "Save failed"
226 end
226 end
227
227
228 def test_destroy_should_delete_members_and_roles
228 def test_destroy_should_delete_members_and_roles
229 members = Member.where(:user_id => 2)
229 members = Member.where(:user_id => 2)
230 ms = members.count
230 ms = members.count
231 rs = members.collect(&:roles).flatten.size
231 rs = members.collect(&:roles).flatten.size
232 assert ms > 0
232 assert ms > 0
233 assert rs > 0
233 assert rs > 0
234 assert_difference 'Member.count', - ms do
234 assert_difference 'Member.count', - ms do
235 assert_difference 'MemberRole.count', - rs do
235 assert_difference 'MemberRole.count', - rs do
236 User.find(2).destroy
236 User.find(2).destroy
237 end
237 end
238 end
238 end
239 assert_nil User.find_by_id(2)
239 assert_nil User.find_by_id(2)
240 assert_equal 0, Member.where(:user_id => 2).count
240 assert_equal 0, Member.where(:user_id => 2).count
241 end
241 end
242
242
243 def test_destroy_should_update_attachments
243 def test_destroy_should_update_attachments
244 attachment = Attachment.create!(:container => Project.find(1),
244 attachment = Attachment.create!(:container => Project.find(1),
245 :file => uploaded_test_file("testfile.txt", "text/plain"),
245 :file => uploaded_test_file("testfile.txt", "text/plain"),
246 :author_id => 2)
246 :author_id => 2)
247
247
248 User.find(2).destroy
248 User.find(2).destroy
249 assert_nil User.find_by_id(2)
249 assert_nil User.find_by_id(2)
250 assert_equal User.anonymous, attachment.reload.author
250 assert_equal User.anonymous, attachment.reload.author
251 end
251 end
252
252
253 def test_destroy_should_update_comments
253 def test_destroy_should_update_comments
254 comment = Comment.create!(
254 comment = Comment.create!(
255 :commented => News.create!(:project_id => 1,
255 :commented => News.create!(:project_id => 1,
256 :author_id => 1, :title => 'foo', :description => 'foo'),
256 :author_id => 1, :title => 'foo', :description => 'foo'),
257 :author => User.find(2),
257 :author => User.find(2),
258 :comments => 'foo'
258 :comments => 'foo'
259 )
259 )
260
260
261 User.find(2).destroy
261 User.find(2).destroy
262 assert_nil User.find_by_id(2)
262 assert_nil User.find_by_id(2)
263 assert_equal User.anonymous, comment.reload.author
263 assert_equal User.anonymous, comment.reload.author
264 end
264 end
265
265
266 def test_destroy_should_update_issues
266 def test_destroy_should_update_issues
267 issue = Issue.create!(:project_id => 1, :author_id => 2,
267 issue = Issue.create!(:project_id => 1, :author_id => 2,
268 :tracker_id => 1, :subject => 'foo')
268 :tracker_id => 1, :subject => 'foo')
269
269
270 User.find(2).destroy
270 User.find(2).destroy
271 assert_nil User.find_by_id(2)
271 assert_nil User.find_by_id(2)
272 assert_equal User.anonymous, issue.reload.author
272 assert_equal User.anonymous, issue.reload.author
273 end
273 end
274
274
275 def test_destroy_should_unassign_issues
275 def test_destroy_should_unassign_issues
276 issue = Issue.create!(:project_id => 1, :author_id => 1,
276 issue = Issue.create!(:project_id => 1, :author_id => 1,
277 :tracker_id => 1, :subject => 'foo', :assigned_to_id => 2)
277 :tracker_id => 1, :subject => 'foo', :assigned_to_id => 2)
278
278
279 User.find(2).destroy
279 User.find(2).destroy
280 assert_nil User.find_by_id(2)
280 assert_nil User.find_by_id(2)
281 assert_nil issue.reload.assigned_to
281 assert_nil issue.reload.assigned_to
282 end
282 end
283
283
284 def test_destroy_should_update_journals
284 def test_destroy_should_update_journals
285 issue = Issue.create!(:project_id => 1, :author_id => 2,
285 issue = Issue.create!(:project_id => 1, :author_id => 2,
286 :tracker_id => 1, :subject => 'foo')
286 :tracker_id => 1, :subject => 'foo')
287 issue.init_journal(User.find(2), "update")
287 issue.init_journal(User.find(2), "update")
288 issue.save!
288 issue.save!
289
289
290 User.find(2).destroy
290 User.find(2).destroy
291 assert_nil User.find_by_id(2)
291 assert_nil User.find_by_id(2)
292 assert_equal User.anonymous, issue.journals.first.reload.user
292 assert_equal User.anonymous, issue.journals.first.reload.user
293 end
293 end
294
294
295 def test_destroy_should_update_journal_details_old_value
295 def test_destroy_should_update_journal_details_old_value
296 issue = Issue.create!(:project_id => 1, :author_id => 1,
296 issue = Issue.create!(:project_id => 1, :author_id => 1,
297 :tracker_id => 1, :subject => 'foo', :assigned_to_id => 2)
297 :tracker_id => 1, :subject => 'foo', :assigned_to_id => 2)
298 issue.init_journal(User.find(1), "update")
298 issue.init_journal(User.find(1), "update")
299 issue.assigned_to_id = nil
299 issue.assigned_to_id = nil
300 assert_difference 'JournalDetail.count' do
300 assert_difference 'JournalDetail.count' do
301 issue.save!
301 issue.save!
302 end
302 end
303 journal_detail = JournalDetail.order('id DESC').first
303 journal_detail = JournalDetail.order('id DESC').first
304 assert_equal '2', journal_detail.old_value
304 assert_equal '2', journal_detail.old_value
305
305
306 User.find(2).destroy
306 User.find(2).destroy
307 assert_nil User.find_by_id(2)
307 assert_nil User.find_by_id(2)
308 assert_equal User.anonymous.id.to_s, journal_detail.reload.old_value
308 assert_equal User.anonymous.id.to_s, journal_detail.reload.old_value
309 end
309 end
310
310
311 def test_destroy_should_update_journal_details_value
311 def test_destroy_should_update_journal_details_value
312 issue = Issue.create!(:project_id => 1, :author_id => 1,
312 issue = Issue.create!(:project_id => 1, :author_id => 1,
313 :tracker_id => 1, :subject => 'foo')
313 :tracker_id => 1, :subject => 'foo')
314 issue.init_journal(User.find(1), "update")
314 issue.init_journal(User.find(1), "update")
315 issue.assigned_to_id = 2
315 issue.assigned_to_id = 2
316 assert_difference 'JournalDetail.count' do
316 assert_difference 'JournalDetail.count' do
317 issue.save!
317 issue.save!
318 end
318 end
319 journal_detail = JournalDetail.order('id DESC').first
319 journal_detail = JournalDetail.order('id DESC').first
320 assert_equal '2', journal_detail.value
320 assert_equal '2', journal_detail.value
321
321
322 User.find(2).destroy
322 User.find(2).destroy
323 assert_nil User.find_by_id(2)
323 assert_nil User.find_by_id(2)
324 assert_equal User.anonymous.id.to_s, journal_detail.reload.value
324 assert_equal User.anonymous.id.to_s, journal_detail.reload.value
325 end
325 end
326
326
327 def test_destroy_should_update_messages
327 def test_destroy_should_update_messages
328 board = Board.create!(:project_id => 1, :name => 'Board', :description => 'Board')
328 board = Board.create!(:project_id => 1, :name => 'Board', :description => 'Board')
329 message = Message.create!(:board_id => board.id, :author_id => 2,
329 message = Message.create!(:board_id => board.id, :author_id => 2,
330 :subject => 'foo', :content => 'foo')
330 :subject => 'foo', :content => 'foo')
331 User.find(2).destroy
331 User.find(2).destroy
332 assert_nil User.find_by_id(2)
332 assert_nil User.find_by_id(2)
333 assert_equal User.anonymous, message.reload.author
333 assert_equal User.anonymous, message.reload.author
334 end
334 end
335
335
336 def test_destroy_should_update_news
336 def test_destroy_should_update_news
337 news = News.create!(:project_id => 1, :author_id => 2,
337 news = News.create!(:project_id => 1, :author_id => 2,
338 :title => 'foo', :description => 'foo')
338 :title => 'foo', :description => 'foo')
339 User.find(2).destroy
339 User.find(2).destroy
340 assert_nil User.find_by_id(2)
340 assert_nil User.find_by_id(2)
341 assert_equal User.anonymous, news.reload.author
341 assert_equal User.anonymous, news.reload.author
342 end
342 end
343
343
344 def test_destroy_should_delete_private_queries
344 def test_destroy_should_delete_private_queries
345 query = Query.new(:name => 'foo', :visibility => Query::VISIBILITY_PRIVATE)
345 query = Query.new(:name => 'foo', :visibility => Query::VISIBILITY_PRIVATE)
346 query.project_id = 1
346 query.project_id = 1
347 query.user_id = 2
347 query.user_id = 2
348 query.save!
348 query.save!
349
349
350 User.find(2).destroy
350 User.find(2).destroy
351 assert_nil User.find_by_id(2)
351 assert_nil User.find_by_id(2)
352 assert_nil Query.find_by_id(query.id)
352 assert_nil Query.find_by_id(query.id)
353 end
353 end
354
354
355 def test_destroy_should_update_public_queries
355 def test_destroy_should_update_public_queries
356 query = Query.new(:name => 'foo', :visibility => Query::VISIBILITY_PUBLIC)
356 query = Query.new(:name => 'foo', :visibility => Query::VISIBILITY_PUBLIC)
357 query.project_id = 1
357 query.project_id = 1
358 query.user_id = 2
358 query.user_id = 2
359 query.save!
359 query.save!
360
360
361 User.find(2).destroy
361 User.find(2).destroy
362 assert_nil User.find_by_id(2)
362 assert_nil User.find_by_id(2)
363 assert_equal User.anonymous, query.reload.user
363 assert_equal User.anonymous, query.reload.user
364 end
364 end
365
365
366 def test_destroy_should_update_time_entries
366 def test_destroy_should_update_time_entries
367 entry = TimeEntry.new(:hours => '2', :spent_on => Date.today,
367 entry = TimeEntry.new(:hours => '2', :spent_on => Date.today,
368 :activity => TimeEntryActivity.create!(:name => 'foo'))
368 :activity => TimeEntryActivity.create!(:name => 'foo'))
369 entry.project_id = 1
369 entry.project_id = 1
370 entry.user_id = 2
370 entry.user_id = 2
371 entry.save!
371 entry.save!
372
372
373 User.find(2).destroy
373 User.find(2).destroy
374 assert_nil User.find_by_id(2)
374 assert_nil User.find_by_id(2)
375 assert_equal User.anonymous, entry.reload.user
375 assert_equal User.anonymous, entry.reload.user
376 end
376 end
377
377
378 def test_destroy_should_delete_tokens
378 def test_destroy_should_delete_tokens
379 token = Token.create!(:user_id => 2, :value => 'foo')
379 token = Token.create!(:user_id => 2, :value => 'foo')
380
380
381 User.find(2).destroy
381 User.find(2).destroy
382 assert_nil User.find_by_id(2)
382 assert_nil User.find_by_id(2)
383 assert_nil Token.find_by_id(token.id)
383 assert_nil Token.find_by_id(token.id)
384 end
384 end
385
385
386 def test_destroy_should_delete_watchers
386 def test_destroy_should_delete_watchers
387 issue = Issue.create!(:project_id => 1, :author_id => 1,
387 issue = Issue.create!(:project_id => 1, :author_id => 1,
388 :tracker_id => 1, :subject => 'foo')
388 :tracker_id => 1, :subject => 'foo')
389 watcher = Watcher.create!(:user_id => 2, :watchable => issue)
389 watcher = Watcher.create!(:user_id => 2, :watchable => issue)
390
390
391 User.find(2).destroy
391 User.find(2).destroy
392 assert_nil User.find_by_id(2)
392 assert_nil User.find_by_id(2)
393 assert_nil Watcher.find_by_id(watcher.id)
393 assert_nil Watcher.find_by_id(watcher.id)
394 end
394 end
395
395
396 def test_destroy_should_update_wiki_contents
396 def test_destroy_should_update_wiki_contents
397 wiki_content = WikiContent.create!(
397 wiki_content = WikiContent.create!(
398 :text => 'foo',
398 :text => 'foo',
399 :author_id => 2,
399 :author_id => 2,
400 :page => WikiPage.create!(:title => 'Foo',
400 :page => WikiPage.create!(:title => 'Foo',
401 :wiki => Wiki.create!(:project_id => 3,
401 :wiki => Wiki.create!(:project_id => 3,
402 :start_page => 'Start'))
402 :start_page => 'Start'))
403 )
403 )
404 wiki_content.text = 'bar'
404 wiki_content.text = 'bar'
405 assert_difference 'WikiContent::Version.count' do
405 assert_difference 'WikiContent::Version.count' do
406 wiki_content.save!
406 wiki_content.save!
407 end
407 end
408
408
409 User.find(2).destroy
409 User.find(2).destroy
410 assert_nil User.find_by_id(2)
410 assert_nil User.find_by_id(2)
411 assert_equal User.anonymous, wiki_content.reload.author
411 assert_equal User.anonymous, wiki_content.reload.author
412 wiki_content.versions.each do |version|
412 wiki_content.versions.each do |version|
413 assert_equal User.anonymous, version.reload.author
413 assert_equal User.anonymous, version.reload.author
414 end
414 end
415 end
415 end
416
416
417 def test_destroy_should_nullify_issue_categories
417 def test_destroy_should_nullify_issue_categories
418 category = IssueCategory.create!(:project_id => 1, :assigned_to_id => 2, :name => 'foo')
418 category = IssueCategory.create!(:project_id => 1, :assigned_to_id => 2, :name => 'foo')
419
419
420 User.find(2).destroy
420 User.find(2).destroy
421 assert_nil User.find_by_id(2)
421 assert_nil User.find_by_id(2)
422 assert_nil category.reload.assigned_to_id
422 assert_nil category.reload.assigned_to_id
423 end
423 end
424
424
425 def test_destroy_should_nullify_changesets
425 def test_destroy_should_nullify_changesets
426 changeset = Changeset.create!(
426 changeset = Changeset.create!(
427 :repository => Repository::Subversion.create!(
427 :repository => Repository::Subversion.create!(
428 :project_id => 1,
428 :project_id => 1,
429 :url => 'file:///tmp',
429 :url => 'file:///tmp',
430 :identifier => 'tmp'
430 :identifier => 'tmp'
431 ),
431 ),
432 :revision => '12',
432 :revision => '12',
433 :committed_on => Time.now,
433 :committed_on => Time.now,
434 :committer => 'jsmith'
434 :committer => 'jsmith'
435 )
435 )
436 assert_equal 2, changeset.user_id
436 assert_equal 2, changeset.user_id
437
437
438 User.find(2).destroy
438 User.find(2).destroy
439 assert_nil User.find_by_id(2)
439 assert_nil User.find_by_id(2)
440 assert_nil changeset.reload.user_id
440 assert_nil changeset.reload.user_id
441 end
441 end
442
442
443 def test_anonymous_user_should_not_be_destroyable
443 def test_anonymous_user_should_not_be_destroyable
444 assert_no_difference 'User.count' do
444 assert_no_difference 'User.count' do
445 assert_equal false, User.anonymous.destroy
445 assert_equal false, User.anonymous.destroy
446 end
446 end
447 end
447 end
448
448
449 def test_password_change_should_destroy_tokens
449 def test_password_change_should_destroy_tokens
450 recovery_token = Token.create!(:user_id => 2, :action => 'recovery')
450 recovery_token = Token.create!(:user_id => 2, :action => 'recovery')
451 autologin_token = Token.create!(:user_id => 2, :action => 'autologin')
451 autologin_token = Token.create!(:user_id => 2, :action => 'autologin')
452
452
453 user = User.find(2)
453 user = User.find(2)
454 user.password, user.password_confirmation = "a new password", "a new password"
454 user.password, user.password_confirmation = "a new password", "a new password"
455 assert user.save
455 assert user.save
456
456
457 assert_nil Token.find_by_id(recovery_token.id)
457 assert_nil Token.find_by_id(recovery_token.id)
458 assert_nil Token.find_by_id(autologin_token.id)
458 assert_nil Token.find_by_id(autologin_token.id)
459 end
459 end
460
460
461 def test_mail_change_should_destroy_tokens
461 def test_mail_change_should_destroy_tokens
462 recovery_token = Token.create!(:user_id => 2, :action => 'recovery')
462 recovery_token = Token.create!(:user_id => 2, :action => 'recovery')
463 autologin_token = Token.create!(:user_id => 2, :action => 'autologin')
463 autologin_token = Token.create!(:user_id => 2, :action => 'autologin')
464
464
465 user = User.find(2)
465 user = User.find(2)
466 user.mail = "user@somwehere.com"
466 user.mail = "user@somwehere.com"
467 assert user.save
467 assert user.save
468
468
469 assert_nil Token.find_by_id(recovery_token.id)
469 assert_nil Token.find_by_id(recovery_token.id)
470 assert_equal autologin_token, Token.find_by_id(autologin_token.id)
470 assert_equal autologin_token, Token.find_by_id(autologin_token.id)
471 end
471 end
472
472
473 def test_change_on_other_fields_should_not_destroy_tokens
473 def test_change_on_other_fields_should_not_destroy_tokens
474 recovery_token = Token.create!(:user_id => 2, :action => 'recovery')
474 recovery_token = Token.create!(:user_id => 2, :action => 'recovery')
475 autologin_token = Token.create!(:user_id => 2, :action => 'autologin')
475 autologin_token = Token.create!(:user_id => 2, :action => 'autologin')
476
476
477 user = User.find(2)
477 user = User.find(2)
478 user.firstname = "Bobby"
478 user.firstname = "Bobby"
479 assert user.save
479 assert user.save
480
480
481 assert_equal recovery_token, Token.find_by_id(recovery_token.id)
481 assert_equal recovery_token, Token.find_by_id(recovery_token.id)
482 assert_equal autologin_token, Token.find_by_id(autologin_token.id)
482 assert_equal autologin_token, Token.find_by_id(autologin_token.id)
483 end
483 end
484
484
485 def test_validate_login_presence
485 def test_validate_login_presence
486 @admin.login = ""
486 @admin.login = ""
487 assert !@admin.save
487 assert !@admin.save
488 assert_equal 1, @admin.errors.count
488 assert_equal 1, @admin.errors.count
489 end
489 end
490
490
491 def test_validate_mail_notification_inclusion
491 def test_validate_mail_notification_inclusion
492 u = User.new
492 u = User.new
493 u.mail_notification = 'foo'
493 u.mail_notification = 'foo'
494 u.save
494 u.save
495 assert_not_equal [], u.errors[:mail_notification]
495 assert_not_equal [], u.errors[:mail_notification]
496 end
496 end
497
497
498 def test_password
498 def test_password
499 user = User.try_to_login("admin", "admin")
499 user = User.try_to_login("admin", "admin")
500 assert_kind_of User, user
500 assert_kind_of User, user
501 assert_equal "admin", user.login
501 assert_equal "admin", user.login
502 user.password = "hello123"
502 user.password = "hello123"
503 assert user.save
503 assert user.save
504
504
505 user = User.try_to_login("admin", "hello123")
505 user = User.try_to_login("admin", "hello123")
506 assert_kind_of User, user
506 assert_kind_of User, user
507 assert_equal "admin", user.login
507 assert_equal "admin", user.login
508 end
508 end
509
509
510 def test_validate_password_length
510 def test_validate_password_length
511 with_settings :password_min_length => '100' do
511 with_settings :password_min_length => '100' do
512 user = User.new(:firstname => "new100",
512 user = User.new(:firstname => "new100",
513 :lastname => "user100", :mail => "newuser100@somenet.foo")
513 :lastname => "user100", :mail => "newuser100@somenet.foo")
514 user.login = "newuser100"
514 user.login = "newuser100"
515 user.password, user.password_confirmation = "password100", "password100"
515 user.password, user.password_confirmation = "password100", "password100"
516 assert !user.save
516 assert !user.save
517 assert_equal 1, user.errors.count
517 assert_equal 1, user.errors.count
518 end
518 end
519 end
519 end
520
520
521 def test_name_format
521 def test_name_format
522 assert_equal 'John S.', @jsmith.name(:firstname_lastinitial)
522 assert_equal 'John S.', @jsmith.name(:firstname_lastinitial)
523 assert_equal 'Smith, John', @jsmith.name(:lastname_comma_firstname)
523 assert_equal 'Smith, John', @jsmith.name(:lastname_comma_firstname)
524 assert_equal 'J. Smith', @jsmith.name(:firstinitial_lastname)
524 assert_equal 'J. Smith', @jsmith.name(:firstinitial_lastname)
525 assert_equal 'J.-P. Lang', User.new(:firstname => 'Jean-Philippe', :lastname => 'Lang').name(:firstinitial_lastname)
525 assert_equal 'J.-P. Lang', User.new(:firstname => 'Jean-Philippe', :lastname => 'Lang').name(:firstinitial_lastname)
526 end
526 end
527
527
528 def test_name_should_use_setting_as_default_format
528 def test_name_should_use_setting_as_default_format
529 with_settings :user_format => :firstname_lastname do
529 with_settings :user_format => :firstname_lastname do
530 assert_equal 'John Smith', @jsmith.reload.name
530 assert_equal 'John Smith', @jsmith.reload.name
531 end
531 end
532 with_settings :user_format => :username do
532 with_settings :user_format => :username do
533 assert_equal 'jsmith', @jsmith.reload.name
533 assert_equal 'jsmith', @jsmith.reload.name
534 end
534 end
535 with_settings :user_format => :lastname do
535 with_settings :user_format => :lastname do
536 assert_equal 'Smith', @jsmith.reload.name
536 assert_equal 'Smith', @jsmith.reload.name
537 end
537 end
538 end
538 end
539
539
540 def test_today_should_return_the_day_according_to_user_time_zone
540 def test_today_should_return_the_day_according_to_user_time_zone
541 preference = User.find(1).pref
541 preference = User.find(1).pref
542 date = Date.new(2012, 05, 15)
542 date = Date.new(2012, 05, 15)
543 time = Time.gm(2012, 05, 15, 23, 30).utc # 2012-05-15 23:30 UTC
543 time = Time.gm(2012, 05, 15, 23, 30).utc # 2012-05-15 23:30 UTC
544 Date.stubs(:today).returns(date)
544 Date.stubs(:today).returns(date)
545 Time.stubs(:now).returns(time)
545 Time.stubs(:now).returns(time)
546
546
547 preference.update_attribute :time_zone, 'Baku' # UTC+4
547 preference.update_attribute :time_zone, 'Baku' # UTC+4
548 assert_equal '2012-05-16', User.find(1).today.to_s
548 assert_equal '2012-05-16', User.find(1).today.to_s
549
549
550 preference.update_attribute :time_zone, 'La Paz' # UTC-4
550 preference.update_attribute :time_zone, 'La Paz' # UTC-4
551 assert_equal '2012-05-15', User.find(1).today.to_s
551 assert_equal '2012-05-15', User.find(1).today.to_s
552
552
553 preference.update_attribute :time_zone, ''
553 preference.update_attribute :time_zone, ''
554 assert_equal '2012-05-15', User.find(1).today.to_s
554 assert_equal '2012-05-15', User.find(1).today.to_s
555 end
555 end
556
556
557 def test_time_to_date_should_return_the_date_according_to_user_time_zone
557 def test_time_to_date_should_return_the_date_according_to_user_time_zone
558 preference = User.find(1).pref
558 preference = User.find(1).pref
559 time = Time.gm(2012, 05, 15, 23, 30).utc # 2012-05-15 23:30 UTC
559 time = Time.gm(2012, 05, 15, 23, 30).utc # 2012-05-15 23:30 UTC
560
560
561 preference.update_attribute :time_zone, 'Baku' # UTC+4
561 preference.update_attribute :time_zone, 'Baku' # UTC+4
562 assert_equal '2012-05-16', User.find(1).time_to_date(time).to_s
562 assert_equal '2012-05-16', User.find(1).time_to_date(time).to_s
563
563
564 preference.update_attribute :time_zone, 'La Paz' # UTC-4
564 preference.update_attribute :time_zone, 'La Paz' # UTC-4
565 assert_equal '2012-05-15', User.find(1).time_to_date(time).to_s
565 assert_equal '2012-05-15', User.find(1).time_to_date(time).to_s
566
566
567 preference.update_attribute :time_zone, ''
567 preference.update_attribute :time_zone, ''
568 assert_equal '2012-05-15', User.find(1).time_to_date(time).to_s
568 assert_equal '2012-05-15', User.find(1).time_to_date(time).to_s
569 end
569 end
570
570
571 def test_fields_for_order_statement_should_return_fields_according_user_format_setting
571 def test_fields_for_order_statement_should_return_fields_according_user_format_setting
572 with_settings :user_format => 'lastname_comma_firstname' do
572 with_settings :user_format => 'lastname_comma_firstname' do
573 assert_equal ['users.lastname', 'users.firstname', 'users.id'],
573 assert_equal ['users.lastname', 'users.firstname', 'users.id'],
574 User.fields_for_order_statement
574 User.fields_for_order_statement
575 end
575 end
576 end
576 end
577
577
578 def test_fields_for_order_statement_width_table_name_should_prepend_table_name
578 def test_fields_for_order_statement_width_table_name_should_prepend_table_name
579 with_settings :user_format => 'lastname_firstname' do
579 with_settings :user_format => 'lastname_firstname' do
580 assert_equal ['authors.lastname', 'authors.firstname', 'authors.id'],
580 assert_equal ['authors.lastname', 'authors.firstname', 'authors.id'],
581 User.fields_for_order_statement('authors')
581 User.fields_for_order_statement('authors')
582 end
582 end
583 end
583 end
584
584
585 def test_fields_for_order_statement_with_blank_format_should_return_default
585 def test_fields_for_order_statement_with_blank_format_should_return_default
586 with_settings :user_format => '' do
586 with_settings :user_format => '' do
587 assert_equal ['users.firstname', 'users.lastname', 'users.id'],
587 assert_equal ['users.firstname', 'users.lastname', 'users.id'],
588 User.fields_for_order_statement
588 User.fields_for_order_statement
589 end
589 end
590 end
590 end
591
591
592 def test_fields_for_order_statement_with_invalid_format_should_return_default
592 def test_fields_for_order_statement_with_invalid_format_should_return_default
593 with_settings :user_format => 'foo' do
593 with_settings :user_format => 'foo' do
594 assert_equal ['users.firstname', 'users.lastname', 'users.id'],
594 assert_equal ['users.firstname', 'users.lastname', 'users.id'],
595 User.fields_for_order_statement
595 User.fields_for_order_statement
596 end
596 end
597 end
597 end
598
598
599 test ".try_to_login with good credentials should return the user" do
599 test ".try_to_login with good credentials should return the user" do
600 user = User.try_to_login("admin", "admin")
600 user = User.try_to_login("admin", "admin")
601 assert_kind_of User, user
601 assert_kind_of User, user
602 assert_equal "admin", user.login
602 assert_equal "admin", user.login
603 end
603 end
604
604
605 test ".try_to_login with wrong credentials should return nil" do
605 test ".try_to_login with wrong credentials should return nil" do
606 assert_nil User.try_to_login("admin", "foo")
606 assert_nil User.try_to_login("admin", "foo")
607 end
607 end
608
608
609 def test_try_to_login_with_locked_user_should_return_nil
609 def test_try_to_login_with_locked_user_should_return_nil
610 @jsmith.status = User::STATUS_LOCKED
610 @jsmith.status = User::STATUS_LOCKED
611 @jsmith.save!
611 @jsmith.save!
612
612
613 user = User.try_to_login("jsmith", "jsmith")
613 user = User.try_to_login("jsmith", "jsmith")
614 assert_nil user
614 assert_nil user
615 end
615 end
616
616
617 def test_try_to_login_with_locked_user_and_not_active_only_should_return_user
617 def test_try_to_login_with_locked_user_and_not_active_only_should_return_user
618 @jsmith.status = User::STATUS_LOCKED
618 @jsmith.status = User::STATUS_LOCKED
619 @jsmith.save!
619 @jsmith.save!
620
620
621 user = User.try_to_login("jsmith", "jsmith", false)
621 user = User.try_to_login("jsmith", "jsmith", false)
622 assert_equal @jsmith, user
622 assert_equal @jsmith, user
623 end
623 end
624
624
625 test ".try_to_login should fall-back to case-insensitive if user login is not found as-typed" do
625 test ".try_to_login should fall-back to case-insensitive if user login is not found as-typed" do
626 user = User.try_to_login("AdMin", "admin")
626 user = User.try_to_login("AdMin", "admin")
627 assert_kind_of User, user
627 assert_kind_of User, user
628 assert_equal "admin", user.login
628 assert_equal "admin", user.login
629 end
629 end
630
630
631 test ".try_to_login should select the exact matching user first" do
631 test ".try_to_login should select the exact matching user first" do
632 case_sensitive_user = User.generate! do |user|
632 case_sensitive_user = User.generate! do |user|
633 user.password = "admin123"
633 user.password = "admin123"
634 end
634 end
635 # bypass validations to make it appear like existing data
635 # bypass validations to make it appear like existing data
636 case_sensitive_user.update_attribute(:login, 'ADMIN')
636 case_sensitive_user.update_attribute(:login, 'ADMIN')
637
637
638 user = User.try_to_login("ADMIN", "admin123")
638 user = User.try_to_login("ADMIN", "admin123")
639 assert_kind_of User, user
639 assert_kind_of User, user
640 assert_equal "ADMIN", user.login
640 assert_equal "ADMIN", user.login
641 end
641 end
642
642
643 if ldap_configured?
643 if ldap_configured?
644 test "#try_to_login using LDAP with failed connection to the LDAP server" do
644 test "#try_to_login using LDAP with failed connection to the LDAP server" do
645 auth_source = AuthSourceLdap.find(1)
645 auth_source = AuthSourceLdap.find(1)
646 AuthSource.any_instance.stubs(:initialize_ldap_con).raises(Net::LDAP::LdapError, 'Cannot connect')
646 AuthSource.any_instance.stubs(:initialize_ldap_con).raises(Net::LDAP::Error, 'Cannot connect')
647
647
648 assert_nil User.try_to_login('edavis', 'wrong')
648 assert_nil User.try_to_login('edavis', 'wrong')
649 end
649 end
650
650
651 test "#try_to_login using LDAP" do
651 test "#try_to_login using LDAP" do
652 assert_nil User.try_to_login('edavis', 'wrong')
652 assert_nil User.try_to_login('edavis', 'wrong')
653 end
653 end
654
654
655 test "#try_to_login using LDAP binding with user's account" do
655 test "#try_to_login using LDAP binding with user's account" do
656 auth_source = AuthSourceLdap.find(1)
656 auth_source = AuthSourceLdap.find(1)
657 auth_source.account = "uid=$login,ou=Person,dc=redmine,dc=org"
657 auth_source.account = "uid=$login,ou=Person,dc=redmine,dc=org"
658 auth_source.account_password = ''
658 auth_source.account_password = ''
659 auth_source.save!
659 auth_source.save!
660
660
661 ldap_user = User.new(:mail => 'example1@redmine.org', :firstname => 'LDAP', :lastname => 'user', :auth_source_id => 1)
661 ldap_user = User.new(:mail => 'example1@redmine.org', :firstname => 'LDAP', :lastname => 'user', :auth_source_id => 1)
662 ldap_user.login = 'example1'
662 ldap_user.login = 'example1'
663 ldap_user.save!
663 ldap_user.save!
664
664
665 assert_equal ldap_user, User.try_to_login('example1', '123456')
665 assert_equal ldap_user, User.try_to_login('example1', '123456')
666 assert_nil User.try_to_login('example1', '11111')
666 assert_nil User.try_to_login('example1', '11111')
667 end
667 end
668
668
669 test "#try_to_login using LDAP on the fly registration" do
669 test "#try_to_login using LDAP on the fly registration" do
670 AuthSourceLdap.find(1).update_attribute :onthefly_register, true
670 AuthSourceLdap.find(1).update_attribute :onthefly_register, true
671
671
672 assert_difference('User.count') do
672 assert_difference('User.count') do
673 assert User.try_to_login('edavis', '123456')
673 assert User.try_to_login('edavis', '123456')
674 end
674 end
675
675
676 assert_no_difference('User.count') do
676 assert_no_difference('User.count') do
677 assert User.try_to_login('edavis', '123456')
677 assert User.try_to_login('edavis', '123456')
678 end
678 end
679
679
680 assert_nil User.try_to_login('example1', '11111')
680 assert_nil User.try_to_login('example1', '11111')
681 end
681 end
682
682
683 test "#try_to_login using LDAP on the fly registration and binding with user's account" do
683 test "#try_to_login using LDAP on the fly registration and binding with user's account" do
684 auth_source = AuthSourceLdap.find(1)
684 auth_source = AuthSourceLdap.find(1)
685 auth_source.update_attribute :onthefly_register, true
685 auth_source.update_attribute :onthefly_register, true
686 auth_source = AuthSourceLdap.find(1)
686 auth_source = AuthSourceLdap.find(1)
687 auth_source.account = "uid=$login,ou=Person,dc=redmine,dc=org"
687 auth_source.account = "uid=$login,ou=Person,dc=redmine,dc=org"
688 auth_source.account_password = ''
688 auth_source.account_password = ''
689 auth_source.save!
689 auth_source.save!
690
690
691 assert_difference('User.count') do
691 assert_difference('User.count') do
692 assert User.try_to_login('example1', '123456')
692 assert User.try_to_login('example1', '123456')
693 end
693 end
694
694
695 assert_no_difference('User.count') do
695 assert_no_difference('User.count') do
696 assert User.try_to_login('example1', '123456')
696 assert User.try_to_login('example1', '123456')
697 end
697 end
698
698
699 assert_nil User.try_to_login('example1', '11111')
699 assert_nil User.try_to_login('example1', '11111')
700 end
700 end
701
701
702 else
702 else
703 puts "Skipping LDAP tests."
703 puts "Skipping LDAP tests."
704 end
704 end
705
705
706 def test_create_anonymous
706 def test_create_anonymous
707 AnonymousUser.delete_all
707 AnonymousUser.delete_all
708 anon = User.anonymous
708 anon = User.anonymous
709 assert !anon.new_record?
709 assert !anon.new_record?
710 assert_kind_of AnonymousUser, anon
710 assert_kind_of AnonymousUser, anon
711 end
711 end
712
712
713 def test_ensure_single_anonymous_user
713 def test_ensure_single_anonymous_user
714 AnonymousUser.delete_all
714 AnonymousUser.delete_all
715 anon1 = User.anonymous
715 anon1 = User.anonymous
716 assert !anon1.new_record?
716 assert !anon1.new_record?
717 assert_kind_of AnonymousUser, anon1
717 assert_kind_of AnonymousUser, anon1
718 anon2 = AnonymousUser.create(
718 anon2 = AnonymousUser.create(
719 :lastname => 'Anonymous', :firstname => '',
719 :lastname => 'Anonymous', :firstname => '',
720 :login => '', :status => 0)
720 :login => '', :status => 0)
721 assert_equal 1, anon2.errors.count
721 assert_equal 1, anon2.errors.count
722 end
722 end
723
723
724 def test_rss_key
724 def test_rss_key
725 assert_nil @jsmith.rss_token
725 assert_nil @jsmith.rss_token
726 key = @jsmith.rss_key
726 key = @jsmith.rss_key
727 assert_equal 40, key.length
727 assert_equal 40, key.length
728
728
729 @jsmith.reload
729 @jsmith.reload
730 assert_equal key, @jsmith.rss_key
730 assert_equal key, @jsmith.rss_key
731 end
731 end
732
732
733 def test_rss_key_should_not_be_generated_twice
733 def test_rss_key_should_not_be_generated_twice
734 assert_difference 'Token.count', 1 do
734 assert_difference 'Token.count', 1 do
735 key1 = @jsmith.rss_key
735 key1 = @jsmith.rss_key
736 key2 = @jsmith.rss_key
736 key2 = @jsmith.rss_key
737 assert_equal key1, key2
737 assert_equal key1, key2
738 end
738 end
739 end
739 end
740
740
741 def test_api_key_should_not_be_generated_twice
741 def test_api_key_should_not_be_generated_twice
742 assert_difference 'Token.count', 1 do
742 assert_difference 'Token.count', 1 do
743 key1 = @jsmith.api_key
743 key1 = @jsmith.api_key
744 key2 = @jsmith.api_key
744 key2 = @jsmith.api_key
745 assert_equal key1, key2
745 assert_equal key1, key2
746 end
746 end
747 end
747 end
748
748
749 test "#api_key should generate a new one if the user doesn't have one" do
749 test "#api_key should generate a new one if the user doesn't have one" do
750 user = User.generate!(:api_token => nil)
750 user = User.generate!(:api_token => nil)
751 assert_nil user.api_token
751 assert_nil user.api_token
752
752
753 key = user.api_key
753 key = user.api_key
754 assert_equal 40, key.length
754 assert_equal 40, key.length
755 user.reload
755 user.reload
756 assert_equal key, user.api_key
756 assert_equal key, user.api_key
757 end
757 end
758
758
759 test "#api_key should return the existing api token value" do
759 test "#api_key should return the existing api token value" do
760 user = User.generate!
760 user = User.generate!
761 token = Token.create!(:action => 'api')
761 token = Token.create!(:action => 'api')
762 user.api_token = token
762 user.api_token = token
763 assert user.save
763 assert user.save
764
764
765 assert_equal token.value, user.api_key
765 assert_equal token.value, user.api_key
766 end
766 end
767
767
768 test "#find_by_api_key should return nil if no matching key is found" do
768 test "#find_by_api_key should return nil if no matching key is found" do
769 assert_nil User.find_by_api_key('zzzzzzzzz')
769 assert_nil User.find_by_api_key('zzzzzzzzz')
770 end
770 end
771
771
772 test "#find_by_api_key should return nil if the key is found for an inactive user" do
772 test "#find_by_api_key should return nil if the key is found for an inactive user" do
773 user = User.generate!
773 user = User.generate!
774 user.status = User::STATUS_LOCKED
774 user.status = User::STATUS_LOCKED
775 token = Token.create!(:action => 'api')
775 token = Token.create!(:action => 'api')
776 user.api_token = token
776 user.api_token = token
777 user.save
777 user.save
778
778
779 assert_nil User.find_by_api_key(token.value)
779 assert_nil User.find_by_api_key(token.value)
780 end
780 end
781
781
782 test "#find_by_api_key should return the user if the key is found for an active user" do
782 test "#find_by_api_key should return the user if the key is found for an active user" do
783 user = User.generate!
783 user = User.generate!
784 token = Token.create!(:action => 'api')
784 token = Token.create!(:action => 'api')
785 user.api_token = token
785 user.api_token = token
786 user.save
786 user.save
787
787
788 assert_equal user, User.find_by_api_key(token.value)
788 assert_equal user, User.find_by_api_key(token.value)
789 end
789 end
790
790
791 def test_default_admin_account_changed_should_return_false_if_account_was_not_changed
791 def test_default_admin_account_changed_should_return_false_if_account_was_not_changed
792 user = User.find_by_login("admin")
792 user = User.find_by_login("admin")
793 user.password = "admin"
793 user.password = "admin"
794 assert user.save(:validate => false)
794 assert user.save(:validate => false)
795
795
796 assert_equal false, User.default_admin_account_changed?
796 assert_equal false, User.default_admin_account_changed?
797 end
797 end
798
798
799 def test_default_admin_account_changed_should_return_true_if_password_was_changed
799 def test_default_admin_account_changed_should_return_true_if_password_was_changed
800 user = User.find_by_login("admin")
800 user = User.find_by_login("admin")
801 user.password = "newpassword"
801 user.password = "newpassword"
802 user.save!
802 user.save!
803
803
804 assert_equal true, User.default_admin_account_changed?
804 assert_equal true, User.default_admin_account_changed?
805 end
805 end
806
806
807 def test_default_admin_account_changed_should_return_true_if_account_is_disabled
807 def test_default_admin_account_changed_should_return_true_if_account_is_disabled
808 user = User.find_by_login("admin")
808 user = User.find_by_login("admin")
809 user.password = "admin"
809 user.password = "admin"
810 user.status = User::STATUS_LOCKED
810 user.status = User::STATUS_LOCKED
811 assert user.save(:validate => false)
811 assert user.save(:validate => false)
812
812
813 assert_equal true, User.default_admin_account_changed?
813 assert_equal true, User.default_admin_account_changed?
814 end
814 end
815
815
816 def test_default_admin_account_changed_should_return_true_if_account_does_not_exist
816 def test_default_admin_account_changed_should_return_true_if_account_does_not_exist
817 user = User.find_by_login("admin")
817 user = User.find_by_login("admin")
818 user.destroy
818 user.destroy
819
819
820 assert_equal true, User.default_admin_account_changed?
820 assert_equal true, User.default_admin_account_changed?
821 end
821 end
822
822
823 def test_membership_with_project_should_return_membership
823 def test_membership_with_project_should_return_membership
824 project = Project.find(1)
824 project = Project.find(1)
825
825
826 membership = @jsmith.membership(project)
826 membership = @jsmith.membership(project)
827 assert_kind_of Member, membership
827 assert_kind_of Member, membership
828 assert_equal @jsmith, membership.user
828 assert_equal @jsmith, membership.user
829 assert_equal project, membership.project
829 assert_equal project, membership.project
830 end
830 end
831
831
832 def test_membership_with_project_id_should_return_membership
832 def test_membership_with_project_id_should_return_membership
833 project = Project.find(1)
833 project = Project.find(1)
834
834
835 membership = @jsmith.membership(1)
835 membership = @jsmith.membership(1)
836 assert_kind_of Member, membership
836 assert_kind_of Member, membership
837 assert_equal @jsmith, membership.user
837 assert_equal @jsmith, membership.user
838 assert_equal project, membership.project
838 assert_equal project, membership.project
839 end
839 end
840
840
841 def test_membership_for_non_member_should_return_nil
841 def test_membership_for_non_member_should_return_nil
842 project = Project.find(1)
842 project = Project.find(1)
843
843
844 user = User.generate!
844 user = User.generate!
845 membership = user.membership(1)
845 membership = user.membership(1)
846 assert_nil membership
846 assert_nil membership
847 end
847 end
848
848
849 def test_roles_for_project_with_member_on_public_project_should_return_roles_and_non_member
849 def test_roles_for_project_with_member_on_public_project_should_return_roles_and_non_member
850 roles = @jsmith.roles_for_project(Project.find(1))
850 roles = @jsmith.roles_for_project(Project.find(1))
851 assert_kind_of Role, roles.first
851 assert_kind_of Role, roles.first
852 assert_equal ["Manager"], roles.map(&:name)
852 assert_equal ["Manager"], roles.map(&:name)
853 end
853 end
854
854
855 def test_roles_for_project_with_member_on_private_project_should_return_roles
855 def test_roles_for_project_with_member_on_private_project_should_return_roles
856 Project.find(1).update_attribute :is_public, false
856 Project.find(1).update_attribute :is_public, false
857
857
858 roles = @jsmith.roles_for_project(Project.find(1))
858 roles = @jsmith.roles_for_project(Project.find(1))
859 assert_kind_of Role, roles.first
859 assert_kind_of Role, roles.first
860 assert_equal ["Manager"], roles.map(&:name)
860 assert_equal ["Manager"], roles.map(&:name)
861 end
861 end
862
862
863 def test_roles_for_project_with_non_member_with_public_project_should_return_non_member
863 def test_roles_for_project_with_non_member_with_public_project_should_return_non_member
864 set_language_if_valid 'en'
864 set_language_if_valid 'en'
865 roles = User.find(8).roles_for_project(Project.find(1))
865 roles = User.find(8).roles_for_project(Project.find(1))
866 assert_equal ["Non member"], roles.map(&:name)
866 assert_equal ["Non member"], roles.map(&:name)
867 end
867 end
868
868
869 def test_roles_for_project_with_non_member_with_public_project_and_override_should_return_override_roles
869 def test_roles_for_project_with_non_member_with_public_project_and_override_should_return_override_roles
870 project = Project.find(1)
870 project = Project.find(1)
871 Member.create!(:project => project, :principal => Group.non_member, :role_ids => [1, 2])
871 Member.create!(:project => project, :principal => Group.non_member, :role_ids => [1, 2])
872 roles = User.find(8).roles_for_project(project)
872 roles = User.find(8).roles_for_project(project)
873 assert_equal ["Developer", "Manager"], roles.map(&:name).sort
873 assert_equal ["Developer", "Manager"], roles.map(&:name).sort
874 end
874 end
875
875
876 def test_roles_for_project_with_non_member_with_private_project_should_return_no_roles
876 def test_roles_for_project_with_non_member_with_private_project_should_return_no_roles
877 Project.find(1).update_attribute :is_public, false
877 Project.find(1).update_attribute :is_public, false
878 roles = User.find(8).roles_for_project(Project.find(1))
878 roles = User.find(8).roles_for_project(Project.find(1))
879 assert_equal [], roles.map(&:name)
879 assert_equal [], roles.map(&:name)
880 end
880 end
881
881
882 def test_roles_for_project_with_non_member_with_private_project_and_override_should_return_no_roles
882 def test_roles_for_project_with_non_member_with_private_project_and_override_should_return_no_roles
883 project = Project.find(1)
883 project = Project.find(1)
884 project.update_attribute :is_public, false
884 project.update_attribute :is_public, false
885 Member.create!(:project => project, :principal => Group.non_member, :role_ids => [1, 2])
885 Member.create!(:project => project, :principal => Group.non_member, :role_ids => [1, 2])
886 roles = User.find(8).roles_for_project(project)
886 roles = User.find(8).roles_for_project(project)
887 assert_equal [], roles.map(&:name).sort
887 assert_equal [], roles.map(&:name).sort
888 end
888 end
889
889
890 def test_roles_for_project_with_anonymous_with_public_project_should_return_anonymous
890 def test_roles_for_project_with_anonymous_with_public_project_should_return_anonymous
891 set_language_if_valid 'en'
891 set_language_if_valid 'en'
892 roles = User.anonymous.roles_for_project(Project.find(1))
892 roles = User.anonymous.roles_for_project(Project.find(1))
893 assert_equal ["Anonymous"], roles.map(&:name)
893 assert_equal ["Anonymous"], roles.map(&:name)
894 end
894 end
895
895
896 def test_roles_for_project_with_anonymous_with_public_project_and_override_should_return_override_roles
896 def test_roles_for_project_with_anonymous_with_public_project_and_override_should_return_override_roles
897 project = Project.find(1)
897 project = Project.find(1)
898 Member.create!(:project => project, :principal => Group.anonymous, :role_ids => [1, 2])
898 Member.create!(:project => project, :principal => Group.anonymous, :role_ids => [1, 2])
899 roles = User.anonymous.roles_for_project(project)
899 roles = User.anonymous.roles_for_project(project)
900 assert_equal ["Developer", "Manager"], roles.map(&:name).sort
900 assert_equal ["Developer", "Manager"], roles.map(&:name).sort
901 end
901 end
902
902
903 def test_roles_for_project_with_anonymous_with_private_project_should_return_no_roles
903 def test_roles_for_project_with_anonymous_with_private_project_should_return_no_roles
904 Project.find(1).update_attribute :is_public, false
904 Project.find(1).update_attribute :is_public, false
905 roles = User.anonymous.roles_for_project(Project.find(1))
905 roles = User.anonymous.roles_for_project(Project.find(1))
906 assert_equal [], roles.map(&:name)
906 assert_equal [], roles.map(&:name)
907 end
907 end
908
908
909 def test_roles_for_project_with_anonymous_with_private_project_and_override_should_return_no_roles
909 def test_roles_for_project_with_anonymous_with_private_project_and_override_should_return_no_roles
910 project = Project.find(1)
910 project = Project.find(1)
911 project.update_attribute :is_public, false
911 project.update_attribute :is_public, false
912 Member.create!(:project => project, :principal => Group.anonymous, :role_ids => [1, 2])
912 Member.create!(:project => project, :principal => Group.anonymous, :role_ids => [1, 2])
913 roles = User.anonymous.roles_for_project(project)
913 roles = User.anonymous.roles_for_project(project)
914 assert_equal [], roles.map(&:name).sort
914 assert_equal [], roles.map(&:name).sort
915 end
915 end
916
916
917 def test_roles_for_project_should_be_unique
917 def test_roles_for_project_should_be_unique
918 m = Member.new(:user_id => 1, :project_id => 1)
918 m = Member.new(:user_id => 1, :project_id => 1)
919 m.member_roles.build(:role_id => 1)
919 m.member_roles.build(:role_id => 1)
920 m.member_roles.build(:role_id => 1)
920 m.member_roles.build(:role_id => 1)
921 m.save!
921 m.save!
922
922
923 user = User.find(1)
923 user = User.find(1)
924 project = Project.find(1)
924 project = Project.find(1)
925 assert_equal 1, user.roles_for_project(project).size
925 assert_equal 1, user.roles_for_project(project).size
926 assert_equal [1], user.roles_for_project(project).map(&:id)
926 assert_equal [1], user.roles_for_project(project).map(&:id)
927 end
927 end
928
928
929 def test_projects_by_role_for_user_with_role
929 def test_projects_by_role_for_user_with_role
930 user = User.find(2)
930 user = User.find(2)
931 assert_kind_of Hash, user.projects_by_role
931 assert_kind_of Hash, user.projects_by_role
932 assert_equal 2, user.projects_by_role.size
932 assert_equal 2, user.projects_by_role.size
933 assert_equal [1,5], user.projects_by_role[Role.find(1)].collect(&:id).sort
933 assert_equal [1,5], user.projects_by_role[Role.find(1)].collect(&:id).sort
934 assert_equal [2], user.projects_by_role[Role.find(2)].collect(&:id).sort
934 assert_equal [2], user.projects_by_role[Role.find(2)].collect(&:id).sort
935 end
935 end
936
936
937 def test_accessing_projects_by_role_with_no_projects_should_return_an_empty_array
937 def test_accessing_projects_by_role_with_no_projects_should_return_an_empty_array
938 user = User.find(2)
938 user = User.find(2)
939 assert_equal [], user.projects_by_role[Role.find(3)]
939 assert_equal [], user.projects_by_role[Role.find(3)]
940 # should not update the hash
940 # should not update the hash
941 assert_nil user.projects_by_role.values.detect(&:blank?)
941 assert_nil user.projects_by_role.values.detect(&:blank?)
942 end
942 end
943
943
944 def test_projects_by_role_for_user_with_no_role
944 def test_projects_by_role_for_user_with_no_role
945 user = User.generate!
945 user = User.generate!
946 assert_equal({}, user.projects_by_role)
946 assert_equal({}, user.projects_by_role)
947 end
947 end
948
948
949 def test_projects_by_role_for_anonymous
949 def test_projects_by_role_for_anonymous
950 assert_equal({}, User.anonymous.projects_by_role)
950 assert_equal({}, User.anonymous.projects_by_role)
951 end
951 end
952
952
953 def test_valid_notification_options
953 def test_valid_notification_options
954 # without memberships
954 # without memberships
955 assert_equal 5, User.find(7).valid_notification_options.size
955 assert_equal 5, User.find(7).valid_notification_options.size
956 # with memberships
956 # with memberships
957 assert_equal 6, User.find(2).valid_notification_options.size
957 assert_equal 6, User.find(2).valid_notification_options.size
958 end
958 end
959
959
960 def test_valid_notification_options_class_method
960 def test_valid_notification_options_class_method
961 assert_equal 5, User.valid_notification_options.size
961 assert_equal 5, User.valid_notification_options.size
962 assert_equal 5, User.valid_notification_options(User.find(7)).size
962 assert_equal 5, User.valid_notification_options(User.find(7)).size
963 assert_equal 6, User.valid_notification_options(User.find(2)).size
963 assert_equal 6, User.valid_notification_options(User.find(2)).size
964 end
964 end
965
965
966 def test_notified_project_ids_setter_should_coerce_to_unique_integer_array
966 def test_notified_project_ids_setter_should_coerce_to_unique_integer_array
967 @jsmith.notified_project_ids = ["1", "123", "2u", "wrong", "12", 6, 12, -35, ""]
967 @jsmith.notified_project_ids = ["1", "123", "2u", "wrong", "12", 6, 12, -35, ""]
968 assert_equal [1, 123, 2, 12, 6], @jsmith.notified_projects_ids
968 assert_equal [1, 123, 2, 12, 6], @jsmith.notified_projects_ids
969 end
969 end
970
970
971 def test_mail_notification_all
971 def test_mail_notification_all
972 @jsmith.mail_notification = 'all'
972 @jsmith.mail_notification = 'all'
973 @jsmith.notified_project_ids = []
973 @jsmith.notified_project_ids = []
974 @jsmith.save
974 @jsmith.save
975 @jsmith.reload
975 @jsmith.reload
976 assert @jsmith.projects.first.recipients.include?(@jsmith.mail)
976 assert @jsmith.projects.first.recipients.include?(@jsmith.mail)
977 end
977 end
978
978
979 def test_mail_notification_selected
979 def test_mail_notification_selected
980 @jsmith.mail_notification = 'selected'
980 @jsmith.mail_notification = 'selected'
981 @jsmith.notified_project_ids = [1]
981 @jsmith.notified_project_ids = [1]
982 @jsmith.save
982 @jsmith.save
983 @jsmith.reload
983 @jsmith.reload
984 assert Project.find(1).recipients.include?(@jsmith.mail)
984 assert Project.find(1).recipients.include?(@jsmith.mail)
985 end
985 end
986
986
987 def test_mail_notification_only_my_events
987 def test_mail_notification_only_my_events
988 @jsmith.mail_notification = 'only_my_events'
988 @jsmith.mail_notification = 'only_my_events'
989 @jsmith.notified_project_ids = []
989 @jsmith.notified_project_ids = []
990 @jsmith.save
990 @jsmith.save
991 @jsmith.reload
991 @jsmith.reload
992 assert !@jsmith.projects.first.recipients.include?(@jsmith.mail)
992 assert !@jsmith.projects.first.recipients.include?(@jsmith.mail)
993 end
993 end
994
994
995 def test_comments_sorting_preference
995 def test_comments_sorting_preference
996 assert !@jsmith.wants_comments_in_reverse_order?
996 assert !@jsmith.wants_comments_in_reverse_order?
997 @jsmith.pref.comments_sorting = 'asc'
997 @jsmith.pref.comments_sorting = 'asc'
998 assert !@jsmith.wants_comments_in_reverse_order?
998 assert !@jsmith.wants_comments_in_reverse_order?
999 @jsmith.pref.comments_sorting = 'desc'
999 @jsmith.pref.comments_sorting = 'desc'
1000 assert @jsmith.wants_comments_in_reverse_order?
1000 assert @jsmith.wants_comments_in_reverse_order?
1001 end
1001 end
1002
1002
1003 def test_find_by_mail_should_be_case_insensitive
1003 def test_find_by_mail_should_be_case_insensitive
1004 u = User.find_by_mail('JSmith@somenet.foo')
1004 u = User.find_by_mail('JSmith@somenet.foo')
1005 assert_not_nil u
1005 assert_not_nil u
1006 assert_equal 'jsmith@somenet.foo', u.mail
1006 assert_equal 'jsmith@somenet.foo', u.mail
1007 end
1007 end
1008
1008
1009 def test_random_password
1009 def test_random_password
1010 u = User.new
1010 u = User.new
1011 u.random_password
1011 u.random_password
1012 assert !u.password.blank?
1012 assert !u.password.blank?
1013 assert !u.password_confirmation.blank?
1013 assert !u.password_confirmation.blank?
1014 end
1014 end
1015
1015
1016 test "#change_password_allowed? should be allowed if no auth source is set" do
1016 test "#change_password_allowed? should be allowed if no auth source is set" do
1017 user = User.generate!
1017 user = User.generate!
1018 assert user.change_password_allowed?
1018 assert user.change_password_allowed?
1019 end
1019 end
1020
1020
1021 test "#change_password_allowed? should delegate to the auth source" do
1021 test "#change_password_allowed? should delegate to the auth source" do
1022 user = User.generate!
1022 user = User.generate!
1023
1023
1024 allowed_auth_source = AuthSource.generate!
1024 allowed_auth_source = AuthSource.generate!
1025 def allowed_auth_source.allow_password_changes?; true; end
1025 def allowed_auth_source.allow_password_changes?; true; end
1026
1026
1027 denied_auth_source = AuthSource.generate!
1027 denied_auth_source = AuthSource.generate!
1028 def denied_auth_source.allow_password_changes?; false; end
1028 def denied_auth_source.allow_password_changes?; false; end
1029
1029
1030 assert user.change_password_allowed?
1030 assert user.change_password_allowed?
1031
1031
1032 user.auth_source = allowed_auth_source
1032 user.auth_source = allowed_auth_source
1033 assert user.change_password_allowed?, "User not allowed to change password, though auth source does"
1033 assert user.change_password_allowed?, "User not allowed to change password, though auth source does"
1034
1034
1035 user.auth_source = denied_auth_source
1035 user.auth_source = denied_auth_source
1036 assert !user.change_password_allowed?, "User allowed to change password, though auth source does not"
1036 assert !user.change_password_allowed?, "User allowed to change password, though auth source does not"
1037 end
1037 end
1038
1038
1039 def test_own_account_deletable_should_be_true_with_unsubscrive_enabled
1039 def test_own_account_deletable_should_be_true_with_unsubscrive_enabled
1040 with_settings :unsubscribe => '1' do
1040 with_settings :unsubscribe => '1' do
1041 assert_equal true, User.find(2).own_account_deletable?
1041 assert_equal true, User.find(2).own_account_deletable?
1042 end
1042 end
1043 end
1043 end
1044
1044
1045 def test_own_account_deletable_should_be_false_with_unsubscrive_disabled
1045 def test_own_account_deletable_should_be_false_with_unsubscrive_disabled
1046 with_settings :unsubscribe => '0' do
1046 with_settings :unsubscribe => '0' do
1047 assert_equal false, User.find(2).own_account_deletable?
1047 assert_equal false, User.find(2).own_account_deletable?
1048 end
1048 end
1049 end
1049 end
1050
1050
1051 def test_own_account_deletable_should_be_false_for_a_single_admin
1051 def test_own_account_deletable_should_be_false_for_a_single_admin
1052 User.where(["admin = ? AND id <> ?", true, 1]).delete_all
1052 User.where(["admin = ? AND id <> ?", true, 1]).delete_all
1053
1053
1054 with_settings :unsubscribe => '1' do
1054 with_settings :unsubscribe => '1' do
1055 assert_equal false, User.find(1).own_account_deletable?
1055 assert_equal false, User.find(1).own_account_deletable?
1056 end
1056 end
1057 end
1057 end
1058
1058
1059 def test_own_account_deletable_should_be_true_for_an_admin_if_other_admin_exists
1059 def test_own_account_deletable_should_be_true_for_an_admin_if_other_admin_exists
1060 User.generate! do |user|
1060 User.generate! do |user|
1061 user.admin = true
1061 user.admin = true
1062 end
1062 end
1063
1063
1064 with_settings :unsubscribe => '1' do
1064 with_settings :unsubscribe => '1' do
1065 assert_equal true, User.find(1).own_account_deletable?
1065 assert_equal true, User.find(1).own_account_deletable?
1066 end
1066 end
1067 end
1067 end
1068
1068
1069 test "#allowed_to? for archived project should return false" do
1069 test "#allowed_to? for archived project should return false" do
1070 project = Project.find(1)
1070 project = Project.find(1)
1071 project.archive
1071 project.archive
1072 project.reload
1072 project.reload
1073 assert_equal false, @admin.allowed_to?(:view_issues, project)
1073 assert_equal false, @admin.allowed_to?(:view_issues, project)
1074 end
1074 end
1075
1075
1076 test "#allowed_to? for closed project should return true for read actions" do
1076 test "#allowed_to? for closed project should return true for read actions" do
1077 project = Project.find(1)
1077 project = Project.find(1)
1078 project.close
1078 project.close
1079 project.reload
1079 project.reload
1080 assert_equal false, @admin.allowed_to?(:edit_project, project)
1080 assert_equal false, @admin.allowed_to?(:edit_project, project)
1081 assert_equal true, @admin.allowed_to?(:view_project, project)
1081 assert_equal true, @admin.allowed_to?(:view_project, project)
1082 end
1082 end
1083
1083
1084 test "#allowed_to? for project with module disabled should return false" do
1084 test "#allowed_to? for project with module disabled should return false" do
1085 project = Project.find(1)
1085 project = Project.find(1)
1086 project.enabled_module_names = ["issue_tracking"]
1086 project.enabled_module_names = ["issue_tracking"]
1087 assert_equal true, @admin.allowed_to?(:add_issues, project)
1087 assert_equal true, @admin.allowed_to?(:add_issues, project)
1088 assert_equal false, @admin.allowed_to?(:view_wiki_pages, project)
1088 assert_equal false, @admin.allowed_to?(:view_wiki_pages, project)
1089 end
1089 end
1090
1090
1091 test "#allowed_to? for admin users should return true" do
1091 test "#allowed_to? for admin users should return true" do
1092 project = Project.find(1)
1092 project = Project.find(1)
1093 assert ! @admin.member_of?(project)
1093 assert ! @admin.member_of?(project)
1094 %w(edit_issues delete_issues manage_news add_documents manage_wiki).each do |p|
1094 %w(edit_issues delete_issues manage_news add_documents manage_wiki).each do |p|
1095 assert_equal true, @admin.allowed_to?(p.to_sym, project)
1095 assert_equal true, @admin.allowed_to?(p.to_sym, project)
1096 end
1096 end
1097 end
1097 end
1098
1098
1099 test "#allowed_to? for normal users" do
1099 test "#allowed_to? for normal users" do
1100 project = Project.find(1)
1100 project = Project.find(1)
1101 assert_equal true, @jsmith.allowed_to?(:delete_messages, project) #Manager
1101 assert_equal true, @jsmith.allowed_to?(:delete_messages, project) #Manager
1102 assert_equal false, @dlopper.allowed_to?(:delete_messages, project) #Developper
1102 assert_equal false, @dlopper.allowed_to?(:delete_messages, project) #Developper
1103 end
1103 end
1104
1104
1105 test "#allowed_to? with empty array should return false" do
1105 test "#allowed_to? with empty array should return false" do
1106 assert_equal false, @admin.allowed_to?(:view_project, [])
1106 assert_equal false, @admin.allowed_to?(:view_project, [])
1107 end
1107 end
1108
1108
1109 test "#allowed_to? with multiple projects" do
1109 test "#allowed_to? with multiple projects" do
1110 assert_equal true, @admin.allowed_to?(:view_project, Project.all.to_a)
1110 assert_equal true, @admin.allowed_to?(:view_project, Project.all.to_a)
1111 assert_equal false, @dlopper.allowed_to?(:view_project, Project.all.to_a) #cannot see Project(2)
1111 assert_equal false, @dlopper.allowed_to?(:view_project, Project.all.to_a) #cannot see Project(2)
1112 assert_equal true, @jsmith.allowed_to?(:edit_issues, @jsmith.projects.to_a) #Manager or Developer everywhere
1112 assert_equal true, @jsmith.allowed_to?(:edit_issues, @jsmith.projects.to_a) #Manager or Developer everywhere
1113 assert_equal false, @jsmith.allowed_to?(:delete_issue_watchers, @jsmith.projects.to_a) #Dev cannot delete_issue_watchers
1113 assert_equal false, @jsmith.allowed_to?(:delete_issue_watchers, @jsmith.projects.to_a) #Dev cannot delete_issue_watchers
1114 end
1114 end
1115
1115
1116 test "#allowed_to? with with options[:global] should return true if user has one role with the permission" do
1116 test "#allowed_to? with with options[:global] should return true if user has one role with the permission" do
1117 @dlopper2 = User.find(5) #only Developper on a project, not Manager anywhere
1117 @dlopper2 = User.find(5) #only Developper on a project, not Manager anywhere
1118 @anonymous = User.find(6)
1118 @anonymous = User.find(6)
1119 assert_equal true, @jsmith.allowed_to?(:delete_issue_watchers, nil, :global => true)
1119 assert_equal true, @jsmith.allowed_to?(:delete_issue_watchers, nil, :global => true)
1120 assert_equal false, @dlopper2.allowed_to?(:delete_issue_watchers, nil, :global => true)
1120 assert_equal false, @dlopper2.allowed_to?(:delete_issue_watchers, nil, :global => true)
1121 assert_equal true, @dlopper2.allowed_to?(:add_issues, nil, :global => true)
1121 assert_equal true, @dlopper2.allowed_to?(:add_issues, nil, :global => true)
1122 assert_equal false, @anonymous.allowed_to?(:add_issues, nil, :global => true)
1122 assert_equal false, @anonymous.allowed_to?(:add_issues, nil, :global => true)
1123 assert_equal true, @anonymous.allowed_to?(:view_issues, nil, :global => true)
1123 assert_equal true, @anonymous.allowed_to?(:view_issues, nil, :global => true)
1124 end
1124 end
1125
1125
1126 # this is just a proxy method, the test only calls it to ensure it doesn't break trivially
1126 # this is just a proxy method, the test only calls it to ensure it doesn't break trivially
1127 test "#allowed_to_globally?" do
1127 test "#allowed_to_globally?" do
1128 @dlopper2 = User.find(5) #only Developper on a project, not Manager anywhere
1128 @dlopper2 = User.find(5) #only Developper on a project, not Manager anywhere
1129 @anonymous = User.find(6)
1129 @anonymous = User.find(6)
1130 assert_equal true, @jsmith.allowed_to_globally?(:delete_issue_watchers)
1130 assert_equal true, @jsmith.allowed_to_globally?(:delete_issue_watchers)
1131 assert_equal false, @dlopper2.allowed_to_globally?(:delete_issue_watchers)
1131 assert_equal false, @dlopper2.allowed_to_globally?(:delete_issue_watchers)
1132 assert_equal true, @dlopper2.allowed_to_globally?(:add_issues)
1132 assert_equal true, @dlopper2.allowed_to_globally?(:add_issues)
1133 assert_equal false, @anonymous.allowed_to_globally?(:add_issues)
1133 assert_equal false, @anonymous.allowed_to_globally?(:add_issues)
1134 assert_equal true, @anonymous.allowed_to_globally?(:view_issues)
1134 assert_equal true, @anonymous.allowed_to_globally?(:view_issues)
1135 end
1135 end
1136
1136
1137 def test_notify_about_issue
1137 def test_notify_about_issue
1138 project = Project.find(1)
1138 project = Project.find(1)
1139 author = User.generate!
1139 author = User.generate!
1140 assignee = User.generate!
1140 assignee = User.generate!
1141 Member.create!(:user => assignee, :project => project, :role_ids => [1])
1141 Member.create!(:user => assignee, :project => project, :role_ids => [1])
1142 member = User.generate!
1142 member = User.generate!
1143 Member.create!(:user => member, :project => project, :role_ids => [1])
1143 Member.create!(:user => member, :project => project, :role_ids => [1])
1144 issue = Issue.generate!(:project => project, :assigned_to => assignee, :author => author)
1144 issue = Issue.generate!(:project => project, :assigned_to => assignee, :author => author)
1145
1145
1146 tests = {
1146 tests = {
1147 author => %w(all only_my_events only_owner selected),
1147 author => %w(all only_my_events only_owner selected),
1148 assignee => %w(all only_my_events only_assigned selected),
1148 assignee => %w(all only_my_events only_assigned selected),
1149 member => %w(all)
1149 member => %w(all)
1150 }
1150 }
1151
1151
1152 tests.each do |user, expected|
1152 tests.each do |user, expected|
1153 User::MAIL_NOTIFICATION_OPTIONS.map(&:first).each do |option|
1153 User::MAIL_NOTIFICATION_OPTIONS.map(&:first).each do |option|
1154 user.mail_notification = option
1154 user.mail_notification = option
1155 assert_equal expected.include?(option), user.notify_about?(issue)
1155 assert_equal expected.include?(option), user.notify_about?(issue)
1156 end
1156 end
1157 end
1157 end
1158 end
1158 end
1159
1159
1160 def test_notify_about_issue_for_previous_assignee
1160 def test_notify_about_issue_for_previous_assignee
1161 assignee = User.generate!(:mail_notification => 'only_assigned')
1161 assignee = User.generate!(:mail_notification => 'only_assigned')
1162 Member.create!(:user => assignee, :project_id => 1, :role_ids => [1])
1162 Member.create!(:user => assignee, :project_id => 1, :role_ids => [1])
1163 new_assignee = User.generate!(:mail_notification => 'only_assigned')
1163 new_assignee = User.generate!(:mail_notification => 'only_assigned')
1164 Member.create!(:user => new_assignee, :project_id => 1, :role_ids => [1])
1164 Member.create!(:user => new_assignee, :project_id => 1, :role_ids => [1])
1165 issue = Issue.generate!(:assigned_to => assignee)
1165 issue = Issue.generate!(:assigned_to => assignee)
1166
1166
1167 assert assignee.notify_about?(issue)
1167 assert assignee.notify_about?(issue)
1168 assert !new_assignee.notify_about?(issue)
1168 assert !new_assignee.notify_about?(issue)
1169
1169
1170 issue.assigned_to = new_assignee
1170 issue.assigned_to = new_assignee
1171 assert assignee.notify_about?(issue)
1171 assert assignee.notify_about?(issue)
1172 assert new_assignee.notify_about?(issue)
1172 assert new_assignee.notify_about?(issue)
1173
1173
1174 issue.save!
1174 issue.save!
1175 assert !assignee.notify_about?(issue)
1175 assert !assignee.notify_about?(issue)
1176 assert new_assignee.notify_about?(issue)
1176 assert new_assignee.notify_about?(issue)
1177 end
1177 end
1178
1178
1179 def test_notify_about_news
1179 def test_notify_about_news
1180 user = User.generate!
1180 user = User.generate!
1181 news = News.new
1181 news = News.new
1182
1182
1183 User::MAIL_NOTIFICATION_OPTIONS.map(&:first).each do |option|
1183 User::MAIL_NOTIFICATION_OPTIONS.map(&:first).each do |option|
1184 user.mail_notification = option
1184 user.mail_notification = option
1185 assert_equal (option != 'none'), user.notify_about?(news)
1185 assert_equal (option != 'none'), user.notify_about?(news)
1186 end
1186 end
1187 end
1187 end
1188
1188
1189 def test_salt_unsalted_passwords
1189 def test_salt_unsalted_passwords
1190 # Restore a user with an unsalted password
1190 # Restore a user with an unsalted password
1191 user = User.find(1)
1191 user = User.find(1)
1192 user.salt = nil
1192 user.salt = nil
1193 user.hashed_password = User.hash_password("unsalted")
1193 user.hashed_password = User.hash_password("unsalted")
1194 user.save!
1194 user.save!
1195
1195
1196 User.salt_unsalted_passwords!
1196 User.salt_unsalted_passwords!
1197
1197
1198 user.reload
1198 user.reload
1199 # Salt added
1199 # Salt added
1200 assert !user.salt.blank?
1200 assert !user.salt.blank?
1201 # Password still valid
1201 # Password still valid
1202 assert user.check_password?("unsalted")
1202 assert user.check_password?("unsalted")
1203 assert_equal user, User.try_to_login(user.login, "unsalted")
1203 assert_equal user, User.try_to_login(user.login, "unsalted")
1204 end
1204 end
1205
1205
1206 if Object.const_defined?(:OpenID)
1206 if Object.const_defined?(:OpenID)
1207 def test_setting_identity_url
1207 def test_setting_identity_url
1208 normalized_open_id_url = 'http://example.com/'
1208 normalized_open_id_url = 'http://example.com/'
1209 u = User.new( :identity_url => 'http://example.com/' )
1209 u = User.new( :identity_url => 'http://example.com/' )
1210 assert_equal normalized_open_id_url, u.identity_url
1210 assert_equal normalized_open_id_url, u.identity_url
1211 end
1211 end
1212
1212
1213 def test_setting_identity_url_without_trailing_slash
1213 def test_setting_identity_url_without_trailing_slash
1214 normalized_open_id_url = 'http://example.com/'
1214 normalized_open_id_url = 'http://example.com/'
1215 u = User.new( :identity_url => 'http://example.com' )
1215 u = User.new( :identity_url => 'http://example.com' )
1216 assert_equal normalized_open_id_url, u.identity_url
1216 assert_equal normalized_open_id_url, u.identity_url
1217 end
1217 end
1218
1218
1219 def test_setting_identity_url_without_protocol
1219 def test_setting_identity_url_without_protocol
1220 normalized_open_id_url = 'http://example.com/'
1220 normalized_open_id_url = 'http://example.com/'
1221 u = User.new( :identity_url => 'example.com' )
1221 u = User.new( :identity_url => 'example.com' )
1222 assert_equal normalized_open_id_url, u.identity_url
1222 assert_equal normalized_open_id_url, u.identity_url
1223 end
1223 end
1224
1224
1225 def test_setting_blank_identity_url
1225 def test_setting_blank_identity_url
1226 u = User.new( :identity_url => 'example.com' )
1226 u = User.new( :identity_url => 'example.com' )
1227 u.identity_url = ''
1227 u.identity_url = ''
1228 assert u.identity_url.blank?
1228 assert u.identity_url.blank?
1229 end
1229 end
1230
1230
1231 def test_setting_invalid_identity_url
1231 def test_setting_invalid_identity_url
1232 u = User.new( :identity_url => 'this is not an openid url' )
1232 u = User.new( :identity_url => 'this is not an openid url' )
1233 assert u.identity_url.blank?
1233 assert u.identity_url.blank?
1234 end
1234 end
1235 else
1235 else
1236 puts "Skipping openid tests."
1236 puts "Skipping openid tests."
1237 end
1237 end
1238 end
1238 end
General Comments 0
You need to be logged in to leave comments. Login now