cartodb-4.42/spec/requests/user_state_spec.rb

584 lines
19 KiB
Ruby
Raw Normal View History

2024-04-06 13:25:13 +08:00
require_relative '../spec_helper'
require 'helpers/subdomainless_helper'
include Warden::Test::Helpers
include Carto::Factories::Visualizations
def login(user)
login_as(user, scope: user.username)
domain = user.organization ? user.organization.name : user.username
base_url = CartoDB.subdomainless_urls? ? "localhost.lan" : "#{domain}.localhost.lan"
host! base_url
end
def follow_redirects(limit = 10)
while response.redirect? && (limit -= 1) > 0
follow_redirect!
end
end
describe "UserState" do
before(:all) do
@organization = create_organization_with_owner
@org_account_type = create_account_type_fg('ORGANIZATION USER')
@locked_user = FactoryGirl.create(:locked_user)
@map, @table, @table_visualization, @visualization = create_full_builder_vis(@locked_user)
@visualization.create_mapcap!
@non_locked_user = FactoryGirl.create(:valid_user)
@unverified_user = FactoryGirl.create(:unverified_user)
@public_user_endpoints = ['/me'].freeze
@user_endpoints = ['/account', '/profile'].freeze
@dashboard_endpoints = ['/dashboard', '/dashboard/tables', '/dashboard/datasets', '/dashboard/visualizations',
'/dashboard/maps'].freeze
@tables_endpoints = ["/tables/#{@table.id}", "/tables/#{@table.id}/public", "/tables/#{@table.id}/embed_map"].freeze
@viz_endpoints = ["/viz/#{@visualization.id}/public",
"/viz/#{@visualization.id}/embed_map", "/viz/#{@visualization.id}/public_map",
"/builder/#{@visualization.id}", "/builder/#{@visualization.id}/embed"].freeze
@admin_endpoints = @public_user_endpoints + @user_endpoints + @dashboard_endpoints + @tables_endpoints +
@viz_endpoints
@public_api_viz_endpoints = ["/api/v1/viz", "/api/v1/viz/#{@visualization.id}",
"/api/v2/viz/#{@visualization.id}/viz",
"/api/v3/viz/#{@visualization.id}/viz"].freeze
@public_api_me_endpoint = ["/api/v3/me"].freeze
@public_api_endpoints = @public_api_viz_endpoints + @public_api_me_endpoint
@private_api_endpoints = ["/api/v1/tables/#{@table.id}", "/api/v1/tables/#{@table.id}/columns",
"/api/v1/imports", "/api/v1/users/#{@locked_user.id}/layers",
"/api/v1/synchronizations", "/api/v1/geocodings",
"/api/v1/users/#{@locked_user.id}"]
@headers = {}
@api_headers = { 'CONTENT_TYPE' => 'application/json', :format => "json" }
@maintenance_mode_user = FactoryGirl.create(:valid_user, maintenance_mode: true)
end
after(:all) do
@locked_user.destroy
@non_locked_user.destroy
@maintenance_mode_user.destroy
@unverified_user.destroy
end
context 'unverified user' do
shared_examples 'unverified user' do
it 'redirects to unverified for admin endpoints' do
@admin_endpoints.each do |endpoint|
login(@unverified_user)
endpoint = "/user/#{@unverified_user.username}/#{endpoint}" unless host.include?(@unverified_user.username)
get endpoint, {}, @headers
response.status.should == 302
follow_redirect!
request.path.should include "unverified"
end
end
it 'returns 403 for private api endpoints' do
@private_api_endpoints.each do |endpoint|
login(@unverified_user)
endpoint = "/user/#{@unverified_user.username}/#{endpoint}" unless host.include?(@unverified_user.username)
get "#{endpoint}?api_key=#{@unverified_user.api_key}", {}, @api_headers
response.status.should == 403
end
end
it 'returns 403 for public api viz endpoints' do
@public_api_viz_endpoints.each do |endpoint|
login(@unverified_user)
endpoint = "/user/#{@unverified_user.username}/#{endpoint}" unless host.include?(@unverified_user.username)
get endpoint, {}, @api_headers
response.status.should == 403
end
end
it 'returns 200 for public api me endpoint' do
@public_api_me_endpoint.each do |endpoint|
login(@unverified_user)
get endpoint, {}, @api_headers
request.path.should == endpoint
response.status.should == 200
end
end
end
end
context 'locked state' do
shared_examples "locked user" do
it 'redirects to lockout for admin endpoints' do
@admin_endpoints.each do |endpoint|
login(@locked_user)
endpoint = "/user/#{@locked_user.username}/#{endpoint}" unless host.include?(@locked_user.username)
get endpoint, {}, @headers
response.status.should == 302
follow_redirects
request.path.should include '/lockout'
response.status.should == 200
end
end
it 'returns 403 for private api endpoints' do
@private_api_endpoints.each do |endpoint|
login(@locked_user)
endpoint = "/user/#{@locked_user.username}/#{endpoint}" unless host.include?(@locked_user.username)
get "#{endpoint}?api_key=#{@locked_user.api_key}", {}, @api_headers
response.status.should == 403
end
end
it 'returns 403 for public api viz endpoints' do
@public_api_viz_endpoints.each do |endpoint|
login(@locked_user)
endpoint = "/user/#{@locked_user.username}/#{endpoint}" unless host.include?(@locked_user.username)
get endpoint, {}, @api_headers
response.status.should == 403
end
end
it 'returns 200 for public api me endpoint' do
@public_api_me_endpoint.each do |endpoint|
login(@locked_user)
get endpoint, {}, @api_headers
request.path.should == endpoint
response.status.should == 200
end
end
end
context 'with subdomainless' do
before(:each) do
stub_subdomainless
end
context 'organizational user' do
before(:each) do
@locked_user.organization = @organization
@locked_user.account_type = @org_account_type
@locked_user.save
end
after(:each) do
@locked_user.organization = nil
@locked_user.account_type = 'FREE'
@locked_user.save
end
it_behaves_like 'locked user'
it_behaves_like 'unverified user'
end
context 'regular user' do
it_behaves_like 'locked user'
it_behaves_like 'unverified user'
end
end
context 'with domainful' do
context 'organizational user' do
before(:each) do
stub_domainful(@organization.name)
end
before(:each) do
@locked_user.organization = @organization
@locked_user.account_type = @org_account_type
@locked_user.save
end
after(:each) do
@locked_user.organization = nil
@locked_user.account_type = 'FREE'
@locked_user.save
end
it_behaves_like 'locked user'
it_behaves_like 'unverified user'
end
context 'unverified regular user' do
before(:each) do
stub_domainful(@unverified_user.username)
end
it_behaves_like 'unverified user'
end
context 'regular user' do
before(:each) do
stub_domainful(@locked_user.username)
end
it_behaves_like 'locked user'
it_behaves_like 'unverified user'
it 'user accessing a locked user resources' do
login(@non_locked_user)
host! "#{@locked_user.username}.localhost.lan"
@user_endpoints.each do |endpoint|
get endpoint, {}, @headers
response.status.should == 404
end
@public_user_endpoints.each do |endpoint|
get endpoint, {}, @headers
response.status.should == 404
end
@tables_endpoints.each do |endpoint|
get endpoint, {}, @headers
response.status.should == 404
end
@viz_endpoints.each do |endpoint|
get endpoint, {}, @headers
response.status.should == 404
end
@public_api_endpoints.each do |endpoint|
get endpoint, {}, @api_headers
request.path.should == endpoint
response.status.should == if endpoint == "/api/v3/me"
200
else
404
end
end
end
it 'non-logged user accessing a locked user resources' do
host! "#{@locked_user.username}.localhost.lan"
@public_user_endpoints.each do |endpoint|
get endpoint, {}, @headers
response.status.should == 404
end
@tables_endpoints.each do |endpoint|
get endpoint, {}, @headers
response.status.should == 404
end
@viz_endpoints.each do |endpoint|
get endpoint, {}, @headers
response.status.should == 404
end
@public_api_endpoints.each do |endpoint|
get endpoint, {}, @api_headers
request.path.should == endpoint
response.status.should == if endpoint == "/api/v3/me"
200
else
404
end
end
end
end
end
it 'locked user can delete their own account' do
to_be_deleted_user = FactoryGirl.create(:locked_user)
to_be_deleted_user.password = 'pwd123'
to_be_deleted_user.password_confirmation = 'pwd123'
to_be_deleted_user.save
login(to_be_deleted_user)
delete api_v3_users_delete_me_url, deletion_password_confirmation: 'pwd123'
expect(User.find(id: to_be_deleted_user.id)).to be_nil
end
end
context 'maintenance mode' do
shared_examples "maintenance mode" do
it 'redirects to maintenance_mode for admin endpoints' do
@admin_endpoints.each do |endpoint|
login(@maintenance_mode_user)
endpoint = "/user/#{@maintenance_mode_user.username}/#{endpoint}" unless host.include?(@maintenance_mode_user.username)
get endpoint, {}, @headers
response.status.should == 302
follow_redirects
request.path.should include '/maintenance_mode'
response.status.should == 200
end
end
it 'returns 403 for private api endpoints' do
@private_api_endpoints.each do |endpoint|
login(@maintenance_mode_user)
endpoint = "/user/#{@maintenance_mode_user.username}/#{endpoint}" unless host.include?(@maintenance_mode_user.username)
get "#{endpoint}?api_key=#{@maintenance_mode_user.api_key}", {}, @api_headers
response.status.should == 403
end
end
it 'returns 403 for public api viz endpoints' do
@public_api_viz_endpoints.each do |endpoint|
login(@maintenance_mode_user)
endpoint = "/user/#{@maintenance_mode_user.username}/#{endpoint}" unless host.include?(@maintenance_mode_user.username)
get endpoint, {}, @api_headers
response.status.should == 403
end
end
end
context 'with subdomainless' do
before(:each) do
stub_subdomainless
end
context 'organizational user' do
before(:each) do
@maintenance_mode_user.organization = @organization
@maintenance_mode_user.account_type = @org_account_type
@maintenance_mode_user.save
end
after(:each) do
@maintenance_mode_user.organization = nil
@maintenance_mode_user.account_type = 'FREE'
@maintenance_mode_user.save
end
it_behaves_like 'maintenance mode'
end
context 'regular user' do
it_behaves_like 'maintenance mode'
end
end
context 'with domainful' do
context 'organizational user' do
before(:each) do
stub_domainful(@organization.name)
end
before(:each) do
@maintenance_mode_user.organization = @organization
@maintenance_mode_user.account_type = @org_account_type
@maintenance_mode_user.save
end
after(:each) do
@maintenance_mode_user.organization = nil
@maintenance_mode_user.account_type = 'FREE'
@maintenance_mode_user.save
end
it_behaves_like 'maintenance mode'
end
context 'regular user' do
before(:each) do
stub_domainful(@maintenance_mode_user.username)
end
it_behaves_like 'maintenance mode'
it 'returns 403 for public api me endpoint' do
@public_api_me_endpoint.each do |endpoint|
login(@maintenance_mode_user)
get endpoint, {}, @api_headers
request.path.should == endpoint
response.status.should == 403
end
end
it 'user accessing a maintenance mode user resources' do
login(@non_locked_user)
host! "#{@maintenance_mode_user.username}.localhost.lan"
@user_endpoints.each do |endpoint|
get endpoint, {}, @headers
response.status.should == 404
end
@public_user_endpoints.each do |endpoint|
get endpoint, {}, @headers
response.status.should == 404
end
@tables_endpoints.each do |endpoint|
get endpoint, {}, @headers
response.status.should == 404
end
@viz_endpoints.each do |endpoint|
get endpoint, {}, @headers
response.status.should == 404
end
@public_api_endpoints.each do |endpoint|
get endpoint, {}, @api_headers
request.path.should == endpoint
response.status.should == 404
end
end
it 'non-logged user accessing a maintenance mode user resources' do
host! "#{@maintenance_mode_user.username}.localhost.lan"
@public_user_endpoints.each do |endpoint|
get endpoint, {}, @headers
response.status.should == 404
end
@tables_endpoints.each do |endpoint|
get endpoint, {}, @headers
response.status.should == 404
end
@viz_endpoints.each do |endpoint|
get endpoint, {}, @headers
response.status.should == 404
end
@public_api_endpoints.each do |endpoint|
get endpoint, {}, @api_headers
request.path.should == endpoint
response.status.should == 404
end
end
end
end
it 'maintenance mode user cannot delete their own account' do
to_be_deleted_user = FactoryGirl.create(:valid_user, maintenance_mode: true)
to_be_deleted_user.password = 'pwd123'
to_be_deleted_user.password_confirmation = 'pwd123'
to_be_deleted_user.save
login(to_be_deleted_user)
delete api_v3_users_delete_me_url, deletion_password_confirmation: 'pwd123'
expect(User.find(id: to_be_deleted_user.id)).to_not be_nil
end
end
context 'active state' do
before(:each) do
@locked_user.state = 'active'
@locked_user.save
end
after(:each) do
@locked_user.state = 'locked'
@locked_user.save
end
it 'lets the owner access their resources' do
# we use this to avoid generating the static assets in CI
Admin::UsersController.any_instance.stubs(:render)
Admin::VisualizationsController.any_instance.stubs(:render)
login(@locked_user)
host! "#{@locked_user.username}.localhost.lan"
@dashboard_endpoints.each do |endpoint|
get endpoint, {}, @headers
follow_redirects
request.path.should_not == '/lockout'
response.status.should == 200
end
@user_endpoints.each do |endpoint|
get endpoint, {}, @headers
follow_redirects
request.path.should_not == '/lockout'
response.status.should == 200
end
@public_user_endpoints.each do |endpoint|
get endpoint, {}, @headers
follow_redirects
request.path.should_not == '/lockout'
response.status.should == 200
end
@tables_endpoints.each do |endpoint|
get endpoint, {}, @headers
follow_redirects
request.path.should_not == '/lockout'
response.status.should == 200
end
@viz_endpoints.each do |endpoint|
get endpoint, {}, @headers
follow_redirects
request.path.should_not == '/lockout'
response.status.should == 200
end
@private_api_endpoints.each do |endpoint|
get "#{endpoint}?api_key=#{@locked_user.api_key}", {}, @api_headers
request.path.should == endpoint
response.status.should == 200
end
@public_api_endpoints.each do |endpoint|
get endpoint, {}, @api_headers
request.path.should == endpoint
response.status.should == 200
end
end
it 'lets a non locked user access resources from an active user' do
# we use this to avoid generating the static assets in CI
Admin::VisualizationsController.any_instance.stubs(:render)
login(@non_locked_user)
@user_endpoints.each do |endpoint|
host! "#{@locked_user.username}.localhost.lan"
get endpoint, {}, @headers
follow_redirects
response.status.should == 200
end
@public_user_endpoints.each do |endpoint|
host! "#{@locked_user.username}.localhost.lan"
get endpoint, {}, @headers
follow_redirects
response.status.should == 200
end
@tables_endpoints.each do |endpoint|
host! "#{@locked_user.username}.localhost.lan"
get endpoint, {}, @headers
follow_redirects
response.status.should == 200
end
@viz_endpoints.each do |endpoint|
host! "#{@locked_user.username}.localhost.lan"
get endpoint, {}, @headers
follow_redirects
response.status.should == 200
end
@public_api_endpoints.each do |endpoint|
get endpoint, {}, @api_headers
request.path.should == endpoint
response.status.should == 200
end
end
it 'lets unauthenticated users access resources from an active user' do
host! "#{@locked_user.username}.localhost.lan"
@public_user_endpoints.each do |endpoint|
get endpoint, {}, @headers
follow_redirects
response.status.should == 200
end
@tables_endpoints.each do |endpoint|
get endpoint, {}, @headers
follow_redirects
response.status.should == 200
end
@viz_endpoints.each do |endpoint|
get endpoint, {}, @headers
follow_redirects
response.status.should == 200
end
@public_api_endpoints.each do |endpoint|
get endpoint, {}, @api_headers
request.path.should == endpoint
response.status.should == 200
end
end
end
end