def test_generate_signature(self): """ Using example data from http://docs.aws.amazon.com/general/latest/gr/sigv4-calculate-signature.html """ access_key = 'wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY' region = 'us-east-1' service = 'iam' date = '20110909' key = AWS4SigningKey(access_key, region, service, date) req_text = [ 'POST https://iam.amazonaws.com/ HTTP/1.1', 'Host: iam.amazonaws.com', 'Content-Type: application/x-www-form-urlencoded; charset=utf-8', 'X-Amz-Date: 20110909T233600Z', '', 'Action=ListUsers&Version=2010-05-08' ] req_text = '\n'.join(req_text) + '\n' req = request_from_text(req_text) del req.headers['content-length'] include_hdrs = list(req.headers) auth = AWS4Auth('dummy', key, include_hdrs=include_hdrs) AWS4Auth.encode_body(req) hsh = hashlib.sha256(req.body) req.headers['x-amz-content-sha256'] = hsh.hexdigest() sreq = auth(req) signature = sreq.headers['Authorization'].split('=')[3] expected = ('ced6826de92d2bdeed8f846f0bf508e8559e98e4b0199114b84c541' '74deb456c') self.assertEqual(signature, expected)
def test_signing_key_phases(self): """ Using example data from: http://docs.aws.amazon.com/general/latest/gr/signature-v4-examples.html """ access_key = 'wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY' region = 'us-east-1' service = 'iam' date = '20120215' # These are signing key, date_key, region_key and service_key # respectively expected_raw = ( 'f4780e2d9f65fa895f9c67b32ce1baf0b0d8a43505a000a1a9e090d414db404d', '969fbb94feb542b71ede6f87fe4d5fa29c789342b0f407474670f0c2489e0a0d', '69daa0209cd9c5ff5c8ced464a696fd4252e981430b10e3d3fd8e2f197d7a70c', 'f72cfd46f26bc4643f06a11eabb6c0ba18780c19a8da0c31ace671265e3c87fa') expected = [] for hsh in expected_raw: hexen = re.findall('..', hsh) expected.append([int(x, base=16) for x in hexen]) result = AWS4SigningKey.generate_key(access_key, region, service, date, intermediate=True) for i, hsh in enumerate(result): hsh = [ord(x) for x in hsh] if PY2 else list(hsh) self.assertEqual(hsh, expected[i], msg='Item number {}'.format(i))
def test_instantiate_from_signing_key(self): key = AWS4SigningKey('access_key', 'region', 'service', 'date') auth = AWS4Auth('access_id', key) self.assertEqual(auth.access_id, 'access_id') self.assertEqual(auth.region, 'region') self.assertEqual(auth.service, 'service') self.assertIsInstance(auth.signing_key, AWS4SigningKey) self.assertEqual(auth.signing_key.region, 'region') self.assertEqual(auth.signing_key.service, 'service')
def test_sts_creds_include_security_token_header(self): key = AWS4SigningKey('secret_key', 'region', 'service', '1999010') auth = AWS4Auth('access_id', key, session_token='sessiontoken') req = requests.Request('GET', 'http://blah.com') req = req.prepare() sreq = auth(req) self.assertIn('x-amz-security-token', sreq.headers) self.assertEqual(sreq.headers.get('x-amz-security-token'), 'sessiontoken')
def test_date_mismatch_nosecretkey_raise(self): key = AWS4SigningKey('secret_key', 'region', 'service', '1999010', False) auth = AWS4Auth('access_id', key) req = requests.Request('GET', 'http://blah.com') req = req.prepare() if 'date' in req.headers: del req.headers['date'] req.headers['x-amz-date'] = '20000101T010101Z' self.assertRaises(NoSecretKeyError, auth, req)
def test_sign_sha256_bytes_msg(self): key = b'The quick brown fox jumps over the lazy dog' msg = (b'Forsaking monastic tradition, twelve jovial friars gave up ' b'their vocation for a questionable existence on the flying ' b'trapeze') expected = [250, 103, 254, 220, 118, 118, 37, 81, 166, 41, 65, 14, 142, 77, 204, 122, 185, 19, 38, 15, 145, 249, 113, 69, 178, 30, 131, 244, 230, 190, 246, 23] hsh = AWS4SigningKey.sign_sha256(key, msg) hsh = [ord(x) for x in hsh] if PY2 else list(hsh) self.assertEqual(hsh, expected)
def setUp(self): self.region = 'region' self.service = 'service' self.date = '19990101' self.secret_key = 'secret_key' self.access_id = 'access_id' self.auth = AWS4Auth(self.access_id, self.secret_key, self.region, self.service, self.date) self.sig_key_no_secret = AWS4SigningKey(self.secret_key, self.region, self.service, self.date, False) self.auth_no_secret = AWS4Auth(self.access_id, self.sig_key_no_secret)
def test_aws4auth_add_header(self): req = requests.Request('GET', 'http://blah.com') req = req.prepare() if 'date' in req.headers: del req.headers['date'] secret_key = 'dummy' region = 'us-east-1' service = 'iam' key = AWS4SigningKey(secret_key, region, service) auth = AWS4Auth('dummy', key) sreq = auth(req) self.assertIn('x-amz-date', sreq.headers) self.assertIsNotNone(AWS4Auth.get_request_date(sreq))
def test_amz_date(self): """ Will be removed when deprecated amz_date attribute is removed """ with warnings.catch_warnings(record=True) as w: warnings.simplefilter('always') test_date = datetime.datetime.utcnow().strftime('%Y%m%d') obj = AWS4SigningKey('secret_key', 'region', 'service') if obj.amz_date != test_date: test_date = datetime.datetime.utcnow().strftime('%Y%m%d') self.assertEqual(obj.amz_date, test_date)
def test_sign_sha256_bytes_msg(self): key = b'The quick brown fox jumps over the lazy dog' msg = (b'Forsaking monastic tradition, twelve jovial friars gave up ' b'their vocation for a questionable existence on the flying ' b'trapeze') expected = [ 250, 103, 254, 220, 118, 118, 37, 81, 166, 41, 65, 14, 142, 77, 204, 122, 185, 19, 38, 15, 145, 249, 113, 69, 178, 30, 131, 244, 230, 190, 246, 23 ] hsh = AWS4SigningKey.sign_sha256(key, msg) hsh = [ord(x) for x in hsh] if PY2 else list(hsh) self.assertEqual(hsh, expected)
def test_generate_key(self): """ Using example data from: http://docs.aws.amazon.com/general/latest/gr/sigv4-calculate-signature.html """ access_key = 'wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY' region = 'us-east-1' service = 'iam' date = '20110909' expected = [152, 241, 216, 137, 254, 196, 244, 66, 26, 220, 82, 43, 171, 12, 225, 248, 46, 105, 41, 194, 98, 237, 21, 229, 169, 76, 144, 239, 209, 227, 176, 231] key = AWS4SigningKey.generate_key(access_key, region, service, date) key = [ord(x) for x in key] if PY2 else list(key) self.assertEqual(key, expected)
def test_amz_date_warning(self): """ Will be removed when deprecated amz_date attribute is removed """ warnings.resetwarnings() with warnings.catch_warnings(record=True) as w: obj = AWS4SigningKey('secret_key', 'region', 'service') if PY2: warnings.simplefilter('always') obj.amz_date self.assertEqual(len(w), 1) self.assertEqual(w[-1].category, DeprecationWarning) else: warnings.simplefilter('ignore') self.assertWarns(DeprecationWarning, getattr, obj, 'amz_date')
def test_instantiation_generate_key(self): """ Using example data from: http://docs.aws.amazon.com/general/latest/gr/sigv4-calculate-signature.html """ access_key = 'wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY' region = 'us-east-1' service = 'iam' date = '20110909' expected = [ 152, 241, 216, 137, 254, 196, 244, 66, 26, 220, 82, 43, 171, 12, 225, 248, 46, 105, 41, 194, 98, 237, 21, 229, 169, 76, 144, 239, 209, 227, 176, 231 ] key = AWS4SigningKey(access_key, region, service, date).key key = [ord(x) for x in key] if PY2 else list(key) self.assertEqual(key, expected)
def test_regen_key_on_date_mismatch(self): vals = [('20001231T235959Z', '20010101'), ('20000101T010101Z', '20000102'), ('19900101T010101Z', '20000101')] for amzdate, scope_date in vals: req = requests.Request('GET', 'http://blah.com') req = req.prepare() if 'date' in req.headers: del req.headers['date'] req.headers['x-amz-date'] = amzdate secret_key = 'dummy' region = 'us-east-1' service = 'iam' date = scope_date key = AWS4SigningKey(secret_key, region, service, date) orig_id = id(key) auth = AWS4Auth('dummy', key) sreq = auth(req) self.assertNotEqual(id(auth.signing_key), orig_id) self.assertEqual(auth.date, amzdate.split('T')[0])
def _test_amz_test_suite_item(self, group_name): group = amz_aws4_testsuite.data[group_name] req = request_from_text(group['.req']) if 'content-length' in req.headers: del req.headers['content-length'] include_hdrs = list(req.headers) AWS4Auth.encode_body(req) hsh = hashlib.sha256(req.body or b'') req.headers['x-amz-content-sha256'] = hsh.hexdigest() req.headers['x-amz-date'] = amz_aws4_testsuite.timestamp key = AWS4SigningKey(amz_aws4_testsuite.access_key, amz_aws4_testsuite.region, amz_aws4_testsuite.service, amz_aws4_testsuite.date) auth = AWS4Auth(amz_aws4_testsuite.access_id, key, include_hdrs=include_hdrs) sreq = auth(req) auth_hdr = sreq.headers['Authorization'] msg = 'Group: ' + group_name self.assertEqual(auth_hdr, group['.authz'], msg=msg)
def test_mobileanalytics(self): url = 'https://mobileanalytics.us-east-1.amazonaws.com/2014-06-05/events' service = 'mobileanalytics' region = 'us-east-1' dt = datetime.utcnow() date = dt.strftime('%Y%m%d') sig_key = AWS4SigningKey(live_access_key, region, service, date) auth = AWS4Auth(live_access_id, sig_key) headers = { 'Content-Type': 'application/json', 'X-Amz-Date': dt.strftime('%Y%m%dT%H%M%SZ'), 'X-Amz-Client-Context': json.dumps({ 'client': { 'client_id': 'a', 'app_title': 'a' }, 'custom': {}, 'env': { 'platform': 'a' }, 'services': {} }) } body = json.dumps({ 'events': [{ 'eventType': 'a', 'timestamp': dt.strftime('%Y-%m-%dT%H:%M:%S.000Z'), 'session': {} }] }) response = requests.post(url, auth=auth, headers=headers, data=body) response.connection.close() self.assertTrue(response.ok)
def test_no_store_secret_key(self): obj = AWS4SigningKey('secret_key', 'region', 'service', store_secret_key=False) self.assertEqual(obj.secret_key, None)
def lambda_handler(event, context): logger.info("Event: " + dumps(event)) logger.info("Request Context: " + dumps(event['requestContext'])) requestContext = event['requestContext'] table = dynamodb.Table('iotmx-lighting-socket') try: if requestContext['routeKey'] == "$connect": socketDTO = {} socketDTO['connectionId'] = requestContext['connectionId'] socketDTO['connectionTime'] = requestContext['connectedAt'] socketDTO['domainName'] = requestContext['domainName'] socketDTO['identity'] = requestContext['identity'] socketDTO['online'] = True socketDTO['_id'] = uuid.uuid4().hex logger.info("Putting item in iotmx-lighting-socket: " + dumps(socketDTO)) table.put_item(Item=socketDTO) statusCode = 200 mensaje = "Connected." elif requestContext['routeKey'] == "message": statusCode = 200 logger.info("Message: " + dumps(event['body'])) onlineClient = list() response = table.scan(FilterExpression=Attr('online').eq(True)) for i in response['Items']: onlineClient.append(i['connectionId']) if requestContext['connectionId'] in onlineClient: onlineClient.remove(requestContext['connectionId']) if len(onlineClient) != 0: #Post message to connected clients date = (datetime.datetime.utcnow()).strftime('%Y%m%d') auth = AWS4Auth( aws.access_id, AWS4SigningKey(aws.secret_key, aws.region, 'execute-api', date)) headers = { 'Context-Type': 'application/json', 'X-Amz-Date': (datetime.datetime.utcnow()).strftime('%Y%m%dT%H%M%SZ'), 'X-Amz-Client-Context': dumps({}) } for id in onlineClient: endpoint = "https://" + requestContext[ 'domainName'] + "/v1/@connections/" + str(id) messageDTO = json.loads(event['body']) payload = messageDTO['data'] r = requests.post(url=endpoint, data=dumps(payload), auth=auth, headers=headers) params = json.loads(event['body']) paramsDTO = {"httpMethod": "POST", "body": params['data']} logger.info("paramsDTO: " + dumps(paramsDTO)) response = lambdaClient.invoke( FunctionName='iotmx-lighting-device', InvocationType='Event', Payload=dumps(paramsDTO)) logger.info("Lambda Invokation: " + dumps(response)) mensaje = "Message received." elif requestContext['routeKey'] == "$disconnect": client = {} response = table.scan(FilterExpression=Attr('connectionId').eq( requestContext['connectionId'])) for i in response['Items']: client = i if len(client) != 0: logger.info("Connection Id: " + dumps(client['connectionId'])) table.delete_item(Key={"_id": client['_id']}) statusCode = 200 mensaje = "Desconexion de socket" else: statusCode = 200 mensaje = requestContext['routeKey'] except Exception as e: logger.info("Error: " + str(e)) statusCode = 500 mensaje = "Error: " + str(e) return { "isBase64Encoded": False, "statusCode": statusCode, "body": mensaje, "headers": { 'Content-Type': 'application/json', 'charset': 'utf8', 'Access-Control-Allow-Origin': '*' } }
def test_basic_instantiation(self): obj = AWS4SigningKey('access_key', 'region', 'service', 'date') self.assertEqual(obj.region, 'region') self.assertEqual(obj.service, 'service') self.assertEqual(obj.amz_date, 'date') self.assertEqual(obj.scope, 'date/region/service/aws4_request')
def test_default_store_secret_key(self): obj = AWS4SigningKey('secret_key', 'region', 'service') self.assertEqual(obj.secret_key, 'secret_key')
def test_date(self): test_date = datetime.utcnow().strftime('%Y%m%d') obj = AWS4SigningKey('access_key', 'region', 'service') if obj.amz_date != test_date: test_date = datetime.utcnow().strftime('%Y%m%d') self.assertEqual(obj.amz_date, test_date)