Merge pull request #22348 from edx/diana/move-get-login-session-form

Move get_login_session_form to user_authn.
This commit is contained in:
Diana Huang
2019-11-19 13:28:40 -05:00
committed by GitHub
6 changed files with 102 additions and 130 deletions

View File

@@ -1,117 +0,0 @@
"""
User Apis.
"""
from __future__ import absolute_import
import copy
import crum
import six
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
from django.urls import reverse
from django.utils.translation import ugettext as _
from django_countries import countries
import third_party_auth
from edxmako.shortcuts import marketing_link
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
from openedx.core.djangoapps.user_api import accounts
from openedx.core.djangoapps.user_api.helpers import FormDescription
from openedx.core.djangolib.markup import HTML, Text
from openedx.features.enterprise_support.api import enterprise_customer_for_request
from student.models import UserProfile
from util.password_policy_validators import (
DEFAULT_MAX_PASSWORD_LENGTH,
password_validators_instruction_texts,
password_validators_restrictions
)
def get_login_session_form(request):
"""Return a description of the login form.
This decouples clients from the API definition:
if the API decides to modify the form, clients won't need
to be updated.
See `user_api.helpers.FormDescription` for examples
of the JSON-encoded form description.
Returns:
HttpResponse
"""
form_desc = FormDescription("post", reverse("user_api_login_session"))
_apply_third_party_auth_overrides(request, form_desc)
# Translators: This label appears above a field on the login form
# meant to hold the user's email address.
email_label = _(u"Email")
# Translators: This example email address is used as a placeholder in
# a field on the login form meant to hold the user's email address.
email_placeholder = _(u"username@domain.com")
# Translators: These instructions appear on the login form, immediately
# below a field meant to hold the user's email address.
email_instructions = _(u"The email address you used to register with {platform_name}").format(
platform_name=configuration_helpers.get_value('PLATFORM_NAME', settings.PLATFORM_NAME)
)
form_desc.add_field(
"email",
field_type="email",
label=email_label,
placeholder=email_placeholder,
instructions=email_instructions,
restrictions={
"min_length": accounts.EMAIL_MIN_LENGTH,
"max_length": accounts.EMAIL_MAX_LENGTH,
}
)
# Translators: This label appears above a field on the login form
# meant to hold the user's password.
password_label = _(u"Password")
form_desc.add_field(
"password",
label=password_label,
field_type="password",
restrictions={'max_length': DEFAULT_MAX_PASSWORD_LENGTH}
)
return form_desc
def _apply_third_party_auth_overrides(request, form_desc):
"""Modify the login form if the user has authenticated with a third-party provider.
If a user has successfully authenticated with a third-party provider,
and an email is associated with it then we fill in the email field with readonly property.
Arguments:
request (HttpRequest): The request for the registration form, used
to determine if the user has successfully authenticated
with a third-party provider.
form_desc (FormDescription): The registration form description
"""
if third_party_auth.is_enabled():
running_pipeline = third_party_auth.pipeline.get(request)
if running_pipeline:
current_provider = third_party_auth.provider.Registry.get_from_pipeline(running_pipeline)
if current_provider and enterprise_customer_for_request(request):
pipeline_kwargs = running_pipeline.get('kwargs')
# Details about the user sent back from the provider.
details = pipeline_kwargs.get('details')
email = details.get('email', '')
# override the email field.
form_desc.override_field_properties(
"email",
default=email,
restrictions={"readonly": "readonly"} if email else {
"min_length": accounts.EMAIL_MIN_LENGTH,
"max_length": accounts.EMAIL_MAX_LENGTH,
}
)

View File

@@ -23,9 +23,6 @@ from six import text_type
from openedx.core.djangoapps.django_comment_common.models import Role
from openedx.core.djangoapps.user_api import accounts
from openedx.core.djangoapps.user_api.accounts.api import check_account_exists
from openedx.core.djangoapps.user_api.api import (
get_login_session_form,
)
from openedx.core.lib.api.view_utils import require_post_params
from openedx.core.djangoapps.user_api.models import UserPreference
from openedx.core.djangoapps.user_api.preferences.api import get_country_time_zones, update_email_opt_in

View File

@@ -28,7 +28,7 @@ from rest_framework.views import APIView
from edxmako.shortcuts import render_to_response
from openedx.core.djangoapps.password_policy import compliance as password_policy_compliance
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
from openedx.core.djangoapps.user_api.api import get_login_session_form
from openedx.core.djangoapps.user_authn.views.login_form import get_login_session_form
from openedx.core.djangoapps.user_authn.cookies import refresh_jwt_cookies, set_logged_in_cookies
from openedx.core.djangoapps.user_authn.exceptions import AuthFailedError
from openedx.core.djangoapps.util.user_messages import PageLevelMessages

View File

