Example #1
0
def get_environ2():
    """Returns currently defined course settings as a dictionary."""
    gDefier_yaml = None
    gDefier_yaml_dict = None
    
    ns = ApplicationContext.get_namespace_name_for_request()
    app_context = sites.get_app_context_for_namespace(ns)

    course_data_filename = sites.abspath(app_context.get_home_folder(), DFR_CONFIG_FILENAME)

    if app_context.fs.isfile(course_data_filename):
        gDefier_yaml = app_context.fs.open(course_data_filename)
    if not gDefier_yaml:
        return deep_dict_merge(gDefier_model.DEFAULT_COURSE_GDEFIER_DICT,
                               [])
    try:
        gDefier_yaml_dict = yaml.safe_load(
            gDefier_yaml.read().decode('utf-8'))
    except Exception as e:  # pylint: disable-msg=broad-except
        logging.info(
            'Error: gDefier.yaml file at %s not accessible, '
            'loading defaults. %s', course_data_filename, e)

    if not gDefier_yaml_dict:
        return deep_dict_merge(gDefier_model.DEFAULT_COURSE_GDEFIER_DICT,
                               [])
    return deep_dict_merge(
        gDefier_yaml_dict, gDefier_model.DEFAULT_COURSE_GDEFIER_DICT)
Example #2
0
    def test_dict_merge(self):
        real_values = {'foo': 'bar', 'baz': {'alice': 'john'}}
        real_original = dict(real_values.items())
        default_values = {'foo': 'baz', 'baz': {'alice': 'ana', 'bob': 'sue'}}
        default_original = dict(default_values.items())

        # Check merge.
        assert {'foo': 'bar', 'baz': {'bob': 'sue', 'alice': 'john'}} == (
            courses.deep_dict_merge(real_values, default_values))

        # Check originals dicts are intact.
        assert real_original == real_values
        assert default_original == default_values

        # Check merge into an empty dict.
        assert courses.DEFAULT_COURSE_YAML_DICT == courses.deep_dict_merge(
            {}, courses.DEFAULT_COURSE_YAML_DICT)

        # Check value does not merge into dictionary.
        real_values = {'foo': 'bar'}
        default_values = {'foo': {'bar': 'baz'}}
        assert {'foo': 'bar'} == (
            courses.deep_dict_merge(real_values, default_values))

        # Test array element.
        real_values = {'foo': [1, 2, 3]}
        default_values = {'baz': [4, 5, 6]}
        assert {'foo': [1, 2, 3], 'baz': [4, 5, 6]} == (
            courses.deep_dict_merge(real_values, default_values))
Example #3
0
    def test_dict_merge(self):
        real_values = {'foo': 'bar', 'baz': {'alice': 'john'}}
        real_original = dict(real_values.items())
        default_values = {'foo': 'baz', 'baz': {'alice': 'ana', 'bob': 'sue'}}
        default_original = dict(default_values.items())

        # Check merge.
        assert {'foo': 'bar', 'baz': {'bob': 'sue', 'alice': 'john'}} == (
            courses.deep_dict_merge(real_values, default_values))

        # Check originals dicts are intact.
        assert real_original == real_values
        assert default_original == default_values

        # Check merge into an empty dict.
        assert courses.DEFAULT_COURSE_YAML_DICT == courses.deep_dict_merge(
            {}, courses.DEFAULT_COURSE_YAML_DICT)

        # Check value does not merge into dictionary.
        real_values = {'foo': 'bar'}
        default_values = {'foo': {'bar': 'baz'}}
        assert {'foo': 'bar'} == (
            courses.deep_dict_merge(real_values, default_values))

        # Test array element.
        real_values = {'foo': [1, 2, 3]}
        default_values = {'baz': [4, 5, 6]}
        assert {'foo': [1, 2, 3], 'baz': [4, 5, 6]} == (
            courses.deep_dict_merge(real_values, default_values))
Example #4
0
def update_course_config(name, settings):
    """Merge settings into the saved course.yaml configuration.

    Args:
      name: Name of the course.  E.g., 'my_test_course'.
      settings: A nested dict of name/value settings.  Names for items here
          can be found in modules/dashboard/course_settings.py in
          create_course_registry.  See below in simple_add_course()
          for an example.
    Returns:
      Context object for the modified course.
    """
    site_type = 'course'
    namespace = 'ns_%s' % name
    slug = '/%s' % name
    rule = '%s:%s::%s' % (site_type, slug, namespace)

    context = sites.get_all_courses(rule)[0]
    environ = courses.deep_dict_merge(settings,
                                      courses.Course.get_environ(context))
    course = courses.Course(handler=None, app_context=context)
    course.save_settings(environ)
    course_config = config.Registry.test_overrides.get(
        sites.GCB_COURSES_CONFIG.name, 'course:/:/')
    if rule not in course_config:
        course_config = '%s, %s' % (rule, course_config)
        sites.setup_courses(course_config)
    return context
