def initialize(cls, template_values):
     template_values.update(
         {'show_course_explorer_tab': GCB_ENABLE_COURSE_EXPLORER_PAGE.value})
     user = users.get_current_user()
     if user:
         profile = StudentProfileDAO.get_profile_by_user_id(
             users.get_current_user().user_id())
         template_values.update({'has_global_profile': profile is not None})
Example #2
0
 def initialize(cls, template_values):
     template_values.update(
         {'show_course_explorer_tab': GCB_ENABLE_COURSE_EXPLORER_PAGE.value})
     user = users.get_current_user()
     if user:
         profile = StudentProfileDAO.get_profile_by_user_id(
             users.get_current_user().user_id())
         template_values.update({'has_global_profile': profile is not None})
    def add_delete_data_footer(cls, app_context):
        user = users.get_current_user()
        if not user:
            return []

        # No need for link if user has no PII in the course.  Here, we are
        # using the presence of a Student record as a marker for that, and
        # that's reasonable.  If there is no Student record, then either
        # there is no PII, or deletion is already in progress, and
        # re-requesting deletion would be pointless.
        student = models.Student.get_by_user(user)
        if not student or student.is_transient:
            return []
        if student.is_enrolled:
            link = 'student/unenroll'
        else:
            link = DataRemovalConfirmationHandler.URL.lstrip('/')

        # I18N: Gives a link on the footer of the page to permit the user
        # to delete their personal data.  This link only appears for users
        # who are currently enrolled in the course or who were enrolled
        # but still have personal data present in the course.
        text = app_context.gettext('Delete My Data')
        return [
            safe_dom.Element('li').add_child(safe_dom.A(link).add_text(text))]
Example #4
0
    def render_page(self, template_values, in_action=None):
        page_title = template_values['page_title']
        template_values['header_title'] = page_title
        template_values['page_headers'] = [
            hook(self) for hook in self.PAGE_HEADER_HOOKS]
        template_values['breadcrumbs'] = page_title

        current_action = (in_action or self.request.get('action')
            or self.default_action_for_current_permissions())
        current_menu_item = self.actions_to_menu_items.get(current_action)
        template_values['root_menu_group'] = self.root_menu_group
        template_values['current_menu_item'] = current_menu_item
        template_values['is_global_admin'] = True
        template_values['course_app_contexts'] = dashboard.get_visible_courses()

        template_values['gcb_course_base'] = '/'
        template_values['user_nav'] = safe_dom.NodeList().append(
            safe_dom.Text('%s | ' % users.get_current_user().email())
        ).append(
            safe_dom.Element(
                'a', href=users.create_logout_url(self.request.uri)
            ).add_text('Logout'))
        template_values[
            'page_footer'] = 'Page created on: %s' % datetime.datetime.now()
        template_values['coursebuilder_version'] = (
            os.environ['GCB_PRODUCT_VERSION'])
        template_values['application_id'] = app.get_application_id()
        template_values['application_version'] = (
            os.environ['CURRENT_VERSION_ID'])
        template_values['can_highlight_code'] = oeditor.CAN_HIGHLIGHT_CODE.value
        if not template_values.get('sections'):
            template_values['sections'] = []

        self.response.write(
            self.get_template('view.html', []).render(template_values))
Example #5
0
 def _get_env(self):
     return {
         'IN_SESSION': users.get_current_user() is not None,
         'ORIGIN': self.request.host_url,
         'RESOURCE_URI_PREFIX_BOUNDARY': _DISPATCH_INFIX,
         'SIGN_IN_URL': self._get_absolute_sign_in_url(),
     }
Example #6
0
    def render_page(self, template_values, in_action=None):
        page_title = template_values['page_title']
        template_values['header_title'] = page_title
        template_values['page_headers'] = [
            hook(self) for hook in self.PAGE_HEADER_HOOKS]
        template_values['breadcrumbs'] = page_title

        current_action = (in_action or self.request.get('action')
            or self.default_action_for_current_permissions())
        current_menu_item = self.actions_to_menu_items.get(current_action)
        template_values['root_menu_group'] = self.root_menu_group
        template_values['current_menu_item'] = current_menu_item
        template_values['is_global_admin'] = True
        template_values['course_app_contexts'] = dashboard.get_visible_courses()

        template_values['gcb_course_base'] = '/'
        template_values['user_nav'] = safe_dom.NodeList().append(
            safe_dom.Text('%s | ' % users.get_current_user().email())
        ).append(
            safe_dom.Element(
                'a', href=users.create_logout_url(self.request.uri)
            ).add_text('Logout'))
        template_values[
            'page_footer'] = 'Page created on: %s' % datetime.datetime.now()
        template_values['coursebuilder_version'] = (
            os.environ['GCB_PRODUCT_VERSION'])
        template_values['application_id'] = app.get_application_id()
        template_values['application_version'] = (
            os.environ['CURRENT_VERSION_ID'])
        if not template_values.get('sections'):
            template_values['sections'] = []

        self.response.write(
            self.get_template('view.html', []).render(template_values))
Example #7
0
    def post_config_override(self):
        """Handles 'override' property action."""
        name = self.request.get('name')

        # Find item in registry.
        item = None
        if name and name in config.Registry.registered.keys():
            item = config.Registry.registered[name]
        if not item:
            self.redirect('?action=settings' % self.LINK_URL)

        with Namespace(appengine_config.DEFAULT_NAMESPACE_NAME):
            # Add new entity if does not exist.
            try:
                entity = config.ConfigPropertyEntity.get_by_key_name(name)
            except db.BadKeyError:
                entity = None
            if not entity:
                entity = config.ConfigPropertyEntity(key_name=name)
                entity.value = str(item.value)
                entity.is_draft = True
                entity.put()

            models.EventEntity.record(
                'override-property', users.get_current_user(),
                transforms.dumps({
                    'name': name, 'value': str(entity.value)}))

        self.redirect('%s?%s' % (self.URL, urllib.urlencode(
            {'action': 'config_edit', 'name': name})))
