take advantage of the cache to store parsed grants. This allows to limit the...

take advantage of the cache to store parsed grants. This allows to limit the size of the pre-computed grants
parent c7085d9e
......@@ -54,6 +54,7 @@ class ACLloader(BUIaclLoader):
section=self.section
)
meta_grants.options = opts
meta_grants.init_app(app)
if self.app.acl_engine and 'none' not in self.app.acl_engine:
me, _ = os.path.splitext(os.path.basename(__file__))
back = self.app.acl_engine
......
......@@ -50,7 +50,13 @@ class BUIaclLoader(with_metaclass(ABCMeta, object)):
:param app: Application context
:type app: :class:`burpui.server.BUIServer`
"""
pass # pragma: no cover
self.app = None
if app: # pragma: no cover
self.init_app(app)
def init_app(self, app):
"""Register the given app"""
self.app = app
@abstractmethod
def reload(self):
......@@ -81,6 +87,21 @@ class BUIacl(with_metaclass(ABCMeta, object)):
engine.
"""
def __init__(self, app=None):
""":func:`burpui.misc.acl.interface.BUIacl.__init__` instanciate
the ACL.
:param app: Application context
:type app: :class:`burpui.server.BUIServer`
"""
self.app = None
if app: # pragma: no cover
self.init_app(app)
def init_app(self, app):
"""Register the given app"""
self.app = app
@abstractmethod
def is_admin(self, username=None):
""":func:`burpui.misc.acl.interface.BUIacl.is_admin` is used to know if
......
......@@ -10,6 +10,7 @@
from .interface import BUIacl
from ...utils import make_list
from ...config import config
from ...ext.cache import cache
from six import iteritems, itervalues
......@@ -172,15 +173,11 @@ class BUIgrantHandler(BUImetaGrant, BUIacl):
_grants = {}
_groups = {}
_parsed_grants = []
_clients_cache = {}
_agents_cache = {}
_advanced_cache = {}
_options = {}
_backends = {}
_name = 'meta_grant'
@property
def id(self):
"""current handler id, used to detect configuration changes"""
......@@ -216,10 +213,7 @@ class BUIgrantHandler(BUImetaGrant, BUIacl):
"""a configuration change occurred, we reload our grants and groups"""
self._grants.clear()
self._groups.clear()
self._parsed_grants = []
self._clients_cache.clear()
self._agents_cache.clear()
self._advanced_cache.clear()
self._reset_cached()
self._id += 1
for name, backend in iteritems(self._backends):
if name == reset_from:
......@@ -277,8 +271,27 @@ class BUIgrantHandler(BUImetaGrant, BUIacl):
groups.append((group.name, inh))
return groups
def _gen_key(self, username):
return '{}-{}'.format(self._name, username)
def _set_cached(self, username, value):
key = self._gen_key(username)
return cache.cache.set(key, value)
def _get_cached(self, username):
key = self._gen_key(username)
return cache.cache.get(key)
def _reset_cached(self):
cache.clear()
def _is_cached(self, username):
key = self._gen_key(username)
return cache.cache.has(key)
def _extract_grants(self, username, parent=None):
if username not in self._parsed_grants:
if not self._is_cached(username):
data = {}
if username in self.grants:
grants = self.grants[username].grants
......@@ -286,24 +299,23 @@ class BUIgrantHandler(BUImetaGrant, BUIacl):
grants = []
clients, agents, advanced = self._parse_clients(grants)
self._clients_cache[username] = clients
self._agents_cache[username] = agents
self._advanced_cache[username] = [advanced]
data['clients'] = clients
data['agents'] = agents
data['advanced'] = [advanced] if advanced else []
def __merge_grants_with(grp, prt):
if grp not in self._parsed_grants:
self._extract_grants(grp, prt)
self._clients_cache[username] = self._merge_data(
self._clients_cache[username],
self._clients_cache.get(grp, [])
data2 = self._extract_grants(grp, prt)
data['clients'] = self._merge_data(
data['clients'],
data2['clients']
)
self._agents_cache[username] = self._merge_data(
self._agents_cache[username],
self._agents_cache.get(grp, [])
data['agents'] = self._merge_data(
data['agents'],
data2['agents']
)
tmp = self._advanced_cache.get(grp, False)
if tmp is not False:
self._advanced_cache[username] += tmp
tmp = data2['advanced']
if tmp:
data['advanced'] += tmp
# moderator is also a group
for gname, group in iteritems(self.groups):
......@@ -318,22 +330,20 @@ class BUIgrantHandler(BUImetaGrant, BUIacl):
if ret and gname != username and parent and gname not in parent:
__merge_grants_with(gname, parent)
self._parsed_grants.append(username)
self._set_cached(username, data)
return data
return self._get_cached(username)
def _extract_clients(self, username):
if username not in self._parsed_grants:
self._extract_grants(username)
return self._clients_cache.get(username, [])
ret = self._extract_grants(username)
return ret.get('clients', [])
def _extract_agents(self, username):
if username not in self._parsed_grants:
self._extract_grants(username)
return self._agents_cache.get(username, [])
ret = self._extract_grants(username)
return ret.get('advanced', [])
def _extract_advanced(self, username, idx=None):
if username not in self._parsed_grants:
self._extract_grants(username)
ret = self._advanced_cache.get(username, [])
ret = self._extract_grants(username).get('advanced', [])
if idx is not None:
return ret[idx]
if self.opt('inverse_inheritance'):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment