def test_preference_setting_changes_cookie(self, lang_pref_out):
        """
        Test that the LANGUAGE_COOKIE is always set to the user's current language preferences
        at the end of the request, with an expiry that's the same as the users current session cookie.
        """
        if lang_pref_out:
            set_user_preference(self.user, LANGUAGE_KEY, lang_pref_out)
        else:
            delete_user_preference(self.user, LANGUAGE_KEY)

        response = mock.Mock(spec=HttpResponse)
        self.middleware.process_response(self.request, response)

        if lang_pref_out:
            response.set_cookie.assert_called_with(
                settings.LANGUAGE_COOKIE,
                value=lang_pref_out,
                domain=settings.SESSION_COOKIE_DOMAIN,
                max_age=COOKIE_DURATION,
            )
        else:
            response.delete_cookie.assert_called_with(
                settings.LANGUAGE_COOKIE,
                domain=settings.SESSION_COOKIE_DOMAIN,
            )

        self.assertNotIn(LANGUAGE_SESSION_KEY, self.request.session)
示例#2
0
def create_user_account(request, params):

    params = dict(params.items())

    params["password"] = pipeline.make_random_password()

    form = AccountCreationForm(
        data=params, enforce_username_neq_password=True, enforce_password_policy=False, tos_required=False
    )

    with transaction.commit_on_success():
        # first, create the account
        (user, profile, registration) = _do_create_account(form)

        uid = params["uid"]

        # associate the user with azuread
        associate_user(request.backend, uid, user)

        # Perform operations that are non-critical parts of account creation
        preferences_api.set_user_preference(user, LANGUAGE_KEY, get_language())

        # create_comments_service_user(user)

        registration.activate()

    return {"username": user.username, "email": user.email}
示例#3
0
 def create(self, request, *args, **kwargs):
     serializer = self.get_serializer(data=request.DATA, files=request.FILES)
     if serializer.is_valid():
         value = serializer.object["share_with_facebook_friends"]
         set_user_preference(request.user, "share_with_facebook_friends", value)
         return self.get(request, *args, **kwargs)
     return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
示例#4
0
    def _activate_preview_language(self, request):
        """
        If the request has the get parameter ``preview-lang``,
        and that language doesn't appear in ``self.released_langs``,
        then set the session LANGUAGE_SESSION_KEY to that language.
        """
        if 'clear-lang' in request.GET:
            # Reset dark lang
            delete_user_preference(request.user, DARK_LANGUAGE_KEY)
            # Reset user's language to their language preference, if they have one
            user_pref = get_user_preference(request.user, LANGUAGE_KEY)
            if user_pref:
                request.session[LANGUAGE_SESSION_KEY] = user_pref
            elif LANGUAGE_SESSION_KEY in request.session:
                del request.session[LANGUAGE_SESSION_KEY]
            return

        preview_lang = request.GET.get('preview-lang', None)
        if not preview_lang:
            try:
                # Try to get the request user's preference (might not have a user, though)
                preview_lang = get_user_preference(request.user, DARK_LANGUAGE_KEY)
            except UserNotFound:
                return

        if not preview_lang:
            return

        request.session[LANGUAGE_SESSION_KEY] = preview_lang
        set_user_preference(request.user, DARK_LANGUAGE_KEY, preview_lang)
    def test_get_account_private_visibility(self, api_client, requesting_username, preference_visibility):
        """
        Test the return from GET based on user visibility setting.
        """
        def verify_fields_visible_to_all_users(response):
            """
            Confirms that private fields are private, and public/shareable fields are public/shareable
            """
            if preference_visibility == PRIVATE_VISIBILITY:
                self._verify_private_account_response(response, account_privacy=PRIVATE_VISIBILITY)
            else:
                self._verify_full_shareable_account_response(response, ALL_USERS_VISIBILITY, badges_enabled=True)

        client = self.login_client(api_client, requesting_username)

        # Update user account visibility setting.
        set_user_preference(self.user, ACCOUNT_VISIBILITY_PREF_KEY, preference_visibility)
        self.create_mock_profile(self.user)
        response = self.send_get(client)

        if requesting_username == "different_user":
            verify_fields_visible_to_all_users(response)
        else:
            self._verify_full_account_response(response)

        # Verify how the view parameter changes the fields that are returned.
        response = self.send_get(client, query_parameters='view=shared')
        verify_fields_visible_to_all_users(response)
示例#6
0
    def test_custom_visibility_over_age(self, api_client, requesting_username):
        self.create_mock_profile(self.user)
        # set user's custom visibility preferences
        set_user_preference(self.user, ACCOUNT_VISIBILITY_PREF_KEY, CUSTOM_VISIBILITY)
        shared_fields = ("bio", "language_proficiencies", "name")
        for field_name in shared_fields:
            set_user_preference(self.user, "visibility.{}".format(field_name), ALL_USERS_VISIBILITY)

        # make API request
        client = self.login_client(api_client, requesting_username)
        response = self.send_get(client)

        # verify response
        if requesting_username == "different_user":
            data = response.data
            self.assertEqual(6, len(data))

            # public fields
            self.assertEqual(self.user.username, data["username"])
            self.assertEqual(UserPreference.get_value(self.user, 'account_privacy'), data["account_privacy"])
            self._verify_profile_image_data(data, has_profile_image=True)

            # custom shared fields
            self.assertEqual(TEST_BIO_VALUE, data["bio"])
            self.assertEqual([{"code": TEST_LANGUAGE_PROFICIENCY_CODE}], data["language_proficiencies"])
            self.assertEqual(self.user.first_name + " " + self.user.last_name, data["name"])
        else:
            self._verify_full_account_response(response)
示例#7
0
def set_user_preview_site_theme(request, preview_site_theme):
    """
    Sets the current user's preferred preview site theme.

    Args:
        request: the current request
        preview_site_theme (str or SiteTheme): the preview site theme or theme name.
          None can be specified to remove the preview site theme.
    """
    if preview_site_theme:
        if isinstance(preview_site_theme, SiteTheme):
            preview_site_theme_name = preview_site_theme.theme_dir_name
        else:
            preview_site_theme_name = preview_site_theme
        if theme_exists(preview_site_theme_name):
            set_user_preference(request.user, PREVIEW_SITE_THEME_PREFERENCE_KEY, preview_site_theme_name)
            PageLevelMessages.register_success_message(
                request,
                _('Site theme changed to {site_theme}'.format(site_theme=preview_site_theme_name))
            )
        else:
            PageLevelMessages.register_error_message(
                request,
                _('Theme {site_theme} does not exist'.format(site_theme=preview_site_theme_name))
            )
    else:
        delete_user_preference(request.user, PREVIEW_SITE_THEME_PREFERENCE_KEY)
        PageLevelMessages.register_success_message(request, _('Site theme reverted to the default'))
