From 6078367b37609aa29c7ffba97ee7c5e95c54ef6e Mon Sep 17 00:00:00 2001 From: Janik von Rotz Date: Tue, 14 May 2024 16:39:54 +0200 Subject: [PATCH 01/24] Fix: move tenant id config step in readme --- auth_oidc/readme/CONFIGURE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/auth_oidc/readme/CONFIGURE.md b/auth_oidc/readme/CONFIGURE.md index 8145f4faf9..6e25411908 100644 --- a/auth_oidc/readme/CONFIGURE.md +++ b/auth_oidc/readme/CONFIGURE.md @@ -27,6 +27,7 @@ companies can use their AzureAD login without an guest account. - Client ID: Application (client) id - Client Secret: Client secret - Allowed: yes +- replace {tenant_id} in urls with your Azure tenant id or @@ -34,7 +35,6 @@ or - Client ID: Application (client) id - Client Secret: Client secret - Allowed: yes -- replace {tenant_id} in urls with your Azure tenant id ![image](../static/description/odoo-azure_ad_multitenant.png) From c79fe742893187d237a8691c2196bdac94e396ba Mon Sep 17 00:00:00 2001 From: Carlos Roca Date: Wed, 24 Jul 2024 12:35:43 +0200 Subject: [PATCH 02/24] [IMP] vault: Update value when input is decrypted Up until now, when a field was decrypted, making a change would cause it to be lost, which could confuse the user. After fixing this, it happened that discarding the changes made it seem like the change had not been discarded. The measure that has been taken is to, upon discarding, do as saving does: hide the value of the field, and the change remains in the input as long as it is not saved, discarded, or hidden. --- vault/static/src/backend/controller.esm.js | 7 +++++++ vault/static/src/backend/fields/vault_field.esm.js | 5 +++++ 2 files changed, 12 insertions(+) diff --git a/vault/static/src/backend/controller.esm.js b/vault/static/src/backend/controller.esm.js index d3f4b6c42e..0fb908f335 100644 --- a/vault/static/src/backend/controller.esm.js +++ b/vault/static/src/backend/controller.esm.js @@ -374,6 +374,13 @@ patch(FormController.prototype, "vault", { return await _super(...arguments); }, + async discard() { + const _super = this._super.bind(this); + if (this.model.root.resModel === "vault.entry") + this.model.env.bus.trigger("RELATIONAL_MODEL:ENCRYPT_FIELDS"); + return await _super(...arguments); + }, + async beforeLeave() { const _super = this._super.bind(this); if (this.model.root.isDirty) await this._vaultAction(); diff --git a/vault/static/src/backend/fields/vault_field.esm.js b/vault/static/src/backend/fields/vault_field.esm.js index a12deb9db8..84e9fc0a37 100644 --- a/vault/static/src/backend/fields/vault_field.esm.js +++ b/vault/static/src/backend/fields/vault_field.esm.js @@ -65,6 +65,10 @@ export default class VaultField extends VaultMixin(Component) { useBus(self.env.bus, "RELATIONAL_MODEL:NEED_LOCAL_CHANGES", (ev) => ev.detail.proms.push(self.commitChanges()) ); + useBus(self.env.bus, "RELATIONAL_MODEL:ENCRYPT_FIELDS", () => { + this.state.decrypted = false; + this.showValue(); + }); } /** @@ -174,6 +178,7 @@ export default class VaultField extends VaultMixin(Component) { const val = this.input.el.value || false; if (val !== (this.state.lastSetValue || false)) { this.state.lastSetValue = this.input.el.value; + this.state.decryptedValue = this.input.el.value; await this.storeValue(val); this.props.setDirty(this.state.isDirty); } From edc0a102757db4f05e98f93a62453d162f4e2e42 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Fri, 9 Aug 2024 08:53:20 +0000 Subject: [PATCH 03/24] [BOT] post-merge updates --- README.md | 2 +- vault/README.rst | 2 +- vault/__manifest__.py | 2 +- vault/static/description/index.html | 13 ++++++++----- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 80cd00f7d4..52150fcd07 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ addon | version | maintainers | summary [users_ldap_groups](users_ldap_groups/) | 16.0.1.0.0 | | Adds user accounts to groups based on rules defined by the administrator. [users_ldap_mail](users_ldap_mail/) | 16.0.1.0.0 | [![joao-p-marques](https://github.com/joao-p-marques.png?size=30px)](https://github.com/joao-p-marques) | LDAP mapping for user name and e-mail [users_ldap_populate](users_ldap_populate/) | 16.0.1.0.0 | [![joao-p-marques](https://github.com/joao-p-marques.png?size=30px)](https://github.com/joao-p-marques) | LDAP Populate -[vault](vault/) | 16.0.1.0.2 | | Password vault integration in Odoo +[vault](vault/) | 16.0.1.0.3 | | Password vault integration in Odoo [vault_share](vault_share/) | 16.0.1.0.0 | | Implementation of a mechanism to share secrets [//]: # (end addons) diff --git a/vault/README.rst b/vault/README.rst index 2ac024194b..678f6c098d 100644 --- a/vault/README.rst +++ b/vault/README.rst @@ -7,7 +7,7 @@ Vault !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:c9322b42a59c68d6b56c6ec7f7bd9118851f133923afec2e750b8631615ea1b7 + !! source digest: sha256:c0c446463d63752dc25080d52e0132ae87b0b43fd51edc7915ed1b919763b40e !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/vault/__manifest__.py b/vault/__manifest__.py index b036351bb6..188a58ed45 100644 --- a/vault/__manifest__.py +++ b/vault/__manifest__.py @@ -5,7 +5,7 @@ "name": "Vault", "summary": "Password vault integration in Odoo", "license": "AGPL-3", - "version": "16.0.1.0.2", + "version": "16.0.1.0.3", "website": "https://github.com/OCA/server-auth", "application": True, "author": "initOS GmbH, Odoo Community Association (OCA)", diff --git a/vault/static/description/index.html b/vault/static/description/index.html index da944b5581..fb80a5694f 100644 --- a/vault/static/description/index.html +++ b/vault/static/description/index.html @@ -8,10 +8,11 @@ /* :Author: David Goodger (goodger@python.org) -:Id: $Id: html4css1.css 8954 2022-01-20 10:10:25Z milde $ +: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. @@ -274,7 +275,7 @@ margin-left: 2em ; margin-right: 2em } -pre.code .ln { color: grey; } /* line numbers */ +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 } @@ -300,7 +301,7 @@ span.pre { white-space: pre } -span.problematic { +span.problematic, pre.problematic { color: red } span.section-subtitle { @@ -366,7 +367,7 @@

Vault

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:c9322b42a59c68d6b56c6ec7f7bd9118851f133923afec2e750b8631615ea1b7 +!! source digest: sha256:c0c446463d63752dc25080d52e0132ae87b0b43fd51edc7915ed1b919763b40e !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

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

This module implements a vault for secrets and files using end-to-end-encryption. The encryption and decryption happens in the browser using a vault specific shared master key. The master keys are encrypted using asymmetrically. For this the user has to enter a second password on the first login or if he needs to access data in a vault. The asymmetric keys are stored for a certain time in the browser storage.

@@ -437,7 +438,9 @@

Contributors

Maintainers

This module is maintained by the OCA.

-Odoo Community Association + +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.

From 149eba7d77c31019e9d058469050c35736d79bc9 Mon Sep 17 00:00:00 2001 From: mymage Date: Sat, 17 Aug 2024 16:16:53 +0000 Subject: [PATCH 04/24] Translated using Weblate (Italian) Currently translated at 100.0% (18 of 18 strings) Translation: server-auth-16.0/server-auth-16.0-auth_api_key Translate-URL: https://translation.odoo-community.org/projects/server-auth-16-0/server-auth-16-0-auth_api_key/it/ --- auth_api_key/i18n/it.po | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/auth_api_key/i18n/it.po b/auth_api_key/i18n/it.po index 47a977a578..2be7830419 100644 --- a/auth_api_key/i18n/it.po +++ b/auth_api_key/i18n/it.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 15.0\n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2024-07-18 06:52+0000\n" +"PO-Revision-Date: 2024-08-17 18:58+0000\n" "Last-Translator: mymage \n" "Language-Team: none\n" "Language: it\n" @@ -40,7 +40,7 @@ msgstr "Creato da" #. module: auth_api_key #: model:ir.model.fields,field_description:auth_api_key.field_auth_api_key__create_date msgid "Created on" -msgstr "Creata il" +msgstr "Creato il" #. module: auth_api_key #: model:ir.model.fields,field_description:auth_api_key.field_auth_api_key__display_name From 98a33a34a12360b03a93b696e33bbeb480e418c3 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Sun, 18 Aug 2024 12:23:30 +0000 Subject: [PATCH 05/24] [BOT] post-merge updates --- README.md | 2 +- auth_oidc/README.rst | 4 ++-- auth_oidc/__manifest__.py | 2 +- auth_oidc/static/description/index.html | 15 +++++++++------ 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 52150fcd07..819c5ac48a 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ addon | version | maintainers | summary [auth_ldaps](auth_ldaps/) | 16.0.1.0.0 | | Allows to use LDAP over SSL authentication [auth_oauth_multi_token](auth_oauth_multi_token/) | 16.0.1.0.0 | | Allow multiple connection with the same OAuth account [auth_oauth_ropc](auth_oauth_ropc/) | 16.0.1.0.0 | | Allow to login with OAuth Resource Owner Password Credentials Grant -[auth_oidc](auth_oidc/) | 16.0.1.2.0 | [![sbidoul](https://github.com/sbidoul.png?size=30px)](https://github.com/sbidoul) | Allow users to login through OpenID Connect Provider +[auth_oidc](auth_oidc/) | 16.0.1.2.1 | [![sbidoul](https://github.com/sbidoul.png?size=30px)](https://github.com/sbidoul) | Allow users to login through OpenID Connect Provider [auth_oidc_environment](auth_oidc_environment/) | 16.0.1.0.0 | | This module allows to use server env for OIDC configuration [auth_saml](auth_saml/) | 16.0.1.1.0 | [![vincent-hatakeyama](https://github.com/vincent-hatakeyama.png?size=30px)](https://github.com/vincent-hatakeyama) | SAML2 Authentication [auth_session_timeout](auth_session_timeout/) | 16.0.1.0.0 | | This module disable all inactive sessions since a given delay diff --git a/auth_oidc/README.rst b/auth_oidc/README.rst index 495caa673b..cbcd525dc2 100644 --- a/auth_oidc/README.rst +++ b/auth_oidc/README.rst @@ -7,7 +7,7 @@ Authentication OpenID Connect !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:0fa6d13be474eeb0ba5716895f4fc42ded1b84285279efbe29a476cead7e5565 + !! source digest: sha256:0151be3fa09ed3535a518b36fbf8bd9fa122f56d84180c1bc79a14ab9792dbbe !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png @@ -79,6 +79,7 @@ companies can use their AzureAD login without an guest account. - Client ID: Application (client) id - Client Secret: Client secret - Allowed: yes +- replace {tenant_id} in urls with your Azure tenant id or @@ -86,7 +87,6 @@ or - Client ID: Application (client) id - Client Secret: Client secret - Allowed: yes -- replace {tenant_id} in urls with your Azure tenant id |image2| diff --git a/auth_oidc/__manifest__.py b/auth_oidc/__manifest__.py index df9bdaac8a..3f1abf0c1d 100644 --- a/auth_oidc/__manifest__.py +++ b/auth_oidc/__manifest__.py @@ -4,7 +4,7 @@ { "name": "Authentication OpenID Connect", - "version": "16.0.1.2.0", + "version": "16.0.1.2.1", "license": "AGPL-3", "author": ( "ICTSTUDIO, André Schenkels, " diff --git a/auth_oidc/static/description/index.html b/auth_oidc/static/description/index.html index 46ba91854f..6b5283b2ed 100644 --- a/auth_oidc/static/description/index.html +++ b/auth_oidc/static/description/index.html @@ -8,10 +8,11 @@ /* :Author: David Goodger (goodger@python.org) -:Id: $Id: html4css1.css 8954 2022-01-20 10:10:25Z milde $ +: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. @@ -274,7 +275,7 @@ margin-left: 2em ; margin-right: 2em } -pre.code .ln { color: grey; } /* line numbers */ +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 } @@ -300,7 +301,7 @@ span.pre { white-space: pre } -span.problematic { +span.problematic, pre.problematic { color: red } span.section-subtitle { @@ -366,7 +367,7 @@

Authentication OpenID Connect

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:0fa6d13be474eeb0ba5716895f4fc42ded1b84285279efbe29a476cead7e5565 +!! source digest: sha256:0151be3fa09ed3535a518b36fbf8bd9fa122f56d84180c1bc79a14ab9792dbbe !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

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

This module allows users to login through an OpenID Connect provider @@ -437,6 +438,7 @@

Setup for Microsoft Azure

Client ID: Application (client) id
  • Client Secret: Client secret
  • Allowed: yes
  • +
  • replace {tenant_id} in urls with your Azure tenant id
  • or

      @@ -444,7 +446,6 @@

      Setup for Microsoft Azure

      Client ID: Application (client) id
    • Client Secret: Client secret
    • Allowed: yes
    • -
    • replace {tenant_id} in urls with your Azure tenant id

    image2

      @@ -579,7 +580,9 @@

      Contributors

      Maintainers

      This module is maintained by the OCA.

      -Odoo Community Association + +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.

      From 9feb331eb9c76edc1849341c806783dc199aaa12 Mon Sep 17 00:00:00 2001 From: Carlos Roca Date: Tue, 20 Aug 2024 07:49:47 +0200 Subject: [PATCH 06/24] [FIX] vault_share: Button to share value not showed and not working To show the button up, it is requiring a getter that is not defined on vault field. So the getter is added and make the button works correctly. Steps to reproduce the problem: 1. Go to Vault 2. Enter/Create a Vault 3. Press on entries 4. Access/Create a entry with a field The button with external link is not showed --- vault_share/static/src/backend/fields/vault_field.esm.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/vault_share/static/src/backend/fields/vault_field.esm.js b/vault_share/static/src/backend/fields/vault_field.esm.js index 57190388cb..574c1075c4 100644 --- a/vault_share/static/src/backend/fields/vault_field.esm.js +++ b/vault_share/static/src/backend/fields/vault_field.esm.js @@ -11,18 +11,22 @@ import vault from "vault"; // Extend the widget to share patch(VaultField.prototype, "vault_share", { + get shareButton() { + return this.props.value; + }, /** * Share the value for an external user * * @private */ - async _onShareValue() { + async _onShareValue(ev) { + ev.stopPropagation(); const iv = await utils.generate_iv_base64(); const pin = sh_utils.generate_pin(sh_utils.PinSize); const salt = utils.generate_bytes(utils.SaltLength).buffer; const key = await utils.derive_key(pin, salt, utils.Derive.iterations); const public_key = await vault.get_public_key(); - const value = await this._decrypt(this.value); + const value = await this._decrypt(this.props.value); this.action.doAction({ type: "ir.actions.act_window", From 2f13bb5260a3e7b76a093146ef3dce6150f9dab2 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Tue, 20 Aug 2024 06:13:16 +0000 Subject: [PATCH 07/24] [BOT] post-merge updates --- README.md | 2 +- vault_share/README.rst | 2 +- vault_share/__manifest__.py | 2 +- vault_share/static/description/index.html | 13 ++++++++----- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 819c5ac48a..637323ce37 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ addon | version | maintainers | summary [users_ldap_mail](users_ldap_mail/) | 16.0.1.0.0 | [![joao-p-marques](https://github.com/joao-p-marques.png?size=30px)](https://github.com/joao-p-marques) | LDAP mapping for user name and e-mail [users_ldap_populate](users_ldap_populate/) | 16.0.1.0.0 | [![joao-p-marques](https://github.com/joao-p-marques.png?size=30px)](https://github.com/joao-p-marques) | LDAP Populate [vault](vault/) | 16.0.1.0.3 | | Password vault integration in Odoo -[vault_share](vault_share/) | 16.0.1.0.0 | | Implementation of a mechanism to share secrets +[vault_share](vault_share/) | 16.0.1.0.1 | | Implementation of a mechanism to share secrets [//]: # (end addons) diff --git a/vault_share/README.rst b/vault_share/README.rst index 69390742a5..474f260840 100644 --- a/vault_share/README.rst +++ b/vault_share/README.rst @@ -7,7 +7,7 @@ Vault - Share !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:adce488b82d4097f6a7f94b8dfeb82712b9e717846f3cc745600419fc4393eed + !! source digest: sha256:4f783283b6bf81c2c6575a505ca9e6d9f5d0ea120a8c48b2d2921596e51956f6 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/vault_share/__manifest__.py b/vault_share/__manifest__.py index 7e05ea658a..ca57451111 100644 --- a/vault_share/__manifest__.py +++ b/vault_share/__manifest__.py @@ -5,7 +5,7 @@ "name": "Vault - Share", "summary": "Implementation of a mechanism to share secrets", "license": "AGPL-3", - "version": "16.0.1.0.0", + "version": "16.0.1.0.1", "website": "https://github.com/OCA/server-auth", "application": False, "author": "initOS GmbH, Odoo Community Association (OCA)", diff --git a/vault_share/static/description/index.html b/vault_share/static/description/index.html index 29d5221c0d..c537ea1195 100644 --- a/vault_share/static/description/index.html +++ b/vault_share/static/description/index.html @@ -8,10 +8,11 @@ /* :Author: David Goodger (goodger@python.org) -:Id: $Id: html4css1.css 8954 2022-01-20 10:10:25Z milde $ +: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. @@ -274,7 +275,7 @@ margin-left: 2em ; margin-right: 2em } -pre.code .ln { color: grey; } /* line numbers */ +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 } @@ -300,7 +301,7 @@ span.pre { white-space: pre } -span.problematic { +span.problematic, pre.problematic { color: red } span.section-subtitle { @@ -366,7 +367,7 @@

      Vault - Share

      !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:adce488b82d4097f6a7f94b8dfeb82712b9e717846f3cc745600419fc4393eed +!! source digest: sha256:4f783283b6bf81c2c6575a505ca9e6d9f5d0ea120a8c48b2d2921596e51956f6 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

      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.

      @@ -414,7 +415,9 @@

      Contributors

      Maintainers

      This module is maintained by the OCA.

      -Odoo Community Association + +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.

      From 58472e1a9c599ded5b8c496f8084fc704e2615df Mon Sep 17 00:00:00 2001 From: Kev-Roche Date: Tue, 14 May 2024 09:54:25 +0200 Subject: [PATCH 08/24] [14.0][ADD] impersonate_login --- impersonate_login/README.rst | 96 ++++ impersonate_login/__init__.py | 1 + impersonate_login/__manifest__.py | 30 ++ impersonate_login/models/__init__.py | 6 + impersonate_login/models/impersonate_log.py | 26 ++ impersonate_login/models/ir_http.py | 20 + impersonate_login/models/mail_message.py | 52 +++ impersonate_login/models/mail_thread.py | 30 ++ impersonate_login/models/model.py | 24 + impersonate_login/models/res_users.py | 87 ++++ impersonate_login/readme/CONTRIBUTORS.rst | 1 + impersonate_login/readme/DESCRIPTION.rst | 7 + impersonate_login/readme/USAGE.rst | 2 + impersonate_login/security/group.xml | 13 + .../security/ir.model.access.csv | 2 + .../static/description/index.html | 437 ++++++++++++++++++ impersonate_login/static/src/css/navbar.scss | 23 + .../static/src/js/abstract_web_client.js | 18 + impersonate_login/static/src/js/user_menu.js | 66 +++ .../static/src/xml/user_menu.xml | 22 + impersonate_login/views/assets.xml | 24 + impersonate_login/views/impersonate_log.xml | 36 ++ impersonate_login/views/res_users.xml | 22 + 23 files changed, 1045 insertions(+) create mode 100644 impersonate_login/README.rst create mode 100644 impersonate_login/__init__.py create mode 100644 impersonate_login/__manifest__.py create mode 100644 impersonate_login/models/__init__.py create mode 100644 impersonate_login/models/impersonate_log.py create mode 100644 impersonate_login/models/ir_http.py create mode 100644 impersonate_login/models/mail_message.py create mode 100644 impersonate_login/models/mail_thread.py create mode 100644 impersonate_login/models/model.py create mode 100644 impersonate_login/models/res_users.py create mode 100644 impersonate_login/readme/CONTRIBUTORS.rst create mode 100644 impersonate_login/readme/DESCRIPTION.rst create mode 100644 impersonate_login/readme/USAGE.rst create mode 100644 impersonate_login/security/group.xml create mode 100644 impersonate_login/security/ir.model.access.csv create mode 100644 impersonate_login/static/description/index.html create mode 100644 impersonate_login/static/src/css/navbar.scss create mode 100644 impersonate_login/static/src/js/abstract_web_client.js create mode 100644 impersonate_login/static/src/js/user_menu.js create mode 100644 impersonate_login/static/src/xml/user_menu.xml create mode 100644 impersonate_login/views/assets.xml create mode 100644 impersonate_login/views/impersonate_log.xml create mode 100644 impersonate_login/views/res_users.xml diff --git a/impersonate_login/README.rst b/impersonate_login/README.rst new file mode 100644 index 0000000000..5df334246f --- /dev/null +++ b/impersonate_login/README.rst @@ -0,0 +1,96 @@ +================= +Impersonate Login +================= + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:1fca331cbc5f2dcb804e5612e5669a9ab4998d80f22d46d6683266580f9ca40f + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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/licence-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/14.0/impersonate_login + :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-14-0/server-auth-14-0-impersonate_login + :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=14.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module allows to login as another user. +In the chatter, the user who is logged as another user is displayed. +The mails and messages are sent from the orignal user. +A table diplays the impersonated logins in technical. +The user can return to his own user by clicking on the button "Return to my user". +This module is very useful for the support team. +An alternative module will be auth_admin_passkey. + +**Table of contents** + +.. contents:: + :local: + +Usage +===== + +1. On the top right corner, click my user and "switch login" +2. Same place to "return to my login" + +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 +~~~~~~~ + +* Akretion + +Contributors +~~~~~~~~~~~~ + +* Kévin Roche + +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-Kev-Roche| image:: https://github.com/Kev-Roche.png?size=40px + :target: https://github.com/Kev-Roche + :alt: Kev-Roche + +Current `maintainer `__: + +|maintainer-Kev-Roche| + +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/impersonate_login/__init__.py b/impersonate_login/__init__.py new file mode 100644 index 0000000000..0650744f6b --- /dev/null +++ b/impersonate_login/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/impersonate_login/__manifest__.py b/impersonate_login/__manifest__.py new file mode 100644 index 0000000000..61c00eb90e --- /dev/null +++ b/impersonate_login/__manifest__.py @@ -0,0 +1,30 @@ +# Copyright 2024 Akretion (https://www.akretion.com). +# @author Kévin Roche +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +{ + "name": "Impersonate Login", + "summary": "tools", + "version": "14.0.1.0.0", + "category": "Tools", + "website": "https://github.com/OCA/server-auth", + "author": "Akretion, Odoo Community Association (OCA)", + "maintainers": ["Kev-Roche"], + "license": "AGPL-3", + "application": False, + "installable": True, + "depends": [ + "web", + "mail", + ], + "data": [ + "views/assets.xml", + "views/res_users.xml", + "views/impersonate_log.xml", + "security/group.xml", + "security/ir.model.access.csv", + ], + "qweb": [ + "static/src/xml/user_menu.xml", + ], +} diff --git a/impersonate_login/models/__init__.py b/impersonate_login/models/__init__.py new file mode 100644 index 0000000000..debb66e9c1 --- /dev/null +++ b/impersonate_login/models/__init__.py @@ -0,0 +1,6 @@ +from . import res_users +from . import ir_http +from . import mail_thread +from . import mail_message +from . import impersonate_log +from . import model diff --git a/impersonate_login/models/impersonate_log.py b/impersonate_login/models/impersonate_log.py new file mode 100644 index 0000000000..31ab131f63 --- /dev/null +++ b/impersonate_login/models/impersonate_log.py @@ -0,0 +1,26 @@ +# Copyright (C) 2024 Akretion (). +# @author Kévin Roche +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + + +from odoo import fields, models + + +class ImpersonateLog(models.Model): + _name = "impersonate.log" + _description = "Impersonate Logs" + + user_id = fields.Many2one( + comodel_name="res.partner", + string="User", + ) + impersonated_partner_id = fields.Many2one( + comodel_name="res.partner", + string="Logged as", + ) + date_start = fields.Datetime( + string="Start Date", + ) + date_end = fields.Datetime( + string="End Date", + ) diff --git a/impersonate_login/models/ir_http.py b/impersonate_login/models/ir_http.py new file mode 100644 index 0000000000..f01aa613d2 --- /dev/null +++ b/impersonate_login/models/ir_http.py @@ -0,0 +1,20 @@ +# Copyright (C) 2024 Akretion (). +# @author Kévin Roche +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import models +from odoo.http import request + + +class Http(models.AbstractModel): + _inherit = "ir.http" + + def session_info(self): + session_info = super().session_info() + session_info.update( + { + "is_impersonate_user": request.env.user._is_impersonate_user(), + "impersonate_from_uid": request.session.impersonate_from_uid, + } + ) + return session_info diff --git a/impersonate_login/models/mail_message.py b/impersonate_login/models/mail_message.py new file mode 100644 index 0000000000..332d117ee3 --- /dev/null +++ b/impersonate_login/models/mail_message.py @@ -0,0 +1,52 @@ +# Copyright (C) 2024 Akretion (). +# @author Kévin Roche +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import _, api, fields, models +from odoo.http import request + + +class Message(models.Model): + _inherit = "mail.message" + + impersonated_author_id = fields.Many2one( + comodel_name="res.partner", + string="Impersonated Author", + compute="_compute_impersonated_author_id", + store=True, + ) + + body = fields.Html( + compute="_compute_message_body", + store=True, + ) + + @api.depends("author_id") + def _compute_impersonated_author_id(self): + for rec in self: + if request and request.session.impersonate_from_uid: + rec.impersonated_author_id = ( + self.env["res.users"] + .browse(request.session.impersonate_from_uid) + .partner_id.id + ) + else: + rec.impersonated_author_id = False + + @api.depends("author_id", "impersonated_author_id") + def _compute_message_body(self): + for rec in self: + additional_info = "" + if ( + request + and request.session.impersonate_from_uid + and rec.impersonated_author_id + ): + current_partner = ( + self.env["res.users"].browse(request.session.uid).partner_id + ) + additional_info = _(f"Logged as {current_partner.name}") + if rec.body and additional_info: + rec.body = f"{additional_info}
      {rec.body}" + else: + rec.body = additional_info diff --git a/impersonate_login/models/mail_thread.py b/impersonate_login/models/mail_thread.py new file mode 100644 index 0000000000..1c1f80da83 --- /dev/null +++ b/impersonate_login/models/mail_thread.py @@ -0,0 +1,30 @@ +# Copyright (C) 2024 Akretion (). +# @author Kévin Roche +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import models +from odoo.http import request + + +class MailThread(models.AbstractModel): + _inherit = "mail.thread" + + def _message_compute_author( + self, author_id=None, email_from=None, raise_exception=True + ): + if ( + request + and request.session.impersonate_from_uid + and author_id in [request.session.uid, None] + ): + author = ( + self.env["res.users"] + .browse(request.session.impersonate_from_uid) + .partner_id + ) + email = author.email_formatted + return author.id, email + else: + return super()._message_compute_author( + author_id, email_from, raise_exception + ) diff --git a/impersonate_login/models/model.py b/impersonate_login/models/model.py new file mode 100644 index 0000000000..61f6e6655d --- /dev/null +++ b/impersonate_login/models/model.py @@ -0,0 +1,24 @@ +# Copyright (C) 2024 Akretion (). +# @author Kévin Roche +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import api, models +from odoo.http import request + + +class BaseModel(models.AbstractModel): + _inherit = "base" + + @api.model_create_multi + def _create(self, data_list): + res = super()._create(data_list) + if request and request.session.impersonate_from_uid: + for rec in res: + rec.create_uid = request.session.impersonate_from_uid + return res + + def write(self, vals): + res = super().write(vals) + if request and request.session.impersonate_from_uid: + self.write_uid = request.session.impersonate_from_uid + return res diff --git a/impersonate_login/models/res_users.py b/impersonate_login/models/res_users.py new file mode 100644 index 0000000000..f7e8cea4b0 --- /dev/null +++ b/impersonate_login/models/res_users.py @@ -0,0 +1,87 @@ +# Copyright 2024 Akretion (https://www.akretion.com). +# @author Kévin Roche +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +import logging + +from odoo import _, api, fields, models +from odoo.exceptions import UserError +from odoo.http import request +from odoo.service import security + +logger = logging.getLogger(__name__) + + +class Users(models.Model): + _inherit = "res.users" + + def _get_partner_name(self, user_id): + return self.env["res.users"].browse(user_id).partner_id.name + + def _is_impersonate_user(self): + self.ensure_one() + return self.has_group("impersonate_login.group_impersonate_login") + + def impersonate_login(self): + if request: + if request.session.impersonate_from_uid: + raise UserError(_("You are already Logged as another user.")) + if self.id == request.session.uid: + raise UserError(_("It's you.")) + if request.env.user._is_impersonate_user(): + target_uid = self.id + request.session.impersonate_from_uid = self._uid + request.session.uid = target_uid + impersonate_log = ( + self.env["impersonate.log"] + .sudo() + .create( + { + "user_id": self.env["res.users"] + .browse(self._uid) + .partner_id.id, + "impersonated_partner_id": self.env["res.users"] + .browse(target_uid) + .partner_id.id, + "date_start": fields.datetime.now(), + } + ) + ) + request.session.impersonate_log_id = impersonate_log.id + logger.info( + f"IMPERSONATE: {self._get_partner_name(self._uid)} " + f"Login as {self._get_partner_name(self.id)}" + ) + + request.env["res.users"].clear_caches() + request.session.session_token = security.compute_session_token( + request.session, request.env + ) + return { + "type": "ir.actions.client", + "tag": "reload", + } + + @api.model + def back_to_origin_login(self): + if request: + from_uid = request.session.impersonate_from_uid + if from_uid: + request.session.uid = from_uid + self.env["impersonate.log"].sudo().browse( + request.session.impersonate_log_id + ).write( + { + "date_end": fields.datetime.now(), + } + ) + request.env["res.users"].clear_caches() + request.session.impersonate_from_uid = False + request.session.impersonate_log_id = False + request.session.session_token = security.compute_session_token( + request.session, request.env + ) + logger.info( + f"IMPERSONATE: {self._get_partner_name(from_uid)} " + f"Logout as {self._get_partner_name(self._uid)}" + ) diff --git a/impersonate_login/readme/CONTRIBUTORS.rst b/impersonate_login/readme/CONTRIBUTORS.rst new file mode 100644 index 0000000000..dcae277c8c --- /dev/null +++ b/impersonate_login/readme/CONTRIBUTORS.rst @@ -0,0 +1 @@ +* Kévin Roche diff --git a/impersonate_login/readme/DESCRIPTION.rst b/impersonate_login/readme/DESCRIPTION.rst new file mode 100644 index 0000000000..7ffc13f484 --- /dev/null +++ b/impersonate_login/readme/DESCRIPTION.rst @@ -0,0 +1,7 @@ +This module allows to login as another user. +In the chatter, the user who is logged as another user is displayed. +The mails and messages are sent from the orignal user. +A table diplays the impersonated logins in technical. +The user can return to his own user by clicking on the button "Return to my user". +This module is very useful for the support team. +An alternative module will be auth_admin_passkey. diff --git a/impersonate_login/readme/USAGE.rst b/impersonate_login/readme/USAGE.rst new file mode 100644 index 0000000000..d0109247f9 --- /dev/null +++ b/impersonate_login/readme/USAGE.rst @@ -0,0 +1,2 @@ +1. On the top right corner, click my user and "switch login" +2. Same place to "return to my login" diff --git a/impersonate_login/security/group.xml b/impersonate_login/security/group.xml new file mode 100644 index 0000000000..e996175066 --- /dev/null +++ b/impersonate_login/security/group.xml @@ -0,0 +1,13 @@ + + + + + Impersonate Users + + + diff --git a/impersonate_login/security/ir.model.access.csv b/impersonate_login/security/ir.model.access.csv new file mode 100644 index 0000000000..3a5c10c53d --- /dev/null +++ b/impersonate_login/security/ir.model.access.csv @@ -0,0 +1,2 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_impersonate_log,impersonate logs,model_impersonate_log,base.group_user,1,1,0,0 diff --git a/impersonate_login/static/description/index.html b/impersonate_login/static/description/index.html new file mode 100644 index 0000000000..f56e86fcd8 --- /dev/null +++ b/impersonate_login/static/description/index.html @@ -0,0 +1,437 @@ + + + + + + +Impersonate Login + + + +
      +

      Impersonate Login

      + + +

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

      +

      This module allows to login as another user. +In the chatter, the user who is logged as another user is displayed. +The mails and messages are sent from the orignal user. +A table diplays the impersonated logins in technical. +The user can return to his own user by clicking on the button “Return to my user”. +This module is very useful for the support team. +An alternative module will be auth_admin_passkey.

      +

      Table of contents

      + +
      +

      Usage

      +
        +
      1. On the top right corner, click my user and “switch login”
      2. +
      3. Same place to “return to my login”
      4. +
      +
      +
      +

      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

      +
        +
      • Akretion
      • +
      +
      +
      +

      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.

      +

      Current maintainer:

      +

      Kev-Roche

      +

      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/impersonate_login/static/src/css/navbar.scss b/impersonate_login/static/src/css/navbar.scss new file mode 100644 index 0000000000..556a38a5ee --- /dev/null +++ b/impersonate_login/static/src/css/navbar.scss @@ -0,0 +1,23 @@ +body.o_is_impersonated .o_menu_systray { + background: repeating-linear-gradient( + 135deg, + #32d804, + #32d804 10px, + #373435 10px, + #373435 20px + ); + border-bottom-left-radius: 20px; + + > li { + > a, + > label { + &:hover { + background-color: fade_out($o-navbar-inverse-link-hover-bg, 0.5); + } + } + } + + .show .dropdown-toggle { + background-color: fade_out($o-navbar-inverse-link-hover-bg, 0.5); + } +} diff --git a/impersonate_login/static/src/js/abstract_web_client.js b/impersonate_login/static/src/js/abstract_web_client.js new file mode 100644 index 0000000000..1c3ef6d444 --- /dev/null +++ b/impersonate_login/static/src/js/abstract_web_client.js @@ -0,0 +1,18 @@ +// Copyright 2024 Akretion (https://www.akretion.com). +// @author Kévin Roche +// License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +odoo.define("impersonate_login.AbstractWebClient", function (require) { + "use strict"; + + var AbstractWebClient = require("web.AbstractWebClient"); + var session = require("web.session"); + + AbstractWebClient.include({ + _onWebClientStarted: function () { + this._super.apply(this, arguments); + if (session.impersonate_from_uid) { + this.$el.addClass("o_is_impersonated"); + } + }, + }); +}); diff --git a/impersonate_login/static/src/js/user_menu.js b/impersonate_login/static/src/js/user_menu.js new file mode 100644 index 0000000000..ad3672ac1b --- /dev/null +++ b/impersonate_login/static/src/js/user_menu.js @@ -0,0 +1,66 @@ +// Copyright 2024 Akretion (https://www.akretion.com). +// @author Kévin Roche +// License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +odoo.define("impersonate_login.UserMenu", function (require) { + "use strict"; + + var UserMenu = require("web.UserMenu"); + var core = require("web.core"); + var session = require("web.session"); + var _t = core._t; + + UserMenu.include({ + start: function () { + this.toggleImpersonationLinks(); + return this._super.apply(this, arguments); + }, + + _onMenuImpersonate: function () { + var self = this; + this._rpc({ + model: "ir.model.data", + method: "xmlid_to_res_model_res_id", + args: ["impersonate_login.impersonate_res_users_tree"], + }).then(function (data) { + self.do_action({ + type: "ir.actions.act_window", + name: _t("Users"), + res_model: "res.users", + target: "new", + view_mode: "list", + views: [[data[1], "list"]], + domain: [["share", "=", false]], + }); + }); + }, + + _onMenuOrigin_login: function () { + var self = this; + return self + ._rpc({ + model: "res.users", + method: "back_to_origin_login", + args: [], + }) + .then(function () { + location.reload(true); + }); + }, + + toggleImpersonationLinks: function () { + var returnToLogin = this.$('[data-menu="origin_login"]'); + var impersonateLogin = this.$('[data-menu="impersonate"]'); + if (session.impersonate_from_uid) { + returnToLogin.removeClass("d-none"); + impersonateLogin.addClass("d-none"); + } else if (session.is_impersonate_user) { + returnToLogin.addClass("d-none"); + impersonateLogin.removeClass("d-none"); + } else { + returnToLogin.addClass("d-none"); + impersonateLogin.addClass("d-none"); + } + }, + }); +}); diff --git a/impersonate_login/static/src/xml/user_menu.xml b/impersonate_login/static/src/xml/user_menu.xml new file mode 100644 index 0000000000..bce12c050c --- /dev/null +++ b/impersonate_login/static/src/xml/user_menu.xml @@ -0,0 +1,22 @@ + + + + + + 🔙 To my Login + 🔄 Switch Login + + + diff --git a/impersonate_login/views/assets.xml b/impersonate_login/views/assets.xml new file mode 100644 index 0000000000..cf15b77905 --- /dev/null +++ b/impersonate_login/views/assets.xml @@ -0,0 +1,24 @@ + + +