diff --git a/cms/djangoapps/contentstore/tests/test_course_create_rerun.py b/cms/djangoapps/contentstore/tests/test_course_create_rerun.py index c76837912da..719fe36dd14 100644 --- a/cms/djangoapps/contentstore/tests/test_course_create_rerun.py +++ b/cms/djangoapps/contentstore/tests/test_course_create_rerun.py @@ -25,6 +25,7 @@ from cms.djangoapps.contentstore.tests.utils import AjaxEnabledTestClient, parse_json from cms.djangoapps.course_creators.admin import CourseCreatorAdmin from cms.djangoapps.course_creators.models import CourseCreator +from cms.djangoapps.contentstore.views.course import get_allowed_organizations, user_can_create_organizations from common.djangoapps.student.auth import update_org_role from common.djangoapps.student.roles import CourseInstructorRole, CourseStaffRole, OrgContentCreatorRole from common.djangoapps.student.tests.factories import AdminFactory, UserFactory @@ -227,6 +228,7 @@ def test_course_creation_when_user_in_org_with_creator_role(self, store): 'description': 'Testing Organization Description', }) update_org_role(self.global_admin, OrgContentCreatorRole, self.user, [self.source_course_key.org]) + self.assertIn(self.source_course_key.org, get_allowed_organizations(self.user)) with modulestore().default_store(store): response = self.client.ajax_post(self.course_create_rerun_url, { 'org': self.source_course_key.org, @@ -254,6 +256,8 @@ def test_course_creation_with_all_org_checked(self, store): self.course_creator_entry.all_organizations = True self.course_creator_entry.state = CourseCreator.GRANTED self.creator_admin.save_model(self.request, self.course_creator_entry, None, True) + self.assertIn(self.source_course_key.org, get_allowed_organizations(self.user)) + self.assertFalse(user_can_create_organizations(self.user)) with modulestore().default_store(store): response = self.client.ajax_post(self.course_create_rerun_url, { 'org': self.source_course_key.org, @@ -283,6 +287,8 @@ def test_course_creation_with_permission_for_specific_organization(self, store): self.creator_admin.save_model(self.request, self.course_creator_entry, None, True) dc_org_object = Organization.objects.get(name='Test Organization') self.course_creator_entry.organizations.add(dc_org_object) + self.assertIn(self.source_course_key.org, get_allowed_organizations(self.user)) + self.assertFalse(user_can_create_organizations(self.user)) with modulestore().default_store(store): response = self.client.ajax_post(self.course_create_rerun_url, { 'org': self.source_course_key.org, @@ -319,6 +325,8 @@ def test_course_creation_without_permission_for_specific_organization(self, stor # When the user tries to create course under `Test Organization` it throws a 403. dc_org_object = Organization.objects.get(name='DC') self.course_creator_entry.organizations.add(dc_org_object) + self.assertNotIn(self.source_course_key.org, get_allowed_organizations(self.user)) + self.assertFalse(user_can_create_organizations(self.user)) with modulestore().default_store(store): response = self.client.ajax_post(self.course_create_rerun_url, { 'org': self.source_course_key.org, diff --git a/cms/djangoapps/contentstore/views/course.py b/cms/djangoapps/contentstore/views/course.py index 2f6a6a0c6fe..aaacbb1b534 100644 --- a/cms/djangoapps/contentstore/views/course.py +++ b/cms/djangoapps/contentstore/views/course.py @@ -35,6 +35,7 @@ from rest_framework.exceptions import ValidationError from cms.djangoapps.course_creators.views import add_user_with_status_unrequested, get_course_creator_status +from cms.djangoapps.course_creators.models import CourseCreator from cms.djangoapps.models.settings.course_grading import CourseGradingModel from cms.djangoapps.models.settings.course_metadata import CourseMetadata from cms.djangoapps.models.settings.encoder import CourseSettingsEncoder @@ -72,6 +73,7 @@ from openedx.features.content_type_gating.models import ContentTypeGatingConfig from openedx.features.content_type_gating.partitions import CONTENT_TYPE_GATING_SCHEME from openedx.features.course_experience.waffle import ENABLE_COURSE_ABOUT_SIDEBAR_HTML +from organizations.models import Organization from xmodule.contentstore.content import StaticContent # lint-amnesty, pylint: disable=wrong-import-order from xmodule.course_module import CourseBlock, DEFAULT_START_DATE, CourseFields # lint-amnesty, pylint: disable=wrong-import-order from xmodule.error_module import ErrorBlock # lint-amnesty, pylint: disable=wrong-import-order @@ -586,7 +588,9 @@ def format_in_process_course_view(uca): 'allow_unicode_course_id': settings.FEATURES.get('ALLOW_UNICODE_COURSE_ID', False), 'allow_course_reruns': settings.FEATURES.get('ALLOW_COURSE_RERUNS', True), 'optimization_enabled': optimization_enabled, - 'active_tab': 'courses' + 'active_tab': 'courses', + 'allowed_organizations': get_allowed_organizations(user), + 'can_create_organizations': user_can_create_organizations(user), }) @@ -1907,3 +1911,35 @@ def _get_course_creator_status(user): course_creator_status = 'granted' return course_creator_status + + +def get_allowed_organizations(user): + """ + Helper method for returning the list of organizations for which the user is allowed to create courses. + """ + if settings.FEATURES.get('ENABLE_CREATOR_GROUP', False): + return get_organizations(user) + else: + return [] + + +def user_can_create_organizations(user): + """ + Returns True if the user can create organizations. + """ + return user.is_staff or not settings.FEATURES.get('ENABLE_CREATOR_GROUP', False) + + +def get_organizations(user): + """ + Returns the list of organizations for which the user is allowed to create courses. + """ + course_creator = CourseCreator.objects.filter(user=user).first() + if not course_creator: + return [] + elif course_creator.all_organizations: + organizations = Organization.objects.all().values_list('short_name', flat=True) + else: + organizations = course_creator.organizations.all().values_list('short_name', flat=True) + + return organizations diff --git a/cms/static/sass/views/_course-create.scss b/cms/static/sass/views/_course-create.scss index 96301540c70..1a7a8e6caed 100644 --- a/cms/static/sass/views/_course-create.scss +++ b/cms/static/sass/views/_course-create.scss @@ -68,6 +68,10 @@ width: 100%; } + .new-course-org{ + padding: 10px; + } + .rerun-course-number, .rerun-course-number-label { color: #a0a0a0; diff --git a/cms/static/sass/views/_dashboard.scss b/cms/static/sass/views/_dashboard.scss index 3e5a4293789..b412eb96882 100644 --- a/cms/static/sass/views/_dashboard.scss +++ b/cms/static/sass/views/_dashboard.scss @@ -676,10 +676,16 @@ .new-course-org, .new-course-number, .new-course-name, - .new-course-run { + .new-course-run, + .new-library-org { width: 100%; } + .new-course-org, + .new-library-org { + padding: 10px; + } + .course-run-text-direction { direction: ltr; text-align: right; diff --git a/cms/templates/index.html b/cms/templates/index.html index 4ba762b8f33..12e50215ba6 100644 --- a/cms/templates/index.html +++ b/cms/templates/index.html @@ -81,7 +81,15 @@

${_("Create a New Course")}

## Translators: This is an example for the name of the organization sponsoring a course, seen when filling out the form to create a new course. The organization name cannot contain spaces. ## Translators: "e.g. UniversityX or OrganizationX" is a placeholder displayed when user put no data into this field. - + % if can_create_organizations: + + % else: + + % endif ${Text(_("The name of the organization sponsoring the course. {strong_start}Note: The organization name is part of the course URL.{strong_end} This cannot be changed, but you can set a different display name in Advanced Settings later.")).format( strong_start=HTML(''), strong_end=HTML(''), @@ -155,7 +163,15 @@

${_("Create a New Library")}

  • - + % if can_create_organizations: + + % else: + + % endif ${_("The public organization name for your library.")} ${_("This cannot be changed.")}