示例#8
0
    def test_parental_consent(self, api_client, requesting_username, has_full_access):
        """
        Verifies that under thirteens never return a public profile.
        """
        client = self.login_client(api_client, requesting_username)

        year_of_birth = self._set_user_age_to_10_years(self.user)
        set_user_preference(self.user, ACCOUNT_VISIBILITY_PREF_KEY, ALL_USERS_VISIBILITY)

        # Verify that the default view is still private (except for clients with full access)
        response = self.send_get(client)
        if has_full_access:
            data = response.data
            self.assertEqual(22, len(data))
            self.assertEqual(self.user.username, data["username"])
            self.assertEqual(self.user.first_name + " " + self.user.last_name, data["name"])
            self.assertEqual(self.user.email, data["email"])
            self.assertEqual(year_of_birth, data["year_of_birth"])
            for empty_field in ("country", "level_of_education", "mailing_address", "bio"):
                self.assertIsNone(data[empty_field])
            self.assertEqual("m", data["gender"])
            self.assertEqual("Learn a lot", data["goals"])
            self.assertTrue(data["is_active"])
            self.assertIsNotNone(data["date_joined"])
            self._verify_profile_image_data(data, False)
            self.assertTrue(data["requires_parental_consent"])
            self.assertEqual(PRIVATE_VISIBILITY, data["account_privacy"])
        else:
            self._verify_private_account_response(response, requires_parental_consent=True)

        # Verify that the shared view is still private
        response = self.send_get(client, query_parameters='view=shared')
        self._verify_private_account_response(response, requires_parental_consent=True)
示例#9
0
    def process_request(self, request):
        """
        If a user's UserPreference contains a language preference, use the user's preference.
        Save the current language preference cookie as the user's preferred language.
        """
        cookie_lang = request.COOKIES.get(settings.LANGUAGE_COOKIE, None)
        if cookie_lang:
            if request.user.is_authenticated():
                set_user_preference(request.user, LANGUAGE_KEY, cookie_lang)
            else:
                request._anonymous_user_cookie_lang = cookie_lang

            accept_header = request.META.get(LANGUAGE_HEADER, None)
            if accept_header:
                current_langs = parse_accept_lang_header(accept_header)
                # Promote the cookie_lang over any language currently in the accept header
                current_langs = [(lang, qvalue) for (lang, qvalue) in current_langs if lang != cookie_lang]
                current_langs.insert(0, (cookie_lang, 1))
                accept_header = ",".join("{};q={}".format(lang, qvalue) for (lang, qvalue) in current_langs)
            else:
                accept_header = cookie_lang
            request.META[LANGUAGE_HEADER] = accept_header

            # Allow the new cookie setting to update the language in the user's session
            if LANGUAGE_SESSION_KEY in request.session and request.session[LANGUAGE_SESSION_KEY] != cookie_lang:
                del request.session[LANGUAGE_SESSION_KEY]
示例#10
0
 def set_sharing_preferences(self, user, boolean_value):
     """
     Sets self.user's share settings to boolean_value
     """
     # Note that setting the value to boolean will result in the conversion to the unicode form of the boolean.
     set_user_preference(user, 'share_with_facebook_friends', boolean_value)
     self.assertEqual(get_user_preference(user, 'share_with_facebook_friends'), unicode(boolean_value))
示例#11
0
 def test_render_date_string_time_zone(self, delta, expected_date_string):
     self.setup_course_and_user(
         days_till_start=-10, verification_status="denied", days_till_verification_deadline=delta
     )
     set_user_preference(self.user, "time_zone", "America/Los_Angeles")
     block = VerificationDeadlineDate(self.course, self.user)
     self.assertEqual(block.get_context()["date"], expected_date_string)
示例#12
0
    def process_response(self, request, response):
        # If the user is logged in, check for their language preference
        if getattr(request, 'user', None) and request.user.is_authenticated():
            user_pref = None

            anonymous_cookie_lang = getattr(request, '_anonymous_user_cookie_lang', None)
            if anonymous_cookie_lang:
                user_pref = anonymous_cookie_lang
                set_user_preference(request.user, LANGUAGE_KEY, anonymous_cookie_lang)
            else:
                # Get the user's language preference
                try:
                    user_pref = get_user_preference(request.user, LANGUAGE_KEY)
                except (UserAPIRequestError, UserAPIInternalError):
                    # If we can't find the user preferences, then don't modify the cookie
                    pass

            # If set, set the user_pref in the LANGUAGE_COOKIE
            if user_pref:
                response.set_cookie(
                    settings.LANGUAGE_COOKIE,
                    value=user_pref,
                    domain=settings.SESSION_COOKIE_DOMAIN,
                    max_age=COOKIE_DURATION,
                )
            else:
                response.delete_cookie(
                    settings.LANGUAGE_COOKIE,
                    domain=settings.SESSION_COOKIE_DOMAIN
                )

        return response
 def test_delete_user_lang_preference_not_supported_by_system(self):
     """
     test: user preferred language has been removed from user preferences model if it is not supported by system
     for authenticated users.
     """
     set_user_preference(self.user, LANGUAGE_KEY, 'eo')
     self.middleware.process_request(self.request)
     self.assertEqual(get_user_preference(self.request.user, LANGUAGE_KEY), None)
示例#14
0
文件: test.py 项目: jgrynber/fun-apps
    def setUp(self):
        super(BaseCourseDetail, self).setUp()
        self.init(True, "fun")

        self.user.groups.add(self.backoffice_group)
        set_user_preference(self.user, LANGUAGE_KEY, 'en-en')
        self.client.login(username=self.user.username, password=self.password)
        self.url = reverse('backoffice:course-detail', args=[self.course.id.to_deprecated_string()])
示例#15
0
    def handle_sucessfull_register(self, user_email, lang):
        user = User.objects.get(email=user_email)
        user.is_active = True
        user.save()

        set_user_preference(user, LANGUAGE_KEY, lang)

        ForusProfile.create_for_user(user)
    def test_language_in_session(self):
        # language set in both the user preferences and session,
        # session should get precedence
        self.request.session['django_language'] = 'en'
        set_user_preference(self.user, LANGUAGE_KEY, 'eo')
        self.middleware.process_request(self.request)

        self.assertEquals(self.request.session['django_language'], 'en')
示例#17
0
文件: test.py 项目: openfun/fun-apps
    def setUp(self):
        super(BaseCourseDetail, self).setUp()
        self.init(True, "fun")

        self.user.groups.add(self.backoffice_group)
        set_user_preference(self.user, LANGUAGE_KEY, 'en-en')
        self.client.login(username=self.user.username, password=self.password)
        self.url = reverse('backoffice:course-detail', args=[unicode(self.course.scope_ids.usage_id.course_key)])
示例#18
0
    def test_user_with_locale_claim(self):
        language = "en"
        set_user_preference(self.user, LANGUAGE_KEY, language)
        scopes, claims = self.get_id_token_values("openid profile")

        self.assertIn("profile", scopes)

        locale = claims["locale"]
        self.assertEqual(language, locale)
示例#19
0
文件: tests.py 项目: edx/edx-platform
    def test_user_with_locale_claim(self):
        language = 'en'
        set_user_preference(self.user, LANGUAGE_KEY, language)
        scopes, claims = self.get_id_token_values('openid profile')

        self.assertIn('profile', scopes)

        locale = claims['locale']
        self.assertEqual(language, locale)
示例#20
0
def set_language(request):
    """
    This view is called when the user would like to set a language preference
    """
    lang_pref = request.POST.get('language', None)

    if lang_pref:
        set_user_preference(request.user, LANGUAGE_KEY, lang_pref)
        return HttpResponse('{"success": true}')

    return HttpResponseBadRequest('no language provided')
    def test_language_in_session(self):
        # language set in both the user preferences and session,
        # preference should get precedence. The session will hold the last value,
        # which is probably the user's last preference. Look up the updated preference.

        # Dark lang middleware should run after this middleware, so it can
        # set a session language as an override of the user's preference.
        self.request.session[LANGUAGE_SESSION_KEY] = 'en'
        set_user_preference(self.user, LANGUAGE_KEY, 'eo')
        self.middleware.process_request(self.request)

        self.assertEquals(self.request.session[LANGUAGE_SESSION_KEY], 'eo')
