Skip to content

Commit fa5b48b

Browse files
ramonskiwinniehell
andauthored
Allow to disable global Auditlogging (senaite#2074)
* Patched catalog_object method * Added schema fields in senaite_setup * Hide setup tile when auditlogging is disabled * Added proxy fields in bika_setup * Changelog updated * Update src/bika/lims/content/bikasetup.py Co-authored-by: Winnie <[email protected]> * Show status message when auditlog is disabled Co-authored-by: Winnie <[email protected]>
1 parent b4f47e1 commit fa5b48b

File tree

7 files changed

+153
-2
lines changed

7 files changed

+153
-2
lines changed

CHANGES.rst

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ Changelog
55
2.3.0 (unreleased)
66
------------------
77

8+
- #2074 Allow to disable global Auditlogging
89
- #2072 Refactor report filename generation to own method
910
- #2071 Move sample reports to report catalog, add batch ID and email sent flag to listing
1011
- #2070 Fix typo/duplicate translation key in colophon

src/bika/lims/content/bikasetup.py

+32
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,21 @@ def getCounterTypes(self, instance=None):
200200
"this option will be checked and readonly.")
201201
)
202202
),
203+
# NOTE: This is a Proxy Field which delegates to the SENAITE Registry!
204+
BooleanField(
205+
"EnableGlobalAuditlog",
206+
schemata="Security",
207+
default=False,
208+
widget=BooleanWidget(
209+
label=_("Enable global Audit Log"),
210+
description=_(
211+
"The global Auditlog shows all modifications of the system. "
212+
"When enabled, all entities will be indexed in a separate "
213+
"catalog. This will increase the time when objects are "
214+
"created or modified."
215+
)
216+
)
217+
),
203218
BooleanField(
204219
'ShowPrices',
205220
schemata="Accounting",
@@ -1001,5 +1016,22 @@ def setEmailBodySamplePublication(self, value):
10011016
if setup:
10021017
setup.setEmailBodySamplePublication(value)
10031018

1019+
def getEnableGlobalAuditlog(self):
1020+
"""Get the value from the senaite setup
1021+
"""
1022+
setup = api.get_senaite_setup()
1023+
# setup is `None` during initial site content structure installation
1024+
if setup:
1025+
return setup.getEnableGlobalAuditlog()
1026+
return False
1027+
1028+
def setEnableGlobalAuditlog(self, value):
1029+
"""Set the value in the senaite setup
1030+
"""
1031+
setup = api.get_senaite_setup()
1032+
# setup is `None` during initial site content structure installation
1033+
if setup:
1034+
setup.setEnableGlobalAuditlog(value)
1035+
10041036

10051037
registerType(BikaSetup, PROJECTNAME)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# -*- coding: utf-8 -*-
2+
3+
from bika.lims import api
4+
from plone.app.layout.viewlets import ViewletBase
5+
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
6+
7+
8+
class AuditlogDisabledViewlet(ViewletBase):
9+
"""Viewlet that is displayed when the Auditlog is disabled
10+
"""
11+
template = ViewPageTemplateFile("templates/auditlog_disabled.pt")
12+
13+
def __init__(self, context, request, view, manager=None):
14+
super(AuditlogDisabledViewlet, self).__init__(
15+
context, request, view, manager=manager)
16+
self.context = context
17+
self.request = request
18+
self.view = view
19+
20+
@property
21+
def setup(self):
22+
return api.get_setup()
23+
24+
def get_setup_url(self):
25+
"""Return the absolute URL of the setup
26+
"""
27+
return api.get_url(self.setup)
28+
29+
def is_enabled(self):
30+
"""Returns whether the global auditlog is disabled
31+
"""
32+
return self.setup.getEnableGlobalAuditlog()
33+
34+
def is_disabled(self):
35+
"""Returns whether the global auditlog is disabled
36+
"""
37+
return not self.is_enabled()
38+
39+
def index(self):
40+
if self.is_enabled():
41+
return ""
42+
return self.template()

src/senaite/core/browser/viewlets/configure.zcml

+10
Original file line numberDiff line numberDiff line change
@@ -328,4 +328,14 @@
328328
permission="zope2.View"
329329
layer="senaite.core.interfaces.ISenaiteCore" />
330330

331+
<!-- Auditlog viewlet -->
332+
<browser:viewlet
333+
for="bika.lims.interfaces.IAuditLog"
334+
name="auditlog_disabled"
335+
class=".auditlog.AuditlogDisabledViewlet"
336+
manager="plone.app.layout.viewlets.interfaces.IAboveContent"
337+
template="templates/auditlog_disabled.pt"
338+
permission="zope2.View"
339+
layer="senaite.core.interfaces.ISenaiteCore" />
340+
331341
</configure>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<div tal:omit-tag=""
2+
tal:condition="python:view.is_disabled()"
3+
i18n:domain="senaite.core">
4+
5+
<div id="portal-alert">
6+
<div class="portlet-alert-item alert alert-warning alert-dismissible">
7+
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
8+
<span aria-hidden="true">&times;</span>
9+
</button>
10+
<p class="title">
11+
<strong i18n:translate="">
12+
Global Audit Log is disabled
13+
</strong>
14+
</p>
15+
<p class="description" i18n:translate="">
16+
You can enable the global Audit Log again in the
17+
<a href="#" tal:attributes="href python:view.get_setup_url()">Setup</a>
18+
</p>
19+
</div>
20+
</div>
21+
22+
</div>

src/senaite/core/content/senaitesetup.py

+33-2
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,19 @@
22

33
from AccessControl import ClassSecurityInfo
44
from bika.lims import api
5+
from plone.app.textfield import IRichTextValue
6+
from plone.app.textfield.widget import RichTextFieldWidget # TBD: port to core
57
from plone.autoform import directives
68
from plone.supermodel import model
7-
from plone.app.textfield.widget import RichTextFieldWidget # TBD: port to core
8-
from plone.app.textfield import IRichTextValue
99
from Products.CMFCore import permissions
1010
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
11+
from senaite.core.catalog import AUDITLOG_CATALOG
1112
from senaite.core.content.base import Container
1213
from senaite.core.interfaces import IHideActionsMenu
1314
from senaite.core.interfaces import ISetup
1415
from senaite.core.schema import RichTextField
1516
from senaite.impress import senaiteMessageFactory as _
17+
from zope import schema
1618
from zope.interface import implementer
1719
from zope.interface import provider
1820
from zope.schema.interfaces import IContextAwareDefaultFactory
@@ -44,6 +46,17 @@ class ISetupSchema(model.Schema):
4446
required=False,
4547
)
4648

