Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion config/docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ RUN apk update && \
pip3 install -Ir requirements-dev.txt && \
rm requirements.txt requirements-dev.txt

WORKDIR /ion
WORKDIR /ion
9 changes: 8 additions & 1 deletion intranet/apps/auth/backends.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class PamAuthenticationResult(enum.Enum):
FAILURE = 0 # Authentication failed
SUCCESS = 1 # Authentication succeeded
EXPIRED = -1 # Password expired; needs reset
LOCKED = 6 # User locked out due to incorrect attempts


class PamAuthenticationBackend:
Expand Down Expand Up @@ -72,14 +73,16 @@ def pam_auth(username, password):
realm = settings.CSL_REALM
pam_authenticator = pam.pam()
full_username = f"{username}@{realm}"
result = pam_authenticator.authenticate(full_username, password)
result = pam_authenticator.authenticate(full_username, password, service="ion-login")

if result:
result = PamAuthenticationResult.SUCCESS
logger.debug("PAM authorized %s@%s", username, realm)
else:
logger.debug("PAM failed to authorize %s", username)
result = PamAuthenticationResult.FAILURE
if pam_authenticator.code == 6:
result = PamAuthenticationResult.LOCKED
if "authentication token is no longer valid" in pam_authenticator.reason.lower():
result = PamAuthenticationResult.EXPIRED
logger.debug("Password for %s@%s expired, needs reset", username, realm)
Expand Down Expand Up @@ -128,6 +131,10 @@ def authenticate(self, request, username=None, password=None):
elif result == PamAuthenticationResult.EXPIRED:
user, _ = get_user_model().objects.get_or_create(username="RESET_PASSWORD", user_type="service", id=999999)
return user
elif result == PamAuthenticationResult.LOCKED:
if request is not None:
request.session["user_locked_out"] = 1
return None
else:
pam_authenticate_failures.inc()
return None
Expand Down
11 changes: 10 additions & 1 deletion intranet/apps/auth/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ def index_view(request, auth_form=None, force_login=False, added_context=None, h
}
schedule = schedule_context(request)
data.update(schedule)

if added_context is not None:
data.update(added_context)
return render(request, "auth/login.html", data)
Expand All @@ -172,13 +173,21 @@ def post(self, request):
if re.search(r"^(\d{4})?[a-zA-Z]+\d?$", username) is None:
return index_view(request, added_context={"auth_message": "Your username format is incorrect."})

form = AuthenticateForm(data=request.POST)
form = AuthenticateForm(request, data=request.POST)

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

if request.session.get("user_locked_out", "") == 1:
request.session.pop("user_locked_out")
return index_view(
request,
auth_form=form,
added_context={"auth_message": "You are locked out due to too many incorrect logins. Please try again later."},
)

if form.is_valid():
reset_user, _ = get_user_model().objects.get_or_create(username="RESET_PASSWORD", user_type="service", id=999999)
if form.get_user() == reset_user:
Expand Down