Skip to content

Commit

Permalink
Merge fa50746 into 4e95b22
Browse files Browse the repository at this point in the history
  • Loading branch information
rafalp committed Dec 20, 2018
2 parents 4e95b22 + fa50746 commit e4d7e0e
Show file tree
Hide file tree
Showing 300 changed files with 5,802 additions and 5,797 deletions.
9 changes: 6 additions & 3 deletions devproject/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@
# Misago apps
'misago.admin',
'misago.acl',
'misago.cache',
'misago.core',
'misago.conf',
'misago.markup',
Expand Down Expand Up @@ -223,12 +224,14 @@
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',

'misago.cache.middleware.cache_versions_middleware',
'misago.conf.middleware.dynamic_settings_middleware',
'misago.users.middleware.UserMiddleware',
'misago.acl.middleware.user_acl_middleware',
'misago.core.middleware.ExceptionHandlerMiddleware',
'misago.users.middleware.OnlineTrackerMiddleware',
'misago.admin.middleware.AdminAuthMiddleware',
'misago.threads.middleware.UnreadThreadsCountMiddleware',
'misago.core.middleware.ThreadStoreMiddleware',
]

ROOT_URLCONF = 'devproject.urls'
Expand Down Expand Up @@ -283,12 +286,12 @@
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',

'misago.acl.context_processors.user_acl',
'misago.conf.context_processors.conf',
'misago.core.context_processors.site_address',
'misago.core.context_processors.momentjs_locale',
'misago.conf.context_processors.settings',
'misago.search.context_processors.search_providers',
'misago.users.context_processors.user_links',
'misago.legal.context_processors.legal_links',

# Data preloaders
'misago.conf.context_processors.preload_settings_json',
Expand Down
3 changes: 1 addition & 2 deletions devproject/test_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@
# Use in-memory cache
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
'LOCATION': 'uniqu3-sn0wf14k3'
'BACKEND': 'django.core.cache.backends.dummy.DummyCache',
}
}

Expand Down
4 changes: 2 additions & 2 deletions misago/acl/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
from .api import get_user_acl, add_acl, serialize_acl

default_app_config = 'misago.acl.apps.MisagoACLsConfig'

ACL_CACHE = "acl"
65 changes: 0 additions & 65 deletions misago/acl/api.py

This file was deleted.

1 change: 1 addition & 0 deletions misago/acl/apps.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from django.apps import AppConfig
from .providers import providers


class MisagoACLsConfig(AppConfig):
name = 'misago.acl'
label = 'misago_acl'
Expand Down
File renamed without changes.
23 changes: 23 additions & 0 deletions misago/acl/cache.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from django.core.cache import cache

from misago.cache.versions import invalidate_cache

from . import ACL_CACHE


def get_acl_cache(user, cache_versions):
key = get_cache_key(user, cache_versions)
return cache.get(key)


def set_acl_cache(user, cache_versions, user_acl):
key = get_cache_key(user, cache_versions)
cache.set(key, user_acl)


def get_cache_key(user, cache_versions):
return 'acl_%s_%s' % (user.acl_key, cache_versions[ACL_CACHE])


def clear_acl_cache():
invalidate_cache(ACL_CACHE)
1 change: 0 additions & 1 deletion misago/acl/constants.py

This file was deleted.

2 changes: 2 additions & 0 deletions misago/acl/context_processors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
def user_acl(request):
return {"user_acl": request.user_acl}
12 changes: 12 additions & 0 deletions misago/acl/middleware.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from django.utils.functional import SimpleLazyObject

from . import useracl


def user_acl_middleware(get_response):
"""Sets request.user_acl attribute with dict containing current user acl."""
def middleware(request):
request.user_acl = useracl.get_user_acl(request.user, request.cache_versions)
return get_response(request)

return middleware
12 changes: 2 additions & 10 deletions misago/acl/migrations/0002_acl_version_tracker.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,12 @@
from django.db import migrations

from misago.acl.constants import ACL_CACHEBUSTER
from misago.core.migrationutils import cachebuster_register_cache


def register_acl_version_tracker(apps, schema_editor):
cachebuster_register_cache(apps, ACL_CACHEBUSTER)


class Migration(migrations.Migration):
"""Superseded by 0004"""

dependencies = [
('misago_acl', '0001_initial'),
('misago_core', '0001_initial'),
]

operations = [
migrations.RunPython(register_acl_version_tracker),
]
operations = []
17 changes: 17 additions & 0 deletions misago/acl/migrations/0004_cache_version.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# -*- coding: utf-8 -*-
from django.db import migrations

from misago.acl import ACL_CACHE
from misago.cache.operations import StartCacheVersioning


class Migration(migrations.Migration):

dependencies = [
('misago_acl', '0003_default_roles'),
('misago_cache', '0001_initial'),
]

operations = [
StartCacheVersioning(ACL_CACHE)
]
6 changes: 3 additions & 3 deletions misago/acl/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from django.db import models
from django.utils.translation import gettext as _

from . import version as acl_version
from .cache import clear_acl_cache


def permissions_default():
Expand All @@ -22,11 +22,11 @@ def __str__(self):

def save(self, *args, **kwargs):
if self.pk:
acl_version.invalidate()
clear_acl_cache()
return super().save(*args, **kwargs)

