Merge pull request #2881 from ostcar/has_perm_with_id

Changed the function has_perm to support an user id or None as the fi…
This commit is contained in:
Norman Jäckel 2017-01-24 22:17:12 +01:00 committed by GitHub
commit e0d5f6d92f
9 changed files with 51 additions and 23 deletions

View File

@ -16,6 +16,7 @@ before_install:
install:
- pip install --upgrade setuptools
- pip install --upgrade --requirement requirements.txt
- pip freeze
- npm install
- node_modules/.bin/gulp --production
script:

View File

@ -99,6 +99,8 @@ Other:
- Support https as websocket protocol (wss).
- Added migration path from 2.0.
- Accelerated startup process (send all data to the client after login).
- Added function utils.auth.anonymous_is_enabled which returns true, if it is.
- Changed has_perm to support an user id or None (for anyonmous) as first argument.
Version 2.0 (2016-04-18)

View File

@ -1,5 +1,5 @@
from ..utils.access_permissions import BaseAccessPermissions
from ..utils.auth import DjangoAnonymousUser, has_perm
from ..utils.auth import DjangoAnonymousUser, anonymous_is_enabled, has_perm
class ProjectorAccessPermissions(BaseAccessPermissions):
@ -29,11 +29,9 @@ class TagAccessPermissions(BaseAccessPermissions):
"""
Returns True if the user has read access model instances.
"""
from .config import config
# Every authenticated user can retrieve tags. Anonymous users can do
# so if they are enabled.
return not isinstance(user, DjangoAnonymousUser) or config['general_system_enable_anonymous']
return not isinstance(user, DjangoAnonymousUser) or anonymous_is_enabled()
def get_serializer_class(self, user=None):
"""
@ -112,11 +110,9 @@ class ConfigAccessPermissions(BaseAccessPermissions):
"""
Returns True if the user has read access model instances.
"""
from .config import config
# Every authenticated user can see the metadata and list or retrieve
# the config. Anonymous users can do so if they are enabled.
return not isinstance(user, DjangoAnonymousUser) or config['general_system_enable_anonymous']
return not isinstance(user, DjangoAnonymousUser) or anonymous_is_enabled()
def get_full_data(self, instance):
"""

View File