Example #8
0
    def post_config_reset(self):
        """Handles 'reset' property action."""
        name = self.request.get('name')

        # Find item in registry.
        item = None
        if name and name in config.Registry.registered.keys():
            item = config.Registry.registered[name]
        if not item:
            self.redirect('%s?action=settings' % self.LINK_URL)

        with Namespace(appengine_config.DEFAULT_NAMESPACE_NAME):
            # Delete if exists.
            try:
                entity = config.ConfigPropertyEntity.get_by_key_name(name)
                if entity:
                    old_value = entity.value
                    entity.delete()

                    models.EventEntity.record(
                        'delete-property', users.get_current_user(),
                        transforms.dumps({
                            'name': name, 'value': str(old_value)}))

            except db.BadKeyError:
                pass

        self.redirect('%s?action=settings' % self.URL)
Example #9
0
    def _create_token(cls, action_id, issued_on):
        """Creates a string representation (digest) of a token."""

        # We have decided to use transient tokens stored in memcache to reduce
        # datastore costs. The token has 4 parts: hash of the actor user id,
        # hash of the action, hash of the time issued and the plain text of time
        # issued.

        # Lookup user id.
        user = users.get_current_user()
        if user:
            user_id = user.user_id()
        else:
            user_id = cls.USER_ID_DEFAULT

        # Round time to seconds.
        issued_on = long(issued_on)

        digest = EncryptionManager.hmac(
            cls.DELIMITER_PRIVATE.join([
                str(user_id), str(action_id), str(issued_on)]))
        token = '%s%s%s' % (
            issued_on, cls.DELIMITER_PUBLIC, base64.urlsafe_b64encode(digest))

        return token
 def in_any_role(cls, app_context):
     user = users.get_current_user()
     if not user:
         return False
     permissions_map = cls._load_permissions_map()
     user_permissions = permissions_map.get(user.email(), {})
     return bool(user_permissions)
Example #11
0
def login_with_specified_user_id(email, user_id, is_admin=False):
    assert email
    assert user_id
    os.environ['USER_EMAIL'] = email
    os.environ['USER_ID'] = user_id
    os.environ['USER_IS_ADMIN'] = '1' if is_admin else '0'
    return users.get_current_user()
 def get(self):
     template = _TEMPLATES_ENV.get_template(_FINISH_AUTH_NAME)
     self.response.out.write(template.render({
         _ENV_NAME: transforms.dumps({
             _IN_SESSION_NAME: bool(users.get_current_user()),
         })
     }))
Example #13
0
    def get(self):
        user = users.get_current_user()
        if not user:
            self.redirect(
                users.create_login_url('/modules/admin'), normalize=False)
            return
        if not self.can_view():
            login_url = users.create_login_url('/modules/admin')

            node_list = safe_dom.NodeList().append(
                safe_dom.Element('p').add_text(
                   'The current user has insufficient rights ' +
                    'to access this page.'))

            paragraph = safe_dom.Element('p').add_text('Go to the ')
            paragraph.append(safe_dom.A(href=login_url).add_text('Login page'))
            paragraph.add_text(
                ' to log in as an administrator, or go back to the ')
            paragraph.append(safe_dom.A(href='/').add_text('Home page'))
            paragraph.add_text('.')
            node_list.append(paragraph)

            self.response.write(node_list.sanitized)
            self.response.set_status(403)
            return

        super(WelcomeHandler, self).get()
Example #14
0
    def test_get_current_user_delegates_to_gae_users_service(self):
        actions.login(self.email)
        users_result = users.get_current_user()
        gae_users_result = gae_users.get_current_user()

        self.assert_service_results_equal_and_not_none(users_result,
                                                       gae_users_result)
def login_with_specified_user_id(email, user_id, is_admin=False):
    assert email
    assert user_id
    os.environ['USER_EMAIL'] = email
    os.environ['USER_ID'] = user_id
    os.environ['USER_IS_ADMIN'] = '1' if is_admin else '0'
    return users.get_current_user()