Example #5
0
    def put(self):
        """Handles REST PUT verb with JSON payload."""
        assert self.app_context.is_editable_fs()

        request_param = self.request.get('request')
        if not request_param:
            transforms.send_json_response(
                self, 400, 'Missing "request" parameter.')
            return
        try:
            request = transforms.loads(request_param)
        except ValueError:
            transforms.send_json_response(
                self, 400, 'Malformed "request" parameter.')
            return
        key = request.get('key')
        if not key:
            transforms.send_json_response(
                self, 400, 'Request missing "key" parameter.')
            return
        payload_param = request.get('payload')
        if not payload_param:
            transforms.send_json_response(
                self, 400, 'Request missing "payload" parameter.')
            return
        try:
            payload = transforms.loads(payload_param)
        except ValueError:
            transforms.send_json_response(
                self, 400, 'Malformed "payload" parameter.')
            return
        if not self.assert_xsrf_token_or_fail(
                request, self.XSRF_ACTION, {'key': key}):
            return
        if not permissions.can_edit(self.app_context,
                                    constants.SCOPE_COURSE_SETTINGS):
            transforms.send_json_response(
                self, 401, 'Access denied.', {'key': key})
            return

        request_data = self.process_put(request, payload)

        schema = self.get_course().create_settings_schema()
        permissions.SchemaPermissionRegistry.redact_schema_to_permitted_fields(
            self.app_context, constants.SCOPE_COURSE_SETTINGS, schema)
        schema.redact_entity_to_schema(payload)

        if request_data:
            course_settings = courses.deep_dict_merge(
                request_data, self.get_course_dict())
            self.postprocess_put(course_settings, request)

            if not self.get_course().save_settings(course_settings):
                transforms.send_json_response(self, 412, 'Validation error.')
            transforms.send_json_response(self, 200, 'Saved.')
