This commit is contained in:
2025-10-29 09:25:48 -03:00
parent 8cce6df501
commit 110ba4146a
82 changed files with 3373 additions and 0 deletions

BIN
files/.DS_Store vendored Normal file

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,101 @@
{
"compartment_id": "<API Gateway Compartment OCID>",
"defined_tags": {
"Oracle-Tags": {
"CreatedBy": "oracleidentitycloudservice/cristiano.hoshikawa@oracle.com",
"CreatedOn": "2024-01-04T14:21:31.582Z"
}
},
"display_name": "applyValidationApi",
"endpoint": "https://aaaaaaaaaaaaaaaaaaaaaaaaaa.apigateway.us-ashburn-1.oci.customer-oci.com/applyValidationApi",
"freeform_tags": {},
"gateway_id": "ocid1.apigateway.oc1.iad.amaaaaaanamaaaaaanamaaaaaanamaaaaaanamaaaaaanamaaaaaanamaaaaaan",
"id": "ocid1.apideployment.oc1.iad.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"lifecycle_details": null,
"lifecycle_state": "ACTIVE",
"path_prefix": "/applyValidationApi",
"specification": {
"logging_policies": {
"access_log": null,
"execution_log": {
"is_enabled": null,
"log_level": "INFO"
}
},
"request_policies": {
"authentication": {
"cache_key": [
"apiId",
"apiCompartmentId",
"functionId",
"host",
"token",
"apiGatewayId"
],
"function_id": "<applyValidationApi function OCID>",
"is_anonymous_access_allowed": false,
"parameters": {
"apiCompartmentId": "request.headers[apiCompartmentId]",
"apiId": "request.headers[apiId]",
"body": "request.body",
"functionId": "request.headers[functionId]",
"host": "request.host",
"token": "request.headers[token]",
"apiGatewayId": "request.headers[apiGatewayId]",
"rateLimit": "request.headers[rateLimit]"
},
"token_header": null,
"token_query_param": null,
"type": "CUSTOM_AUTHENTICATION",
"validation_failure_policy": null
},
"cors": null,
"dynamic_authentication": null,
"mutual_tls": {
"allowed_sans": [],
"is_verified_certificate_required": false
},
"rate_limiting": null,
"usage_plans": null
},
"routes": [
{
"backend": {
"body": "{\"status\": \"success\"}",
"headers": [],
"status": 200,
"type": "STOCK_RESPONSE_BACKEND"
},
"logging_policies": {
"access_log": null,
"execution_log": {
"is_enabled": null,
"log_level": null
}
},
"methods": [
"POST"
],
"path": "/apply",
"request_policies": {
"authorization": {
"type": "AUTHENTICATION_ONLY"
},
"body_validation": null,
"cors": null,
"header_transformations": null,
"header_validations": null,
"query_parameter_transformations": null,
"query_parameter_validations": null,
"response_cache_lookup": null
},
"response_policies": {
"header_transformations": null,
"response_cache_store": null
}
}
]
},
"time_created": "2024-01-04T14:21:31.831000+00:00",
"time_updated": "2024-01-04T14:31:48.792000+00:00"
}

View File

@@ -0,0 +1,7 @@
[DEFAULT]
user=ocid1.user.oc1..aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
fingerprint=36:04:63:cd:36:04:63:cd:36:04:63:cd:36:04:63:cd
key_file=oci_api_key.pem
tenancy=ocid1.tenancy.oc1..aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
region=us-ashburn-1

View File

@@ -0,0 +1,12 @@
{
"ClientId" : "0b8cd92bb60b8cd92bb60b8cd92bb6",
"ClientSecret" : "41964196-2cfb-2cfb-2cfb-63246a63246a",
"BaseUrl" : "https://idcs-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.identity.oraclecloud.com",
"AudienceServiceUrl" : "https://idcs-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.identity.oraclecloud.com",
"scope" : "aaaaaaaaaaaaaaaaaaaaaaa.apigateway.us-ashburn-1.oci.customer-oci.com/super_scope",
"TokenIssuer" : "https://identity.oraclecloud.com",
"redirectURL": "http://localhost:8000/callback",
"logoutSufix":"/oauth2/v1/userlogout",
"LogLevel":"INFO",
"ConsoleLog":"True"
}

View File

