require File.dirname(__FILE__) + '/../test_helper' class UserTest < Test::Unit::TestCase fixtures :groups, :users, :projects, :groups_users, :groups_projects def setup RetroCM.reload end def test_crud_user User.current = User.find(:first) user = User.new( :name => 'Some User', :plain_password => 'password', :plain_password_confirmation => 'password' ) user.login = 'some_user' user.email = 'some_user@email.com' assert(user.save) assert_not_nil(user.salt) dpl = User.find(user.id) assert_equal(user, dpl) dpl.name = 'New Name' assert(dpl.save) assert_not_equal(user.name, dpl.name) user.reload assert_equal(user.name, dpl.name) assert(dpl.destroy) end def test_create_admin user = User.new( :name => 'SomeUser', :plain_password => 'password', :plain_password_confirmation => 'password' ) user.login = 'some_user' user.email = 'some@email.com' user.admin = true assert_nothing_raised(){user.save!} end def test_presence_validations user = User.create assert(!user.save) assert_not_nil(user.errors[:login]) assert_not_nil(user.errors[:plain_password]) assert_not_nil(user.errors[:name]) assert_not_nil(user.errors[:email]) end def test_uniqueness_validations user1 = build_some_valid_user assert(user1.save) user2 = build_some_valid_user assert(!user2.save) assert_not_nil(user2.errors[:login]) assert_not_nil(user2.errors[:email]) end def test_content_validations user = User.new( :name => 'Some User', :plain_password => 'short', :plain_password_confirmation => 'short' ) user.login = 'so' user.email = 'invalid' assert(!user.save) assert_not_nil(user.errors[:login]) assert_not_nil(user.errors[:plain_password]) assert_not_nil(user.errors[:email]) user.email = 'correct@email.com' assert(!user.save) assert_nil(user.errors[:email]) user.login = 'correct' assert(!user.save) assert_nil(user.errors[:login]) user.plain_password = 'correct' user.plain_password_confirmation = 'incorrect' assert(!user.save) assert_not_nil(user.errors[:plain_password]) user.plain_password = 'correct' user.plain_password_confirmation = 'correct' assert(user.save) end def test_accessors user = User.new(:login => 'some_login', :name => 'Some Name', :email => 'some@email.com', :password => 'myownpass', :admin => true, :group_ids => ['1']) assert_equal('Some Name', user.name) assert_equal(nil, user.login) assert_equal(nil, user.password) assert_equal(nil, user.email) assert_equal(false, user.admin?) assert_equal([], user.groups) end def test_not_possible_to_make_public_user_admin_1 user = User.public_user user.admin = true assert(!user.save) user.reload assert(!user.admin?) end def test_other_public_restrictions User.delete_all random_pass = Randomizer.string user = User.new( :name => 'Anonymous', :plain_password => random_pass, :plain_password_confirmation => random_pass ) user.admin = true user.active = false user.login = 'Public' assert(!user.save) assert_not_nil(user.errors[:admin]) assert_not_nil(user.errors[:active]) end def test_not_possible_to_degrade_last_admin user = users(:admin) user.admin = false assert_equal(1, User.count(:conditions => ["admin = ?", true])) assert(!user.save) assert_not_nil(user.errors[:admin]) user.admin = true assert(user.save) end def test_not_possible_to_degrade_self random_pass = Randomizer.string another_admin = User.new(:name => 'Another Administrator', :plain_password => random_pass, :plain_password_confirmation => random_pass) another_admin.admin = true another_admin.active = true another_admin.login = "another-admin" another_admin.email = "another-admin@localhost" another_admin.save! assert_operator(1, :<, User.count(:conditions => ["admin = ?", true])) user = users(:admin) User.current = User.find(user.id) user.admin = false assert(!user.save) assert_not_nil(user.errors[:admin]) User.current = nil assert(user.save) end def test_not_possible_to_deactivate_self user = users(:admin) User.current = User.find(user.id) user.active = false assert(!user.save) assert_not_nil(user.errors[:active]) User.current = nil assert(user.save) end def test_not_possible_to_destroy_public_user user = User.public_user assert(!user.destroy) end def test_not_possible_to_destroy_last_admin user = users(:admin) assert(user.last_admin?) assert(!user.destroy) end def test_not_possible_to_destroy_self user = build_some_valid_user assert(user.save) User.current = user assert(!user.destroy) end def test_authentication_for_new_user RetroCM[:general][:user_management][:secure_auth] = false dummy = build_some_valid_user plain = dummy.plain_password.dup assert(dummy.save) auth_user = User.authenticate(:login => dummy.login, :password => plain) assert_not_nil(auth_user) assert_equal(dummy.id, auth_user.id) end def test_authentication_for_user_after_password_change RetroCM[:general][:user_management][:secure_auth] = false u = build_some_valid_user assert(u.save) plain = 'new_password' u.password = u.send(:hash_crypt, plain) assert(u.save) assert(u.valid_password?(plain)) assert(!u.outdated_valid_password?(plain)) params = {:login => u.login, :password => plain} auth = User.authenticate(params) assert_not_nil(auth) assert_equal(u.id, auth.id) assert_equal(u.send(:hash_crypt, plain), u.password) end def test_secure_authentication u = build_some_valid_user assert(u.save) tan = Tan.generate hash = Digest::SHA1.hexdigest("#{tan}:#{u.password}") params = {:login => u.login, :tan => tan, :hash => hash} RetroCM[:general][:user_management][:secure_auth] = false auth = User.authenticate(params) assert_nil(auth) RetroCM[:general][:user_management][:secure_auth] = true auth = User.authenticate(params) assert_not_nil(auth) assert_equal(u.id, auth.id) tan = Tan.generate(1) hash = Digest::SHA1.hexdigest("#{tan}:#{u.password}") params = {:login => u.login, :tan => tan, :hash => hash} sleep(2) auth = User.authenticate(params) assert_nil(auth) end def test_password_backward_compatibility_1 RetroCM[:general][:user_management][:secure_auth] = false u = build_some_valid_user assert(u.save) plain = 'new_password' u.password = Digest::SHA1.hexdigest("+++{{#{plain}}}---") assert(u.save) assert(!u.valid_password?(plain)) assert(u.outdated_valid_password?(plain)) params = {:login => u.login, :password => plain} auth = User.authenticate(params) assert_not_nil(auth) assert_equal(u.id, auth.id) # check for re-login u.reload assert_equal(u.send(:hash_crypt, plain), u.password) login = u.login.dup User.reset_column_information params = {:login => login, :password => plain} auth = User.authenticate(params) assert_not_nil(auth) end def test_password_backward_compatibility_2 RetroCM[:general][:user_management][:secure_auth] = false u = build_some_valid_user assert(u.save) plain = 'new_password' u.password = Digest::SHA1.hexdigest("c-o-l-l-a-b-o-a--#{plain}--") assert(u.save) assert(!u.valid_password?(plain)) assert(u.outdated_valid_password?(plain)) params = {:login => u.login, :password => plain} auth = User.authenticate(params) assert_not_nil(auth) assert_equal(u.id, auth.id) # check for re-login u.reload assert_equal(u.send(:hash_crypt, plain), u.password) login = u.login.dup User.reset_column_information params = {:login => login, :password => plain} auth = User.authenticate(params) assert_not_nil(auth) end def test_password_backward_compatibility_3 u = users(:collaboa) assert_equal(u.password, Digest::SHA1.hexdigest("c-o-l-l-a-b-o-a--password--")) params = {:login => 'collaboa', :password => 'password'} u = User.authenticate(params) assert_not_nil(u) assert_equal('collaboa', u.login) assert_equal(u.send(:hash_crypt, 'password'), u.password) # check for re-login User.reset_column_information params = {:login => 'collaboa', :password => 'password'} u = User.authenticate(params) assert_not_nil(u) assert_equal('collaboa', u.login) assert_equal(u.send(:hash_crypt, 'password'), u.password) end def test_if_public_user_can_be_modified pu = User.public_user assert(pu.public?) assert(!pu.save) pu.login = 'evil' assert_equal(pu.login, 'Public') assert(!pu.save) pu.reload pu.admin = true assert(!pu.save) pu.reload pu.active = true assert(!pu.save) pu.reload assert_equal(pu.login, 'Public') end def test_public_user_must_not_be_authenticated pu = User.public_user params = {:login => pu.login, :password => 'public'} auth_user = User.authenticate(params) assert_nil(auth_user) end def test_not_possible_to_remove_default_group_from_a_user user = build_some_valid_user assert(user.save) assert(user.groups.include?(Group.default_group)) user.groups = [] assert(user.save) assert(user.groups.include?(Group.default_group)) end def test_uniqueness_of_groups user = build_some_valid_user assert_nothing_raised(){user.save!} assert_equal(1, user.groups.size) group = Group.new(:name => 'Test Group') group.permissions = [RetroAM.permission_list.last] assert_nothing_raised(){group.save!} user.groups << group assert_nothing_raised(){user.save!} assert_equal(2, user.groups.size) user.groups << group assert(user.save) assert_equal(2, user.groups.size) end def test_user_project_relation p1 = projects(:retro) assert(p1) p2 = Project.new(:name => 'Second') assert(p2.save) user = User.public_user group = Group.default_group assert(user.groups.include?(group)) assert_equal(1, user.groups.size) group.access_to_all_projects = false group.projects = [] assert(group.save) assert_equal(0, group.reload.projects.size) assert_equal(0, user.reload.projects.size) group.projects = [p1] assert(group.save) assert_equal(1, group.reload.projects.size) assert_equal(1, user.reload.projects.size) group.projects = [p1, p2] assert(group.save) assert_equal(2, group.reload.projects.size) assert_equal(2, user.reload.projects.size) all_projects_size = Project.count all_opened_projects_size = Project.count(:conditions => ["closed = ?", false]) group.projects = [] group.access_to_all_projects = true assert(group.save) assert_equal(all_projects_size, group.reload.projects.size) assert_equal(['All'], group.project_names) assert_equal(all_opened_projects_size, user.reload.projects.size) p2.closed = true assert(p2.save) assert_equal(all_projects_size, group.reload.projects.size) assert_equal(['All'], group.project_names) assert_equal(all_opened_projects_size - 1, user.reload.projects.size) end private def build_some_valid_user user = User.new( :name => 'Some User', :plain_password => 'password', :plain_password_confirmation => 'password' ) user.login = 'some_user' user.email = 'some_user@email.com' user end end