-
Notifications
You must be signed in to change notification settings - Fork 50
[MIG] T3173: Bring back external translation platform client #2096
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 18.0
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,6 @@ | ||
| ############################################################################## | ||
| # | ||
| # Copyright (C) 2023 Compassion CH (http://www.compassion.ch) | ||
| # Copyright (C) 2023-2026 Compassion CH (http://www.compassion.ch) | ||
| # Releasing children from poverty in Jesus' name | ||
| # | ||
| # The licence is in the file __manifest__.py | ||
|
|
@@ -11,75 +11,31 @@ | |
| from werkzeug.utils import redirect | ||
|
|
||
| from odoo import http | ||
| from odoo.http import request | ||
|
|
||
| from odoo.addons.portal.controllers.portal import CustomerPortal | ||
| from odoo.tools import file_open | ||
|
|
||
| _logger = logging.getLogger(__name__) | ||
|
|
||
|
|
||
| class TranslationPlatformController(CustomerPortal): | ||
| @http.route( | ||
| "/my/translation-platform", | ||
| type="http", | ||
| auth="user", | ||
| website=True, | ||
| ) | ||
| def translation_platform_portal(self, **kwargs): | ||
| """ | ||
| Portal page for the Translation Platform OWL app. | ||
| Only accessible to authenticated users who belong to the | ||
| sbc_translation.group_user group. | ||
| """ | ||
| if not request.env.user.has_group("sbc_translation.group_user"): | ||
| return redirect("/my") | ||
| return request.render("sbc_translation.portal_translation_platform", {}) | ||
|
|
||
| class TranslationPlatformController(http.Controller): | ||
| @http.route( | ||
| ["/translation-platform", "/translation-platform/<path:page>"], | ||
| type="http", | ||
| auth="user", | ||
| website=True, | ||
| auth="public", | ||
| ) | ||
| def translation_platform_legacy(self, page="", **kwargs): | ||
| def translation_platform(self, page=""): | ||
|
NoeBerdoz marked this conversation as resolved.
|
||
| """Serve the built translation-platform-web SPA from | ||
| `static/tp/`. | ||
|
|
||
| `static/tp/` is the destination for the `npm run build` | ||
| output of the external translation-platform-web repo: copy | ||
| the `dist/` folder there at release time. The webapp itself | ||
| does client-side routing; this controller only serves | ||
| `index.html` for app routes and redirects asset URLs into | ||
| `/sbc_translation/static/tp/...`. | ||
| """ | ||
| Legacy route: redirect old standalone-app URLs to the new portal page. | ||
| """ | ||
| return redirect("/my/translation-platform", 301) | ||
|
|
||
| def _prepare_home_portal_values(self, counters): | ||
| values = super()._prepare_home_portal_values(counters) | ||
| if not request.env.user.has_group("sbc_translation.group_user"): | ||
| return values | ||
| partner = request.env.user.partner_id | ||
| translator = request.env["translation.user"].search( | ||
| [("partner_id", "=", partner.id)] | ||
| ) | ||
| if translator and "letters_to_translate" in counters: | ||
| if translator.translation_skills: | ||
| nb_letters = request.env["correspondence"].search_count( | ||
| [ | ||
| ("state", "=", "Global Partner translation queue"), | ||
| ("translation_status", "=", "to do"), | ||
| ("new_translator_id", "=", False), | ||
| ( | ||
| "translation_competence_id.skill_ids", | ||
| "in", | ||
| translator.translation_skills.ids, | ||
| ), | ||
| ] | ||
| ) | ||
| values["letters_to_translate"] = nb_letters | ||
| else: | ||
| values["letters_to_translate"] = 1 | ||
| if translator and "letters_in_progress" in counters: | ||
| nb_letters = request.env["correspondence"].search_count( | ||
| [ | ||
| ("state", "=", "Global Partner translation queue"), | ||
| ("translation_status", "!=", "done"), | ||
| ("new_translator_id", "=", translator.id), | ||
| ] | ||
| ) | ||
| values["letters_in_progress"] = nb_letters | ||
| values["translator"] = translator | ||
| return values | ||
| if ( | ||
| "assets" in page or page.endswith(".png") or page.endswith(".jpg") | ||
| ): | ||
| return redirect(f"/sbc_translation/static/tp/{page}") | ||
|
NoeBerdoz marked this conversation as resolved.
Comment on lines
+36
to
+39
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The condition A safer approach is to match only well-known asset extensions (and validate no |
||
| with file_open("sbc_translation/static/tp/index.html") as app: | ||
| return app.read() | ||
|
Comment on lines
+40
to
+41
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
If |
||
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The previous controller required user-level authentication and an explicit translator-group check before rendering the page. The new route sets the auth parameter to
"public", so unauthenticated visitors receive the SPA shell with no server-side gate. If the SPA handles login internally this is intentional, but it is a significant security posture change: any regression in the SPA client-side login logic would silently expose the platform to anonymous users. Consider keeping user-level auth so Odoo redirects unauthenticated visitors to the login page before serving the app shell.