def delete(self, *args, **kwargs):
acl_version.invalidate()
clear_acl_cache()
return super().delete(*args, **kwargs)


Expand Down
18 changes: 18 additions & 0 deletions misago/acl/objectacl.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from .providers import providers


def add_acl_to_obj(user_acl, obj):
"""add valid ACL to obj (iterable of objects or single object)"""
if hasattr(obj, '__iter__'):
for item in obj:
_add_acl_to_obj(user_acl, item)
else:
_add_acl_to_obj(user_acl, obj)


def _add_acl_to_obj(user_acl, obj):
"""add valid ACL to single obj, helper for add_acl function"""
obj.acl = {}

for annotator in providers.get_obj_type_annotators(obj):
annotator(user_acl, obj)
2 changes: 1 addition & 1 deletion misago/acl/panels.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def process_response(self, request, response):
misago_user = None

try:
misago_acl = misago_user.acl_cache
misago_acl = request.user_acl
except AttributeError:
misago_acl = {}

Expand Down
28 changes: 15 additions & 13 deletions misago/acl/providers.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@

_NOT_INITIALIZED_ERROR = (
"PermissionProviders instance has to load providers with load() "
"before get_obj_type_annotators(), get_obj_type_serializers(), "
"before get_obj_type_annotators(), get_user_acl_serializers(), "
"list() or dict() methods will be available."
)

_ALREADY_INITIALIZED_ERROR = (
"PermissionProviders instance has already loaded providers and "
"acl_annotator or acl_serializer are no longer available."
"acl_annotator or user_acl_serializer are no longer available."
)


Expand All @@ -24,14 +24,16 @@ def __init__(self):
self._providers_dict = {}

self._annotators = {}
self._serializers = {}
self._user_acl_serializers = []

def load(self):
if not self._initialized:
self._register_providers()
self._change_lists_to_tupes(self._annotators)
self._change_lists_to_tupes(self._serializers)
self._initialized = True
if self._initialized:
raise RuntimeError("providers are already loaded")

self._register_providers()
self._coerce_dict_values_to_tuples(self._annotators)
self._user_acl_serializers = tuple(self._user_acl_serializers)
self._initialized = True

def _register_providers(self):
for namespace in settings.MISAGO_ACL_EXTENSIONS:
Expand All @@ -41,7 +43,7 @@ def _register_providers(self):
if hasattr(self._providers_dict[namespace], 'register_with'):
self._providers_dict[namespace].register_with(self)

def _change_lists_to_tupes(self, types_dict):
def _coerce_dict_values_to_tuples(self, types_dict):
for hashType in types_dict.keys():
types_dict[hashType] = tuple(types_dict[hashType])

Expand All @@ -50,18 +52,18 @@ def acl_annotator(self, hashable_type, func):
assert not self._initialized, _ALREADY_INITIALIZED_ERROR
self._annotators.setdefault(hashable_type, []).append(func)

def acl_serializer(self, hashable_type, func):
def user_acl_serializer(self, func):
"""registers ACL serializer for specified types"""
assert not self._initialized, _ALREADY_INITIALIZED_ERROR
self._serializers.setdefault(hashable_type, []).append(func)
self._user_acl_serializers.append(func)

def get_obj_type_annotators(self, obj):
assert self._initialized, _NOT_INITIALIZED_ERROR
return self._annotators.get(obj.__class__, [])

def get_obj_type_serializers(self, obj):
def get_user_acl_serializers(self):
assert self._initialized, _NOT_INITIALIZED_ERROR
return self._serializers.get(obj.__class__, [])
return self._user_acl_serializers

def list(self):
assert self._initialized, _NOT_INITIALIZED_ERROR
Expand Down
56 changes: 56 additions & 0 deletions misago/acl/test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
from contextlib import ContextDecorator, ExitStack, contextmanager
from functools import wraps
from unittest.mock import patch

from .useracl import get_user_acl

__all__ = ["patch_user_acl"]


class patch_user_acl(ContextDecorator, ExitStack):
"""Testing utility that patches get_user_acl results
Can be used as decorator or context manager.
Patch should be a dict or callable.
"""

_acl_patches = []

def __init__(self, acl_patch):
super().__init__()
self.acl_patch = acl_patch

def patched_get_user_acl(self, user, cache_versions):
user_acl = get_user_acl(user, cache_versions)
self.apply_acl_patches(user, user_acl)
return user_acl

def apply_acl_patches(self, user, user_acl):
for acl_patch in self._acl_patches:
self.apply_acl_patch(user, user_acl, acl_patch)

def apply_acl_patch(self, user, user_acl, acl_patch):
if callable(acl_patch):
acl_patch(user, user_acl)
else:
user_acl.update(acl_patch)

def __enter__(self):
super().__enter__()
self.enter_context(self.enable_acl_patch())
self.enter_context(self.patch_user_acl())

@contextmanager
def enable_acl_patch(self):
try:
self._acl_patches.append(self.acl_patch)
yield
finally:
self._acl_patches.pop(-1)

def patch_user_acl(self):
return patch(
"misago.acl.useracl.get_user_acl",
side_effect=self.patched_get_user_acl,
)

0 comments on commit e4d7e0e

Please sign in to comment.