@ -17,6 +17,7 @@ from django.utils.translation import ugettext as _
from .. import __version__ as version
from ..utils import views as utils_views
from ..utils.auth import anonymous_is_enabled
from ..utils.autoupdate import inform_changed_data, inform_deleted_data
from ..utils.collection import Collection, CollectionElement
from ..utils.plugins import (
@ -573,7 +574,7 @@ class TagViewSet(ModelViewSet):
elif self.action == 'metadata':
# Every authenticated user can see the metadata.
# Anonymous users can do so if they are enabled.
result = self.request.user.is_authenticated() or config['general_system_enable_anonymous']
result = self.request.user.is_authenticated() or anonymous_is_enabled()
elif self.action in ('create', 'update', 'destroy'):
result = self.request.user.has_perm('core.can_manage_tags')
else:
@ -630,7 +631,7 @@ class ConfigViewSet(ViewSet):
# Every authenticated user can see the metadata and list or
# retrieve the config. Anonymous users can do so if they are
# enabled.
result = self.request.user.is_authenticated() or config['general_system_enable_anonymous']
result = self.request.user.is_authenticated() or anonymous_is_enabled()
elif self.action == 'update':
result = self.request.user.has_perm('core.can_manage_config')
else:

View File

@ -1,5 +1,5 @@
from ..utils.access_permissions import BaseAccessPermissions
from ..utils.auth import DjangoAnonymousUser, has_perm
from ..utils.auth import DjangoAnonymousUser, anonymous_is_enabled, has_perm
class UserAccessPermissions(BaseAccessPermissions):
@ -90,14 +90,12 @@ class GroupAccessPermissions(BaseAccessPermissions):
"""
Returns True if the user has read access model instances.
"""
from ..core.config import config
# Every authenticated user can retrieve groups. Anonymous users can do
# so if they are enabled.
# Our AnonymousUser is a subclass of the DjangoAnonymousUser. Normaly, a
# DjangoAnonymousUser means, that AnonymousUser is disabled. But this is
# no garanty. send_data uses the AnonymousUser in any case.
return not isinstance(user, DjangoAnonymousUser) or config['general_system_enable_anonymous']
return not isinstance(user, DjangoAnonymousUser) or anonymous_is_enabled()
def get_serializer_class(self, user=None):
"""

View File

@ -5,6 +5,7 @@ from django.utils.encoding import force_text
from django.utils.translation import ugettext as _
from ..core.config import config
from ..utils.auth import anonymous_is_enabled
from ..utils.collection import CollectionElement
from ..utils.rest_api import (
ModelViewSet,
@ -137,7 +138,7 @@ class GroupViewSet(ModelViewSet):
elif self.action == 'metadata':
# Every authenticated user can see the metadata.
# Anonymous users can do so if they are enabled.
result = self.request.user.is_authenticated() or config['general_system_enable_anonymous']
result = self.request.user.is_authenticated() or anonymous_is_enabled()
elif self.action in ('create', 'partial_update', 'update', 'destroy'):
# Users with all app permissions can edit groups.
result = (self.request.user.has_perm('users.can_see_name') and
@ -247,7 +248,7 @@ class WhoAmIView(APIView):
user_data = None
return super().get_context_data(
user_id=user_id,
guest_enabled=config['general_system_enable_anonymous'],
guest_enabled=anonymous_is_enabled(),
user=user_data,
**context)

View File

@ -62,12 +62,11 @@ class RESTFrameworkAnonymousAuthentication(BaseAuthentication):
Authentication class for the Django REST framework.
Sets the user to the our AnonymousUser but only if
general_system_enable_anonymous is set to True in the config.
anonymous user is enabled in the config.
"""
def authenticate(self, request):
from ..core.config import config
if config['general_system_enable_anonymous']:
if anonymous_is_enabled():
return (AnonymousUser(), None)
return None
@ -99,13 +98,12 @@ def get_user(request):
This is a mix of django.contrib.auth.get_user and
django.contrib.auth.middleware.get_user which uses our anonymous user.
"""
from ..core.config import config
try:
return_user = request._cached_user
except AttributeError:
# Get the user. If it is a DjangoAnonymousUser, then use our AnonymousUser
return_user = _get_user(request)
if config['general_system_enable_anonymous'] and isinstance(return_user, DjangoAnonymousUser):
if anonymous_is_enabled() and isinstance(return_user, DjangoAnonymousUser):
return_user = AnonymousUser()
request._cached_user = return_user
return return_user
@ -114,7 +112,18 @@ def get_user(request):
def has_perm(user, perm):
"""
Checks that user has a specific permission.
User can be an user object, an user id None (for anonymous) or a
CollectionElement for a user.
"""
# First, convert a user id or None to an anonymous user or an CollectionElement
if user is None and anonymous_is_enabled():
user = AnonymousUser()
elif user is None:
user = DjangoAnonymousUser()
elif isinstance(user, int):
user = CollectionElement.from_values('users/user', user)
if isinstance(user, AnonymousUser):
# Our anonymous user has a has_perm-method that works with the cache
# system. So we can use it here.
@ -142,3 +151,8 @@ def has_perm(user, perm):
else:
has_perm = False
return has_perm
def anonymous_is_enabled():
from ..core.config import config
return config['general_system_enable_anonymous']

View File

@ -9,7 +9,7 @@ from django.db import transaction
from ..core.config import config
from ..core.models import Projector
from .auth import AnonymousUser
from .auth import AnonymousUser, anonymous_is_enabled
from .cache import websocket_user_cache
from .collection import Collection, CollectionElement, CollectionElementList
@ -40,7 +40,7 @@ def ws_add_site(message):
# Skip apps that do not implement get_startup_elements
continue
for collection in get_startup_elements():
output.extend(collection.as_autoupdate_for_user(message.user))
output.extend(collection.as_autoupdate_for_user(message.user.id))
# Send all data. If there is no data, then only accept the connection
if output:
@ -66,7 +66,7 @@ def ws_add_projector(message, projector_id):
"""
user = message.user
# user is the django anonymous user. We have our own.
if user.is_anonymous and config['general_system_enable_anonymous']:
if user.is_anonymous and anonymous_is_enabled():
user = AnonymousUser()
if not user.has_perm('core.can_see_projector'):

View File

@ -117,6 +117,9 @@ class CollectionElement:
"""
Returns a dict that can be sent through the autoupdate system for a site
user.
The argument `user` can be anything, that is allowd as argument for
utils.auth.has_perm().
"""
return self.as_autoupdate(
'get_restricted_data',
@ -133,6 +136,9 @@ class CollectionElement:
def as_dict_for_user(self, user):
"""
Returns a dict with the data for a user. Can be used for the rest api.
The argument `user` can be anything, that is allowd as argument for
utils.auth.has_perm().
"""
return self.get_access_permissions().get_restricted_data(
self.get_full_data(),
@ -259,6 +265,9 @@ class CollectionElementList(list):
def as_autoupdate_for_user(self, user):
"""
Returns a list of dicts, that can be send though the websocket to a user.
The argument `user` can be anything, that is allowd as argument for
utils.auth.has_perm().
"""
result = []
for element in self:
@ -355,6 +364,9 @@ class Collection:
def as_autoupdate_for_user(self, user):
"""
Returns a list of dicts, that can be send though the websocket to a user.
The argument `user` can be anything, that is allowd as argument for
utils.auth.has_perm().
"""
output = []
for collection_element in self.element_generator():
@ -367,6 +379,9 @@ class Collection:
"""
Returns a list of dictonaries to send them to a user, for example over
the rest api.
The argument `user` can be anything, that is allowd as argument for
utils.auth.has_perm().
"""
output = []
for collection_element in self.element_generator():