Better handle policy timeouts
This commit is contained in:
parent
5b8e3689ec
commit
6be8d0cbb2
|
@ -1,7 +1,9 @@
|
||||||
"""passbook core policy engine"""
|
"""passbook core policy engine"""
|
||||||
from logging import getLogger
|
from logging import getLogger
|
||||||
|
|
||||||
|
from amqp.exceptions import UnexpectedFrame
|
||||||
from celery import group
|
from celery import group
|
||||||
|
from celery.exceptions import TimeoutError as CeleryTimeoutError
|
||||||
from ipware import get_client_ip
|
from ipware import get_client_ip
|
||||||
|
|
||||||
from passbook.core.celery import CELERY_APP
|
from passbook.core.celery import CELERY_APP
|
||||||
|
@ -38,6 +40,7 @@ class PolicyEngine:
|
||||||
_group = None
|
_group = None
|
||||||
_request = None
|
_request = None
|
||||||
_user = None
|
_user = None
|
||||||
|
_get_timeout = 0
|
||||||
|
|
||||||
def __init__(self, policies):
|
def __init__(self, policies):
|
||||||
self.policies = policies
|
self.policies = policies
|
||||||
|
@ -67,7 +70,14 @@ class PolicyEngine:
|
||||||
if not kwargs['remote_ip']:
|
if not kwargs['remote_ip']:
|
||||||
kwargs['remote_ip'] = '255.255.255.255'
|
kwargs['remote_ip'] = '255.255.255.255'
|
||||||
for policy in self.policies:
|
for policy in self.policies:
|
||||||
signatures.append(_policy_engine_task.s(self._user.pk, policy.pk.hex, **kwargs))
|
signatures.append(_policy_engine_task.signature(
|
||||||
|
args=(self._user.pk, policy.pk.hex),
|
||||||
|
kwargs=kwargs,
|
||||||
|
time_limit=policy.timeout))
|
||||||
|
self._get_timeout += policy.timeout
|
||||||
|
self._get_timeout += 3
|
||||||
|
self._get_timeout = (self._get_timeout / len(self.policies)) * 1.5
|
||||||
|
LOGGER.debug("Set total policy timeout to %r", self._get_timeout)
|
||||||
self._group = group(signatures)()
|
self._group = group(signatures)()
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
@ -76,10 +86,14 @@ class PolicyEngine:
|
||||||
"""Get policy-checking result"""
|
"""Get policy-checking result"""
|
||||||
messages = []
|
messages = []
|
||||||
try:
|
try:
|
||||||
# ValueError can be thrown from _policy_engine_task when user is None
|
group_result = self._group.get(timeout=self._get_timeout)
|
||||||
group_result = self._group.get()
|
|
||||||
except ValueError as exc:
|
except ValueError as exc:
|
||||||
return False, str(exc)
|
# ValueError can be thrown from _policy_engine_task when user is None
|
||||||
|
return False, [str(exc)]
|
||||||
|
except UnexpectedFrame as exc:
|
||||||
|
return False, [str(exc)]
|
||||||
|
except CeleryTimeoutError as exc:
|
||||||
|
return False, [str(exc)]
|
||||||
for policy_action, policy_result, policy_message in group_result:
|
for policy_action, policy_result, policy_message in group_result:
|
||||||
passing = (policy_action == Policy.ACTION_ALLOW and policy_result) or \
|
passing = (policy_action == Policy.ACTION_ALLOW and policy_result) or \
|
||||||
(policy_action == Policy.ACTION_DENY and not policy_result)
|
(policy_action == Policy.ACTION_DENY and not policy_result)
|
||||||
|
|
Reference in New Issue