From 4cd06c0070774e7535b79eafb9c6a70875e10e2d Mon Sep 17 00:00:00 2001 From: Eduardo Robles Date: Tue, 4 Jan 2022 13:17:01 +0100 Subject: [PATCH] fix timeout of non-otp authentication methods (#167) A bug was introduced during code refatoring. Authentication methods that are not using OTP time-limited tokens were (bug) applying time-limits of the authentication code as if they were an OTP code. Fixing that. --- authapi/authmethods/m_email.py | 2 +- authapi/authmethods/m_email_otp.py | 5 ++++- authapi/authmethods/m_sms.py | 2 +- authapi/authmethods/m_sms_otp.py | 5 ++++- authapi/authmethods/utils.py | 23 +++++++++++++++-------- 5 files changed, 25 insertions(+), 12 deletions(-) diff --git a/authapi/authmethods/m_email.py b/authapi/authmethods/m_email.py index 624dab66..fa76198a 100644 --- a/authapi/authmethods/m_email.py +++ b/authapi/authmethods/m_email.py @@ -703,7 +703,7 @@ def authenticate(self, auth_event, request): if not verify_num_successful_logins(user_auth_event, 'Email', user, req): return self.error("Incorrect data", error_codename="invalid_credentials") - code = get_user_code(user) + code = get_user_code(user, timeout_seconds=None) if not code: LOGGER.error(\ "Email.authenticate error\n"\ diff --git a/authapi/authmethods/m_email_otp.py b/authapi/authmethods/m_email_otp.py index aac7690c..81695849 100644 --- a/authapi/authmethods/m_email_otp.py +++ b/authapi/authmethods/m_email_otp.py @@ -707,7 +707,10 @@ def authenticate(self, auth_event, request): if not verify_num_successful_logins(auth_event, 'EmailOtp', user, req): return self.error("Incorrect data", error_codename="invalid_credentials") - code = get_user_code(user) + code = get_user_code( + user, + timeout_seconds=settings.SMS_OTP_EXPIRE_SECONDS + ) if not code: LOGGER.error( "EmailOtp.authenticate error\n"\ diff --git a/authapi/authmethods/m_sms.py b/authapi/authmethods/m_sms.py index 5dd840de..01fcbc4d 100644 --- a/authapi/authmethods/m_sms.py +++ b/authapi/authmethods/m_sms.py @@ -695,7 +695,7 @@ def authenticate(self, auth_event, request): if not verify_num_successful_logins(auth_event, 'Sms', user, req): return self.error("Incorrect data", error_codename="invalid_credentials") - code = get_user_code(user) + code = get_user_code(user, timeout_seconds=None) if not code: LOGGER.error(\ "Sms.authenticate error\n"\ diff --git a/authapi/authmethods/m_sms_otp.py b/authapi/authmethods/m_sms_otp.py index a57fa4ab..a7ea97a1 100644 --- a/authapi/authmethods/m_sms_otp.py +++ b/authapi/authmethods/m_sms_otp.py @@ -697,7 +697,10 @@ def authenticate(self, auth_event, request): return self.error("Incorrect data", error_codename="invalid_credentials") - code = get_user_code(user) + code = get_user_code( + user, + timeout_seconds=settings.SMS_OTP_EXPIRE_SECONDS + ) if not code: LOGGER.error( "SmsOtp.authenticate error\n"\ diff --git a/authapi/authmethods/utils.py b/authapi/authmethods/utils.py index 71e72ed5..0f82de65 100644 --- a/authapi/authmethods/utils.py +++ b/authapi/authmethods/utils.py @@ -878,17 +878,24 @@ def get_trimmed_user(user, ae): return metadata -def get_user_code(user): - expiration_date = ( - timezone.now() - timedelta(seconds=settings.SMS_OTP_EXPIRE_SECONDS) +def get_user_code(user, timeout_seconds=None): + ''' + Retrieves from the database the current valid user code for a given user and + optionally a timeout period. The timeout period (timeout_seconds) is + optional and only used if it's not None. + ''' + filter_kwargs = dict( + user=user.userdata, + is_enabled=True ) + if timeout_seconds is not None: + filter_kwargs['created__gt'] = ( + timezone.now() - timedelta(seconds=timeout_seconds) + ) + return Code\ .objects\ - .filter( - user=user.userdata, - created__gt=expiration_date, - is_enabled=True - )\ + .filter(**filter_kwargs)\ .order_by('-created')\ .first()