@@ -0,0 +1,710 @@
import base64
import json
import io
from fdk import response
import oci
import requests
import time
from itertools import groupby
import yaml
import datetime
import ast
#### IDCS Routines
#### https://docs.oracle.com/en/learn/apigw-modeldeployment/index.html#introduction
#### https://docs.oracle.com/en/learn/migrate-api-to-api-gateway/#introduction
def auth_idcs(token, url, clientID, secretID):
url = url + "/oauth2/v1/introspect"
auth = clientID + ":" + secretID
auth_bytes = auth.encode("ascii")
auth_base64_bytes = base64.b64encode(auth_bytes)
auth_base64_message = auth_base64_bytes.decode("ascii")
headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Basic ' + auth_base64_message
}
payload = "token=" + token
response = requests.request("POST", url, headers=headers, data=payload)
return response
#Function used to load the configurations from the config.json file
def getOptions():
fo = open("config.json", "r")
config = fo.read()
options = json.loads(config)
return options
### OCI API Gateway Migration Routines
def find_base_path(strPath):
base_path = strPath.split('/')[1]
if (len(base_path) == 0):
base_path = strPath
else:
base_path = "/" + base_path
return base_path
def has_path_endpoint(endPoint):
endPointAux = endPoint.replace("//", "#")
endPointSplited = endPointAux.split('/')
if (len(endPointSplited) > 1):
return True
else:
return False
def concatSplited(endPointSplited):
count = 0
endPointStr = ""
for item in endPointSplited:
if (count > 0):
endPointStr = endPointStr + "/" + item
count = count + 1
return endPointStr
def find_base_pathendpoint(endPoint, strPath):
base_path = strPath.split('/')[1]
if (len(base_path) == 0 and has_path_endpoint(endPoint)):
endPointAux = endPoint.replace("//", "#")
endPointSplited = endPointAux.split('/')
if (len(endPointSplited) > 1):
endPointSplitedStr = concatSplited(endPointSplited)
if (endPointSplitedStr != None):
base_path = endPointSplitedStr
else:
base_path = strPath
else:
base_path = strPath
else:
endPointAux = endPoint.replace("//", "#")
endPointSplited = endPointAux.split('/')
if (len(endPointSplited) > 1):
endPointSplitedStr = concatSplited(endPointSplited)
if (endPointSplitedStr != None):
base_path = endPointSplitedStr
endPoint = endPointSplited[0].replace("#", "//")
else:
base_path = "/" + base_path
else:
base_path = "/" + base_path
return base_path
def find_base_endpoint(endPoint):
endPointAux = endPoint.replace("//", "#")
endPointSplited = endPointAux.split('/')
if (len(endPointSplited) > 1):
endPointSplitedStr = endPointSplited[1]
if (endPointSplitedStr != None):
endPoint = endPointSplited[0].replace("#", "//")
return endPoint
def find_path(strPath):
base_path = strPath.split('/')
if (len(base_path) == 0):
return strPath
else:
auxPath = ""
skipCount = 0
for b in base_path:
if (skipCount > 1):
auxPath = auxPath + "/" + b
skipCount = skipCount + 1
base_path = auxPath
return auxPath
def removeLastSlash(path):
return path.rstrip("/")
def creeateOrUpdateDeployment(compartmendId, displayName, validation_deployment_details, create_deployment_details, api_gateway_id):
config = oci.config.from_file("config")
apigateway_client = oci.apigateway.DeploymentClient(config)
listGateway = apigateway_client.list_deployments(compartment_id=compartmendId, display_name=displayName, lifecycle_state="ACTIVE")
gateway = json.loads(str(listGateway.data))
ind = -1
c = -1
if (len(gateway) > 0):
c = 0
for item in gateway["items"]:
if (item["gateway_id"] == api_gateway_id):
ind = c
break
c = c + 1
if (gateway["items"] != [] and c > -1 and ind > -1):
gateway_id = gateway["items"][ind]["gateway_id"]
deployment_id = gateway["items"][ind]["id"]
else:
gateway_id = api_gateway_id
deployment_id = ""
if (gateway["items"] != [] and deployment_id != ""):
apigateway_client.update_deployment(deployment_id=deployment_id, update_deployment_details=validation_deployment_details)
else:
apigateway_client.create_deployment(create_deployment_details=create_deployment_details)
def applyAuthApi(compartmentId, displayName, payload, functionId, host, api_gateway_id, rate_limit):
config = oci.config.from_file("config")
logging = oci.loggingingestion.LoggingClient(config)
apigateway_client = oci.apigateway.DeploymentClient(config)
listGateway = apigateway_client.list_deployments(compartment_id=compartmentId, display_name=displayName, lifecycle_state="ACTIVE")
gateway = json.loads(str(listGateway.data))
ind = -1
c = -1
if (len(gateway) > 0):
c = 0
for item in gateway["items"]:
if (item["gateway_id"] == api_gateway_id):
ind = c
break
c = c + 1
if (gateway["items"] != [] and c > -1 and ind > -1):
gateway_id = gateway["items"][ind]["gateway_id"]
deployment_id = gateway["items"][ind]["id"]
else:
gateway_id = api_gateway_id
deployment_id = 0
try:
rate_config = rate_limit.split(',')
rate_seconds = int(rate_config[0])
rate_key = rate_config[1]
rate_limiting = oci.apigateway.models.RateLimitingPolicy(
rate_in_requests_per_second=rate_seconds,
rate_key=rate_key)
except:
rate_limiting = None
path_prefix = "/"
routes = [ ]
new_routes = [ ]
for item in payload:
methods = [item["METHOD"]]
path_prefix = item["PATH_PREFIX"]
callback_url = ("https://" + host + item["PATH_PREFIX"] + "validation-callback" + item["PATH"]).replace("{", "${request.path[").replace("}", "]}")
item_policy = []
item_query = []
item_header = []
if (item["SCHEMA_BODY_VALIDATION"] != ""):
item_policy.append(oci.apigateway.models.SetHeaderPolicyItem(
name="body_schema_validation",
values=[item["SCHEMA_BODY_VALIDATION"]],
if_exists="APPEND"))
if (item["SCHEMA_QUERY_VALIDATION"] != ""):
item_policy.append(oci.apigateway.models.SetHeaderPolicyItem(
name="query_schema_validation",
values=[item["SCHEMA_QUERY_VALIDATION"]],
if_exists="APPEND"))
try:
for items in ast.literal_eval(item["SCHEMA_QUERY_VALIDATION"]):
if (items["in"] == "query"):
item_query.append(oci.apigateway.models.QueryParameterValidationItem(
name=items["name"],
required=items["required"]
))
if (items["in"] == "header"):
item_header.append(oci.apigateway.models.HeaderValidationItem(
name=items["name"],
required=items["required"]
))
except:
print("NO")
if (item["SCHEMA_BODY_VALIDATION"] != "" or item["SCHEMA_QUERY_VALIDATION"] != ""):
put_logs_response = logging.put_logs(
log_id="ocid1.log.oc1.iad.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
put_logs_details=oci.loggingingestion.models.PutLogsDetails(
specversion="EXAMPLE-specversion-Value",
log_entry_batches=[
oci.loggingingestion.models.LogEntryBatch(
entries=[
oci.loggingingestion.models.LogEntry(
data="callback_url: " + callback_url,
id="ocid1.test.oc1..00000001.EXAMPLE-id-Value")],
source="EXAMPLE-source-Value",
type="EXAMPLE-type-Value")]))
header_transformation = None
query_parameter_validation = None
header_validation = None
if (len(item_policy) >0):
header_transformation=oci.apigateway.models.HeaderTransformationPolicy(
set_headers=oci.apigateway.models.SetHeaderPolicy(
items=item_policy))
if (len(item_query) > 0):
query_parameter_validation=oci.apigateway.models.QueryParameterValidationRequestPolicy(
parameters=item_query
)
if (len(item_header) > 0):
header_validation=oci.apigateway.models.HeaderValidationRequestPolicy(
headers=item_header
)
routes.append(
oci.apigateway.models.ApiSpecificationRoute(
path=item["PATH"],
backend=oci.apigateway.models.HTTPBackend(
type="HTTP_BACKEND",
url=callback_url,
is_ssl_verify_disabled=False),
methods=methods,
request_policies=oci.apigateway.models.ApiSpecificationRouteRequestPolicies(
header_transformations=header_transformation,
query_parameter_validations=query_parameter_validation,
header_validations=header_validation
)))
new_routes.append(
oci.apigateway.models.ApiSpecificationRoute(
path=item["PATH"],
backend=oci.apigateway.models.HTTPBackend(
type="HTTP_BACKEND",
url=item["ENDPOINT"],
is_ssl_verify_disabled=False),
methods=methods,
request_policies=oci.apigateway.models.ApiSpecificationRouteRequestPolicies(
header_transformations=header_transformation,
query_parameter_validations=query_parameter_validation,
header_validations=header_validation
)
))
else:
routes.append(
oci.apigateway.models.ApiSpecificationRoute(
path=item["PATH"],
backend=oci.apigateway.models.HTTPBackend(
type="HTTP_BACKEND",
url=callback_url,
is_ssl_verify_disabled=False),
methods=methods))
new_routes.append(
oci.apigateway.models.ApiSpecificationRoute(
path=item["PATH"],
backend=oci.apigateway.models.HTTPBackend(
type="HTTP_BACKEND",
url=item["ENDPOINT"],
is_ssl_verify_disabled=False),
methods=methods))
if (new_routes != [ ]):
validation_deployment_details=oci.apigateway.models.UpdateDeploymentDetails(
display_name=displayName + "-validation",
specification=oci.apigateway.models.ApiSpecification(
request_policies=oci.apigateway.models.ApiSpecificationRequestPolicies(
rate_limiting=rate_limiting,
authentication=oci.apigateway.models.CustomAuthenticationPolicy(
type="CUSTOM_AUTHENTICATION",
function_id=functionId,
is_anonymous_access_allowed=False,
parameters={
'token': 'request.headers[token]',
'body': 'request.body',
'body_schema_validation': 'request.headers[body_schema_validation]',
'query_schema_validation': 'request.headers[query_schema_validation]',
'opc-request-id': 'request.headers[opc-request-id]'},
cache_key=["token", "opc-request-id"],
validation_failure_policy=oci.apigateway.models.ModifyResponseValidationFailurePolicy(
type="MODIFY_RESPONSE",
response_code="401",
response_message="${request.auth[error]}"
)
)),
routes=new_routes))
create_deployment_details=oci.apigateway.models.CreateDeploymentDetails(
display_name=displayName + "-validation",
compartment_id=compartmentId,
gateway_id=gateway_id,
path_prefix= path_prefix + "validation-callback",
specification=oci.apigateway.models.ApiSpecification(
request_policies=oci.apigateway.models.ApiSpecificationRequestPolicies(
rate_limiting=rate_limiting,
authentication=oci.apigateway.models.CustomAuthenticationPolicy(
type="CUSTOM_AUTHENTICATION",
function_id=functionId,
is_anonymous_access_allowed=False,
parameters={
'token': 'request.headers[token]',
'body': 'request.body',
'body_schema_validation': 'request.headers[body_schema_validation]',
'query_schema_validation': 'request.headers[query_schema_validation]',
'opc-request-id': 'request.headers[opc-request-id]'},
cache_key=["token", "opc-request-id"],
validation_failure_policy=oci.apigateway.models.ModifyResponseValidationFailurePolicy(
type="MODIFY_RESPONSE",
response_code="401",
response_message="${request.auth[error]}"
)
)),
routes=new_routes))
creeateOrUpdateDeployment(compartmendId=compartmentId, displayName=displayName + "-validation", validation_deployment_details=validation_deployment_details, create_deployment_details=create_deployment_details, api_gateway_id=api_gateway_id)
if (routes != [ ]):
# The 1st layer will not authenticate
validation_deployment_details=oci.apigateway.models.UpdateDeploymentDetails(
display_name=displayName,
specification=oci.apigateway.models.ApiSpecification(
request_policies=oci.apigateway.models.ApiSpecificationRequestPolicies(
rate_limiting=rate_limiting),
routes=routes))
create_deployment_details=oci.apigateway.models.CreateDeploymentDetails(
display_name=displayName,
compartment_id=compartmentId,
gateway_id=gateway_id,
path_prefix= path_prefix,
specification=oci.apigateway.models.ApiSpecification(
request_policies=oci.apigateway.models.ApiSpecificationRequestPolicies(
rate_limiting=rate_limiting),
routes=routes))
creeateOrUpdateDeployment(compartmendId=compartmentId, displayName=displayName, validation_deployment_details=validation_deployment_details, create_deployment_details=create_deployment_details, api_gateway_id=api_gateway_id)
def check_endpoint(schemes, endpoint):
if (schemes == ""):
if (endpoint.find("http://") == -1 and endpoint.find("https://") == -1):
endpoint = "https://" + endpoint
else:
if (endpoint.find("http://") == -1 and endpoint.find("https://") == -1):
if (schemes.find("://") == -1):
endpoint = schemes + "://" + endpoint
else:
endpoint = schemes + endpoint
return endpoint
def key_func(k):
return k['PATH']
def verify_path(json_data_list):
list_final = []
for item in json_data_list:
if (item["PATH"] == ""):
for item2 in json_data_list:
if (item2["PATH"] == ""):
list_final.append({
'API_NAME': item2["API_NAME"],
'TYPE': item2["TYPE"],
'ENVIRONMENT': item2["ENVIRONMENT"],
'METHOD': item2["METHOD"],
'PATH_PREFIX': "/",
'PATH': item2["PATH_PREFIX"],
'ENDPOINT': item2["ENDPOINT"],
'SCHEMA_BODY_VALIDATION': item2["SCHEMA_BODY_VALIDATION"],
'SCHEMA_QUERY_VALIDATION': item2["SCHEMA_QUERY_VALIDATION"],
'CONTENT_TYPE': item2["CONTENT_TYPE"]
})
else:
list_final.append({
'API_NAME': item2["API_NAME"],
'TYPE': item2["TYPE"],
'ENVIRONMENT': item2["ENVIRONMENT"],
'METHOD': item2["METHOD"],
'PATH_PREFIX': item2["PATH_PREFIX"],
'PATH': item2["PATH"],
'ENDPOINT': item2["ENDPOINT"],
'SCHEMA_BODY_VALIDATION': item2["SCHEMA_BODY_VALIDATION"],
'SCHEMA_QUERY_VALIDATION': item2["SCHEMA_QUERY_VALIDATION"],
'CONTENT_TYPE': item2["CONTENT_TYPE"]
})
return list_final
return json_data_list
def process_api_spec(api_id, compartmentId, environment, swagger, functionId, host, api_gateway_id, rate_limit):
type = "REST"
config = oci.config.from_file("config")
apigateway_client = oci.apigateway.ApiGatewayClient(config)
logging = oci.loggingingestion.LoggingClient(config)
#-----------------------------------------------------------------
try:
data = swagger
fullSpec = json.loads(data)
version = "3"
try:
version = (fullSpec["swagger"])[:1]
except:
version = (fullSpec["openapi"])[:1]
print("version", version)
if (version == "3"):
endPoint = fullSpec["servers"][0]["url"]
else:
endPoint = fullSpec["host"]
get_api = apigateway_client.get_api_deployment_specification(api_id=api_id, opc_request_id="DEPLOY-0001")
api_spec = json.loads(str(get_api.data))
json_data_list = []
endPointOrigin = endPoint
for spec in api_spec["routes"]:
status = spec["backend"]["status"]
specPath = spec["path"]
for method in spec["methods"]:
METHOD = method.lstrip().upper()
CONTENT_TYPE = ""
if (version == "3"):
if (has_path_endpoint(endPointOrigin)):
endPoint = find_base_endpoint(endPointOrigin)
specPath = (find_base_pathendpoint(endPointOrigin, specPath)).replace("//", "/")
fullEndpoint = (endPoint + specPath + spec["path"]).replace("{", "${request.path[").replace("}", "]}")
FULL_PATH = specPath
ENDPOINT = fullEndpoint
PATH = spec["path"]
PATH_PREFIX = specPath
else:
fullEndpoint = (endPoint + find_base_path(specPath) + find_path(specPath)).replace("{", "${request.path[").replace("}", "]}")
FULL_PATH = specPath
ENDPOINT = fullEndpoint
PATH = find_path(specPath)
PATH_PREFIX = find_base_path(specPath)
else:
schemes = ""
try:
schemes = fullSpec["schemes"][0]
except:
schemes = "https"
fullEndpoint = check_endpoint(schemes, (endPoint + removeLastSlash(fullSpec["basePath"]) + spec["path"]).replace("{", "${request.path[").replace("}", "]}"))
FULL_PATH = fullSpec["basePath"] + spec["path"]
ENDPOINT = fullEndpoint
PATH = spec["path"]
PATH_PREFIX = removeLastSlash(fullSpec["basePath"])
OPERATIONID = fullSpec["paths"][spec["path"]][str(spec["methods"][0]).lower()]["operationId"]
API_NAME = fullSpec["info"]["title"]
if (version == "3"):
try:
try:
reference = str(fullSpec["paths"][spec["path"]][str(spec["methods"][0]).lower()]["requestBody"]["content"]["application/json"]["schema"]["$ref"]).replace("#/components/schemas/", "")
SCHEMA_BODY_VALIDATION = reference + "," + api_id
except:
reference = str(fullSpec["paths"][spec["path"]][str(spec["methods"][0]).lower()]["requestBody"]["content"]["application/json"])
SCHEMA_BODY_VALIDATION = reference
CONTENT_TYPE = "application/json"
except:
SCHEMA_BODY_VALIDATION = ""
else:
SCHEMA_BODY_VALIDATION = ""
try:
reference = str(fullSpec["paths"][spec["path"]][str(spec["methods"][0]).lower()]["parameters"][0]["schema"]["$ref"]).replace("#/definitions/", "")
SCHEMA_BODY_VALIDATION = reference + "," + api_id
CONTENT_TYPE = "application/json"
except:
SCHEMA_BODY_VALIDATION = ""
# 2024-06-26 - Query Parameter
if (version == "3"):
try:
try:
reference = str(fullSpec["paths"][spec["path"]][str(spec["methods"][0]).lower()]["parameters"])
SCHEMA_QUERY_VALIDATION = reference #+ "," + api_id
except:
reference = str(fullSpec["paths"][spec["path"]][str(spec["methods"][0]).lower()]["parameters"])
SCHEMA_QUERY_VALIDATION = reference
CONTENT_TYPE = "application/json"
except:
SCHEMA_QUERY_VALIDATION = ""
else:
SCHEMA_QUERY_VALIDATION = ""
try:
reference = str(fullSpec["paths"][spec["path"]][str(spec["methods"][0]).lower()]["parameters"])
SCHEMA_QUERY_VALIDATION = reference #+ "," + api_id
CONTENT_TYPE = "application/json"
except:
SCHEMA_QUERY_VALIDATION = ""
TYPE = type
ENVIRONMENT = environment
json_data_list.append({
'API_NAME': API_NAME,
'TYPE': TYPE,
'ENVIRONMENT': ENVIRONMENT,
'METHOD': METHOD,
'PATH_PREFIX': PATH_PREFIX,
'PATH': PATH,
'ENDPOINT': ENDPOINT,
'SCHEMA_BODY_VALIDATION': SCHEMA_BODY_VALIDATION,
'SCHEMA_QUERY_VALIDATION': SCHEMA_QUERY_VALIDATION,
'CONTENT_TYPE': CONTENT_TYPE
})
print(API_NAME, TYPE, ENVIRONMENT, METHOD, PATH_PREFIX, PATH, ENDPOINT, SCHEMA_BODY_VALIDATION, SCHEMA_QUERY_VALIDATION, CONTENT_TYPE)
put_logs_response = logging.put_logs(
log_id="ocid1.log.oc1.iad.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
put_logs_details=oci.loggingingestion.models.PutLogsDetails(
specversion="EXAMPLE-specversion-Value",
log_entry_batches=[
oci.loggingingestion.models.LogEntryBatch(
entries=[
oci.loggingingestion.models.LogEntry(
data="api deployment: " + json.dumps({
'API_NAME': API_NAME,
'TYPE': TYPE,
'ENVIRONMENT': ENVIRONMENT,
'METHOD': METHOD,
'PATH_PREFIX': PATH_PREFIX,
'PATH': PATH,
'ENDPOINT': ENDPOINT,
'SCHEMA_BODY_VALIDATION': SCHEMA_BODY_VALIDATION,
'SCHEMA_QUERY_VALIDATION': SCHEMA_QUERY_VALIDATION,
'CONTENT_TYPE': CONTENT_TYPE
}),
id="ocid1.test.oc1..00000001.EXAMPLE-id-Value")],
source="EXAMPLE-source-Value",
type="EXAMPLE-type-Value")]))
json_data_list = verify_path(json_data_list)
payload = json.dumps(json_data_list)
put_logs_response = logging.put_logs(
log_id="ocid1.log.oc1.iad.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
put_logs_details=oci.loggingingestion.models.PutLogsDetails(
specversion="EXAMPLE-specversion-Value",
log_entry_batches=[
oci.loggingingestion.models.LogEntryBatch(
entries=[
oci.loggingingestion.models.LogEntry(
data="json_data_list: " + payload,
id="ocid1.test.oc1..00000001.EXAMPLE-id-Value")],
source="EXAMPLE-source-Value",
type="EXAMPLE-type-Value")]))
payload = json.loads(json.dumps(json_data_list))
print(payload)
applyAuthApi(compartmentId=compartmentId, displayName=API_NAME, payload=payload, functionId=functionId, host=host, api_gateway_id=api_gateway_id, rate_limit=rate_limit)
except(Exception) as ex:
raise
def DateEncoder(obj):
if isinstance(obj, datetime.datetime):
return obj.strftime('%Y-%m-%d')
def is_json(swagger):
try:
body = json.loads(swagger)
return True
except:
try:
yaml_object = yaml.safe_load(swagger) # yaml_object will be a list or a dict
s = json.dumps(yaml_object, indent=2, default=DateEncoder)
return False
except:
return False
def convert_json(swagger):
yaml_object = yaml.safe_load(swagger) # yaml_object will be a list or a dict
return json.dumps(yaml_object, indent=2, default=DateEncoder)
###
def handler(ctx, data: io.BytesIO = None):
config = oci.config.from_file("config")
logging = oci.loggingingestion.LoggingClient(config)
# functions context variables
app_context = dict(ctx.Config())
jsonData = ""
options = getOptions()
try:
header = json.loads(data.getvalue().decode('utf-8'))["data"]
url = options["BaseUrl"]
body = dict(json.loads(data.getvalue().decode('utf-8')).get("data"))["body"]
# body content
swagger = str(body)
if (is_json(swagger)):
body = json.loads(body)
else:
body = json.loads(convert_json(swagger))
swagger = convert_json(swagger)
environment = "DEV"
# header values
access_token = header["token"]
api_id = header["apiId"]
host = header["host_name"]
compartmentId = header['apiCompartmentId']
functionId = header['functionId']
api_gateway_id = header['apiGatewayId']
rate_limit = header['rateLimit']
authorization = auth_idcs(access_token, url, options["ClientId"], options["ClientSecret"])
try:
if (authorization.json().get("active") != True):
return response.Response(
ctx,
status_code=401,
response_data=json.dumps({"active": False, "wwwAuthenticate": jsonData})
)
except(Exception) as ex1:
jsonData = 'error parsing json payload: ' + str(ex1)
put_logs_response = logging.put_logs(
log_id="ocid1.log.oc1.iad.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
put_logs_details=oci.loggingingestion.models.PutLogsDetails(
specversion="EXAMPLE-specversion-Value",
log_entry_batches=[
oci.loggingingestion.models.LogEntryBatch(
entries=[
oci.loggingingestion.models.LogEntry(
data="error(1): " + jsonData,
id="ocid1.test.oc1..00000001.EXAMPLE-id-Value")],
source="EXAMPLE-source-Value",
type="EXAMPLE-type-Value")]))
return response.Response(
ctx,
status_code=401,
response_data=json.dumps({"active": False, "wwwAuthenticate": jsonData})
)
# Create API spec
process_api_spec(api_id=api_id, compartmentId=compartmentId, environment=environment, swagger=swagger, functionId=functionId, host=host, api_gateway_id=api_gateway_id, rate_limit=rate_limit)
rdata = json.dumps({
"active": True,
"context": {
"environment": environment,
"api_id": api_id
}})
return response.Response(
ctx, response_data=rdata,
status_code=200,
headers={"Content-Type": "application/json", "apiId": api_id, "environment": environment}
)
except(Exception) as ex:
jsonData = 'error parsing json payload: ' + str(ex)
put_logs_response = logging.put_logs(
log_id="ocid1.log.oc1.iad.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
put_logs_details=oci.loggingingestion.models.PutLogsDetails(
specversion="EXAMPLE-specversion-Value",
log_entry_batches=[
oci.loggingingestion.models.LogEntryBatch(
entries=[
oci.loggingingestion.models.LogEntry(
data="error(2): " + jsonData,
id="ocid1.test.oc1..00000001.EXAMPLE-id-Value")],
source="EXAMPLE-source-Value",
type="EXAMPLE-type-Value")]))
pass
return response.Response(
ctx,
status_code=401,
response_data=json.dumps({"active": False, "wwwAuthenticate": jsonData})
)