Example #6
0
    def put(self):
        """Handles REST PUT verb with JSON payload."""
        assert is_editable_fs(self.app_context)

        request = transforms.loads(self.request.get('request'))
        key = request.get('key')

        if not self.assert_xsrf_token_or_fail(
                request, 'basic-course-settings-put', {'key': key}):
            return

        if not CourseSettingsRights.can_edit(self):
            transforms.send_json_response(self, 401, 'Access denied.',
                                          {'key': key})
            return

        payload = request.get('payload')
        request_data = {}
        CourseSettingsRESTHandler.REGISTORY.convert_json_to_entity(
            transforms.loads(payload), request_data)

        course_data = request_data['course']
        if 'forum_email' in course_data.keys():
            forum_email = course_data['forum_email']
            forum_web_url = self.get_groups_web_url(forum_email)
            if forum_web_url:
                course_data['forum_url'] = forum_web_url
            forum_web_url = self.get_groups_embed_url(forum_email)
            if forum_web_url:
                course_data['forum_embed_url'] = forum_web_url

        if 'announcement_list_email' in course_data.keys():
            announcement_email = course_data['announcement_list_email']
            announcement_web_url = self.get_groups_web_url(announcement_email)
            if announcement_web_url:
                course_data['announcement_list_url'] = announcement_web_url

        entity = courses.deep_dict_merge(request_data, self.get_course_dict())
        content = yaml.safe_dump(entity)

        try:
            self.validate_content(content)
            content_stream = vfs.string_to_stream(unicode(content))
        except Exception as e:  # pylint: disable=W0703
            transforms.send_json_response(self, 412,
                                          'Validation error: %s' % e)
            return

        # Store new file content.
        fs = self.app_context.fs.impl
        filename = fs.physical_to_logical(key)
        fs.put(filename, content_stream)

        # Send reply.
        transforms.send_json_response(self, 200, 'Saved.')
    def put(self):
        """Handles REST PUT verb with JSON payload."""
        assert is_editable_fs(self.app_context)

        request = transforms.loads(self.request.get('request'))
        key = request.get('key')

        if not self.assert_xsrf_token_or_fail(
                request, 'basic-course-settings-put', {'key': key}):
            return

        if not CourseSettingsRights.can_edit(self):
            transforms.send_json_response(
                self, 401, 'Access denied.', {'key': key})
            return

        payload = request.get('payload')
        request_data = {}
        CourseSettingsRESTHandler.REGISTORY.convert_json_to_entity(
            transforms.loads(payload), request_data)

        course_data = request_data['course']
        if 'forum_email' in course_data.keys():
            forum_email = course_data['forum_email']
            forum_web_url = self.get_groups_web_url(forum_email)
            if forum_web_url:
                course_data['forum_url'] = forum_web_url
            forum_web_url = self.get_groups_embed_url(forum_email)
            if forum_web_url:
                course_data['forum_embed_url'] = forum_web_url

        if 'announcement_list_email' in course_data.keys():
            announcement_email = course_data['announcement_list_email']
            announcement_web_url = self.get_groups_web_url(announcement_email)
            if announcement_web_url:
                course_data['announcement_list_url'] = announcement_web_url

        entity = courses.deep_dict_merge(request_data, self.get_course_dict())
        content = yaml.safe_dump(entity)

        try:
            self.validate_content(content)
            content_stream = vfs.string_to_stream(unicode(content))
        except Exception as e:  # pylint: disable=W0703
            transforms.send_json_response(self, 412, 'Validation error: %s' % e)
            return

        # Store new file content.
        fs = self.app_context.fs.impl
        filename = fs.physical_to_logical(key)
        fs.put(filename, content_stream)

        # Send reply.
        transforms.send_json_response(self, 200, 'Saved.')
    def put(self):
        """Handles REST PUT verb with JSON payload."""
        assert self.app_context.is_editable_fs()

        request_param = self.request.get('request')
        if not request_param:
            transforms.send_json_response(self, 400,
                                          'Missing "request" parameter.')
            return
        try:
            request = transforms.loads(request_param)
        except ValueError:
            transforms.send_json_response(self, 400,
                                          'Malformed "request" parameter.')
            return
        key = request.get('key')
        if not key:
            transforms.send_json_response(self, 400,
                                          'Request missing "key" parameter.')
            return
        payload_param = request.get('payload')
        if not payload_param:
            transforms.send_json_response(
                self, 400, 'Request missing "payload" parameter.')
            return
        try:
            payload = transforms.loads(payload_param)
        except ValueError:
            transforms.send_json_response(self, 400,
                                          'Malformed "payload" parameter.')
            return
        if not self.assert_xsrf_token_or_fail(request, self.XSRF_ACTION,
                                              {'key': key}):
            return
        if not CourseSettingsRights.can_edit(self):
            transforms.send_json_response(self, 401, 'Access denied.',
                                          {'key': key})
            return

        request_data = self.process_put(request, payload)
        if request_data:
            course_settings = courses.deep_dict_merge(request_data,
                                                      self.get_course_dict())
            self.postprocess_put(course_settings, request)

            if not self.get_course().save_settings(course_settings):
                transforms.send_json_response(self, 412, 'Validation error.')
            transforms.send_json_response(self, 200, 'Saved.')
    def put(self):
        """Handles REST PUT verb with JSON payload."""
        assert self.app_context.is_editable_fs()

        request_param = self.request.get('request')
        if not request_param:
            transforms.send_json_response(
                self, 400, 'Missing "request" parameter.')
            return
        try:
            request = transforms.loads(request_param)
        except ValueError:
            transforms.send_json_response(
                self, 400, 'Malformed "request" parameter.')
            return
        key = request.get('key')
        if not key:
            transforms.send_json_response(
                self, 400, 'Request missing "key" parameter.')
            return
        payload_param = request.get('payload')
        if not payload_param:
            transforms.send_json_response(
                self, 400, 'Request missing "payload" parameter.')
            return
        try:
            payload = transforms.loads(payload_param)
        except ValueError:
            transforms.send_json_response(
                self, 400, 'Malformed "payload" parameter.')
            return
        if not self.assert_xsrf_token_or_fail(
                request, self.XSRF_ACTION, {'key': key}):
            return
        if not CourseSettingsRights.can_edit(self):
            transforms.send_json_response(
                self, 401, 'Access denied.', {'key': key})
            return

        request_data = self.process_put(request, payload)
        if request_data:
            course_settings = courses.deep_dict_merge(
                request_data, self.get_course_dict())
            self.postprocess_put(course_settings, request)

            if not self.get_course().save_settings(course_settings):
                transforms.send_json_response(self, 412, 'Validation error.')
            transforms.send_json_response(self, 200, 'Saved.')
Example #10
0
 def test_recursive_merge(self):
     tgt = {'a': {'b': 1}}
     src = {'a': 1, 'c': {'d': 4}}
     r = courses.deep_dict_merge(tgt, src)
     e = {'a': {'b': 1}, 'c': {'d': 4}}
     self.assertEqual(e, r)
Example #11
0
 def test_non_recursive_merge(self):
     tgt = {'a': 1, 'b': 2, 'd': 4}
     src = {'a': 1, 'b': 22, 'c': 3}
     r = courses.deep_dict_merge(tgt, src)
     e = {'a': 1, 'b': 2, 'c': 3, 'd': 4}
     self.assertEqual(e, r)
Example #12
0
 def test_tgt_empty_merge(self):
     tgt = {}
     src = {'a': 1}
     r = courses.deep_dict_merge(tgt, src)
     self.assertEqual(src, r)
Example #13
0
 def test_src_empty_merge(self):
     tgt = {'a': {'b': 2}, 'c': None}
     src = {}
     r = courses.deep_dict_merge(tgt, src)
     self.assertEqual(tgt, r)
Example #14
0
 def test_both_empty_merge(self):
     tgt = {}
     src = {}
     r = courses.deep_dict_merge(tgt, src)
     self.assertEqual({}, r)
Example #15
0
 def _get_environ(self, app_context):
     return courses.deep_dict_merge(
         self._new_env, self._old_get_environ(app_context))