示例#22
0
 def _today_date_helper(self, expected_display_date):
     """
     Helper function to test that today's date block renders correctly
     and displays the correct time, accounting for daylight savings
     """
     self.setup_course_and_user()
     set_user_preference(self.user, "time_zone", "America/Los_Angeles")
     block = TodaysDate(self.course, self.user)
     self.assertTrue(block.is_enabled)
     self.assertEqual(block.date, datetime.now(utc))
     self.assertEqual(block.title, "Today is {date}".format(date=expected_display_date))
     self.assertNotIn("date-summary-date", block.render())
    def setUp(self):
        super(TestInstructorAPIEnrollmentEmailLocalization, self).setUp()

        # Platform language is English, instructor's language is Chinese,
        # student's language is French, so the emails should all be sent in
        # French.
        self.instructor = InstructorFactory(course_key=self.course.id)
        set_user_preference(self.instructor, LANGUAGE_KEY, 'zh-cn')
        self.client.login(username=self.instructor.username, password='******')

        self.student = UserFactory.create()
        set_user_preference(self.student, LANGUAGE_KEY, 'fr')
示例#24
0
def set_language(request):

    auth_user = request.user.is_authenticated()
    lang_code = request.POST.get('language', None)

    request.session[LANGUAGE_SESSION_KEY] = lang_code

    if auth_user:
        set_user_preference(request.user, DARK_LANGUAGE_KEY, lang_code)

    return django_set_language(request)
    # we can return a simple redirect response, but I left this in place just in case !
示例#25
0
 def test_start_date_render_time_zone(self):
     self.setup_course_and_user()
     self.client.login(username='******', password='******')
     set_user_preference(self.user, "time_zone", "America/Los_Angeles")
     url = reverse('info', args=(self.course.id,))
     response = self.client.get(url)
     html_elements = [
         'data-string="in 1 day - {date}"',
         'data-datetime="2015-01-03 00:00:00+00:00"',
         'data-timezone="America/Los_Angeles"'
     ]
     for html in html_elements:
         self.assertContains(response, html)
    def test_get_user_time_zone(self):
        """
        Test to ensure get_user_time_zone() returns the correct time zone
        or UTC if user has not specified time zone.
        """
        # User time zone should be UTC when no time zone has been chosen
        user_tz = get_user_time_zone(self.user)
        self.assertEqual(user_tz, utc)

        # User time zone should change when user specifies time zone
        set_user_preference(self.user, 'time_zone', 'Asia/Tokyo')
        user_tz = get_user_time_zone(self.user)
        self.assertEqual(user_tz, timezone('Asia/Tokyo'))
    def test_preference_cookie_changes_setting(self, lang_cookie, lang_pref_in, mock_set_user_preference):
        self.request.COOKIES[settings.LANGUAGE_COOKIE] = lang_cookie

        if lang_pref_in:
            set_user_preference(self.user, LANGUAGE_KEY, lang_pref_in)
        else:
            delete_user_preference(self.user, LANGUAGE_KEY)

        self.middleware.process_request(self.request)

        if lang_cookie is None:
            self.assertEqual(mock_set_user_preference.mock_calls, [])
        else:
            mock_set_user_preference.assert_called_with(self.user, LANGUAGE_KEY, lang_cookie)
 def test_start_date_render_time_zone(self, url_name):
     with freeze_time('2015-01-02'):
         course = create_course_run()
         user = create_user()
         self.client.login(username=user.username, password=TEST_PASSWORD)
         set_user_preference(user, 'time_zone', 'America/Los_Angeles')
         url = reverse(url_name, args=(course.id,))
         response = self.client.get(url, follow=True)
         html_elements = [
             'data-string="in 1 day - {date}"',
             'data-datetime="2015-01-03 00:00:00+00:00"',
             'data-timezone="America/Los_Angeles"'
         ]
         for html in html_elements:
             self.assertContains(response, html)
示例#29
0
    def _set_preview_language(self, request):
        """
        Sets the preview language for the current user.
        """
        preview_language = request.POST.get(LANGUAGE_INPUT_FIELD, '')
        if not preview_language.strip():
            PageLevelMessages.register_error_message(request, _('Language not provided'))
            return

        set_user_preference(request.user, DARK_LANGUAGE_KEY, preview_language)
        PageLevelMessages.register_success_message(
            request,
            _(u'Language set to {preview_language}').format(
                preview_language=preview_language
            )
        )
示例#30
0
    def test_preview_precedence(self):
        # Regression test; LOC-87
        self.release_languages('ar, es-419')

        # Set user language preference
        set_user_preference(self.user, LANGUAGE_KEY, 'ar')
        # Verify preview-lang takes precedence
        response = self.client.get('{}?preview-lang=eo'.format(self.url))
        self.assert_tag_has_attr(response.content, "html", "lang", 'eo')
        # Hitting another page should keep the dark language set.
        response = self.client.get(reverse('courses'))
        self.assert_tag_has_attr(response.content, "html", "lang", "eo")

        # Clearing language must set language back to preference language
        response = self.client.get('{}?clear-lang'.format(self.url))
        self.assert_tag_has_attr(response.content, "html", "lang", 'ar')
示例#31
0
    def test_parental_consent(self, api_client, requesting_username,
                              has_full_access):
        """
        Verifies that under thirteens never return a public profile.
        """
        client = self.login_client(api_client, requesting_username)

        # Set the user to be ten years old with a public profile
        legacy_profile = UserProfile.objects.get(id=self.user.id)
        current_year = datetime.datetime.now().year
        legacy_profile.year_of_birth = current_year - 10
        legacy_profile.save()
        set_user_preference(self.user, ACCOUNT_VISIBILITY_PREF_KEY,
                            ALL_USERS_VISIBILITY)

        # Verify that the default view is still private (except for clients with full access)
        response = self.send_get(client)
        if has_full_access:
            data = response.data
            self.assertEqual(17, len(data))
            self.assertEqual(self.user.username, data["username"])
            self.assertEqual(self.user.first_name + " " + self.user.last_name,
                             data["name"])
            self.assertEqual(self.user.email, data["email"])
            self.assertEqual(current_year - 10, data["year_of_birth"])
            for empty_field in ("country", "level_of_education",
                                "mailing_address", "bio"):
                self.assertIsNone(data[empty_field])
            self.assertEqual("m", data["gender"])
            self.assertEqual("Learn a lot", data["goals"])
            self.assertTrue(data["is_active"])
            self.assertIsNotNone(data["date_joined"])
            self._verify_profile_image_data(data, False)
            self.assertTrue(data["requires_parental_consent"])
            self.assertEqual(PRIVATE_VISIBILITY, data["account_privacy"])
        else:
            self._verify_private_account_response(
                response,
                requires_parental_consent=True,
                account_privacy=PRIVATE_VISIBILITY)

        # Verify that the shared view is still private
        response = self.send_get(client, query_parameters='view=shared')
        self._verify_private_account_response(
            response,
            requires_parental_consent=True,
            account_privacy=PRIVATE_VISIBILITY)