View File

@@ -0,0 +1,8 @@
schema_version: 20180708
name: apply-validation-api
version: 0.0.512
runtime: python
build_image: fnproject/python:3.9-dev
run_image: fnproject/python:3.9
entrypoint: /python/bin/fdk /function/func.py handler
memory: 256

View File

@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
+PlyICemh7G2GNTwleCu61CVYaVcXxZG8LQkHAHCykuq+R7d6lwxkHQTIyKmUj+o
6BCWIQKBgQCAHaQZ4p/XDHVqajity2YCauQKM7eD0cyUnY9h+MKkih1g7brU43DR
u1yJoOnQzddapVr7yVXMl874mU+Jgm7arh+XRL8WuV2RtltKurBhYqtSwiGg0JFx
pRZm1D73NtXRaTSSwYdXakQjPb4FaFdwBouxVylP6GSy4kI2iva3og==
-----END RSA PRIVATE KEY-----

View File

@@ -0,0 +1,9 @@
fdk>=0.1.54
requests
oci
cryptography
six
PyJWT
py3_lru_cache
simplejson
PyYAML

169
files/authApi/Redaction.py Normal file
View File

@@ -0,0 +1,169 @@
import re
# This class does not work with numeric attributes, only with String
# Use the method redact and put your patterns as the example:
# SENSITIVE_PATTERNS = [
# r"\d{3}-\d{2}-\d{4}", # Social Security Number (SSN) pattern
# r"\d{4}[-\s]\d{4}[-\s]\d{4}[-\s]\d{4}", # Credit card number pattern
# r"\(?\d{3}\)?[-\s.]?\d{3}[-\s.]?\d{4}", # Phone number
# r"(0[1-9]|1[0-2])[-/.](0[1-9]|[12][0-9]|3[01])[-/.](19|20)\d\d", # date of birth
# r"((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)", # IP address
# r"[a-zA-Z0-9]{32}" # API key
# ]
#
# ATTRIBUTE_PATTERNS = [
# "nome",
# "cpf",
# "teste",
# "valor",
# "original",
# "type",
# "solicitacaoPagador",
# "chave",
# "description",
# "items",
# "example"
# ]
class Redaction():
def repl_value2(self, message, pattern):
flag_aspas = False
flag_attribute = False
# flag_vezes = 0
flag_dois_pontos = False
flag_colchetes = False
i = 0
z = pattern
str_acc = ""
while (i < len(message)):
try:
if (message[i:i + len(z)] == z and (message[i + len(z):i + len(z) + 1] == "'" or message[i + len(z):i + len(z) + 1] == "\"")):
flag_attribute = True
flag_aspas = True
except:
print("except")
if (message[i] == ":" and not flag_aspas and flag_attribute):
flag_dois_pontos = True
if (flag_aspas and message[i] != "'" and message[i] != "\"" and flag_attribute and flag_dois_pontos):
str_acc = str_acc + message[i]
message = message[0:i] + "*" + message[i + 1:len(message) + i]
if (message[i] == "{" and flag_dois_pontos and not flag_aspas):
flag_attribute = False
flag_dois_pontos = False
flag_aspas = False
flag_colchetes = False
if ((message[i] == "}" or message[i] == "]") and not flag_aspas):
flag_attribute = False
flag_dois_pontos = False
flag_aspas = False
flag_colchetes = False
str_acc = ""
if (flag_dois_pontos and not flag_aspas and message[i] == "["):
flag_colchetes = True
if (message[i] == "," and not flag_aspas and not flag_colchetes):
flag_attribute = False
flag_dois_pontos = False
flag_aspas = False
flag_colchetes = False
str_acc = ""
if ((message[i] == "'" or message[i] == "\"")):
flag_aspas = not flag_aspas
if (flag_aspas == False and flag_attribute == True and flag_dois_pontos and len(str_acc) > 0 and not flag_colchetes):
flag_attribute = False
flag_dois_pontos = False
str_acc = ""
i = i + 1
return message
def repl_value(self, message, pattern):
flag_aspas = False
flag_attribute = False
# flag_vezes = 0
flag_dois_pontos = False
flag_colchetes = False
flag_string = True
flag_descobre_tipo = False
i = 0
z = pattern
str_acc = ""
while (i < len(message)):
try:
if (message[i:i + len(z)] == z and (message[i + len(z):i + len(z) + 1] == "'" or message[i + len(z):i + len(z) + 1] == "\"")):
flag_attribute = True
flag_aspas = True
except:
print("except")
if (message[i] == ":" and not flag_aspas and flag_attribute):
flag_dois_pontos = True
flag_descobre_tipo = True
if ((flag_aspas and message[i] != "'" and message[i] != "\"" and flag_attribute and flag_dois_pontos)
or (message[i] in "0123456789." and flag_attribute and flag_dois_pontos and not flag_string)):
str_acc = str_acc + message[i]
message = message[0:i] + "*" + message[i + 1:len(message) + i]
if (message[i] == "{" and flag_dois_pontos and not flag_aspas):
flag_attribute = False
flag_dois_pontos = False
flag_aspas = False
flag_colchetes = False
flag_descobre_tipo = False
flag_string = True
if ((message[i] == "}" or message[i] == "]") and not flag_aspas):
flag_attribute = False
flag_dois_pontos = False
flag_aspas = False
flag_colchetes = False
flag_descobre_tipo = False
flag_string = True
str_acc = ""
if ((message[i] == "}" or message[i] == "]") and not flag_aspas and not flag_string):
flag_attribute = False
flag_dois_pontos = False
flag_aspas = False
flag_colchetes = False
flag_descobre_tipo = False
flag_string = True
str_acc = ""
if (flag_dois_pontos and not flag_aspas and message[i] == "["):
flag_colchetes = True
if (message[i] == "," and not flag_aspas and not flag_colchetes and not flag_string):
flag_attribute = False
flag_dois_pontos = False
flag_aspas = False
flag_colchetes = False
flag_descobre_tipo = False
flag_string = True
str_acc = ""
if ((message[i] == "'" or message[i] == "\"")):
flag_aspas = not flag_aspas
if (flag_descobre_tipo):
flag_string = True
flag_descobre_tipo = False
if (message[i] in "01234567890." and flag_descobre_tipo):
flag_string = False
flag_descobre_tipo = False
str_acc = str_acc + message[i]
message = message[0:i] + "*" + message[i + 1:len(message) + i]
if (flag_aspas == False and flag_attribute == True and flag_dois_pontos and len(str_acc) > 0 and not flag_colchetes and flag_string):
flag_attribute = False
flag_dois_pontos = False
flag_descobre_tipo = False
str_acc = ""
i = i + 1
return message
def repl(self, attribute_pattern, message):
msg_return = []
for pattern in attribute_pattern:
message = self.repl_value(message, pattern)
return message
def change(self, sensitive_pattern, message):
for pattern in sensitive_pattern:
message = re.sub(pattern, "<REDACTED>", message)
return message
def redact(self, sensitive_pattern, attribute_pattern, message):
message = self.repl(attribute_pattern, message)
message = self.change(sensitive_pattern, message)
return message

348
files/authApi/authRPApi.py Normal file
View File

