Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/models/cinstance.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ class Cinstance < Contract

self.background_deletion = %i[referrer_filters application_keys alerts]

delegate :backend_version, to: :service, allow_nil: true
delegate :backend_version, :audience_mapper_client_id, to: :service, allow_nil: true

belongs_to :plan, class_name: 'ApplicationPlan', foreign_key: :plan_id, inverse_of: :cinstances
alias application_plan plan
Expand Down
19 changes: 19 additions & 0 deletions app/models/proxy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,17 @@ def find_policy_config_by(name:, version:)
policies_config.find_by(name: name, version: version)
end

def audience_mapper_client_id
policy = find_policy_config_by(name: 'token_introspection', version: 'builtin')
return unless policy&.enabled

config = policy.configuration&.with_indifferent_access || {}
auth_type = config[:auth_type]
return unless auth_type == 'use_3scale_oidc_issuer_endpoint' || auth_type.blank?

issuer_endpoint_client_id
end

def oidc_configuration
super || build_oidc_configuration(standard_flow_enabled: true)
end
Expand Down Expand Up @@ -470,6 +481,14 @@ def proxy
self
end

private

def issuer_endpoint_client_id
URI.parse(oidc_issuer_endpoint).user
rescue URI::InvalidURIError
nil
end

protected

class PolicyConfig
Expand Down
2 changes: 1 addition & 1 deletion app/models/service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -589,7 +589,7 @@ def notify_deletion
delegate :oauth?, to: :authentication_scheme?

delegate :authentication_method, to: :proxy, prefix: true, allow_nil: true
delegate :oidc?, :pending_affecting_changes?, to: :proxy, allow_nil: true
delegate :oidc?, :pending_affecting_changes?, :audience_mapper_client_id, to: :proxy, allow_nil: true

def authentication_scheme?
backend_version.to_s.inquiry
Expand Down
5 changes: 3 additions & 2 deletions app/representers/cinstance_representer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,9 @@ module CinstanceRepresenter
oauth.property :client_secret
end

with_options(if: ->(*) { service.oidc? }, render_nil: true) do |oidc|
oidc.property :oidc_configuration, decorator: OIDCConfigurationRepresenter, wrap: false
with_options(if: ->(*) { service.oidc? }, render_nil: true) do
property :oidc_configuration, decorator: OIDCConfigurationRepresenter, wrap: false
property :audience_mapper_client_id
end

def provider_verification_key
Expand Down
64 changes: 64 additions & 0 deletions test/unit/proxy_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -843,6 +843,70 @@ class ProxyConfigAffectingChangesTest < ActiveSupport::TestCase
end
end

class AudienceMapperClientIdTest < ActiveSupport::TestCase
ISSUER_URL = 'https://introspection-client:s3cr3t@sso.example.com/auth/realms/master'.freeze
TOKEN_INTROSPECTION_POLICY = { name: 'token_introspection', version: 'builtin' }.freeze

def setup
@proxy = FactoryBot.build(:simple_proxy)
end

def proxy_with_policy(config)
Comment thread
qltysh[bot] marked this conversation as resolved.
@proxy.policies_config = [TOKEN_INTROSPECTION_POLICY.merge(configuration: config, enabled: true)]
@proxy
end

test 'returns user from oidc_issuer_endpoint when auth_type is use_3scale_oidc_issuer_endpoint' do
proxy = proxy_with_policy('auth_type' => 'use_3scale_oidc_issuer_endpoint')
proxy.oidc_issuer_endpoint = ISSUER_URL
assert_equal 'introspection-client', proxy.audience_mapper_client_id
end

test 'returns user from oidc_issuer_endpoint when auth_type is blank' do
proxy = proxy_with_policy({})
proxy.oidc_issuer_endpoint = ISSUER_URL
assert_equal 'introspection-client', proxy.audience_mapper_client_id
end

test 'returns nil when auth_type is client_id+client_secret' do
proxy = proxy_with_policy('auth_type' => 'client_id+client_secret', 'client_id' => 'my-introspection-client')
assert_nil proxy.audience_mapper_client_id
end

test 'returns nil when auth_type is client_secret_jwt' do
proxy = proxy_with_policy('auth_type' => 'client_secret_jwt', 'client_id' => 'my-introspection-client')
assert_nil proxy.audience_mapper_client_id
end

test 'returns nil when auth_type is private_key_jwt' do
proxy = proxy_with_policy('auth_type' => 'private_key_jwt', 'client_id' => 'my-introspection-client')
assert_nil proxy.audience_mapper_client_id
end

test 'returns nil when policy is disabled' do
proxy = FactoryBot.build(:simple_proxy)
proxy.policies_config = [TOKEN_INTROSPECTION_POLICY.merge(configuration: { 'auth_type' => 'use_3scale_oidc_issuer_endpoint' }, enabled: false)]
assert_nil proxy.audience_mapper_client_id
end

test 'returns nil when token introspection policy is absent' do
proxy = FactoryBot.build(:simple_proxy)
assert_nil proxy.audience_mapper_client_id
end

test 'returns nil when oidc_issuer_endpoint has no user' do
proxy = proxy_with_policy('auth_type' => 'use_3scale_oidc_issuer_endpoint')
proxy.oidc_issuer_endpoint = 'https://sso.example.com/auth/realms/master'
assert_nil proxy.audience_mapper_client_id
end

test 'returns nil when oidc_issuer_endpoint is blank' do
proxy = proxy_with_policy('auth_type' => 'use_3scale_oidc_issuer_endpoint')
proxy.oidc_issuer_endpoint = nil
assert_nil proxy.audience_mapper_client_id
end
end

class StaleObjectErrorTest < ActiveSupport::TestCase
test 'proxy does not raise stale object error on concurrent touch' do
class ProxyWithFiber < ::Proxy
Expand Down