Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
01c22531
Commit
01c22531
authored
Jul 22, 2015
by
cahrens
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add team permission check on commentable_id.
TNL-2864
parent
7a32fbc9
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
60 additions
and
46 deletions
+60
-46
lms/djangoapps/django_comment_client/base/tests.py
+0
-0
lms/djangoapps/django_comment_client/base/views.py
+2
-24
lms/djangoapps/django_comment_client/forum/tests.py
+4
-4
lms/djangoapps/django_comment_client/permissions.py
+44
-18
lms/lib/comment_client/commentable.py
+10
-0
No files found.
lms/djangoapps/django_comment_client/base/tests.py
View file @
01c22531
This diff is collapsed.
Click to expand it.
lms/djangoapps/django_comment_client/base/views.py
View file @
01c22531
...
...
@@ -51,6 +51,8 @@ def permitted(fn):
content
=
cc
.
Thread
.
find
(
kwargs
[
"thread_id"
])
.
to_dict
()
elif
"comment_id"
in
kwargs
:
content
=
cc
.
Comment
.
find
(
kwargs
[
"comment_id"
])
.
to_dict
()
elif
"commentable_id"
in
kwargs
:
content
=
cc
.
Commentable
.
find
(
kwargs
[
"commentable_id"
])
.
to_dict
()
else
:
content
=
None
return
content
...
...
@@ -608,16 +610,6 @@ def follow_commentable(request, course_id, commentable_id):
@require_POST
@login_required
@permitted
def
follow_user
(
request
,
course_id
,
followed_user_id
):
user
=
cc
.
User
.
from_django_user
(
request
.
user
)
followed_user
=
cc
.
User
.
find
(
followed_user_id
)
user
.
follow
(
followed_user
)
return
JsonResponse
({})
@require_POST
@login_required
@permitted
def
unfollow_thread
(
request
,
course_id
,
thread_id
):
"""
given a course id and thread id, stop following this thread
...
...
@@ -645,20 +637,6 @@ def unfollow_commentable(request, course_id, commentable_id):
@require_POST
@login_required
@permitted
def
unfollow_user
(
request
,
course_id
,
followed_user_id
):
"""
given a course id and user id, stop following this user
ajax only
"""
user
=
cc
.
User
.
from_django_user
(
request
.
user
)
followed_user
=
cc
.
User
.
find
(
followed_user_id
)
user
.
unfollow
(
followed_user
)
return
JsonResponse
({})
@require_POST
@login_required
@csrf.csrf_exempt
def
upload
(
request
,
course_id
):
# ajax upload file to a question or answer
"""view that handles file upload via Ajax
...
...
lms/djangoapps/django_comment_client/forum/tests.py
View file @
01c22531
...
...
@@ -333,11 +333,11 @@ class SingleThreadQueryCountTestCase(ModuleStoreTestCase):
@ddt.data
(
# old mongo with cache
(
ModuleStoreEnum
.
Type
.
mongo
,
1
,
7
,
5
,
1
3
,
8
),
(
ModuleStoreEnum
.
Type
.
mongo
,
50
,
7
,
5
,
1
3
,
8
),
(
ModuleStoreEnum
.
Type
.
mongo
,
1
,
7
,
5
,
1
4
,
8
),
(
ModuleStoreEnum
.
Type
.
mongo
,
50
,
7
,
5
,
1
4
,
8
),
# split mongo: 3 queries, regardless of thread response size.
(
ModuleStoreEnum
.
Type
.
split
,
1
,
3
,
3
,
1
3
,
8
),
(
ModuleStoreEnum
.
Type
.
split
,
50
,
3
,
3
,
1
3
,
8
),
(
ModuleStoreEnum
.
Type
.
split
,
1
,
3
,
3
,
1
4
,
8
),
(
ModuleStoreEnum
.
Type
.
split
,
50
,
3
,
3
,
1
4
,
8
),
)
@ddt.unpack
def
test_number_of_mongo_queries
(
...
...
lms/djangoapps/django_comment_client/permissions.py
View file @
01c22531
...
...
@@ -10,6 +10,7 @@ from lms.lib.comment_client import Thread
from
opaque_keys.edx.keys
import
CourseKey
from
django_comment_common.models
import
all_permissions_for_user_in_course
from
teams.models
import
CourseTeam
def
has_permission
(
user
,
permission
,
course_id
=
None
):
...
...
@@ -27,7 +28,7 @@ def has_permission(user, permission, course_id=None):
return
permission
in
all_permissions
CONDITIONS
=
[
'is_open'
,
'is_author'
,
'is_question_author'
]
CONDITIONS
=
[
'is_open'
,
'is_author'
,
'is_question_author'
,
'is_team_member_if_applicable'
]
def
_check_condition
(
user
,
condition
,
content
):
...
...
@@ -55,10 +56,37 @@ def _check_condition(user, condition, content):
except
KeyError
:
return
False
def
check_team_member
(
user
,
content
):
"""
If the content has a commentable_id, verifies that either it is not associated with a team,
or if it is, that the user is a member of that team.
"""
if
not
content
:
return
False
try
:
commentable_id
=
content
[
'commentable_id'
]
request_cache_dict
=
RequestCache
.
get_request_cache
()
.
data
cache_key
=
"django_comment_client.check_team_member.{}.{}"
.
format
(
user
.
id
,
commentable_id
)
if
cache_key
in
request_cache_dict
:
return
request_cache_dict
[
cache_key
]
team
=
CourseTeam
.
objects
.
get
(
discussion_topic_id
=
commentable_id
)
passes_condition
=
team
.
users
.
filter
(
id
=
user
.
id
)
.
count
()
>
0
request_cache_dict
[
cache_key
]
=
passes_condition
except
KeyError
:
# We do not expect KeyError in production-- it usually indicates an improper test mock.
logging
.
warning
(
"Did not find key commentable_id in content."
)
passes_condition
=
False
except
CourseTeam
.
DoesNotExist
:
passes_condition
=
True
request_cache_dict
[
cache_key
]
=
passes_condition
return
passes_condition
handlers
=
{
'is_open'
:
check_open
,
'is_author'
:
check_author
,
'is_question_author'
:
check_question_author
,
'is_team_member_if_applicable'
:
check_team_member
}
return
handlers
[
condition
](
user
,
content
)
...
...
@@ -88,30 +116,28 @@ def _check_conditions_permissions(user, permissions, course_id, content):
VIEW_PERMISSIONS
=
{
'update_thread'
:
[
'edit_content'
,
[
'update_thread'
,
'is_open'
,
'is_author'
]],
'create_comment'
:
[[
"create_comment"
,
"is_open"
]],
'create_comment'
:
[[
"create_comment"
,
"is_open"
,
"is_team_member_if_applicable"
]],
'delete_thread'
:
[
'delete_thread'
,
[
'update_thread'
,
'is_author'
]],
'update_comment'
:
[
'edit_content'
,
[
'update_comment'
,
'is_open'
,
'is_author'
]],
'endorse_comment'
:
[
'endorse_comment'
,
'is_question_author'
],
'openclose_thread'
:
[
'openclose_thread'
],
'create_sub_comment'
:
[[
'create_sub_comment'
,
'is_open'
]],
'create_sub_comment'
:
[[
'create_sub_comment'
,
'is_open'
,
'is_team_member_if_applicable'
]],
'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'
],
'un_flag_abuse_for_thread'
:
[
'vote'
],
'flag_abuse_for_comment'
:
[
'vote'
],
'un_flag_abuse_for_comment'
:
[
'vote'
],
'undo_vote_for_thread'
:
[[
'unvote'
,
'is_open'
]],
'vote_for_comment'
:
[[
'vote'
,
'is_open'
,
'is_team_member_if_applicable'
]],
'undo_vote_for_comment'
:
[[
'unvote'
,
'is_open'
,
'is_team_member_if_applicable'
]],
'vote_for_thread'
:
[[
'vote'
,
'is_open'
,
'is_team_member_if_applicable'
]],
'flag_abuse_for_thread'
:
[
[
'vote'
,
'is_team_member_if_applicable'
]
],
'un_flag_abuse_for_thread'
:
[
[
'vote'
,
'is_team_member_if_applicable'
]
],
'flag_abuse_for_comment'
:
[
[
'vote'
,
'is_team_member_if_applicable'
]
],
'un_flag_abuse_for_comment'
:
[
[
'vote'
,
'is_team_member_if_applicable'
]
],
'undo_vote_for_thread'
:
[[
'unvote'
,
'is_open'
,
'is_team_member_if_applicable'
]],
'pin_thread'
:
[
'openclose_thread'
],
'un_pin_thread'
:
[
'openclose_thread'
],
'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'
],
'follow_thread'
:
[[
'follow_thread'
,
'is_team_member_if_applicable'
]],
'follow_commentable'
:
[[
'follow_commentable'
,
'is_team_member_if_applicable'
]],
'unfollow_thread'
:
[[
'unfollow_thread'
,
'is_team_member_if_applicable'
]],
'unfollow_commentable'
:
[[
'unfollow_commentable'
,
'is_team_member_if_applicable'
]],
'create_thread'
:
[[
'create_thread'
,
'is_team_member_if_applicable'
]],
}
...
...
lms/lib/comment_client/commentable.py
View file @
01c22531
...
...
@@ -5,5 +5,15 @@ from lms.lib.comment_client import settings
class
Commentable
(
models
.
Model
):
accessible_fields
=
[
'id'
,
'commentable_id'
]
base_url
=
"{prefix}/commentables"
.
format
(
prefix
=
settings
.
PREFIX
)
type
=
'commentable'
def
retrieve
(
self
,
*
args
,
**
kwargs
):
"""
Override default behavior because commentables don't actually exist in the comment service.
"""
self
.
attributes
[
"commentable_id"
]
=
self
.
attributes
[
"id"
]
self
.
retrieved
=
True
return
self
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment