Skip to content

Commit

Permalink
Merge pull request #3860 from akostadinov/tenant_id_restore
Browse files Browse the repository at this point in the history
tenant checker should recognize master better
  • Loading branch information
akostadinov authored Aug 2, 2024
2 parents 696c723 + b6c5483 commit be41de0
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 8 deletions.
22 changes: 17 additions & 5 deletions lib/three_scale/middleware/multitenant.rb
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,26 @@ def master?

@master ||= ::Account.unscoped.master

@is_master = session_of_master? || provider_key_of_master? || token_of_master?
end

def session_of_master?
# this is supposed to match how we get the user_session in app/lib/authenticated_system/request.rb
# on API calls cookies are not present though, so we need to use safe navigation
@user_session ||= UserSession.authenticate(@env['action_dispatch.cookies']&.signed&.public_send(:[], :user_session))
user_session ||= UserSession.authenticate(@env['action_dispatch.cookies']&.signed&.public_send(:[], :user_session))
user_session&.user&.account == @master
end

def provider_key_of_master?
param_places = %w[action_dispatch.request.query_parameters action_dispatch.request.request_parameters]
possible_keys = %w[provider_key api_key]
param_places.product(possible_keys).any? { |params, key| @env[params][key] == @master.provider_key }
end

@is_master = @user_session&.user&.account == @master ||
@env["action_dispatch.request.query_parameters"]["provider_key"] == @master.api_key ||
# must match how we check access token in app/lib/api_authentication/by_access_token.rb
@master.access_tokens.find_from_value(@env["action_dispatch.request.query_parameters"]["access_token"])
def token_of_master?
token = @env["action_dispatch.request.query_parameters"]["access_token"] ||
@env["action_dispatch.request.request_parameters"]["access_token"]
@master.access_tokens.find_from_value(token)
end
end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ def setup
end

test '#create' do
AccessToken.stubs(:random_id).returns('randomValue')

# sends activation email
ProviderUserMailer.expects(:activation).returns(mock(deliver_later: true))

Expand Down
37 changes: 36 additions & 1 deletion test/integration/multitenant_enforcement_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,16 +57,51 @@ class MultitenantEnforcementTest < ActionDispatch::IntegrationTest
AccessToken.new.value
get admin_api_service_application_plans_path(service_id: service.id, format: :json, access_token: token)
assert_response :success
put admin_api_service_application_plan_path(service_id: service.id, id: plan.id, format: :json), params: {access_token: token, description: "desc1"}
assert_response :success
end

test "multitenant account can retrieve from multiple tenants by master key" do
test "multitenant master can retrieve from multiple tenants by provider key" do
host! master_account.external_admin_domain
service = master_account.first_service!
plan = FactoryBot.create(:application_plan, issuer: service)
service.update_column(:tenant_id, @provider.tenant_id)
plan.update_column(:tenant_id, @provider.tenant_id + 1)
get admin_api_service_application_plans_path(service_id: service.id, format: :json, provider_key: master_account.provider_key)
assert_response :success
put admin_api_service_application_plan_path(service_id: service.id, id: plan.id, format: :json), params: {provider_key: master_account.provider_key, description: "desc1"}
assert_response :success
end

test "multitenant master retrieve from multiple tenants in master API by api_key in query" do
proxies = FactoryBot.create_list(:proxy, 2)
proxies.each do |proxy|
FactoryBot.create_list(:proxy_config, 1, proxy: proxy, environment: 'sandbox')
FactoryBot.create_list(:proxy_config, 1, proxy: proxy, environment: 'production')
end
proxies[1].update(tenant_id: proxies[0].reload.tenant_id + 1)

host! master_account.internal_admin_domain
get master_api_proxy_configs_path(environment: 'production', api_key: master_account.provider_key)
assert_response :success
end

test "multitenant master retrieve from multiple tenants in master API by api_key in request" do
User.any_instance.expects(:tenant_id).at_least(2).returns(@provider.reload.tenant_id)

signup_params = {
api_key: master_account.api_key,
org_name: 'Alaska',
username: 'person',
email: 'person@example.com',
password: '123456',
user_extra_field: 'hi-user',
account_extra_field: 'hi-account'
}

host! master_account.internal_admin_domain
post master_api_providers_path, params: signup_params
assert_response :created
end

test "multitenant account can retrieve from multiple tenants by user" do
Expand Down

0 comments on commit be41de0

Please sign in to comment.