示例#32
0
    def test_todays_date_timezone(self, url_name):
        with freeze_time('2015-01-02'):
            course = create_course_run()
            user = create_user()
            self.client.login(username=user.username, password=TEST_PASSWORD)
            set_user_preference(user, 'time_zone', 'America/Los_Angeles')
            url = reverse(url_name, args=(course.id, ))
            response = self.client.get(url, follow=True)

            html_elements = [
                '<h3 class="hd hd-6 handouts-header">Upcoming Dates</h3>',
                '<div class="date-summary-container">',
                '<p class="hd hd-6 date localized-datetime"',
                'data-timezone="America/Los_Angeles"'
            ]
            for html in html_elements:
                self.assertContains(response, html)
示例#33
0
    def test_masquerade(self):
        user = UserFactory()
        set_user_preference(user, 'time_zone', 'Asia/Tokyo')
        CourseEnrollment.enroll(user, self.course.id)

        self.switch_to_staff()  # needed for masquerade

        # Sanity check on our normal user
        self.assertEqual(
            self.client.get(self.url).data['dates_widget']['user_timezone'],
            None)

        # Now switch users and confirm we get a different result
        self.update_masquerade(username=user.username)
        self.assertEqual(
            self.client.get(self.url).data['dates_widget']['user_timezone'],
            'Asia/Tokyo')
示例#34
0
    def test_parental_consent(self, api_client, requesting_username,
                              has_full_access):
        """
        Verifies that under thirteens never return a public profile.
        """
        client = self.login_client(api_client, requesting_username)

        year_of_birth = self._set_user_age_to_10_years(self.user)
        set_user_preference(self.user, ACCOUNT_VISIBILITY_PREF_KEY,
                            ALL_USERS_VISIBILITY)

        # Verify that the default view is still private (except for clients with full access)
        response = self.send_get(client)
        if has_full_access:
            data = response.data
            assert 27 == len(data)
            assert self.user.username == data['username']
            assert ((self.user.first_name + ' ') +
                    self.user.last_name) == data['name']
            assert self.user.email == data['email']
            assert self.user.id == data['id']
            assert year_of_birth == data['year_of_birth']
            for empty_field in (
                    "country",
                    "level_of_education",
                    "mailing_address",
                    "bio",
                    "state",
            ):
                assert data[empty_field] is None
            assert 'm' == data['gender']
            assert 'Learn a lot' == data['goals']
            assert data['is_active']
            assert data['date_joined'] is not None
            assert data['last_login'] is not None
            self._verify_profile_image_data(data, False)
            assert data['requires_parental_consent']
            assert PRIVATE_VISIBILITY == data['account_privacy']
        else:
            self._verify_private_account_response(
                response, requires_parental_consent=True)

        # Verify that the shared view is still private
        response = self.send_get(client, query_parameters='view=shared')
        self._verify_private_account_response(response,
                                              requires_parental_consent=True)
示例#35
0
    def test_get_user_timezone_or_last_seen_timezone_or_utc(self):
        # We default to UTC
        course = CourseFactory()
        time_zone = get_user_timezone_or_last_seen_timezone_or_utc(self.user)
        assert time_zone == timezone('UTC')

        # We record the timezone when a user hits the courseware api
        self.client.login(username=self.user.username, password='******')
        self.client.get(
            f'/api/courseware/course/{course.id}?browser_timezone=America/New_York'
        )
        time_zone = get_user_timezone_or_last_seen_timezone_or_utc(self.user)
        assert time_zone == timezone('America/New_York')

        # If a user has their timezone set, then we use that setting
        set_user_preference(self.user, 'time_zone', 'Asia/Tokyo')
        time_zone = get_user_timezone_or_last_seen_timezone_or_utc(self.user)
        assert time_zone == timezone('Asia/Tokyo')
示例#36
0
    def test_lang_preference(self):
        # Regression test; LOC-87
        self.release_languages('ar, es-419')

        # Visit the front page; verify we see site default lang
        response = self.client.get(self.url)
        self.assert_tag_has_attr(response.content, "html", "lang", self.site_lang)

        # Set user language preference
        set_user_preference(self.user, LANGUAGE_KEY, 'ar')
        # and verify we now get an ar response
        response = self.client.get(self.url)
        self.assert_tag_has_attr(response.content, "html", "lang", 'ar')

        # Verify that switching language preference gives the right language
        set_user_preference(self.user, LANGUAGE_KEY, 'es-419')
        response = self.client.get(self.url)
        self.assert_tag_has_attr(response.content, "html", "lang", 'es-419')
示例#37
0
    def test_todays_date_timezone(self):
        self.setup_course_and_user()
        self.client.login(username='******', password='******')
        set_user_preference(self.user, "time_zone", "America/Los_Angeles")
        url = reverse('info', args=(self.course.id,))
        response = self.client.get(url)

        html_elements = [
            '<h4 class="handouts-header">Important Course Dates</h4>',
            '<div class="date-summary-container">',
            '<div class="date-summary date-summary-todays-date">',
            '<h3 class="heading localized-datetime"',
            'data-datetime="2015-01-02 00:00:00+00:00"',
            'data-string="Today is {date}"',
            'data-timezone="America/Los_Angeles"'
        ]
        for html in html_elements:
            self.assertContains(response, html)
示例#38
0
    def process_response(self, request, response):  # lint-amnesty, pylint: disable=missing-function-docstring
        # If the user is logged in, check for their language preference. Also check for real user
        # if current user is a masquerading user,
        user_pref = None
        current_user = None
        if hasattr(request, 'user'):
            current_user = getattr(request.user, 'real_user', request.user)

        if current_user and current_user.is_authenticated:

            # DarkLangMiddleware has already set this cookie
            if DarkLangConfig.current().enabled and get_user_preference(current_user, DARK_LANGUAGE_KEY):
                return response

            anonymous_cookie_lang = getattr(request, '_anonymous_user_cookie_lang', None)
            if anonymous_cookie_lang:
                user_pref = anonymous_cookie_lang
                set_user_preference(current_user, LANGUAGE_KEY, anonymous_cookie_lang)
            else:
                # Get the user's language preference
                try:
                    user_pref = get_user_preference(current_user, LANGUAGE_KEY)
                except (UserAPIRequestError, UserAPIInternalError):
                    # If we can't find the user preferences, then don't modify the cookie
                    pass

            # If set, set the user_pref in the LANGUAGE_COOKIE_NAME
            if user_pref and not is_request_from_mobile_app(request):
                response.set_cookie(
                    settings.LANGUAGE_COOKIE_NAME,
                    value=user_pref,
                    domain=settings.SHARED_COOKIE_DOMAIN,
                    max_age=COOKIE_DURATION,
                    secure=request.is_secure()
                )
            else:
                response.delete_cookie(
                    settings.LANGUAGE_COOKIE_NAME,
                    domain=settings.SHARED_COOKIE_DOMAIN
                )

        return response