Example #16
0
    def render_page(self, template_values, in_action=None, in_tab=None):
        """Renders a page using provided template values."""
        template_values['header_title'] = template_values['page_title']
        template_values['page_headers'] = [
            hook(self) for hook in self.PAGE_HEADER_HOOKS]
        template_values['course_picker'] = self.get_course_picker()
        template_values['course_title'] = self.app_context.get_title()
        template_values['top_nav'] = self._get_top_nav(in_action, in_tab)
        template_values['gcb_course_base'] = self.get_base_href(self)
        template_values['user_nav'] = safe_dom.NodeList().append(
            safe_dom.Text('%s | ' % users.get_current_user().email())
        ).append(
            safe_dom.Element(
                'a', href=users.create_logout_url(self.request.uri)
            ).add_text('Logout'))
        template_values[
            'page_footer'] = 'Page created on: %s' % datetime.datetime.now()
        template_values['coursebuilder_version'] = (
            os.environ['GCB_PRODUCT_VERSION'])
        template_values['application_id'] = app_identity.get_application_id()
        template_values['application_version'] = (
            os.environ['CURRENT_VERSION_ID'])
        template_values['can_highlight_code'] = oeditor.CAN_HIGHLIGHT_CODE.value
        template_values['extra_css_href_list'] = self.EXTRA_CSS_HREF_LIST
        template_values['extra_js_href_list'] = self.EXTRA_JS_HREF_LIST
        if not template_values.get('sections'):
            template_values['sections'] = []

        self.response.write(
            self.get_template('view.html', []).render(template_values))
    def test_progress_pre_assessment_submitted_but_wrong(self):
        self.unit.pre_assessment = self.assessment_one.unit_id
        self.unit.post_assessment = self.assessment_two.unit_id
        self.course.save()

        self._get_unit_page(self.unit)
        response = self._post_assessment(self.assessment_one.unit_id, '99')

        # Reload student; assessment scores are cached in student.
        with Namespace(NAMESPACE):
            self.student = models.Student.get_by_user(users.get_current_user())

        # Zero progress because posting the assessment did not score 100%.
        self.tracker._progress_by_user_id.clear()
        with Namespace(NAMESPACE):
            self.assertEquals(0.000, self.tracker.get_unit_percent_complete(
                self.student)[self.unit.unit_id])

        # Still zero progress when take redirect to assessment confirmation.
        response = response.follow()
        self.tracker._progress_by_user_id.clear()
        with Namespace(NAMESPACE):
            self.assertEquals(0.000, self.tracker.get_unit_percent_complete(
                self.student)[self.unit.unit_id])

        # But have 33% progress when following the link to the 1st lesson
        response = self._click_next_button(response)
        self.tracker._progress_by_user_id.clear()
        with Namespace(NAMESPACE):
            self.assertEquals(0.333, self.tracker.get_unit_percent_complete(
                self.student)[self.unit.unit_id])
Example #18
0
    def post_config_override(self):
        """Handles 'override' property action."""
        name = self.request.get('name')

        # Find item in registry.
        item = None
        if name and name in config.Registry.registered.keys():
            item = config.Registry.registered[name]
        if not item:
            self.redirect('?action=settings' % self.LINK_URL)

        with Namespace(appengine_config.DEFAULT_NAMESPACE_NAME):
            # Add new entity if does not exist.
            try:
                entity = config.ConfigPropertyEntity.get_by_key_name(name)
            except db.BadKeyError:
                entity = None
            if not entity:
                entity = config.ConfigPropertyEntity(key_name=name)
                entity.value = str(item.value)
                entity.is_draft = True
                entity.put()

            models.EventEntity.record(
                'override-property', users.get_current_user(),
                transforms.dumps({
                    'name': name, 'value': str(entity.value)}))

        self.redirect('%s?%s' % (self.URL, urllib.urlencode(
            {'action': 'config_edit', 'name': name})))
Example #19
0
    def _create_token(cls, action_id, issued_on):
        """Creates a string representation (digest) of a token."""

        # We have decided to use transient tokens stored in memcache to reduce
        # datastore costs. The token has 4 parts: hash of the actor user id,
        # hash of the action, hash of the time issued and the plain text of time
        # issued.

        # Lookup user id.
        user = users.get_current_user()
        if user:
            user_id = user.user_id()
        else:
            user_id = cls.USER_ID_DEFAULT

        # Round time to seconds.
        issued_on = long(issued_on)

        digest = EncryptionManager.hmac(
            cls.DELIMITER_PRIVATE.join([
                str(user_id), str(action_id), str(issued_on)]))
        token = '%s%s%s' % (
            issued_on, cls.DELIMITER_PUBLIC, base64.urlsafe_b64encode(digest))

        return token
Example #20
0
    def render_page(self, template_values, in_action=None, in_tab=None):
        """Renders a page using provided template values."""
        template_values['header_title'] = template_values['page_title']
        template_values['page_headers'] = [
            hook(self) for hook in self.PAGE_HEADER_HOOKS
        ]
        template_values['course_picker'] = self.get_course_picker()
        template_values['course_title'] = self.app_context.get_title()
        template_values['top_nav'] = self._get_top_nav(in_action, in_tab)
        template_values['gcb_course_base'] = self.get_base_href(self)
        template_values['user_nav'] = safe_dom.NodeList().append(
            safe_dom.Text('%s | ' % users.get_current_user().email())).append(
                safe_dom.Element('a',
                                 href=users.create_logout_url(
                                     self.request.uri)).add_text('Logout'))
        template_values[
            'page_footer'] = 'Page created on: %s' % datetime.datetime.now()
        template_values['coursebuilder_version'] = (
            os.environ['GCB_PRODUCT_VERSION'])
        template_values['application_id'] = app_identity.get_application_id()
        template_values['application_version'] = (
            os.environ['CURRENT_VERSION_ID'])
        template_values[
            'can_highlight_code'] = oeditor.CAN_HIGHLIGHT_CODE.value
        template_values['extra_css_href_list'] = self.EXTRA_CSS_HREF_LIST
        template_values['extra_js_href_list'] = self.EXTRA_JS_HREF_LIST
        if not template_values.get('sections'):
            template_values['sections'] = []

        self.response.write(
            self.get_template('view.html', []).render(template_values))
 def get(self):
     template = _TEMPLATES_ENV.get_template(_FINISH_AUTH_NAME)
     self.response.out.write(template.render({
         _ENV_NAME: transforms.dumps({
             _IN_SESSION_NAME: bool(users.get_current_user()),
         })
     }))
