Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
152 commits
Select commit Hold shift + click to select a range
9dd1828
Set empty aws credentials to None.
feanil Nov 8, 2013
2a31e35
sending template pdf with certificate request
jarv Nov 6, 2013
2fed618
fixing some typos
jarv Nov 6, 2013
1b7a871
Fixed password reset message
Nov 15, 2013
c8a9805
CSV Reporting of Shopping Cart Purchases, with tests
jbau Nov 16, 2013
41b73d8
Basic test fix
Nov 18, 2013
2e31ff8
Recover from error loading forum thread list
Nov 14, 2013
9593261
Add focus trap on forum navigation thread loading
Nov 14, 2013
e3b8ce7
changes to allow multiple choicetextresponses in one problem
robertjmarks Nov 18, 2013
fc46efb
Fix bug in grabbing course enrollments.
dianakhuang Nov 19, 2013
954ca83
Update AUTHORS
danielcebrian Nov 19, 2013
87238e6
Removed null bits
Nov 19, 2013
bc4ebfd
Merge pull request #1693 from edx/flowerhack/fix/password-reset-messages
Nov 19, 2013
bcb5f1b
Increased timeout for element count in HTML test
Nov 19, 2013
6e0140b
revises .gitignore file to include static css directories and remnant…
talbs Nov 19, 2013
e7c06e3
Change preview view method to use RESTful URL.
Nov 15, 2013
1656876
If student has not passed verification, issue an honor code cert.
dianakhuang Nov 19, 2013
d72b61a
Use class methods to find the enrollment mode.
dianakhuang Nov 19, 2013
cb113de
Separate all db ops from modulestore ops
Oct 11, 2013
783e4b2
Show error on invalid html in course handout edit + Added tests
zubair-arbi Nov 7, 2013
cc2f1e7
BLD-524: Add missing assert in video test.
polesye Nov 20, 2013
29c8a0e
Merge pull request #1722 from edx/will/fix-html-failure
Nov 20, 2013
c941692
Merge pull request #1680 from edx/christina/preview
Nov 20, 2013
d821553
Merge pull request #1719 from danielcebrian/patch-1
singingwolfboy Nov 20, 2013
df349b9
Merge pull request #1333 from edx/dhm/separate_pymongo
dmitchell Nov 20, 2013
729f2e3
Merge pull request #1637 from edx/feanil/aws_creds
feanil Nov 20, 2013
f01b36b
Test for i4x on returned pages.
Nov 18, 2013
82092bd
Merge pull request #1697 from edx/christina/i4x_test
Nov 20, 2013
21169cb
Merge pull request #1707 from edx/gprice/forum-thread-list-focus-trap
Nov 20, 2013
d1c19cb
Minor cleanup around public RESTful URLs.
Nov 20, 2013
7b72a18
more granular transactions in grading [LMS-1480]
adampalay Nov 12, 2013
538be89
Merge pull request #1725 from edx/anton/transcripts-fix-acceptance-test
polesye Nov 20, 2013
92238d7
Merge pull request #1729 from edx/adam/more-granular-grading-transact…
adampalay Nov 20, 2013
e4817f5
Removed Backbone sourcemap comment
singingwolfboy Nov 20, 2013
2b3d6b2
Merge pull request #1730 from edx/db/remove-backbone-sourcemap-comment
singingwolfboy Nov 20, 2013
696f1df
Pass through the certificate mode correctly.
dianakhuang Nov 20, 2013
f0874d4
Fix 0010 courseware migration
jbau Nov 21, 2013
f0bbd34
Merge pull request #1715 from robertjmarks/master
valera-rozuvan Nov 21, 2013
062c3b4
Initial commit.
Nov 15, 2013
7528517
Adding tests.
Nov 18, 2013
6910ac9
Addressing reviewer's comments.
Nov 19, 2013
005e313
Merge pull request #1677 from edx/valera/alert_screenreader_video_end
valera-rozuvan Nov 21, 2013
df97df6
Merge pull request #1606 from zubair-arbi/zub/bugfix/std293-coursehan…
zubair-arbi Nov 21, 2013
d526027
Merge pull request #1721 from edx/talbs/update-gitignore
talbs Nov 21, 2013
e8beb4d
Allow colons in Locator fields.
Nov 21, 2013
77c208a
BLD-474: Allow multiple answers for string response.
polesye Nov 18, 2013
e150207
Merge pull request #1740 from edx/bug/locator_parse
dmitchell Nov 21, 2013
99cf0ec
Merge pull request #1727 from edx/christina/public
Nov 21, 2013
7bab863
Merge pull request #1698 from edx/anton/multiple-answers-string-response
polesye Nov 21, 2013
1b2be30
Convert tabs to RESTful URL.
Nov 14, 2013
3f44ff2
Merge pull request #1675 from edx/christina/tab-new
Nov 21, 2013
835893c
Merge pull request #1736 from edx/jbau/fix/cw-migrations
jbau Nov 21, 2013
d1f511e
Clean up test files, no substantive changes.
nedbat Nov 22, 2013
3bbc743
BLD-530: Fix 500 error in transcripts.
auraz Nov 21, 2013
51fa7e0
Merge pull request #1739 from edx/alex/fix-transcripts-500-error
polesye Nov 22, 2013
7606810
Update course_navigation.html
puntxo Nov 22, 2013
b7438bc
BLD-400: Update the calculator hints tooltip.
polesye Nov 21, 2013
7e50824
Merge pull request #1738 from edx/anton/update-calculator-hints
polesye Nov 22, 2013
83c5e8b
BLD-126: Code response improvements.
polesye Nov 19, 2013
1786435
Restful course settings
Nov 15, 2013
7e074f1
Add error recovery to inline discussion loading
Nov 21, 2013
4ace4f9
Add two tests of problems-with-files
nedbat Nov 22, 2013
de7d2cd
Properly convert files from Webob to pure files.
nedbat Nov 22, 2013
8d564f2
Use Choices to track possible modes.
dianakhuang Nov 22, 2013
7ab31f5
Merge pull request #1710 from edx/dhm/restful_settings
dmitchell Nov 22, 2013
586b1f7
Fix typo in comment.
dianakhuang Nov 22, 2013
938bd6b
Merge pull request #1745 from edx/ned/lms-1492
nedbat Nov 22, 2013
90bbb7b
Merge pull request #1706 from edx/anton/code-response-improvements
polesye Nov 22, 2013
e7b386c
fixes a branding test which was passing for a trivial (wrong) reason
jbau Nov 23, 2013
17e54a8
Added LMS_BASE to devstack settings to enable View Live in Studio
Nov 23, 2013
e9ebdb0
Merge pull request #1755 from edx/jbau/fix/marketing-test
jbau Nov 23, 2013
6941d1d
adding additional IDE files to global .gitignore
talbs Nov 24, 2013
b996cae
Merge pull request #1759 from edx/talbs/update-gitignore
talbs Nov 24, 2013
93823db
Merge pull request #1756 from edx/will/devstack-view-live
Nov 25, 2013
7a56e00
Merge pull request #1604 from edx/jarv/verified-certs
dianakhuang Nov 25, 2013
5d066db
Add feature to do auto signup with external auth
carsongee Oct 1, 2013
0f324ba
Fixed PEP8 and indentation issues
carsongee Oct 7, 2013
3f0f7fa
Merge pull request #1752 from edx/gprice/inline-discussion-error-reco…
Nov 25, 2013
96c7cb5
Added tests for signup skipping
carsongee Nov 25, 2013
ace8df3
Turned back on several Video Jasmine tests.
Nov 19, 2013
037cec6
Merge pull request #1711 from edx/valera/enable_all_video_jasmine_tests
valera-rozuvan Nov 25, 2013
50128cf
Convert edit_subsection, edit_unit, and publishing to RESTful URLs.
Nov 20, 2013
b5d72a3
Updates from code review. Includes backing out the
Nov 25, 2013
fe5e2b3
Refunding CertificateItem now marks parent Order refunded as well
Nov 25, 2013
304ccc9
Merge pull request #1728 from edx/christina/components
Nov 25, 2013
31ee6f0
Merge pull request #1766 from edx/flowerhack/fix/order-and-orderitem-…
Nov 25, 2013
bf94083
Revert PR 1711; disabling JS tests again
Nov 25, 2013
ceb1520
Merge pull request #1767 from edx/will/revert-1711
Nov 25, 2013
9a106a3
Merged master to rc/2013-11-21
Nov 25, 2013
368c575
Fix CHANGELOG conflicts again.
Nov 25, 2013
d3906f8
fixed the path to the header example image in the Studio html editor …
Nov 25, 2013
df0e1c4
Merge pull request #1768 from edx/ned/merge-master-to-rc-2013-11-21
nedbat Nov 25, 2013
bf9ac26
Corrected CMS tests so that one is passing, added external_auth to cm…
carsongee Nov 25, 2013
f3aa720
Merge pull request #1769 from edx/frances/fix/studio-edit-headerimage…
Nov 25, 2013
cccd61e
Make remaining dialogs in wiki accessible.
nedbat Nov 4, 2013
e4ebb58
Update mode appropriately when user enrolls
Nov 25, 2013
c023797
Merge pull request #1583 from edx/ned/fix/lms-1337
nedbat Nov 25, 2013
1795e15
Upgrade coverage to 3.7
nedbat Oct 11, 2013
d2a2aaa
LMS: adds in collapse/expand UI for dashboard view upsell
talbs Nov 24, 2013
f002ce4
Changed unit identifier to be readonly, not disabled
andy-armstrong Nov 25, 2013
b822df4
Added refund datetime info to Orders, OrderItems
Nov 25, 2013
63bc8c9
Merge pull request #1771 from edx/flowerhack/fix/lms-1526
Nov 25, 2013
3ad705c
Removing external_auth addition to cms, and skipping test
carsongee Nov 25, 2013
6733d04
Merge pull request #1317 from edx/ned/upgrade-coverage
nedbat Nov 25, 2013
2b5b4f4
Merge pull request #1760 from edx/talbs/lms-upsell-ui
talbs Nov 25, 2013
bbfa774
Studio: correcting hiding state of notification UI for < IE9
talbs Nov 26, 2013
829cd7d
Fix unique vertical url + add test
zubair-arbi Nov 26, 2013
18f342c
Merge pull request #1781 from zubair-arbi/zub/bugfix/std979-displayna…
zubair-arbi Nov 26, 2013
7f91ce4
Restful api for course advanced settings
Nov 21, 2013
389df17
Merge pull request #1748 from puntxo/patch-1
singingwolfboy Nov 26, 2013
38fba24
Merge pull request #1754 from edx/dhm/restful_settings
dmitchell Nov 26, 2013
957175e
Merge pull request #1773 from edx/andy/unitidentifier
andy-armstrong Nov 26, 2013
d00e5a4
Disabled video caption tests that failed in master
Nov 26, 2013
88ccf85
Merge pull request #1786 from edx/will/disable-caption-test
Nov 26, 2013
5a5c8c0
Merge pull request #1779 from edx/talbs/fix-studio-notificationsie
talbs Nov 26, 2013
bff94de
Studio: adding basic italicize text styling into xmodule/block previe…
talbs Nov 26, 2013
812c821
Merge pull request #1778 from edx/talbs/studio-fix-italics
talbs Nov 26, 2013
761699b
Disabled another video test that failed in master
Nov 26, 2013
3ed96f7
Merge pull request #1788 from edx/will/disable-caption-test-2
Nov 26, 2013
a0fa9d0
Refactor keypress activation for forum buttons
Nov 22, 2013
81798dd
Improve accessibility of inline discussions
Nov 22, 2013
f94565d
Merge pull request #1685 from edx/jbau/shopping-cart/report
jbau Nov 26, 2013
341875b
Remove code related to Pearson Testing Centers
Oct 10, 2013
a56b945
Rebase to re-prepare PR
Nov 25, 2013
6614d7e
Add migration to remove pearson tables
Nov 26, 2013
bb3917f
Merge pull request #1299 from edx/zoldak/remove-pearson-code
Nov 27, 2013
006b8f8
Removed old migration
Nov 27, 2013
280e3c3
Merge conflicts
Nov 27, 2013
30cd57f
New migrations file
Nov 27, 2013
3e3a57f
Merge pull request #1774 from edx/flowerhack/refund-requested-date
Nov 27, 2013
c8a7b25
Resolve conflicts merging master to rc/2013-11-21
Nov 27, 2013
39b29dc
Merge pull request #1802 from edx/ned/merge-master-to-rc-2013-11-21-a…
nedbat Nov 27, 2013
d75b580
Enabled back turned off Video acceptance tests.
Nov 27, 2013
ef52849
Merge pull request #1797 from edx/valera/enable_acceptance_video
valera-rozuvan Nov 29, 2013
0dbb760
BLD-533: Improve calculator's tooltip accessibility.
polesye Nov 25, 2013
45d373c
Merge pull request #1798 from edx/anton/calculator-hint-a11y
polesye Dec 2, 2013
8f01387
BLD-525: Fix Numerical input to support mathematical operations.
polesye Dec 2, 2013
9dc68b0
Improve auth handling of Locators
Nov 27, 2013
7fa7641
Merge pull request #1799 from edx/dhm/bug-1003
dmitchell Dec 2, 2013
62a2582
Merge pull request #1765 from edx/gprice/inline-discussion-a11y
Dec 2, 2013
78149d0
Add comment.
polesye Dec 3, 2013
c8adbe3
Merge pull request #1182 from carsongee/add_mitx_ssl_bypass_signup
brianhw Dec 3, 2013
29e3a03
Merge pull request #1810 from edx/anton/fix-math-operations-in-numeri…
polesye Dec 3, 2013
41d82df
BLD-542: Add display name.
polesye Dec 3, 2013
e0f2ece
Merge pull request #1820 from edx/anton/fix-lti-display-name
polesye Dec 3, 2013
dd5ac4c
Change video transcripts to use locators instead of locations.
Nov 26, 2013
050031f
Disable Peer Track Changes
zubair-arbi Dec 4, 2013
72bb0f8
Merge pull request #1854 from cpennington/wording-fixes
cpennington Dec 5, 2013
9d48bb0
removes temporary error messages
adampalay Dec 5, 2013
108e02e
Remove the one-time-use managemant command.
Dec 5, 2013
be3ab1c
Drop the temp table
Dec 5, 2013
faa8f16
Merge pull request #1877 from edx/ned/hotfix-2013-12-04-with-temp-stu…
nedbat Dec 6, 2013
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ cms/envs/private.py
/nbproject
.idea/
.redcar/
codekit-config.json

