Skip to content

[14.0][IMP] currency_rate_update_wise: rename from transferwise + security hardening#219

Open
klodr wants to merge 1 commit into
OCA:14.0from
klodr:14.0-imp-currency_rate_update_wise
Open

[14.0][IMP] currency_rate_update_wise: rename from transferwise + security hardening#219
klodr wants to merge 1 commit into
OCA:14.0from
klodr:14.0-imp-currency_rate_update_wise

Conversation

@klodr

@klodr klodr commented Jun 19, 2026

Copy link
Copy Markdown

currency_rate_update_wise (rename of currency_rate_update_transferwise)

TransferWise rebranded to Wise in 2021. This renames the module currency_rate_update_transferwisecurrency_rate_update_wise and the provider TransferWiseWise, with identical rate-fetching functionality.

  • New provider res_currency_rate_provider_Wise.py.
  • migrations/14.0.2.0.0/pre-migration.py migrates existing res.currency.rate.provider records (service TransferWiseWise) and the related ir.model.data, so existing configurations keep working after a plain module update.
  • Security hardening of the rate-fetch HTTP call: request timeout, query-param encoding, explicit handling of non-JSON responses, and the API key restricted to base.group_system.
  • Hermetic tests (HTTP mocked), i18n (es/fr/it) and README updated.

See the commit message for the full rationale (Wise vs ECB coverage, UUID→JWT token transition).

Migrations to 15.0–18.0 will follow in dedicated PRs.

@OCA-git-bot OCA-git-bot added mod:currency_rate_update_wise Module currency_rate_update_wise series:14.0 labels Jun 19, 2026
…urity hardening

Rename the provider after the TransferWise -> Wise rebrand (2021) and apply
security fixes from a code audit, on the module that was merged in 14.0 (OCA
PR OCA#174). Existing installations get the renamed, hardened module through a
plain module update (an OpenUpgrade pre-migration handles the rename).

Why keep and update this provider, as a worldwide complement to the ECB provider.
The ECB provider is the official European, EUR-centric daily reference; Wise is a
global rate source covering currencies and use cases ECB does not:

- Rate quality: Wise returns the interbank mid-market rate. Aligned with the ECB
  fixing on a working day, it tracks the ECB reference markedly closer than
  xe.com (mean deviation ~0.02% vs ~0.12%, closest to ECB on 25 of 29 currencies).
- Worldwide coverage: Wise quotes ~164 currencies against the ECB reference list
  of 29, including ones ECB omits (e.g. AED, COP). ECB stays the European
  reference; Wise extends accurate rates to the rest of the world.
- Stable JSON API: an authenticated REST endpoint, not HTML scraping like the
  xe.com provider (which breaks whenever the web page changes).
- Targeted requests: we fetch only the currency pairs actually configured,
  instead of downloading a whole rate table.
- History and granularity: the API serves past rates (by timestamp or date
  range) at day/hour/minute granularity, enabling backfill and corrections.

Rename:
- module currency_rate_update_transferwise -> currency_rate_update_wise
- field res.company.transferwise_api_key -> wise_api_key
- provider service value 'TransferWise' -> 'Wise' (label "Wise.com")
- API base URL api.transferwise.com -> api.wise.com (/v1/rates endpoint unchanged)
- OpenUpgrade pre-migration (update_module_names + rename_columns + UPDATE
  service) -> no data loss: token, provider records and rate history preserved

Security hardening (from audit):
- network via requests with a (10, 30)s timeout instead of urllib without any
  timeout: a cron/worker can no longer hang indefinitely on an unresponsive API
- API token restricted with groups="base.group_system" (model + settings + view)
  and shown with the password widget -> no longer readable by non-admin users
- query parameters passed through requests params= (proper encoding)
- explicit handling of non-JSON responses (UserError instead of a raw traceback)
- robust error detection: isinstance(data, dict) and data.get("error")
- ondelete fixed (key is the service value "Wise"; dropped the stray label key)
- token storage is an unlimited opaque string, so both the legacy UUID format
  and the newer JWT format Wise is migrating to are accepted without truncation
- legacy-token heads-up: Wise is migrating API access tokens from UUID to JWT,
  with production issuing JWT from the end-July-2026 transition. During the
  migration window (2026-08-01 to 2027-08-01) a warning is logged (at Odoo load
  time and on each scheduled update) when a Wise token still uses the UUID
  format, inviting regeneration in the Wise Developer Hub. No warning outside
  that window (before: UUID is the only format; after: migration is over) nor
  when no key is set. Ref:
  https://docs.wise.com/guides/developer/auth-and-security/client-credentials-token-migration
- tests made hermetic (HTTP mocked, no real network call) + error-response and
  legacy-token-warning cases

Signed-off-by: Claude Perrin <klodr@users.noreply.github.com>
@klodr

klodr commented Jun 20, 2026

Copy link
Copy Markdown
Author

@OCA/currency-maintainers when you have a moment, could you please review? This renames currency_rate_update_transferwisecurrency_rate_update_wise (TransferWise → Wise rebrand) with an OpenUpgrade pre-migration and some security hardening. CI is green except the unrelated xe test and the pre-commit/pkg_resources infra issue, both addressed in #220 and #221. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

mod:currency_rate_update_wise Module currency_rate_update_wise series:14.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants