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
35 changes: 17 additions & 18 deletions warrant_lite/__init__.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
import base64
import binascii
import contextlib
import datetime
import hashlib
import hmac
import locale
import re

import boto3
import os
Expand Down Expand Up @@ -36,6 +33,8 @@ class TokenVerificationException(Exception):
g_hex = '2'
info_bits = bytearray('Caldera Derived Key', 'utf-8')

week_names = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
month_names = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']

def hash_sha256(buf):
"""AuthenticationHelper.hash"""
Expand Down Expand Up @@ -102,11 +101,20 @@ def calculate_u(big_a, big_b):
return hex_to_long(u_hex_hash)


@contextlib.contextmanager
def temp_locale(new_locale):
original = locale.getlocale()
yield locale.setlocale(locale.LC_ALL, new_locale)
locale.setlocale(locale.LC_ALL, original)
def timestamp_string(date):
"""
Generate a timestamp string for the current time in the following format:
Fri Oct 2 01:02:03 UTC 2020
"""
return "%s %s %d %02d:%02d:%02d UTC %d" % (
week_names[date.weekday()],
month_names[date.month-1],
date.day,
date.hour,
date.minute,
date.second,
date.year
)


class WarrantLite(object):
Expand Down Expand Up @@ -197,16 +205,7 @@ def process_challenge(self, challenge_parameters):
salt_hex = challenge_parameters['SALT']
srp_b_hex = challenge_parameters['SRP_B']
secret_block_b64 = challenge_parameters['SECRET_BLOCK']
# re strips leading zero from a day number (required by AWS Cognito)
try:
with temp_locale(('en_US', 'utf-8')):
timestamp = re.sub(r" 0(\d) ", r" \1 ",
datetime.datetime.utcnow().strftime("%a %b %d %H:%M:%S UTC %Y"))
except locale.Error:
# try windows locale format
with temp_locale(('English_United States', '1252')):
timestamp = re.sub(r" 0(\d) ", r" \1 ",
datetime.datetime.utcnow().strftime("%a %b %d %H:%M:%S UTC %Y"))
timestamp = timestamp_string(datetime.datetime.utcnow())
hkdf = self.get_password_authentication_key(user_id_for_srp,
self.password, hex_to_long(srp_b_hex), salt_hex)
secret_block_bytes = base64.standard_b64decode(secret_block_b64)
Expand Down
31 changes: 30 additions & 1 deletion warrant_lite/tests.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import datetime
import unittest

from envs import env

from warrant_lite import WarrantLite, TokenVerificationException
from warrant_lite import WarrantLite, TokenVerificationException, timestamp_string


class WarrantLiteTestCase(unittest.TestCase):
Expand Down Expand Up @@ -39,6 +40,34 @@ def test_authenticate_user(self):
self.assertTrue('AccessToken' in tokens['AuthenticationResult'])
self.assertTrue('RefreshToken' in tokens['AuthenticationResult'])

class TimestampStringTest(unittest.TestCase):

def test_when_no_padding_is_necessary_should_return(self):
date = datetime.datetime(2020, 10, 28, hour=16, minute=36,
second=17, microsecond=14,
tzinfo=datetime.timezone.utc)

actual = timestamp_string(date)

self.assertEqual("Wed Oct 28 16:36:17 UTC 2020", actual)

def test_should_pad_timestamp(self):
date = datetime.datetime(2020, 10, 28, hour=1, minute=2,
second=3, microsecond=4,
tzinfo=datetime.timezone.utc)

actual = timestamp_string(date)

self.assertEqual("Wed Oct 28 01:02:03 UTC 2020", actual)

def test_should_not_pad_day(self):
date = datetime.datetime(2020, 10, 2, hour=1, minute=2,
second=3, microsecond=4,
tzinfo=datetime.timezone.utc)

actual = timestamp_string(date)

self.assertEqual("Fri Oct 2 01:02:03 UTC 2020", actual)

if __name__ == '__main__':
unittest.main()