Skip to content

Commit 78adf1d

Browse files
committed
feat: tell user if they are locked out
1 parent d31f901 commit 78adf1d

File tree

3 files changed

+19
-3
lines changed

3 files changed

+19
-3
lines changed

config/docker/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,4 @@ RUN apk update && \
1515
pip3 install -Ir requirements-dev.txt && \
1616
rm requirements.txt requirements-dev.txt
1717

18-
WORKDIR /ion
18+
WORKDIR /ion

intranet/apps/auth/backends.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ class PamAuthenticationResult(enum.Enum):
2222
FAILURE = 0 # Authentication failed
2323
SUCCESS = 1 # Authentication succeeded
2424
EXPIRED = -1 # Password expired; needs reset
25+
LOCKED = 6 # User locked out due to incorrect attempts
2526

2627

2728
class PamAuthenticationBackend:
@@ -72,14 +73,16 @@ def pam_auth(username, password):
7273
realm = settings.CSL_REALM
7374
pam_authenticator = pam.pam()
7475
full_username = f"{username}@{realm}"
75-
result = pam_authenticator.authenticate(full_username, password)
76+
result = pam_authenticator.authenticate(full_username, password, service="ion-login")
7677

7778
if result:
7879
result = PamAuthenticationResult.SUCCESS
7980
logger.debug("PAM authorized %s@%s", username, realm)
8081
else:
8182
logger.debug("PAM failed to authorize %s", username)
8283
result = PamAuthenticationResult.FAILURE
84+
if pam_authenticator.code == 6:
85+
result = PamAuthenticationResult.LOCKED
8386
if "authentication token is no longer valid" in pam_authenticator.reason.lower():
8487
result = PamAuthenticationResult.EXPIRED
8588
logger.debug("Password for %s@%s expired, needs reset", username, realm)
@@ -128,6 +131,10 @@ def authenticate(self, request, username=None, password=None):
128131
elif result == PamAuthenticationResult.EXPIRED:
129132
user, _ = get_user_model().objects.get_or_create(username="RESET_PASSWORD", user_type="service", id=999999)
130133
return user
134+
elif result == PamAuthenticationResult.LOCKED:
135+
if request is not None:
136+
request.session["user_locked_out"] = 1
137+
return None
131138
else:
132139
pam_authenticate_failures.inc()
133140
return None

intranet/apps/auth/views.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ def index_view(request, auth_form=None, force_login=False, added_context=None, h
151151
}
152152
schedule = schedule_context(request)
153153
data.update(schedule)
154+
154155
if added_context is not None:
155156
data.update(added_context)
156157
return render(request, "auth/login.html", data)
@@ -172,13 +173,21 @@ def post(self, request):
172173
if re.search(r"^(\d{4})?[a-zA-Z]+\d?$", username) is None:
173174
return index_view(request, added_context={"auth_message": "Your username format is incorrect."})
174175

175-
form = AuthenticateForm(data=request.POST)
176+
form = AuthenticateForm(request, data=request.POST)
176177

177178
if request.session.test_cookie_worked():
178179
request.session.delete_test_cookie()
179180
else:
180181
logger.warning("No cookie support detected! This could cause problems.")
181182

183+
if request.session.get("user_locked_out", "") == 1:
184+
request.session.pop("user_locked_out")
185+
return index_view(
186+
request,
187+
auth_form=form,
188+
added_context={"auth_message": "You are locked out due to too many incorrect logins. Please try again later."},
189+
)
190+
182191
if form.is_valid():
183192
reset_user, _ = get_user_model().objects.get_or_create(username="RESET_PASSWORD", user_type="service", id=999999)
184193
if form.get_user() == reset_user:

0 commit comments

Comments
 (0)