Example #22
0
    def get(self):
        user = users.get_current_user()
        if not user:
            self.redirect(
                users.create_login_url('/modules/admin'), normalize=False)
            return
        if not self.can_view():
            login_url = users.create_login_url('/modules/admin')

            node_list = safe_dom.NodeList().append(
                safe_dom.Element('p').add_text(
                   'The current user has insufficient rights ' +
                    'to access this page.'))

            paragraph = safe_dom.Element('p').add_text('Go to the ')
            paragraph.append(safe_dom.A(href=login_url).add_text('Login page'))
            paragraph.add_text(
                ' to log in as an administrator, or go back to the ')
            paragraph.append(safe_dom.A(href='/').add_text('Home page'))
            paragraph.add_text('.')
            node_list.append(paragraph)

            self.response.write(node_list.sanitized)
            return
        super(WelcomeHandler, self).get()
    def post_config_reset(self):
        """Handles 'reset' property action."""
        name = self.request.get('name')

        # Find item in registry.
        item = None
        if name and name in config.Registry.registered.keys():
            item = config.Registry.registered[name]
        if not item:
            self.redirect('%s?action=settings' % self.LINK_URL)

        with common_utils.Namespace(appengine_config.DEFAULT_NAMESPACE_NAME):
            # Delete if exists.
            try:
                entity = config.ConfigPropertyEntity.get_by_key_name(name)
                if entity:
                    old_value = entity.value
                    entity.delete()

                    models.EventEntity.record(
                        'delete-property', users.get_current_user(),
                        transforms.dumps({
                            'name': name,
                            'value': str(old_value)
                        }))

            except db.BadKeyError:
                pass

        self.redirect('%s?action=settings' % self.URL)
Example #24
0
 def in_any_role(cls, app_context):
     user = users.get_current_user()
     if not user:
         return False
     permissions_map = cls._load_permissions_map()
     user_permissions = permissions_map.get(user.email(), {})
     return bool(user_permissions)
Example #25
0
    def test_get_current_user_delegates_to_gae_users_service(self):
        actions.login(self.email)
        users_result = users.get_current_user()
        gae_users_result = gae_users.get_current_user()

        self.assert_service_results_equal_and_not_none(
            users_result, gae_users_result)
Example #26
0
    def render_page(self, template_values, in_action=None, in_tab=None):
        page_title = template_values['page_title']
        template_values['header_title'] = page_title
        template_values['page_headers'] = [
            hook(self) for hook in self.PAGE_HEADER_HOOKS
        ]
        template_values['breadcrumbs'] = page_title

        template_values['top_nav'] = self._get_top_nav(in_action, in_tab)
        template_values['gcb_course_base'] = '/'
        template_values['user_nav'] = safe_dom.NodeList().append(
            safe_dom.Text('%s | ' % users.get_current_user().email())).append(
                safe_dom.Element('a',
                                 href=users.create_logout_url(
                                     self.request.uri)).add_text('Logout'))
        template_values[
            'page_footer'] = 'Page created on: %s' % datetime.datetime.now()
        template_values['coursebuilder_version'] = (
            os.environ['GCB_PRODUCT_VERSION'])
        template_values['application_id'] = app.get_application_id()
        template_values['application_version'] = (
            os.environ['CURRENT_VERSION_ID'])
        template_values[
            'can_highlight_code'] = oeditor.CAN_HIGHLIGHT_CODE.value
        if not template_values.get('sections'):
            template_values['sections'] = []

        self.response.write(
            self.get_template('view.html', []).render(template_values))
Example #27
0
    def render_page(self, template_values, in_action=None, in_tab=None):
        page_title = template_values['page_title']
        template_values['header_title'] = page_title
        template_values['page_headers'] = [
            hook(self) for hook in self.PAGE_HEADER_HOOKS]
        template_values['breadcrumbs'] = page_title

        template_values['top_nav'] = self._get_top_nav(in_action, in_tab)
        template_values['gcb_course_base'] = '/'
        template_values['user_nav'] = safe_dom.NodeList().append(
            safe_dom.Text('%s | ' % users.get_current_user().email())
        ).append(
            safe_dom.Element(
                'a', href=users.create_logout_url(self.request.uri)
            ).add_text('Logout'))
        template_values[
            'page_footer'] = 'Page created on: %s' % datetime.datetime.now()
        template_values['coursebuilder_version'] = (
            os.environ['GCB_PRODUCT_VERSION'])
        template_values['application_id'] = app.get_application_id()
        template_values['application_version'] = (
            os.environ['CURRENT_VERSION_ID'])
        template_values['can_highlight_code'] = oeditor.CAN_HIGHLIGHT_CODE.value
        if not template_values.get('sections'):
            template_values['sections'] = []

        self.response.write(
            self.get_template('view.html', []).render(template_values))
    def add_delete_data_footer(cls, app_context):
        user = users.get_current_user()
        if not user:
            return []

        # No need for link if user has no PII in the course.  Here, we are
        # using the presence of a Student record as a marker for that, and
        # that's reasonable.  If there is no Student record, then either
        # there is no PII, or deletion is already in progress, and
        # re-requesting deletion would be pointless.
        student = models.Student.get_by_user(user)
        if not student or student.is_transient:
            return []
        if student.is_enrolled:
            link = 'student/unenroll'
        else:
            link = DataRemovalConfirmationHandler.URL.lstrip('/')

        # I18N: Gives a link on the footer of the page to permit the user
        # to delete their personal data.  This link only appears for users
        # who are currently enrolled in the course or who were enrolled
        # but still have personal data present in the course.
        text = app_context.gettext('Delete My Data')
        return [
            safe_dom.Element('li').add_child(safe_dom.A(link).add_text(text))]
