fix(billing): reconciliation review fixes — per-subscription key, IDOR guard
- CRITICAL: reconciliation upsert keyed on (service, partner, period) collided when one customer has two deployments (two subs) in a period — the second overwrote the first. Add external_subscription_id to the model + a UNIQUE(service_id, external_subscription_id, period) constraint, and key the upsert per subscription. New test proves two subs for one partner keep two rows. - raise a clear error if the nexacloud service is missing (was a confusing per-row failure). - _fc_resolve_subscription: the integer fallback no longer reaches a different service's tagged subscription (latent multi-service IDOR); live untagged subs stay resolvable and the partner-link authz is unchanged. Full suite green on odoo-trial.
This commit is contained in:
@@ -126,9 +126,16 @@ class FusionBillingService(models.Model):
|
||||
if sub:
|
||||
return sub
|
||||
try:
|
||||
return SaleOrder.browse(int(external_ref))
|
||||
candidate = SaleOrder.browse(int(external_ref))
|
||||
except (TypeError, ValueError):
|
||||
return SaleOrder
|
||||
# Don't let the integer fallback reach a DIFFERENT service's tagged subscription.
|
||||
# (Live, API-created subs carry no service tag and stay resolvable here; the caller
|
||||
# still enforces partner-is-linked-to-this-service authorization.)
|
||||
if candidate.exists() and candidate.x_fc_billing_service_id \
|
||||
and candidate.x_fc_billing_service_id != self:
|
||||
return SaleOrder
|
||||
return candidate
|
||||
|
||||
def _api_record_usage(self, payload):
|
||||
"""Ingest a batch of usage events.
|
||||
|
||||
Reference in New Issue
Block a user