@@ -0,0 +1,348 @@
import base64
import json
import io
from fdk import response
import oci
import requests
import time
from openapi_schema_validator import validate
import os
import ast
from bravado_core.spec import Spec
from bravado_core.validate import validate_object
from datetime import datetime
from random import randrange
import Redaction
SENSITIVE_PATTERNS = [
r"\d{3}-\d{2}-\d{4}", # Social Security Number (SSN) pattern
r"\d{4}[-\s]\d{4}[-\s]\d{4}[-\s]\d{4}", # Credit card number pattern
r"\(?\d{3}\)?[-\s.]?\d{3}[-\s.]?\d{4}", # Phone number
r"(0[1-9]|1[0-2])[-/.](0[1-9]|[12][0-9]|3[01])[-/.](19|20)\d\d", # date of birth
r"((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)", # IP address
r"[a-zA-Z0-9]{32}", # API key
r"^(\d{5}.\d{2}-\d)|(\d{8})$"
]
ATTRIBUTE_PATTERNS = [
"documentNumber",
"documentCustodyAgentAccountCode",
"isinCode",
"payingAgentAccountCode",
"registrationParticipantAccountCode",
"nome",
"$ref",
"cpf",
"teste",
"valor",
"original",
"type",
"solicitacaoPagador",
"expiracao",
"chave",
"description",
"items",
"required",
"x-scope",
"maxLength"
]
#### IDCS Routines
#### https://docs.oracle.com/en/learn/apigw-modeldeployment/index.html#introduction
#### https://docs.oracle.com/en/learn/migrate-api-to-api-gateway/#introduction
def auth_idcs(token, url, clientID, secretID):
url = url + "/oauth2/v1/introspect"
auth = clientID + ":" + secretID
auth_bytes = auth.encode("ascii")
auth_base64_bytes = base64.b64encode(auth_bytes)
auth_base64_message = auth_base64_bytes.decode("ascii")
headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Basic ' + auth_base64_message
}
payload = "token=" + token
response = requests.request("POST", url, headers=headers, data=payload)
return response
def beautify_str(str_msg):
msg = str(str_msg.encode('unicode_escape').decode("utf-8")).replace("\\n", " ")
split_str = msg.split()
return " ".join(split_str)
###
def replace_regex(variavel):
variavel = variavel.replace("\\d", "[0-9]")
variavel = variavel.replace("\\D", "[^0-9]")
variavel = variavel.replace("\\.", "[.]")
variavel = variavel.replace("\\w", "[a-zA-Z0-9_]")
variavel = variavel.replace("\\W", "[^a-zA-Z0-9_]")
variavel = variavel.replace("/^", "^")
variavel = variavel.replace("$/", "$")
return variavel
def remove_property(dictionary, property_name):
keys_to_delete = [key for key in dictionary if key == property_name]
for key in keys_to_delete:
if ("\\s" in dictionary[key] or "\\S" in dictionary[key] or "\\w" in dictionary[key] or "\\W" in dictionary[key]
or "\\b" in dictionary[key] or "\\B" in dictionary[key] or "\\A" in dictionary[key] or "\\Z" in dictionary[key]):
del dictionary[key]
else:
dictionary[key] = replace_regex(dictionary[key])
for value in dictionary.values():
if isinstance(value, dict):
remove_property(value, property_name)
elif isinstance(value, list):
for item in value:
if isinstance(item, dict):
remove_property(item, property_name)
return dictionary
def count_attributes(json_data):
count = 0
for key, value in json_data.items():
count += 1
if isinstance(value, dict):
count += count_attributes(value)
return count
def read_secret_value(secret_client, secret_id):
response = secret_client.get_secret_bundle(secret_id)
base64_Secret_content = response.data.secret_bundle_content.content
base64_secret_bytes = base64_Secret_content.encode('ascii')
base64_message_bytes = base64.b64decode(base64_secret_bytes)
secret_content = base64_message_bytes.decode('ascii')
return secret_content
def handler(ctx, data: io.BytesIO = None):
config = oci.config.from_file("config")
logging = oci.loggingingestion.LoggingClient(config)
# functions context variables
app_context = dict(ctx.Config())
jsonData = ""
try:
header = json.loads(data.getvalue().decode('utf-8'))["data"]
# IDCS Validation
url = "https://idcs-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.identity.oraclecloud.com"
ClientId = read_secret_value(secret_client, "ocid1.vaultsecret.oc1.iad.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
ClientSecret = read_secret_value(secret_client, "ocid1.vaultsecret.oc1.iad.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
# JSON Items counter
jsonData = dict(json.loads(data.getvalue().decode('utf-8')).get("data"))["body"]
jsonData = dict(json.loads(jsonData))
c = count_attributes(jsonData)
if (c > 21):
rdata = json.dumps({
"active": False,
"context": {
"status_code": 401,
"message": "JSON exception",
"error": "JSON exception",
}})
return response.Response(
ctx,
status_code=401,
response_data=rdata
)
try:
body = dict(json.loads(data.getvalue().decode('utf-8')).get("data"))["body"]
body = json.loads(body)
except:
body = None
# body content
body_schema_validation = None
try:
if (".apigatewayapi." not in header["body_schema_validation"]):
body_schema_validation = ast.literal_eval(header["body_schema_validation"])
else:
body_schema_validation = header["body_schema_validation"]
except:
body_schema_validation = None
# header values
access_token = header["token"]
authorization = auth_idcs(access_token, url, ClientId, ClientSecret)
try:
if (authorization.json().get("active") != True):
return response.Response(
ctx,
status_code=401,
response_data=json.dumps({"active": False, "wwwAuthenticate": jsonData})
)
except(Exception) as ex1:
jsonData = 'error parsing json payload: ' + str(ex1)
put_logs_response = logging.put_logs(
log_id="ocid1.log.oc1.iad.amaaaaaanamaaaaaanamaaaaaanamaaaaaanamaaaaaanamaaaaaan",
put_logs_details=oci.loggingingestion.models.PutLogsDetails(
specversion="EXAMPLE-specversion-Value",
log_entry_batches=[
oci.loggingingestion.models.LogEntryBatch(
entries=[
oci.loggingingestion.models.LogEntry(
data="error(a): " + jsonData,
id="ocid1.test.oc1..00000001.EXAMPLE-id-Value")],
source="EXAMPLE-source-Value",
type="EXAMPLE-type-Value")]))
rdata = json.dumps({
"active": False,
"context": {
"status_code": 401,
"message": "Unauthorized",
"body": body,
"body_schema_validation": json.dumps(body_schema_validation),
"error": str(ex1)
}})
return response.Response(
ctx,
status_code=401,
response_data=rdata
)
rdata = json.dumps({
"active": True,
"context": {
"body": body,
"body_schema_validation": json.dumps(body_schema_validation)
}})
# Validate API spec
if (body_schema_validation != None):
if (".apigatewayapi." not in header["body_schema_validation"]):
# Com validacao direto por propriedades (sem schemas e referencias)
try:
validate(body, body_schema_validation["schema"])
return response.Response(
ctx, response_data=rdata,
status_code=200,
headers={"Content-Type": "application/json", "body": json.dumps(body)}
)
except(Exception) as ex2:
error_msg = beautify_str(str(ex2))
redaction = Redaction.Redaction()
error_msg = redaction.redact(sensitive_pattern=SENSITIVE_PATTERNS, attribute_pattern=ATTRIBUTE_PATTERNS, message=error_msg)
put_logs_response = logging.put_logs(
log_id="ocid1.log.oc1.iad.amaaaaaanamaaaaaanamaaaaaanamaaaaaanamaaaaaanamaaaaaan",
put_logs_details=oci.loggingingestion.models.PutLogsDetails(
specversion="EXAMPLE-specversion-Value",
log_entry_batches=[
oci.loggingingestion.models.LogEntryBatch(
entries=[
oci.loggingingestion.models.LogEntry(
data="error(b): " + error_msg,
id="ocid1.test.oc1..00000001.EXAMPLE-id-Value")],
source="EXAMPLE-source-Value",
type="EXAMPLE-type-Value")]))
rdata = json.dumps({
"active": False,
"context": {
"status_code": 401,
"message": "Unauthorized",
"body": body,
"body_schema_validation": json.dumps(body_schema_validation),
"error": error_msg
}})
return response.Response(
ctx,
status_code=401,
response_data=rdata
)
else:
# Com schema de validação - Tanto swagger como Open API 3
try:
bravado_config = {
'validate_swagger_spec': False,
'validate_requests': False,
'validate_responses': False,
'use_models': True,
}
contents = body_schema_validation.split(",")
apigateway_client = oci.apigateway.ApiGatewayClient(config)
api_spec = apigateway_client.get_api_content(contents[1])
spec_dict = json.loads(api_spec.data.content)
spec_dict = remove_property(spec_dict, "pattern")
spec = Spec.from_dict(spec_dict, config=bravado_config)
try:
schema = spec_dict["definitions"][contents[0]]
except:
schema = spec_dict["components"]["schemas"][contents[0]]
schema_without_pattern = remove_property(schema, "pattern")
validate_object(spec, schema_without_pattern, body)
except (Exception) as ex3:
error_msg = beautify_str(str(ex3))
redaction = Redaction.Redaction()
error_msg = redaction.redact(sensitive_pattern=SENSITIVE_PATTERNS, attribute_pattern=ATTRIBUTE_PATTERNS, message=error_msg)
put_logs_response = logging.put_logs(
log_id="ocid1.log.oc1.iad.amaaaaaanamaaaaaanamaaaaaanamaaaaaanamaaaaaanamaaaaaan",
put_logs_details=oci.loggingingestion.models.PutLogsDetails(
specversion="EXAMPLE-specversion-Value",
log_entry_batches=[
oci.loggingingestion.models.LogEntryBatch(
entries=[
oci.loggingingestion.models.LogEntry(
data="error(b): " + error_msg,
id="ocid1.test.oc1..00000001.EXAMPLE-id-Value")],
source="EXAMPLE-source-Value",
type="EXAMPLE-type-Value")]))
rdata = json.dumps({
"active": False,
"context": {
"status_code": 401,
"message": "Unauthorized",
"body": body,
"body_schema_validation": json.dumps(body_schema_validation),
"error": error_msg
}})
return response.Response(
ctx,
status_code=401,
response_data=rdata
)
return response.Response(
ctx, response_data=rdata,
status_code=200,
headers={"Content-Type": "application/json", "body_schema_validation": body_schema_validation, "body": json.dumps(body)}
)
except(Exception) as ex:
jsonData = 'error parsing json payload: ' + str(ex)
put_logs_response = logging.put_logs(
log_id="ocid1.log.oc1.iad.amaaaaaanamaaaaaanamaaaaaanamaaaaaanamaaaaaanamaaaaaan",
put_logs_details=oci.loggingingestion.models.PutLogsDetails(
specversion="EXAMPLE-specversion-Value",
log_entry_batches=[
oci.loggingingestion.models.LogEntryBatch(
entries=[
oci.loggingingestion.models.LogEntry(
data="error(c): " + jsonData,
id="ocid1.test.oc1..00000001.EXAMPLE-id-Value")],
source="EXAMPLE-source-Value",
type="EXAMPLE-type-Value")]))
pass
return response.Response(
ctx,
status_code=401,
response_data=json.dumps({"active": False, "wwwAuthenticate": jsonData})
)

7
files/authApi/config Normal file
View File

@@ -0,0 +1,7 @@
[DEFAULT]
user=ocid1.user.oc1..aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
fingerprint=36:04:63:cd:36:04:63:cd:36:04:63:cd:36:04:63:cd
key_file=oci_api_key.pem
tenancy=ocid1.tenancy.oc1..aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
region=us-ashburn-1

12
files/authApi/config.json Normal file
View File

@@ -0,0 +1,12 @@
{
"ClientId" : "0b8cd92bb60b8cd92bb60b8cd92bb6",
"ClientSecret" : "41964196-2cfb-2cfb-2cfb-63246a63246a",
"BaseUrl" : "https://idcs-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.identity.oraclecloud.com",
"AudienceServiceUrl" : "https://idcs-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.identity.oraclecloud.com",
"scope" : "aaaaaaaaaaaaaaaaaaaaaaa.apigateway.us-ashburn-1.oci.customer-oci.com/super_scope",
"TokenIssuer" : "https://identity.oraclecloud.com",
"redirectURL": "http://localhost:8000/callback",
"logoutSufix":"/oauth2/v1/userlogout",
"LogLevel":"INFO",
"ConsoleLog":"True"
}

340
files/authApi/func.py Normal file
View File

@@ -0,0 +1,340 @@
import base64
import json
import io
from fdk import response
import oci
import requests
import time
from openapi_schema_validator import validate
import os
import ast
from bravado_core.spec import Spec
from bravado_core.validate import validate_object
from datetime import datetime
from random import randrange
import Redaction
SENSITIVE_PATTERNS = [
r"\d{3}-\d{2}-\d{4}", # Social Security Number (SSN) pattern
r"\d{4}[-\s]\d{4}[-\s]\d{4}[-\s]\d{4}", # Credit card number pattern
r"\(?\d{3}\)?[-\s.]?\d{3}[-\s.]?\d{4}", # Phone number
r"(0[1-9]|1[0-2])[-/.](0[1-9]|[12][0-9]|3[01])[-/.](19|20)\d\d", # date of birth
r"((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)", # IP address
r"[a-zA-Z0-9]{32}", # API key
r"^(\d{5}.\d{2}-\d)|(\d{8})$"
]
ATTRIBUTE_PATTERNS = [
"documentNumber",
"documentCustodyAgentAccountCode",
"isinCode",
"payingAgentAccountCode",
"registrationParticipantAccountCode",
"nome",
"$ref",
"cpf",
"teste",
"valor",
"original",
"type",
"solicitacaoPagador",
"expiracao",
"chave",
"description",
"items",
"required",
"x-scope",
"maxLength"
]
#### IDCS Routines
#### https://docs.oracle.com/en/learn/apigw-modeldeployment/index.html#introduction
#### https://docs.oracle.com/en/learn/migrate-api-to-api-gateway/#introduction
def auth_idcs(token, url, clientID, secretID):
url = url + "/oauth2/v1/introspect"
auth = clientID + ":" + secretID
auth_bytes = auth.encode("ascii")
auth_base64_bytes = base64.b64encode(auth_bytes)
auth_base64_message = auth_base64_bytes.decode("ascii")
headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Basic ' + auth_base64_message
}
payload = "token=" + token
response = requests.request("POST", url, headers=headers, data=payload)
return response
def beautify_str(str_msg):
msg = str(str_msg.encode('unicode_escape').decode("utf-8")).replace("\\n", " ")
split_str = msg.split()
return " ".join(split_str)
###
def replace_regex(variavel):
variavel = variavel.replace("\\d", "[0-9]")
variavel = variavel.replace("\\D", "[^0-9]")
variavel = variavel.replace("\\.", "[.]")
variavel = variavel.replace("\\w", "[a-zA-Z0-9_]")
variavel = variavel.replace("\\W", "[^a-zA-Z0-9_]")
variavel = variavel.replace("/^", "^")
variavel = variavel.replace("$/", "$")
return variavel
def remove_property(dictionary, property_name):
keys_to_delete = [key for key in dictionary if key == property_name]
for key in keys_to_delete:
if ("\\s" in dictionary[key] or "\\S" in dictionary[key] or "\\w" in dictionary[key] or "\\W" in dictionary[key]
or "\\b" in dictionary[key] or "\\B" in dictionary[key] or "\\A" in dictionary[key] or "\\Z" in dictionary[key]):
del dictionary[key]
else:
dictionary[key] = replace_regex(dictionary[key])
for value in dictionary.values():
if isinstance(value, dict):
remove_property(value, property_name)
elif isinstance(value, list):
for item in value:
if isinstance(item, dict):
remove_property(item, property_name)
return dictionary
def count_attributes(json_data):
count = 0
for key, value in json_data.items():
count += 1
if isinstance(value, dict):
count += count_attributes(value)
return count
def handler(ctx, data: io.BytesIO = None):
config = oci.config.from_file("config")
logging = oci.loggingingestion.LoggingClient(config)
# functions context variables
app_context = dict(ctx.Config())
jsonData = ""
try:
header = json.loads(data.getvalue().decode('utf-8'))["data"]
# IDCS Validation
url = "https://idcs-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.identity.oraclecloud.com"
ClientId = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
ClientSecret = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
# JSON Items counter
jsonData = dict(json.loads(data.getvalue().decode('utf-8')).get("data"))["body"]
jsonData = dict(json.loads(jsonData))
c = count_attributes(jsonData)
if (c > 21):
rdata = json.dumps({
"active": False,
"context": {
"status_code": 401,
"message": "JSON exception",
"error": "JSON exception",
}})
return response.Response(
ctx,
status_code=401,
response_data=rdata
)
try:
body = dict(json.loads(data.getvalue().decode('utf-8')).get("data"))["body"]
body = json.loads(body)
except:
body = None
# body content
body_schema_validation = None
try:
if (".apigatewayapi." not in header["body_schema_validation"]):
body_schema_validation = ast.literal_eval(header["body_schema_validation"])
else:
body_schema_validation = header["body_schema_validation"]
except:
body_schema_validation = None
# header values
access_token = header["token"]
authorization = auth_idcs(access_token, url, ClientId, ClientSecret)
try:
if (authorization.json().get("active") != True):
return response.Response(
ctx,
status_code=401,
response_data=json.dumps({"active": False, "wwwAuthenticate": jsonData})
)
except(Exception) as ex1:
jsonData = 'error parsing json payload: ' + str(ex1)
put_logs_response = logging.put_logs(
log_id="ocid1.log.oc1.iad.amaaaaaanamaaaaaanamaaaaaanamaaaaaanamaaaaaanamaaaaaan",
put_logs_details=oci.loggingingestion.models.PutLogsDetails(
specversion="EXAMPLE-specversion-Value",
log_entry_batches=[
oci.loggingingestion.models.LogEntryBatch(
entries=[
oci.loggingingestion.models.LogEntry(
data="error(a): " + jsonData,
id="ocid1.test.oc1..00000001.EXAMPLE-id-Value")],
source="EXAMPLE-source-Value",
type="EXAMPLE-type-Value")]))
rdata = json.dumps({
"active": False,
"context": {
"status_code": 401,
"message": "Unauthorized",
"body": body,
"body_schema_validation": json.dumps(body_schema_validation),
"error": str(ex1)
}})
return response.Response(
ctx,
status_code=401,
response_data=rdata
)
rdata = json.dumps({
"active": True,
"context": {
"body": body,
"body_schema_validation": json.dumps(body_schema_validation)
}})
# Validate API spec
if (body_schema_validation != None):
if (".apigatewayapi." not in header["body_schema_validation"]):
# Com validacao direto por propriedades (sem schemas e referencias)
try:
validate(body, body_schema_validation["schema"])
return response.Response(
ctx, response_data=rdata,
status_code=200,
headers={"Content-Type": "application/json", "body": json.dumps(body)}
)
except(Exception) as ex2:
error_msg = beautify_str(str(ex2))
redaction = Redaction.Redaction()
error_msg = redaction.redact(sensitive_pattern=SENSITIVE_PATTERNS, attribute_pattern=ATTRIBUTE_PATTERNS, message=error_msg)
put_logs_response = logging.put_logs(
log_id="ocid1.log.oc1.iad.amaaaaaanamaaaaaanamaaaaaanamaaaaaanamaaaaaanamaaaaaan",
put_logs_details=oci.loggingingestion.models.PutLogsDetails(
specversion="EXAMPLE-specversion-Value",
log_entry_batches=[
oci.loggingingestion.models.LogEntryBatch(
entries=[
oci.loggingingestion.models.LogEntry(
data="error(b): " + error_msg,
id="ocid1.test.oc1..00000001.EXAMPLE-id-Value")],
source="EXAMPLE-source-Value",
type="EXAMPLE-type-Value")]))
rdata = json.dumps({
"active": False,
"context": {
"status_code": 401,
"message": "Unauthorized",
"body": body,
"body_schema_validation": json.dumps(body_schema_validation),
"error": error_msg
}})
return response.Response(
ctx,
status_code=401,
response_data=rdata
)
else:
# Com schema de validação - Tanto swagger como Open API 3
try:
bravado_config = {
'validate_swagger_spec': False,
'validate_requests': False,
'validate_responses': False,
'use_models': True,
}
contents = body_schema_validation.split(",")
apigateway_client = oci.apigateway.ApiGatewayClient(config)
api_spec = apigateway_client.get_api_content(contents[1])
spec_dict = json.loads(api_spec.data.content)
spec_dict = remove_property(spec_dict, "pattern")
spec = Spec.from_dict(spec_dict, config=bravado_config)
try:
schema = spec_dict["definitions"][contents[0]]
except:
schema = spec_dict["components"]["schemas"][contents[0]]
schema_without_pattern = remove_property(schema, "pattern")
validate_object(spec, schema_without_pattern, body)
except (Exception) as ex3:
error_msg = beautify_str(str(ex3))
redaction = Redaction.Redaction()
error_msg = redaction.redact(sensitive_pattern=SENSITIVE_PATTERNS, attribute_pattern=ATTRIBUTE_PATTERNS, message=error_msg)
put_logs_response = logging.put_logs(
log_id="ocid1.log.oc1.iad.amaaaaaanamaaaaaanamaaaaaanamaaaaaanamaaaaaanamaaaaaan",
put_logs_details=oci.loggingingestion.models.PutLogsDetails(
specversion="EXAMPLE-specversion-Value",
log_entry_batches=[
oci.loggingingestion.models.LogEntryBatch(
entries=[
oci.loggingingestion.models.LogEntry(
data="error(b): " + error_msg,
id="ocid1.test.oc1..00000001.EXAMPLE-id-Value")],
source="EXAMPLE-source-Value",
type="EXAMPLE-type-Value")]))
rdata = json.dumps({
"active": False,
"context": {
"status_code": 401,
"message": "Unauthorized",
"body": body,
"body_schema_validation": json.dumps(body_schema_validation),
"error": error_msg
}})
return response.Response(
ctx,
status_code=401,
response_data=rdata
)
return response.Response(
ctx, response_data=rdata,
status_code=200,
headers={"Content-Type": "application/json", "body_schema_validation": body_schema_validation, "body": json.dumps(body)}
)
except(Exception) as ex:
jsonData = 'error parsing json payload: ' + str(ex)
put_logs_response = logging.put_logs(
log_id="ocid1.log.oc1.iad.amaaaaaanamaaaaaanamaaaaaanamaaaaaanamaaaaaanamaaaaaan",
put_logs_details=oci.loggingingestion.models.PutLogsDetails(
specversion="EXAMPLE-specversion-Value",
log_entry_batches=[
oci.loggingingestion.models.LogEntryBatch(
entries=[
oci.loggingingestion.models.LogEntry(
data="error(c): " + jsonData,
id="ocid1.test.oc1..00000001.EXAMPLE-id-Value")],
source="EXAMPLE-source-Value",
type="EXAMPLE-type-Value")]))
pass
return response.Response(
ctx,
status_code=401,
response_data=json.dumps({"active": False, "wwwAuthenticate": jsonData})
)

8
files/authApi/func.yaml Normal file
View File

@@ -0,0 +1,8 @@
schema_version: 20180708
name: auth-api
version: 0.0.523
runtime: python
build_image: fnproject/python:3.9-dev
run_image: fnproject/python:3.9
entrypoint: /python/bin/fdk /function/func.py handler
memory: 256

View File

@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
+PlyICemh7G2GNTwleCu61CVYaVcXxZG8LQkHAHCykuq+R7d6lwxkHQTIyKmUj+o
6BCWIQKBgQCAHaQZ4p/XDHVqajity2YCauQKM7eD0cyUnY9h+MKkih1g7brU43DR
u1yJoOnQzddapVr7yVXMl874mU+Jgm7arh+XRL8WuV2RtltKurBhYqtSwiGg0JFx
pRZm1D73NtXRaTSSwYdXakQjPb4FaFdwBouxVylP6GSy4kI2iva3og==
-----END RSA PRIVATE KEY-----

View File

@@ -0,0 +1,10 @@
fdk>=0.1.54
requests
oci
cryptography
six
PyJWT
py3_lru_cache
simplejson
openapi-schema-validator
bravado-core

7
files/createapi/config Normal file
View File

@@ -0,0 +1,7 @@
[DEFAULT]
user=ocid1.user.oc1..aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
fingerprint=36:04:63:cd:36:04:63:cd:36:04:63:cd:36:04:63:cd
key_file=oci_api_key.pem
tenancy=ocid1.tenancy.oc1..aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
region=us-ashburn-1

View File

@@ -0,0 +1,12 @@
{
"ClientId" : "0b8cd92bb60b8cd92bb60b8cd92bb6",
"ClientSecret" : "41964196-2cfb-2cfb-2cfb-63246a63246a",
"BaseUrl" : "https://idcs-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.identity.oraclecloud.com",
"AudienceServiceUrl" : "https://idcs-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.identity.oraclecloud.com",
"scope" : "aaaaaaaaaaaaaaaaaaaaaaa.apigateway.us-ashburn-1.oci.customer-oci.com/super_scope",
"TokenIssuer" : "https://identity.oraclecloud.com",
"redirectURL": "http://localhost:8000/callback",
"logoutSufix":"/oauth2/v1/userlogout",
"LogLevel":"INFO",
"ConsoleLog":"True"
}

View File

@@ -0,0 +1,136 @@
{
"compartment_id": "<API Gateway Compartment OCID>",
"defined_tags": {
"Oracle-Tags": {
"CreatedBy": "oracleidentitycloudservice/cristiano.hoshikawa@oracle.com",
"CreatedOn": "2024-01-01T13:15:34.193Z"
}
},
"display_name": "createApi",
"endpoint": "https://aaaaaaaaaaaaaaaaaaaaaaaaaa.apigateway.us-ashburn-1.oci.customer-oci.com/createApi",
"freeform_tags": {},
"gateway_id": "ocid1.apigateway.oc1.iad.amaaaaaanamaaaaaanamaaaaaanamaaaaaanamaaaaaanamaaaaaanamaaaaaan",
"id": "ocid1.apideployment.oc1.iad.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"lifecycle_details": null,
"lifecycle_state": "ACTIVE",
"path_prefix": "/createApi",
"specification": {
"logging_policies": {
"access_log": null,
"execution_log": {
"is_enabled": null,
"log_level": "INFO"
}
},
"request_policies": {
"authentication": {
"cache_key": [
"token",
"displayName",
"apiCompartmentId"
],
"function_id": "<createApi function OCID>",
"is_anonymous_access_allowed": false,
"parameters": {
"apiCompartmentId": "request.headers[apiCompartmentId]",
"body": "request.body",
"displayName": "request.headers[displayName]",
"token": "request.headers[token]"
},
"token_header": null,
"token_query_param": null,
"type": "CUSTOM_AUTHENTICATION",
"validation_failure_policy": null
},
"cors": null,
"dynamic_authentication": null,
"mutual_tls": {
"allowed_sans": [],
"is_verified_certificate_required": false
},
"rate_limiting": null,
"usage_plans": null
},
"routes": [
{
"backend": {
"body": "{\"status\": \"success\"}",
"headers": [],
"status": 200,
"type": "STOCK_RESPONSE_BACKEND"
},
"logging_policies": {
"access_log": null,
"execution_log": {
"is_enabled": null,
"log_level": null
}
},
"methods": [
"POST"
],
"path": "/create",
"request_policies": {
"authorization": {
"type": "AUTHENTICATION_ONLY"
},
"body_validation": null,
"cors": null,
"header_transformations": {
"filter_headers": null,
"rename_headers": null,
"set_headers": {
"items": [
{
"if_exists": "OVERWRITE",
"name": "token",
"values": [
"${request.headers[token]}"
]
},
{
"if_exists": "OVERWRITE",
"name": "displayName",
"values": [
"${request.headers[displayName]}"
]
},
{
"if_exists": "OVERWRITE",
"name": "apiCompartmentId",
"values": [
"${request.headers[apiCompartmentId]}"
]
}
]
}
},
"header_validations": null,
"query_parameter_transformations": null,
"query_parameter_validations": null,
"response_cache_lookup": null
},
"response_policies": {
"header_transformations": {
"filter_headers": null,
"rename_headers": null,
"set_headers": {
"items": [
{
"if_exists": "APPEND",
"name": "api_id",
"values": [
"${request.auth[api_id]}"
]
}
]
}
},
"response_cache_store": null
}
}
]
},
"time_created": "2024-01-01T13:15:35.448000+00:00",
"time_updated": "2024-01-01T13:39:00.396000+00:00"
}

261
files/createapi/func.py Normal file
View File

@@ -0,0 +1,261 @@
import base64
import json
import io
from fdk import response
import oci
import requests
import yaml
import datetime
#### IDCS Routines
#### https://docs.oracle.com/en/learn/apigw-modeldeployment/index.html#introduction
#### https://docs.oracle.com/en/learn/migrate-api-to-api-gateway/#introduction
def auth_idcs(token, url, clientID, secretID):
url = url + "/oauth2/v1/introspect"
auth = clientID + ":" + secretID
auth_bytes = auth.encode("ascii")
auth_base64_bytes = base64.b64encode(auth_bytes)
auth_base64_message = auth_base64_bytes.decode("ascii")
headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Basic ' + auth_base64_message
}
payload = "token=" + token
response = requests.request("POST", url, headers=headers, data=payload)
return response
#Function used to load the configurations from the config.json file
def getOptions():
fo = open("config.json", "r")
config = fo.read()
options = json.loads(config)
return options
### OCI API Gateway Migration Routines
def migrate_to_apigw(payload, url, clientID, secretID):
auth = clientID + ":" + secretID
auth_bytes = auth.encode("ascii")
auth_base64_bytes = base64.b64encode(auth_bytes)
auth_base64_message = auth_base64_bytes.decode("ascii")
headers = {
'Content-Type': 'application/json',
'Authorization': 'Basic ' + auth_base64_message
}
response = requests.request("POST", url, headers=headers, data=payload)
return response
def find_base_path(strPath):
base_path = strPath.split('/')[1]
if (len(base_path) == 0):
base_path = strPath
else:
base_path = "/" + base_path
return base_path
def find_path(strPath):
base_path = strPath.split('/')
if (len(base_path) == 0):
return strPath
else:
auxPath = ""
skipCount = 0
for b in base_path:
if (skipCount > 1):
auxPath = auxPath + "/" + b
skipCount = skipCount + 1
base_path = auxPath
return auxPath
def process_api_spec(displayName, compartmentId, environment, swagger):
type = "REST"
config = oci.config.from_file("config")
apigateway_client = oci.apigateway.ApiGatewayClient(config)
logging = oci.loggingingestion.LoggingClient(config)
#-----------------------------------------------------------------
try:
data = swagger
fullSpec = json.loads(data)
version = "3"
try:
version = (fullSpec["swagger"])[:1]
except:
version = (fullSpec["openapi"])[:1]
print("version", version)
if (version == "3"):
endPoint = fullSpec["servers"][0]["url"]
else:
endPoint = fullSpec["host"]
listApis = apigateway_client.list_apis(compartment_id=compartmentId, display_name=displayName, lifecycle_state="ACTIVE")
apis = json.loads(str(listApis.data))
c = len(apis["items"])
api_id = ""
if (c == 0):
print("create api")
create_api_response = apigateway_client.create_api(
create_api_details=oci.apigateway.models.CreateApiDetails(
compartment_id=compartmentId,
display_name=displayName,
content=data))
api_created = json.loads(str(create_api_response.data))
api_id = api_created
else:
print("update api")
update_api_response = apigateway_client.update_api(api_id=apis["items"][0]["id"],
update_api_details=oci.apigateway.models.UpdateApiDetails(
display_name=displayName,
content=data))
api_updated = dict(update_api_response.headers)
api_id = api_updated
return api_id
except(Exception) as ex:
raise
def DateEncoder(obj):
if isinstance(obj, datetime.datetime):
return obj.strftime('%Y-%m-%d')
def is_json(swagger):
try:
body = json.loads(swagger)
return True
except:
try:
yaml_object = yaml.safe_load(swagger) # yaml_object will be a list or a dict
s = json.dumps(yaml_object, indent=2, default=DateEncoder)
return False
except:
return False
def convert_json(swagger):
yaml_object = yaml.safe_load(swagger) # yaml_object will be a list or a dict
return json.dumps(yaml_object, indent=2, default=DateEncoder)
###
def handler(ctx, data: io.BytesIO = None):
config = oci.config.from_file("config")
logging = oci.loggingingestion.LoggingClient(config)
# functions context variables
app_context = dict(ctx.Config())
jsonData = ""
options = getOptions()
try:
header = json.loads(data.getvalue().decode('utf-8'))["data"]
url = options["BaseUrl"]
body = dict(json.loads(data.getvalue().decode('utf-8')).get("data"))["body"]
# body content
swagger = str(body)
if (is_json(swagger)):
body = json.loads(body)
else:
body = json.loads(convert_json(swagger))
swagger = convert_json(swagger)
environment = "DEV"
# header values
access_token = header["token"]
displayName = header["displayName"]
compartmentId = header['apiCompartmentId']
authorization = auth_idcs(access_token, url, options["ClientId"], options["ClientSecret"])
try:
if (authorization.json().get("active") != True):
return response.Response(
ctx,
status_code=401,
response_data=json.dumps({"active": False, "wwwAuthenticate": jsonData})
)
except(Exception) as ex1:
jsonData = 'error parsing json payload: ' + str(ex1)
put_logs_response = logging.put_logs(
log_id="ocid1.log.oc1.iad.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
put_logs_details=oci.loggingingestion.models.PutLogsDetails(
specversion="EXAMPLE-specversion-Value",
log_entry_batches=[
oci.loggingingestion.models.LogEntryBatch(
entries=[
oci.loggingingestion.models.LogEntry(
data="error: " + jsonData,
id="ocid1.test.oc1..00000001.EXAMPLE-id-Value")],
source="EXAMPLE-source-Value",
type="EXAMPLE-type-Value")]))
return response.Response(
ctx,
status_code=401,
response_data=json.dumps({"active": False, "wwwAuthenticate": jsonData})
)
# Create API spec
api_id = process_api_spec(displayName, compartmentId, environment, swagger)
rdata = json.dumps({
"active": True,
"context": {
"environment": environment,
"display_name": displayName,
"api_id": json.dumps(api_id)
}})
# put_logs_response = logging.put_logs(
# log_id="ocid1.log.oc1.iad.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
# put_logs_details=oci.loggingingestion.models.PutLogsDetails(
# specversion="EXAMPLE-specversion-Value",
# log_entry_batches=[
# oci.loggingingestion.models.LogEntryBatch(
# entries=[
# oci.loggingingestion.models.LogEntry(
# data="request payload: " + json.dumps(header),
# id="ocid1.test.oc1..00000001.EXAMPLE-id-Value-1")],
# source="EXAMPLE-source-Value",
# type="EXAMPLE-type-Value")]))
return response.Response(
ctx, response_data=rdata,
status_code=200,
headers={"Content-Type": "application/json", "data": rdata}
)
except(Exception) as ex:
jsonData = 'error parsing json payload: ' + str(ex)
put_logs_response = logging.put_logs(
log_id="ocid1.log.oc1.iad.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
put_logs_details=oci.loggingingestion.models.PutLogsDetails(
specversion="EXAMPLE-specversion-Value",
log_entry_batches=[
oci.loggingingestion.models.LogEntryBatch(
entries=[
oci.loggingingestion.models.LogEntry(
data="error: " + jsonData + "/" + swagger,
id="ocid1.test.oc1..00000001.EXAMPLE-id-Value")],
source="EXAMPLE-source-Value",
type="EXAMPLE-type-Value")]))
pass
return response.Response(
ctx,
status_code=401,
response_data=json.dumps({"active": False, "wwwAuthenticate": jsonData})
)

