Browse Source

[10.0] [ADD] user_immutable: Add Module (#830)

* [ADD] user_immutable: Add Module
* Add module to support users that are immutable

* [IMP] user_immutable: Fixes per PR
* Add missing test
* Fix README
* Add logging

* [IMP] user_immutable: Fixes per PR
* Lower code complexity
* Fix README
* Fix License

* [IMP] user_immutable: Fixes per PR Review
* Call `_check_immutable` on singleton
* Simplify check for immutable group
pull/844/head
Ted Salmon 7 years ago
committed by Dave Lasley
parent
commit
bd4868a1de
  1. 68
      user_immutable/README.rst
  2. 5
      user_immutable/__init__.py
  3. 20
      user_immutable/__manifest__.py
  4. 13
      user_immutable/data/user_immutable_data.xml
  5. 11
      user_immutable/demo/user_immutable_demo.xml
  6. 6
      user_immutable/models/__init__.py
  7. 28
      user_immutable/models/res_groups.py
  8. 48
      user_immutable/models/res_users.py
  9. 6
      user_immutable/tests/__init__.py
  10. 28
      user_immutable/tests/test_res_groups.py
  11. 66
      user_immutable/tests/test_res_users.py

68
user_immutable/README.rst

@ -0,0 +1,68 @@
.. image:: https://img.shields.io/badge/license-LGPL--3-blue.svg
:target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html
:alt: License: LGPL-3
==============
User Immutable
==============
This module adds a group named `Immutable` which cannot be altered by users
outside of that group. By default, the `Administrator` user is the only user
given access to this group on install. This module also adds protections
against non-members granting/revoking membership to this group.
Installation
============
* Install module as normal
Usage
=====
Simply add any user to the `Immutable` group, provided that your login user
is a member of that group already.
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
:alt: Try me on Runbot
:target: https://runbot.odoo-community.org/runbot/149/10.0
Bug Tracker
===========
Bugs are tracked on `GitHub Issues
`<https://github.com/OCA/server-tools/issues>`_. In case of trouble, please
check there if your issue has already been reported. If you spotted it first,
help us smash it by providing detailed and welcomed feedback.
Credits
=======
Images
------
* Odoo Community Association: `Icon <https://github.com/OCA/maintainer-tools/blob/master/template/module/static/description/icon.svg>`_.
Contributors
------------
* Ted Salmon <tsalmon@laslabs.com>
Maintainer
----------
.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org
This module is maintained by the OCA.
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.
To contribute to this module, please visit https://odoo-community.org.

5
user_immutable/__init__.py

@ -0,0 +1,5 @@
# -*- coding: utf-8 -*-
# Copyright 2017 LasLabs Inc.
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
from . import models

20
user_immutable/__manifest__.py

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Copyright 2017 LasLabs Inc.
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
{
"name": "Immutable Users",
"summary": "Add Immutable User Support",
"version": "10.0.1.0.0",
"category": "Authentication",
"website": "https://www.laslabs.com",
"author": "LasLabs, Odoo Community Association (OCA)",
"license": "LGPL-3",
"application": False,
'installable': True,
"data": [
'data/user_immutable_data.xml',
],
"demo": [
'demo/user_immutable_demo.xml',
]
}

13
user_immutable/data/user_immutable_data.xml

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2017 LasLabs Inc.
License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). -->
<odoo noupdate="1">
<record id="group_immutable" model="res.groups">
<field name="name">Immutable</field>
<field name="category_id" ref="base.module_category_hidden"/>
<field name="users" eval="[(4, ref('base.user_root'))]"/>
</record>
</odoo>

11
user_immutable/demo/user_immutable_demo.xml

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2017 LasLabs Inc.
License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). -->
<odoo>
<record id="group_immutable" model="res.groups">
<field name="users" eval="[(4, ref('base.user_demo'))]" />
</record>
</odoo>

6
user_immutable/models/__init__.py

@ -0,0 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright 2017 LasLabs Inc.
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
from . import res_groups
from . import res_users

28
user_immutable/models/res_groups.py

@ -0,0 +1,28 @@
# -*- coding: utf-8 -*-
# Copyright 2017 LasLabs Inc.
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
from odoo import _, api, models
from odoo.exceptions import AccessError
IMMUTABLE = 'user_immutable.group_immutable'
class ResGroups(models.Model):
_inherit = 'res.groups'
@api.multi
def write(self, vals):
""" Override write to verify that access to the `Immutable` group is
not given or removed by users without access
"""
if not vals.get('users') or self.env.user.has_group(IMMUTABLE):
return super(ResGroups, self).write(vals)
immutable = self.env.ref(IMMUTABLE, raise_if_not_found=False)
if immutable and immutable in self:
raise AccessError(_(
'You must be a member of the `Immutable` group to grant'
' access to it'
))
return super(ResGroups, self).write(vals)

