Public release from ruodoo-project: 19.0 - 2026-05-10 21:19:01 UTC
This commit is contained in:
27
access_restricted/README.rst
Normal file
27
access_restricted/README.rst
Normal file
@ -0,0 +1,27 @@
|
||||
.. image:: https://itpp.dev/images/infinity-readme.png
|
||||
:alt: Tested and maintained by IT Projects Labs
|
||||
:target: https://itpp.dev
|
||||
|
||||
Restricted administration rights
|
||||
================================
|
||||
|
||||
The module makes impossible for administrator to set (and see) more access rights (groups) than he already has.
|
||||
The only partial exception of this rule is made if you are already a member of the *Allow add implied groups from settings* security group.
|
||||
Then you are allowed to escalate your privileges but just from ``Settings`` menus (by means of ``group_XXX`` boolean fields of ``res.config.settings`` models views).
|
||||
|
||||
This doesn't affect superuser, of course.
|
||||
|
||||
Typical usage of the module
|
||||
===========================
|
||||
|
||||
The superuser creates an administrator user without access group "Show Apps Menu" (see **access_apps** module). Then the administrator has access to settings, but not able to install new apps (without this module he can add himself to "Show Apps Menu" and get access to apps).
|
||||
|
||||
Roadmap
|
||||
=======
|
||||
|
||||
* Settings menu shows group fields are not updated without *Allow add implied groups from settings* (ok), but it shows the fields as not editable (not ok)
|
||||
|
||||
Further information
|
||||
===================
|
||||
|
||||
Tested on `Odoo 17.0 <https://github.com/odoo/odoo/commit/40b19d89846303016098840f4958fe7cc105067c>`_
|
||||
1
access_restricted/__init__.py
Normal file
1
access_restricted/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
from . import models
|
||||
15
access_restricted/__manifest__.py
Normal file
15
access_restricted/__manifest__.py
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "Restricted administration rights",
|
||||
"summary": "Apply strict restriction on what an admin can do",
|
||||
"version": "19.0.1.3.5",
|
||||
"author": "IT-Projects LLC, Ivan Yelizariev",
|
||||
"category": "Extra Tools",
|
||||
"images": ["images/banner.jpg"],
|
||||
"support": "apps@itpp.dev",
|
||||
"website": "https://twitter.com/OdooFree",
|
||||
"license": "Other OSI approved licence", # MIT
|
||||
"currency": "EUR",
|
||||
"depends": ["ir_rule_protected"],
|
||||
"data": ["security/access_restricted_security.xml"],
|
||||
"installable": True,
|
||||
}
|
||||
50
access_restricted/doc/changelog.rst
Normal file
50
access_restricted/doc/changelog.rst
Normal file
@ -0,0 +1,50 @@
|
||||
`1.3.5`
|
||||
-------
|
||||
|
||||
- **Fix:** Fixed possibility to write inappropriate groups directly via write method after some odoo updates https://github.com/odoo/odoo/commit/5f12e244f6e57b8edb56788147774150e2ae134d
|
||||
|
||||
`1.3.4`
|
||||
-------
|
||||
|
||||
- **Fix:** Allow superuser to write groups via settings menu
|
||||
|
||||
`1.3.3`
|
||||
-------
|
||||
|
||||
- **Fix:** If no permission to add groups then just ignore write operations to groups model records but apply any other valid settings. In other words - do not block rest of the settings from applying if there is only no permission to add groups
|
||||
|
||||
`1.3.2`
|
||||
-------
|
||||
|
||||
- **Fix:** regardless of ``Allow add implied groups from settings`` always allow to uncheck **group_XXX** fields from settings menu. This makes possible for ``access_apps`` module to independently install apps from settings menu. Otherwise users of ``access_apps`` need always be in ``Allow add implied...`` to install from settings
|
||||
|
||||
`1.3.1`
|
||||
-------
|
||||
|
||||
- **Fix:** a user, if he has ``Allow add implied groups from settings`` group access right, should be able to uncheck **group_XXX** fields from a settings menu to exit from implied groups (all other users that are in implying group also quit from the implied group)
|
||||
|
||||
`1.3.0`
|
||||
-------
|
||||
|
||||
- [ADD] security group that allows increasing rights from settings menu (by checking ``res.config.settings`` 'group_XXX' boolean fields)
|
||||
|
||||
`1.2.0`
|
||||
-------
|
||||
|
||||
- [REF] clean and simplify code
|
||||
|
||||
`1.1.0`
|
||||
-------
|
||||
|
||||
- ADD: Make restricted groups readonly in Settigs pages (res.config.settings)
|
||||
- ADD: don't restrict access to Technical Settings group
|
||||
|
||||
`1.0.1`
|
||||
-------
|
||||
|
||||
- FIX: update to the latest odoo 9.0 version due to this comit from Mar 24, 2016 https://github.com/odoo/odoo/commit/40a299c580c4608edab8781fda4e66f39611543b
|
||||
|
||||
`1.0.0`
|
||||
-------
|
||||
|
||||
- init version
|
||||
37
access_restricted/doc/index.rst
Normal file
37
access_restricted/doc/index.rst
Normal file
@ -0,0 +1,37 @@
|
||||
==================================
|
||||
Restricted administration rights
|
||||
==================================
|
||||
|
||||
Installation
|
||||
============
|
||||
|
||||
* `Install <https://odoo-development.readthedocs.io/en/latest/odoo/usage/install-module.html>`__ this module in a usual way
|
||||
|
||||
Configuration
|
||||
=============
|
||||
|
||||
|
||||
* `Log in as SUPERUSER <https://odoo-development.readthedocs.io/en/latest/odoo/usage/login-as-superuser.html>`__
|
||||
* Navigate to menu ``[[ Settings ]] >> Users & Companies >> Users``
|
||||
* In ``Access Rights`` tab you can select *Allow add implied groups from settings*:
|
||||
it allows a user to configure groups via ``group_XXX`` fields from ``Settings`` menu.
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
By default all users except a superuser restricted to escalate the privileges.
|
||||
|
||||
Let's take ``Sales (sale_management)`` module as an example.
|
||||
|
||||
Without this module installed:
|
||||
|
||||
* Say you have a user with administration rights ``Administration: Access Rights``. This user thus may increase his own rights in ``Application Accesses`` from ``Sales: User: Own Documents Only``
|
||||
to ``Sales: Administrator``. Also he can open menu ``[[ Sales ]] >> Configuration >> Settings`` and select ``Customer Addresses`` there
|
||||
and then click ``[Apply]`` button (adding ``group_sale_delivery_address``)
|
||||
|
||||
With this module installed:
|
||||
|
||||
* The user from previous example cannot increase his privileges. There is no ``Sales: Manager`` option for him, and also no ``Customer Addresses``
|
||||
option in module configuration
|
||||
* The only exception is done for users who are in special group *Allow add implied groups from settings*: if your user is included in this group by the superuser then you may select
|
||||
``Customer Addresses`` from ``Sale`` module ``Configuration >> Settings`` menu
|
||||
94
access_restricted/i18n/access_restricted.pot
Normal file
94
access_restricted/i18n/access_restricted.pot
Normal file
@ -0,0 +1,94 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * access_restricted
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 12.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: access_restricted
|
||||
#: code:addons/access_restricted/models/res_config_settings.py:48
|
||||
#, python-format
|
||||
msgid "\n"
|
||||
"\n"
|
||||
"You don't have access to change this settings, because you administration rights are restricted"
|
||||
msgstr ""
|
||||
|
||||
#. module: access_restricted
|
||||
#: model:ir.model,name:access_restricted.model_res_groups
|
||||
msgid "Access Groups"
|
||||
msgstr ""
|
||||
|
||||
#. module: access_restricted
|
||||
#: model:res.groups,name:access_restricted.group_allow_add_implied_from_settings
|
||||
msgid "Allow add implied groups from settings"
|
||||
msgstr ""
|
||||
|
||||
#. module: access_restricted
|
||||
#: model:ir.model,name:access_restricted.model_res_config_settings
|
||||
msgid "Config Settings"
|
||||
msgstr ""
|
||||
|
||||
#. module: access_restricted
|
||||
#: model:ir.model.fields,field_description:access_restricted.field_test_config_settings__create_uid
|
||||
msgid "Created by"
|
||||
msgstr ""
|
||||
|
||||
#. module: access_restricted
|
||||
#: model:ir.model.fields,field_description:access_restricted.field_test_config_settings__create_date
|
||||
msgid "Created on"
|
||||
msgstr ""
|
||||
|
||||
#. module: access_restricted
|
||||
#: model:ir.model.fields,field_description:access_restricted.field_test_config_settings__display_name
|
||||
msgid "Display Name"
|
||||
msgstr ""
|
||||
|
||||
#. module: access_restricted
|
||||
#: model:ir.model.fields,field_description:access_restricted.field_test_config_settings__group_private_addresses
|
||||
msgid "Group Private Addresses"
|
||||
msgstr ""
|
||||
|
||||
#. module: access_restricted
|
||||
#: model:ir.model.fields,field_description:access_restricted.field_test_config_settings__id
|
||||
msgid "ID"
|
||||
msgstr ""
|
||||
|
||||
#. module: access_restricted
|
||||
#: model:ir.model.fields,field_description:access_restricted.field_test_config_settings____last_update
|
||||
msgid "Last Modified on"
|
||||
msgstr ""
|
||||
|
||||
#. module: access_restricted
|
||||
#: model:ir.model.fields,field_description:access_restricted.field_test_config_settings__write_uid
|
||||
msgid "Last Updated by"
|
||||
msgstr ""
|
||||
|
||||
#. module: access_restricted
|
||||
#: model:ir.model.fields,field_description:access_restricted.field_test_config_settings__write_date
|
||||
msgid "Last Updated on"
|
||||
msgstr ""
|
||||
|
||||
#. module: access_restricted
|
||||
#: model:ir.model,name:access_restricted.model_res_users
|
||||
msgid "Users"
|
||||
msgstr ""
|
||||
|
||||
#. module: access_restricted
|
||||
#: code:addons/access_restricted/models/res_users.py:95
|
||||
#, python-format
|
||||
msgid "You cannot add groups to Implied groups, because you are not allowed to increase your rights. Please contact your system administrator."
|
||||
msgstr ""
|
||||
|
||||
#. module: access_restricted
|
||||
#: model:ir.model,name:access_restricted.model_test_config_settings
|
||||
msgid "test.config.settings"
|
||||
msgstr ""
|
||||
|
||||
105
access_restricted/i18n/de.po
Normal file
105
access_restricted/i18n/de.po
Normal file
@ -0,0 +1,105 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * access_restricted
|
||||
#
|
||||
# Translators:
|
||||
# Sergej Briesin <20bs18@gmail.com>, 2018
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 11.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2018-04-21 00:17+0000\n"
|
||||
"PO-Revision-Date: 2018-04-21 00:17+0000\n"
|
||||
"Last-Translator: Sergej Briesin <20bs18@gmail.com>, 2018\n"
|
||||
"Language-Team: German (https://www.transifex.com/it-projects-llc/teams/76080/"
|
||||
"de/)\n"
|
||||
"Language: de\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"
|
||||
|
||||
#. module: access_restricted
|
||||
#: code:addons/access_restricted/models/res_config_settings.py:48
|
||||
#, python-format
|
||||
msgid ""
|
||||
"\n"
|
||||
"\n"
|
||||
"You don't have access to change this settings, because you administration "
|
||||
"rights are restricted"
|
||||
msgstr ""
|
||||
|
||||
#. module: access_restricted
|
||||
#: model:ir.model,name:access_restricted.model_res_groups
|
||||
msgid "Access Groups"
|
||||
msgstr ""
|
||||
|
||||
#. module: access_restricted
|
||||
#: model:res.groups,name:access_restricted.group_allow_add_implied_from_settings
|
||||
msgid "Allow add implied groups from settings"
|
||||
msgstr ""
|
||||
|
||||
#. module: access_restricted
|
||||
#: model:ir.model,name:access_restricted.model_res_config_settings
|
||||
msgid "Config Settings"
|
||||
msgstr ""
|
||||
|
||||
#. module: access_restricted
|
||||
#: model:ir.model.fields,field_description:access_restricted.field_test_config_settings__create_uid
|
||||
msgid "Created by"
|
||||
msgstr ""
|
||||
|
||||
#. module: access_restricted
|
||||
#: model:ir.model.fields,field_description:access_restricted.field_test_config_settings__create_date
|
||||
msgid "Created on"
|
||||
msgstr ""
|
||||
|
||||
#. module: access_restricted
|
||||
#: model:ir.model.fields,field_description:access_restricted.field_test_config_settings__display_name
|
||||
msgid "Display Name"
|
||||
msgstr ""
|
||||
|
||||
#. module: access_restricted
|
||||
#: model:ir.model.fields,field_description:access_restricted.field_test_config_settings__group_private_addresses
|
||||
msgid "Group Private Addresses"
|
||||
msgstr ""
|
||||
|
||||
#. module: access_restricted
|
||||
#: model:ir.model.fields,field_description:access_restricted.field_test_config_settings__id
|
||||
msgid "ID"
|
||||
msgstr ""
|
||||
|
||||
#. module: access_restricted
|
||||
#: model:ir.model.fields,field_description:access_restricted.field_test_config_settings____last_update
|
||||
msgid "Last Modified on"
|
||||
msgstr ""
|
||||
|
||||
#. module: access_restricted
|
||||
#: model:ir.model.fields,field_description:access_restricted.field_test_config_settings__write_uid
|
||||
msgid "Last Updated by"
|
||||
msgstr ""
|
||||
|
||||
#. module: access_restricted
|
||||
#: model:ir.model.fields,field_description:access_restricted.field_test_config_settings__write_date
|
||||
msgid "Last Updated on"
|
||||
msgstr ""
|
||||
|
||||
#. module: access_restricted
|
||||
#: code:addons/access_restricted/models/res_users.py:95
|
||||
#, python-format
|
||||
msgid ""
|
||||
"The requested operation cannot be completed due to security restrictions. "
|
||||
"Please contact your system administrator.\n"
|
||||
"\n"
|
||||
"(Document type: %s, Operation: %s)"
|
||||
msgstr ""
|
||||
|
||||
#. module: access_restricted
|
||||
#: model:ir.model,name:access_restricted.model_res_users
|
||||
msgid "Users"
|
||||
msgstr "Nutzer"
|
||||
|
||||
#. module: access_restricted
|
||||
#: model:ir.model,name:access_restricted.model_test_config_settings
|
||||
msgid "test.config.settings"
|
||||
msgstr ""
|
||||
105
access_restricted/i18n/es.po
Normal file
105
access_restricted/i18n/es.po
Normal file
@ -0,0 +1,105 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * access_restricted
|
||||
#
|
||||
# Translators:
|
||||
# charles paul requena palomino <rcharles84@gmail.com>, 2018
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 10.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2018-04-26 19:17+0000\n"
|
||||
"PO-Revision-Date: 2018-04-26 19:17+0000\n"
|
||||
"Last-Translator: charles paul requena palomino <rcharles84@gmail.com>, 2018\n"
|
||||
"Language-Team: Spanish (https://www.transifex.com/it-projects-llc/"
|
||||
"teams/76080/es/)\n"
|
||||
"Language: es\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"
|
||||
|
||||
#. module: access_restricted
|
||||
#: code:addons/access_restricted/models/res_config_settings.py:48
|
||||
#, python-format
|
||||
msgid ""
|
||||
"\n"
|
||||
"\n"
|
||||
"You don't have access to change this settings, because you administration "
|
||||
"rights are restricted"
|
||||
msgstr ""
|
||||
|
||||
#. module: access_restricted
|
||||
#: model:ir.model,name:access_restricted.model_res_groups
|
||||
msgid "Access Groups"
|
||||
msgstr "Grupos de acceso"
|
||||
|
||||
#. module: access_restricted
|
||||
#: model:res.groups,name:access_restricted.group_allow_add_implied_from_settings
|
||||
msgid "Allow add implied groups from settings"
|
||||
msgstr ""
|
||||
|
||||
#. module: access_restricted
|
||||
#: model:ir.model,name:access_restricted.model_res_config_settings
|
||||
msgid "Config Settings"
|
||||
msgstr ""
|
||||
|
||||
#. module: access_restricted
|
||||
#: model:ir.model.fields,field_description:access_restricted.field_test_config_settings__create_uid
|
||||
msgid "Created by"
|
||||
msgstr "Creado por"
|
||||
|
||||
#. module: access_restricted
|
||||
#: model:ir.model.fields,field_description:access_restricted.field_test_config_settings__create_date
|
||||
msgid "Created on"
|
||||
msgstr "Creado en"
|
||||
|
||||
#. module: access_restricted
|
||||
#: model:ir.model.fields,field_description:access_restricted.field_test_config_settings__display_name
|
||||
msgid "Display Name"
|
||||
msgstr "Nombre para mostrar"
|
||||
|
||||
#. module: access_restricted
|
||||
#: model:ir.model.fields,field_description:access_restricted.field_test_config_settings__group_private_addresses
|
||||
msgid "Group Private Addresses"
|
||||
msgstr ""
|
||||
|
||||
#. module: access_restricted
|
||||
#: model:ir.model.fields,field_description:access_restricted.field_test_config_settings__id
|
||||
msgid "ID"
|
||||
msgstr "ID"
|
||||
|
||||
#. module: access_restricted
|
||||
#: model:ir.model.fields,field_description:access_restricted.field_test_config_settings____last_update
|
||||
msgid "Last Modified on"
|
||||
msgstr "Última modificación en"
|
||||
|
||||
#. module: access_restricted
|
||||
#: model:ir.model.fields,field_description:access_restricted.field_test_config_settings__write_uid
|
||||
msgid "Last Updated by"
|
||||
msgstr "Última actualización por"
|
||||
|
||||
#. module: access_restricted
|
||||
#: model:ir.model.fields,field_description:access_restricted.field_test_config_settings__write_date
|
||||
msgid "Last Updated on"
|
||||
msgstr "Ultima actualizacion en"
|
||||
|
||||
#. module: access_restricted
|
||||
#: code:addons/access_restricted/models/res_users.py:95
|
||||
#, python-format
|
||||
msgid ""
|
||||
"The requested operation cannot be completed due to security restrictions. "
|
||||
"Please contact your system administrator.\n"
|
||||
"\n"
|
||||
"(Document type: %s, Operation: %s)"
|
||||
msgstr ""
|
||||
|
||||
#. module: access_restricted
|
||||
#: model:ir.model,name:access_restricted.model_res_users
|
||||
msgid "Users"
|
||||
msgstr ""
|
||||
|
||||
#. module: access_restricted
|
||||
#: model:ir.model,name:access_restricted.model_test_config_settings
|
||||
msgid "test.config.settings"
|
||||
msgstr ""
|
||||
114
access_restricted/i18n/es_CR.po
Normal file
114
access_restricted/i18n/es_CR.po
Normal file
@ -0,0 +1,114 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * access_restricted
|
||||
#
|
||||
# Translators:
|
||||
# Randall <randall_castro@me.com>, 2018
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 11.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2018-04-21 00:17+0000\n"
|
||||
"PO-Revision-Date: 2017-11-28 13:02+0000\n"
|
||||
"Last-Translator: Randall <randall_castro@me.com>, 2018\n"
|
||||
"Language-Team: Spanish (Costa Rica) (https://www.transifex.com/it-projects-"
|
||||
"llc/teams/76080/es_CR/)\n"
|
||||
"Language: es_CR\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"
|
||||
|
||||
#. module: access_restricted
|
||||
#: code:addons/access_restricted/models/res_config_settings.py:48
|
||||
#, python-format
|
||||
msgid ""
|
||||
"\n"
|
||||
"\n"
|
||||
"You don't have access to change this settings, because you administration "
|
||||
"rights are restricted"
|
||||
msgstr ""
|
||||
"\n"
|
||||
"\n"
|
||||
"No tiene acceso para cambiar esta configuración, ya que los derechos de "
|
||||
"administración están restringidos."
|
||||
|
||||
#. module: access_restricted
|
||||
#: model:ir.model,name:access_restricted.model_res_groups
|
||||
msgid "Access Groups"
|
||||
msgstr "Grupos de Accesos"
|
||||
|
||||
#. module: access_restricted
|
||||
#: model:res.groups,name:access_restricted.group_allow_add_implied_from_settings
|
||||
msgid "Allow add implied groups from settings"
|
||||
msgstr "Permitir agregar grupos implícitos desde la configuración"
|
||||
|
||||
#. module: access_restricted
|
||||
#: model:ir.model,name:access_restricted.model_res_config_settings
|
||||
#, fuzzy
|
||||
msgid "Config Settings"
|
||||
msgstr "res.config.settings"
|
||||
|
||||
#. module: access_restricted
|
||||
#: model:ir.model.fields,field_description:access_restricted.field_test_config_settings__create_uid
|
||||
msgid "Created by"
|
||||
msgstr "Creado por"
|
||||
|
||||
#. module: access_restricted
|
||||
#: model:ir.model.fields,field_description:access_restricted.field_test_config_settings__create_date
|
||||
msgid "Created on"
|
||||
msgstr "Creado en"
|
||||
|
||||
#. module: access_restricted
|
||||
#: model:ir.model.fields,field_description:access_restricted.field_test_config_settings__display_name
|
||||
msgid "Display Name"
|
||||
msgstr "Mostrar Nombre"
|
||||
|
||||
#. module: access_restricted
|
||||
#: model:ir.model.fields,field_description:access_restricted.field_test_config_settings__group_private_addresses
|
||||
msgid "Group Private Addresses"
|
||||
msgstr ""
|
||||
|
||||
#. module: access_restricted
|
||||
#: model:ir.model.fields,field_description:access_restricted.field_test_config_settings__id
|
||||
msgid "ID"
|
||||
msgstr "ID"
|
||||
|
||||
#. module: access_restricted
|
||||
#: model:ir.model.fields,field_description:access_restricted.field_test_config_settings____last_update
|
||||
msgid "Last Modified on"
|
||||
msgstr "Última modificación el"
|
||||
|
||||
#. module: access_restricted
|
||||
#: model:ir.model.fields,field_description:access_restricted.field_test_config_settings__write_uid
|
||||
msgid "Last Updated by"
|
||||
msgstr "Última actualización por"
|
||||
|
||||
#. module: access_restricted
|
||||
#: model:ir.model.fields,field_description:access_restricted.field_test_config_settings__write_date
|
||||
msgid "Last Updated on"
|
||||
msgstr "Última actualización en "
|
||||
|
||||
#. module: access_restricted
|
||||
#: code:addons/access_restricted/models/res_users.py:95
|
||||
#, python-format
|
||||
msgid ""
|
||||
"The requested operation cannot be completed due to security restrictions. "
|
||||
"Please contact your system administrator.\n"
|
||||
"\n"
|
||||
"(Document type: %s, Operation: %s)"
|
||||
msgstr ""
|
||||
|
||||
#. module: access_restricted
|
||||
#: model:ir.model,name:access_restricted.model_res_users
|
||||
msgid "Users"
|
||||
msgstr "Usuarios"
|
||||
|
||||
#. module: access_restricted
|
||||
#: model:ir.model,name:access_restricted.model_test_config_settings
|
||||
msgid "test.config.settings"
|
||||
msgstr "test.config.settings"
|
||||
|
||||
#~ msgid "Group User"
|
||||
#~ msgstr "Grupos de Usuario"
|
||||
BIN
access_restricted/images/banner.jpg
Normal file
BIN
access_restricted/images/banner.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 392 KiB |
3
access_restricted/models/__init__.py
Normal file
3
access_restricted/models/__init__.py
Normal file
@ -0,0 +1,3 @@
|
||||
from . import res_config_settings
|
||||
from . import res_users
|
||||
from . import test_config_settings
|
||||
71
access_restricted/models/res_config_settings.py
Normal file
71
access_restricted/models/res_config_settings.py
Normal file
@ -0,0 +1,71 @@
|
||||
from odoo import SUPERUSER_ID, api, models
|
||||
from odoo.tools import ustr
|
||||
from odoo.tools.translate import _
|
||||
|
||||
|
||||
class ResConfigSettings(models.TransientModel):
|
||||
_inherit = "res.config.settings"
|
||||
|
||||
@api.model
|
||||
def _get_classified_fields(self, fnames=None):
|
||||
uid = self.env.uid
|
||||
classified = super()._get_classified_fields(fnames)
|
||||
config = self.env.context.get("config")
|
||||
is_execute_stage = config and isinstance(config, models.Model)
|
||||
|
||||
if uid == SUPERUSER_ID or is_execute_stage:
|
||||
return classified
|
||||
|
||||
group = []
|
||||
user = self.env.user
|
||||
|
||||
for name, groups, implied_group in classified["group"]:
|
||||
if (
|
||||
implied_group in user.group_ids
|
||||
or user.has_group(
|
||||
"access_restricted.group_allow_add_implied_from_settings"
|
||||
)
|
||||
):
|
||||
group.append((name, groups, implied_group))
|
||||
|
||||
classified["group"] = group
|
||||
return classified
|
||||
|
||||
@api.model
|
||||
def fields_get(self, allfields=None, **kwargs):
|
||||
uid = self.env.uid
|
||||
fields = super().fields_get(allfields, **kwargs)
|
||||
|
||||
if uid == SUPERUSER_ID:
|
||||
return fields
|
||||
|
||||
user = self.env.user
|
||||
|
||||
for name in fields:
|
||||
if not name.startswith("group_"):
|
||||
continue
|
||||
|
||||
f = self._fields[name]
|
||||
|
||||
if (
|
||||
f.implied_group in user.group_ids
|
||||
or user.has_group(
|
||||
"access_restricted.group_allow_add_implied_from_settings"
|
||||
)
|
||||
):
|
||||
continue
|
||||
|
||||
fields[name].update(
|
||||
readonly=True,
|
||||
help=ustr(fields[name].get("help", ""))
|
||||
+ _(
|
||||
"\n\nYou don't have access to change this settings, because your administration rights are restricted"
|
||||
),
|
||||
)
|
||||
|
||||
return fields
|
||||
|
||||
def execute(self):
|
||||
return super(
|
||||
ResConfigSettings, self.with_context({"config": self})
|
||||
).execute()
|
||||
112
access_restricted/models/res_users.py
Normal file
112
access_restricted/models/res_users.py
Normal file
@ -0,0 +1,112 @@
|
||||
from odoo import SUPERUSER_ID, _, api, models
|
||||
from odoo.exceptions import AccessError
|
||||
|
||||
IR_CONFIG_NAME = "access_restricted.fields_view_get_uid"
|
||||
|
||||
|
||||
class ResUsers(models.Model):
|
||||
_inherit = "res.users"
|
||||
|
||||
@api.model
|
||||
def get_views(self, views, options=None):
|
||||
last_uid = self.env["ir.config_parameter"].sudo().get_param(IR_CONFIG_NAME)
|
||||
if int(last_uid) != self.env.uid:
|
||||
self.env["res.groups"]._update_user_groups_view()
|
||||
return super().get_views(views, options)
|
||||
|
||||
def write(self, vals):
|
||||
if 'groups_id' in vals:
|
||||
self.env["ir.config_parameter"].sudo().set_param(IR_CONFIG_NAME, "0")
|
||||
return super().write(vals)
|
||||
|
||||
|
||||
class ResGroups(models.Model):
|
||||
_inherit = "res.groups"
|
||||
|
||||
@api.model
|
||||
def _update_user_groups_view(self):
|
||||
real_uid = self.env.uid
|
||||
self.env["ir.config_parameter"].sudo().set_param(IR_CONFIG_NAME, real_uid)
|
||||
self.env.flush_all()
|
||||
|
||||
@api.model
|
||||
def get_application_groups(self, domain=None):
|
||||
if domain is None:
|
||||
domain = []
|
||||
domain.append(("share", "=", False))
|
||||
|
||||
real_uid = int(
|
||||
self.env["ir.config_parameter"].sudo().get_param(IR_CONFIG_NAME, "0")
|
||||
)
|
||||
if real_uid and real_uid != SUPERUSER_ID:
|
||||
group_no_one_id = self.env.ref("base.group_no_one").id
|
||||
domain = domain + [
|
||||
"|",
|
||||
("user_ids", "in", [real_uid]),
|
||||
("id", "=", group_no_one_id),
|
||||
]
|
||||
return self.sudo().search(domain)
|
||||
|
||||
def write(self, vals):
|
||||
config = self.env.context.get("config")
|
||||
|
||||
# `isinstance` check is a non-xmplrpc proof.
|
||||
if config and isinstance(config, models.Model):
|
||||
implied_ids = vals.get("implied_ids")
|
||||
classified_group = config._get_classified_fields()["group"]
|
||||
# when `res.config.settings`'s `execute` method writes the `users` field to group,
|
||||
# it is always to remove users and the `users` field is the only key in the write dict
|
||||
users = vals.get("user_ids")
|
||||
implied_group = implied_ids and implied_ids[0][1]
|
||||
users_exclude_operation = (
|
||||
users and len(vals) == 1 and all(u[0] == 3 for u in users)
|
||||
)
|
||||
# ``all(u[0] == 3 for u in users)`` is to be sure that all operations are for removing.
|
||||
# `(3, id)` tuple removes the record from the set (the Many2many field `users`)
|
||||
add_implied_group_operation = implied_group in [
|
||||
group[2].id for group in classified_group
|
||||
]
|
||||
curr_user_allowed = self.env.user._is_superuser() or self.env.user.has_group(
|
||||
"access_restricted.group_allow_add_implied_from_settings"
|
||||
)
|
||||
if (
|
||||
users_exclude_operation
|
||||
or add_implied_group_operation
|
||||
and curr_user_allowed
|
||||
):
|
||||
self = self.with_user(SUPERUSER_ID)
|
||||
else:
|
||||
# do nothing with groups if there is no permission to add from settings
|
||||
return
|
||||
|
||||
# in the https://github.com/odoo/odoo/commit/5f12e244f6e57b8edb56788147774150e2ae134d commit
|
||||
# the method was refactored due to a higher performance.
|
||||
# Super method lacks of orm part so as consequent ir rules are not checked and we check its conditions manually.
|
||||
# We apply super method and check the difference of implied groups,
|
||||
# if the not proper group was set error is raised
|
||||
check_for_implied_ids = (
|
||||
"implied_ids" in vals
|
||||
and vals["implied_ids"]
|
||||
and self.env.user.id != SUPERUSER_ID
|
||||
)
|
||||
if check_for_implied_ids:
|
||||
implied_ids_before = self.mapped("implied_ids")
|
||||
groups_before = self.env.user.group_ids
|
||||
|
||||
result = super(ResGroups, self).write(vals)
|
||||
|
||||
if check_for_implied_ids:
|
||||
implied_ids_after = self.mapped("implied_ids")
|
||||
group_no_one = self.env.ref("base.group_no_one")
|
||||
implied_group_ids = implied_ids_after - implied_ids_before - group_no_one
|
||||
|
||||
# R1 <= R2 True if all records of R1 are also in R2
|
||||
if not implied_group_ids <= groups_before:
|
||||
raise AccessError(
|
||||
_(
|
||||
"You cannot add groups to Implied groups, because you are not allowed to increase your rights. "
|
||||
"Please contact your system administrator."
|
||||
)
|
||||
)
|
||||
|
||||
return result
|
||||
13
access_restricted/models/test_config_settings.py
Normal file
13
access_restricted/models/test_config_settings.py
Normal file
@ -0,0 +1,13 @@
|
||||
from odoo import fields, models
|
||||
|
||||
|
||||
class TestConfigSettings(models.TransientModel):
|
||||
|
||||
_description = "Test config settings"
|
||||
_inherit = ["res.config.settings"]
|
||||
|
||||
group_test_access_restricted = fields.Boolean(
|
||||
group="base.group_system",
|
||||
# random group for test purposes
|
||||
implied_group="base.group_multi_currency",
|
||||
)
|
||||
30
access_restricted/security/access_restricted_security.xml
Normal file
30
access_restricted/security/access_restricted_security.xml
Normal file
@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo>
|
||||
<record id="group_allow_add_implied_from_settings" model="res.groups">
|
||||
<field name="name">Allow add implied groups from settings</field>
|
||||
</record>
|
||||
<record id="not_admin_tenant_rule" model="ir.rule">
|
||||
<field name="name">Only admin can edit admin</field>
|
||||
<field name="model_id" ref="base.model_res_users" />
|
||||
<field name="global" eval="1" />
|
||||
<field name="domain_force">[('id', '!=', 1)]</field>
|
||||
<field name="perm_read" eval="False" />
|
||||
<field name="perm_write" eval="True" />
|
||||
<field name="perm_create" eval="True" />
|
||||
<field name="perm_unlink" eval="True" />
|
||||
<field name="protected" eval="True" />
|
||||
</record>
|
||||
<record id="res_groups_restricted" model="ir.rule">
|
||||
<field name="name">res.groups.restricted</field>
|
||||
<field name="model_id" ref="base.model_res_groups" />
|
||||
<field
|
||||
name="domain_force"
|
||||
eval=""['|', ('user_ids','in', [user.id]), ('id', '=', '%s')]" % ref('base.group_no_one')"
|
||||
/>
|
||||
<field name="perm_read" eval="False" />
|
||||
<field name="perm_write" eval="True" />
|
||||
<field name="perm_create" eval="False" />
|
||||
<field name="perm_unlink" eval="True" />
|
||||
<field name="protected" eval="True" />
|
||||
</record>
|
||||
</odoo>
|
||||
BIN
access_restricted/static/description/icon.png
Normal file
BIN
access_restricted/static/description/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.9 KiB |
3
access_restricted/tests/__init__.py
Normal file
3
access_restricted/tests/__init__.py
Normal file
@ -0,0 +1,3 @@
|
||||
from . import test_fields_view_get
|
||||
from . import test_fields_get
|
||||
from . import test_allow_implied
|
||||
86
access_restricted/tests/test_allow_implied.py
Normal file
86
access_restricted/tests/test_allow_implied.py
Normal file
@ -0,0 +1,86 @@
|
||||
from odoo.exceptions import AccessError
|
||||
from odoo.tests.common import TransactionCase
|
||||
|
||||
GROUP = "base.group_multi_currency"
|
||||
|
||||
|
||||
class TestAllowImplied(TransactionCase):
|
||||
def _get_classified_groups(self, config):
|
||||
groups = config._get_classified_fields()["group"]
|
||||
return [g[0] for g in groups]
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.group = self.env.ref(GROUP)
|
||||
self.demo_user = self.env["res.users"].create({
|
||||
"name": "Test Demo User",
|
||||
"login": "test_demo_allow_implied",
|
||||
"groups_id": [(6, 0, [self.env.ref("base.group_user").id])],
|
||||
})
|
||||
|
||||
def test_base(self):
|
||||
demo_user = self.demo_user
|
||||
|
||||
group_system = self.env.ref("base.group_system")
|
||||
|
||||
demo_user.write({"group_ids": [(3, self.group.id)]})
|
||||
self.group.write({"users": [(3, demo_user.id)]})
|
||||
self.assertFalse(self.env["res.users"].with_user(demo_user.id).has_group(GROUP))
|
||||
|
||||
demo_user.write({"group_ids": [(4, group_system.id)]})
|
||||
|
||||
test_config_settings = (
|
||||
self.env["res.config.settings"]
|
||||
.with_user(demo_user.id)
|
||||
.create({"group_test_access_restricted": True})
|
||||
)
|
||||
self.assertFalse(self.env["res.users"].with_user(demo_user.id).has_group(GROUP))
|
||||
|
||||
# check that the field is readonly
|
||||
self.assertTrue(
|
||||
test_config_settings.fields_get()["group_test_access_restricted"][
|
||||
"readonly"
|
||||
]
|
||||
)
|
||||
# check that test group hasn't got appended to classified
|
||||
self.assertNotIn(
|
||||
"self.group", self._get_classified_groups(test_config_settings)
|
||||
)
|
||||
|
||||
group_allow = self.env.ref(
|
||||
"access_restricted.group_allow_add_implied_from_settings"
|
||||
)
|
||||
demo_user.write({"group_ids": [(4, group_allow.id)]})
|
||||
|
||||
# check that now the field is not readonly
|
||||
self.assertFalse(
|
||||
test_config_settings.fields_get()["group_test_access_restricted"][
|
||||
"readonly"
|
||||
]
|
||||
)
|
||||
# check that now the group is in classified
|
||||
self.assertIn(
|
||||
"group_test_access_restricted",
|
||||
self._get_classified_groups(test_config_settings),
|
||||
)
|
||||
|
||||
self.assertFalse(self.env["res.users"].with_user(demo_user.id).has_group(GROUP))
|
||||
test_config_settings.with_user(demo_user.id).execute()
|
||||
self.assertTrue(self.env["res.users"].with_user(demo_user.id).has_group(GROUP))
|
||||
|
||||
def test_assert_raises(self):
|
||||
demo_user = self.demo_user
|
||||
group_system = self.env.ref("base.group_system")
|
||||
|
||||
demo_user.write({"group_ids": [(3, self.group.id)]})
|
||||
self.group.write({"users": [(3, demo_user.id)]})
|
||||
self.assertFalse(self.env["res.users"].with_user(demo_user.id).has_group(GROUP))
|
||||
|
||||
demo_user.write({"group_ids": [(4, group_system.id)]})
|
||||
self.assertFalse(self.env["res.users"].with_user(demo_user.id).has_group(GROUP))
|
||||
|
||||
# check that there is no access to put test group into implied_ids anyways
|
||||
with self.assertRaises(AccessError):
|
||||
group_system.with_user(demo_user.id).write(
|
||||
{"implied_ids": [(4, self.group.id)]}
|
||||
)
|
||||
39
access_restricted/tests/test_fields_get.py
Normal file
39
access_restricted/tests/test_fields_get.py
Normal file
@ -0,0 +1,39 @@
|
||||
from odoo.tests.common import TransactionCase
|
||||
|
||||
|
||||
def _sel_groups_field_name(group_ids):
|
||||
"""Generate sel_groups field name from group ids (replaces removed name_selection_groups)."""
|
||||
return 'sel_groups_' + '_'.join(str(i) for i in sorted(group_ids))
|
||||
|
||||
|
||||
class TestFieldsGet(TransactionCase):
|
||||
def test_base(self):
|
||||
demo_user = self.env["res.users"].create({
|
||||
"name": "Test Demo User Fields",
|
||||
"login": "test_demo_fields_get",
|
||||
"groups_id": [(6, 0, [self.env.ref("base.group_user").id])],
|
||||
})
|
||||
group_erp_manager = self.env.ref("base.group_erp_manager")
|
||||
group_system = self.env.ref("base.group_system")
|
||||
|
||||
demo_user.write({"group_ids": [(3, group_system.id)]})
|
||||
group_system.write({"user_ids": [(3, demo_user.id)]})
|
||||
demo_user.write({"group_ids": [(4, group_erp_manager.id)]})
|
||||
|
||||
view_users_form = self.env.ref("base.view_users_form")
|
||||
(
|
||||
self.env["res.users"]
|
||||
.with_user(demo_user)
|
||||
.with_context({"uid": demo_user.id})
|
||||
.get_views([[view_users_form.id, "form"]])
|
||||
)
|
||||
|
||||
sel_groups = _sel_groups_field_name([group_erp_manager.id])
|
||||
res = self.env["res.users"].with_user(demo_user).fields_get()
|
||||
self.assertTrue(res.get(sel_groups))
|
||||
|
||||
demo_user.write({"groups_id": [(4, group_system.id)]})
|
||||
|
||||
sel_groups = _sel_groups_field_name([group_erp_manager.id, group_system.id])
|
||||
res = self.env["res.users"].with_user(demo_user).fields_get()
|
||||
self.assertTrue(res.get(sel_groups))
|
||||
71
access_restricted/tests/test_fields_view_get.py
Normal file
71
access_restricted/tests/test_fields_view_get.py
Normal file
@ -0,0 +1,71 @@
|
||||
from odoo.tests.common import TransactionCase, tagged
|
||||
|
||||
IR_CONFIG_NAME = "access_restricted.fields_view_get_uid"
|
||||
|
||||
|
||||
@tagged("post_install", "-at_install")
|
||||
class TestFieldsViewGet(TransactionCase):
|
||||
def clear_config(self):
|
||||
self.env["ir.config_parameter"].search([("key", "=", IR_CONFIG_NAME)]).unlink()
|
||||
|
||||
def clear_access(self, user):
|
||||
user.write(
|
||||
{
|
||||
"group_ids": [
|
||||
(3, self.env.ref("base.group_erp_manager").id, 0),
|
||||
(3, self.env.ref("base.group_system").id, 0),
|
||||
]
|
||||
}
|
||||
)
|
||||
|
||||
def add_access(self, user, group_xmlid):
|
||||
user.write({"group_ids": [(4, self.env.ref(group_xmlid).id, 0)]})
|
||||
|
||||
def _view_form(self, user, view_xmlid):
|
||||
view_id = self.env.ref(view_xmlid).id
|
||||
# context = {'lang': "en_US", 'tz': "Europe/Brussels", 'uid': user.id}
|
||||
self.env["res.users"].with_user(user.id).get_view(view_id=view_id)
|
||||
|
||||
def view_preference_form(self, user):
|
||||
self._view_form(user, "base.view_users_form_simple_modif")
|
||||
|
||||
def view_user_form(self, user):
|
||||
self._view_form(user, "base.view_users_form")
|
||||
|
||||
def view_form_all(self, user):
|
||||
self.view_preference_form(user)
|
||||
self.clear_config()
|
||||
|
||||
self.view_user_form(user)
|
||||
self.clear_config()
|
||||
|
||||
def view_form_mix(self, user1, user2):
|
||||
self.view_preference_form(user1)
|
||||
self.view_user_form(user2)
|
||||
|
||||
self.view_preference_form(user1)
|
||||
self.view_preference_form(user2)
|
||||
|
||||
self.view_form_all(user1)
|
||||
self.view_user_form(user2)
|
||||
|
||||
def test_base(self):
|
||||
admin = self.env.ref("base.user_root")
|
||||
demo = self.env.ref("base.user_demo")
|
||||
|
||||
# test for admin
|
||||
self.view_form_all(admin)
|
||||
|
||||
# demo doesn't have admin rights
|
||||
self.clear_access(demo)
|
||||
self.view_preference_form(demo)
|
||||
|
||||
# demo has "Access Rights"
|
||||
self.add_access(demo, "base.group_erp_manager")
|
||||
self.view_form_all(demo)
|
||||
|
||||
# demo has "Settings"
|
||||
self.add_access(demo, "base.group_system")
|
||||
self.view_form_all(demo)
|
||||
|
||||
self.view_form_mix(admin, demo)
|
||||
Reference in New Issue
Block a user