Example #29
0
 def wrapper(self, *args, **kwargs):
     if not users.get_current_user():
         try:
             self.DenyAccess()
         except Exception, e:  # pylint: disable=broad-except
             self.handle_exception(e, self.app.debug)
         finally:
    def test_progress_pre_assessment_submitted_and_fully_correct(self):
        self.unit.pre_assessment = self.assessment_one.unit_id
        self.unit.post_assessment = self.assessment_two.unit_id
        self.course.save()

        self._get_unit_page(self.unit)
        response = self._post_assessment(self.assessment_one.unit_id, '100')

        # Reload student; assessment scores are cached in student.
        with Namespace(NAMESPACE):
            self.student = models.Student.get_by_user(users.get_current_user())

        # 100% progress because pre-assessment was 100% correct.
        with Namespace(NAMESPACE):
            self.assertEquals(
                1.000,
                self.tracker.get_unit_percent_complete(
                    self.student)[self.unit.unit_id])

        # Still 100% after navigating onto a lesson
        response = response.follow()
        with Namespace(NAMESPACE):
            self.assertEquals(
                1.000,
                self.tracker.get_unit_percent_complete(
                    self.student)[self.unit.unit_id])
    def test_progress_pre_assessment_submitted_but_wrong(self):
        self.unit.pre_assessment = self.assessment_one.unit_id
        self.unit.post_assessment = self.assessment_two.unit_id
        self.course.save()

        self._get_unit_page(self.unit)
        response = self._post_assessment(self.assessment_one.unit_id, '99')

        # Reload student; assessment scores are cached in student.
        with Namespace(NAMESPACE):
            self.student = models.Student.get_by_user(users.get_current_user())

        # Zero progress because posting the assessment did not score 100%.
        with Namespace(NAMESPACE):
            self.assertEquals(
                0.000,
                self.tracker.get_unit_percent_complete(
                    self.student)[self.unit.unit_id])

        # Still zero progress when take redirect to assessment confirmation.
        response = response.follow()
        with Namespace(NAMESPACE):
            self.assertEquals(
                0.000,
                self.tracker.get_unit_percent_complete(
                    self.student)[self.unit.unit_id])

        # But have 33% progress when following the link to the 1st lesson
        response = self._click_next_button(response)
        with Namespace(NAMESPACE):
            self.assertEquals(
                0.333,
                self.tracker.get_unit_percent_complete(
                    self.student)[self.unit.unit_id])
 def get(self):
     user = users.get_current_user()
     self._set_headers(self.response.headers)
     template = self.get_template(_ENROLL_ERROR_NAME, [_TEMPLATES_DIR_V1])
     self.response.out.write(template.render({
         _EMBED_CHILD_JS_URL_NAME: _EMBED_CHILD_JS_URL,
         _EMAIL_NAME: user.email() if user else None,
     }))
Example #33
0
    def test_get_current_user_returns_none_when_enabled_but_no_token(self):
        self.runtime_config.enabled = True
        gitkit.Runtime.set_current_runtime_config(self.runtime_config)
        service = self._get_gitkit_service(self.gitkit_user)
        self.swap(
            gitkit, '_make_gitkit_service', lambda *args, **kwargs: service)

        self.assertIsNone(users.get_current_user())
 def get(self):
     user = users.get_current_user()
     self._set_headers(self.response.headers)
     template = self.get_template(_ENROLL_ERROR_NAME, [_TEMPLATES_DIR_V1])
     self.response.out.write(template.render({
         _EMBED_CHILD_JS_URL_NAME: _EMBED_CHILD_JS_URL,
         _EMAIL_NAME: user.email() if user else None,
     }))
Example #35
0
    def test_get_current_user_returns_none_when_enabled_but_no_token(self):
        self.runtime_config.enabled = True
        gitkit.Runtime.set_current_runtime_config(self.runtime_config)
        service = self._get_gitkit_service(self.gitkit_user)
        self.swap(gitkit, '_make_gitkit_service',
                  lambda *args, **kwargs: service)

        self.assertIsNone(users.get_current_user())