View File

@@ -0,0 +1,8 @@
schema_version: 20180708
name: create-api
version: 0.0.37
runtime: python
build_image: fnproject/python:3.9-dev
run_image: fnproject/python:3.9
entrypoint: /python/bin/fdk /function/func.py handler
memory: 256

View File

@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
+PlyICemh7G2GNTwleCu61CVYaVcXxZG8LQkHAHCykuq+R7d6lwxkHQTIyKmUj+o
6BCWIQKBgQCAHaQZ4p/XDHVqajity2YCauQKM7eD0cyUnY9h+MKkih1g7brU43DR
u1yJoOnQzddapVr7yVXMl874mU+Jgm7arh+XRL8WuV2RtltKurBhYqtSwiGg0JFx
pRZm1D73NtXRaTSSwYdXakQjPb4FaFdwBouxVylP6GSy4kI2iva3og==
-----END RSA PRIVATE KEY-----

View File

@@ -0,0 +1,9 @@
fdk>=0.1.54
requests
oci
cryptography
six
PyJWT
py3_lru_cache
simplejson
PyYAML

7
files/test/config Normal file
View File

@@ -0,0 +1,7 @@
[DEFAULT]
user=ocid1.user.oc1..aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
fingerprint=36:04:63:cd:36:04:63:cd:36:04:63:cd:36:04:63:cd
key_file=oci_api_key.pem
tenancy=ocid1.tenancy.oc1..aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
region=us-ashburn-1