示例#39
0
    def test_todays_date_timezone(self, url_name):
        with freeze_time('2015-01-02'):
            self.setup_course_and_user()
            self.client.login(username=self.user.username,
                              password=TEST_PASSWORD)
            set_user_preference(self.user, "time_zone", "America/Los_Angeles")
            url = reverse(url_name, args=(self.course.id, ))
            response = self.client.get(url, follow=True)

            html_elements = [
                '<h3 class="hd hd-6 handouts-header">Important Course Dates</h3>',
                '<div class="date-summary-container">',
                '<div class="date-summary date-summary-todays-date">',
                '<span class="hd hd-6 heading localized-datetime"',
                'data-datetime="2015-01-02 00:00:00+00:00"',
                'data-string="Today is {date}"',
                'data-timezone="America/Los_Angeles"'
            ]
            for html in html_elements:
                self.assertContains(response, html)
示例#40
0
def set_language(request):
    """
    A re-implementation of django_set_language that is suitable of Edraak's edX platform.

    It allows the user to redirect to the marketing site as well as the LMS.

    :param request: a request object for the view.
    :return HttpResponseRedirect: Redirects the user to the next safe URL.
    """

    default_redirect_hosts = (request.get_host(), )

    hosts = getattr(settings, 'SAFE_REDIRECT_HOSTS', default_redirect_hosts)

    safe_url = get_any_safe_url(hosts=hosts,
                                urls=(
                                    request.REQUEST.get('next'),
                                    request.META.get('HTTP_REFERER'),
                                    '/',
                                ))

    response = http.HttpResponseRedirect(safe_url)

    if request.method == 'POST':
        lang_code = request.POST.get('language', None)

        if lang_code and check_for_language(lang_code):

            if request.user.is_authenticated():
                set_user_preference(request.user, DARK_LANGUAGE_KEY, lang_code)

            if hasattr(request, 'session'):
                request.session[LANGUAGE_SESSION_KEY] = lang_code
            else:
                response.set_cookie(settings.LANGUAGE_COOKIE_NAME, lang_code)

    # Prevents accidental refresh: https://en.wikipedia.org/wiki/Post/Redirect/Get
    response.status_code = 303

    return response
示例#41
0
    def _activate_preview_language(self, request):
        """
        If the request has the get parameter ``preview-lang``,
        and that language doesn't appear in ``self.released_langs``,
        then set the session LANGUAGE_SESSION_KEY to that language.
        """
        auth_user = request.user.is_authenticated()
        if 'clear-lang' in request.GET:
            # delete the session language key (if one is set)
            if LANGUAGE_SESSION_KEY in request.session:
                del request.session[LANGUAGE_SESSION_KEY]

            if auth_user:
                # Reset user's dark lang preference to null
                delete_user_preference(request.user, DARK_LANGUAGE_KEY)
                # Get & set user's preferred language
                user_pref = get_user_preference(request.user, LANGUAGE_KEY)
                if user_pref:
                    request.session[LANGUAGE_SESSION_KEY] = user_pref
            return

        # Get the user's preview lang - this is either going to be set from a query
        # param `?preview-lang=xx`, or we may have one already set as a dark lang preference.
        preview_lang = request.GET.get('preview-lang', None)
        if not preview_lang and auth_user:
            # Get the request user's dark lang preference
            preview_lang = get_user_preference(request.user, DARK_LANGUAGE_KEY)

        # User doesn't have a dark lang preference, so just return
        if not preview_lang:
            return

        # Set the session key to the requested preview lang
        request.session[LANGUAGE_SESSION_KEY] = preview_lang

        # Make sure that we set the requested preview lang as the dark lang preference for the
        # user, so that the lang_pref middleware doesn't clobber away the dark lang preview.
        if auth_user:
            set_user_preference(request.user, DARK_LANGUAGE_KEY, preview_lang)
 def setUp(self):
     super().setUp()
     self.user = UserFactory(username="******", email="*****@*****.**")
     self.user.profile.name = "Test Tester"
     set_user_preference(self.user, 'pref-lang', 'en')
     set_user_preference(self.user, 'time_zone', 'US/Pacific')
     set_user_preference(self.user, 'not_white_listed', 'hidden_value')
     self.anon_user = AnonymousUserFactory()
示例#43
0
 def setUp(self):
     super(UserServiceTestCase, self).setUp()  # lint-amnesty, pylint: disable=super-with-arguments
     self.user = UserFactory(username="******", email="*****@*****.**")
     self.user.profile.name = "Test Tester"
     set_user_preference(self.user, 'pref-lang', 'en')
     set_user_preference(self.user, 'time_zone', 'US/Pacific')
     set_user_preference(self.user, 'not_white_listed', 'hidden_value')
     self.anon_user = AnonymousUserFactory()
示例#44
0
    def process_response(self, request, response):
        # If the user is logged in, check for their language preference. Also check for real user
        # if current user is a masquerading user,
        user_pref = None
        current_user = None
        if hasattr(request, 'user'):
            current_user = getattr(request.user, 'real_user', request.user)

        if current_user and current_user.is_authenticated:
            anonymous_cookie_lang = getattr(request,
                                            '_anonymous_user_cookie_lang',
                                            None)
            if anonymous_cookie_lang:
                user_pref = anonymous_cookie_lang
                set_user_preference(current_user, LANGUAGE_KEY,
                                    anonymous_cookie_lang)
            else:
                # Get the user's language preference
                try:
                    user_pref = get_user_preference(current_user, LANGUAGE_KEY)
                except (UserAPIRequestError, UserAPIInternalError):
                    # If we can't find the user preferences, then don't modify the cookie
                    pass

            # If set, set the user_pref in the LANGUAGE_COOKIE
            if user_pref:
                if not is_request_from_mobile_app(request):
                    response.set_cookie(
                        settings.LANGUAGE_COOKIE,
                        value=user_pref,
                        domain=settings.SESSION_COOKIE_DOMAIN,
                        max_age=COOKIE_DURATION,
                    )
            else:
                response.delete_cookie(settings.LANGUAGE_COOKIE,
                                       domain=settings.SESSION_COOKIE_DOMAIN)

        return response
示例#45
0
    def process_request(self, request):
        """
        If a user's UserPreference contains a language preference, use the user's preference.
        Save the current language preference cookie as the user's preferred language.
        """
        cookie_lang = request.COOKIES.get(settings.LANGUAGE_COOKIE, None)
        if cookie_lang:
            if request.user.is_authenticated():
                set_user_preference(request.user, LANGUAGE_KEY, cookie_lang)

            accept_header = request.META.get(LANGUAGE_HEADER, None)
            if accept_header:
                current_langs = parse_accept_lang_header(accept_header)
                # Promote the cookie_lang over any language currently in the accept header
                current_langs = [(lang, qvalue)
                                 for (lang, qvalue) in current_langs
                                 if lang != cookie_lang]
                current_langs.insert(0, (cookie_lang, 1))
                accept_header = ",".join("{};q={}".format(lang, qvalue)
                                         for (lang, qvalue) in current_langs)
            else:
                accept_header = cookie_lang
            request.META[LANGUAGE_HEADER] = accept_header
示例#46
0
    def test_preview_precedence(self):
        # Regression test; LOC-87
        self.release_languages('ar, es-419')

        # Set user language preference
        set_user_preference(self.user, LANGUAGE_KEY, 'ar')
        # Verify preview-lang takes precedence
        self.client.post(self.preview_language_url, {
            'preview_lang': 'eo',
            'set_language': 'set_language'
        })
        response = self.client.get(self.url)

        self.assert_tag_has_attr(response.content, "html", "lang", 'eo')
        # Hitting another page should keep the dark language set.
        response = self.client.get(reverse('courses'))
        self.assert_tag_has_attr(response.content, "html", "lang", "eo")

        # Clearing language must set language back to preference language
        self.client.post(self.preview_language_url, {'reset': 'reset'})
        response = self.client.get(self.url)

        self.assert_tag_has_attr(response.content, "html", "lang", 'ar')