Example #36
0
    def put(self):
        """Handles REST PUT verb with JSON payload."""
        request = transforms.loads(self.request.get('request'))
        key = request.get('key')

        if not self.assert_xsrf_token_or_fail(
                request, 'config-property-put', {'key': key}):
            return

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

        item = None
        if key and key in config.Registry.registered.keys():
            item = config.Registry.registered[key]
        if not item:
            self.redirect('/admin?action=settings')

        try:
            entity = config.ConfigPropertyEntity.get_by_key_name(key)
        except db.BadKeyError:
            transforms.send_json_response(
                self, 404, 'Object not found.', {'key': key})
            return
        if not entity:
            entity = config.ConfigPropertyEntity(key_name=key)
            old_value = None
        else:
            old_value = entity.value

        payload = request.get('payload')
        json_object = transforms.loads(payload)
        new_value = item.value_type(json_object['value'])

        # Validate the value.
        errors = []
        if item.validator:
            item.validator(new_value, errors)
        if errors:
            transforms.send_json_response(self, 412, '\n'.join(errors))
            return

        # Update entity.

        entity.value = str(new_value)
        entity.is_draft = False
        entity.put()
        if item.after_change:
            item.after_change(item, old_value)

        models.EventEntity.record(
            'put-property', users.get_current_user(), transforms.dumps({
                'name': key,
                'before': str(old_value), 'after': str(entity.value)}))

        transforms.send_json_response(self, 200, 'Saved.')
    def _unregister_flow(self,
                         response,
                         with_deletion_checked=False,
                         cancel_on_unregister=False,
                         cancel_on_deletion=False):
        unregistration_expected = (not cancel_on_unregister
                                   and not cancel_on_deletion)
        data_deletion_expected = (unregistration_expected
                                  and with_deletion_checked)

        # Caller should have arranged for us to be at the unregister form.
        form = response.form
        if with_deletion_checked:
            form['data_removal'].checked = True
        if cancel_on_unregister:
            response = self.click(response, "No")
            return response

        # Submit unregister form.
        response = form.submit()

        if with_deletion_checked:
            self.assertIn(
                'Once you delete your data, there is no way to recover it.',
                response.body)
            form = response.form
            form.action = self.canonicalize(form.action, response)
            if cancel_on_deletion:
                response = form.submit('cancel_removal').follow()
                self.assertIn(
                    'To leave the course permanently, click on Unenroll',
                    response.body)
            else:
                response = form.submit('data_removal')
                self.assertIn('You have been unenrolled', response.body)

        # Try to visit student's profile - verify can or can't depending
        # on whether we unregistered the student.
        response = self.get('student/home')
        if unregistration_expected:
            self.assertEquals(response.status_int, 302)
            self.assertEquals(response.location,
                              'http://localhost/%s/course' % self.COURSE)
            response = response.follow()
            self.assertEquals(response.status_int, 200)
        else:
            self.assertEquals(response.status_int, 200)  # not 302 to /course

        # Run pipeline which might do deletion to ensure we are really
        # giving the code the opportunity to do the deletion before we
        # check whether the Student is not gone.
        self._complete_removal()
        with common_utils.Namespace(self.NAMESPACE):
            user = users.get_current_user()
            if data_deletion_expected:
                self.assertIsNone(models.Student.get_by_user(user))
            else:
                self.assertIsNotNone(models.Student.get_by_user(user))
Example #38
0
    def post(self):
        name = COURSE_EXPLORER_SETTINGS.name
        request = transforms.loads(self.request.get('request'))

        if not self.assert_xsrf_token_or_fail(request, self.ACTION, {}):
            return

        if not roles.Roles.is_course_admin(self.app_context):
            transforms.send_json_response(self, 401, 'Access denied.', {})
            return

        raw_data = transforms.loads(request.get('payload'))
        raw_data.pop('logo', None)
        try:
            data = transforms.json_to_dict(
                raw_data,
                schema_provider(None).get_json_schema_dict())
        except (TypeError, ValueError) as err:
            self.validation_error(err.replace('\n', ' '))
            return

        logo = self.request.POST.get('logo')
        logo_uploaded = isinstance(logo, cgi.FieldStorage)
        if logo_uploaded:
            data['logo_bytes_base64'] = base64.b64encode(logo.file.read())
            data['logo_mime_type'] = logo.type

        with common_utils.Namespace(appengine_config.DEFAULT_NAMESPACE_NAME):
            entity = config.ConfigPropertyEntity.get_by_key_name(name)

            if entity is None:
                entity = config.ConfigPropertyEntity(key_name=name)
                old_value = None
            else:
                old_value = entity.value

            # Don't delete the logo.
            if not logo_uploaded and old_value:
                old_dict = transforms.loads(old_value)
                if ('logo_bytes_base64' in old_dict
                        and 'logo_mime_type' in old_dict):
                    data['logo_bytes_base64'] = old_dict['logo_bytes_base64']
                    data['logo_mime_type'] = old_dict['logo_mime_type']

            entity.value = transforms.dumps(data)
            entity.is_draft = False
            entity.put()

            # is this necessary?
            models.EventEntity.record(
                'put-property', users.get_current_user(),
                transforms.dumps({
                    'name': name,
                    'before': str(old_value),
                    'after': str(entity.value)
                }))

        transforms.send_file_upload_response(self, 200, 'Saved.')
Example #39
0
 def get(self):
     user = users.get_current_user()
     if not user:
         self.redirect(users.create_login_url('/admin/welcome'),
                       normalize=False)
         return
     if not self.can_view():
         return
     super(WelcomeHandler, self).get()
Example #40
0
    def test_get_current_user_returns_gae_value_for_admins_when_disabled(self):
        # This tests that we return users who are in config yaml's admins list
        # when disabled is True. This is important because during the bootstrap
        # process (when disabled is True), we only want admin users to be able
        # to sign into the site.
        self.runtime_config.enabled = False
        self.runtime_config.admins = ['*****@*****.**']
        gitkit.Runtime.set_current_runtime_config(self.runtime_config)

        actions.login('*****@*****.**')
        user = users.get_current_user()

        self.assertEquals('*****@*****.**', user.email())

        actions.login('*****@*****.**')

        self.assertIsNone(users.get_current_user())
        self.assertLogContains('Disallowing get_current_user() for non-admin')
Example #41
0
 def get(self):
     user = users.get_current_user()
     if not user:
         self.redirect(
             users.create_login_url('/admin/welcome'), normalize=False)
         return
     if not self.can_view():
         return
     super(WelcomeHandler, self).get()
Example #42
0
    def apply(cls, handler):
        user = users.get_current_user()
        assert user

        if models.Student.get_enrolled_student_by_user(user):
            return

        models.StudentProfileDAO.add_new_student_for_current_user(
            None, None, handler)
