{% block content %}
<div class="row justify-content-center my-5">
<div class="col col-md-4">
- <div class="card mb-5">
+ <div class="card {% if incorrect %}border-danger{% end %} mb-5">
<div class="card-body">
<h5 class="card-title text-center mb-4">{{ _("Log In") }}</h5>
+ {% if incorrect %}
+ <h6 class="card-subtitle mb-4 text-danger text-center">
+ {{ _("You entered an invalid username or password") }}
+ </h6>
+ {% end %}
+
<form action="" method="POST">
{% raw xsrf_form_html() %}
<div class="form-group">
<input type="text" class="form-control form-control-lg"
- name="username" placeholder="{{ _("Username") }}" required autofocus>
+ name="username" placeholder="{{ _("Username") }}"
+ value="{{ username or "" }}" required autofocus>
</div>
<div class="form-group">
{{ _("Log in") }}
</button>
</form>
+
+ <p class="card-text text-center small mt-3">
+ <a class="text-muted" href="//people.ipfire.org/password-reset{% if incorrect %}?uid={{ username }}{% end %}">
+ {{ _("Did you forget your password?") }}
+ </a>
+ </p>
</div>
</div>
def get(self):
next = self.get_argument("next", None)
- self.render("auth/login.html", next=next)
+ self.render("auth/login.html", next=next,
+ incorrect=False, username=None)
@base.blacklisted
@base.ratelimit(minutes=60, requests=5)
def post(self):
username = self.get_argument("username")
password = self.get_argument("password")
+ next = self.get_argument("next", "/")
# Find user
account = self.backend.accounts.auth(username, password)
if not account:
- raise tornado.web.HTTPError(401, "Unknown user or invalid password: %s" % username)
+ logging.error("Unknown user or invalid password: %s" % username)
+
+ # Set status to 401
+ self.set_status(401)
+
+ # Render login page again
+ return self.render("auth/login.html",
+ incorrect=True, username=username, next=next,
+ )
# Create session
with self.db.transaction():
self.login(account)
- # Determine the page we should redirect to
- next = self.get_argument("next", None)
-
- return self.redirect(next or "/")
+ # Redirect the user
+ return self.redirect(next)
class LogoutHandler(AuthenticationMixin, base.BaseHandler):