12
files/test/config.json Normal file
View File

@@ -0,0 +1,12 @@
{
"ClientId" : "0b8cd92bb60b8cd92bb60b8cd92bb6",
"ClientSecret" : "41964196-2cfb-2cfb-2cfb-63246a63246a",
"BaseUrl" : "https://idcs-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.identity.oraclecloud.com",
"AudienceServiceUrl" : "https://idcs-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.identity.oraclecloud.com",
"scope" : "aaaaaaaaaaaaaaaaaaaaaaa.apigateway.us-ashburn-1.oci.customer-oci.com/super_scope",
"TokenIssuer" : "https://identity.oraclecloud.com",
"redirectURL": "http://localhost:8000/callback",
"logoutSufix":"/oauth2/v1/userlogout",
"LogLevel":"INFO",
"ConsoleLog":"True"
}

View File

@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
MIIEpAIBAAKCAQEA16UCid4+eyt6kzo+u1BRV4UM8QKfViBZasZBclCOvt8j+lDK
+PlyICemh7G2GNTwleCu61CVYaVcXxZG8LQkHAHCykuq+R7d6lwxkHQTIyKmUj+o
6BCWIQKBgQCAHaQZ4p/XDHVqajity2YCauQKM7eD0cyUnY9h+MKkih1g7brU43DR
u1yJoOnQzddapVr7yVXMl874mU+Jgm7arh+XRL8WuV2RtltKurBhYqtSwiGg0JFx
pRZm1D73NtXRaTSSwYdXakQjPb4FaFdwBouxVylP6GSy4kI2iva3og==
-----END RSA PRIVATE KEY-----

View File

