Skip to content

Commit

Permalink
Fix ZypperAuth check for paid products
Browse files Browse the repository at this point in the history
if system is either hybrid or byos, we need to check
the paid extensions

if the system is byos, we need to check any extension
  • Loading branch information
jesusbv committed Jan 14, 2025
1 parent a67e8e8 commit 108e63e
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 50 deletions.
75 changes: 32 additions & 43 deletions engines/scc_proxy/lib/scc_proxy/engine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -210,25 +210,19 @@ def product_path_access(x_original_uri, products_ids)
end

def product_class_access(scc_systems_activations, product)
active_products_names = scc_systems_activations.map { |act| act['service']['product']['product_class'] if act['status'].casecmp('active').zero? }.flatten
if active_products_names.include?(product)
{ is_active: true }
else
expired_products_names = scc_systems_activations.map do |act|
act['service']['product']['product_class'] unless act['status'].casecmp('active').zero?
end.flatten
message = if expired_products_names.all?(&:nil?)
'Product not activated.'
elsif expired_products_names.include?(product)
'Subscription expired.'
else
'Unexpected error when checking product subscription.'
end
{ is_active: false, message: message }
end
expired_products_names = scc_systems_activations.map do |act|
act['service']['product']['product_class'] unless act['status'].casecmp('active').zero?
end.flatten
message = if expired_products_names.all?(&:nil?)
'Product not activated.'
elsif expired_products_names.include?(product)
'Subscription expired.'
else
'Unexpected error when checking product subscription.'
end
{ is_active: false, message: message }
end

# rubocop:disable Metrics/PerceivedComplexity
def activations_fail_state(scc_systems_activations, headers, product = nil)
return SccProxy.product_class_access(scc_systems_activations, product) unless product.nil?

Expand All @@ -239,40 +233,35 @@ def activations_fail_state(scc_systems_activations, headers, product = nil)
# in any case, verification is true if ALL activations are ACTIVE
return { is_active: (scc_systems_activations.length == active_products_ids.length) } if x_original_uri.empty?

if SccProxy.product_path_access(x_original_uri, active_products_ids)
{ is_active: true }
# product not found in the active subscriptions, check the expired ones
expired_products_ids = scc_systems_activations.map { |act| act['service']['product']['id'] unless act['status'].casecmp('active').zero? }.flatten
if expired_products_ids.all?(&:nil?)
{
is_active: false,
message: 'Product not activated.'
}
end
if SccProxy.product_path_access(x_original_uri, expired_products_ids)
{
is_active: false,
message: 'Subscription expired.'
}
else
# product not found in the active subscriptions, check the expired ones
expired_products_ids = scc_systems_activations.map { |act| act['service']['product']['id'] unless act['status'].casecmp('active').zero? }.flatten
if expired_products_ids.all?(&:nil?)
{
is_active: false,
message: 'Product not activated.'
}
end
if SccProxy.product_path_access(x_original_uri, expired_products_ids)
{
is_active: false,
message: 'Subscription expired.'
}
else
{
is_active: false,
message: 'Unexpected error when checking product subscription.'
}
end
{
is_active: false,
message: 'Unexpected error when checking product subscription.'
}
end
end
# rubocop:enable Metrics/PerceivedComplexity

def scc_check_subscription_expiration(headers, system, product = nil)
scc_systems_activations = SccProxy.get_scc_activations(headers, system)
return { is_active: false, message: 'No activations.' } if scc_systems_activations.empty?

no_status_products_ids = scc_systems_activations.map do |act|
act['service']['product']['id'] if (act['status'].nil? && act['expires_at'].nil?)
end.flatten.compact
return { is_active: true } unless no_status_products_ids.all?(&:nil?)
status_products_classes = scc_systems_activations.select do |act|
act['service']['product']['product_class'] if act['status'].casecmp('active').zero? && act['service']['product']['product_class'] == product
end.flatten
return { is_active: true } unless status_products_classes.empty?

SccProxy.activations_fail_state(scc_systems_activations, headers, product)
rescue StandardError
Expand Down
15 changes: 8 additions & 7 deletions engines/zypper_auth/lib/zypper_auth/engine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ def auth_logger
def verify_instance(request, logger, system, params_product_id = nil)
return false unless request.headers['X-Instance-Data']

instance_data = Base64.decode64(request.headers['X-Instance-Data'].to_s)

base_product = system.products.find_by(product_type: 'base')
return false unless base_product

Expand All @@ -27,7 +25,7 @@ def verify_instance(request, logger, system, params_product_id = nil)
logger,
request,
base_product.attributes.symbolize_keys.slice(:identifier, :version, :arch, :release_type),
instance_data
Base64.decode64(request.headers['X-Instance-Data'].to_s) # instance data
)

is_valid = verification_provider.instance_valid?
Expand All @@ -37,7 +35,7 @@ def verify_instance(request, logger, system, params_product_id = nil)
InstanceVerification.update_cache(request.remote_ip, system.login, base_product.id)
is_valid
rescue InstanceVerification::Exception => e
return handle_scc_subscription(request, system, verification_provider) if system.byos?
return handle_scc_subscription(request, system, verification_provider, params_product_id) if system.byos?

ZypperAuth.zypper_auth_message(request, system, verification_provider, e.message)
false
Expand All @@ -54,19 +52,22 @@ def handle_scc_subscription(request, system, verification_provider, params_produ
if params_product_id.present?
product_class = Product.find_by(id: params_product_id).product_class
result = SccProxy.scc_check_subscription_expiration(request.headers, system, product_class)
return true if result[:is_active]
else
# no product id provided
# check all non free extensions subscriptions with SCC, if any
paid_extensions = system.products.select { |prod| prod if !prod.free && prod.product_type == 'extension' }
return true if paid_extensions.empty?
return true if paid_extensions.empty? && system.hybrid?

all_active = paid_extensions.all? do |paid_extension|
result = SccProxy.scc_check_subscription_expiration(request.headers, system, paid_extension.product_class)
result[:is_active]
end
return true if all_active

# check BYOS on SCC
result = SccProxy.scc_check_subscription_expiration(request.headers, system) if system.byos?
end
return true if result[:is_active]

ZypperAuth.zypper_auth_message(request, system, verification_provider, result[:message])
false
Expand Down Expand Up @@ -156,7 +157,7 @@ def verify_instance
def path_allowed?(headers)
return false unless original_path_allowed?(headers)

if @system.hybrid?
if @system.hybrid? || @system.byos?
paid_extensions = @system.products.select { |prod| prod if !prod.free && prod.product_type == 'extension' }
paid_extensions.each do |paid_extension|
repos_paths = paid_extension.repositories.pluck(:local_path)
Expand Down

0 comments on commit 108e63e

Please sign in to comment.