[FIX] payment_stripe: turn credentials helper methods into functions

This commit removes the access to stripe credentials through model
helper methods.

closes odoo/odoo#87972

X-original-commit: 61faa2b32880d60c8cfb7c7761cd313383c26a0b
Signed-off-by: Antoine Vandevenne (anv) <anv@odoo.com>
Signed-off-by: Thibault Libioulle (tle) <tle@odoo.com>
Co-authored-by: Antoine Vandevenne (anv) <anv@odoo.com>
This commit is contained in:
Thibault Libioulle
2022-04-05 15:17:31 +02:00
co-authored by Antoine Vandevenne
parent e5f7b64258
commit 4cdc00f418
4 changed files with 70 additions and 57 deletions
+3 -1
View File
@@ -13,8 +13,10 @@ from odoo import http
from odoo.exceptions import ValidationError
from odoo.http import request
from odoo.addons.payment_stripe import utils as stripe_utils
from odoo.addons.payment_stripe.const import HANDLED_WEBHOOK_EVENTS
_logger = logging.getLogger(__name__)
@@ -142,7 +144,7 @@ class StripeController(http.Controller):
:raise: :class:`werkzeug.exceptions.Forbidden` if the timestamp is too old or if the
signatures don't match
"""
webhook_secret = tx_sudo.acquirer_id._get_stripe_webhook_secret()
webhook_secret = stripe_utils.get_webhook_secret(tx_sudo.acquirer_id)
if not webhook_secret:
_logger.warning("ignored webhook event due to undefined webhook secret")
return
@@ -4,15 +4,17 @@ import logging
import uuid
import requests
from werkzeug.urls import url_join, url_encode
from werkzeug.urls import url_encode, url_join
from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
from odoo.addons.payment_stripe import utils as stripe_utils
from odoo.addons.payment_stripe.const import API_VERSION, PROXY_URL, HANDLED_WEBHOOK_EVENTS
from odoo.addons.payment_stripe.controllers.onboarding import OnboardingController
from odoo.addons.payment_stripe.controllers.main import StripeController
_logger = logging.getLogger(__name__)
@@ -39,12 +41,12 @@ class PaymentAcquirer(models.Model):
""" Check that the acquirer of a connected account can never been set to 'test'.
This constraint is defined in the present module to allow the export of the translation
string of the `ValidationError` that can be raised by the internal module responsible for
Stripe Connect, although this constraint depends on a field that is defined in that external
module.
Additionally, having the field defined in the external module prevents from using it
as a trigger for this constraint. This is however not a problem because the field `state` is
used as trigger, and we always write on `state` when we write on the internal field.
string of the `ValidationError` should it be raised by modules that would fully implement
Stripe Connect.
Additionally, the field `state` is used as a trigger for this constraint to allow those
modules to indirectly trigger it when writing on custom fields. Indeed, by always writing on
`state` together with writing on those custom fields, the constraint would be triggered.
:return: None
"""
@@ -58,7 +60,7 @@ class PaymentAcquirer(models.Model):
def _stripe_has_connected_account(self):
""" Return whether the acquirer is linked to a connected Stripe account.
Note: This method is overridden by the internal module responsible for Stripe Connect.
Note: This method serves as a hook for modules that would fully implement Stripe Connect.
Note: self.ensure_one()
:return: Whether the acquirer is linked to a connected Stripe account
@@ -77,7 +79,7 @@ class PaymentAcquirer(models.Model):
the URL the user is redirected to when coming back on Odoo after the onboarding. If the link
generation failed, redirect the user to the acquirer form.
Note: This method is overridden by the internal module responsible for Stripe Connect.
Note: This method serves as a hook for modules that would fully implement Stripe Connect.
Note: self.ensure_one()
:param int menu_id: The menu from which the user started the onboarding step, as an
@@ -173,7 +175,11 @@ class PaymentAcquirer(models.Model):
self.ensure_one()
url = url_join('https://api.stripe.com/v1/', endpoint)
headers = self._get_stripe_request_headers(endpoint)
headers = {
'AUTHORIZATION': f'Bearer {stripe_utils.get_secret_key(self)}',
'Stripe-Version': API_VERSION, # SetupIntent requires a specific version.
**self._get_stripe_extra_request_headers(),
}
try:
response = requests.request(method, url, data=payload, headers=headers, timeout=60)
# Stripe can send 4XX errors for payment failures (not only for badly-formed requests).
@@ -200,19 +206,15 @@ class PaymentAcquirer(models.Model):
raise ValidationError("Stripe: " + _("Could not establish the connection to the API."))
return response.json()
def _get_stripe_request_headers(self, endpoint):
""" Return the headers for the Stripe API request.
def _get_stripe_extra_request_headers(self):
""" Return the extra headers for the Stripe API request.
Note: This method is overridden by the internal module responsible for Stripe Connect.
Note: This method serves as a hook for modules that would fully implement Stripe Connect.
:param str endpoint: The Stripe endpoint that will be called
:returns: The request headers
:return: The extra request headers.
:rtype: dict
"""
return {
'AUTHORIZATION': f'Bearer {self._get_stripe_secret_key()}',
'Stripe-Version': API_VERSION, # SetupIntent needs a specific version
}
return {}
def _get_default_payment_method_id(self):
self.ensure_one()
@@ -228,44 +230,12 @@ class PaymentAcquirer(models.Model):
'stripe_webhook_secret',
])
# === BUSINESS METHODS - STRIPE CONNECT CREDENTIALS === #
def _get_stripe_publishable_key(self):
""" Return the publishable key for Stripe.
Note: This method is overridden by the internal module responsible for Stripe Connect.
:return: The publishable key
:rtype: str
"""
return self.stripe_publishable_key
def _get_stripe_secret_key(self):
""" Return the secret key for Stripe.
Note: This method is overridden by the internal module responsible for Stripe Connect.
:return: The secret key
:rtype: str
"""
return self.stripe_secret_key
def _get_stripe_webhook_secret(self):
""" Return the webhook secret for Stripe.
Note: This method is overridden by the internal module responsible for Stripe Connect.
:returns: The webhook secret
:rtype: str
"""
return self.stripe_webhook_secret
# === BUSINESS METHODS - STRIPE CONNECT ONBOARDING === #
def _stripe_fetch_or_create_connected_account(self):
""" Fetch the connected Stripe account and create one if not already done.
Note: This method is overridden by the internal module responsible for Stripe Connect.
Note: This method serves as a hook for modules that would fully implement Stripe Connect.
:return: The connected account
:rtype: dict
@@ -277,7 +247,7 @@ class PaymentAcquirer(models.Model):
def _stripe_prepare_connect_account_payload(self):
""" Prepare the payload for the creation of a connected account in Stripe format.
Note: This method is overridden by the internal module responsible for Stripe Connect.
Note: This method serves as a hook for modules that would fully implement Stripe Connect.
Note: self.ensure_one()
:return: The Stripe-formatted payload for the creation request
@@ -9,9 +9,11 @@ from odoo import _, fields, models
from odoo.exceptions import UserError, ValidationError
from odoo.addons.payment import utils as payment_utils
from odoo.addons.payment_stripe import utils as stripe_utils
from odoo.addons.payment_stripe.const import INTENT_STATUS_MAPPING, PAYMENT_METHOD_TYPES
from odoo.addons.payment_stripe.controllers.main import StripeController
_logger = logging.getLogger(__name__)
@@ -35,7 +37,7 @@ class PaymentTransaction(models.Model):
checkout_session = self._stripe_create_checkout_session()
return {
'publishable_key': self.acquirer_id._get_stripe_publishable_key(),
'publishable_key': stripe_utils.get_publishable_key(self.acquirer_id),
'session_id': checkout_session['id'],
}
@@ -147,7 +149,7 @@ class PaymentTransaction(models.Model):
def _get_common_stripe_session_values(self, pmt_values, customer):
""" Return the Stripe Session values that are common to redirection and validation.
Note: This method is overridden by the internal module responsible for Stripe Connect.
Note: This method serves as a hook for modules that would fully implement Stripe Connect.
:param dict pmt_values: The payment method types values
:param dict customer: The Stripe customer to assign to the session
@@ -278,7 +280,7 @@ class PaymentTransaction(models.Model):
def _stripe_prepare_payment_intent_payload(self):
""" Prepare the payload for the creation of a payment intent in Stripe format.
Note: This method is overridden by the internal module responsible for Stripe Connect.
Note: This method serves as a hook for modules that would fully implement Stripe Connect.
Note: self.ensure_one()
:return: The Stripe-formatted payload for the payment intent request
+39
View File
@@ -0,0 +1,39 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
def get_publishable_key(acquirer_sudo):
""" Return the publishable key for Stripe.
Note: This method serves as a hook for modules that would fully implement Stripe Connect.
:param recordset acquirer_sudo: The acquirer on which the key should be read, as a sudoed
`payment.acquire` record.
:return: The publishable key
:rtype: str
"""
return acquirer_sudo.stripe_publishable_key
def get_secret_key(acquirer_sudo):
""" Return the secret key for Stripe.
Note: This method serves as a hook for modules that would fully implement Stripe Connect.
:param recordset acquirer_sudo: The acquirer on which the key should be read, as a sudoed
`payment.acquire` record.
:return: The secret key
:rtype: str
"""
return acquirer_sudo.stripe_secret_key
def get_webhook_secret(acquirer_sudo):
""" Return the webhook secret for Stripe.
Note: This method serves as a hook for modules that would fully implement Stripe Connect.
:param recordset acquirer_sudo: The acquirer on which the key should be read, as a sudoed
`payment.acquire` record.
:returns: The webhook secret
:rtype: str
"""
return acquirer_sudo.stripe_webhook_secret