@@ -7,9 +7,12 @@ import logging
import six
import six.moves.urllib.parse # pylint: disable=import-error
import third_party_auth
from django.conf import settings
from django.contrib import messages
from django.shortcuts import redirect
from django.urls import reverse
from django.utils.translation import ugettext as _
from django.views.decorators.csrf import ensure_csrf_cookie
from django.views.decorators.http import require_http_methods
@@ -17,13 +20,12 @@ from django.views.decorators.http import require_http_methods
import third_party_auth
from edxmako.shortcuts import render_to_response
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
from openedx.core.djangoapps.user_api import accounts
from openedx.core.djangoapps.user_api.accounts.utils import (
is_secondary_email_feature_enabled,
is_multiple_user_enterprises_feature_enabled
)
from openedx.core.djangoapps.user_api.api import (
get_login_session_form,
)
from openedx.core.djangoapps.user_api.helpers import FormDescription
from openedx.core.djangoapps.user_authn.cookies import are_logged_in_cookies_set
from openedx.core.djangoapps.user_authn.views.registration_form import RegistrationFormFactory
from openedx.core.djangoapps.user_authn.views.password_reset import get_password_reset_form
@@ -36,9 +38,102 @@ from student.helpers import get_next_url_for_login_page
from third_party_auth import pipeline
from third_party_auth.decorators import xframe_allow_whitelisted
from util.password_policy_validators import (
DEFAULT_MAX_PASSWORD_LENGTH,
)
log = logging.getLogger(__name__)
def _apply_third_party_auth_overrides(request, form_desc):
"""Modify the login form if the user has authenticated with a third-party provider.
If a user has successfully authenticated with a third-party provider,
and an email is associated with it then we fill in the email field with readonly property.
Arguments:
request (HttpRequest): The request for the registration form, used
to determine if the user has successfully authenticated
with a third-party provider.
form_desc (FormDescription): The registration form description
"""
if third_party_auth.is_enabled():
running_pipeline = third_party_auth.pipeline.get(request)
if running_pipeline:
current_provider = third_party_auth.provider.Registry.get_from_pipeline(running_pipeline)
if current_provider and enterprise_customer_for_request(request):
pipeline_kwargs = running_pipeline.get('kwargs')
# Details about the user sent back from the provider.
details = pipeline_kwargs.get('details')
email = details.get('email', '')
# override the email field.
form_desc.override_field_properties(
"email",
default=email,
restrictions={"readonly": "readonly"} if email else {
"min_length": accounts.EMAIL_MIN_LENGTH,
"max_length": accounts.EMAIL_MAX_LENGTH,
}
)
def get_login_session_form(request):
"""Return a description of the login form.
This decouples clients from the API definition:
if the API decides to modify the form, clients won't need
to be updated.
See `user_api.helpers.FormDescription` for examples
of the JSON-encoded form description.
Returns:
HttpResponse
"""
form_desc = FormDescription("post", reverse("user_api_login_session"))
_apply_third_party_auth_overrides(request, form_desc)
# Translators: This label appears above a field on the login form
# meant to hold the user's email address.
email_label = _(u"Email")
# Translators: This example email address is used as a placeholder in
# a field on the login form meant to hold the user's email address.
email_placeholder = _(u"username@domain.com")
# Translators: These instructions appear on the login form, immediately
# below a field meant to hold the user's email address.
email_instructions = _(u"The email address you used to register with {platform_name}").format(
platform_name=configuration_helpers.get_value('PLATFORM_NAME', settings.PLATFORM_NAME)
)
form_desc.add_field(
"email",
field_type="email",
label=email_label,
placeholder=email_placeholder,
instructions=email_instructions,
restrictions={
"min_length": accounts.EMAIL_MIN_LENGTH,
"max_length": accounts.EMAIL_MAX_LENGTH,
}
)
# Translators: This label appears above a field on the login form
# meant to hold the user's password.
password_label = _(u"Password")
form_desc.add_field(
"password",
label=password_label,
field_type="password",
restrictions={'max_length': DEFAULT_MAX_PASSWORD_LENGTH}
)
return form_desc
@require_http_methods(['GET'])
@ensure_csrf_cookie
@xframe_allow_whitelisted

View File

@@ -585,7 +585,7 @@ class RegistrationViewTest(ThirdPartyAuthTestMixin, UserAPITestCase):
provider = self.configure_google_provider(enabled=True)
with simulate_running_pipeline(
"openedx.core.djangoapps.user_api.api.third_party_auth.pipeline", "google-oauth2",
"openedx.core.djangoapps.user_authn.views.login_form.third_party_auth.pipeline", "google-oauth2",
email="bob@example.com",
fullname="Bob",
username=input_username,

View File

@@ -413,7 +413,6 @@ class LoginAndRegistrationTest(ThirdPartyAuthTestMixin, UrlResetMixin, ModuleSto
self._assert_third_party_auth_data(response, None, None, [], None)
@mock.patch('openedx.core.djangoapps.user_authn.views.login_form.enterprise_customer_for_request')
@mock.patch('openedx.core.djangoapps.user_api.api.enterprise_customer_for_request')
@ddt.data(
("signin_user", None, None, None, False),
("register_user", None, None, None, False),
@@ -443,8 +442,7 @@ class LoginAndRegistrationTest(ThirdPartyAuthTestMixin, UrlResetMixin, ModuleSto
current_provider,
expected_enterprise_customer_mock_attrs,
add_user_details,
enterprise_customer_mock_1,
enterprise_customer_mock_2
enterprise_customer_mock,
):
params = [
('course_id', 'course-v1:Org+Course+Run'),
@@ -468,8 +466,7 @@ class LoginAndRegistrationTest(ThirdPartyAuthTestMixin, UrlResetMixin, ModuleSto
email = None
if add_user_details:
email = 'test@test.com'
enterprise_customer_mock_1.return_value = expected_ec
enterprise_customer_mock_2.return_value = expected_ec
enterprise_customer_mock.return_value = expected_ec
# Simulate a running pipeline
if current_backend is not None: