Files
edx-platform/lms/djangoapps/django_comment_client/permissions.py
Greg Price cec58f885b Remove forum user profile moderator toggle button
This button has been broken for at least a year, so the code has
suffered from bit rot and should be reimplmemented if the feature is
necessary in the short term (which is unlikely since it has been broken
for so long).
2013-12-09 10:23:21 -05:00

114 lines
4.0 KiB
Python

"""
Module for checking permissions with the comment_client backend
"""
import logging
from django.core import cache
CACHE = cache.get_cache('default')
CACHE_LIFESPAN = 60
def cached_has_permission(user, permission, course_id=None):
"""
Call has_permission if it's not cached. A change in a user's role or
a role's permissions will only become effective after CACHE_LIFESPAN seconds.
"""
key = "permission_%d_%s_%s" % (user.id, str(course_id), permission)
val = CACHE.get(key, None)
if val not in [True, False]:
val = has_permission(user, permission, course_id=course_id)
CACHE.set(key, val, CACHE_LIFESPAN)
return val
def has_permission(user, permission, course_id=None):
for role in user.roles.filter(course_id=course_id):
if role.has_permission(permission):
return True
return False
CONDITIONS = ['is_open', 'is_author']
def check_condition(user, condition, course_id, data):
def check_open(user, condition, course_id, data):
try:
return data and not data['content']['closed']
except KeyError:
return False
def check_author(user, condition, course_id, data):
try:
return data and data['content']['user_id'] == str(user.id)
except KeyError:
return False
handlers = {
'is_open': check_open,
'is_author': check_author,
}
return handlers[condition](user, condition, course_id, data)
def check_conditions_permissions(user, permissions, course_id, **kwargs):
"""
Accepts a list of permissions and proceed if any of the permission is valid.
Note that ["can_view", "can_edit"] will proceed if the user has either
"can_view" or "can_edit" permission. To use AND operator in between, wrap them in
a list.
"""
def test(user, per, operator="or"):
if isinstance(per, basestring):
if per in CONDITIONS:
return check_condition(user, per, course_id, kwargs)
return cached_has_permission(user, per, course_id=course_id)
elif isinstance(per, list) and operator in ["and", "or"]:
results = [test(user, x, operator="and") for x in per]
if operator == "or":
return True in results
elif operator == "and":
return not False in results
return test(user, permissions, operator="or")
VIEW_PERMISSIONS = {
'update_thread': ['edit_content', ['update_thread', 'is_open', 'is_author']],
'create_comment': [["create_comment", "is_open"]],
'delete_thread': ['delete_thread', ['update_thread', 'is_author']],
'update_comment': ['edit_content', ['update_comment', 'is_open', 'is_author']],
'endorse_comment': ['endorse_comment'],
'openclose_thread': ['openclose_thread'],
'create_sub_comment': [['create_sub_comment', 'is_open']],
'delete_comment': ['delete_comment', ['update_comment', 'is_open', 'is_author']],
'vote_for_comment': [['vote', 'is_open']],
'undo_vote_for_comment': [['unvote', 'is_open']],
'vote_for_thread': [['vote', 'is_open']],
'flag_abuse_for_thread': [['vote', 'is_open']],
'un_flag_abuse_for_thread': [['vote', 'is_open']],
'flag_abuse_for_comment': [['vote', 'is_open']],
'un_flag_abuse_for_comment': [['vote', 'is_open']],
'undo_vote_for_thread': [['unvote', 'is_open']],
'pin_thread': ['create_comment'],
'un_pin_thread': ['create_comment'],
'follow_thread': ['follow_thread'],
'follow_commentable': ['follow_commentable'],
'follow_user': ['follow_user'],
'unfollow_thread': ['unfollow_thread'],
'unfollow_commentable': ['unfollow_commentable'],
'unfollow_user': ['unfollow_user'],
'create_thread': ['create_thread'],
}
def check_permissions_by_view(user, course_id, content, name):
try:
p = VIEW_PERMISSIONS[name]
except KeyError:
logging.warning("Permission for view named %s does not exist in permissions.py" % name)
return check_conditions_permissions(user, p, course_id, content=content)