Fixed get_projector_data impementation. Closed #3282.

This commit is contained in:
Norman Jäckel 2017-06-13 21:44:45 +02:00
parent 7947f2ed34
commit eaebeb8f06
7 changed files with 147 additions and 42 deletions

View File

@ -89,13 +89,32 @@ class ItemAccessPermissions(BaseAccessPermissions):
return restricted_data
def get_projector_data(self, full_data):
def get_projector_data(self, container):
"""
Returns the restricted serialized data for the instance prepared
for the projector. Removes field 'comment'.
"""
data = {}
for key in full_data.keys():
if key != 'comment':
data[key] = full_data[key]
return data
def filtered_data(full_data, blocked_keys):
"""
Returns a new dict like full_data but with all blocked_keys removed.
"""
whitelist = full_data.keys() - blocked_keys
return {key: full_data[key] for key in whitelist}
# Expand full_data to a list if it is not one.
full_data = container.get_full_data() if isinstance(container, Collection) else [container.get_full_data()]
# Parse data.
blocked_keys = ('comment',)
data = [filtered_data(full, blocked_keys) for full in full_data]
# Reduce result to a single item or None if it was not a collection at
# the beginning of the method.
if isinstance(container, Collection):
projector_data = data
elif data:
projector_data = data[0]
else:
projector_data = None
return projector_data

View File

@ -58,11 +58,28 @@ class AssignmentAccessPermissions(BaseAccessPermissions):
return restricted_data
def get_projector_data(self, full_data):
def get_projector_data(self, container):
"""
Returns the restricted serialized data for the instance prepared
for the projector. Removes several fields.
for the projector. Removes unpublished polls.
"""
data = full_data.copy()
data['polls'] = [poll for poll in data['polls'] if poll['published']]
return data
# Expand full_data to a list if it is not one.
full_data = container.get_full_data() if isinstance(container, Collection) else [container.get_full_data()]
# Parse data. Exclude unpublished polls.
data = []
for full in full_data:
full_copy = full.copy()
full_copy['polls'] = [poll for poll in full['polls'] if poll['published']]
data.append(full_copy)
# Reduce result to a single item or None if it was not a collection at
# the beginning of the method.
if isinstance(container, Collection):
projector_data = data
elif data:
projector_data = data[0]
else:
projector_data = None
return projector_data

View File

@ -96,21 +96,41 @@ class MotionAccessPermissions(BaseAccessPermissions):
return restricted_data
def get_projector_data(self, full_data):
def get_projector_data(self, container):
"""
Returns the restricted serialized data for the instance prepared
for the projector. Removes several fields.
for the projector. Removes several comment fields.
"""
data = full_data.copy()
if data.get('comments') is not None:
# Expand full_data to a list if it is not one.
full_data = container.get_full_data() if isinstance(container, Collection) else [container.get_full_data()]
# Parse data.
data = []
for full in full_data:
# Set private comment fields to None.
if full.get('comments') is not None:
full_copy = deepcopy(full)
for i, field in enumerate(config['motions_comments']):
if not field.get('public'):
try:
data['comments'][i] = None
full_copy['comments'][i] = None
except IndexError:
# No data in range. Just do nothing.
pass
return data
data.append(full_copy)
else:
data.append(full)
# Reduce result to a single item or None if it was not a collection at
# the beginning of the method.
if isinstance(container, Collection):
projector_data = data
elif data:
projector_data = data[0]
else:
projector_data = None
return projector_data
class MotionChangeRecommendationAccessPermissions(BaseAccessPermissions):

View File

@ -102,19 +102,38 @@ class UserAccessPermissions(BaseAccessPermissions):
return restricted_data
def get_projector_data(self, full_data):
def get_projector_data(self, container):
"""
Returns the restricted serialized data for the instance prepared
for the projector. Removes several fields.
"""
from .serializers import USERCANSEESERIALIZER_FIELDS
# Let only some fields pass this method.
data = {}
for key in full_data.keys():
if key in USERCANSEESERIALIZER_FIELDS:
data[key] = full_data[key]
return data
def filtered_data(full_data, whitelist):
"""
Returns a new dict like full_data but only with whitelisted keys.
"""
return {key: full_data[key] for key in whitelist}
# Expand full_data to a list if it is not one.
full_data = container.get_full_data() if isinstance(container, Collection) else [container.get_full_data()]
# Parse data.
litte_data_fields = set(USERCANSEESERIALIZER_FIELDS)
litte_data_fields.add('groups_id')
litte_data_fields.discard('groups')
data = [filtered_data(full, litte_data_fields) for full in full_data]
# Reduce result to a single item or None if it was not a collection at
# the beginning of the method.
if isinstance(container, Collection):
projector_data = data
elif data:
projector_data = data[0]
else:
projector_data = None
return projector_data
class GroupAccessPermissions(BaseAccessPermissions):

View File

@ -82,10 +82,10 @@ class BaseAccessPermissions(object, metaclass=SignalConnectMetaClass):
data = None
return data
def get_projector_data(self, full_data):
def get_projector_data(self, container):
"""
Returns the serialized data for the projector. Returns None if the
user has no access to this specific data. Returns reduced data if
the user has limited access. Default: Returns full data.
"""
return full_data
return container.get_full_data()

View File

@ -102,18 +102,9 @@ class CollectionElement:
"""
from .autoupdate import format_for_autoupdate
# TODO: Revert this after get_projector_data is also enhanced like get_restricted_data. See also #3282.
if method == 'get_restricted_data':
container = self
elif not self.is_deleted():
container = self.get_full_data()
else:
container = None
# End of hack
if not self.is_deleted():
data = getattr(self.get_access_permissions(), method)(
container,
self,
*args)
else:
data = None

View File

@ -0,0 +1,39 @@
from unittest import TestCase
from openslides.users.access_permissions import UserAccessPermissions
from openslides.utils.collection import CollectionElement
class UserGetProjectorDataTest(TestCase):
def test_get_projector_data_with_collection(self):
"""
This test ensures that comment field is removed.
"""
container = CollectionElement.from_values('users/user', 42, full_data={
'id': 42,
'username': 'username_ai3Oofu7eit0eeyu1sie',
'title': '',
'first_name': 'first_name_iu8toShae0oolie8aevo',
'last_name': 'last_name_OhZ4beezohY0doNoh2th',
'structure_level': '',
'number': '',
'about_me': '',
'groups_id': [],
'is_present': False,
'is_committee': False,
'comment': 'comment_gah7aipeJohv9xethoku',
})
data = UserAccessPermissions().get_projector_data(container)
self.assertEqual(data, {
'id': 42,
'username': 'username_ai3Oofu7eit0eeyu1sie',
'title': '',
'first_name': 'first_name_iu8toShae0oolie8aevo',
'last_name': 'last_name_OhZ4beezohY0doNoh2th',
'structure_level': '',
'number': '',
'about_me': '',
'groups_id': [],
'is_present': False,
'is_committee': False,
})