Example #43
0
    def post(self):
        name = COURSE_EXPLORER_SETTINGS.name
        request = transforms.loads(self.request.get('request'))

        if not self.assert_xsrf_token_or_fail(
                request, self.ACTION, {}):
            return

        if not roles.Roles.is_course_admin(self.app_context):
            transforms.send_json_response(
                self, 401, 'Access denied.', {})
            return

        raw_data = transforms.loads(request.get('payload'))
        raw_data.pop('logo', None)
        try:
            data = transforms.json_to_dict(
                raw_data, schema_provider(None).get_json_schema_dict())
        except (TypeError, ValueError) as err:
            self.validation_error(err.replace('\n', ' '))
            return

        logo = self.request.POST.get('logo')
        logo_uploaded = isinstance(logo, cgi.FieldStorage)
        if logo_uploaded:
            data['logo_bytes_base64'] = base64.b64encode(logo.file.read())
            data['logo_mime_type'] = logo.type

        with common_utils.Namespace(appengine_config.DEFAULT_NAMESPACE_NAME):
            entity = config.ConfigPropertyEntity.get_by_key_name(name)

            if entity is None:
                entity = config.ConfigPropertyEntity(key_name=name)
                old_value = None
            else:
                old_value = entity.value

            # Don't delete the logo.
            if not logo_uploaded and old_value:
                old_dict = transforms.loads(old_value)
                if (
                        'logo_bytes_base64' in old_dict and
                        'logo_mime_type' in old_dict):
                    data['logo_bytes_base64'] = old_dict['logo_bytes_base64']
                    data['logo_mime_type'] = old_dict['logo_mime_type']

            entity.value = transforms.dumps(data)
            entity.is_draft = False
            entity.put()

            # is this necessary?
            models.EventEntity.record(
                'put-property', users.get_current_user(), transforms.dumps({
                    'name': name,
                    'before': str(old_value), 'after': str(entity.value)}))

        transforms.send_file_upload_response(self, 200, 'Saved.')
Example #44
0
    def test_get_current_user_returns_gae_value_for_admins_when_disabled(self):
        # This tests that we return users who are in config yaml's admins list
        # when disabled is True. This is important because during the bootstrap
        # process (when disabled is True), we only want admin users to be able
        # to sign into the site.
        self.runtime_config.enabled = False
        self.runtime_config.admins = ['*****@*****.**']
        gitkit.Runtime.set_current_runtime_config(self.runtime_config)

        actions.login('*****@*****.**')
        user = users.get_current_user()

        self.assertEquals('*****@*****.**', user.email())

        actions.login('*****@*****.**')

        self.assertIsNone(users.get_current_user())
        self.assertLogContains('Disallowing get_current_user() for non-admin')
Example #45
0
def create_course_file_if_not_exists(handler):
    assert handler.app_context.is_editable_fs()

    # Check if course.yaml exists; create if not.
    fs = handler.app_context.fs.impl
    course_yaml = fs.physical_to_logical('/course.yaml')
    if not fs.isfile(course_yaml):
        fs.put(course_yaml, vfs.string_to_stream(
            courses.EMPTY_COURSE_YAML % users.get_current_user().email()))
Example #46
0
 def _add_broken_label_references(self):
     # Add some broken references to student's labels list.
     actions.login(REGISTERED_STUDENT_EMAIL)
     user = users.get_current_user()
     student = (
         models.StudentProfileDAO.get_enrolled_student_by_user_for(
             user, FakeContext(NAMESPACE)))
     student.labels = '123123123 456456456 %d' % self.foo_id
     student.put()
    def apply(cls, handler):
        user = users.get_current_user()
        assert user

        if models.Student.get_enrolled_student_by_user(user):
            return

        models.StudentProfileDAO.add_new_student_for_current_user(
            None, None, handler)
    def _unregister_flow(self, response,
                         with_deletion_checked=False,
                         cancel_on_unregister=False,
                         cancel_on_deletion=False):
        unregistration_expected = (not cancel_on_unregister and
                                   not cancel_on_deletion)
        data_deletion_expected = (unregistration_expected and
                                  with_deletion_checked)

        # Caller should have arranged for us to be at the unregister form.
        form = response.form
        if with_deletion_checked:
            form['data_removal'].checked = True
        if cancel_on_unregister:
            response = self.click(response, "No")
            return response

        # Submit unregister form.
        response = form.submit()

        if with_deletion_checked:
            self.assertIn(
                'Once you delete your data, there is no way to recover it.',
                response.body)
            form = response.form
            form.action = self.canonicalize(form.action, response)
            if cancel_on_deletion:
                response = form.submit('cancel_removal').follow()
                self.assertIn(
                    'To leave the course permanently, click on Unenroll',
                    response.body)
            else:
                response = form.submit('data_removal')
                self.assertIn('You have been unenrolled', response.body)

        # Try to visit student's profile - verify can or can't depending
        # on whether we unregistered the student.
        response = self.get('student/home')
        if unregistration_expected:
            self.assertEquals(response.status_int, 302)
            self.assertEquals(response.location,
                              'http://localhost/%s/course' % self.COURSE)
            response = response.follow()
            self.assertEquals(response.status_int, 200)
        else:
            self.assertEquals(response.status_int, 200)  # not 302 to /course

        # Run pipeline which might do deletion to ensure we are really
        # giving the code the opportunity to do the deletion before we
        # check whether the Student is not gone.
        self._complete_removal()
        with common_utils.Namespace(self.NAMESPACE):
            user = users.get_current_user()
            if data_deletion_expected:
                self.assertIsNone(models.Student.get_by_user(user))
            else:
                self.assertIsNotNone(models.Student.get_by_user(user))
