Files
shcool/odoosh_connector/controllers/main.py
T
2026-09-10 19:36:08 +08:00

81 lines
3.4 KiB
Python

# -*- coding: utf-8 -*-
"""User-facing entry points.
Hard rule: the identity sent to OdooshCN always comes from request.env.user, never from a
request parameter. Otherwise a user could edit the URL and land in somebody else's
environment. No line in this file reads an identity from kw.
The access token is read on the server only (inside odoosh.client) and never reaches the
browser.
"""
import logging
from odoo import _, http
from odoo.http import request
from ..models.odoosh_client import OdooshError
_logger = logging.getLogger(__name__)
class OdooshPortal(http.Controller):
def _guard(self):
"""Whether the current user may use a lab environment."""
user = request.env.user
if not user or user._is_public():
return _("Please sign in first.")
if not user.sudo()._odoosh_in_scope():
return _("Your account is not set up for lab environments. Ask your administrator.")
return None
# ------------------------------------------------------------------ redirect entry
@http.route('/odoosh/go', type='http', auth='user', website=False)
def go(self, target='console', env=None, **kw):
"""Exchange for a passwordless URL and redirect. target=console opens the console,
target=odoo goes straight into the instance.
`env` is only an environment name, not an identity; the platform still checks that
the environment belongs to the current user."""
error = self._guard()
if error:
return request.render('odoosh_connector.entry_error', {'message': error})
uid = str(request.env.user.id) # identity comes from the session, only ever from there
try:
result = request.env['odoosh.client'].sudo().handoff(
uid, target='odoo' if target == 'odoo' else 'console', env=env)
except OdooshError as err:
_logger.warning("OdooshCN handoff failed for user#%s: %s", uid, err)
return request.render('odoosh_connector.entry_error', {
'message': _("Cannot open the lab environment: %s", err.message),
'code': err.code,
})
return request.redirect(result['url'], local=False)
# ------------------------------------------------------------------ JSON for the client action
@http.route('/odoosh/my/envs', type='json', auth='user')
def my_envs(self, **kw):
"""The current user's environments, for the board in the menu."""
error = self._guard()
if error:
return {'error': error, 'envs': []}
try:
data = request.env['odoosh.client'].sudo().list_envs(str(request.env.user.id))
except OdooshError as err:
return {'error': err.message, 'code': err.code, 'envs': []}
return {'envs': data.get('envs', []), 'username': data.get('username')}
@http.route('/odoosh/my/url', type='json', auth='user')
def my_url(self, target='console', env=None, **kw):
"""Exchange for a passwordless URL for the browser to open right away."""
error = self._guard()
if error:
return {'error': error}
try:
result = request.env['odoosh.client'].sudo().handoff(
str(request.env.user.id), target='odoo' if target == 'odoo' else 'console', env=env)
except OdooshError as err:
return {'error': err.message, 'code': err.code}
return {'url': result['url'], 'expires_in': result.get('expires_in')}