示例#47
0
    def test_custom_visibility_under_age(self, api_client, requesting_username):
        self.create_mock_profile(self.user)
        year_of_birth = self._set_user_age_to_10_years(self.user)

        # set user's custom visibility preferences
        set_user_preference(self.user, ACCOUNT_VISIBILITY_PREF_KEY, CUSTOM_VISIBILITY)
        shared_fields = ("bio", "language_proficiencies")
        for field_name in shared_fields:
            set_user_preference(self.user, "visibility.{}".format(field_name), ALL_USERS_VISIBILITY)

        # make API request
        client = self.login_client(api_client, requesting_username)
        response = self.send_get(client)

        # verify response
        if requesting_username == "different_user":
            self._verify_private_account_response(response, requires_parental_consent=True)
        else:
            self._verify_full_account_response(
                response,
                requires_parental_consent=True,
                year_of_birth=year_of_birth,
            )
示例#48
0
    def test_get_account_private_visibility(self, api_client,
                                            requesting_username,
                                            preference_visibility):
        """
        Test the return from GET based on user visibility setting.
        """
        def verify_fields_visible_to_all_users(response):
            """
            Confirms that private fields are private, and public/shareable fields are public/shareable
            """
            if preference_visibility == PRIVATE_VISIBILITY:
                self._verify_private_account_response(response)
            else:
                self._verify_full_shareable_account_response(
                    response, ALL_USERS_VISIBILITY, badges_enabled=True)

        client = self.login_client(api_client, requesting_username)

        # Update user account visibility setting.
        set_user_preference(self.user, ACCOUNT_VISIBILITY_PREF_KEY,
                            preference_visibility)
        self.create_mock_profile(self.user)
        response = self.send_get(client)

        if requesting_username == "different_user":
            verify_fields_visible_to_all_users(response)
        else:
            self._verify_full_account_response(response)

        # Verify how the view parameter changes the fields that are returned.
        response = self.send_get(client, query_parameters='view=shared')
        verify_fields_visible_to_all_users(response)

        response = self.send_get(
            client,
            query_parameters='view=shared&email={}'.format(self.user.email))
        verify_fields_visible_to_all_users(response)
示例#49
0
    def _set_preview_language(self, request, context):
        """
        Set the Preview language

        Arguments:
            request (Request): The incoming Django Request
            context dict: The basic context for the Response

        Returns:
            HttpResponse: View containing the form for setting the preview lang with the status
                included in the context
        """
        message = None
        show_refresh_message = False

        preview_lang = request.POST.get(LANGUAGE_INPUT_FIELD, '')
        if not preview_lang.strip():
            message = _('Language code not provided')
        else:
            # Set the session key to the requested preview lang
            request.session[LANGUAGE_SESSION_KEY] = preview_lang

            # Make sure that we set the requested preview lang as the dark lang preference for the
            # user, so that the lang_pref middleware doesn't clobber away the dark lang preview.
            auth_user = request.user
            if auth_user:
                set_user_preference(request.user, DARK_LANGUAGE_KEY,
                                    preview_lang)

            message = _(
                'Language set to language code: {preview_language_code}'
            ).format(preview_language_code=preview_lang)
            show_refresh_message = True
        context.update({'form_submit_message': message})
        context.update({'success': show_refresh_message})
        response = render_to_response(self.template_name, context)
        return response
示例#50
0
    def test_custom_visibility_over_age(self, api_client, requesting_username):
        self.create_mock_profile(self.user)
        # set user's custom visibility preferences
        set_user_preference(self.user, ACCOUNT_VISIBILITY_PREF_KEY,
                            CUSTOM_VISIBILITY)
        shared_fields = ("bio", "language_proficiencies", "name")
        for field_name in shared_fields:
            set_user_preference(self.user, f"visibility.{field_name}",
                                ALL_USERS_VISIBILITY)

        # make API request
        client = self.login_client(api_client, requesting_username)
        response = self.send_get(client)

        # verify response
        if requesting_username == "different_user":
            data = response.data
            assert 8 == len(data)

            # public fields
            assert self.user.username == data['username']
            assert self.user.id == data['id']
            assert self.user.email == data['email']
            assert UserPreference.get_value(
                self.user, 'account_privacy') == data['account_privacy']
            self._verify_profile_image_data(data, has_profile_image=True)

            # custom shared fields
            assert TEST_BIO_VALUE == data['bio']
            assert [{
                'code': TEST_LANGUAGE_PROFICIENCY_CODE
            }] == data['language_proficiencies']
            assert ((self.user.first_name + ' ') +
                    self.user.last_name) == data['name']
        else:
            self._verify_full_account_response(response)
示例#51
0
    def test_masquerading_with_language_preference(self):
        """
        Tests that masquerading as a specific user for the course does not update preference language
        for the staff.

        Login as a staff user and set user's language preference to english and visit the courseware page.
        Set masquerade to view same page as a specific student having different language preference and
        revisit the courseware page.
        """
        english_language_code = 'en'
        set_user_preference(self.test_user, preference_key=LANGUAGE_KEY, preference_value=english_language_code)
        self.login_staff()

        # Reload the page and check we have expected language preference in system and in cookies.
        self.get_courseware_page()
        self.assertExpectedLanguageInPreference(self.test_user, english_language_code)

        # Set student language preference and set masquerade to view same page the student.
        set_user_preference(self.student_user, preference_key=LANGUAGE_KEY, preference_value='es-419')
        self.update_masquerade(role='student', username=self.student_user.username)

        # Reload the page and check we have expected language preference in system and in cookies.
        self.get_courseware_page()
        self.assertExpectedLanguageInPreference(self.test_user, english_language_code)
 def test_no_timezone_preference(self):
     set_user_preference(self.user, 'pref-lang', 'en')
     context = user_timezone_locale_prefs(self.request)
     assert context['user_timezone'] is None
     assert context['user_language'] is not None
     assert context['user_language'] == 'en'
 def test_language_in_user_prefs(self):
     # language set in the user preferences and not the session
     set_user_preference(self.user, LANGUAGE_KEY, 'eo')
     self.middleware.process_request(self.request)
     self.assertEquals(self.request.session[LANGUAGE_SESSION_KEY], 'eo')
示例#54
0
def enable_notifications(step_):
    user = User.objects.get(username=USERNAME)
    set_user_preference(user, NOTIFICATION_PREF_KEY, UNSUB_TOKEN)
