core: fix saving of policy not correctly clearing it's cache

This commit is contained in:
Jens Langhammer 2020-02-24 13:15:27 +01:00
parent f8599438df
commit 4daa70c894
3 changed files with 15 additions and 8 deletions

View File

@ -18,9 +18,11 @@ password_changed = Signal(providing_args=["user", "password"])
def invalidate_policy_cache(sender, instance, **_): def invalidate_policy_cache(sender, instance, **_):
"""Invalidate Policy cache when policy is updated""" """Invalidate Policy cache when policy is updated"""
from passbook.core.models import Policy from passbook.core.models import Policy
from passbook.policies.process import cache_key
if isinstance(instance, Policy): if isinstance(instance, Policy):
LOGGER.debug("Invalidating policy cache", policy=instance) LOGGER.debug("Invalidating policy cache", policy=instance)
keys = cache.keys("%s#*" % instance.pk) prefix = cache_key(instance) + "*"
keys = cache.keys(prefix)
cache.delete_many(keys) cache.delete_many(keys)
LOGGER.debug("Deleted %d keys", len(keys)) LOGGER.debug("Deleted %d keys", len(keys))

View File

@ -5,16 +5,19 @@ from multiprocessing.connection import Connection
from django.core.cache import cache from django.core.cache import cache
from structlog import get_logger from structlog import get_logger
from passbook.core.models import Policy from passbook.core.models import Policy, User
from passbook.policies.exceptions import PolicyException from passbook.policies.exceptions import PolicyException
from passbook.policies.types import PolicyRequest, PolicyResult from passbook.policies.types import PolicyRequest, PolicyResult
LOGGER = get_logger() LOGGER = get_logger()
def cache_key(policy, user): def cache_key(policy: Policy, user: User = None) -> str:
"""Generate Cache key for policy""" """Generate Cache key for policy"""
return f"policy_{policy.pk}#{user.pk}" prefix = f"policy_{policy.pk}"
if user:
prefix += f"#{user.pk}"
return prefix
class PolicyProcess(Process): class PolicyProcess(Process):
@ -33,7 +36,7 @@ class PolicyProcess(Process):
def run(self): def run(self):
"""Task wrapper to run policy checking""" """Task wrapper to run policy checking"""
LOGGER.debug( LOGGER.debug(
"Running policy", "P_ENG(proc): Running policy",
policy=self.policy, policy=self.policy,
user=self.request.user, user=self.request.user,
process="PolicyProcess", process="PolicyProcess",
@ -41,13 +44,13 @@ class PolicyProcess(Process):
try: try:
policy_result = self.policy.passes(self.request) policy_result = self.policy.passes(self.request)
except PolicyException as exc: except PolicyException as exc:
LOGGER.debug(exc) LOGGER.debug("P_ENG(proc): error", exc=exc)
policy_result = PolicyResult(False, str(exc)) policy_result = PolicyResult(False, str(exc))
# Invert result if policy.negate is set # Invert result if policy.negate is set
if self.policy.negate: if self.policy.negate:
policy_result.passing = not policy_result.passing policy_result.passing = not policy_result.passing
LOGGER.debug( LOGGER.debug(
"Got result", "P_ENG(proc): Finished",
policy=self.policy, policy=self.policy,
result=policy_result, result=policy_result,
process="PolicyProcess", process="PolicyProcess",
@ -56,5 +59,5 @@ class PolicyProcess(Process):
) )
key = cache_key(self.policy, self.request.user) key = cache_key(self.policy, self.request.user)
cache.set(key, policy_result) cache.set(key, policy_result)
LOGGER.debug("Cached policy evaluation", key=key) LOGGER.debug("P_ENG(proc): Cached policy evaluation", key=key)
self.connection.send(policy_result) self.connection.send(policy_result)

View File

@ -19,6 +19,8 @@ class OIDCProviderForm(forms.ModelForm):
self.fields["client_secret"].initial = generate_client_secret() self.fields["client_secret"].initial = generate_client_secret()
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
self.instance.reuse_consent = False # This is managed by passbook
self.instance.require_consent = True # This is managed by passbook
response = super().save(*args, **kwargs) response = super().save(*args, **kwargs)
# Check if openidprovider class instance exists # Check if openidprovider class instance exists
if not OpenIDProvider.objects.filter(oidc_client=self.instance).exists(): if not OpenIDProvider.objects.filter(oidc_client=self.instance).exists():