diff --git a/test-requirements.txt b/test-requirements.txt new file mode 100644 index 0000000000..df1af8fcb8 --- /dev/null +++ b/test-requirements.txt @@ -0,0 +1 @@ +odoo-addon-vault @ git+https://github.com/OCA/server-auth.git@refs/pull/1055/head#subdirectory=vault diff --git a/vault_share/README.rst b/vault_share/README.rst new file mode 100644 index 0000000000..51d14a3a9f --- /dev/null +++ b/vault_share/README.rst @@ -0,0 +1,100 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + +============= +Vault - Share +============= + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:cf5a42f160382ee63d76e136dca379f519787cd438eca581a1a9f13ddf74e45f + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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/20.0/vault_share + :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-20-0/server-auth-20-0-vault_share + :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=20.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module implements possibilities to share specific secrets with +external users. This bases on the vault implementation and the generated +RSA key pair. + +Share +----- + +This allows an user to share a secret with external users. A share can +be generated from a vault entry or directly created by an user. The +secret is symmetrically encrypted by a key derived from a pin. To grant +access the user has to transmit the link and pin with the external. If +either the access counter reaches 0 or the share expires it will be +deleted automatically. Due to the usage of a numeric pin and the browser +side decryption a share is vulnerable to brute-force attacks and +shouldn't be used as a permanent storage for secrets. For long time uses +the user should create an account and a vault should be used. + +**Table of contents** + +.. contents:: + :local: + +Known issues / Roadmap +====================== + +- Secure the download of the encrypted file behind a challenge/response + +Bug Tracker +=========== + +Bugs are tracked on `GitHub 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 `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +------- + +* initOS GmbH + +Contributors +------------ + +- Florian Kantelberg + +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. + +This module is part of the `OCA/server-auth `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/vault_share/__init__.py b/vault_share/__init__.py new file mode 100644 index 0000000000..05ae53c8cb --- /dev/null +++ b/vault_share/__init__.py @@ -0,0 +1,4 @@ +# © 2021 Florian Kantelberg - initOS GmbH +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from . import controllers, models diff --git a/vault_share/__manifest__.py b/vault_share/__manifest__.py new file mode 100644 index 0000000000..a3efe16bae --- /dev/null +++ b/vault_share/__manifest__.py @@ -0,0 +1,34 @@ +# © 2021-2024 Florian Kantelberg - initOS GmbH +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +{ + "name": "Vault - Share", + "summary": "Implementation of a mechanism to share secrets", + "license": "AGPL-3", + "version": "20.0.1.0.0", + "website": "https://github.com/OCA/server-auth", + "application": False, + "author": "initOS GmbH, Odoo Community Association (OCA)", + "category": "Vault", + "depends": ["vault"], + "data": [ + "data/ir_cron.xml", + "security/ir.access.csv", + "views/menuitems.xml", + "views/res_config_settings_views.xml", + "views/templates.xml", + "views/vault_share_views.xml", + ], + "assets": { + "web.assets_backend": [ + "vault_share/static/src/common/**/*.js", + "vault_share/static/src/backend/**/*.js", + "vault_share/static/src/backend/**/*.scss", + "vault_share/static/src/backend/**/*.xml", + ], + "vault_share.assets_frontend": [ + "vault/static/src/common/*.js", + "vault_share/static/src/frontend/*.js", + ], + }, +} diff --git a/vault_share/controllers/__init__.py b/vault_share/controllers/__init__.py new file mode 100644 index 0000000000..aabfa83edd --- /dev/null +++ b/vault_share/controllers/__init__.py @@ -0,0 +1,4 @@ +# © 2021 Florian Kantelberg - initOS GmbH +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from . import main diff --git a/vault_share/controllers/main.py b/vault_share/controllers/main.py new file mode 100644 index 0000000000..381374ba71 --- /dev/null +++ b/vault_share/controllers/main.py @@ -0,0 +1,36 @@ +# © 2021 Florian Kantelberg - initOS GmbH +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +import logging + +from odoo import http +from odoo.http import request + +_logger = logging.getLogger(__name__) + + +class Controller(http.Controller): + @http.route("/vault/share/", type="http", auth="public", website=True) + def vault_share(self, token): + ctx = {"disable_footer": True, "token": token} + share = request.env["vault.share"].sudo() + secret = share.get(token, ip=request.httprequest.remote_addr) + if secret is None: + ctx["error"] = request.env._("The secret expired") + return request.render("vault_share.share", ctx) + + if len(secret) != 1: + ctx["error"] = request.env._("Invalid token") + return request.render("vault_share.share", ctx) + + ctx.update( + { + "encrypted": secret.secret, + "salt": secret.salt, + "iv": secret.iv, + "encrypted_file": secret.secret_file, + "filename": secret.filename, + "iterations": secret.iterations, + } + ) + return request.render("vault_share.share", ctx) diff --git a/vault_share/data/ir_cron.xml b/vault_share/data/ir_cron.xml new file mode 100644 index 0000000000..568cf399a4 --- /dev/null +++ b/vault_share/data/ir_cron.xml @@ -0,0 +1,12 @@ + + + + Clean outgoing share + + code + model.clean() + + minutes + + + diff --git a/vault_share/i18n/es.po b/vault_share/i18n/es.po new file mode 100644 index 0000000000..a73a93b1cb --- /dev/null +++ b/vault_share/i18n/es.po @@ -0,0 +1,296 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * vault_share +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 13.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-06-06 07:44+0000\n" +"PO-Revision-Date: 2023-10-30 21:37+0000\n" +"Last-Translator: Ivorra78 \n" +"Language-Team: \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.17\n" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__accesses +msgid "Access counter" +msgstr "Contador de acceso" + +#. module: vault_share +#: model:ir.actions.server,name:vault_share.cron_share_clean_ir_actions_server +#: model:ir.cron,cron_name:vault_share.cron_share_clean +#: model:ir.cron,name:vault_share.cron_share_clean +msgid "Clean outgoing share" +msgstr "Limpiar recurso compartido externo" + +#. module: vault_share +#: model:ir.model,name:vault_share.model_res_company +msgid "Companies" +msgstr "Compañías" + +#. module: vault_share +#: model:ir.model,name:vault_share.model_res_config_settings +msgid "Config Settings" +msgstr "Opciones de Configuración" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__create_uid +#: model:ir.model.fields,field_description:vault_share.field_vault_share_log__create_uid +msgid "Created by" +msgstr "Creado por" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__create_date +#: model:ir.model.fields,field_description:vault_share.field_vault_share_log__create_date +msgid "Created on" +msgstr "Creado el" + +#. module: vault_share +#: model_terms:ir.ui.view,arch_db:vault_share.res_config_settings_view_form +msgid "Days" +msgstr "Días" + +#. module: vault_share +#: model_terms:ir.ui.view,arch_db:vault_share.res_config_settings_view_form +msgid "Delay the deletion of shares" +msgstr "Retrasar el borrado de recursos compartidos" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_res_config_settings__vault_share_delay +msgid "Delayed Deletion" +msgstr "Retrasar borrado" + +#. module: vault_share +#: model:ir.model.fields,help:vault_share.field_res_config_settings__vault_share_delay +msgid "" +"Delays the deletion of a share. After the expiration date it continues to " +"stay inaccessible" +msgstr "" +"Retrasa la eliminación de un recurso compartido. Después de la fecha de " +"caducidad sigue siendo inaccesible" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__display_name +#: model:ir.model.fields,field_description:vault_share.field_vault_share_log__display_name +msgid "Display Name" +msgstr "Nombre a mostrar" + +#. module: vault_share +#: model_terms:ir.ui.view,arch_db:vault_share.share +msgid "Enter the pin:" +msgstr "Ingresa el pin:" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__expiration +msgid "Expiration" +msgstr "Expiración" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__filename +msgid "Filename" +msgstr "Nombre del fichero" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__id +#: model:ir.model.fields,field_description:vault_share.field_vault_share_log__id +msgid "ID" +msgstr "ID" + +#. module: vault_share +#: code:addons/vault_share/controllers/main.py:0 +#, python-format +msgid "Invalid token" +msgstr "Token inválido" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__iv +msgid "Iv" +msgstr "Iv" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share____last_update +#: model:ir.model.fields,field_description:vault_share.field_vault_share_log____last_update +msgid "Last Modified on" +msgstr "Última modificación el" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__write_uid +#: model:ir.model.fields,field_description:vault_share.field_vault_share_log__write_uid +msgid "Last Updated by" +msgstr "Última modificación por" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__write_date +#: model:ir.model.fields,field_description:vault_share.field_vault_share_log__write_date +msgid "Last Updated on" +msgstr "Última actualización en" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__log_ids +msgid "Log" +msgstr "Registro" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__name +#: model:ir.model.fields,field_description:vault_share.field_vault_share_log__name +msgid "Name" +msgstr "Nombre" + +#. module: vault_share +#: code:addons/vault_share/models/vault_share.py:0 +#: model:ir.model.constraint,message:vault_share.constraint_vault_share_value_check +#, python-format +msgid "No value found" +msgstr "No se ha encontrado ningún valor" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__pin +msgid "Pin" +msgstr "Pin" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__salt +msgid "Salt" +msgstr "Sal" + +#. module: vault_share +#. openerp-web +#: code:addons/vault_share/static/src/backend/templates.xml:0 +#, python-format +msgid "Save in a vault" +msgstr "Guardar en un vault" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__secret +msgid "Secret" +msgstr "Secreto" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__secret_file +msgid "Secret File" +msgstr "Archivo de secretos" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share_log__share_id +msgid "Share" +msgstr "Compartir" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__share_link +msgid "Share URL" +msgstr "Compartir url" + +#. module: vault_share +#. openerp-web +#: code:addons/vault_share/static/src/legacy/vault_fields.js:0 +#, python-format +msgid "Share the secret" +msgstr "Compartir el secreto" + +#. module: vault_share +#. openerp-web +#: code:addons/vault_share/static/src/backend/templates.xml:0 +#, python-format +msgid "Share the secret with an external user" +msgstr "Compartir el secreto con usuario externo" + +#. module: vault_share +#: model_terms:ir.ui.view,arch_db:vault_share.share +msgid "Shared file:" +msgstr "Archivo compartido:" + +#. module: vault_share +#: model_terms:ir.ui.view,arch_db:vault_share.share +msgid "Shared secret:" +msgstr "Secreto compartido:" + +#. module: vault_share +#: model:ir.actions.act_window,name:vault_share.action_vault_share +#: model:ir.ui.menu,name:vault_share.menu_vault_share +msgid "Shares" +msgstr "Recursos compartidos" + +#. module: vault_share +#: model:ir.model.fields,help:vault_share.field_vault_share__expiration +msgid "Specifies how long a share can be accessed until deletion." +msgstr "" +"Especifica el tiempo que se puede acceder a un recurso compartido hasta su " +"eliminación." + +#. module: vault_share +#: model:ir.model.fields,help:vault_share.field_vault_share__accesses +msgid "Specifies how often a share can be accessed before deletion." +msgstr "" +"Especifica la frecuencia con la que se puede acceder a un recurso compartido " +"antes de eliminarlo." + +#. module: vault_share +#: model:ir.model.fields,help:vault_share.field_vault_share__pin +msgid "The pin needed to decrypt the share." +msgstr "El pin necesario para descifrar el recurso compartido." + +#. module: vault_share +#: code:addons/vault_share/controllers/main.py:0 +#, python-format +msgid "The secret expired" +msgstr "El secreto ha expirado" + +#. module: vault_share +#: code:addons/vault_share/models/vault_share.py:0 +#, python-format +msgid "The share was accessed by %(name)s via %(ip)s" +msgstr "%(name)s ha accedido a la acción a través de %(ip)s" + +#. module: vault_share +#: code:addons/vault_share/models/vault_share.py:0 +#, python-format +msgid "The share was created by %(name)s" +msgstr "La acción fue creada por %(name)s" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__token +msgid "Token" +msgstr "Token" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__user_id +msgid "User" +msgstr "Usuario" + +#. module: vault_share +#: model:ir.model.fields,help:vault_share.field_vault_share__share_link +msgid "Using this link and pin people can access the secret." +msgstr "Utilizando este enlace y el pin la gente puede acceder al secreto." + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_res_company__vault_share_delay +msgid "Vault Share Delay" +msgstr "Retraso de la Acción de la Bóveda" + +#. module: vault_share +#: code:addons/vault_share/models/vault_share_log.py:0 +#: model:ir.model,name:vault_share.model_vault_share_log +#, python-format +msgid "Vault share log" +msgstr "Registro de compartición de la bóveda" + +#. module: vault_share +#: code:addons/vault_share/models/vault_share.py:0 +#: model:ir.model,name:vault_share.model_vault_share +#, python-format +msgid "Vault share outgoing secrets" +msgstr "La bóveda comparte secretos de salida" + +#, python-format +#~ msgid "The share was accessed by %s via %s" +#~ msgstr "El recurso compartido fue accedido por %s a través de %s" + +#, python-format +#~ msgid "The share was created by %s" +#~ msgstr "El recurso compartido fue creado por %s" diff --git a/vault_share/i18n/it.po b/vault_share/i18n/it.po new file mode 100644 index 0000000000..f6b1a8c662 --- /dev/null +++ b/vault_share/i18n/it.po @@ -0,0 +1,308 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * vault_share +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-03-08 15:34+0000\n" +"Last-Translator: mymage \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 4.17\n" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__accesses +msgid "Access counter" +msgstr "Contatore accessi" + +#. module: vault_share +#: model:ir.actions.server,name:vault_share.cron_share_clean_ir_actions_server +#: model:ir.cron,cron_name:vault_share.cron_share_clean +msgid "Clean outgoing share" +msgstr "Pulizia condivisione in uscita" + +#. module: vault_share +#: model:ir.model,name:vault_share.model_res_company +msgid "Companies" +msgstr "Aziende" + +#. module: vault_share +#: model:ir.model,name:vault_share.model_res_config_settings +msgid "Config Settings" +msgstr "Impostazioni configurazione" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__create_uid +#: model:ir.model.fields,field_description:vault_share.field_vault_share_log__create_uid +msgid "Created by" +msgstr "Creato da" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__create_date +#: model:ir.model.fields,field_description:vault_share.field_vault_share_log__create_date +msgid "Created on" +msgstr "Creato il" + +#. module: vault_share +#: model_terms:ir.ui.view,arch_db:vault_share.res_config_settings_view_form +msgid "Days" +msgstr "Giorni" + +#. module: vault_share +#: model_terms:ir.ui.view,arch_db:vault_share.res_config_settings_view_form +msgid "Delay the deletion of shares" +msgstr "Ritarda la cancellazione delle condivisioni" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_res_config_settings__vault_share_delay +msgid "Delayed Deletion" +msgstr "Cancellazioni ritardate" + +#. module: vault_share +#: model:ir.model.fields,help:vault_share.field_res_config_settings__vault_share_delay +msgid "" +"Delays the deletion of a share. After the expiration date it continues to " +"stay inaccessible" +msgstr "" +"Ritarda la cancellazione di una condivisione. Dopo la scadenza continua ad " +"essere inaccessibile" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__display_name +#: model:ir.model.fields,field_description:vault_share.field_vault_share_log__display_name +msgid "Display Name" +msgstr "Nome visualizzato" + +#. module: vault_share +#: model_terms:ir.ui.view,arch_db:vault_share.share +msgid "Enter the pin:" +msgstr "Inserire il PIN:" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__expiration +msgid "Expiration" +msgstr "Scadenza" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__filename +msgid "Filename" +msgstr "Nome file" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__id +#: model:ir.model.fields,field_description:vault_share.field_vault_share_log__id +msgid "ID" +msgstr "ID" + +#. module: vault_share +#. odoo-python +#: code:addons/vault_share/controllers/main.py:0 +#, python-format +msgid "Invalid token" +msgstr "Token non valido" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__iterations +msgid "Iterations" +msgstr "Iterazioni" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__iv +msgid "Iv" +msgstr "Iv" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share____last_update +#: model:ir.model.fields,field_description:vault_share.field_vault_share_log____last_update +msgid "Last Modified on" +msgstr "Ultima modifica il" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__write_uid +#: model:ir.model.fields,field_description:vault_share.field_vault_share_log__write_uid +msgid "Last Updated by" +msgstr "Ultimo aggiornamento di" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__write_date +#: model:ir.model.fields,field_description:vault_share.field_vault_share_log__write_date +msgid "Last Updated on" +msgstr "Ultimo aggiornamento il" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__log_ids +msgid "Log" +msgstr "Log" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__name +#: model:ir.model.fields,field_description:vault_share.field_vault_share_log__name +msgid "Name" +msgstr "Nome" + +#. module: vault_share +#. odoo-python +#: code:addons/vault_share/models/vault_share.py:0 +#: model:ir.model.constraint,message:vault_share.constraint_vault_share_value_check +#, python-format +msgid "No value found" +msgstr "Nessun valore trovato" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__pin +msgid "Pin" +msgstr "PIN" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__salt +msgid "Salt" +msgstr "Salt" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__secret +msgid "Secret" +msgstr "Segreto" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__secret_file +msgid "Secret File" +msgstr "File segreto" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share_log__share_id +msgid "Share" +msgstr "Condividi" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__share_link +msgid "Share URL" +msgstr "URL condivisione" + +#. module: vault_share +#. odoo-javascript +#: code:addons/vault_share/static/src/backend/fields/vault_field.esm.js:0 +#, python-format +msgid "Share the secret" +msgstr "Condividi il segreto" + +#. module: vault_share +#. odoo-javascript +#: code:addons/vault_share/static/src/backend/fields/templates.xml:0 +#: code:addons/vault_share/static/src/backend/fields/templates.xml:0 +#, python-format +msgid "Share the secret with an external user" +msgstr "Condividi il segreto con un utente esterno" + +#. module: vault_share +#: model_terms:ir.ui.view,arch_db:vault_share.share +msgid "Shared file:" +msgstr "File condiviso:" + +#. module: vault_share +#: model_terms:ir.ui.view,arch_db:vault_share.share +msgid "Shared secret:" +msgstr "Segreto condiviso:" + +#. module: vault_share +#: model:ir.actions.act_window,name:vault_share.action_vault_share +#: model:ir.ui.menu,name:vault_share.menu_vault_share +msgid "Shares" +msgstr "Condivisioni" + +#. module: vault_share +#: model:ir.model.fields,help:vault_share.field_vault_share__expiration +msgid "Specifies how long a share can be accessed until deletion." +msgstr "" +"Indica per quanto tempo si può accedere ad una condivisione prima della " +"cancellazione." + +#. module: vault_share +#: model:ir.model.fields,help:vault_share.field_vault_share__accesses +msgid "Specifies how often a share can be accessed before deletion." +msgstr "" +"Indica quante volte si può accedere ad una condivisione prima della " +"cancellazione." + +#. module: vault_share +#: model:ir.model.fields,help:vault_share.field_vault_share__pin +msgid "The pin needed to decrypt the share." +msgstr "Il PIN richiesto per decriptare la condivisione." + +#. module: vault_share +#. odoo-python +#: code:addons/vault_share/controllers/main.py:0 +#, python-format +msgid "The secret expired" +msgstr "Il segreto è scaduto" + +#. module: vault_share +#. odoo-python +#: code:addons/vault_share/models/vault_share.py:0 +#, python-format +msgid "The share was accessed by %(name)s via %(ip)s" +msgstr "La codivisione è stata utilizzata da %(name)s attraverso %(ip)s" + +#. module: vault_share +#. odoo-python +#: code:addons/vault_share/models/vault_share.py:0 +#, python-format +msgid "The share was created by %(name)s" +msgstr "La condivisione è stata creata da %(name)s" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__token +msgid "Token" +msgstr "Token" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__user_id +msgid "User" +msgstr "Utente" + +#. module: vault_share +#: model:ir.model.fields,help:vault_share.field_vault_share__share_link +msgid "Using this link and pin people can access the secret." +msgstr "" +"Utilizzando questo collegamento e PIN le persone possono accedere al segreto." + +#. module: vault_share +#. odoo-javascript +#: code:addons/vault_share/static/src/backend/fields/vault_pin_field.esm.js:0 +#, python-format +msgid "Vault Pin Field" +msgstr "Campo PIN deposito di sicurezza" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_res_company__vault_share_delay +msgid "Vault Share Delay" +msgstr "Ritardo condivisione deposito di sicurezza" + +#. module: vault_share +#. odoo-javascript +#: code:addons/vault_share/static/src/backend/fields/vault_share_field.esm.js:0 +#: code:addons/vault_share/static/src/backend/fields/vault_share_file.esm.js:0 +#, python-format +msgid "Vault Share Field" +msgstr "Campo condivisione deposito di sicurezza" + +#. module: vault_share +#. odoo-python +#: code:addons/vault_share/models/vault_share_log.py:0 +#: model:ir.model,name:vault_share.model_vault_share_log +#, python-format +msgid "Vault share log" +msgstr "Log condivisione deposito di sicurezza" + +#. module: vault_share +#. odoo-python +#: code:addons/vault_share/models/vault_share.py:0 +#: model:ir.model,name:vault_share.model_vault_share +#, python-format +msgid "Vault share outgoing secrets" +msgstr "Segreti uscita condivisione deposito di sicurezza" diff --git a/vault_share/i18n/nl.po b/vault_share/i18n/nl.po new file mode 100644 index 0000000000..5ea11a1ac3 --- /dev/null +++ b/vault_share/i18n/nl.po @@ -0,0 +1,281 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * vault_share +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 15.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2023-05-05 13:33+0000\n" +"Last-Translator: Bosd \n" +"Language-Team: none\n" +"Language: nl\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 4.14.1\n" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__accesses +msgid "Access counter" +msgstr "Toegangsteller" + +#. module: vault_share +#: model:ir.actions.server,name:vault_share.cron_share_clean_ir_actions_server +#: model:ir.cron,cron_name:vault_share.cron_share_clean +#: model:ir.cron,name:vault_share.cron_share_clean +msgid "Clean outgoing share" +msgstr "" + +#. module: vault_share +#: model:ir.model,name:vault_share.model_res_company +msgid "Companies" +msgstr "Bedrijven" + +#. module: vault_share +#: model:ir.model,name:vault_share.model_res_config_settings +msgid "Config Settings" +msgstr "Configuratie-instellingen" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__create_uid +#: model:ir.model.fields,field_description:vault_share.field_vault_share_log__create_uid +msgid "Created by" +msgstr "Aangemaakt door" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__create_date +#: model:ir.model.fields,field_description:vault_share.field_vault_share_log__create_date +msgid "Created on" +msgstr "Aangemaakt op" + +#. module: vault_share +#: model_terms:ir.ui.view,arch_db:vault_share.res_config_settings_view_form +msgid "Days" +msgstr "Dagen" + +#. module: vault_share +#: model_terms:ir.ui.view,arch_db:vault_share.res_config_settings_view_form +msgid "Delay the deletion of shares" +msgstr "" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_res_config_settings__vault_share_delay +msgid "Delayed Deletion" +msgstr "Uitgestelde verwijdering" + +#. module: vault_share +#: model:ir.model.fields,help:vault_share.field_res_config_settings__vault_share_delay +msgid "" +"Delays the deletion of a share. After the expiration date it continues to " +"stay inaccessible" +msgstr "" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__display_name +#: model:ir.model.fields,field_description:vault_share.field_vault_share_log__display_name +msgid "Display Name" +msgstr "Schermnaam" + +#. module: vault_share +#: model_terms:ir.ui.view,arch_db:vault_share.share +msgid "Enter the pin:" +msgstr "Voer de pincode in:" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__expiration +msgid "Expiration" +msgstr "Vervaldatum" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__filename +msgid "Filename" +msgstr "Bestandsnaam" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__id +#: model:ir.model.fields,field_description:vault_share.field_vault_share_log__id +msgid "ID" +msgstr "ID" + +#. module: vault_share +#: code:addons/vault_share/controllers/main.py:0 +#, python-format +msgid "Invalid token" +msgstr "Ongeldige token" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__iv +msgid "Iv" +msgstr "" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share____last_update +#: model:ir.model.fields,field_description:vault_share.field_vault_share_log____last_update +msgid "Last Modified on" +msgstr "Laatst gewijzigd op" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__write_uid +#: model:ir.model.fields,field_description:vault_share.field_vault_share_log__write_uid +msgid "Last Updated by" +msgstr "Laatst bijgewerkt door" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__write_date +#: model:ir.model.fields,field_description:vault_share.field_vault_share_log__write_date +msgid "Last Updated on" +msgstr "Laatst bijgewerkt op" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__log_ids +msgid "Log" +msgstr "Log" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__name +#: model:ir.model.fields,field_description:vault_share.field_vault_share_log__name +msgid "Name" +msgstr "Naam" + +#. module: vault_share +#: code:addons/vault_share/models/vault_share.py:0 +#: model:ir.model.constraint,message:vault_share.constraint_vault_share_value_check +#, python-format +msgid "No value found" +msgstr "Geen waarde gevonden" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__pin +msgid "Pin" +msgstr "Pin" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__salt +msgid "Salt" +msgstr "" + +#. module: vault_share +#. openerp-web +#: code:addons/vault_share/static/src/backend/templates.xml:0 +#, python-format +msgid "Save in a vault" +msgstr "Opslaan in een kluis" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__secret +msgid "Secret" +msgstr "Geheim" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__secret_file +msgid "Secret File" +msgstr "Secret File" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share_log__share_id +msgid "Share" +msgstr "Delen" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__share_link +msgid "Share URL" +msgstr "Share URL" + +#. module: vault_share +#. openerp-web +#: code:addons/vault_share/static/src/legacy/vault_fields.js:0 +#, python-format +msgid "Share the secret" +msgstr "Deel het geheim" + +#. module: vault_share +#. openerp-web +#: code:addons/vault_share/static/src/backend/templates.xml:0 +#, python-format +msgid "Share the secret with an external user" +msgstr "Het geheim delen met een externe gebruiker" + +#. module: vault_share +#: model_terms:ir.ui.view,arch_db:vault_share.share +msgid "Shared file:" +msgstr "Gedeeld bestand:" + +#. module: vault_share +#: model_terms:ir.ui.view,arch_db:vault_share.share +msgid "Shared secret:" +msgstr "Gedeeld geheim:" + +#. module: vault_share +#: model:ir.actions.act_window,name:vault_share.action_vault_share +#: model:ir.ui.menu,name:vault_share.menu_vault_share +msgid "Shares" +msgstr "" + +#. module: vault_share +#: model:ir.model.fields,help:vault_share.field_vault_share__expiration +msgid "Specifies how long a share can be accessed until deletion." +msgstr "" + +#. module: vault_share +#: model:ir.model.fields,help:vault_share.field_vault_share__accesses +msgid "Specifies how often a share can be accessed before deletion." +msgstr "" + +#. module: vault_share +#: model:ir.model.fields,help:vault_share.field_vault_share__pin +msgid "The pin needed to decrypt the share." +msgstr "" + +#. module: vault_share +#: code:addons/vault_share/controllers/main.py:0 +#, python-format +msgid "The secret expired" +msgstr "Het geheim is verlopen" + +#. module: vault_share +#: code:addons/vault_share/models/vault_share.py:0 +#, python-format +msgid "The share was accessed by %(name)s via %(ip)s" +msgstr "Het record werd geopend door %(name)s via %(ip)s" + +#. module: vault_share +#: code:addons/vault_share/models/vault_share.py:0 +#, python-format +msgid "The share was created by %(name)s" +msgstr "Het record is gemaakt door %(name)s" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__token +msgid "Token" +msgstr "Token" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__user_id +msgid "User" +msgstr "Gebruiker" + +#. module: vault_share +#: model:ir.model.fields,help:vault_share.field_vault_share__share_link +msgid "Using this link and pin people can access the secret." +msgstr "Met deze link en pin kunnen mensen toegang krijgen tot het geheim." + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_res_company__vault_share_delay +msgid "Vault Share Delay" +msgstr "" + +#. module: vault_share +#: code:addons/vault_share/models/vault_share_log.py:0 +#: model:ir.model,name:vault_share.model_vault_share_log +#, python-format +msgid "Vault share log" +msgstr "" + +#. module: vault_share +#: code:addons/vault_share/models/vault_share.py:0 +#: model:ir.model,name:vault_share.model_vault_share +#, python-format +msgid "Vault share outgoing secrets" +msgstr "" diff --git a/vault_share/i18n/vault_share.pot b/vault_share/i18n/vault_share.pot new file mode 100644 index 0000000000..f8c357ca0f --- /dev/null +++ b/vault_share/i18n/vault_share.pot @@ -0,0 +1,273 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * vault_share +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 18.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: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__accesses +msgid "Access counter" +msgstr "" + +#. module: vault_share +#: model:ir.actions.server,name:vault_share.cron_share_clean_ir_actions_server +msgid "Clean outgoing share" +msgstr "" + +#. module: vault_share +#: model:ir.model,name:vault_share.model_res_company +msgid "Companies" +msgstr "" + +#. module: vault_share +#: model:ir.model,name:vault_share.model_res_config_settings +msgid "Config Settings" +msgstr "" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__create_uid +#: model:ir.model.fields,field_description:vault_share.field_vault_share_log__create_uid +msgid "Created by" +msgstr "" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__create_date +#: model:ir.model.fields,field_description:vault_share.field_vault_share_log__create_date +msgid "Created on" +msgstr "" + +#. module: vault_share +#: model_terms:ir.ui.view,arch_db:vault_share.res_config_settings_view_form +msgid "Days" +msgstr "" + +#. module: vault_share +#: model_terms:ir.ui.view,arch_db:vault_share.res_config_settings_view_form +msgid "Delay the deletion of shares" +msgstr "" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_res_config_settings__vault_share_delay +msgid "Delayed Deletion" +msgstr "" + +#. module: vault_share +#: model:ir.model.fields,help:vault_share.field_res_config_settings__vault_share_delay +msgid "" +"Delays the deletion of a share. After the expiration date it continues to " +"stay inaccessible" +msgstr "" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__display_name +#: model:ir.model.fields,field_description:vault_share.field_vault_share_log__display_name +msgid "Display Name" +msgstr "" + +#. module: vault_share +#: model_terms:ir.ui.view,arch_db:vault_share.share +msgid "Enter the pin:" +msgstr "" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__expiration +msgid "Expiration" +msgstr "" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__filename +msgid "Filename" +msgstr "" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__id +#: model:ir.model.fields,field_description:vault_share.field_vault_share_log__id +msgid "ID" +msgstr "" + +#. module: vault_share +#. odoo-python +#: code:addons/vault_share/controllers/main.py:0 +msgid "Invalid token" +msgstr "" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__iterations +msgid "Iterations" +msgstr "" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__iv +msgid "Iv" +msgstr "" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__write_uid +#: model:ir.model.fields,field_description:vault_share.field_vault_share_log__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__write_date +#: model:ir.model.fields,field_description:vault_share.field_vault_share_log__write_date +msgid "Last Updated on" +msgstr "" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__log_ids +msgid "Log" +msgstr "" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__name +#: model:ir.model.fields,field_description:vault_share.field_vault_share_log__name +msgid "Name" +msgstr "" + +#. module: vault_share +#: model:ir.model.constraint,message:vault_share.constraint_vault_share_value_check +msgid "No value found" +msgstr "" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__pin +msgid "Pin" +msgstr "" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__salt +msgid "Salt" +msgstr "" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__secret +msgid "Secret" +msgstr "" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__secret_file +msgid "Secret File" +msgstr "" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share_log__share_id +msgid "Share" +msgstr "" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__share_link +msgid "Share URL" +msgstr "" + +#. module: vault_share +#. odoo-javascript +#: code:addons/vault_share/static/src/backend/fields/vault_field.esm.js:0 +msgid "Share the secret" +msgstr "" + +#. module: vault_share +#. odoo-javascript +#: code:addons/vault_share/static/src/backend/fields/templates.xml:0 +msgid "Share the secret with an external user" +msgstr "" + +#. module: vault_share +#: model_terms:ir.ui.view,arch_db:vault_share.share +msgid "Shared file:" +msgstr "" + +#. module: vault_share +#: model_terms:ir.ui.view,arch_db:vault_share.share +msgid "Shared secret:" +msgstr "" + +#. module: vault_share +#: model:ir.actions.act_window,name:vault_share.action_vault_share +#: model:ir.ui.menu,name:vault_share.menu_vault_share +msgid "Shares" +msgstr "" + +#. module: vault_share +#: model:ir.model.fields,help:vault_share.field_vault_share__expiration +msgid "Specifies how long a share can be accessed until deletion." +msgstr "" + +#. module: vault_share +#: model:ir.model.fields,help:vault_share.field_vault_share__accesses +msgid "Specifies how often a share can be accessed before deletion." +msgstr "" + +#. module: vault_share +#: model:ir.model.fields,help:vault_share.field_vault_share__pin +msgid "The pin needed to decrypt the share." +msgstr "" + +#. module: vault_share +#. odoo-python +#: code:addons/vault_share/controllers/main.py:0 +msgid "The secret expired" +msgstr "" + +#. module: vault_share +#. odoo-python +#: code:addons/vault_share/models/vault_share.py:0 +msgid "The share was accessed by %(name)s via %(ip)s" +msgstr "" + +#. module: vault_share +#. odoo-python +#: code:addons/vault_share/models/vault_share.py:0 +msgid "The share was created by %(name)s" +msgstr "" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__token +msgid "Token" +msgstr "" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_vault_share__user_id +msgid "User" +msgstr "" + +#. module: vault_share +#: model:ir.model.fields,help:vault_share.field_vault_share__share_link +msgid "Using this link and pin people can access the secret." +msgstr "" + +#. module: vault_share +#. odoo-javascript +#: code:addons/vault_share/static/src/backend/fields/vault_pin_field.esm.js:0 +msgid "Vault Pin Field" +msgstr "" + +#. module: vault_share +#: model:ir.model.fields,field_description:vault_share.field_res_company__vault_share_delay +msgid "Vault Share Delay" +msgstr "" + +#. module: vault_share +#. odoo-javascript +#: code:addons/vault_share/static/src/backend/fields/vault_share_field.esm.js:0 +#: code:addons/vault_share/static/src/backend/fields/vault_share_file.esm.js:0 +msgid "Vault Share Field" +msgstr "" + +#. module: vault_share +#: model:ir.model,name:vault_share.model_vault_share_log +msgid "Vault share log" +msgstr "" + +#. module: vault_share +#: model:ir.model,name:vault_share.model_vault_share +msgid "Vault share outgoing secrets" +msgstr "" diff --git a/vault_share/migrations/20.0.1.0.0/pre-migration.py b/vault_share/migrations/20.0.1.0.0/pre-migration.py new file mode 100644 index 0000000000..004285a8e9 --- /dev/null +++ b/vault_share/migrations/20.0.1.0.0/pre-migration.py @@ -0,0 +1,19 @@ +# Copyright 2026 Tecnativa - Carlos Roca +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo.tools import SQL + +# The access rights and record rules were merged into ir.access in 20.0, keeping +# the same external ids. Remove the external ids still pointing to the old models +# so that they can be loaded again as ir.access records. +OLD_MODELS = ("ir.model.access", "ir.rule") + + +def migrate(cr, version): + cr.execute( + SQL( + "DELETE FROM ir_model_data WHERE module = %s AND model IN %s", + "vault_share", + OLD_MODELS, + ) + ) diff --git a/vault_share/models/__init__.py b/vault_share/models/__init__.py new file mode 100644 index 0000000000..e6b947e32a --- /dev/null +++ b/vault_share/models/__init__.py @@ -0,0 +1,4 @@ +# © 2021 Florian Kantelberg - initOS GmbH +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from . import res_company, res_config_settings, vault_share, vault_share_log diff --git a/vault_share/models/res_company.py b/vault_share/models/res_company.py new file mode 100644 index 0000000000..8eac8cd823 --- /dev/null +++ b/vault_share/models/res_company.py @@ -0,0 +1,10 @@ +# © 2021 Florian Kantelberg - initOS GmbH +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class RecCompany(models.Model): + _inherit = "res.company" + + vault_share_delay = fields.Integer(default=0) diff --git a/vault_share/models/res_config_settings.py b/vault_share/models/res_config_settings.py new file mode 100644 index 0000000000..4a69c1c18b --- /dev/null +++ b/vault_share/models/res_config_settings.py @@ -0,0 +1,24 @@ +# © 2021 Florian Kantelberg - initOS GmbH +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +import logging + +from odoo import api, fields, models + +_logger = logging.getLogger(__name__) + + +class ResConfigSettings(models.TransientModel): + _inherit = "res.config.settings" + + vault_share_delay = fields.Integer( + string="Delayed Deletion", + related="company_id.vault_share_delay", + readonly=False, + help="Delays the deletion of a share. After the expiration date it continues " + "to stay inaccessible", + ) + + @api.onchange("vault_share_delay") + def _onchange_vault_share_delay(self): + self.vault_share_delay = max(0, self.vault_share_delay) diff --git a/vault_share/models/vault_share.py b/vault_share/models/vault_share.py new file mode 100644 index 0000000000..8abfe86618 --- /dev/null +++ b/vault_share/models/vault_share.py @@ -0,0 +1,89 @@ +# © 2021 Florian Kantelberg - initOS GmbH +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +import logging +from datetime import timedelta +from uuid import uuid4 + +from odoo import api, fields, models + +_logger = logging.getLogger(__name__) + + +class VaultShare(models.Model): + _name = "vault.share" + _description = "Vault share outgoing secrets" + + user_id = fields.Many2one("res.users", default=lambda self: self.env.uid) + name = fields.Char(required=True) + share_link = fields.Char( + "Share URL", + compute="_compute_url", + store=False, + help="Using this link and pin people can access the secret.", + ) + token = fields.Char( + readonly=True, required=True, copy=False, default=lambda self: str(uuid4()) + ) + secret = fields.Char() + secret_file = fields.Char() + filename = fields.Char() + salt = fields.Char(required=True) + iterations = fields.Integer() + iv = fields.Char(required=True) + pin = fields.Char(required=True, help="The pin needed to decrypt the share.") + accesses = fields.Integer( + "Access counter", + default=5, + help="Specifies how often a share can be accessed before deletion.", + ) + expiration = fields.Datetime( + default=lambda self: fields.Datetime.now() + timedelta(days=7), + help="Specifies how long a share can be accessed until deletion.", + ) + log_ids = fields.One2many("vault.share.log", "share_id", readonly=True) + + _value_check = models.Constraint( + "CHECK(secret IS NOT NULL OR secret_file IS NOT NULL)", + "No value found", + ) + + @api.depends("token") + def _compute_url(self): + base_url = self.env["ir.config_parameter"].sudo().get_str("web.base.url") + for rec in self: + rec.share_link = ( + f"{base_url}/vault/share/{rec.token}" if rec.token else False + ) + + @api.model + def get(self, token, ip=None): + rec = self.search([("token", "=", token)], limit=1) + if not rec: + return rec + + if fields.Datetime.now() < rec.expiration and rec.accesses > 0: + rec.accesses -= 1 + log = self.env._( + "The share was accessed by %(name)s via %(ip)s", + name=self.env.user.name, + ip=ip or "n/a", + ) + rec.log_ids = [(0, 0, {"name": log})] + return rec + + return None + + @api.model_create_multi + def create(self, vals_list): + res = super().create(vals_list) + log = self.env._("The share was created by %(name)s", name=self.env.user.name) + for rec in res: + rec.log_ids = [(0, 0, {"name": log})] + return res + + @api.model + def clean(self): + now = fields.Datetime.now() + offset = timedelta(days=self.env.company.vault_share_delay) + self.search([("expiration", "<=", now + offset)]).unlink() diff --git a/vault_share/models/vault_share_log.py b/vault_share/models/vault_share_log.py new file mode 100644 index 0000000000..dc4126bca6 --- /dev/null +++ b/vault_share/models/vault_share_log.py @@ -0,0 +1,22 @@ +# © 2021 Florian Kantelberg - initOS GmbH +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +import logging + +from odoo import fields, models + +_logger = logging.getLogger(__name__) + + +class VaultShareLog(models.Model): + _name = "vault.share.log" + _description = "Vault share log" + _order = "create_date DESC" + + share_id = fields.Many2one( + "vault.share", + ondelete="cascade", + readonly=True, + required=True, + ) + name = fields.Char(readonly=True) diff --git a/vault_share/pyproject.toml b/vault_share/pyproject.toml new file mode 100644 index 0000000000..4231d0cccb --- /dev/null +++ b/vault_share/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/vault_share/readme/CONTRIBUTORS.md b/vault_share/readme/CONTRIBUTORS.md new file mode 100644 index 0000000000..5710e10104 --- /dev/null +++ b/vault_share/readme/CONTRIBUTORS.md @@ -0,0 +1 @@ +- Florian Kantelberg \ diff --git a/vault_share/readme/DESCRIPTION.md b/vault_share/readme/DESCRIPTION.md new file mode 100644 index 0000000000..5559e57d9e --- /dev/null +++ b/vault_share/readme/DESCRIPTION.md @@ -0,0 +1,15 @@ +This module implements possibilities to share specific secrets with +external users. This bases on the vault implementation and the generated +RSA key pair. + +## Share + +This allows an user to share a secret with external users. A share can +be generated from a vault entry or directly created by an user. The +secret is symmetrically encrypted by a key derived from a pin. To grant +access the user has to transmit the link and pin with the external. If +either the access counter reaches 0 or the share expires it will be +deleted automatically. Due to the usage of a numeric pin and the browser +side decryption a share is vulnerable to brute-force attacks and +shouldn't be used as a permanent storage for secrets. For long time uses +the user should create an account and a vault should be used. diff --git a/vault_share/readme/ROADMAP.md b/vault_share/readme/ROADMAP.md new file mode 100644 index 0000000000..8cf6f997c9 --- /dev/null +++ b/vault_share/readme/ROADMAP.md @@ -0,0 +1 @@ +- Secure the download of the encrypted file behind a challenge/response diff --git a/vault_share/security/ir.access.csv b/vault_share/security/ir.access.csv new file mode 100644 index 0000000000..be9a2a8b11 --- /dev/null +++ b/vault_share/security/ir.access.csv @@ -0,0 +1,5 @@ +id,name,model_id,group_id/id,operation,domain +access_vault_share,access_vault_share,vault.share,base.group_user,crud, +vault_share_owner,vault.share.access.owner,vault.share,,crud,"[('user_id', '=', user.id)]" +access_vault_share_log,access_vault_share_log,vault.share.log,base.group_user,crud, +vault_share_log_owner,vault.share.log.access.owner,vault.share.log,,crud,"[('share_id.user_id', '=', user.id)]" diff --git a/vault_share/static/description/icon.png b/vault_share/static/description/icon.png new file mode 100644 index 0000000000..d79aa6f575 Binary files /dev/null and b/vault_share/static/description/icon.png differ diff --git a/vault_share/static/description/index.html b/vault_share/static/description/index.html new file mode 100644 index 0000000000..4c1290604a --- /dev/null +++ b/vault_share/static/description/index.html @@ -0,0 +1,445 @@ + + + + + +Vault - Share + + + +
+ + + +Odoo Community Association + +
+