### OS X artifacts
*.DS_Store
Expand Down Expand Up @@ -48,14 +49,18 @@ reports/
.prereqs_cache
.vagrant/
node_modules
.bundle/
bin/

### Static assets pipeline artifacts
*.scssc
lms/static/css/
lms/static/sass/*.css
lms/static/sass/application.scss
lms/static/sass/application-extend1.scss
lms/static/sass/application-extend2.scss
lms/static/sass/course.scss
cms/static/css/
cms/static/sass/*.css

### Logging artifacts
Expand Down
2 changes: 2 additions & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,5 @@ Iain Dunning <idunning@mit.edu>
Olivier Marquez <oliviermarquez@gmail.com>
Florian Dufour <neurolit@gmail.com>
Manuel Freire <manuel.freire@fdi.ucm.es>
Daniel Cebrián Robles <danielcebrianr@gmail.com>
Carson Gee <cgee@mit.edu>
50 changes: 44 additions & 6 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ These are notable changes in edx-platform. This is a rolling list of changes,
in roughly chronological order, most recent first. Add your entries at or near
the top. Include a label indicating the component affected.

Blades: Fix Numerical input to support mathematical operations. BLD-525.

Blades: Improve calculator's tooltip accessibility. Add possibility to navigate
through the hints via arrow keys. BLD-533.

LMS: Add feature for providing background grade report generation via Celery
instructor task, with reports uploaded to S3. Feature is visible on the beta
instructor dashboard. LMS-58
Expand All @@ -13,9 +18,38 @@ Blades: Added grading support for LTI module. LTI providers can now grade
student's work and send edX scores. OAuth1 based authentication
implemented. BLD-384.

LMS: Beta-tester status is now set on a per-course-run basis, rather than being valid
across all runs with the same course name. Old group membership will still work
across runs, but new beta-testers will only be added to a single course run.
LMS: Beta-tester status is now set on a per-course-run basis, rather than being
valid across all runs with the same course name. Old group membership will
still work across runs, but new beta-testers will only be added to a single
course run.

Blades: Enabled several Video Jasmine tests. BLD-463.

Studio: Continued modification of Studio pages to follow a RESTful framework.
includes Settings pages, edit page for Subsection and Unit, and interfaces
for updating xblocks (xmodules) and getting their editing HTML.

LMS: Improve accessibility of inline discussions in courseware.

Blades: Put 2nd "Hide output" button at top of test box & increase text size for
code response questions. BLD-126.

Blades: Update the calculator hints tooltip with full information. BLD-400.

Blades: Fix transcripts 500 error in studio (BLD-530)

LMS: Add error recovery when a user loads or switches pages in an
inline discussion.

Blades: Allow multiple strings as the correct answer to a string response
question. BLD-474.

Blades: a11y - Videos will alert screenreaders when the video is over.

LMS: Trap focus on the loading element when a user loads more threads
in the forum sidebar to improve accessibility.

LMS: Add error recovery when a user loads more threads in the forum sidebar.

LMS: Add a user-visible alert modal when a forums AJAX request fails.

Expand All @@ -36,7 +70,8 @@ text like with bold or italics. (BLD-449)
LMS: Beta instructor dashboard will only count actively enrolled students for
course enrollment numbers.

Blades: Fix speed menu that is not rendered correctly when YouTube is unavailable. (BLD-457).
Blades: Fix speed menu that is not rendered correctly when YouTube is
unavailable. (BLD-457).

LMS: Users with is_staff=True no longer have the STAFF label appear on
their forum posts.
Expand All @@ -54,6 +89,9 @@ key in course settings. (BLD-426)

Blades: Fix bug when the speed can only be changed when the video is playing.

LMS: The dialogs on the wiki "changes" page are now accessible to screen
readers. Now all wiki pages have been made accessible. (LMS-1337)

LMS: Change bulk email implementation to use less memory, and to better handle
duplicate tasks in celery.

Expand All @@ -70,8 +108,8 @@ client error are correctly passed through to the client.
LMS: Improve performance of page load and thread list load for
discussion tab

LMS: The wiki markup cheatsheet dialog is now accessible to people with
disabilites. (LMS-1303)
LMS: The wiki markup cheatsheet dialog is now accessible to screen readers.
(LMS-1303)

Common: Add skip links for accessibility to CMS and LMS. (LMS-1311)

Expand Down
130 changes: 87 additions & 43 deletions cms/djangoapps/auth/authz.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
"""
Studio authorization functions primarily for course creators, instructors, and staff
"""
#=======================================================================================================================
#
# This code is somewhat duplicative of access.py in the LMS. We will unify the code as a separate story
Expand All @@ -11,7 +14,8 @@
from xmodule.modulestore import Location
from xmodule.modulestore.locator import CourseLocator, Locator
from xmodule.modulestore.django import loc_mapper
from xmodule.modulestore.exceptions import InvalidLocationError
from xmodule.modulestore.exceptions import InvalidLocationError, ItemNotFoundError
import itertools


# define a couple of simple roles, we just need ADMIN and EDITOR now for our purposes
Expand All @@ -26,7 +30,11 @@
# of those two variables


def get_course_groupname_for_role(location, role):
def get_all_course_role_groupnames(location, role, use_filter=True):
'''
Get all of the possible groupnames for this role location pair. If use_filter==True,
only return the ones defined in the groups collection.
'''
location = Locator.to_locator_or_location(location)

# hack: check for existence of a group name in the legacy LMS format <role>_<course>
Expand All @@ -38,22 +46,46 @@ def get_course_groupname_for_role(location, role):
except InvalidLocationError: # will occur on old locations where location is not of category course
pass
if isinstance(location, Location):
# least preferred role_course format
groupnames.append('{0}_{1}'.format(role, location.course))
try:
locator = loc_mapper().translate_location(location.course_id, location, False, False)
groupnames.append('{0}_{1}'.format(role, locator.course_id))
except (InvalidLocationError, ItemNotFoundError):
pass
elif isinstance(location, CourseLocator):
old_location = loc_mapper().translate_locator_to_location(location, get_course=True)
if old_location:
# the slashified version of the course_id (myu/mycourse/myrun)
groupnames.append('{0}_{1}'.format(role, old_location.course_id))

for groupname in groupnames:
if Group.objects.filter(name=groupname).exists():
return groupname
return groupnames[0]
# add the least desirable but sometimes occurring format.
groupnames.append('{0}_{1}'.format(role, old_location.course))
# filter to the ones which exist
default = groupnames[0]
if use_filter:
groupnames = [group for group in groupnames if Group.objects.filter(name=group).exists()]
return groupnames, default


def get_users_in_course_group_by_role(location, role):
groupname = get_course_groupname_for_role(location, role)
(group, _created) = Group.objects.get_or_create(name=groupname)
return group.user_set.all()
def get_course_groupname_for_role(location, role):
'''
Get the preferred used groupname for this role, location combo.
Preference order:
* role_course_id (e.g., staff_myu.mycourse.myrun)
* role_old_course_id (e.g., staff_myu/mycourse/myrun)
* role_old_course (e.g., staff_mycourse)
'''
groupnames, default = get_all_course_role_groupnames(location, role)
return groupnames[0] if groupnames else default


def get_course_role_users(course_locator, role):
'''
Get all of the users with the given role in the given course.
'''
groupnames, _ = get_all_course_role_groupnames(course_locator, role)
groups = [Group.objects.get(name=groupname) for groupname in groupnames]
return list(itertools.chain.from_iterable(group.user_set.all() for group in groups))


def create_all_course_groups(creator, location):
Expand All @@ -65,11 +97,11 @@ def create_all_course_groups(creator, location):


def create_new_course_group(creator, location, role):
groupname = get_course_groupname_for_role(location, role)
(group, created) = Group.objects.get_or_create(name=groupname)
if created:
group.save()

'''
Create the new course group always using the preferred name even if another form already exists.
'''
groupnames, __ = get_all_course_role_groupnames(location, role, use_filter=False)
group, __ = Group.objects.get_or_create(name=groupnames[0])
creator.groups.add(group)
creator.save()

Expand All @@ -82,41 +114,39 @@ def _delete_course_group(location):
asserted permissions
"""
# remove all memberships
instructors = Group.objects.get(name=get_course_groupname_for_role(location, INSTRUCTOR_ROLE_NAME))
for user in instructors.user_set.all():
user.groups.remove(instructors)
user.save()

staff = Group.objects.get(name=get_course_groupname_for_role(location, STAFF_ROLE_NAME))
for user in staff.user_set.all():
user.groups.remove(staff)
user.save()
for role in [INSTRUCTOR_ROLE_NAME, STAFF_ROLE_NAME]:
groupnames, _ = get_all_course_role_groupnames(location, role)
for groupname in groupnames:
group = Group.objects.get(name=groupname)
for user in group.user_set.all():
user.groups.remove(group)
user.save()


def _copy_course_group(source, dest):
"""
This is to be called only by either a command line code path or through an app which has already
asserted permissions to do this action
"""
instructors = Group.objects.get(name=get_course_groupname_for_role(source, INSTRUCTOR_ROLE_NAME))
new_instructors_group = Group.objects.get(name=get_course_groupname_for_role(dest, INSTRUCTOR_ROLE_NAME))
for user in instructors.user_set.all():
user.groups.add(new_instructors_group)
user.save()

staff = Group.objects.get(name=get_course_groupname_for_role(source, STAFF_ROLE_NAME))
new_staff_group = Group.objects.get(name=get_course_groupname_for_role(dest, STAFF_ROLE_NAME))
for user in staff.user_set.all():
user.groups.add(new_staff_group)
user.save()
for role in [INSTRUCTOR_ROLE_NAME, STAFF_ROLE_NAME]:
groupnames, _ = get_all_course_role_groupnames(source, role)
for groupname in groupnames:
group = Group.objects.get(name=groupname)
new_group, _ = Group.objects.get_or_create(name=get_course_groupname_for_role(dest, INSTRUCTOR_ROLE_NAME))
for user in group.user_set.all():
user.groups.add(new_group)
user.save()


def add_user_to_course_group(caller, user, location, role):
"""
If caller is authorized, add the given user to the given course's role
"""
# only admins can add/remove other users
if not is_user_in_course_group_role(caller, location, INSTRUCTOR_ROLE_NAME):
raise PermissionDenied

group = Group.objects.get(name=get_course_groupname_for_role(location, role))
group, _ = Group.objects.get_or_create(name=get_course_groupname_for_role(location, role))
return _add_user_to_group(user, group)


Expand All @@ -132,9 +162,7 @@ def add_user_to_creator_group(caller, user):
if not caller.is_active or not caller.is_authenticated or not caller.is_staff:
raise PermissionDenied

(group, created) = Group.objects.get_or_create(name=COURSE_CREATOR_GROUP_NAME)
if created:
group.save()
(group, _) = Group.objects.get_or_create(name=COURSE_CREATOR_GROUP_NAME)
return _add_user_to_group(user, group)


Expand All @@ -152,6 +180,9 @@ def _add_user_to_group(user, group):


def get_user_by_email(email):
"""
Get the user whose email is the arg. Return None if no such user exists.
"""
user = None
# try to look up user, return None if not found
try:
Expand All @@ -163,13 +194,21 @@ def get_user_by_email(email):


def remove_user_from_course_group(caller, user, location, role):
"""
If caller is authorized, remove the given course x role authorization for user
"""
# only admins can add/remove other users
if not is_user_in_course_group_role(caller, location, INSTRUCTOR_ROLE_NAME):
raise PermissionDenied

# see if the user is actually in that role, if not then we don't have to do anything
if is_user_in_course_group_role(user, location, role):
_remove_user_from_group(user, get_course_groupname_for_role(location, role))
groupnames, _ = get_all_course_role_groupnames(location, role)
for groupname in groupnames:
groups = user.groups.filter(name=groupname)
if groups:
# will only be one with that name
user.groups.remove(groups[0])
user.save()


def remove_user_from_creator_group(caller, user):
Expand All @@ -195,11 +234,16 @@ def _remove_user_from_group(user, group_name):


def is_user_in_course_group_role(user, location, role, check_staff=True):
"""
Check whether the given user has the given role in this course. If check_staff
then give permission if the user is staff without doing a course-role query.
"""
if user.is_active and user.is_authenticated:
# all "is_staff" flagged accounts belong to all groups
if check_staff and user.is_staff:
return True
return user.groups.filter(name=get_course_groupname_for_role(location, role)).exists()
groupnames, _ = get_all_course_role_groupnames(location, role)
return any(user.groups.filter(name=groupname).exists() for groupname in groupnames)

return False

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,6 @@
from terrain.steps import reload_the_page


def _is_expected_element_count(css, expected_number):
"""
Returns whether the number of elements found on the page by css locator
the same number that you expected.
"""
return len(world.css_find(css)) == expected_number


@world.absorb
def create_component_instance(step, category, component_type=None, is_advanced=False):
"""
Expand Down Expand Up @@ -47,8 +39,11 @@ def create_component_instance(step, category, component_type=None, is_advanced=F
world.wait_for_invisible(component_button_css)
click_component_from_menu(category, component_type, is_advanced)

world.wait_for(lambda _: _is_expected_element_count(module_css,
module_count_before + 1))
expected_count = module_count_before + 1
world.wait_for(
lambda _: len(world.css_find(module_css)) == expected_count,
timeout=20
)


@world.absorb
Expand Down
14 changes: 14 additions & 0 deletions cms/djangoapps/contentstore/features/course-updates.feature
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,17 @@ Feature: CMS.Course updates
Then I see the handout "/c4x/MITx/999/asset/modified.jpg"
And when I reload the page
Then I see the handout "/c4x/MITx/999/asset/modified.jpg"

Scenario: Users cannot save handouts with bad html until edit or update it properly
Given I have opened a new course in Studio
And I go to the course updates page
When I modify the handout to "<p><a href=>[LINK TEXT]</a></p>"
Then I see the handout error text
And I see handout save button disabled
When I edit the handout to "<p><a href='https://www.google.com.pk/'>home</a></p>"
Then I see handout save button re-enabled
When I save handout edit
# Can only do partial text matches because of the quotes with in quotes (and regexp step matching).
Then I see the handout "https://www.google.com.pk/"
And when I reload the page
Then I see the handout "https://www.google.com.pk/"
Loading