SAT9/.resources/39ad9288b6a75113302b7d52b3f7fc60a2baa58e22ad75ea896e22ac63484702
2025-05-01 00:04:09 -07:00

294 lines
12 KiB
Plaintext

import sys, os, datetime, hashlib, hmac
from StringIO import StringIO
import gzip
import urllib
import urllib2
import json
def get_filters_2(**kwargs):
filter_stack = []
canonical_querystring = ""
url_encoding = kwargs.get("url_encoding")
sources = kwargs.get("sources")
if sources:
source_string = "SourceId=" + ",".join(sources)
filter_stack.append(source_string)
devices = kwargs.get("devices")
if devices:
device_string = "Device=" + ",".join(devices)
filter_stack.append(device_string)
priorities = kwargs.get("priorities")
if priorities:
priority_string = "Priority=" + ",".join(str(item) for item in priorities)
filter_stack.append(priority_string)
types = kwargs.get("types")
if types:
type_string = ("Type=" + ",".join(str(item) for item in types))
filter_stack.append(type_string)
time_from = kwargs.get("start")
if time_from:
time_from_string = "StartTimestamp=" + str(time_from)
filter_stack.append(time_from_string)
time_to = kwargs.get("end")
if time_to:
time_to_string = "EndTimestamp=" + str(time_to)
filter_stack.append(time_to_string)
duration = kwargs.get("duration")
if duration:
duration_string = "MinimumDuration=" + str(duration)
filter_stack.append(duration_string)
if filter_stack:
if url_encoding:
canonical_querystring += "Filter="
for i, j in enumerate(filter_stack):
if i == len(filter_stack)-1 and url_encoding == True:
canonical_querystring += urllib.quote(j, "")
elif i == len(filter_stack)-1:
canonical_querystring += j
elif url_encoding == True:
canonical_querystring += urllib.quote(j + "&", "")
else:
canonical_querystring += (j + "&")
return canonical_querystring
def get_filters(**kwargs):
#Build filter string, filters are passed as key word arguments into the function
#Check if any of the filters have been passed means we need to add Filter=.
#Each filter is then converted using the urllib_parse.
canonical_querystring = ""
sources = kwargs.get("sources")
devices = kwargs.get("devices")
priorities = kwargs.get("priorities")
types = kwargs.get("types")
time_from = kwargs.get("start")
time_to = kwargs.get("end")
duration = kwargs.get("duration")
url_encoding = kwargs.get("url_encoding")
filter_list = [sources, devices, priorities, types, time_from, time_to, duration]
if any(filter_list):
canonical_querystring = "Filter="
if sources:
source_string = ("SourceId=" + ",".join(sources))
if url_encoding == True:
canonical_querystring += urllib.quote(source_string + "&","")
else:
canonical_querystring += source_string + "&"
if devices:
device_string = ("Device=" + ",".join(devices))
if url_encoding == True:
canonical_querystring += urllib.quote(device_string + "&","")
else:
canonical_querystring += device_string +"&"
if priorities:
priority_string = ("Priority=" + ",".join(str(item) for item in priorities))
if url_encoding == True:
canonical_querystring += urllib.quote(priority_string + "&", "")
else:
canonical_querystring += priority_string +"&"
if types:
type_string = ("Type=" + ",".join(str(item) for item in types))
if url_encoding == True:
canonical_querystring += urllib.quote(type_string + "&","")
else:
canonical_querystring += type_string +"&"
if time_from:
if url_encoding == True:
canonical_querystring += urllib.quote("StartTimestamp=" + str(time_from) + "&","")
else:
canonical_querystring += "StartTimestamp=" + str(time_from) +"&"
if time_to:
if url_encoding == True:
canonical_querystring += urllib.quote("EndTimestamp=" + str(time_to) + "&","")
else:
canonical_querystring += "EndTimestamp=" + str(time_to) +"&"
if duration:
if url_encoding == True:
canonical_querystring += urllib.quote("MinimumDuration=" + str(duration) + "&","")
else:
canonical_querystring += "MinimumDuration=" + str(duration) +"&"
system.perspective.print("filtered string = " + canonical_querystring )
canonical_querystring = canonical_querystring.rstrip("&")
return canonical_querystring
def get_response(response):
if response.info().get('Content-Encoding') == 'gzip':
buf = StringIO(response.read())
f = gzip.GzipFile(fileobj=buf)
data = f.read()
return (response.getcode(), data)
else:
buf = StringIO(response.read())
return(response.getcode(), buf.read())
def build_url(credentials, **kwargs):
# ************* REQUEST VALUES *************
method = 'GET'
service = 'lambda'
# This is a lookup in secrets to a return the function url for the lambda that needs called.
# This allows beta and prod to be dynamically retrived.
whid = kwargs.get("fc")
region = kwargs.get("region")
API_ID, STAGE, ACC_ID, FUNC_URL = AWS.secrets_manager.get_secret(str(whid), 'scada/api/endpoint')
api_id = FUNC_URL
host = "%s.%s-url.%s.on.aws" % (api_id, service, region)
endpoint = "https://%s" % (host)
# Key derivation functions. See:
# http://docs.aws.amazon.com/general/latest/gr/signature-v4-examples.html#signature-v4-examples-python
def sign(key, msg):
return hmac.new(key, msg.encode('utf-8'), hashlib.sha256).digest()
def getSignatureKey(key, dateStamp, regionName, serviceName):
kDate = sign(('AWS4' + key).encode('utf-8'), dateStamp)
kRegion = sign(kDate, regionName)
kService = sign(kRegion, serviceName)
kSigning = sign(kService, 'aws4_request')
return kSigning
# Read AWS access key from env. variables or configuration file. Best practice is NOT
# to embed credentials in code.
# access_key = os.environ.get('AWS_ACCESS_KEY_ID')
# access_key= 'ASIATVSVCYSV2JJJMDPP'
# secret_key = os.environ.get('AWS_SECRET_ACCESS_KEY')
# secret_key= 'Hc0G/0eACBlgplGSBnfsB98Y6DPqwpvyb4nc1Rvs'
# session_token = os.environ["AWS_SESSION_TOKEN"]
# session_token= 'IQoJb3JpZ2luX2VjEJr//////////wEaCWV1LXdlc3QtMSJHMEUCIQCbrPQoj4OM0SXIo6QtcNAblnplgXfvSYIcA+k8xkXmZwIgN1Pi7Nyc66T8p0HkZSMmuW8pu1qPEVJii41YgYCuiBYqngIIo///////////ARAAGgwyNTI1MDc3Njc5NzkiDKGV69tLNcKNVcoeryryARkU2Lmnj0aa+ilLOrg35FIb81jvmj6bpPR3+5zJ3Wna+vOBgz6cqphyn28+Q8Ryw/lzM6gM0vWH+gV26CuQZtKd1U4ETo9eL9QuluLBqLnZYfT5q+F9hzJy3OQQl0c3VvwcaCjOPrMdbvWnJGEoEZTKe7Xm5v3ok3huJDgKLEIVlE6Z4c2kKNy/N/JfbxB5a33A2eaE9YaGj1V0cQgUFCCkn9uDq8W4TzOPZ3NgKAyj8RoBR6KAC8gEtWXFEwwZR3ZMwYIXryEepcU7HQSHpp66JAFm/X5+HNxRe7WUwTETAveYMNi5ssFzl3rneKh9+U37MPW58psGOp0B11BghSma0KZHgCfXqdsgfGyD7/sBEyYE9wdnzmi8fOpel5EDQoUoYilRSXod2E9wlaXj3h8S+dtBJjGVqsIbHEIrW7WKOEYELxoW4VSDw5hDjZaUuZ5fA3z59c4CEeAz3v5EA6NN6+ulEb7/4pbWF8s3fezNk9T73NpmKnjaMFukcBX8DofesZGJFpfGij2Sx4hQ3qlmG91uac8kMw=='
access_key = credentials["AccessKey"]
secret_key = credentials["SecretKey"]
session_token = credentials["SessionKey"]
if access_key is None or secret_key is None:
system.perspective.print('No access key is available.')
sys.exit()
# Create a date for headers and the credential string
t = datetime.datetime.utcnow()
amz_date = t.strftime('%Y%m%dT%H%M%SZ') # Format date as YYYYMMDD'T'HHMMSS'Z'
datestamp = t.strftime('%Y%m%d') # Date w/o time, used in credential scope
system.perspective.print("creating header")
system.perspective.print("datestamp = " + str(datestamp) + " region = " + str(region) + "service = " + str(service))
# ************* TASK 1: CREATE A CANONICAL REQUEST *************
# http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html
# Because almost all information is being passed in the query string,
# the order of these steps is slightly different than examples that
# use an authorization header.
# Step 1: Define the verb (GET, POST, etc.)--already done.
# Step 2: Create canonical URI--the part of the URI from domain to query
# string (use '/' if no path)
fc = kwargs.get("fc")
canonical_uri = "/history/%s" % (fc)
# Step 3: Create the canonical headers and signed headers. Header names
# must be trimmed and lowercase, and sorted in code point order from
# low to high. Note trailing \n in canonical_headers.
# signed_headers is the list of headers that are being included
# as part of the signing process. For requests that use query strings,
# only "host" is included in the signed headers.
canonical_headers = 'host:' + host + '\n'
signed_headers = 'host'
# Match the algorithm to the hashing algorithm you use, either SHA-1 or
# SHA-256 (recommended)
algorithm = 'AWS4-HMAC-SHA256'
credential_scope = datestamp + '/' + region + '/' + service + '/' + 'aws4_request'
# Step 4: Create the canonical query string. In this example, request
# parameters are in the query string. Query string values must
# be URL-encoded (space=%20). The parameters must be sorted by name.
#canonical_querystring = 'Action=CreateUser&UserName=NewUser&Version=2010-05-08'
#canonical_querystring = 'NextToken=' + urllib.parse.quote("1669217267.5230844/PLC09/T00049",'') + '&PageSize=50'
#canonical_querystring = 'PageSize=50&PreviousToken=' + urllib.parse.quote('1669217267.5824845/PLC09/T00099','')
canonical_querystring = ""
#Build filter string, filters are passed as key word arguments int the function
#Check if any of the filters have been passed means we need to add Filter=.
#Each filter is then converted using the urllib_parse.
#Including client id for timestream api.
client_id = kwargs.get("client_id")
if client_id:
canonical_querystring += 'ClientId=' + client_id + '&'
PAGE_SIZE = "200"
filters= kwargs.get("filters","")
if filters != "":
canonical_querystring += filters + "&"
next_token = kwargs.get("next_token")
previous_token = kwargs.get("previous_token")
if next_token != None:
canonical_querystring += 'NextToken=' + urllib.quote(next_token,'') + '&'
system.perspective.print("created string " + canonical_querystring)
if previous_token != None:
canonical_querystring += 'PreviousToken=' + urllib.quote(previous_token,'') + '&'
else:
canonical_querystring += 'X-Amz-Algorithm=AWS4-HMAC-SHA256'
canonical_querystring += '&X-Amz-Credential=' + urllib.quote_plus(access_key + '/' + credential_scope)
canonical_querystring += '&X-Amz-Date=' + amz_date
#canonical_querystring += '&X-Amz-Expires=30'
canonical_querystring += "&X-Amz-Security-Token=" + urllib.quote_plus(session_token)
canonical_querystring += '&X-Amz-SignedHeaders=' + signed_headers
# Step 5: Create payload hash. For GET requests, the payload is an
# empty string ("").
payload_hash = hashlib.sha256(('').encode('utf-8')).hexdigest()
# Step 6: Combine elements to create canonical request
canonical_request = method + '\n' + canonical_uri + '\n' + canonical_querystring + '\n' + canonical_headers + '\n' + signed_headers + '\n' + payload_hash
# ************* TASK 2: CREATE THE STRING TO SIGN*************
string_to_sign = algorithm + '\n' + amz_date + '\n' + credential_scope + '\n' + hashlib.sha256(canonical_request.encode('utf-8')).hexdigest()
# ************* TASK 3: CALCULATE THE SIGNATURE *************
# Create the signing key
signing_key = getSignatureKey(secret_key, datestamp, region, service)
# Sign the string_to_sign using the signing_key
signature = hmac.new(signing_key, (string_to_sign).encode("utf-8"), hashlib.sha256).hexdigest()
# ************* TASK 4: ADD SIGNING INFORMATION TO THE REQUEST *************
# The auth information can be either in a query string
# value or in a header named Authorization. This code shows how to put
# everything into a query string.
canonical_querystring += '&X-Amz-Signature=' + signature
# ************* SEND THE REQUEST *************
# The 'host' header is added automatically by the Python 'request' lib. But it
# must exist as a header in the request.
request_url = endpoint + canonical_uri + "?" + canonical_querystring
system.perspective.print('\nBEGIN REQUEST++++++++++++++++++++++++++++++++++++')
system.perspective.print('Request URL = ' + request_url)
# r = requests.get(request_url)
request = urllib2.Request(request_url)
request.add_header('Accept-encoding', 'gzip')
try:
response = urllib2.urlopen(request)
except urllib2.HTTPError as e:
return(e.code, None)
except urllib2.URLError as e:
return(e.reason, None)
return get_response(response)