Vault - Share

+ +

Beta License: AGPL-3 OCA/server-auth Translate me on Weblate Try me on Runboat

+

This module implements possibilities to share specific secrets with +external users. This bases on the vault implementation and the generated +RSA key pair.

+
+

Share

+

This allows an user to share a secret with external users. A share can +be generated from a vault entry or directly created by an user. The +secret is symmetrically encrypted by a key derived from a pin. To grant +access the user has to transmit the link and pin with the external. If +either the access counter reaches 0 or the share expires it will be +deleted automatically. Due to the usage of a numeric pin and the browser +side decryption a share is vulnerable to brute-force attacks and +shouldn’t be used as a permanent storage for secrets. For long time uses +the user should create an account and a vault should be used.

+

Table of contents

+ +
+

Known issues / Roadmap

+
    +
  • Secure the download of the encrypted file behind a challenge/response
  • +
+
+
+

Bug Tracker

+

Bugs are tracked on GitHub 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.

+

Do not contact contributors directly about support or help with technical issues.

+
+ +
+
+

Authors

+
    +
  • initOS GmbH
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+ +Odoo Community Association + +

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.

+

This module is part of the OCA/server-auth project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + diff --git a/vault_share/static/src/backend/fields/templates.xml b/vault_share/static/src/backend/fields/templates.xml new file mode 100644 index 0000000000..85f022086b --- /dev/null +++ b/vault_share/static/src/backend/fields/templates.xml @@ -0,0 +1,45 @@ + + + + + !this.isNew + + + + + + this.isNew + + + + +
+ ******* +
+
+ + +
+
+ + + +