@@ -0,0 +1,681 @@
import base64
import json
import io
from fdk import response
import oci
import requests
import time
from itertools import groupby
import yaml
import datetime
# DEFINIR AS VARIAVEIS
#
# Método: process_api_spec()
# displayName = "qrcode"
# compartmentId = "ocid1.compartment.oc1..aaaaaaaaqomaaaaaaaaqomaaaaaaaaqomaaaaaaaaqomaaaaaaaaqomaaaaaaaaqom"
# config = oci.config.from_file(profile_name='DEFAULT')
#
# Método: getSpec()
# text_file = open("/Users/cristianohoshikawa/Dropbox/ORACLE/B3/API Gateway/Teste 2024-03-15/qrcode.yaml", "r")
def migrate_to_apigw(payload, url, clientID, secretID):
auth = clientID + ":" + secretID
auth_bytes = auth.encode("ascii")
auth_base64_bytes = base64.b64encode(auth_bytes)
auth_base64_message = auth_base64_bytes.decode("ascii")
headers = {
'Content-Type': 'application/json',
'Authorization': 'Basic ' + auth_base64_message
}
response = requests.request("POST", url, headers=headers, data=payload)
return response
def getSpec(name):
text_file = open(name, "r", encoding='utf-8')
data = text_file.read()
text_file.close()
if (is_json(data)):
data = data
else:
data = convert_json(data)
return data
def find_base_path(strPath):
base_path = strPath.split('/')[1]
if (len(base_path) == 0):
base_path = strPath
else:
base_path = "/" + base_path
return base_path
def has_path_endpoint(endPoint):
endPointAux = endPoint.replace("//", "#")
endPointSplited = endPointAux.split('/')
if (len(endPointSplited) > 1):
return True
else:
return False
def concatSplited(endPointSplited):
count = 0
endPointStr = ""
for item in endPointSplited:
if (count > 0):
endPointStr = endPointStr + "/" + item
count = count + 1
return endPointStr
def find_base_pathendpoint(endPoint, strPath):
base_path = strPath.split('/')[1]
if (len(base_path) == 0 and has_path_endpoint(endPoint)):
endPointAux = endPoint.replace("//", "#")
endPointSplited = endPointAux.split('/')
if (len(endPointSplited) > 1):
endPointSplitedStr = concatSplited(endPointSplited)
if (endPointSplitedStr != None):
base_path = endPointSplitedStr
else:
base_path = strPath
else:
base_path = strPath
else:
endPointAux = endPoint.replace("//", "#")
endPointSplited = endPointAux.split('/')
if (len(endPointSplited) > 1):
endPointSplitedStr = concatSplited(endPointSplited)
if (endPointSplitedStr != None):
base_path = endPointSplitedStr
endPoint = endPointSplited[0].replace("#", "//")
else:
base_path = "/" + base_path
else:
base_path = "/" + base_path
return base_path
def find_base_endpoint(endPoint):
endPointAux = endPoint.replace("//", "#")
endPointSplited = endPointAux.split('/')
if (len(endPointSplited) > 1):
endPointSplitedStr = endPointSplited[1]
if (endPointSplitedStr != None):
endPoint = endPointSplited[0].replace("#", "//")
return endPoint
def find_path(strPath):
base_path = strPath.split('/')
if (len(base_path) == 0):
return strPath
else:
auxPath = ""
skipCount = 0
for b in base_path:
if (skipCount > 1):
auxPath = auxPath + "/" + b
skipCount = skipCount + 1
base_path = auxPath
return auxPath
def removeLastSlash(path):
return path.rstrip("/")
def accMethods(routes, path, status):
METHOD = ""
for spec in routes:
if (find_path(spec["path"]) == path and spec["backend"]["status"] == status):
for method in spec["methods"]:
if (method not in METHOD):
METHOD = (METHOD + " " + method).lstrip().upper()
return METHOD
def accMethods_v2(routes, path, status):
METHOD = ""
for spec in routes:
if (spec["path"] == path and spec["backend"]["status"] == status):
for method in spec["methods"]:
if (method not in METHOD):
METHOD = (METHOD + " " + method).lstrip().upper()
return METHOD
def accMethods_v3(routes, path, status):
METHOD = ""
for spec in routes:
if (spec["path"] == path and spec["backend"]["status"] == status):
for method in spec["methods"]:
if (method not in METHOD):
METHOD = (METHOD + " " + method).lstrip().upper()
return METHOD
def check_endpoint(schemes, endpoint):
if (schemes == ""):
if (endpoint.find("http://") == -1 and endpoint.find("https://") == -1):
endpoint = "https://" + endpoint
else:
if (endpoint.find("http://") == -1 and endpoint.find("https://") == -1):
if (schemes.find("://") == -1):
endpoint = schemes + "://" + endpoint
else:
endpoint = schemes + endpoint
return endpoint
def key_func(k):
return k['PATH']
def group_by(payload):
payload = json.loads(payload)
INFO = sorted(payload, key=key_func)
result_payload = [ ]
for key, value in groupby(INFO, key_func):
list_elements = [ ]
method_list = ""
for element in list(value):
list_elements.append(element)
for subItem in list_elements:
item = json.loads(json.dumps(subItem))
if (item["METHOD"] not in method_list):
method_list = (method_list + " " + item["METHOD"]).lstrip().upper()
API_NAME = item["API_NAME"]
TYPE = item["TYPE"]
ENVIRONMENT = item["ENVIRONMENT"]
PATH_PREFIX = item["PATH_PREFIX"]
PATH = item["PATH"]
ENDPOINT = item["ENDPOINT"]
SCHEMA_BODY_VALIDATION = item["SCHEMA_BODY_VALIDATION"]
result_payload.append({"API_NAME": API_NAME, "TYPE": TYPE, "ENVIRONMENT": ENVIRONMENT, "PATH_PREFIX": PATH_PREFIX, "PATH": PATH, "ENDPOINT": ENDPOINT, "METHOD": method_list, "SCHEMA_BODY_VALIDATION": SCHEMA_BODY_VALIDATION})
return result_payload
def verify_path(json_data_list):
list_final = []
for item in json_data_list:
if (item["PATH"] == ""):
for item2 in json_data_list:
if (item2["PATH"] == ""):
list_final.append({
'API_NAME': item2["API_NAME"],
'TYPE': item2["TYPE"],
'ENVIRONMENT': item2["ENVIRONMENT"],
'METHOD': item2["METHOD"],
'PATH_PREFIX': "/",
'PATH': item2["PATH_PREFIX"],
'ENDPOINT': item2["ENDPOINT"],
'SCHEMA_BODY_VALIDATION': item2["SCHEMA_BODY_VALIDATION"],
'CONTENT_TYPE': item2["CONTENT_TYPE"]
})
else:
list_final.append({
'API_NAME': item2["API_NAME"],
'TYPE': item2["TYPE"],
'ENVIRONMENT': item2["ENVIRONMENT"],
'METHOD': item2["METHOD"],
'PATH_PREFIX': item2["PATH_PREFIX"],
'PATH': item2["PATH"],
'ENDPOINT': item2["ENDPOINT"],
'SCHEMA_BODY_VALIDATION': item2["SCHEMA_BODY_VALIDATION"],
'CONTENT_TYPE': item2["CONTENT_TYPE"]
})
return list_final
return json_data_list
def DateEncoder(obj):
if isinstance(obj, datetime.datetime):
return obj.strftime('%Y-%m-%d')
def is_json(swagger):
try:
body = json.loads(swagger)
return True
except:
try:
yaml_object = yaml.safe_load(swagger) # yaml_object will be a list or a dict
s = json.dumps(yaml_object, indent=2, default=DateEncoder)
return False
except:
return False
def replace_escape_chars(obj):
for k, v in obj.items():
if isinstance(v, str):
obj[k] = v.replace('\\\\', '\\"')
elif isinstance(v, dict):
obj[k] = replace_escape_chars(v)
elif isinstance(v, list):
for i in range(len(v)):
if isinstance(v[i], str):
v[i] = v[i].replace('\\\\', '\\"')
elif isinstance(v[i], dict):
v[i] = replace_escape_chars(v[i])
return obj
def convert_json(swagger):
yaml_object = yaml.safe_load(swagger) # yaml_object will be a list or a dict
x = json.dumps(yaml_object, ensure_ascii=False, indent=2, default=DateEncoder).encode('utf-8')
return x.decode()
def process_api_spec():
# displayName = "EXEMPLO"
compartmentId = "ocid1.compartment.oc1..aaaaaaaaqom2belitvh5ubr342rgzyeycvyg3zt6b4i4owmkzpnpwft37rga"
environment = "QA"
type = "REST"
rate_limit = "2500,CLIENT_IP"
try:
rate_config = rate_limit.split(',')
rate_seconds = int(rate_config[0])
rate_key = rate_config[1]
print(rate_seconds)
print(rate_key)
except:
print("erro")
# Create a default config using DEFAULT profile in default location
# Refer to
# https://docs.cloud.oracle.com/en-us/iaas/Content/API/Concepts/sdkconfig.htm#SDK_and_CLI_Configuration_File
# for more info
config = oci.config.from_file(profile_name='DEFAULT')
# TELEMETRY
# monitoring_client = oci.monitoring.MonitoringClient(config, service_endpoint="https://telemetry-ingestion.us-ashburn-1.oraclecloud.com/20180401")
#
# post_metric_data_response = monitoring_client.post_metric_data(
# post_metric_data_details=oci.monitoring.models.PostMetricDataDetails(
# metric_data=[
# oci.monitoring.models.MetricDataDetails(
# namespace="api_customers",
# compartment_id=compartmentId,
# name="customer_request",
# dimensions={
# "customer": "Cliente A"},
# datapoints=[
# oci.monitoring.models.Datapoint(
# timestamp=datetime.strptime(
# datetime.utcnow().isoformat() + 'Z',
# "%Y-%m-%dT%H:%M:%S.%fZ"),
# value=1,
# count=1)],
# resource_group="API_group",
# metadata={
# "metadados": "api"})]))
# Initialize service client with default config file
apigateway_client = oci.apigateway.ApiGatewayClient(config)
# -----------------------------------------------------------------
arquivo = []
arquivo.append("/Users/cristianohoshikawa/Dropbox/ORACLE/B3/API Gateway/Testes 2024-03-11/1.0.0-rc2_rcc-interop-agenda_modificado.json")
arquivo.append("/Users/cristianohoshikawa/Dropbox/ORACLE/B3/API Gateway/Testes 2024-03-11/caso1.yaml")
arquivo.append("/Users/cristianohoshikawa/Dropbox/ORACLE/B3/API Gateway/Testes 2024-03-11/caso2.yaml")
arquivo.append("/Users/cristianohoshikawa/Dropbox/ORACLE/B3/API Gateway/Teste 2024-03-15/caso2024-03-15.yaml")
arquivo.append("/Users/cristianohoshikawa/Dropbox/ORACLE/B3/API Gateway/Teste 2024-03-15/qrcode.yaml")
#arquivo.append("/Users/cristianohoshikawa/Dropbox/ORACLE/B3/API Gateway/Teste 2024-03-18/1.0.0-rc1_cob 1.yaml")
arquivo.append("/Users/cristianohoshikawa/Dropbox/ORACLE/B3/API Gateway/Teste 2024-03-18/1.0.0-rc1_cobv.yaml")
arquivo.append("/Users/cristianohoshikawa/Dropbox/ORACLE/B3/API Gateway/Teste 2024-03-18/1.0.0-rc1_loc.yaml")
arquivo.append("/Users/cristianohoshikawa/Dropbox/ORACLE/B3/API Gateway/Teste 2024-03-18/1.0.0-rc1_lotecobv.yaml")
#arquivo.append("/Users/cristianohoshikawa/Dropbox/ORACLE/B3/API Gateway/Teste 2024-03-18/1.0.0-rc1_pix.yaml")
arquivo.append("/Users/cristianohoshikawa/Dropbox/ORACLE/B3/API Gateway/Teste 2024-03-18/1.0.0-rc1_webhook.yaml")
arquivo.append("/Users/cristianohoshikawa/Dropbox/ORACLE/B3/API Gateway/Teste 2024-03-20/1.0.0-rc8_cprs.json")
#arquivo.append("/Users/cristianohoshikawa/Dropbox/ORACLE/B3/API Gateway/Teste 2024-03-21/1.0.0-rc1_cob 1.yaml")
arquivo.append("/Users/cristianohoshikawa/Dropbox/ORACLE/B3/API Gateway/Teste 2024-03-21/1.0.0-rc2_rcc-interop-agenda.json")
arquivo.append("/Users/cristianohoshikawa/Dropbox/ORACLE/B3/API Gateway/Teste 2024-03-22/1.0.0-rc8_cprs.json")
#arquivo.append("/Users/cristianohoshikawa/Dropbox/ORACLE/B3/API Gateway/Teste 2024-03-25/Banco B3/1.0.0-rc1_cob.yaml")
arquivo.append("/Users/cristianohoshikawa/Dropbox/ORACLE/B3/API Gateway/Teste 2024-06-03/1.0.0-rc1_cob.yaml")
arquivo.append("/Users/cristianohoshikawa/Dropbox/ORACLE/B3/API Gateway/Teste 2024-06-19/1.0.0-rc1_cob.yaml")
display = []
display.append("Interoperabilidades-Agenda")
display.append("caso-1")
display.append("caso-2")
display.append("caso2024-03-15")
display.append("qrcode")
#display.append("cob")
display.append("cobv")
display.append("loc")
display.append("lotecobv")
#display.append("pix")
display.append("webhook")
display.append("cprs")
#display.append("cob1")
display.append("rcc-interop-agenda")
display.append("Rural")
#display.append("cob")
display.append("pix")
display.append("GI - Modulo PIX Cob")
idxArquivo = 0
while idxArquivo < len(arquivo):
print("---------------------------------------------------------")
print(arquivo[idxArquivo])
print("")
data = getSpec(arquivo[idxArquivo])
fullSpec = json.loads(data)
swagger = str(data)
swagger2 = str(data)
if (is_json(swagger)):
body = json.loads(swagger)
else:
body = json.loads(convert_json(swagger2))
swagger = convert_json(data)
swagger = swagger
displayName = display[idxArquivo]
version = "3"
try:
version = (fullSpec["swagger"])[:1]
except:
version = (fullSpec["openapi"])[:1]
print("version", version)
if (version == "3"):
endPoint = fullSpec["servers"][0]["url"]
else:
endPoint = fullSpec["host"]
print("url")
print(endPoint)
listApis = apigateway_client.list_apis(compartment_id=compartmentId, display_name=displayName,
lifecycle_state="ACTIVE")
apis = json.loads(str(listApis.data))
c = len(apis["items"])
api_id = apis["items"][0]["id"]
print(api_id)
try:
get_api = apigateway_client.get_api_deployment_specification(api_id=api_id)
api_spec = json.loads(str(get_api.data))
print(api_spec["routes"])
json_data_list = []
endPointOrigin = endPoint
for spec in api_spec["routes"]:
status = spec["backend"]["status"]
specPath = spec["path"]
for method in spec["methods"]:
METHOD = method.lstrip().upper()
if (version == "3"):
if (has_path_endpoint(endPointOrigin)):
endPoint = find_base_endpoint(endPointOrigin)
specPath = (find_base_pathendpoint(endPointOrigin, specPath)).replace("//", "/")
fullEndpoint = (endPoint + specPath + spec["path"]).replace("{", "${request.path[").replace("}", "]}")
FULL_PATH = specPath
ENDPOINT = fullEndpoint
PATH = spec["path"]
PATH_PREFIX = specPath
#METHOD = accMethods_v3(api_spec["routes"], spec["path"], status)
else:
fullEndpoint = (endPoint + find_base_path(specPath) + find_path(specPath)).replace("{", "${request.path[").replace("}", "]}")
FULL_PATH = specPath
ENDPOINT = fullEndpoint
PATH = find_path(specPath)
PATH_PREFIX = find_base_path(specPath)
#METHOD = accMethods(api_spec["routes"], find_path(spec["path"]), status)
else:
schemes = ""
try:
schemes = fullSpec["schemes"][0]
except:
schemes = "https"
fullEndpoint = check_endpoint(schemes, (endPoint + removeLastSlash(fullSpec["basePath"]) + spec["path"]).replace("{", "${request.path[").replace("}", "]}"))
FULL_PATH = fullSpec["basePath"] + spec["path"]
ENDPOINT = fullEndpoint
PATH = spec["path"]
PATH_PREFIX = removeLastSlash(fullSpec["basePath"])
#METHOD = accMethods_v2(api_spec["routes"], PATH, status)
OPERATIONID = fullSpec["paths"][spec["path"]][str(spec["methods"][0]).lower()]["operationId"]
API_NAME = fullSpec["info"]["title"]
if (version == "3"):
try:
SCHEMA_BODY_VALIDATION = str(fullSpec["paths"][spec["path"]][str(spec["methods"][0]).lower()]["requestBody"]["content"]["application/json"])
CONTENT_TYPE = "application/json"
except:
SCHEMA_BODY_VALIDATION = ""
CONTENT_TYPE = ""
else:
SCHEMA_BODY_VALIDATION = ""
CONTENT_TYPE = ""
try:
reference = str(fullSpec["paths"][spec["path"]][str(spec["methods"][0]).lower()]["parameters"][0]["schema"]["$ref"]).replace("#/definitions/", "")
SCHEMA_BODY_VALIDATION = reference + "," + api_id
CONTENT_TYPE = "application/json"
except:
SCHEMA_BODY_VALIDATION = ""
CONTENT_TYPE = ""
TYPE = type
ENVIRONMENT = environment
json_data_list.append({
'API_NAME': API_NAME,
'TYPE': TYPE,
'ENVIRONMENT': ENVIRONMENT,
'METHOD': METHOD,
'PATH_PREFIX': PATH_PREFIX,
'PATH': PATH,
'ENDPOINT': ENDPOINT,
'SCHEMA_BODY_VALIDATION': SCHEMA_BODY_VALIDATION,
'CONTENT_TYPE': CONTENT_TYPE
})
print(API_NAME, TYPE, ENVIRONMENT, METHOD, PATH_PREFIX, PATH, ENDPOINT, SCHEMA_BODY_VALIDATION, CONTENT_TYPE)
json_data_list = verify_path(json_data_list)
payload = json.dumps(json_data_list)
#json_data_list = { each['PATH'] : each for each in json_data_list}.values()
# if (version == "2"):
# payload = json.loads(json.dumps(group_by(payload)))
# #json_data_list = { each['PATH'] : each for each in payload}.values()
#payload = json.loads(json.dumps(group_by(payload)))
payload = json.loads(json.dumps(json_data_list))
print(payload)
# migrate_to_apigw(payload, "https://oic-hoshikawa2-idcci5ks1puo-ia.integration.ocp.oraclecloud.com:443/ic/api/integration/v1/flows/rest/MIGRATE_TO_APIGW/1.0/convert", "OIC_SERVICE_USER_BASICAUTH", "e7ae6069-e471-496e-916d-5dc2ae3edac0")
applyAuthApi(compartmentId=compartmentId, displayName=API_NAME, payload=payload, functionId="", host="", api_gateway_id="", rate_limit=rate_limit)
c = 0
idxArquivo = idxArquivo + 1
except(Exception) as ex:
print(ex)
time.sleep(2)
def applyAuthApi(compartmentId, displayName, payload, functionId, host, api_gateway_id, rate_limit):
config = oci.config.from_file(profile_name='DEFAULT')
logging = oci.loggingingestion.LoggingClient(config)
apigateway_client = oci.apigateway.DeploymentClient(config)
listGateway = apigateway_client.list_deployments(compartment_id=compartmentId, display_name=displayName, lifecycle_state="ACTIVE")
gateway = json.loads(str(listGateway.data))
ind = -1
c = -1
if (len(gateway) > 0):
c = 0
for item in gateway["items"]:
if (item["gateway_id"] == api_gateway_id):
ind = c
break
c = c + 1
if (gateway["items"] != [] and c > -1 and ind > -1):
gateway_id = gateway["items"][ind]["gateway_id"]
deployment_id = gateway["items"][ind]["id"]
else:
gateway_id = api_gateway_id
deployment_id = 0
try:
rate_config = rate_limit.split(',')
rate_seconds = int(rate_config[0])
rate_key = rate_config[1]
rate_limiting = oci.apigateway.models.RateLimitingPolicy(
rate_in_requests_per_second=rate_seconds,
rate_key=rate_key)
except:
rate_limiting = None
path_prefix = "/"
routes = [ ]
new_routes = [ ]
for item in payload:
methods = [item["METHOD"]]
path_prefix = item["PATH_PREFIX"]
callback_url = ("https://" + host + item["PATH_PREFIX"] + "validation-callback" + item["PATH"]).replace("{", "${request.path[").replace("}", "]}")
if (item["SCHEMA_BODY_VALIDATION"] != ""):
put_logs_response = logging.put_logs(
log_id="ocid1.log.oc1.iad.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
put_logs_details=oci.loggingingestion.models.PutLogsDetails(
specversion="EXAMPLE-specversion-Value",
log_entry_batches=[
oci.loggingingestion.models.LogEntryBatch(
entries=[
oci.loggingingestion.models.LogEntry(
data="callback_url: " + callback_url,
id="ocid1.test.oc1..00000001.EXAMPLE-id-Value")],
source="EXAMPLE-source-Value",
type="EXAMPLE-type-Value")]))
routes.append(
oci.apigateway.models.ApiSpecificationRoute(
path=item["PATH"],
backend=oci.apigateway.models.HTTPBackend(
type="HTTP_BACKEND",
url=callback_url,
is_ssl_verify_disabled=False),
methods=methods,
request_policies=oci.apigateway.models.ApiSpecificationRouteRequestPolicies(
header_transformations=oci.apigateway.models.HeaderTransformationPolicy(
set_headers=oci.apigateway.models.SetHeaderPolicy(
items=[
oci.apigateway.models.SetHeaderPolicyItem(
name="body_schema_validation",
values=[item["SCHEMA_BODY_VALIDATION"]],
if_exists="APPEND")]),
)
)))
new_routes.append(
oci.apigateway.models.ApiSpecificationRoute(
path=item["PATH"],
backend=oci.apigateway.models.HTTPBackend(
type="HTTP_BACKEND",
url=item["ENDPOINT"],
is_ssl_verify_disabled=False),
methods=methods,
request_policies=oci.apigateway.models.ApiSpecificationRouteRequestPolicies(
header_transformations=oci.apigateway.models.HeaderTransformationPolicy(
set_headers=oci.apigateway.models.SetHeaderPolicy(
items=[
oci.apigateway.models.SetHeaderPolicyItem(
name="body_schema_validation",
values=[item["SCHEMA_BODY_VALIDATION"]],
if_exists="APPEND")]),
)
)
))
else:
routes.append(
oci.apigateway.models.ApiSpecificationRoute(
path=item["PATH"],
backend=oci.apigateway.models.HTTPBackend(
type="HTTP_BACKEND",
url=callback_url,
is_ssl_verify_disabled=False),
methods=methods))
new_routes.append(
oci.apigateway.models.ApiSpecificationRoute(
path=item["PATH"],
backend=oci.apigateway.models.HTTPBackend(
type="HTTP_BACKEND",
url=item["ENDPOINT"],
is_ssl_verify_disabled=False),
methods=methods))
if (new_routes != [ ]):
validation_deployment_details=oci.apigateway.models.UpdateDeploymentDetails(
display_name=displayName + "-validation",
specification=oci.apigateway.models.ApiSpecification(
request_policies=oci.apigateway.models.ApiSpecificationRequestPolicies(
rate_limiting=rate_limiting,
authentication=oci.apigateway.models.CustomAuthenticationPolicy(
type="CUSTOM_AUTHENTICATION",
function_id=functionId,
is_anonymous_access_allowed=False,
parameters={
'token': 'request.headers[token]',
'body': 'request.body',
'body_schema_validation': 'request.headers[body_schema_validation]',
'opc-request-id': 'request.headers[opc-request-id]'},
cache_key=["token", "opc-request-id"],
validation_failure_policy=oci.apigateway.models.ModifyResponseValidationFailurePolicy(
type="MODIFY_RESPONSE",
response_code="401",
response_message="${request.auth[error]}"
)
)),
routes=new_routes))
create_deployment_details=oci.apigateway.models.CreateDeploymentDetails(
display_name=displayName + "-validation",
compartment_id=compartmentId,
gateway_id=gateway_id,
path_prefix= path_prefix + "validation-callback",
specification=oci.apigateway.models.ApiSpecification(
request_policies=oci.apigateway.models.ApiSpecificationRequestPolicies(
rate_limiting=rate_limiting,
authentication=oci.apigateway.models.CustomAuthenticationPolicy(
type="CUSTOM_AUTHENTICATION",
function_id=functionId,
is_anonymous_access_allowed=False,
parameters={
'token': 'request.headers[token]',
'body': 'request.body',
'body_schema_validation': 'request.headers[body_schema_validation]',
'opc-request-id': 'request.headers[opc-request-id]'},
cache_key=["token", "opc-request-id"],
validation_failure_policy=oci.apigateway.models.ModifyResponseValidationFailurePolicy(
type="MODIFY_RESPONSE",
response_code="401",
response_message="${request.auth[error]}"
)
)),
routes=new_routes))
#creeateOrUpdateDeployment(compartmendId=compartmentId, displayName=displayName + "-validation", validation_deployment_details=validation_deployment_details, create_deployment_details=create_deployment_details, api_gateway_id=api_gateway_id)
if (routes != [ ]):
# The 1st layer will not authenticate
validation_deployment_details=oci.apigateway.models.UpdateDeploymentDetails(
display_name=displayName,
specification=oci.apigateway.models.ApiSpecification(
request_policies=oci.apigateway.models.ApiSpecificationRequestPolicies(
rate_limiting=rate_limiting),
routes=routes))
create_deployment_details=oci.apigateway.models.CreateDeploymentDetails(
display_name=displayName,
compartment_id=compartmentId,
gateway_id=gateway_id,
path_prefix= path_prefix,
specification=oci.apigateway.models.ApiSpecification(
request_policies=oci.apigateway.models.ApiSpecificationRequestPolicies(
rate_limiting=rate_limiting),
routes=routes))
#creeateOrUpdateDeployment(compartmendId=compartmentId, displayName=displayName, validation_deployment_details=validation_deployment_details, create_deployment_details=create_deployment_details, api_gateway_id=api_gateway_id)
# Mudar DisplayName e text_file para poder executar
process_api_spec()
# data = getSpec()
# fullSpec = json.loads(data)
# print(fullSpec["paths"]["/v1/credit-rights/{internal_number}"]["get"]["operationId"])

View File

@@ -0,0 +1,9 @@
fdk>=0.1.54
requests
oci
cryptography
six
PyJWT
py3_lru_cache
simplejson
PyYAML