示例#55
0
def create_edxapp_user(*args, **kwargs):
    """
    Creates a user on the open edx django site using calls to
    functions defined in the edx-platform codebase

    Example call:

    data = {
        'email': "*****@*****.**",
        'username': "******",
        'password': "******",
        'fullname': "Full Name",
        'activate': True,
        'site': request.site,
        'language_preference': 'es-419',
    }
    user = create_edxapp_user(**data)

    """
    errors = []

    email = kwargs.pop("email")
    username = kwargs.pop("username")
    conflicts = check_edxapp_account_conflicts(email=email, username=username)
    if conflicts:
        return None, [
            "Fatal: account collition with the provided: {}".format(
                ", ".join(conflicts))
        ]

    data = {
        'username': username,
        'email': email,
        'password': kwargs.pop("password"),
        'name': kwargs.pop("fullname"),
    }
    # Go ahead and create the new user
    with transaction.atomic():
        # In theory is possible to extend the registration form with a custom app
        # An example form app for this can be found at http://github.com/open-craft/custom-form-app
        # form = get_registration_extension_form(data=params)
        # if not form:
        form = AccountCreationForm(
            data=data,
            tos_required=False,
            # TODO: we need to support the extra profile fields as defined in the django.settings
            # extra_fields=extra_fields,
            # extended_profile_fields=extended_profile_fields,
            # enforce_password_policy=enforce_password_policy,
        )
        (user, profile, registration) = do_create_account(form)  # pylint: disable=unused-variable

    site = kwargs.pop("site", False)
    if site:
        create_or_set_user_attribute_created_on_site(user, site)
    else:
        errors.append("The user was not assigned to any site")

    try:
        create_comments_service_user(user)
    except Exception:  # pylint: disable=broad-except
        errors.append("No comments_service_user was created")

    # TODO: link account with third party auth

    lang_pref = kwargs.pop("language_preference", False)
    if lang_pref:
        try:
            preferences_api.set_user_preference(user, LANGUAGE_KEY, lang_pref)
        except Exception:  # pylint: disable=broad-except
            errors.append(
                "Could not set lang preference '{} for user '{}'".format(
                    lang_pref,
                    user.username,
                ))

    if kwargs.pop("activate_user", False):
        user.is_active = True
        user.save()

    # TODO: run conditional email sequence

    return user, errors
示例#56
0
 def test_no_timezone_preference(self):
     set_user_preference(self.user, 'pref-lang', 'en')
     context = user_timezone_locale_prefs(self.request)
     self.assertIsNone(context['user_timezone'])
     self.assertIsNotNone(context['user_language'])
     self.assertEqual(context['user_language'], 'en')
示例#57
0
 def test_no_language_preference(self):
     set_user_preference(self.user, 'time_zone', 'Asia/Tokyo')
     context = user_timezone_locale_prefs(self.request)
     self.assertIsNone(context['user_language'])
     self.assertIsNotNone(context['user_timezone'])
     self.assertEqual(context['user_timezone'], 'Asia/Tokyo')
 def test_no_language_preference(self):
     set_user_preference(self.user, 'time_zone', 'Asia/Tokyo')
     context = user_timezone_locale_prefs(self.request)
     assert context['user_language'] is None
     assert context['user_timezone'] is not None
     assert context['user_timezone'] == 'Asia/Tokyo'
示例#59
0
def create_account_with_params(request, params):
    """
    Given a request and a dict of parameters (which may or may not have come
    from the request), create an account for the requesting user, including
    creating a comments service user object and sending an activation email.
    This also takes external/third-party auth into account, updates that as
    necessary, and authenticates the user for the request's session.

    Does not return anything.

    Raises AccountValidationError if an account with the username or email
    specified by params already exists, or ValidationError if any of the given
    parameters is invalid for any other reason.

    Issues with this code:
    * It is non-transactional except where explicitly wrapped in atomic to
      alleviate deadlocks and improve performance. This means failures at
      different places in registration can leave users in inconsistent
      states.
    * Third-party auth passwords are not verified. There is a comment that
      they are unused, but it would be helpful to have a sanity check that
      they are sane.
    * The user-facing text is rather unfriendly (e.g. "Username must be a
      minimum of two characters long" rather than "Please use a username of
      at least two characters").
    * Duplicate email raises a ValidationError (rather than the expected
      AccountValidationError). Duplicate username returns an inconsistent
      user message (i.e. "An account with the Public Username '{username}'
      already exists." rather than "It looks like {username} belongs to an
      existing account. Try again with a different username.") The two checks
      occur at different places in the code; as a result, registering with
      both a duplicate username and email raises only a ValidationError for
      email only.
    """
    # Copy params so we can modify it; we can't just do dict(params) because if
    # params is request.POST, that results in a dict containing lists of values
    params = dict(params.items())

    # allow to define custom set of required/optional/hidden fields via configuration
    extra_fields = configuration_helpers.get_value(
        'REGISTRATION_EXTRA_FIELDS',
        getattr(settings, 'REGISTRATION_EXTRA_FIELDS', {})
    )
    # registration via third party (Google, Facebook) using mobile application
    # doesn't use social auth pipeline (no redirect uri(s) etc involved).
    # In this case all related info (required for account linking)
    # is sent in params.
    # `third_party_auth_credentials_in_api` essentially means 'request
    # is made from mobile application'
    third_party_auth_credentials_in_api = 'provider' in params
    is_third_party_auth_enabled = third_party_auth.is_enabled()

    if is_third_party_auth_enabled and (pipeline.running(request) or third_party_auth_credentials_in_api):
        params["password"] = generate_password()

    # in case user is registering via third party (Google, Facebook) and pipeline has expired, show appropriate
    # error message
    if is_third_party_auth_enabled and ('social_auth_provider' in params and not pipeline.running(request)):
        raise ValidationError(
            {'session_expired': [
                _(u"Registration using {provider} has timed out.").format(
                    provider=params.get('social_auth_provider'))
            ]}
        )

    do_external_auth, eamap = pre_account_creation_external_auth(request, params)

    extended_profile_fields = configuration_helpers.get_value('extended_profile_fields', [])
    # Can't have terms of service for certain SHIB users, like at Stanford
    registration_fields = getattr(settings, 'REGISTRATION_EXTRA_FIELDS', {})
    tos_required = (
        registration_fields.get('terms_of_service') != 'hidden' or
        registration_fields.get('honor_code') != 'hidden'
    ) and (
        not settings.FEATURES.get("AUTH_USE_SHIB") or
        not settings.FEATURES.get("SHIB_DISABLE_TOS") or
        not do_external_auth or
        not eamap.external_domain.startswith(settings.SHIBBOLETH_DOMAIN_PREFIX)
    )

    form = AccountCreationForm(
        data=params,
        extra_fields=extra_fields,
        extended_profile_fields=extended_profile_fields,
        do_third_party_auth=do_external_auth,
        tos_required=tos_required,
    )
    custom_form = get_registration_extension_form(data=params)

    # Perform operations within a transaction that are critical to account creation
    with outer_atomic(read_committed=True):
        # first, create the account
        (user, profile, registration) = do_create_account(form, custom_form)

        third_party_provider, running_pipeline = _link_user_to_third_party_provider(
            is_third_party_auth_enabled, third_party_auth_credentials_in_api, user, request, params,
        )

        new_user = authenticate_new_user(request, user.username, params['password'])
        django_login(request, new_user)
        request.session.set_expiry(0)

        post_account_creation_external_auth(do_external_auth, eamap, new_user)

    # Check if system is configured to skip activation email for the current user.
    skip_email = _skip_activation_email(
        user, do_external_auth, running_pipeline, third_party_provider,
    )

    if skip_email:
        registration.activate()
    else:
        compose_and_send_activation_email(user, profile, registration)

    # Perform operations that are non-critical parts of account creation
    create_or_set_user_attribute_created_on_site(user, request.site)

    preferences_api.set_user_preference(user, LANGUAGE_KEY, get_language())

    if settings.FEATURES.get('ENABLE_DISCUSSION_EMAIL_DIGEST'):
        try:
            enable_notifications(user)
        except Exception:  # pylint: disable=broad-except
            log.exception(u"Enable discussion notifications failed for user {id}.".format(id=user.id))

    _track_user_registration(user, profile, params, third_party_provider)

    # Announce registration
    REGISTER_USER.send(sender=None, user=user, registration=registration)

    create_comments_service_user(user)

    try:
        _record_registration_attributions(request, new_user)
    # Don't prevent a user from registering due to attribution errors.
    except Exception:   # pylint: disable=broad-except
        log.exception('Error while attributing cookies to user registration.')

    # TODO: there is no error checking here to see that the user actually logged in successfully,
    # and is not yet an active user.
    if new_user is not None:
        AUDIT_LOG.info(u"Login success on new account creation - {0}".format(new_user.username))

    return new_user