48
user_immutable/models/res_users.py

@ -0,0 +1,48 @@
# -*- coding: utf-8 -*-
# Copyright 2017 LasLabs Inc.
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
from odoo import _, api, models
from odoo.exceptions import AccessError
from .res_groups import IMMUTABLE
class ResUsers(models.Model):
_inherit = 'res.users'
def _check_immutable(self):
""" Check to see if the user being edited is Immutable and if so,
make sure that the user performing the action has access
"""
if self.has_group(IMMUTABLE):
if not self.env.user.has_group(IMMUTABLE):
raise AccessError(
_('You do not have permission to alter an Immutable User')
)
@api.multi
def write(self, vals):
""" Override write to verify that there are no alterations to users
whom are members of the `Immutable` group
"""
for rec in self:
rec._check_immutable()
immutable = self.env.ref(IMMUTABLE)
has_group = self.env.user.has_group(IMMUTABLE)
if vals.get('in_group_%s' % immutable.id) and not has_group:
raise AccessError(
_('You must be a member of the `Immutable` group to grant '
'access to it')
)
return super(ResUsers, self).write(vals)
@api.multi
def unlink(self):
""" Override unlink to verify that there are no deletions of users
whom are members of the `Immutable` group
"""
for rec in self:
rec._check_immutable()
return super(ResUsers, self).unlink()

6
user_immutable/tests/__init__.py

@ -0,0 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright 2017 LasLabs Inc.
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
from . import test_res_groups
from . import test_res_users

28
user_immutable/tests/test_res_groups.py

@ -0,0 +1,28 @@
# -*- coding: utf-8 -*-
# Copyright 2017 LasLabs Inc.
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html
from odoo.exceptions import AccessError
from odoo.tests import TransactionCase
class TestResGroups(TransactionCase):
def setUp(self):
super(TestResGroups, self).setUp()
self.immutable = self.env.ref('user_immutable.group_immutable')
self.user = self.env.ref('base.user_demo')
self.user.write({'in_group_%s' % self.immutable.id: False})
def test_can_add_immutable(self):
""" It should make sure that `Administrator` can add users to the
immutable group by default """
self.immutable.write({'users': [(4, [self.user.id])]})
self.assertTrue(self.user.has_group('user_immutable.group_immutable'))
def test_non_immutable_cannot_add_immutable(self):
""" It should make sure that other users cannot add to the immutable
group """
immutable = self.env.ref('user_immutable.group_immutable')
with self.assertRaises(AccessError):
immutable.sudo(self.user.id).write({'users': [self.user.id]})

66
user_immutable/tests/test_res_users.py

@ -0,0 +1,66 @@
# -*- coding: utf-8 -*-
# Copyright 2017 LasLabs Inc.
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html
from odoo.exceptions import AccessError
from odoo.tests import TransactionCase
class TestResUsers(TransactionCase):
def setUp(self):
super(TestResUsers, self).setUp()
self.immutable = self.env.ref('user_immutable.group_immutable')
self.user = self.env.ref('base.user_demo')
self.user.write({'in_group_%s' % self.immutable.id: False})
def test_can_add_immutable(self):
""" It should verify that `Administrator` can add users to the
immutable group by default
"""
self.user.write({'in_group_%s' % self.immutable.id: True})
self.assertTrue(self.user.has_group('user_immutable.group_immutable'))
def test_non_immutable_cannot_add_immutable(self):
""" It should verify that other users cannot add to the immutable
group
"""
with self.assertRaises(AccessError):
self.user.sudo(self.user.id).write({
'in_group_%s' % self.immutable.id: True
})
def test_immutable_can_alter_immutable(self):
""" It should verify that immutable users can alter users in the
immutable group
"""
self.user.write({'in_group_%s' % self.immutable.id: True})
exp = 'Princess Peach'
self.user.write({'name': exp})
self.assertEquals(self.user.name, exp)
def test_immutable_cannot_be_unlinked(self):
""" It should make sure non `Immutable` members cannot unlink other
`Immutable` Members
"""
with self.assertRaises(AccessError):
self.env.ref('base.user_root').sudo(
self.user.id
).unlink()
def test_immutable_can_be_unlinked_by_immutable(self):
""" It should make sure `Immutable` members can unlink other
`Immutable` Members
"""
user = self.user.copy()
user.write({'in_group_%s' % self.immutable.id: True})
self.assertTrue(user.unlink())
def test_check_immutable(self):
""" It should raise `AccessError` when trying called by a user
outside the `Immutable` group on an `Immutable` user
"""
with self.assertRaises(AccessError):
self.env.ref('base.user_root').sudo(
self.user.id
)._check_immutable()
Loading…
Cancel
Save