49+
enable_global_auditlog = schema.Bool(
50+
title=_(u"Enable global Auditlog"),
51+
description=_(
52+
"The global Auditlog shows all modifications of the system. "
53+
"When enabled, all entities will be indexed in a separate "
54+
"catalog. This will increase the time when objects are "
55+
"created or modified."
56+
),
57+
default=False,
58+
)
59+
4760
###
4861
# Fieldsets
4962
###
@@ -83,3 +96,21 @@ def setEmailBodySamplePublication(self, value):
8396
"""
8497
mutator = self.mutator("email_body_sample_publication")
8598
return mutator(self, value)
99+
100+
@security.protected(permissions.View)
101+
def getEnableGlobalAuditlog(self):
102+
"""Returns if the global Auditlog is enabled
103+
"""
104+
accessor = self.accessor("enable_global_auditlog")
105+
return accessor(self)
106+
107+
@security.protected(permissions.ModifyPortalContent)
108+
def setEnableGlobalAuditlog(self, value):
109+
"""Enable/Disable global Auditlogging
110+
"""
111+
if value is False:
112+
# clear the auditlog catalog
113+
catalog = api.get_tool(AUDITLOG_CATALOG)
114+
catalog.manage_catalogClear()
115+
mutator = self.mutator("enable_global_auditlog")
116+
return mutator(self, value)

src/senaite/core/patches/catalog.py

+13
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,29 @@
33
from bika.lims import api
44
from plone.indexer.interfaces import IIndexableObject
55
from Products.ZCatalog.ZCatalog import ZCatalog
6+
from senaite.core.catalog import AUDITLOG_CATALOG
67
from zope.component import queryMultiAdapter
78

89

10+
def is_auditlog_enabled():
11+
setup = api.get_senaite_setup()
12+
if not setup:
13+
return False
14+
return setup.getEnableGlobalAuditlog()
15+
16+
917
def catalog_object(self, object, uid=None, idxs=None,
1018
update_metadata=1, pghandler=None):
1119

1220
# Never catalog temporary objects
1321
if api.is_temporary(object):
1422
return
1523

24+
# skip indexing auditlog catalog if disabled
25+
if self.id == AUDITLOG_CATALOG:
26+
if not is_auditlog_enabled():
27+
return
28+
1629
if idxs is None:
1730
idxs = []
1831
self._increment_counter()

0 commit comments

Comments
 (0)