Merge pull request #205 from Eficent/11.0-knowledge-document-security

[knowledge][11.0.3.0.0] - add security for access to ir.attachment.
This commit is contained in:
Jordi Ballester Alomar 2019-03-11 20:30:11 +01:00 committed by GitHub
commit f731c04534
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 111 additions and 70 deletions

View File

@ -1,7 +1,7 @@
///* Copyright 2014 Therp BV (<http://therp.nl>)
// * License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). */
/* Copyright 2014 Therp BV (<http://therp.nl>)
* License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). */
odoo.define('attachment_preview', function(require) {
odoo.define('attachment_preview', function (require) {
'use strict';
var core = require('web.core');
@ -14,16 +14,15 @@ odoo.define('attachment_preview', function(require) {
var Widget = require('web.Widget');
var AttachmentPreviewMixin = {
canPreview: function(extension) {
canPreview: function (extension) {
return $.inArray(
extension,
[
'odt', 'odp', 'ods', 'fodt', 'pdf', 'ott', 'fodp', 'otp',
'fods', 'ots'
['odt', 'odp', 'ods', 'fodt', 'pdf', 'ott', 'fodp', 'otp',
'fods', 'ots',
]) > -1;
},
getUrl: function(attachment_id, attachment_url, attachment_extension, attachment_title) {
getUrl: function (attachment_id, attachment_url, attachment_extension, attachment_title) {
var url = (window.location.origin || '') +
'/attachment_preview/static/lib/ViewerJS/index.html' +
'?type=' + encodeURIComponent(attachment_extension) +
@ -33,7 +32,7 @@ odoo.define('attachment_preview', function(require) {
return url;
},
showPreview: function(attachment_id, attachment_url, attachment_extension, attachment_title, split_screen) {
showPreview: function (attachment_id, attachment_url, attachment_extension, attachment_title, split_screen) {
var url = this.getUrl(attachment_id, attachment_url, attachment_extension, attachment_title);
if (split_screen) {
this.trigger_up('onAttachmentPreview', {url: url});
@ -46,51 +45,51 @@ odoo.define('attachment_preview', function(require) {
Sidebar.include(AttachmentPreviewMixin);
Sidebar.include({
events: _.extend({}, Sidebar.prototype.events, {
'click .o_sidebar_preview_attachment': '_onPreviewAttachment'
'click .o_sidebar_preview_attachment': '_onPreviewAttachment',
}),
previewableAttachments: null,
_redraw: function () {
this._super.apply(this, arguments);
this.getPreviewableAttachments().done(function(atts) {
this.getPreviewableAttachments().done(function (atts) {
this.previewableAttachments = atts;
this.updatePreviewButtons(atts);
this.trigger_up('setPreviewableAttachments', {attachments: atts});
}.bind(this));
},
_onPreviewAttachment: function(event) {
_onPreviewAttachment: function (event) {
event.preventDefault();
var self = this,
$target = $(event.currentTarget),
split_screen = $target.attr('data-target') != 'new',
split_screen = $target.attr('data-target') !== 'new',
attachment_id = parseInt($target.attr('data-id'), 10),
attachment_url = $target.attr('data-url'),
attachment_extension = $target.attr('data-extension'),
attachment_title = $target.attr('data-original-title');
if(attachment_extension) {
if (attachment_extension) {
this.showPreview(attachment_id, attachment_url, attachment_extension, attachment_title, split_screen);
} else {
this._rpc({
model: 'ir.attachment',
method: 'get_attachment_extension',
args: [attachment_id]
}).then(function(extension) {
args: [attachment_id],
}).then(function (extension) {
self.showPreview(attachment_id, attachment_url, extension, null, split_screen);
});
}
},
getPreviewableAttachments: function() {
getPreviewableAttachments: function () {
var self = this;
var deferred = $.Deferred();
var $items = this.$el.find('.o_sidebar_preview_attachment');
var attachments = _.object($items.map(function() {
var attachments = _.object($items.map(function () {
return parseInt($(this).attr('data-id'), 10);
}), $items.map(function() {
}), $items.map(function () {
return {
url: $(this).attr('data-url'),
extension: $(this).attr('data-extension'),
@ -102,14 +101,14 @@ odoo.define('attachment_preview', function(require) {
model: 'ir.attachment',
method: 'get_attachment_extension',
args: [
_.map(_.keys(attachments), function(id) {
_.map(_.keys(attachments), function (id) {
return parseInt(id, 10);
})
]
}).then(function(extensions) {
var reviewableAttachments = _.map(_.keys(_.pick(extensions, function(extension, id) {
}),
],
}).then(function (extensions) {
var reviewableAttachments = _.map(_.keys(_.pick(extensions, function (extension, id) {
return self.canPreview(extension);
})), function(id) {
})), function (id) {
return {
id: id,
url: attachments[id]['url'],
@ -120,18 +119,18 @@ odoo.define('attachment_preview', function(require) {
attachments[id]['url'],
extensions[id],
id + ' - ' + attachments[id]['title']
)
}
),
};
});
deferred.resolve(reviewableAttachments);
}, function() {
}, function () {
deferred.reject();
});
return deferred.promise();
},
updatePreviewButtons: function(previewableAttachments) {
this.$el.find('.o_sidebar_preview_attachment').each(function() {
updatePreviewButtons: function (previewableAttachments) {
this.$el.find('.o_sidebar_preview_attachment').each(function () {
var $this = $(this);
var id = $this.attr('data-id');
var att = _.findWhere(previewableAttachments, {id: id});
@ -147,20 +146,20 @@ odoo.define('attachment_preview', function(require) {
basic_fields.FieldBinaryFile.include(AttachmentPreviewMixin);
basic_fields.FieldBinaryFile.include({
events: _.extend({}, basic_fields.FieldBinaryFile.prototype.events, {
'click .fa-search': '_onPreview'
'click .fa-search': '_onPreview',
}),
_renderReadonly: function () {
var self = this;
this._super.apply(this, arguments);
this._getBinaryExtension().done(function(extension) {
if(self.canPreview(extension)) {
this._getBinaryExtension().done(function (extension) {
if (self.canPreview(extension)) {
self._renderPreviewButton(extension);
}
});
},
_renderPreviewButton: function(extension) {
_renderPreviewButton: function (extension) {
this.$previewBtn = $("<span/>");
this.$previewBtn.addClass('fa fa-search');
this.$previewBtn.attr('title', _.str.sprintf(_t('Preview %s'), this.field.string));
@ -176,12 +175,12 @@ odoo.define('attachment_preview', function(require) {
this.model,
this.recordData.id,
this.name,
this.attrs.filename
]
this.attrs.filename,
],
});
},
_onPreview: function(event) {
_onPreview: function (event) {
this.showPreview(
null,
_.str.sprintf(
@ -194,7 +193,7 @@ odoo.define('attachment_preview', function(require) {
_.str.sprintf(_t('Preview %s'), this.field.string),
false
);
}
},
});
var AttachmentPreviewWidget = Widget.extend({
@ -237,7 +236,7 @@ odoo.define('attachment_preview', function(require) {
window.open(this.attachments[this.activeIndex].previewUrl);
},
next: function() {
next: function () {
var index = this.activeIndex + 1;
if (index >= this.attachments.length) {
index = 0;
@ -247,7 +246,7 @@ odoo.define('attachment_preview', function(require) {
this.loadPreview();
},
previous: function() {
previous: function () {
var index = this.activeIndex - 1;
if (index < 0) {
index = this.attachments.length - 1;
@ -267,13 +266,13 @@ odoo.define('attachment_preview', function(require) {
this.trigger('hidden');
},
updatePaginator: function() {
updatePaginator: function () {
var value = _.str.sprintf('%s / %s', this.activeIndex + 1, this.attachments.length);
this.$current.html(value);
},
loadPreview: function() {
if (this.attachments.length == 0) {
loadPreview: function () {
if (this.attachments.length === 0) {
this.$iframe.attr('src', 'about:blank');
return;
}
@ -282,18 +281,18 @@ odoo.define('attachment_preview', function(require) {
this.$iframe.attr('src', att.previewUrl);
},
setAttachments: function(attachments) {
setAttachments: function (attachments) {
this.attachments = attachments;
this.activeIndex = 0;
this.updatePaginator();
this.loadPreview();
}
},
});
FormRenderer.include({
attachmentPreviewWidget: null,
init: function() {
init: function () {
var res = this._super.apply(this, arguments);
this.attachmentPreviewWidget = new AttachmentPreviewWidget(this);
this.attachmentPreviewWidget.on('hidden', this, this._attachmentPreviewWidgetHidden);
@ -305,7 +304,7 @@ odoo.define('attachment_preview', function(require) {
this.attachmentPreviewWidget.insertAfter(this.$el);
},
_attachmentPreviewWidgetHidden: function() {
_attachmentPreviewWidgetHidden: function () {
this.$el.removeClass('attachment_preview');
},
@ -320,29 +319,29 @@ odoo.define('attachment_preview', function(require) {
on_detach_callback: function () {
this.attachmentPreviewWidget.hide();
return this._super.apply(this, arguments);
}
},
});
FormController.include({
custom_events: _.extend({}, FormController.prototype.custom_events, {
onAttachmentPreview: '_onAttachmentPreview',
setPreviewableAttachments: '_setPreviewableAttachments'
setPreviewableAttachments: '_setPreviewableAttachments',
}),
_onAttachmentPreview: function (event) {
this.renderer.showAttachmentPreviewWidget();
},
_setPreviewableAttachments: function(event) {
_setPreviewableAttachments: function (event) {
this.renderer.attachmentPreviewWidget.setAttachments(
event.data.attachments
);
}
},
});
return {
AttachmentPreviewMixin: AttachmentPreviewMixin,
AttachmentPreviewWidget: AttachmentPreviewWidget
AttachmentPreviewWidget: AttachmentPreviewWidget,
};
});

View File

@ -3,9 +3,9 @@
// This file contains tweaks for viewerjs itself and is not meant to be run in
// OpenERP's context
(function(original_Viewer) {
window.Viewer = function(plugin, parameters) {
if(!plugin) {
(function (original_Viewer) {
window.Viewer = function (plugin, parameters) {
if (!plugin) {
// eslint-disable-next-line no-alert
alert('Unsupported file type');
}

View File

@ -39,7 +39,7 @@
<field name="approved_date" readonly="1" attrs="{'invisible':[('state','not in',['approved'])]}"/>
</group>
</xpath>
<!-- Readonly fields -->
<!-- Readonly fields -->
<field name="content" position="attributes"><attribute name="attrs">{'readonly': [('state', 'not in', ['draft'])]}</attribute></field>
<field name="page_id" position="attributes"><attribute name="attrs">{'readonly': [('state', 'not in', ['draft'])]}</attribute></field>
<field name="name" position="attributes"><attribute name="attrs">{'readonly': [('state', 'not in', ['draft'])]}</attribute></field>

View File

@ -4,7 +4,7 @@
{
'name': 'Project Wiki',
'description': 'This module links document pages to projects',
'summary': 'This module links document pages to projects',
'version': '11.0.1.0.0',
"development_status": "Beta",
'category': 'Project',

View File

@ -1,2 +1,2 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_ir_attachment_add_url,access_ir_attachment_add_url,model_ir_attachment_add_url,,1,1,1,1
access_ir_attachment_add_url,access_ir_attachment_add_url,model_ir_attachment_add_url,,1,1,1,1

1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_ir_attachment_add_url access_ir_attachment_add_url model_ir_attachment_add_url 1 1 1 1

View File

@ -21,7 +21,7 @@ odoo.define('document_url', function (require) {
self.$el.find("a[href]").attr('target', '_blank');
self.$el
.find('.oe_sidebar_add_attachment, .o_sidebar_add_attachment')
.after(QWeb.render('AddUrlDocumentItem', {widget: self}))
.after(QWeb.render('AddUrlDocumentItem', {widget: self}));
self.$el.find('.o_sidebar_add_url').on('click', function (e) {
self.on_url_doc();
});
@ -29,7 +29,7 @@ odoo.define('document_url', function (require) {
on_url_doc: function (event) {
var self = this;
var env = self.env
var env = self.env;
var view = self.getParent();
var ids = self.env.activeIds;
if (!_.isEmpty(ids)) {
@ -41,7 +41,7 @@ odoo.define('document_url', function (require) {
if (env.domain) {
activeIdsContext.active_domain = env.domain;
}
var context = new Context(env.context, activeIdsContext)
var context = new Context(env.context, activeIdsContext);
context = pyeval.eval('context', context);
self._rpc({
route: "/web/action/load",

View File

@ -2,10 +2,11 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
"name": "Knowledge Management System",
"version": "11.0.2.0.0",
"version": "11.0.3.0.0",
"author": "OpenERP SA,"
"MONK Software, "
"Tecnativa, "
"Eficent, "
"Odoo Community Association (OCA)",
"category": "Knowledge",
"license": "AGPL-3",

View File

@ -9,11 +9,17 @@ class KnowledgeConfigSettings(models.TransientModel):
_inherit = 'res.config.settings'
module_document = fields.Boolean(
'Manage documents',
'Attachments List and Document Indexation',
help='Document indexation, full text search of attachements.\n'
'- This installs the module document.'
)
group_ir_attachment_user = fields.Boolean(
string='Central access to Documents',
help="When you set this field all users will be able to manage "
"attachments centrally, from the Knowledge/Documents menu.",
implied_group='knowledge.group_ir_attachment_user')
module_document_page = fields.Boolean(
'Manage document pages (Wiki)',
help='Provide document page and category as a wiki.\n'

View File

@ -0,0 +1,20 @@
To set up this module, you need to go to:
* Knowledge / Configuration / Settings
From this menu you'll have a central access to install the apps that belong
to Knowledge.
* Check *Attachments List and Document Indexation* if you want to install the
module that allows users to attach documents to any model.
* Check *Manage attachments centrally* if you want all users to be able to
access to the all attachments to which they have read permissions, from the
menu *Knowledge / Documents*
If you want to grant Central Access to Documents only to some users:
#. Go to *Settings/Activate the developer mode*. Only a user with
*Administration / Settings* permissions can do that.
#. Go to *Settings / Users & Companies / Users* and set the checkbox
*Central access to Documents* to the selected users.

View File

@ -6,3 +6,4 @@
* Fayez Qandeel
* Vicent Cubells <vicent.cubells@tecnativa.com>
* Iván Todorovich <ivan.todorovich@gmail.com>
* Jordi Ballester <jordi.ballester@eficent.com>

View File

@ -1,2 +0,0 @@
* Migrate related modules to v11 and add options in the settings as soon as
they are installable.

View File

@ -1,3 +1,5 @@
To use this module, you need to:
This module adds a new top level menu *Knowledge*
* Go to Knowledge / Configuration / Settings
Users with permission *Central access to Documents* can access in
*Knowledge/Documents* to all the documents attached to records of any model
for which they have read permission.

View File

@ -7,4 +7,10 @@
<field name="users" eval="[(4, ref('base.user_root'))]"/>
</record>
<record id="group_ir_attachment_user" model="res.groups">
<field name="name">Central access to Documents</field>
<field name="category_id" ref="base.module_category_hidden"/>
<field name="implied_ids" eval="[(4, ref('group_document_user'))]"/>
</record>
</odoo>

View File

@ -37,9 +37,9 @@
<menuitem
id="menu_document_section"
name="Documents"
groups="knowledge.group_document_user"
groups="knowledge.group_ir_attachment_user"
parent="menu_document_root"
sequence="10"/>
sequence="150"/>
<menuitem
id="menu_document"

View File

@ -21,6 +21,14 @@
<label for="module_document"/>
</div>
</div>
<div class="col-xs-12 col-md-12 o_setting_box">
<div class="o_setting_left_pane">
<field name="group_ir_attachment_user"/>
</div>
<div class="o_setting_right_pane">
<label for="group_ir_attachment_user"/>
</div>
</div>
<div class="col-xs-12 col-md-12 o_setting_box">
<div class="o_setting_left_pane">
<field name="module_document_page"/>
@ -75,7 +83,7 @@
name="Configuration"
parent="menu_document_root"
groups="base.group_system"
sequence="50"/>
sequence="200"/>
<menuitem id="menu_knowledge_configuration"
name="Settings"
parent="menu_document_configuration"