require_relative '../../../spec_helper' require_relative '../../../../app/controllers/carto/api/organizations_controller' require 'helpers/unique_names_helper' describe Carto::Api::OrganizationUsersController do include_context 'organization with users helper' include UniqueNamesHelper include Rack::Test::Methods include Warden::Test::Helpers def soft_limits(user) [ user.soft_geocoding_limit, user.soft_twitter_datasource_limit, user.soft_here_isolines_limit, user.soft_obs_snapshot_limit, user.soft_obs_general_limit ] end def set_soft_limits(user, soft_limits) user.soft_geocoding_limit = soft_limits[0] user.soft_twitter_datasource_limit = soft_limits[1] user.soft_here_isolines_limit = soft_limits[2] user.soft_obs_snapshot_limit = soft_limits[3] user.soft_obs_general_limit = soft_limits[4] end def replace_soft_limits(user, soft_limits) old_soft_limits = soft_limits(user) set_soft_limits(user, soft_limits) user.save old_soft_limits end def user_params_soft_limits(username, soft_limit, with_password: false) user_params(username, soft_geocoding_limit: soft_limit, soft_twitter_datasource_limit: soft_limit, soft_here_isolines_limit: soft_limit, soft_obs_snapshot_limit: soft_limit, soft_obs_general_limit: soft_limit, with_password: with_password) end def user_params(username = nil, with_password: false, soft_geocoding_limit: false, soft_twitter_datasource_limit: nil, soft_here_isolines_limit: nil, soft_obs_snapshot_limit: nil, soft_obs_general_limit: nil, viewer: nil, org_admin: nil, email: "#{username}@carto.com", force_password_change: false) params = { password: '2{Patrañas}', quota_in_bytes: 1024 } unless username.nil? params[:username] = username params[:email] = email end params[:soft_geocoding_limit] = soft_geocoding_limit unless soft_geocoding_limit.nil? params[:soft_twitter_datasource_limit] = soft_twitter_datasource_limit unless soft_twitter_datasource_limit.nil? params[:soft_here_isolines_limit] = soft_here_isolines_limit unless soft_here_isolines_limit.nil? params[:soft_obs_snapshot_limit] = soft_obs_snapshot_limit unless soft_obs_snapshot_limit.nil? params[:soft_obs_general_limit] = soft_obs_general_limit unless soft_obs_general_limit.nil? params[:viewer] = viewer if viewer params[:org_admin] = org_admin if org_admin params[:force_password_change] = force_password_change params.except!(:password) unless with_password params end def verify_soft_limits(user, value) user.soft_geocoding_limit.should eq value user.soft_twitter_datasource_limit.should eq value user.soft_here_isolines_limit.should eq value user.soft_obs_snapshot_limit.should eq value user.soft_obs_general_limit.should eq value end before(:all) do @org_user_2.org_admin = true @org_user_2.save end before(:each) do ::User.any_instance.stubs(:validate_credentials_not_taken_in_central).returns(true) ::User.any_instance.stubs(:create_in_central).returns(true) ::User.any_instance.stubs(:update_in_central).returns(true) ::User.any_instance.stubs(:delete_in_central).returns(true) ::User.any_instance.stubs(:load_common_data).returns(true) ::User.any_instance.stubs(:reload_avatar).returns(true) end before(:each) do @old_soft_limits = soft_limits(@organization.owner) @old_whitelisted_email_domains = @organization.whitelisted_email_domains end after(:each) do set_soft_limits(@organization.owner, @old_soft_limits) @organization.owner.save @organization.whitelisted_email_domains = @old_whitelisted_email_domains @organization.save end describe 'user creation' do it 'returns 401 for non authorized calls' do post api_v2_organization_users_create_url(id_or_name: @organization.name) last_response.status.should == 401 end it 'returns 401 for non authorized users' do login(@org_user_1) post api_v2_organization_users_create_url(id_or_name: @organization.name) last_response.status.should == 401 end it 'accepts org owners' do login(@organization.owner) post api_v2_organization_users_create_url(id_or_name: @organization.name) last_response.status.should == 410 end it 'accepts org admins' do login(@org_user_2) post api_v2_organization_users_create_url(id_or_name: @organization.name) last_response.status.should == 410 end it 'returns 410 if email is not present' do login(@organization.owner) params = { username: unique_name('user'), password: '2{Patrañas}' } post api_v2_organization_users_create_url(id_or_name: @organization.name), params last_response.body.include?('email is not present').should be true last_response.status.should == 410 end it 'returns 410 if username is not present' do login(@organization.owner) params = { email: unique_email, password: '2{Patrañas}' } post api_v2_organization_users_create_url(id_or_name: @organization.name), params last_response.body.include?('username is not present').should be true last_response.status.should == 410 end it 'returns 410 if password is not present' do login(@organization.owner) username = 'manolo' params = { username: username, email: "#{username}@carto.com" } post api_v2_organization_users_create_url(id_or_name: @organization.name), params last_response.status.should eq 410 last_response.body.include?("password can't be blank").should be true end it 'returns 410 if password is username' do login(@organization.owner) username = 'manolo' params = { username: username, email: "#{username}@carto.com", password: username } post api_v2_organization_users_create_url(id_or_name: @organization.name), params last_response.status.should eq 410 last_response.body.include?('must be different than the user name').should be true end it 'returns 410 if password is a common one' do login(@organization.owner) username = 'manolo' params = { username: username, email: "#{username}@carto.com", password: 'galina' } post api_v2_organization_users_create_url(id_or_name: @organization.name), params last_response.status.should eq 410 last_response.body.include?("can't be a common password").should be true end it 'returns 410 if password is not strong' do Organization.any_instance.stubs(:strong_passwords_enabled).returns(true) login(@organization.owner) username = 'manolo' params = { username: username, email: "#{username}@carto.com", password: 'galina' } post api_v2_organization_users_create_url(id_or_name: @organization.name), params last_response.status.should eq 410 last_response.body.include?('must be at least 8 characters long').should be true Organization.any_instance.unstub(:strong_passwords_enabled) end it 'correctly creates a user' do login(@organization.owner) username = 'manolo-escobar' params = user_params(username, with_password: true) post_json api_v2_organization_users_create_url(id_or_name: @organization.name), params do |response| response.status.should eq 200 response.body[:username].should eq username response.body[:email].should eq "#{username}@carto.com" response.body[:quota_in_bytes].should eq 1024 response.body[:builder_enabled].should be_nil response.body[:engine_enabled].should be_nil response.body[:viewer].should eq false response.body[:org_admin].should eq false response.body[:base_url].should include(username, @organization.name) response.body[:db_size_in_bytes].should eq 0 response.body[:table_count].should eq 0 response.body[:public_visualization_count].should eq 0 response.body[:all_visualization_count].should eq 0 response.body[:soft_geocoding_limit].should eq false # We are returning a nil avatar on creation since this is chosen during creation (Resque) # response.body[:avatar_url].should be end @organization.reload last_user_created = @organization.users.find { |u| u.username == username } last_user_created.username.should eq username last_user_created.email.should eq "#{username}@carto.com" last_user_created.soft_geocoding_limit.should eq false last_user_created.quota_in_bytes.should eq 1024 last_user_created.builder_enabled.should be_nil last_user_created.engine_enabled.should be_nil last_user_created.viewer.should eq false last_user_created.org_admin.should eq false last_user_created.destroy end it 'does not take email whitelisting into account for user creation' do login(@organization.owner) username = 'notwhitelisted' domain = 'notwhitelisted.com' email = "#{username}@#{domain}" params = user_params(username, email: email, with_password: true) old_whitelisted_email_domains = @organization.whitelisted_email_domains @organization.whitelisted_email_domains = ['carto.com'] @organization.save post_json api_v2_organization_users_create_url(id_or_name: @organization.name), params do |response| response.status.should eq 200 response.body[:username].should eq username response.body[:email].should eq email @organization.reload last_user_created = @organization.users.find { |u| u.username == username } last_user_created.username.should eq username last_user_created.email.should eq email end end it 'assigns soft_geocoding_limit to false by default' do login(@organization.owner) username = 'soft-geocoding-limit-false-user' params = user_params(username, soft_geocoding_limit: nil, with_password: true) post api_v2_organization_users_create_url(id_or_name: @organization.name), params last_response.status.should eq 200 @organization.reload last_user_created = @organization.users.find { |u| u.username == username } last_user_created.soft_geocoding_limit.should eq false last_user_created.destroy end it 'can create viewers' do Carto::UserCreation.any_instance.expects(:load_common_data).never login(@organization.owner) username = 'viewer-user' params = user_params(username, viewer: true, with_password: true) post api_v2_organization_users_create_url(id_or_name: @organization.name), params last_response.status.should eq 200 @organization.reload last_user_created = @organization.users.find { |u| u.username == username } last_user_created.viewer.should eq true last_user_created.destroy end it 'creates non-admin builders by default' do login(@organization.owner) username = 'builder-user' params = user_params(username, with_password: true) post api_v2_organization_users_create_url(id_or_name: @organization.name), params last_response.status.should eq 200 @organization.reload last_user_created = @organization.users.find { |u| u.username == username } last_user_created.viewer.should eq false last_user_created.org_admin.should eq false last_user_created.destroy end it 'can create organization admins' do login(@organization.owner) username = 'admin-user' params = user_params(username, org_admin: true, with_password: true) post api_v2_organization_users_create_url(id_or_name: @organization.name), params last_response.status.should eq 200 @organization.reload last_user_created = @organization.users.find { |u| u.username == username } last_user_created.org_admin.should eq true last_user_created.destroy end it 'admins cannot create other organization admins' do login(@org_user_2) username = 'admin-user' params = user_params(username, org_admin: true, with_password: true) post api_v2_organization_users_create_url(id_or_name: @organization.name), params last_response.status.should eq 410 expect(last_response.body).to include 'org_admin can only be set by organization owner' end it 'can enable soft geocoding_limit, twitter_datasource_limit, here_isolines_limit, obs_snapshot_limit and obs_general_limit if owner has them' do replace_soft_limits(@organization.owner, [true, true, true, true, true]) login(@organization.owner) username = 'soft-limits-true-user' params = user_params_soft_limits(username, true, with_password: true) post api_v2_organization_users_create_url(id_or_name: @organization.name), params last_response.status.should eq 200 @organization.reload last_user_created = @organization.users.find { |u| u.username == username } verify_soft_limits(last_user_created, true) last_user_created.destroy end it 'can disable soft geocoding_limit, twitter_datasource_limit, here_isolines_limit, obs_snapshot_limit and obs_general_limit if owner has them' do replace_soft_limits(@organization.owner, [true, true, true, true, true]) login(@organization.owner) username = 'soft-limits-false-user' params = user_params_soft_limits(username, false, with_password: true) post api_v2_organization_users_create_url(id_or_name: @organization.name), params last_response.status.should eq 200 @organization.reload last_user_created = @organization.users.find { |u| u.username == username } verify_soft_limits(last_user_created, false) last_user_created.destroy end it 'cannot enable soft geocoding_limit, twitter_datasource_limit, here_isolines_limit, obs_snapshot_limit or obs_general_limit if owner has not them' do replace_soft_limits(@organization.owner, [false, false, false, false, false]) login(@organization.owner) username = 'soft-limits-true-invalid-user' params = user_params_soft_limits(username, true, with_password: true) post api_v2_organization_users_create_url(id_or_name: @organization.name), params last_response.status.should eq 410 errors = JSON.parse(last_response.body) errors.count.should eq 5 @organization.reload @organization.users.find { |u| u.username == username }.should be_nil end describe 'with password expiration' do before(:all) do @organization.password_expiration_in_d = 10 @organization.save end after(:all) do @organization.password_expiration_in_d = nil @organization.save end it 'can create users with expired passwords' do login(@organization.owner) username = unique_name('user') params = user_params(username, org_admin: true, with_password: true, force_password_change: true) post_json api_v2_organization_users_create_url(id_or_name: @organization.name), params do |response| response.status.should eq 200 end @organization.reload last_user_created = @organization.users.find { |u| u.username == username } expect(last_user_created.password_expired?).to(be(true)) last_user_created.destroy end end end describe 'user update' do it 'returns 401 for non authorized calls' do put api_v2_organization_users_update_url(id_or_name: @organization.name, u_username: @org_user_1.username) last_response.status.should == 401 end it 'returns 401 for non authorized users' do login(@org_user_1) put api_v2_organization_users_update_url(id_or_name: @organization.name, u_username: @org_user_1.username) last_response.status.should == 401 end it 'accepts org owners' do login(@organization.owner) put api_v2_organization_users_update_url(id_or_name: @organization.name, u_username: @org_user_1.username) last_response.status.should == 410 end it 'accepts org admins' do login(@org_user_2) put api_v2_organization_users_update_url(id_or_name: @organization.name, u_username: @org_user_1.username) last_response.status.should == 410 end it 'org admins cannot update other admins' do login(@org_user_2) put api_v2_organization_users_update_url(id_or_name: @organization.name, u_username: @organization.owner.username) last_response.status.should == 401 end it 'org admins cannot convert other users into admins' do login(@org_user_2) put api_v2_organization_users_update_url(id_or_name: @organization.name, u_username: @org_user_1.username), org_admin: true last_response.status.should == 410 expect(last_response.body).to include 'org_admin can only be set by organization owner' end it 'should do nothing if no update params are provided' do login(@organization.owner) user_to_update = @organization.non_owner_users[0] put api_v2_organization_users_update_url(id_or_name: @organization.name, u_username: user_to_update.username) last_response.status.should eq 410 last_response.body.include?('No update params provided').should be true end it 'should update password' do login(@organization.owner) user_to_update = @organization.non_owner_users[0] params = { password: 'limonero' } put api_v2_organization_users_update_url(id_or_name: @organization.name, u_username: user_to_update.username), params last_response.status.should == 200 end it 'fails to update password if the same as old_password' do login(@organization.owner) user_to_update = @organization.non_owner_users[0] user_to_update.password = '00012345678' user_to_update.password_confirmation = '00012345678' user_to_update.save user_to_update.reload last_change = user_to_update.last_password_change_date params = { password: '00012345678' } put api_v2_organization_users_update_url(id_or_name: @organization.name, u_username: user_to_update.username), params last_response.status.should == 410 user_to_update.reload expect(user_to_update.last_password_change_date.utc.to_s).to eq last_change.utc.to_s end it 'fails to update password if the same as username' do login(@organization.owner) user_to_update = @organization.non_owner_users[0] params = { password: user_to_update.username } put api_v2_organization_users_update_url(id_or_name: @organization.name, u_username: user_to_update.username), params last_response.status.should == 410 last_response.body.should include 'must be different than the user name' end it 'fails to update password if it is a common one' do login(@organization.owner) user_to_update = @organization.non_owner_users[0] params = { password: 'galina' } put api_v2_organization_users_update_url(id_or_name: @organization.name, u_username: user_to_update.username), params last_response.status.should == 410 last_response.body.should include "can't be a common password" end it 'fails to update password if strongs passwords enabled' do Organization.any_instance.stubs(:strong_passwords_enabled).returns(true) login(@organization.owner) user_to_update = @organization.non_owner_users[0] params = { password: 'galina' } put api_v2_organization_users_update_url(id_or_name: @organization.name, u_username: user_to_update.username), params last_response.status.should == 410 last_response.body.should include 'password must be at least 8 characters long' Organization.any_instance.unstub(:strong_passwords_enabled) end it 'should update email' do login(@organization.owner) user_to_update = @organization.non_owner_users[0] new_email = "new-#{user_to_update.email}" params = { email: new_email } put api_v2_organization_users_update_url(id_or_name: @organization.name, u_username: user_to_update.username), params last_response.status.should eq 200 user_to_update.reload.email.should == new_email end it 'should update viewer' do login(@organization.owner) 2.times do user_to_update = @org_user_1 new_viewer = !user_to_update.viewer? params = { viewer: new_viewer } put api_v2_organization_users_update_url(id_or_name: @organization.name, u_username: user_to_update.username), params last_response.status.should eq 200 user_to_update.reload.viewer.should == new_viewer end end it 'should update org_admin' do login(@organization.owner) user_to_update = @organization.non_owner_users[0] 2.times do new_org_admin = !user_to_update.org_admin params = { org_admin: new_org_admin } put(api_v2_organization_users_update_url(id_or_name: @organization.name, u_username: user_to_update.username), params) last_response.status.should eq 200 user_to_update.reload.org_admin.should == new_org_admin end end it 'should reject viewers who are also admins' do login(@organization.owner) user_to_update = @organization.non_owner_users[0] params = { org_admin: true, viewer: true } put(api_v2_organization_users_update_url(id_or_name: @organization.name, u_username: user_to_update.username), params) last_response.status.should eq 410 end it 'should update quota_in_bytes' do login(@organization.owner) user_to_update = @organization.non_owner_users[0] params = { quota_in_bytes: 2048 } put api_v2_organization_users_update_url(id_or_name: @organization.name, u_username: user_to_update.username), params last_response.status.should eq 200 user_to_update.reload user_to_update.quota_in_bytes.should == 2048 end it 'should not update soft_geocoding_limit if owner has not it' do replace_soft_limits(@organization.owner, [false, false, false]) login(@organization.owner) user_to_update = @organization.non_owner_users[0] params = { soft_geocoding_limit: true } put api_v2_organization_users_update_url(id_or_name: @organization.name, u_username: user_to_update.username), params last_response.status.should eq 410 user_to_update.reload.soft_geocoding_limit.should be false end it 'should update soft_geocoding_limit' do replace_soft_limits(@organization.owner, [true, true, true]) login(@organization.owner) user_to_update = @organization.non_owner_users[0] params = { soft_geocoding_limit: true } put api_v2_organization_users_update_url(id_or_name: @organization.name, u_username: user_to_update.username), params last_response.status.should eq 200 user_to_update.reload.soft_geocoding_limit.should be true params = { soft_geocoding_limit: false } put api_v2_organization_users_update_url(id_or_name: @organization.name, u_username: user_to_update.username), params last_response.status.should eq 200 user_to_update.reload user_to_update.soft_geocoding_limit.should be false end it 'should do full update' do @organization.owner.soft_geocoding_limit = true @organization.owner.save login(@organization.owner) user_to_update = @organization.non_owner_users[0] new_email = "#{user_to_update.email}.es" params = { email: new_email, password: 'pataton', soft_geocoding_limit: true, quota_in_bytes: 2048 } put_json api_v2_organization_users_update_url(id_or_name: @organization.name, u_username: user_to_update.username), params do |response| user_to_update.reload response.status.should eq 200 response.body[:username].should eq user_to_update.username response.body[:email].should eq new_email response.body[:quota_in_bytes].should eq 2048 response.body[:builder_enabled].should eq user_to_update.builder_enabled response.body[:engine_enabled].should eq user_to_update.engine_enabled response.body[:viewer].should eq user_to_update.viewer response.body[:org_admin].should eq user_to_update.org_admin response.body[:base_url].should include(user_to_update.username, @organization.name) response.body[:db_size_in_bytes].should eq 0 response.body[:table_count].should eq 0 response.body[:public_visualization_count].should eq 0 response.body[:all_visualization_count].should eq 0 response.body[:avatar_url].should eq user_to_update.avatar_url response.body[:soft_geocoding_limit].should eq true end user_to_update.email.should eq new_email user_to_update.soft_geocoding_limit.should be true user_to_update.quota_in_bytes.should == 2048 end it 'can enable soft geocoding_limit, twitter_datasource_limit, here_isolines_limit, obs_snapshot_limit and obs_general_limit if owner has them' do replace_soft_limits(@organization.owner, [true, true, true, true, true]) login(@organization.owner) user_to_update = @organization.non_owner_users[0] params = user_params_soft_limits(nil, true, with_password: false) put api_v2_organization_users_update_url(id_or_name: @organization.name, u_username: user_to_update.username), params last_response.status.should eq 200 user_to_update.reload verify_soft_limits(user_to_update, true) end it 'can disable soft geocoding_limit, twitter_datasource_limit, here_isolines_limit, obs_snapshot_limit and obs_general_limit if owner has them' do replace_soft_limits(@organization.owner, [true, true, true, true, true]) login(@organization.owner) user_to_update = @organization.non_owner_users[0] params = user_params_soft_limits(nil, false, with_password: false) put api_v2_organization_users_update_url(id_or_name: @organization.name, u_username: user_to_update.username), params last_response.status.should eq 200 user_to_update.reload verify_soft_limits(user_to_update, false) end it 'cannot enable soft geocoding_limit, twitter_datasource_limit, here_isolines_limit, obs_snapshot_limit and obs_general_limit if owner has not them' do replace_soft_limits(@organization.owner, [false, false, false, false, false]) login(@organization.owner) user_to_update = @organization.non_owner_users[0] replace_soft_limits(user_to_update, [false, false, false]) params = user_params_soft_limits(nil, true, with_password: false) put api_v2_organization_users_update_url(id_or_name: @organization.name, u_username: user_to_update.username), params last_response.status.should eq 410 errors = JSON.parse(last_response.body) errors.count.should eq 5 user_to_update.reload verify_soft_limits(user_to_update, false) end it 'should not update if it cannot update in central' do ::User.any_instance.stubs(:update_in_central).raises(CartoDB::CentralCommunicationFailure.new('Failed')) login(@organization.owner) user_to_update = @organization.non_owner_users[0] params = { email: 'fail-' + user_to_update.email } put api_v2_organization_users_update_url(id_or_name: @organization.name, u_username: user_to_update.username), params last_response.status.should == 500 user_to_update.reload user_to_update.email.should_not start_with('fail-') end it 'should validate password before updating in Central' do ::User.any_instance.unstub(:update_in_central) ::User.any_instance.stubs(:update_in_central).never login(@organization.owner) user_to_update = @organization.non_owner_users[0] params = { password: 'a' } put api_v2_organization_users_update_url(id_or_name: @organization.name, u_username: user_to_update.username), params last_response.status.should == 410 end it 'should validate before updating in Central' do ::User.any_instance.unstub(:update_in_central) ::User.any_instance.stubs(:update_in_central).never login(@organization.owner) user_to_update = @organization.non_owner_users[0] params = { quota_in_bytes: @organization.quota_in_bytes * 2 } put api_v2_organization_users_update_url(id_or_name: @organization.name, u_username: user_to_update.username), params last_response.status.should == 410 end end describe 'user deletion' do it 'returns 401 for non authorized calls' do delete api_v2_organization_users_delete_url(id_or_name: @organization.name, u_username: @org_user_1.username) last_response.status.should == 401 end it 'returns 401 for non authorized users' do login(@org_user_1) delete api_v2_organization_users_delete_url(id_or_name: @organization.name, u_username: @org_user_1.username) last_response.status.should == 401 end it 'should delete users as owner' do login(@organization.owner) user_to_be_deleted = @organization.non_owner_users[0] delete api_v2_organization_users_delete_url(id_or_name: @organization.name, u_username: user_to_be_deleted.username) last_response.status.should eq 200 User[user_to_be_deleted.id].should be_nil end it 'should delete users with unregistered tables if force parameter is present' do login(@organization.owner) user_with_unregistered_tables = create_test_user('foobarbaz', @organization) user_with_unregistered_tables.in_database.run('CREATE TABLE wadus (id serial)') delete api_v2_organization_users_delete_url( id_or_name: @organization.name, u_username: user_with_unregistered_tables.username, force: true ) last_response.status.should eq 200 User[user_with_unregistered_tables.id].should be_nil end it 'should fail trying to delete users with unregistered tables and no force parameter present' do login(@organization.owner) user_with_unregistered_tables = create_test_user('foobarbaz', @organization) user_with_unregistered_tables.in_database.run('CREATE TABLE wadus (id serial)') delete api_v2_organization_users_delete_url( id_or_name: @organization.name, u_username: user_with_unregistered_tables.username ) last_response.status.should eq 500 end it 'should delete users as admin' do login(@org_user_2) victim = FactoryGirl.create(:valid_user, organization: @organization) delete api_v2_organization_users_delete_url(id_or_name: @organization.name, u_username: victim.username) last_response.status.should eq 200 User[victim.id].should be_nil end it 'should not delete other admins as admin' do login(@org_user_2) victim = FactoryGirl.create(:valid_user, organization: @organization, org_admin: true) delete api_v2_organization_users_delete_url(id_or_name: @organization.name, u_username: victim.username) last_response.status.should eq 401 User[victim.id].should be end it 'should not allow to delete the org owner' do login(@organization.owner) user_to_be_deleted = @organization.owner delete api_v2_organization_users_delete_url(id_or_name: @organization.name, u_username: user_to_be_deleted.username) last_response.status.should == 401 end describe 'with Central' do before(:each) do ::User.any_instance.unstub(:delete_in_central) Cartodb::Central.stubs(:sync_data_with_cartodb_central?).returns(true) @organization.reload @user_to_be_deleted = @organization.non_owner_users.first end def mock_delete_request(code) response_mock = mock response_mock.stubs(:code).returns(code) response_mock.stubs(:body).returns('{"errors": []}') Carto::Http::Request.any_instance.stubs(:run).returns(response_mock) end it 'should delete users in Central' do ::User.any_instance.stubs(:destroy).once mock_delete_request(204) login(@organization.owner) delete api_v2_organization_users_delete_url(id_or_name: @organization.name, u_username: @user_to_be_deleted.username) last_response.status.should eq 200 end it 'should delete users missing from Central' do ::User.any_instance.stubs(:destroy).once mock_delete_request(404) login(@organization.owner) delete api_v2_organization_users_delete_url(id_or_name: @organization.name, u_username: @user_to_be_deleted.username) last_response.status.should eq 200 end it 'should not delete users from Central that failed to delete in the box' do ::User.any_instance.stubs(:delete_in_central).never ::User.any_instance.stubs(:destroy).raises("BOOM") login(@organization.owner) delete api_v2_organization_users_delete_url(id_or_name: @organization.name, u_username: @user_to_be_deleted.username) last_response.status.should eq 500 end end end describe 'user show' do it 'returns 401 for non authorized calls' do get api_v2_organization_users_show_url(id_or_name: @organization.name, u_username: @org_user_1.username) last_response.status.should == 401 end it 'returns 401 for non authorized users' do login(@org_user_1) get api_v2_organization_users_show_url(id_or_name: @organization.name, u_username: @org_user_1.username) last_response.status.should == 401 end it 'should return 404 for non existing users' do login(@organization.owner) get api_v2_organization_users_show_url(id_or_name: @organization.name, u_username: 'bogus-non-existent-user') last_response.status.should == 404 end it 'should show existing users' do login(@organization.owner) @organization.reload user_to_be_shown = @organization.non_owner_users[0] get api_v2_organization_users_show_url(id_or_name: @organization.name, u_username: user_to_be_shown.username) last_response.status.should eq 200 last_response.body == Carto::Api::UserPresenter.new(user_to_be_shown, current_viewer: @organization.owner).to_poro end end describe 'user list' do it 'returns 401 for non authorized calls' do get api_v2_organization_users_index_url(id_or_name: @organization.name) last_response.status.should == 401 end it 'returns 401 for non authorized users' do login(@org_user_1) get api_v2_organization_users_index_url(id_or_name: @organization.name) last_response.status.should == 401 end it 'returns 401 when session is not valid' do organization = create_organization_with_owner user = FactoryGirl.create(:valid_user, organization: organization, org_admin: true) login_response = post_session(user: user, password: 'kkkkkkkkk', organization: organization) set_cookies_for_next_request(login_response) get api_v2_organization_users_index_url(id_or_name: organization.name) last_response.status.should == 200 user.invalidate_all_sessions! set_cookies_for_next_request(login_response) get api_v2_organization_users_index_url(id_or_name: organization.name) last_response.status.should == 401 end it 'should list users' do login(@organization.owner) @organization.reload organization_users_presentations = @organization.users.each do |user| Carto::Api::UserPresenter.new(user, current_viewer: @organization.owner).to_poro end get api_v2_organization_users_index_url(id_or_name: @organization.name) last_response.status.should eq 200 last_response.body == organization_users_presentations end end end