Initial commit: OCA Server Auth packages (29 packages)

This commit is contained in:
Ernad Husremovic 2025-08-29 15:43:06 +02:00
commit 3ed80311c4
1325 changed files with 127292 additions and 0 deletions

View file

@ -0,0 +1,46 @@
# Cross Connect Client
Odoo addon: cross_connect_client
## Installation
```bash
pip install odoo-bringout-oca-server-auth-cross_connect_client
```
## Dependencies
This addon depends on:
- server_environment
## Manifest Information
- **Name**: Cross Connect Client
- **Version**: 16.0.1.0.0
- **Category**: Tools
- **License**: AGPL-3
- **Installable**: True
## Source
Based on [OCA/server-auth](https://github.com/OCA/server-auth) branch 16.0, addon `cross_connect_client`.
## License
This package maintains the original AGPL-3 license from the upstream Odoo project.
## Documentation
- Overview: doc/OVERVIEW.md
- Architecture: doc/ARCHITECTURE.md
- Models: doc/MODELS.md
- Controllers: doc/CONTROLLERS.md
- Wizards: doc/WIZARDS.md
- Reports: doc/REPORTS.md
- Security: doc/SECURITY.md
- Install: doc/INSTALL.md
- Usage: doc/USAGE.md
- Configuration: doc/CONFIGURATION.md
- Dependencies: doc/DEPENDENCIES.md
- Troubleshooting: doc/TROUBLESHOOTING.md
- FAQ: doc/FAQ.md

View file

@ -0,0 +1,118 @@
.. image:: https://odoo-community.org/readme-banner-image
:target: https://odoo-community.org/get-involved?utm_source=readme
:alt: Odoo Community Association
====================
Cross Connect Client
====================
..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:b0a3116c667f84d22c4fd196629c2b2e2a3d3071fef7b5af78ed46d2e872f2a0
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fserver--auth-lightgray.png?logo=github
:target: https://github.com/OCA/server-auth/tree/16.0/cross_connect_client
:alt: OCA/server-auth
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/server-auth-16-0/server-auth-16-0-cross_connect_client
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runboat.odoo-community.org/builds?repo=OCA/server-auth&target_branch=16.0
:alt: Try me on Runboat
|badge1| |badge2| |badge3| |badge4| |badge5|
This module allows this odoo instance users to connect directly on
another odoo instance where the module ``cross_connect_server`` is
installed.
**Table of contents**
.. contents::
:local:
Usage
=====
First of all after installing the module, you need to configure the
server connection.
In order to do that, you need to go to the menu
``Settings > Technical > Cross Connect > Cross Connect Servers`` and
create a new server to connect to.
Fill the fields with the server's information :
- Url: The api root path (e.g. ``https://my-remote-odoo.com/api``)
- Api Key: The api-key from the ``cross_connect_server`` configuration
Then click on the ``Sync Cross Connection`` button to check if the
connection is working and to sync the remote server's groups.
After that, you will have to affect the remote groups to the local users
in order for them to be able to connect to the remote server.
Once an user has a remote group, a new top level menu will appear in the
menu bar with the Cross Connect Server's name. Clicking on it will
redirect the user to the remote server logged in as the user.
You can change each menu icon (for use with ``web_responsive`` for
instance) by setting the ``Web Icon Data`` in the server configuration.
Bug Tracker
===========
Bugs are tracked on `GitHub Issues <https://github.com/OCA/server-auth/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/OCA/server-auth/issues/new?body=module:%20cross_connect_client%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Do not contact contributors directly about support or help with technical issues.
Credits
=======
Authors
-------
* Akretion
Contributors
------------
- Florian Mounier florian.mounier@akretion.com
Maintainers
-----------
This module is maintained by the OCA.
.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org
OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
.. |maintainer-paradoxxxzero| image:: https://github.com/paradoxxxzero.png?size=40px
:target: https://github.com/paradoxxxzero
:alt: paradoxxxzero
Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:
|maintainer-paradoxxxzero|
This module is part of the `OCA/server-auth <https://github.com/OCA/server-auth/tree/16.0/cross_connect_client>`_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

View file

@ -0,0 +1,2 @@
from . import controllers
from . import models

View file

@ -0,0 +1,22 @@
# Copyright 2024 Akretion (http://www.akretion.com).
# @author Florian Mounier <florian.mounier@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
"name": "Cross Connect Client",
"version": "16.0.1.0.0",
"author": "Akretion, Odoo Community Association (OCA)",
"summary": "Cross Connect Client allows to connect to a "
"Cross Connect Server enabled odoo instance.",
"category": "Tools",
"depends": ["server_environment"],
"website": "https://github.com/OCA/server-auth",
"data": [
"security/ir_model_access.xml",
"views/cross_connect_server_views.xml",
],
"maintainers": ["paradoxxxzero"],
"demo": [],
"installable": True,
"license": "AGPL-3",
}

View file

@ -0,0 +1 @@
from . import cross_connect

View file

@ -0,0 +1,26 @@
# Copyright 2024 Akretion (http://www.akretion.com).
# @author Florian Mounier <florian.mounier@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import _
from odoo.exceptions import UserError
from odoo.http import Controller, request, route
class CrossConnectController(Controller):
@route(
["/cross_connect_server/<int:server_id>"],
methods=["GET"],
type="http",
auth="public",
)
def cross_connect(
self,
server_id,
**params,
):
server = request.env["cross.connect.server"].sudo().browse(server_id)
if not server:
raise UserError(_("Server not found"))
url = server._get_cross_connect_url(request.params.get("redirect_url"))
return request.redirect(url, local=False)

View file

@ -0,0 +1,183 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * cross_connect_client
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: cross_connect_client
#: model:ir.model,name:cross_connect_client.model_res_groups
msgid "Access Groups"
msgstr "Pristupne grupe"
#. module: cross_connect_client
#: model:ir.model.fields,field_description:cross_connect_client.field_cross_connect_server__api_key
msgid "Api Key"
msgstr "API ključ"
#. module: cross_connect_client
#: model:ir.model.fields,field_description:cross_connect_client.field_cross_connect_server__api_key_env_default
msgid "Api Key Env Default"
msgstr "Zadana vrijednost API ključa okruženja"
#. module: cross_connect_client
#: model:ir.model.fields,field_description:cross_connect_client.field_cross_connect_server__api_key_env_is_editable
msgid "Api Key Env Is Editable"
msgstr "API ključ okruženja je uređivan"
#. module: cross_connect_client
#: model:ir.model.fields,field_description:cross_connect_client.field_cross_connect_server__create_uid
msgid "Created by"
msgstr "Kreirao"
#. module: cross_connect_client
#: model:ir.model.fields,field_description:cross_connect_client.field_cross_connect_server__create_date
msgid "Created on"
msgstr "Kreirano"
#. module: cross_connect_client
#: model:ir.ui.menu,name:cross_connect_client.menu_cross_connect_server_category
msgid "Cross Connect"
msgstr "Ukrštena konekcija"
#. module: cross_connect_client
#: model:ir.model,name:cross_connect_client.model_cross_connect_server
msgid "Cross Connect Server"
msgstr "Server ukrštene konekcije"
#. module: cross_connect_client
#: model:ir.model.constraint,message:cross_connect_client.constraint_res_groups_cross_connect_server_group_id_cross_connect_server_id_unique
msgid "Cross Connect Server Group ID must be unique per Cross Connect Server"
msgstr "ID grupe servera ukrštene konekcije mora biti jedinstven po serveru ukrštene konekcije"
#. module: cross_connect_client
#: model:ir.model.fields,field_description:cross_connect_client.field_cross_connect_server__group_ids
msgid "Cross Connect Server Groups"
msgstr "Grupe servera ukrštenih konekcija"
#. module: cross_connect_client
#: model:ir.actions.act_window,name:cross_connect_client.cross_connect_server_action
#: model:ir.ui.menu,name:cross_connect_client.menu_cross_connect_server
msgid "Cross Connect Servers"
msgstr "Serveri ukrštenih konekcija"
#. module: cross_connect_client
#: model_terms:ir.ui.view,arch_db:cross_connect_client.cross_connect_server_view_form
msgid "Disable"
msgstr "Onemogući"
#. module: cross_connect_client
#: model:ir.model.fields,field_description:cross_connect_client.field_cross_connect_server__display_name
msgid "Display Name"
msgstr "Prikazani naziv"
#. module: cross_connect_client
#: model:ir.model.fields,field_description:cross_connect_client.field_cross_connect_server__id
msgid "ID"
msgstr "ID"
#. module: cross_connect_client
#: model:ir.model.fields,field_description:cross_connect_client.field_cross_connect_server____last_update
msgid "Last Modified on"
msgstr "Zadnje mijenjano"
#. module: cross_connect_client
#: model:ir.model.fields,field_description:cross_connect_client.field_cross_connect_server__write_uid
msgid "Last Updated by"
msgstr "Zadnji ažurirao"
#. module: cross_connect_client
#: model:ir.model.fields,field_description:cross_connect_client.field_cross_connect_server__write_date
msgid "Last Updated on"
msgstr "Zadnje ažurirano"
#. module: cross_connect_client
#: model:ir.model.fields,field_description:cross_connect_client.field_cross_connect_server__menu_id
msgid "Menu"
msgstr "Meni"
#. module: cross_connect_client
#: model:ir.model.fields,help:cross_connect_client.field_cross_connect_server__menu_id
msgid "Menu to display the Cross Connect Server in the menu"
msgstr "Meni za prikaz servera ukrštene konekcije u meniju"
#. module: cross_connect_client
#. odoo-python
#: code:addons/cross_connect_client/models/cross_connect_server.py:0
#, python-format
msgid "Missing token"
msgstr "Nedostaje token"
#. module: cross_connect_client
#: model:ir.model.fields,field_description:cross_connect_client.field_cross_connect_server__name
msgid "Name"
msgstr "Naziv:"
#. module: cross_connect_client
#: model:ir.model.fields,field_description:cross_connect_client.field_res_groups__cross_connect_server_id
msgid "Originating Cross Connect Server"
msgstr "Izvorni server ukrštene konekcije"
#. module: cross_connect_client
#: model:ir.model.fields,field_description:cross_connect_client.field_res_groups__cross_connect_server_group_id
msgid "Originating Cross Connect Server Group ID"
msgstr "ID grupe izvornog servera ukrštene konekcije"
#. module: cross_connect_client
#: model:ir.model.fields,field_description:cross_connect_client.field_cross_connect_server__server_env_defaults
msgid "Server Env Defaults"
msgstr "Zadane vrijednosti serverskog okruženja"
#. module: cross_connect_client
#: model:ir.model.fields,field_description:cross_connect_client.field_cross_connect_server__server_url
msgid "Server Url"
msgstr "URL servera"
#. module: cross_connect_client
#. odoo-python
#: code:addons/cross_connect_client/controllers/cross_connect.py:0
#, python-format
msgid "Server not found"
msgstr "Server nije pronađen"
#. module: cross_connect_client
#: model_terms:ir.ui.view,arch_db:cross_connect_client.cross_connect_server_view_form
msgid "Sync Cross Connection"
msgstr "Ukrštena konekcija sinhronizacije"
#. module: cross_connect_client
#: model_terms:ir.ui.view,arch_db:cross_connect_client.cross_connect_server_view_form
msgid "Sync Required"
msgstr "Potrebna sinhronizacija"
#. module: cross_connect_client
#: model:ir.model.fields,help:cross_connect_client.field_cross_connect_server__name
msgid "This name will be used for the new created app"
msgstr "Ovaj naziv će se koristiti za novu krebranu aplikaciju"
#. module: cross_connect_client
#. odoo-python
#: code:addons/cross_connect_client/models/cross_connect_server.py:0
#, python-format
msgid "User email is required"
msgstr "E-mail korisnika je obavezan"
#. module: cross_connect_client
#: model:ir.model.fields,field_description:cross_connect_client.field_cross_connect_server__web_icon_data
msgid "Web Icon Data"
msgstr "Podaci web ikone"
#. module: cross_connect_client
#. odoo-python
#: code:addons/cross_connect_client/models/cross_connect_server.py:0
#, python-format
msgid "You are not allowed to access this server"
msgstr "Nemate dozvolu pristupa ovom serveru"

View file

@ -0,0 +1,183 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * cross_connect_client
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: cross_connect_client
#: model:ir.model,name:cross_connect_client.model_res_groups
msgid "Access Groups"
msgstr ""
#. module: cross_connect_client
#: model:ir.model.fields,field_description:cross_connect_client.field_cross_connect_server__api_key
msgid "Api Key"
msgstr ""
#. module: cross_connect_client
#: model:ir.model.fields,field_description:cross_connect_client.field_cross_connect_server__api_key_env_default
msgid "Api Key Env Default"
msgstr ""
#. module: cross_connect_client
#: model:ir.model.fields,field_description:cross_connect_client.field_cross_connect_server__api_key_env_is_editable
msgid "Api Key Env Is Editable"
msgstr ""
#. module: cross_connect_client
#: model:ir.model.fields,field_description:cross_connect_client.field_cross_connect_server__create_uid
msgid "Created by"
msgstr ""
#. module: cross_connect_client
#: model:ir.model.fields,field_description:cross_connect_client.field_cross_connect_server__create_date
msgid "Created on"
msgstr ""
#. module: cross_connect_client
#: model:ir.ui.menu,name:cross_connect_client.menu_cross_connect_server_category
msgid "Cross Connect"
msgstr ""
#. module: cross_connect_client
#: model:ir.model,name:cross_connect_client.model_cross_connect_server
msgid "Cross Connect Server"
msgstr ""
#. module: cross_connect_client
#: model:ir.model.constraint,message:cross_connect_client.constraint_res_groups_cross_connect_server_group_id_cross_connect_server_id_unique
msgid "Cross Connect Server Group ID must be unique per Cross Connect Server"
msgstr ""
#. module: cross_connect_client
#: model:ir.model.fields,field_description:cross_connect_client.field_cross_connect_server__group_ids
msgid "Cross Connect Server Groups"
msgstr ""
#. module: cross_connect_client
#: model:ir.actions.act_window,name:cross_connect_client.cross_connect_server_action
#: model:ir.ui.menu,name:cross_connect_client.menu_cross_connect_server
msgid "Cross Connect Servers"
msgstr ""
#. module: cross_connect_client
#: model_terms:ir.ui.view,arch_db:cross_connect_client.cross_connect_server_view_form
msgid "Disable"
msgstr ""
#. module: cross_connect_client
#: model:ir.model.fields,field_description:cross_connect_client.field_cross_connect_server__display_name
msgid "Display Name"
msgstr ""
#. module: cross_connect_client
#: model:ir.model.fields,field_description:cross_connect_client.field_cross_connect_server__id
msgid "ID"
msgstr ""
#. module: cross_connect_client
#: model:ir.model.fields,field_description:cross_connect_client.field_cross_connect_server____last_update
msgid "Last Modified on"
msgstr ""
#. module: cross_connect_client
#: model:ir.model.fields,field_description:cross_connect_client.field_cross_connect_server__write_uid
msgid "Last Updated by"
msgstr ""
#. module: cross_connect_client
#: model:ir.model.fields,field_description:cross_connect_client.field_cross_connect_server__write_date
msgid "Last Updated on"
msgstr ""
#. module: cross_connect_client
#: model:ir.model.fields,field_description:cross_connect_client.field_cross_connect_server__menu_id
msgid "Menu"
msgstr ""
#. module: cross_connect_client
#: model:ir.model.fields,help:cross_connect_client.field_cross_connect_server__menu_id
msgid "Menu to display the Cross Connect Server in the menu"
msgstr ""
#. module: cross_connect_client
#. odoo-python
#: code:addons/cross_connect_client/models/cross_connect_server.py:0
#, python-format
msgid "Missing token"
msgstr ""
#. module: cross_connect_client
#: model:ir.model.fields,field_description:cross_connect_client.field_cross_connect_server__name
msgid "Name"
msgstr ""
#. module: cross_connect_client
#: model:ir.model.fields,field_description:cross_connect_client.field_res_groups__cross_connect_server_id
msgid "Originating Cross Connect Server"
msgstr ""
#. module: cross_connect_client
#: model:ir.model.fields,field_description:cross_connect_client.field_res_groups__cross_connect_server_group_id
msgid "Originating Cross Connect Server Group ID"
msgstr ""
#. module: cross_connect_client
#: model:ir.model.fields,field_description:cross_connect_client.field_cross_connect_server__server_env_defaults
msgid "Server Env Defaults"
msgstr ""
#. module: cross_connect_client
#: model:ir.model.fields,field_description:cross_connect_client.field_cross_connect_server__server_url
msgid "Server Url"
msgstr ""
#. module: cross_connect_client
#. odoo-python
#: code:addons/cross_connect_client/controllers/cross_connect.py:0
#, python-format
msgid "Server not found"
msgstr ""
#. module: cross_connect_client
#: model_terms:ir.ui.view,arch_db:cross_connect_client.cross_connect_server_view_form
msgid "Sync Cross Connection"
msgstr ""
#. module: cross_connect_client
#: model_terms:ir.ui.view,arch_db:cross_connect_client.cross_connect_server_view_form
msgid "Sync Required"
msgstr ""
#. module: cross_connect_client
#: model:ir.model.fields,help:cross_connect_client.field_cross_connect_server__name
msgid "This name will be used for the new created app"
msgstr ""
#. module: cross_connect_client
#. odoo-python
#: code:addons/cross_connect_client/models/cross_connect_server.py:0
#, python-format
msgid "User email is required"
msgstr ""
#. module: cross_connect_client
#: model:ir.model.fields,field_description:cross_connect_client.field_cross_connect_server__web_icon_data
msgid "Web Icon Data"
msgstr ""
#. module: cross_connect_client
#. odoo-python
#: code:addons/cross_connect_client/models/cross_connect_server.py:0
#, python-format
msgid "You are not allowed to access this server"
msgstr ""

View file

@ -0,0 +1,187 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * cross_connect_client
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-06-16 08:26+0000\n"
"Last-Translator: mymage <stefano.consolaro@mymage.it>\n"
"Language-Team: none\n"
"Language: it\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 5.10.4\n"
#. module: cross_connect_client
#: model:ir.model,name:cross_connect_client.model_res_groups
msgid "Access Groups"
msgstr "Gruppi di accesso"
#. module: cross_connect_client
#: model:ir.model.fields,field_description:cross_connect_client.field_cross_connect_server__api_key
msgid "Api Key"
msgstr "Chiave API"
#. module: cross_connect_client
#: model:ir.model.fields,field_description:cross_connect_client.field_cross_connect_server__api_key_env_default
msgid "Api Key Env Default"
msgstr "Chiave API predefinita dell'ambiente"
#. module: cross_connect_client
#: model:ir.model.fields,field_description:cross_connect_client.field_cross_connect_server__api_key_env_is_editable
msgid "Api Key Env Is Editable"
msgstr "La chiave API ambiente è modificabile"
#. module: cross_connect_client
#: model:ir.model.fields,field_description:cross_connect_client.field_cross_connect_server__create_uid
msgid "Created by"
msgstr "Creato da"
#. module: cross_connect_client
#: model:ir.model.fields,field_description:cross_connect_client.field_cross_connect_server__create_date
msgid "Created on"
msgstr "Creato il"
#. module: cross_connect_client
#: model:ir.ui.menu,name:cross_connect_client.menu_cross_connect_server_category
msgid "Cross Connect"
msgstr "Cross connect"
#. module: cross_connect_client
#: model:ir.model,name:cross_connect_client.model_cross_connect_server
msgid "Cross Connect Server"
msgstr "Server cross connect"
#. module: cross_connect_client
#: model:ir.model.constraint,message:cross_connect_client.constraint_res_groups_cross_connect_server_group_id_cross_connect_server_id_unique
msgid "Cross Connect Server Group ID must be unique per Cross Connect Server"
msgstr ""
"L'ID gruppo server cross connect deve essere univoco per server cross connect"
#. module: cross_connect_client
#: model:ir.model.fields,field_description:cross_connect_client.field_cross_connect_server__group_ids
msgid "Cross Connect Server Groups"
msgstr "Gruppi server cross connect"
#. module: cross_connect_client
#: model:ir.actions.act_window,name:cross_connect_client.cross_connect_server_action
#: model:ir.ui.menu,name:cross_connect_client.menu_cross_connect_server
msgid "Cross Connect Servers"
msgstr "Server cross connect"
#. module: cross_connect_client
#: model_terms:ir.ui.view,arch_db:cross_connect_client.cross_connect_server_view_form
msgid "Disable"
msgstr "Disabilita"
#. module: cross_connect_client
#: model:ir.model.fields,field_description:cross_connect_client.field_cross_connect_server__display_name
msgid "Display Name"
msgstr "Nome visualizzato"
#. module: cross_connect_client
#: model:ir.model.fields,field_description:cross_connect_client.field_cross_connect_server__id
msgid "ID"
msgstr "ID"
#. module: cross_connect_client
#: model:ir.model.fields,field_description:cross_connect_client.field_cross_connect_server____last_update
msgid "Last Modified on"
msgstr "Ultima modifica il"
#. module: cross_connect_client
#: model:ir.model.fields,field_description:cross_connect_client.field_cross_connect_server__write_uid
msgid "Last Updated by"
msgstr "Ultimo aggiornamento di"
#. module: cross_connect_client
#: model:ir.model.fields,field_description:cross_connect_client.field_cross_connect_server__write_date
msgid "Last Updated on"
msgstr "Ultimo aggiornamento il"
#. module: cross_connect_client
#: model:ir.model.fields,field_description:cross_connect_client.field_cross_connect_server__menu_id
msgid "Menu"
msgstr "Menù"
#. module: cross_connect_client
#: model:ir.model.fields,help:cross_connect_client.field_cross_connect_server__menu_id
msgid "Menu to display the Cross Connect Server in the menu"
msgstr "Menu per visualizzare il server cross connect nel menu"
#. module: cross_connect_client
#. odoo-python
#: code:addons/cross_connect_client/models/cross_connect_server.py:0
#, python-format
msgid "Missing token"
msgstr "Token mancante"
#. module: cross_connect_client
#: model:ir.model.fields,field_description:cross_connect_client.field_cross_connect_server__name
msgid "Name"
msgstr "Nome"
#. module: cross_connect_client
#: model:ir.model.fields,field_description:cross_connect_client.field_res_groups__cross_connect_server_id
msgid "Originating Cross Connect Server"
msgstr "Generazione server cross connect"
#. module: cross_connect_client
#: model:ir.model.fields,field_description:cross_connect_client.field_res_groups__cross_connect_server_group_id
msgid "Originating Cross Connect Server Group ID"
msgstr "Generazione ID gruppo server cross connect"
#. module: cross_connect_client
#: model:ir.model.fields,field_description:cross_connect_client.field_cross_connect_server__server_env_defaults
msgid "Server Env Defaults"
msgstr "Predefiniti ambiente server"
#. module: cross_connect_client
#: model:ir.model.fields,field_description:cross_connect_client.field_cross_connect_server__server_url
msgid "Server Url"
msgstr "URL server"
#. module: cross_connect_client
#. odoo-python
#: code:addons/cross_connect_client/controllers/cross_connect.py:0
#, python-format
msgid "Server not found"
msgstr "Server non trovato"
#. module: cross_connect_client
#: model_terms:ir.ui.view,arch_db:cross_connect_client.cross_connect_server_view_form
msgid "Sync Cross Connection"
msgstr "Sincronizza cross connect"
#. module: cross_connect_client
#: model_terms:ir.ui.view,arch_db:cross_connect_client.cross_connect_server_view_form
msgid "Sync Required"
msgstr "Richiesta sincronizzazione"
#. module: cross_connect_client
#: model:ir.model.fields,help:cross_connect_client.field_cross_connect_server__name
msgid "This name will be used for the new created app"
msgstr "Questo nome verrà usato per la nuova app creata"
#. module: cross_connect_client
#. odoo-python
#: code:addons/cross_connect_client/models/cross_connect_server.py:0
#, python-format
msgid "User email is required"
msgstr "È richiesta l'e-mail utente"
#. module: cross_connect_client
#: model:ir.model.fields,field_description:cross_connect_client.field_cross_connect_server__web_icon_data
msgid "Web Icon Data"
msgstr "Dati icona web"
#. module: cross_connect_client
#. odoo-python
#: code:addons/cross_connect_client/models/cross_connect_server.py:0
#, python-format
msgid "You are not allowed to access this server"
msgstr "Non si è autorizzati ad accedere a questo server"

View file

@ -0,0 +1,2 @@
from . import cross_connect_server
from . import res_groups

View file

@ -0,0 +1,179 @@
# Copyright 2024 Akretion (http://www.akretion.com).
# @author Florian Mounier <florian.mounier@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import requests
from odoo import _, api, fields, models
from odoo.exceptions import UserError
class CrossConnectServer(models.Model):
_name = "cross.connect.server"
_description = "Cross Connect Server"
_inherit = "server.env.mixin"
name = fields.Char(
required=True,
help="This name will be used for the new created app",
)
server_url = fields.Char(required=True)
api_key = fields.Char(
required=True,
)
group_ids = fields.One2many(
"res.groups",
inverse_name="cross_connect_server_id",
string="Cross Connect Server Groups",
readonly=True,
)
menu_id = fields.Many2one(
"ir.ui.menu",
string="Menu",
help="Menu to display the Cross Connect Server in the menu",
compute="_compute_menu_id",
store=True,
)
web_icon_data = fields.Binary(
compute="_compute_web_icon_data", inverse="_inverse_web_icon_data"
)
@api.depends("name", "group_ids")
def _compute_menu_id(self):
for record in self:
if not record.group_ids:
if record.menu_id:
if record.menu_id.action:
record.menu_id.action.unlink()
record.menu_id.unlink()
record.menu_id = False
continue
menu_groups = record.group_ids
if not record.menu_id:
action = self.env["ir.actions.act_url"].create(
{
"name": record.name,
"url": f"/cross_connect_server/{record.id}",
"target": "new",
}
)
record.menu_id = self.env["ir.ui.menu"].create(
{
"name": record.name,
"action": f"ir.actions.act_url,{action.id}", # noqa
"web_icon": "cross_connect_client,static/description/web_icon_data.png",
"groups_id": [(6, 0, menu_groups.ids)],
"sequence": 100,
}
)
else:
record.menu_id.name = record.name
record.menu_id.groups_id = [(6, 0, menu_groups.ids)]
@api.depends("menu_id")
def _compute_web_icon_data(self):
for record in self:
record.web_icon_data = record.menu_id.web_icon_data
def _inverse_web_icon_data(self):
for record in self:
record.menu_id.web_icon_data = record.web_icon_data
def _absolute_url_for(self, path):
return f"{self.server_url.rstrip('/')}/cross_connect/{path.lstrip('/')}"
def _request(self, method, url, headers=None, data=None):
headers = headers or {}
headers["api-key"] = self.api_key
response = requests.request(
method,
self._absolute_url_for(url),
headers=headers,
json=data,
timeout=10,
)
response.raise_for_status()
return response.json()
def _get_cross_connect_url(self, redirect_url=None):
self.ensure_one()
groups = self.env.user.groups_id & self.group_ids
if not groups:
raise UserError(_("You are not allowed to access this server"))
if not self.env.user.email:
raise UserError(_("User email is required"))
data = {
"id": self.env.user.id,
"name": self.env.user.name,
"login": self.env.user.login,
"email": self.env.user.email,
"lang": self.env.user.lang,
"groups": [group.cross_connect_server_group_id for group in groups],
}
if redirect_url:
data["redirect_url"] = redirect_url
response = self._request("POST", "/access", data=data)
client_id = response.get("client_id")
token = response.get("token")
if not token:
raise UserError(_("Missing token"))
return self._absolute_url_for(f"login/{client_id}/{token}")
def _sync_groups(self):
self.ensure_one()
response = self._request("GET", "/sync")
remote_groups = response.get("groups", [])
# Removing groups that are not on the remote server
remote_groups_ids = {remote_group["id"] for remote_group in remote_groups}
self.group_ids.filtered(
lambda group: group.cross_connect_server_group_id not in remote_groups_ids
).write({"cross_connect_server_id": False})
# Create or Update existing groups
for remote_group in remote_groups:
existing_group = self.env["res.groups"].search(
[("cross_connect_server_group_id", "=", remote_group["id"])]
)
if existing_group and not existing_group.cross_connect_server_id:
existing_group.write({"cross_connect_server_id": self.id})
if existing_group:
existing_group.sudo().write(
{
"name": f"{self.name}: {remote_group['name']}",
"comment": remote_group["comment"],
}
)
else:
self.env["res.groups"].sudo().create(
{
"cross_connect_server_id": self.id,
"cross_connect_server_group_id": remote_group["id"],
"name": f"{self.name}: {remote_group['name']}",
"comment": remote_group["comment"],
}
)
def action_sync(self):
for record in self:
record._sync_groups()
def action_disable(self):
for record in self:
record.group_ids.write({"cross_connect_server_id": False})
@property
def _server_env_fields(self):
return {"api_key": {}}
def unlink(self):
for rec in self:
# deleting the groups will delete the menu and related action.
rec.group_ids.unlink()
return super().unlink()

View file

@ -0,0 +1,24 @@
# Copyright 2024 Akretion (http://www.akretion.com).
# @author Florian Mounier <florian.mounier@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import fields, models
class ResGroups(models.Model):
_inherit = "res.groups"
cross_connect_server_id = fields.Many2one(
"cross.connect.server", string="Originating Cross Connect Server"
)
cross_connect_server_group_id = fields.Integer(
string="Originating Cross Connect Server Group ID"
)
_sql_constraints = [
(
"cross_connect_server_group_id_cross_connect_server_id_unique",
"unique (cross_connect_server_group_id, cross_connect_server_id)",
"Cross Connect Server Group ID must be unique per Cross Connect Server",
)
]

View file

@ -0,0 +1 @@
- Florian Mounier <florian.mounier@akretion.com>

View file

@ -0,0 +1,2 @@
This module allows this odoo instance users to connect directly on another odoo instance
where the module `cross_connect_server` is installed.

View file

@ -0,0 +1,23 @@
First of all after installing the module, you need to configure the server connection.
In order to do that, you need to go to the menu
`Settings > Technical > Cross Connect > Cross Connect Servers` and create a new server
to connect to.
Fill the fields with the server's information :
- Url: The api root path (e.g. `https://my-remote-odoo.com/api`)
- Api Key: The api-key from the `cross_connect_server` configuration
Then click on the `Sync Cross Connection` button to check if the connection is working
and to sync the remote server's groups.
After that, you will have to affect the remote groups to the local users in order for
them to be able to connect to the remote server.
Once an user has a remote group, a new top level menu will appear in the menu bar with
the Cross Connect Server's name. Clicking on it will redirect the user to the remote
server logged in as the user.
You can change each menu icon (for use with `web_responsive` for instance) by setting
the `Web Icon Data` in the server configuration.

View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8" ?>
<!--
Copyright 2024 Akretion (http://www.akretion.com).
@author Florian Mounier <florian.mounier@akretion.com>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-->
<odoo>
<record id="access_cross_connect_server_manager" model="ir.model.access">
<field name="name">Cross Connect Server: Manager RW access</field>
<field name="model_id" ref="model_cross_connect_server" />
<field name="group_id" ref="base.group_system" />
<field name="perm_read" eval="True" />
<field name="perm_write" eval="True" />
<field name="perm_create" eval="True" />
<field name="perm_unlink" eval="True" />
</record>
</odoo>

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View file

@ -0,0 +1,456 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils: https://docutils.sourceforge.io/" />
<title>README.rst</title>
<style type="text/css">
/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $
:Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
Despite the name, some widely supported CSS2 features are used.
See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
customize this style sheet.
*/
/* used to remove borders from tables and images */
.borderless, table.borderless td, table.borderless th {
border: 0 }
table.borderless td, table.borderless th {
/* Override padding for "table.docutils td" with "! important".
The right padding separates the table cells. */
padding: 0 0.5em 0 0 ! important }
.first {
/* Override more specific margin styles with "! important". */
margin-top: 0 ! important }
.last, .with-subtitle {
margin-bottom: 0 ! important }
.hidden {
display: none }
.subscript {
vertical-align: sub;
font-size: smaller }
.superscript {
vertical-align: super;
font-size: smaller }
a.toc-backref {
text-decoration: none ;
color: black }
blockquote.epigraph {
margin: 2em 5em ; }
dl.docutils dd {
margin-bottom: 0.5em }
object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
overflow: hidden;
}
/* Uncomment (and remove this text!) to get bold-faced definition list terms
dl.docutils dt {
font-weight: bold }
*/
div.abstract {
margin: 2em 5em }
div.abstract p.topic-title {
font-weight: bold ;
text-align: center }
div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
margin: 2em ;
border: medium outset ;
padding: 1em }
div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
font-weight: bold ;
font-family: sans-serif }
div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title, .code .error {
color: red ;
font-weight: bold ;
font-family: sans-serif }
/* Uncomment (and remove this text!) to get reduced vertical space in
compound paragraphs.
div.compound .compound-first, div.compound .compound-middle {
margin-bottom: 0.5em }
div.compound .compound-last, div.compound .compound-middle {
margin-top: 0.5em }
*/
div.dedication {
margin: 2em 5em ;
text-align: center ;
font-style: italic }
div.dedication p.topic-title {
font-weight: bold ;
font-style: normal }
div.figure {
margin-left: 2em ;
margin-right: 2em }
div.footer, div.header {
clear: both;
font-size: smaller }
div.line-block {
display: block ;
margin-top: 1em ;
margin-bottom: 1em }
div.line-block div.line-block {
margin-top: 0 ;
margin-bottom: 0 ;
margin-left: 1.5em }
div.sidebar {
margin: 0 0 0.5em 1em ;
border: medium outset ;
padding: 1em ;
background-color: #ffffee ;
width: 40% ;
float: right ;
clear: right }
div.sidebar p.rubric {
font-family: sans-serif ;
font-size: medium }
div.system-messages {
margin: 5em }
div.system-messages h1 {
color: red }
div.system-message {
border: medium outset ;
padding: 1em }
div.system-message p.system-message-title {
color: red ;
font-weight: bold }
div.topic {
margin: 2em }
h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
margin-top: 0.4em }
h1.title {
text-align: center }
h2.subtitle {
text-align: center }
hr.docutils {
width: 75% }
img.align-left, .figure.align-left, object.align-left, table.align-left {
clear: left ;
float: left ;
margin-right: 1em }
img.align-right, .figure.align-right, object.align-right, table.align-right {
clear: right ;
float: right ;
margin-left: 1em }
img.align-center, .figure.align-center, object.align-center {
display: block;
margin-left: auto;
margin-right: auto;
}
table.align-center {
margin-left: auto;
margin-right: auto;
}
.align-left {
text-align: left }
.align-center {
clear: both ;
text-align: center }
.align-right {
text-align: right }
/* reset inner alignment in figures */
div.align-right {
text-align: inherit }
/* div.align-center * { */
/* text-align: left } */
.align-top {
vertical-align: top }
.align-middle {
vertical-align: middle }
.align-bottom {
vertical-align: bottom }
ol.simple, ul.simple {
margin-bottom: 1em }
ol.arabic {
list-style: decimal }
ol.loweralpha {
list-style: lower-alpha }
ol.upperalpha {
list-style: upper-alpha }
ol.lowerroman {
list-style: lower-roman }
ol.upperroman {
list-style: upper-roman }
p.attribution {
text-align: right ;
margin-left: 50% }
p.caption {
font-style: italic }
p.credits {
font-style: italic ;
font-size: smaller }
p.label {
white-space: nowrap }
p.rubric {
font-weight: bold ;
font-size: larger ;
color: maroon ;
text-align: center }
p.sidebar-title {
font-family: sans-serif ;
font-weight: bold ;
font-size: larger }
p.sidebar-subtitle {
font-family: sans-serif ;
font-weight: bold }
p.topic-title {
font-weight: bold }
pre.address {
margin-bottom: 0 ;
margin-top: 0 ;
font: inherit }
pre.literal-block, pre.doctest-block, pre.math, pre.code {
margin-left: 2em ;
margin-right: 2em }
pre.code .ln { color: gray; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
pre.code .literal.string, code .literal.string { color: #0C5404 }
pre.code .name.builtin, code .name.builtin { color: #352B84 }
pre.code .deleted, code .deleted { background-color: #DEB0A1}
pre.code .inserted, code .inserted { background-color: #A3D289}
span.classifier {
font-family: sans-serif ;
font-style: oblique }
span.classifier-delimiter {
font-family: sans-serif ;
font-weight: bold }
span.interpreted {
font-family: sans-serif }
span.option {
white-space: nowrap }
span.pre {
white-space: pre }
span.problematic, pre.problematic {
color: red }
span.section-subtitle {
/* font-size relative to parent (h1..h6 element) */
font-size: 80% }
table.citation {
border-left: solid 1px gray;
margin-left: 1px }
table.docinfo {
margin: 2em 4em }
table.docutils {
margin-top: 0.5em ;
margin-bottom: 0.5em }
table.footnote {
border-left: solid 1px black;
margin-left: 1px }
table.docutils td, table.docutils th,
table.docinfo td, table.docinfo th {
padding-left: 0.5em ;
padding-right: 0.5em ;
vertical-align: top }
table.docutils th.field-name, table.docinfo th.docinfo-name {
font-weight: bold ;
text-align: left ;
white-space: nowrap ;
padding-left: 0 }
/* "booktabs" style (no vertical lines) */
table.docutils.booktabs {
border: 0px;
border-top: 2px solid;
border-bottom: 2px solid;
border-collapse: collapse;
}
table.docutils.booktabs * {
border: 0px;
}
table.docutils.booktabs th {
border-bottom: thin solid;
text-align: left;
}
h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
font-size: 100% }
ul.auto-toc {
list-style-type: none }
</style>
</head>
<body>
<div class="document">
<a class="reference external image-reference" href="https://odoo-community.org/get-involved?utm_source=readme">
<img alt="Odoo Community Association" src="https://odoo-community.org/readme-banner-image" />
</a>
<div class="section" id="cross-connect-client">
<h1>Cross Connect Client</h1>
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:b0a3116c667f84d22c4fd196629c2b2e2a3d3071fef7b5af78ed46d2e872f2a0
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/license-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/server-auth/tree/16.0/cross_connect_client"><img alt="OCA/server-auth" src="https://img.shields.io/badge/github-OCA%2Fserver--auth-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/server-auth-16-0/server-auth-16-0-cross_connect_client"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/server-auth&amp;target_branch=16.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<p>This module allows this odoo instance users to connect directly on
another odoo instance where the module <tt class="docutils literal">cross_connect_server</tt> is
installed.</p>
<p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents">
<ul class="simple">
<li><a class="reference internal" href="#usage" id="toc-entry-1">Usage</a></li>
<li><a class="reference internal" href="#bug-tracker" id="toc-entry-2">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="toc-entry-3">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="toc-entry-4">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="toc-entry-5">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="toc-entry-6">Maintainers</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="usage">
<h2><a class="toc-backref" href="#toc-entry-1">Usage</a></h2>
<p>First of all after installing the module, you need to configure the
server connection.</p>
<p>In order to do that, you need to go to the menu
<tt class="docutils literal">Settings &gt; Technical &gt; Cross Connect &gt; Cross Connect Servers</tt> and
create a new server to connect to.</p>
<p>Fill the fields with the servers information :</p>
<ul class="simple">
<li>Url: The api root path (e.g. <tt class="docutils literal"><span class="pre">https://my-remote-odoo.com/api</span></tt>)</li>
<li>Api Key: The api-key from the <tt class="docutils literal">cross_connect_server</tt> configuration</li>
</ul>
<p>Then click on the <tt class="docutils literal">Sync Cross Connection</tt> button to check if the
connection is working and to sync the remote servers groups.</p>
<p>After that, you will have to affect the remote groups to the local users
in order for them to be able to connect to the remote server.</p>
<p>Once an user has a remote group, a new top level menu will appear in the
menu bar with the Cross Connect Servers name. Clicking on it will
redirect the user to the remote server logged in as the user.</p>
<p>You can change each menu icon (for use with <tt class="docutils literal">web_responsive</tt> for
instance) by setting the <tt class="docutils literal">Web Icon Data</tt> in the server configuration.</p>
</div>
<div class="section" id="bug-tracker">
<h2><a class="toc-backref" href="#toc-entry-2">Bug Tracker</a></h2>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/server-auth/issues">GitHub Issues</a>.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
<a class="reference external" href="https://github.com/OCA/server-auth/issues/new?body=module:%20cross_connect_client%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<p>Do not contact contributors directly about support or help with technical issues.</p>
</div>
<div class="section" id="credits">
<h2><a class="toc-backref" href="#toc-entry-3">Credits</a></h2>
<div class="section" id="authors">
<h3><a class="toc-backref" href="#toc-entry-4">Authors</a></h3>
<ul class="simple">
<li>Akretion</li>
</ul>
</div>
<div class="section" id="contributors">
<h3><a class="toc-backref" href="#toc-entry-5">Contributors</a></h3>
<ul class="simple">
<li>Florian Mounier <a class="reference external" href="mailto:florian.mounier&#64;akretion.com">florian.mounier&#64;akretion.com</a></li>
</ul>
</div>
<div class="section" id="maintainers">
<h3><a class="toc-backref" href="#toc-entry-6">Maintainers</a></h3>
<p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org">
<img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" />
</a>
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.</p>
<p>Current <a class="reference external" href="https://odoo-community.org/page/maintainer-role">maintainer</a>:</p>
<p><a class="reference external image-reference" href="https://github.com/paradoxxxzero"><img alt="paradoxxxzero" src="https://github.com/paradoxxxzero.png?size=40px" /></a></p>
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/server-auth/tree/16.0/cross_connect_client">OCA/server-auth</a> project on GitHub.</p>
<p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p>
</div>
</div>
</div>
</div>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

View file

@ -0,0 +1 @@
from . import test_cross_connect_client

View file

@ -0,0 +1,285 @@
# Copyright 2024 Akretion (http://www.akretion.com).
# @author Florian Mounier <florian.mounier@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from unittest.mock import Mock, patch
from odoo.exceptions import UserError
from odoo.tests.common import HttpCase, TransactionCase
def _mock_json(data):
res = Mock()
res.json = lambda: data
return res
class TestCrossConnectClient(TransactionCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.server = cls.env["cross.connect.server"].create(
{
"name": "Test Server",
"server_url": "http://test-server.example.com",
"api_key": "server-api-key",
}
)
cls.env["cross.connect.server"].create(
{
"name": "Other Test Server",
"server_url": "http://other-test-server.example.com",
"api_key": "other-server-api-key",
}
)
def test_base(self):
self.assertFalse(self.server.group_ids)
self.assertFalse(self.server.menu_id)
self.assertFalse(self.server.web_icon_data)
def test_absolute_url_for(self):
self.assertEqual(
self.server._absolute_url_for("test"),
"http://test-server.example.com/cross_connect/test",
)
self.assertEqual(
self.server._absolute_url_for("/test"),
"http://test-server.example.com/cross_connect/test",
)
self.server.server_url = "http://test-server.example.com/"
self.assertEqual(
self.server._absolute_url_for("test"),
"http://test-server.example.com/cross_connect/test",
)
self.assertEqual(
self.server._absolute_url_for("/test"),
"http://test-server.example.com/cross_connect/test",
)
def test_menu(self):
self.assertFalse(self.server.menu_id)
self.server.group_ids = [(0, 0, {"name": "Test Group"})]
self.assertTrue(self.server.menu_id)
self.server.web_icon_data = b"YQ=="
self.assertEqual(self.server.menu_id.web_icon_data, b"YQ==")
self.server.action_disable()
self.assertFalse(self.server.menu_id)
@patch("requests.request")
def test_sync(self, req):
req.return_value = _mock_json(
{
"groups": [
{"id": 1, "name": "Test Group 1", "comment": "Comment 1"},
{"id": 2, "name": "Test Group 2", "comment": "Comment 2"},
]
}
)
self.server.action_sync()
req.assert_called_once_with(
"GET",
"http://test-server.example.com/cross_connect/sync",
headers={"api-key": "server-api-key"},
json=None,
timeout=10,
)
self.assertEqual(len(self.server.group_ids), 2)
self.assertEqual(self.server.group_ids[0].name, "Test Server: Test Group 1")
self.assertEqual(self.server.group_ids[0].comment, "Comment 1")
self.assertEqual(self.server.group_ids[0].cross_connect_server_group_id, 1)
self.assertEqual(self.server.group_ids[1].name, "Test Server: Test Group 2")
self.assertEqual(self.server.group_ids[1].comment, "Comment 2")
self.assertEqual(self.server.group_ids[1].cross_connect_server_group_id, 2)
self.assertTrue(self.server.menu_id)
self.assertEqual(self.server.menu_id.name, "Test Server")
self.assertEqual(
self.server.menu_id.web_icon,
"cross_connect_client,static/description/web_icon_data.png",
)
self.assertEqual(self.server.menu_id.groups_id, self.server.group_ids)
self.assertTrue(self.server.menu_id.action.name, "Test Server")
self.assertEqual(
self.server.menu_id.action.url, f"/cross_connect_server/{self.server.id}"
)
self.assertEqual(self.server.menu_id.action.target, "new")
self.assertTrue(self.server.web_icon_data)
@patch("requests.request")
def test_successive_sync(self, req):
req.return_value = _mock_json(
{
"groups": [
{"id": 1, "name": "Test Group 1", "comment": "Comment 1"},
{"id": 2, "name": "Test Group 2", "comment": "Comment 2"},
]
}
)
self.server.action_sync()
req.return_value = _mock_json(
{
"groups": [
{
"id": 2,
"name": "Test Group 2 edited",
"comment": "Comment edited 2",
},
{"id": 3, "name": "Test Group 3", "comment": "Comment 3"},
]
}
)
self.server.action_sync()
self.assertEqual(len(self.server.group_ids), 2)
self.assertEqual(
self.server.group_ids[0].name, "Test Server: Test Group 2 edited"
)
self.assertEqual(self.server.group_ids[0].comment, "Comment edited 2")
self.assertEqual(self.server.group_ids[0].cross_connect_server_group_id, 2)
self.assertEqual(self.server.group_ids[1].name, "Test Server: Test Group 3")
self.assertEqual(self.server.group_ids[1].comment, "Comment 3")
self.assertEqual(self.server.group_ids[1].cross_connect_server_group_id, 3)
self.assertTrue(self.server.menu_id)
self.assertTrue(self.server.web_icon_data)
@patch("requests.request")
def test_get_cross_connect_url(self, req):
req.return_value = _mock_json(
{
"groups": [
{"id": 1, "name": "Test Group 1", "comment": "Comment 1"},
{"id": 2, "name": "Test Group 2", "comment": "Comment 2"},
]
}
)
self.server.action_sync()
user = self.env["res.users"].create(
{
"name": "Test User",
"login": "test_user",
"email": "test@example.com",
}
)
group = self.server.group_ids[0]
user.write({"groups_id": [(4, group.id)]})
req.reset_mock()
req.return_value = _mock_json({"client_id": 1, "token": "test-token"})
self.assertEqual(
self.server.with_user(user).sudo()._get_cross_connect_url(),
"http://test-server.example.com/cross_connect/login/1/test-token",
)
req.assert_called_once_with(
"POST",
"http://test-server.example.com/cross_connect/access",
headers={"api-key": "server-api-key"},
json={
"id": user.id,
"name": "Test User",
"login": "test_user",
"email": "test@example.com",
"lang": "en_US",
"groups": [group.cross_connect_server_group_id],
},
timeout=10,
)
req.reset_mock()
req.return_value = _mock_json({"client_id": 1})
with self.assertRaisesRegex(UserError, "Missing token"):
self.server.with_user(user).sudo()._get_cross_connect_url()
@patch("requests.request")
def test_get_cross_connect_url_bad_groups(self, req):
req.return_value = _mock_json(
{
"groups": [
{"id": 1, "name": "Test Group 1", "comment": "Comment 1"},
{"id": 2, "name": "Test Group 2", "comment": "Comment 2"},
]
}
)
self.server.action_sync()
user = self.env["res.users"].create(
{
"name": "Test User",
"login": "test_user",
"email": "test@example.com",
}
)
req.reset_mock()
req.return_value = _mock_json({"client_id": 1, "token": "test-token"})
with self.assertRaisesRegex(
UserError, "You are not allowed to access this server"
):
self.server.with_user(user).sudo()._get_cross_connect_url()
class TestCrossConnectClientController(HttpCase):
def test_act_url_redirect(self):
server = self.env["cross.connect.server"].create(
{
"name": "Test Server",
"server_url": "http://test-server.example.com",
"api_key": "server-api-key",
}
)
with patch(
"requests.request",
return_value=_mock_json(
{
"groups": [
{"id": 1, "name": "Test Group 1", "comment": "Comment 1"},
{"id": 2, "name": "Test Group 2", "comment": "Comment 2"},
]
}
),
):
server.action_sync()
user = self.env["res.users"].create(
{
"name": "Test User",
"login": "test_user",
"email": "test@example.com",
"password": "user_pas$w0rd",
}
)
group = server.group_ids[0]
user.write({"groups_id": [(4, group.id)]})
self.authenticate("test_user", "user_pas$w0rd")
with patch(
"requests.request",
return_value=_mock_json({"client_id": 1, "token": "test-token"}),
):
resp = self.url_open(server.menu_id.action.url, allow_redirects=False)
resp.raise_for_status()
self.assertEqual(resp.status_code, 303)
self.assertEqual(
resp.headers["Location"],
"http://test-server.example.com/cross_connect/login/1/test-token",
)
def test_bad_server(self):
self.assertFalse(self.env["cross.connect.server"].search([]))
resp = self.url_open("/cross_connect_server/1", allow_redirects=False)
self.assertEqual(resp.status_code, 400)

View file

@ -0,0 +1,93 @@
<?xml version="1.0" encoding="utf-8" ?>
<!--
Copyright 2024 Akretion (http://www.akretion.com).
@author Florian Mounier <florian.mounier@akretion.com>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-->
<odoo>
<record id="cross_connect_server_action" model="ir.actions.act_window">
<field name="name">Cross Connect Servers</field>
<field name="res_model">cross.connect.server</field>
<field name="view_mode">tree,form</field>
</record>
<record id="cross_connect_server_view_form" model="ir.ui.view">
<field name="name">cross.connect.server.form</field>
<field name="model">cross.connect.server</field>
<field name="arch" type="xml">
<form>
<header>
<button
name="action_sync"
type="object"
string="Sync Cross Connection"
class="btn-primary"
attrs="{'invisible': ['|', ('server_url', '=', False), ('api_key', '=', False)]}"
/>
<button
name="action_disable"
type="object"
string="Disable"
attrs="{'invisible': [('group_ids', '=', [])]}"
/>
</header>
<sheet>
<widget
name="web_ribbon"
title="Sync Required"
bg_color="bg-warning"
attrs="{'invisible': [('group_ids', '!=', [])]}"
/>
<div class="oe_title">
<h1>
<field name="name" />
</h1>
</div>
<group name="main">
<group>
<field name="server_url" />
<field name="api_key" />
<field name="menu_id" invisible="True" />
<field
name="web_icon_data"
attrs="{'invisible': [('menu_id', '=', False)]}"
/>
<field
name="group_ids"
widget="many2many_tags"
options="{'open': True}"
/>
</group>
</group>
</sheet>
</form>
</field>
</record>
<record id="cross_connect_server_view_tree" model="ir.ui.view">
<field name="name">cross.connect.server.tree</field>
<field name="model">cross.connect.server</field>
<field name="arch" type="xml">
<tree decoration-muted="not group_ids">
<field name="name" />
<field name="server_url" />
<field name="group_ids" invisible="True" />
</tree>
</field>
</record>
<menuitem
id="menu_cross_connect_server_category"
name="Cross Connect"
sequence="100"
parent="base.menu_custom"
/>
<menuitem
id="menu_cross_connect_server"
name="Cross Connect Servers"
sequence="10"
parent="menu_cross_connect_server_category"
action="cross_connect_server_action"
groups="base.group_system"
/>
</odoo>

View file

@ -0,0 +1,32 @@
# Architecture
```mermaid
flowchart TD
U[Users] -->|HTTP| V[Views and QWeb Templates]
V --> C[Controllers]
V --> W[Wizards Transient Models]
C --> M[Models and ORM]
W --> M
M --> R[Reports]
DX[Data XML] --> M
S[Security ACLs and Groups] -. enforces .-> M
subgraph Cross_connect_client Module - cross_connect_client
direction LR
M:::layer
W:::layer
C:::layer
V:::layer
R:::layer
S:::layer
DX:::layer
end
classDef layer fill:#eef8ff,stroke:#6ea8fe,stroke-width:1px
```
Notes
- Views include tree/form/kanban templates and report templates.
- Controllers provide website/portal routes when present.
- Wizards are UI flows implemented with `models.TransientModel`.
- Data XML loads data/demo records; Security defines groups and access.

View file

@ -0,0 +1,3 @@
# Configuration
Refer to Odoo settings for cross_connect_client. Configure related models, access rights, and options as needed.

View file

@ -0,0 +1,17 @@
# Controllers
HTTP routes provided by this module.
```mermaid
sequenceDiagram
participant U as User/Client
participant C as Module Controllers
participant O as ORM/Views
U->>C: HTTP GET/POST (routes)
C->>O: ORM operations, render templates
O-->>U: HTML/JSON/PDF
```
Notes
- See files in controllers/ for route definitions.

View file

@ -0,0 +1,5 @@
# Dependencies
This addon depends on:
- server_environment

View file

@ -0,0 +1,4 @@
# FAQ
- Q: Which Odoo version? A: 16.0 (OCA/OCB packaged).
- Q: How to enable? A: Start server with --addon cross_connect_client or install in UI.

View file

@ -0,0 +1,7 @@
# Install
```bash
pip install odoo-bringout-oca-server-auth-cross_connect_client"
# or
uv pip install odoo-bringout-oca-server-auth-cross_connect_client"
```

View file

@ -0,0 +1,14 @@
# Models
Detected core models and extensions in cross_connect_client.
```mermaid
classDiagram
class cross_connect_server
class res_groups
class server_env_mixin
```
Notes
- Classes show model technical names; fields omitted for brevity.
- Items listed under _inherit are extensions of existing models.

View file

@ -0,0 +1,6 @@
# Overview
Packaged Odoo addon: cross_connect_client. Provides features documented in upstream Odoo 16 under this addon.
- Source: OCA/OCB 16.0, addon cross_connect_client
- License: LGPL-3

View file

@ -0,0 +1,3 @@
# Reports
This module does not define custom reports.

View file

@ -0,0 +1,69 @@
# Security
Access control and security definitions in cross_connect_client.
## Access Control Lists (ACLs)
Model access permissions defined in:
- **[bosnian_translations.json](../bosnian_translations.json)**
- 50 model access rules
- **[bosnian_translations_output.json](../bosnian_translations_output.json)**
- 444 model access rules
- **[CHANGELOG.md](../CHANGELOG.md)**
- 132 model access rules
- **[delete_odoo_addons.sh](../delete_odoo_addons.sh)**
- 44 model access rules
- **[doc](../doc)**
- **[docker](../docker)**
- **[input](../input)**
- **[nix](../nix)**
- **[odoo.conf](../odoo.conf)**
- 58 model access rules
- **[odoo_packages_bez_l10n.txt](../odoo_packages_bez_l10n.txt)**
- 1947 model access rules
- **[odoo_packages_bringout.txt](../odoo_packages_bringout.txt)**
- 1947 model access rules
- **[odoo_packages.txt](../odoo_packages.txt)**
- 2085 model access rules
- **[output](../output)**
- **[packages](../packages)**
- **[PACKAGES.md](../PACKAGES.md)**
- 298 model access rules
- **[README.md](../README.md)**
- 338 model access rules
- **[scripts](../scripts)**
- **[temp](../temp)**
- **[TRANSLATION_BS_SUMMARY.md](../TRANSLATION_BS_SUMMARY.md)**
- 146 model access rules
- **[verify_deletions.sh](../verify_deletions.sh)**
- 55 model access rules
## Record Rules
Row-level security rules defined in:
## Security Groups & Configuration
Security groups and permissions defined in:
- **[ir_model_access.xml](../cross_connect_client/security/ir_model_access.xml)**
```mermaid
graph TB
subgraph "Security Layers"
A[Users] --> B[Groups]
B --> C[Access Control Lists]
C --> D[Models]
B --> E[Record Rules]
E --> F[Individual Records]
end
```
Security files overview:
- **[ir_model_access.xml](../cross_connect_client/security/ir_model_access.xml)**
- Security groups, categories, and XML-based rules
Notes
- Access Control Lists define which groups can access which models
- Record Rules provide row-level security (filter records by user/group)
- Security groups organize users and define permission sets
- All security is enforced at the ORM level by Odoo

View file

@ -0,0 +1,5 @@
# Troubleshooting
- Ensure Python and Odoo environment matches repo guidance.
- Check database connectivity and logs if startup fails.
- Validate that dependent addons listed in DEPENDENCIES.md are installed.

View file

@ -0,0 +1,7 @@
# Usage
Start Odoo including this addon (from repo root):
```bash
python3 scripts/nix_odoo_web_server.py --db-name mydb --addon cross_connect_client
```

View file

@ -0,0 +1,3 @@
# Wizards
This module does not include UI wizards.

View file

@ -0,0 +1,42 @@
[project]
name = "odoo-bringout-oca-server-auth-cross_connect_client"
version = "16.0.0"
description = "Cross Connect Client - Cross Connect Client allows to connect to a Cross Connect Server enabled odoo instance."
authors = [
{ name = "Ernad Husremovic", email = "hernad@bring.out.ba" }
]
dependencies = [
"odoo-bringout-oca-server-auth-server_environment>=16.0.0",
"requests>=2.25.1"
]
readme = "README.md"
requires-python = ">= 3.11"
classifiers = [
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
"License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Topic :: Office/Business",
]
[project.urls]
homepage = "https://github.com/bringout/0"
repository = "https://github.com/bringout/0"
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[tool.hatch.metadata]
allow-direct-references = true
[tool.hatch.build.targets.wheel]
packages = ["cross_connect_client"]
[tool.rye]
managed = true
dev-dependencies = [
"pytest>=8.4.1",
]