Browse Source

[ADD] Tests

[RFR] Hide button instead of reconstructing div and trigger
[RFR] Keep original behaviour if group is not found, courtesy of Antonio Esposito
[FIX] Monkeypatch when module is actually loaded
[RFR] OCA conventions
[DEL] pot file
pull/743/head
Stefan Rijnhart 8 years ago
parent
commit
3bae14ea1d
  1. 45
      base_import_security_group/README.rst
  2. 2
      base_import_security_group/__init__.py
  3. 37
      base_import_security_group/__openerp__.py
  4. 36
      base_import_security_group/hooks.py
  5. 21
      base_import_security_group/i18n/base_import_security_group.pot
  6. 5
      base_import_security_group/models/__init__.py
  7. 36
      base_import_security_group/models/models.py
  8. 51
      base_import_security_group/static/src/js/import.js
  9. 8
      base_import_security_group/static/src/xml/base_import_security_group.xml
  10. 1
      base_import_security_group/tests/__init__.py
  11. 62
      base_import_security_group/tests/test_base_import_security_group.py

45
base_import_security_group/README.rst

@ -1,6 +1,8 @@
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
:alt: License: AGPL-3
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
===============================================
Group-based permissions for importing CSV files
===============================================
@ -10,9 +12,8 @@ Any other user not belonging to such group will not have the "Import" button
available anywhere. The action will even be blocked internally (to prevent
XMLRPC access, for example).
Usage
=====
Configuration
=============
To allow a user to import data from CSV files, just follow this steps:
@ -21,20 +22,20 @@ To allow a user to import data from CSV files, just follow this steps:
* Within the "Access Rights" tab and "Technical Settings" group, check the
option "Allow importing CSV files".
Usage
=====
For further information, please visit:
- https://www.odoo.com/forum/help-1
.. 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/8.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 smashing it by providing a detailed and welcomed feedback
`here <https://github.com/OCA/server-tools/issues/new?body=module:%20super_calendar%0Aversion:%208.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
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
=======
@ -43,13 +44,20 @@ Contributors
------------
* Alejandro Santana <alejandrosantana@anubia.es>
* Stefan Rijnhart <stefan@opener.amsterdam>
* Antonio Esposito <a.esposito@onestein.nl>
Icon
----
Iconic fonts used in module icon are Font Awesome: http://fontawesome.io/
Maintainer
----------
.. image:: http://odoo-community.org/logo.png
.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: http://odoo-community.org
:target: https://odoo-community.org
This module is maintained by the OCA.
@ -57,9 +65,4 @@ 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 http://odoo-community.org.
Icon
----
Iconic fonts used in module icon are Font Awesome: http://fontawesome.io/
To contribute to this module, please visit https://odoo-community.org.

2
base_import_security_group/__init__.py

@ -2,4 +2,4 @@
# License and authorship info in:
# __openerp__.py file at the root folder of this module.
from . import models
from .hooks import post_load

37
base_import_security_group/__openerp__.py

@ -1,36 +1,17 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Odoo, Open Source Management Solution
#
# Copyright (c) All rights reserved:
# (c) 2015 Anubía, soluciones en la nube,SL (http://www.anubia.es)
# Alejandro Santana <alejandrosantana@anubia.es>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see http://www.gnu.org/licenses
#
##############################################################################
# coding: utf-8
# Copyright 2015 Anubía, soluciones en la nube,SL (http://www.anubia.es)
# Alejandro Santana <alejandrosantana@anubia.es>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
'name': 'Optional CSV import',
'version': '1.0',
'version': '8.0.1.0.0',
'category': 'Server tools',
'summary': 'Group-based permissions for importing CSV files',
'license': 'AGPL-3',
'author': 'Odoo Community Association (OCA), '
'Alejandro Santana <alejandrosantana@anubia.es>',
'maintainer': 'Odoo Community Association (OCA)',
'website': 'http://odoo-community.org',
'website': 'https://github.com/OCA/server-tools',
'depends': [
'base_import'
],
@ -41,7 +22,9 @@
'js': [
'static/src/js/import.js',
],
'qweb': [
'static/src/xml/base_import_security_group.xml',
],
'installable': True,
'application': False,
'auto_install': False,
'post_load': 'post_load',
}

36
base_import_security_group/hooks.py

@ -0,0 +1,36 @@
# -*- coding: utf-8 -*-
# License and authorship info in:
# __openerp__.py file at the root folder of this module.
from openerp import api
from openerp.models import BaseModel
import logging
_logger = logging.getLogger(__name__)
base_load = BaseModel.load
@api.model
def load_import_optional(self, fields=None, data=None):
'''Overriding this method we only allow its execution if the current
user belongs to the group allowed for CSV data import.
An exception is raised otherwise, and the import attempt is logged.
This method is monkeypatched and will also affect other databases on the
same Odoo instance. Therefore, check if the group actually exist as
evidence that this module is installed.
'''
group_ref = 'base_import_security_group.group_import_csv'
group = self.env.ref(group_ref, raise_if_not_found=False)
if not group or self.env.user.has_group(group_ref):
return base_load(self, fields=fields, data=data)
msg = 'User (ID: %s) is not allowed to import data in model %s.' % (
self.env.uid, self._name)
_logger.info(msg)
return {'ids': False, 'messages': [{
'type': 'error',
'message': msg,
'moreinfo': False}]}
def post_load():
BaseModel.load = load_import_optional

21
base_import_security_group/i18n/base_import_security_group.pot

@ -1,21 +0,0 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * base_import_security_group
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 8.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-08-06 18:37+0000\n"
"PO-Revision-Date: 2015-08-06 18:37+0000\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: base_import_security_group
#: model:res.groups,name:base_import_security_group.group_import_csv
msgid "Import CSV files"
msgstr ""

5
base_import_security_group/models/__init__.py

@ -1,5 +0,0 @@
# -*- coding: utf-8 -*-
# License and authorship info in:
# __openerp__.py file at the root folder of this module.
from . import models

36
base_import_security_group/models/models.py

@ -1,36 +0,0 @@
# -*- coding: utf-8 -*-
# License and authorship info in:
# __openerp__.py file at the root folder of this module.
from openerp import api
from openerp.models import BaseModel
import logging
_logger = logging.getLogger(__name__)
base_load = BaseModel.load
@api.model
def load_import_optional(self, fields=None, data=None):
'''Overriding this method we only allow its execution
if current user belongs to the group allowed for CSV data import.
An exception is raised otherwise, and also log the import attempt.
'''
res = {}
current_user = self.env['res.users'].browse(self.env.uid)
allowed_group = 'base_import_security_group.group_import_csv'
if current_user and current_user.has_group(allowed_group):
res = base_load(self, fields=fields, data=data)
else:
msg = ('User (ID: %s) is not allowed to import data '
'in model %s.') % (self.env.uid, self._name)
_logger.error(msg)
messages = []
info = {}
messages.append(dict(info, type='error', message=msg, moreinfo=None))
res = {'ids': None, 'messages': messages}
return res
# Monkey patch function
# Because BaseModel _name = None
BaseModel.load = load_import_optional

51
base_import_security_group/static/src/js/import.js

@ -2,56 +2,15 @@
// __openerp__.py file at the root folder of this module.
openerp.base_import_security_group = function (instance) {
var QWeb = instance.web.qweb;
var _t = instance.web._t;
var _lt = instance.web._lt;
instance.web.ListView.prototype.defaults.import_enabled = false;
base_import_security_group = instance.web.ListView.include({
instance.web.ListView.include({
load_list: function () {
var self = this;
var Users = new openerp.web.Model('res.users');
self._super.apply(self, arguments);
Users.call('has_group', ['base_import_security_group.group_import_csv'])
.then(function (result) {
var import_enabled = result;
this._super.apply(self, arguments);
new openerp.web.Model('res.users').call('has_group', ['base_import_security_group.group_import_csv'])
.then(function (import_enabled) {
self.options.import_enabled = import_enabled;
if (import_enabled) {
if (self.$buttons) {
self.$buttons.remove();
}
self.$buttons = $(QWeb.render("ListView.buttons", {'widget': self}));
if (self.options.$buttons) {
self.$buttons.appendTo(self.options.$buttons);
} else {
self.$el.find('.oe_list_buttons').replaceWith(self.$buttons);
}
self.$buttons.find('.oe_list_add')
.click(self.proxy('do_add_record'))
.prop('disabled', self.grouped);
self.$buttons.on('click', '.oe_list_button_import', function () {
self.do_action({
type: 'ir.actions.client',
tag: 'import',
params: {
model: self.dataset.model,
// self.dataset.get_context() could be a compound?
// not sure. action's context should be evaluated
// so safer bet. Odd that timezone & al in it
// though
context: self.getParent().action.context
}
}, {
on_reverse_breadcrumb: function () {
self.reload();
}
});
return false;
});
self.$buttons.find('span.oe_alternative').show();
}
});
}

8
base_import_security_group/static/src/xml/base_import_security_group.xml

@ -0,0 +1,8 @@
<templates>
<!-- Hide import button, and only show after validation of privileges -->
<t t-extend="ListView.buttons">
<t t-jquery="span.oe_alternative">
this.attr('style', 'display: none;');
</t>
</t>
</templates>

1
base_import_security_group/tests/__init__.py

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

62
base_import_security_group/tests/test_base_import_security_group.py

@ -0,0 +1,62 @@
# coding: utf-8
# Copyright 2017 Stefan Rijnhart <stefan@opener.amsterdam>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from openerp import tests
from openerp.tools import mute_logger
@tests.common.at_install(False)
@tests.common.post_install(True)
class TestImportGroup(tests.HttpCase):
def setUp(self):
super(TestImportGroup, self).setUp()
self.group_ref = 'base_import_security_group.group_import_csv'
self.group = self.env.ref(self.group_ref)
def has_button_import(self, falsify=False):
"""
Verify that the button is either visible or invisible.
After the adjacent button is loaded, allow for a second for
the asynchronous call to finish and update the visibility """
code = """
window.setTimeout(function () {
if (%s$('.oe_list_button_import').is(':visible')) {
console.log('ok');
} else {
console.log('error');
};
}, 1000);
""" % ('!' if falsify else '')
link = '/web#action=%s' % self.env.ref('base.action_res_users').id
with mute_logger('openerp.addons.base.res.res_users'):
# Mute debug log about failing row lock upon user login
self.phantom_js(
link, code, "$('button.oe_list_add').length",
login=self.env.user.login)
def load(self):
self.env['res.partner'].load(
['name'], [['test_base_import_security_group']])
return self.env['res.partner'].search(
[('name', '=', 'test_base_import_security_group')])
def test_01_in_group(self):
""" Show import button to users in the import group """
self.env.user.groups_id += self.group
self.assertTrue(self.env.user.has_group(self.group_ref))
self.has_button_import()
self.assertTrue(self.load())
def test_02_not_in_group(self):
""" Don't show import button to users not in the import group """
self.env.user.groups_id -= self.group
self.assertFalse(self.env.user.has_group(self.group_ref))
self.has_button_import(falsify=True)
self.assertFalse(self.load())
def test_03_no_group(self):
""" When the group does not exist, allow import (monkeypatch to assume
that this module is not installed in that case). """
self.group.unlink()
self.assertFalse(self.env.user.has_group(self.group_ref))
self.assertTrue(self.load())
Loading…
Cancel
Save