cartodb/spec/requests/carto/api/database_groups_controller_spec.rb
2020-06-15 10:58:47 +08:00

264 lines
14 KiB
Ruby

require_relative '../../../spec_helper'
require_relative '.././../../factories/organizations_contexts'
require_relative '.././../../factories/visualization_creation_helpers'
require_relative '../../../../app/controllers/carto/api/database_groups_controller'
# cURL samples:
# - Create group: curl -v --user extension:elephant -H "Content-Type: application/json" -X POST -d '{ "name": "Group 2", "database_role": "DELETEME_FAKE_ROLE" }' http://localhost.lan:3000/api/v1/databases/cartodb_dev_user_3a03e626-c26c-4469-afea-a800fd813e1c_db/groups
# - Delete group: curl -v --user extension:elephant -H "Content-Type: application/json" -X DELETE http://localhost.lan:3000/api/v1/databases/cartodb_dev_user_3a03e626-c26c-4469-afea-a800fd813e1c_db/groups/Group%202
#
# Examples for staging: curl -v --user USER:PASS -H "Content-Type: application/json" -H "X-Forwarded-Proto: https" -X POST -d '{ "name": "MyGroup", "database_role": "DELETEME_FAKE_ROLE" }' http://haproxy.service.consul:8888/api/v1/databases/cartodb_staging_user_21a66689-0d8a-4512-b8e9-1fb8a93f2785_db/groups
# Delete: curl -v --user USER:PASS -H "Content-Type: application/json" -H "X-Forwarded-Proto: https" -X DELETE http://haproxy.service.consul:8888/api/v1/databases/cartodb_staging_user_21a66689-0d8a-4512-b8e9-1fb8a93f2785_db/groups/MyGroup
describe Carto::Api::DatabaseGroupsController do
include_context 'organization with users helper'
describe 'Groups management', :order => :defined do
it "Throws 401 error without http auth" do
post api_v1_databases_group_create_url(user_domain: @org_user_owner.username, database_name: @carto_organization.database_name), {}, http_json_headers
response.status.should == 401
end
it '#creates a new group from name and role, and initializes display_name as name' do
group_information = { name: 'org_group', database_role: 'g_org_database_group' }
post api_v1_databases_group_create_url(database_name: @carto_organization.database_name), group_information.to_json, org_metadata_api_headers
response.status.should == 200
group = Carto::Group.where(organization_id: @carto_organization.id, database_role: group_information[:database_role], name: group_information[:name], display_name: group_information[:name]).first
group.should_not be_nil
end
it '#creates return 409 if a group with that data has already been created' do
group_information = { name: 'org_group', database_role: 'g_org_database_group' }
post api_v1_databases_group_create_url(database_name: @carto_organization.database_name), group_information.to_json, org_metadata_api_headers
response.status.should == 409
end
it '#rename a new group from name and role' do
group = Carto::Group.where(organization_id: @carto_organization.id).first
group_information = { name: 'org_group_2', database_role: 'g_org_database_group_2' }
put api_v1_databases_group_update_url(database_name: group.database_name, old_name: group.name), group_information.to_json, org_metadata_api_headers
response.status.should == 200
updated_group = Carto::Group.find(group.id)
updated_group.should_not be_nil
updated_group.name.should eq group_information[:name]
updated_group.database_role.should eq group_information[:database_role]
updated_group.display_name.should eq group.display_name
end
it '#rename triggers 409 if it looks like renaming already occurred: existing new name, nonexisting old name' do
group_old_information = { name: 'org_group', database_role: 'g_org_database_group' }
group_new_information = { name: 'org_group_2', database_role: 'g_org_database_group_2' }
put api_v1_databases_group_update_url(database_name: @carto_organization.database_name, old_name: group_old_information[:name]), group_new_information.to_json, org_metadata_api_headers
response.status.should == 409
end
it '#rename triggers 500 if renaming can\'t be done and there is no previous match' do
group_old_information = { name: 'org_group', database_role: 'g_org_database_group' }
group_new_information = { name: 'org_group_2', database_role: 'g_org_database_group_WRONG' }
put api_v1_databases_group_update_url(database_name: @carto_organization.database_name, old_name: group_old_information[:name]), group_new_information.to_json, org_metadata_api_headers
response.status.should == 500
end
it '#add_users from username' do
group = Carto::Group.where(organization_id: @carto_organization.id).first
user_information = { username: @org_user_1.username }
post api_v1_databases_group_add_users_url(database_name: group.database_name, name: group.name), user_information.to_json, org_metadata_api_headers
response.status.should == 200
group.reload
group.users.collect(&:username).should include(@org_user_1.username)
end
it '#add_users returns 409 if username is already added' do
group = Carto::Group.where(organization_id: @carto_organization.id).first
user_information = { username: @org_user_1.username }
post api_v1_databases_group_add_users_url(database_name: group.database_name, name: group.name), user_information.to_json, org_metadata_api_headers
response.status.should == 409
end
it '#update_permission returns 404 for visualizations' do
v = FactoryGirl.create(:carto_visualization, user: @carto_org_user_1)
group = Carto::Group.where(organization_id: @carto_organization.id).first
permission = { 'access' => 'r' }
put api_v1_databases_group_update_permission_url(
database_name: group.database_name,
name: group.name,
username: @org_user_1.username,
table_name: v.name), permission.to_json, org_metadata_api_headers
response.status.should == 404
end
it '#update_permission granting read to a table' do
bypass_named_maps
@table_user_2 = create_table_with_options(@org_user_2)
group = Carto::Group.where(organization_id: @carto_organization.id).first
permission = { 'access' => 'r' }
put api_v1_databases_group_update_permission_url(database_name: group.database_name, name: group.name, username: @org_user_2.username, table_name: @table_user_2['name']), permission.to_json, org_metadata_api_headers
response.status.should == 200
permission = ::Visualization::Member.new(id: @table_user_2['table_visualization'][:id]).fetch.permission
permission.should_not be_nil
expected_acl = [
{
type: Permission::TYPE_GROUP,
entity: {
id: group.id,
name: group.name
},
access: Permission::ACCESS_READONLY
}
]
permission.to_poro[:acl].should == expected_acl
# URL generation for users of the granted group not table owners
user = group.users.first
user.id.should_not == @org_user_2.id
vis_id = @table_user_2['table_visualization'][:id]
# subdomain test simulation
host = "#{user.organization.name}.localhost.lan"
url = api_v1_visualizations_show_url(user_domain: user.username, id: vis_id, api_key: user.api_key).gsub('www.example.com', host)
get_json url, {}, http_json_headers do |response|
response.status.should == 200
[
"http://#{host}:#{Cartodb.config[:http_port]}/user/#{user.username}/tables/#{@org_user_2.username}.#{@table_user_2['name']}",
"http://#{host}:#{Cartodb.config[:http_port]}/u/#{user.username}/tables/#{@org_user_2.username}.#{@table_user_2['name']}",
].should include(response.body[:url])
end
end
it '#update_permission granting write to a table' do
bypass_named_maps
@table_user_1 = create_table_with_options(@org_user_1)
group = Carto::Group.where(organization_id: @carto_organization.id).first
# First read, then write, to ensure there're no duplicates
permission = { 'access' => 'r' }
put api_v1_databases_group_update_permission_url(database_name: group.database_name, name: group.name, username: @org_user_1.username, table_name: @table_user_1['name']), permission.to_json, org_metadata_api_headers
response.status.should == 200
permission = { 'access' => 'w' }
put api_v1_databases_group_update_permission_url(database_name: group.database_name, name: group.name, username: @org_user_1.username, table_name: @table_user_1['name']), permission.to_json, org_metadata_api_headers
response.status.should == 200
permission = ::Visualization::Member.new(id: @table_user_1['table_visualization'][:id]).fetch.permission
permission.should_not be_nil
expected_acl = [
{
type: Permission::TYPE_GROUP,
entity: {
id: group.id,
name: group.name
},
access: Permission::ACCESS_READWRITE
}
]
permission.to_poro[:acl].should == expected_acl
end
it '#destroy_permission to a table' do
bypass_named_maps
@table_user_1 = create_table_with_options(@org_user_1)
group = Carto::Group.where(organization_id: @carto_organization.id).first
permission = { 'access' => 'r' }
put api_v1_databases_group_update_permission_url(database_name: group.database_name, name: group.name, username: @org_user_1.username, table_name: @table_user_1['name']), permission.to_json, org_metadata_api_headers
response.status.should == 200
expected_acl = []
delete api_v1_databases_group_destroy_permission_url(database_name: group.database_name, name: group.name, username: @org_user_1.username, table_name: @table_user_1['name']), '', org_metadata_api_headers
response.status.should == 200
permission = ::Visualization::Member.new(id: @table_user_1['table_visualization'][:id]).fetch.permission
permission.to_poro[:acl].should == expected_acl
# Check it doesn't duplicate
delete api_v1_databases_group_destroy_permission_url(database_name: group.database_name, name: group.name, username: @org_user_1.username, table_name: @table_user_1['name']), '', org_metadata_api_headers
response.status.should == 404
end
it '#update_permission granting read on a table to organization, group and user do not duplicate count' do
bypass_named_maps
@table_user_2 = create_table_with_options(@org_user_2)
put api_v1_permissions_update_url(user_domain: @org_user_2.username, api_key: @org_user_2.api_key, id: @table_user_2['table_visualization'][:permission][:id]),
{ acl: [ {
type: CartoDB::Permission::TYPE_USER,
entity: { id: @org_user_1.id },
access: CartoDB::Permission::ACCESS_READONLY
}, {
type: CartoDB::Permission::TYPE_ORGANIZATION,
entity: { id: @organization.id },
access: CartoDB::Permission::ACCESS_READONLY
} ]
}.to_json, http_json_headers
response.status.should == 200
group = Carto::Group.where(organization_id: @carto_organization.id).first
permission = { 'access' => 'r' }
put api_v1_databases_group_update_permission_url(database_name: group.database_name, name: group.name, username: @org_user_2.username, table_name: @table_user_2['name']), permission.to_json, org_metadata_api_headers
response.status.should == 200
get api_v1_visualizations_index_url(user_domain: @org_user_1.username, api_key: @org_user_1.api_key,
type: CartoDB::Visualization::Member::TYPE_CANONICAL, order: 'updated_at', exclude_shared: false, shared: 'only'), http_json_headers
body = JSON.parse(response.body).symbolize_keys
body[:total_entries].should eq 1
body[:visualizations].count.should eq 1
body[:total_shared].should eq 1
end
it '#remove_users from username' do
group = Carto::Group.where(organization_id: @carto_organization.id).first
username = group.users.first.username
delete api_v1_databases_group_remove_users_url(database_name: group.database_name, name: group.name, username: username), {}, org_metadata_api_headers
response.status.should == 200
group.reload
group.users.collect(&:username).should_not include(username)
end
it '#remove_users from username throws 404 if user is not found' do
group = Carto::Group.where(organization_id: @carto_organization.id).first
username = @org_user_1.username
delete api_v1_databases_group_remove_users_url(database_name: group.database_name, name: group.name, username: username), {}, org_metadata_api_headers
response.status.should == 404
end
it '#add_users from username accepts batches' do
group = Carto::Group.where(organization_id: @carto_organization.id).first
user_information = { users: [ @org_user_1.username, @org_user_2.username ] }
post api_v1_databases_group_add_users_url(database_name: group.database_name, name: group.name), user_information.to_json, org_metadata_api_headers
response.status.should == 200
group.reload
group.users.collect(&:username).should include(@org_user_1.username)
group.users.collect(&:username).should include(@org_user_2.username)
end
it '#remove_users from username accepts batches' do
group = Carto::Group.where(organization_id: @carto_organization.id).first
usernames = group.users.collect(&:username)
delete_json api_v1_databases_group_remove_users_url(database_name: group.database_name, name: group.name), { users: usernames }, org_metadata_api_headers
response.status.should == 200
group.reload
usernames.map { |username|
group.users.collect(&:username).should_not include(username)
}
end
it '#destroy an existing group' do
group = Carto::Group.where(organization_id: @carto_organization.id).first
delete api_v1_databases_group_destroy_url(database_name: group.database_name, name: group.name), nil, org_metadata_api_headers
response.status.should == 204
Carto::Group.where(id: group.id).first.should be_nil
end
it '#destroy a nonexisting group returns 404' do
delete api_v1_databases_group_destroy_url(database_name: @carto_organization.database_name, name: 'org_group'), nil, org_metadata_api_headers
response.status.should == 404
end
end
end