示例#60
0
def create_account_with_params(request, params):  # pylint: disable=too-many-statements
    """
    Given a request and a dict of parameters (which may or may not have come
    from the request), create an account for the requesting user, including
    creating a comments service user object and sending an activation email.
    This also takes external/third-party auth into account, updates that as
    necessary, and authenticates the user for the request's session.

    Does not return anything.

    Raises AccountValidationError if an account with the username or email
    specified by params already exists, or ValidationError if any of the given
    parameters is invalid for any other reason.

    Issues with this code:
    * It is non-transactional except where explicitly wrapped in atomic to
      alleviate deadlocks and improve performance. This means failures at
      different places in registration can leave users in inconsistent
      states.
    * Third-party auth passwords are not verified. There is a comment that
      they are unused, but it would be helpful to have a sanity check that
      they are sane.
    * The user-facing text is rather unfriendly (e.g. "Username must be a
      minimum of two characters long" rather than "Please use a username of
      at least two characters").
    * Duplicate email raises a ValidationError (rather than the expected
      AccountValidationError). Duplicate username returns an inconsistent
      user message (i.e. "An account with the Public Username '{username}'
      already exists." rather than "It looks like {username} belongs to an
      existing account. Try again with a different username.") The two checks
      occur at different places in the code; as a result, registering with
      both a duplicate username and email raises only a ValidationError for
      email only.
    """
    # Copy params so we can modify it; we can't just do dict(params) because if
    # params is request.POST, that results in a dict containing lists of values
    params = dict(list(params.items()))

    # allow to define custom set of required/optional/hidden fields via configuration
    extra_fields = configuration_helpers.get_value(
        'REGISTRATION_EXTRA_FIELDS',
        getattr(settings, 'REGISTRATION_EXTRA_FIELDS', {}))
    if is_registration_api_v1(request):
        if 'confirm_email' in extra_fields:
            del extra_fields['confirm_email']

    if settings.ENABLE_COPPA_COMPLIANCE and 'year_of_birth' in params:
        params['year_of_birth'] = ''

    # registration via third party (Google, Facebook) using mobile application
    # doesn't use social auth pipeline (no redirect uri(s) etc involved).
    # In this case all related info (required for account linking)
    # is sent in params.
    # `third_party_auth_credentials_in_api` essentially means 'request
    # is made from mobile application'
    third_party_auth_credentials_in_api = 'provider' in params
    is_third_party_auth_enabled = third_party_auth.is_enabled()

    if is_third_party_auth_enabled and (pipeline.running(request) or
                                        third_party_auth_credentials_in_api):
        params["password"] = generate_password()

    # in case user is registering via third party (Google, Facebook) and pipeline has expired, show appropriate
    # error message
    if is_third_party_auth_enabled and ('social_auth_provider' in params
                                        and not pipeline.running(request)):
        raise ValidationError({
            'session_expired': [
                _("Registration using {provider} has timed out.").format(
                    provider=params.get('social_auth_provider'))
            ],
            'error_code':
            'tpa-session-expired',
        })

    if is_third_party_auth_enabled:
        set_custom_attribute('register_user_tpa', pipeline.running(request))
    extended_profile_fields = configuration_helpers.get_value(
        'extended_profile_fields', [])
    # Can't have terms of service for certain SHIB users, like at Stanford
    registration_fields = getattr(settings, 'REGISTRATION_EXTRA_FIELDS', {})
    tos_required = (registration_fields.get('terms_of_service') != 'hidden'
                    or registration_fields.get('honor_code') != 'hidden')

    form = AccountCreationForm(
        data=params,
        extra_fields=extra_fields,
        extended_profile_fields=extended_profile_fields,
        do_third_party_auth=False,
        tos_required=tos_required,
    )
    custom_form = get_registration_extension_form(data=params)

    # Perform operations within a transaction that are critical to account creation
    with outer_atomic():
        # first, create the account
        (user, profile, registration) = do_create_account(form, custom_form)

        third_party_provider, running_pipeline = _link_user_to_third_party_provider(
            is_third_party_auth_enabled,
            third_party_auth_credentials_in_api,
            user,
            request,
            params,
        )

        new_user = authenticate_new_user(request, user.username,
                                         form.cleaned_data['password'])
        django_login(request, new_user)
        request.session.set_expiry(0)

    # Sites using multiple languages need to record the language used during registration.
    # If not, compose_and_send_activation_email will be sent in site's default language only.
    create_or_set_user_attribute_created_on_site(user, request.site)

    # Only add a default user preference if user does not already has one.
    if not preferences_api.has_user_preference(user, LANGUAGE_KEY):
        preferences_api.set_user_preference(user, LANGUAGE_KEY, get_language())

    # Check if system is configured to skip activation email for the current user.
    skip_email = _skip_activation_email(
        user,
        running_pipeline,
        third_party_provider,
    )

    if skip_email:
        registration.activate()
    else:
        redirect_to, root_url = get_next_url_for_login_page(request,
                                                            include_host=True)
        redirect_url = get_redirect_url_with_host(root_url, redirect_to)
        compose_and_send_activation_email(user, profile, registration,
                                          redirect_url)

    if settings.FEATURES.get('ENABLE_DISCUSSION_EMAIL_DIGEST'):
        try:
            enable_notifications(user)
        except Exception:  # pylint: disable=broad-except
            log.exception(
                f"Enable discussion notifications failed for user {user.id}.")

    _track_user_registration(user, profile, params, third_party_provider,
                             registration)

    # Announce registration
    REGISTER_USER.send(sender=None, user=user, registration=registration)

    # .. event_implemented_name: STUDENT_REGISTRATION_COMPLETED
    STUDENT_REGISTRATION_COMPLETED.send_event(user=UserData(
        pii=UserPersonalData(
            username=user.username,
            email=user.email,
            name=user.profile.name,
        ),
        id=user.id,
        is_active=user.is_active,
    ), )

    create_comments_service_user(user)

    try:
        _record_registration_attributions(request, new_user)
        _record_marketing_emails_opt_in_attribute(
            params.get('marketing_emails_opt_in'), new_user)
    # Don't prevent a user from registering due to attribution errors.
    except Exception:  # pylint: disable=broad-except
        log.exception('Error while attributing cookies to user registration.')

    # TODO: there is no error checking here to see that the user actually logged in successfully,
    # and is not yet an active user.
    is_new_user(form.cleaned_data['password'], new_user)
    return new_user