Example #49
0
    def put(self):
        """Handles REST PUT verb with JSON payload."""
        request = transforms.loads(self.request.get('request'))
        key = request.get('key')

        if not self.assert_xsrf_token_or_fail(request, 'config-property-put',
                                              {'key': key}):
            return

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

        item = None
        if key and key in config.Registry.registered.keys():
            item = config.Registry.registered[key]
        if not item:
            self.redirect('/admin?action=settings')

        try:
            entity = config.ConfigPropertyEntity.get_by_key_name(key)
        except db.BadKeyError:
            transforms.send_json_response(self, 404, 'Object not found.',
                                          {'key': key})
            return

        payload = request.get('payload')
        json_object = transforms.loads(payload)
        new_value = item.value_type(json_object['value'])

        # Validate the value.
        errors = []
        if item.validator:
            item.validator(new_value, errors)
        if errors:
            transforms.send_json_response(self, 412, '\n'.join(errors))
            return

        # Update entity.
        old_value = entity.value
        entity.value = str(new_value)
        entity.is_draft = json_object['is_draft']
        entity.put()
        if item.after_change:
            item.after_change(item, old_value)

        models.EventEntity.record(
            'put-property', users.get_current_user(),
            transforms.dumps({
                'name': key,
                'before': str(old_value),
                'after': str(entity.value)
            }))

        transforms.send_json_response(self, 200, 'Saved.')
    def edit_admin_preferences(handler):
        if not roles.Roles.is_course_admin(handler.app_context):
            handler.error(401)
            return

        # Admin's prefs must exist as real DB row for REST handler to operate.
        user_id = users.get_current_user().user_id()
        prefs = models.StudentPreferencesDAO.load(user_id)
        if not prefs:
            prefs = models.StudentPreferencesDAO.load_or_default()
            models.StudentPreferencesDAO.save(prefs)

        return {
            'page_title': handler.format_title('Edit Preferences'),
            'main_content': handler.get_form(
                AdminPreferencesRESTHandler,
                users.get_current_user().user_id(),
                exit_url='', deletable=False)
        }
Example #51
0
def create_course_file_if_not_exists(handler):
    assert handler.app_context.is_editable_fs()

    # Check if course.yaml exists; create if not.
    fs = handler.app_context.fs.impl
    course_yaml = fs.physical_to_logical('/course.yaml')
    if not fs.isfile(course_yaml):
        fs.put(course_yaml, vfs.string_to_stream(
            courses.Course.EMPTY_COURSE_YAML %
            users.get_current_user().email()))
 def _get_env(self):
     return {
         _EMBED_CHILD_CSS_URL_NAME: self._get_absolute_embed_child_css_url(),
         _IN_SESSION_NAME: users.get_current_user() is not None,
         _MATERIAL_ICONS_URL_NAME: _MATERIAL_ICONS_URL,
         _ORIGIN_NAME: self.request.host_url,
         _RESOURCE_URI_PREFIX_BOUNDARY_NAME: _DISPATCH_INFIX,
         _ROBOTO_URL_NAME: _ROBOTO_URL,
         _SIGN_IN_URL_NAME: self._get_absolute_sign_in_url(),
     }
 def _get_env(self):
     return {
         _EMBED_CHILD_CSS_URL_NAME: self._get_absolute_embed_child_css_url(),
         _IN_SESSION_NAME: users.get_current_user() is not None,
         _MATERIAL_ICONS_URL_NAME: _MATERIAL_ICONS_URL,
         _ORIGIN_NAME: self.request.host_url,
         _RESOURCE_URI_PREFIX_BOUNDARY_NAME: _DISPATCH_INFIX,
         _ROBOTO_URL_NAME: _ROBOTO_URL,
         _SIGN_IN_URL_NAME: self._get_absolute_sign_in_url(),
     }
Example #54
0
    def is_user_allowed(cls, app_context, module, permission):
        """Check whether the current user is assigned a certain permission.

        Args:
            app_context: sites.ApplicationContext of the relevant course
            module: module object that registered the permission.
            permission: string specifying the permission.

        Returns:
            boolean indicating whether the current user is allowed to perform
                the action associated with the permission.
        """
        if cls.is_course_admin(app_context):
            return True
        if not module or not permission or not users.get_current_user():
            return False
        permissions_map = cls._load_permissions_map()
        user_permissions = permissions_map.get(
            users.get_current_user().email(), {})
        return permission in user_permissions.get(module.name, set())
    def is_user_allowed(cls, app_context, module, permission):
        """Check whether the current user is assigned a certain permission.

        Args:
            app_context: sites.ApplicationContext of the relevant course
            module: module object that registered the permission.
            permission: string specifying the permission.

        Returns:
            boolean indicating whether the current user is allowed to perform
                the action associated with the permission.
        """
        if cls.is_course_admin(app_context):
            return True
        if not module or not permission or not users.get_current_user():
            return False
        permissions_map = cls._load_permissions_map()
        user_permissions = permissions_map.get(
            users.get_current_user().email(), {})
        return permission in user_permissions.get(module.name, set())
 def _edit_admin_preferences(handler, template_values, exit_url):
     if not roles.Roles.is_course_admin(handler.app_context):
         handler.error(401)
         return
     template_values.update({
         'page_title': handler.format_title('Edit Preferences'),
         'main_content': handler.get_form(
             AdminPreferencesRESTHandler,
             users.get_current_user().user_id(),
             exit_url, deletable=False)
     })
Example #57
0
 def _make_new_course(self, uid, title):
     """Make a new course entry."""
     errors = []
     admin_email = users.get_current_user().email()
     entry = sites.add_new_course_entry(uid, title, admin_email, errors)
     if errors:
         raise Exception(errors)
     app_context = sites.get_all_courses(entry)[0]
     new_course = models.courses.Course(None, app_context=app_context)
     new_course.init_new_course_settings(title, admin_email)
     return app_context