diff --git a/common/djangoapps/student/views.py b/common/djangoapps/student/views.py
index aae467104b08..d64643ced580 100644
--- a/common/djangoapps/student/views.py
+++ b/common/djangoapps/student/views.py
@@ -1536,10 +1536,13 @@ def login_user(request, error=""): # pylint: disable=too-many-statements,unused
try:
user = User.objects.get(email=email)
except User.DoesNotExist:
- if settings.FEATURES['SQUELCH_PII_IN_LOGS']:
- AUDIT_LOG.warning(u"Login failed - Unknown user email")
- else:
- AUDIT_LOG.warning(u"Login failed - Unknown user email: {0}".format(email))
+ try:
+ user = User.objects.get(username=email)
+ except:
+ if settings.FEATURES['SQUELCH_PII_IN_LOGS']:
+ AUDIT_LOG.warning(u"Login failed - Unknown user email or username")
+ else:
+ AUDIT_LOG.warning(u"Login failed - Unknown user email or username: {0}".format(email))
# check if the user has a linked shibboleth account, if so, redirect the user to shib-login
# This behavior is pretty much like what gmail does for shibboleth. Try entering some @stanford.edu
diff --git a/lms/static/js/student_account/views/FormView.js b/lms/static/js/student_account/views/FormView.js
index 53d8d5e33bfe..ccf8ec4ca76f 100644
--- a/lms/static/js/student_account/views/FormView.js
+++ b/lms/static/js/student_account/views/FormView.js
@@ -157,6 +157,7 @@
$el.val($el.val().trim());
}
+<<<<<<< HEAD
if (key) {
validation = this.validate(elements[i]);
if (validation.isValid) {
@@ -167,6 +168,24 @@
errors.push(validation.message);
$el.addClass('error');
$label.addClass('error');
+=======
+ if (key) {
+<<<<<<< HEAD
+ validation = this.validate(elements[i]);
+ if (validation.isValid) {
+=======
+ test = this.validate(elements[i]);
+ if (test.isValid || $el.attr('id') == 'login-email') {
+>>>>>>> Login with username (#420)
+ obj[key] = $el.attr('type') === 'checkbox' ? $el.is(':checked') : $el.val();
+ $el.removeClass('error');
+ $label.removeClass('error');
+ } else {
+ errors.push(validation.message);
+ $el.addClass('error');
+ $label.addClass('error');
+ }
+>>>>>>> Login with username (#420)
}
}
}
diff --git a/lms/templates/login.html b/lms/templates/login.html
index bd8060685f41..1c0b76827d4b 100644
--- a/lms/templates/login.html
+++ b/lms/templates/login.html
@@ -178,8 +178,8 @@
${_('Required Information')}
-
-
+
+
${_("This is the e-mail address you used to register with {platform}").format(platform=platform_name)}
diff --git a/openedx/core/djangoapps/user_api/views.py b/openedx/core/djangoapps/user_api/views.py
index faaee595e4dd..3bafc3e35863 100644
--- a/openedx/core/djangoapps/user_api/views.py
+++ b/openedx/core/djangoapps/user_api/views.py
@@ -44,7 +44,78 @@ class LoginSessionView(APIView):
@method_decorator(ensure_csrf_cookie)
def get(self, request):
+<<<<<<< HEAD
return HttpResponse(get_login_session_form(request).to_json(), content_type="application/json")
+=======
+<<<<<<< HEAD
+ return HttpResponse(get_login_session_form().to_json(), content_type="application/json")
+=======
+ """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"))
+
+ # Translators: This label appears above a field on the login form
+ # meant to hold the user's email address.
+ email_label = "%s %s %s" % (_(u"Username"), _(u"or"), _(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 = "%s %s %s" % (_(u"username"), _(u"or"), _(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 = _("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": EMAIL_MIN_LENGTH,
+ "max_length": 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={
+ "min_length": PASSWORD_MIN_LENGTH,
+ "max_length": PASSWORD_MAX_LENGTH,
+ }
+ )
+
+ form_desc.add_field(
+ "remember",
+ field_type="checkbox",
+ label=_("Remember me"),
+ default=False,
+ required=False,
+ )
+
+ return HttpResponse(form_desc.to_json(), content_type="application/json")
+>>>>>>> Login with username (#420)
+>>>>>>> Login with username (#420)
@method_decorator(require_post_params(["email", "password"]))
@method_decorator(csrf_protect)