Compare commits
36 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 110ba4146a | |||
| 8cce6df501 | |||
| 7ec28a84b7 | |||
| a9bbb8aba3 | |||
| c2385c6cda | |||
| a16bc3fd8d | |||
| 099174acfb | |||
| 212c732699 | |||
| da001e46ae | |||
| 32aa6cd977 | |||
| 270487ddb5 | |||
| 1871cad962 | |||
| 706454f2ba | |||
| 8ca2eed36e | |||
| 67fbce9fec | |||
| 7892d3436e | |||
| dde52b26eb | |||
| 6b417d0151 | |||
| 91400737e2 | |||
| 01f1f73e49 | |||
| 73560c2fa0 | |||
| 6210668600 | |||
| 5971bfb3f7 | |||
| bc4276087c | |||
| 14b8350ff7 | |||
| a8313cb914 | |||
| 2de174b2e4 | |||
| 76d7f30e1a | |||
| 6343721d66 | |||
| 9f88574064 | |||
| 65812cf3da | |||
| 2349b97f77 | |||
| b42a644ce3 | |||
| 98266a1b7d | |||
| 15cfd2d2f3 | |||
| 1fc4aad29d |
142
README.md
@@ -69,6 +69,14 @@ And this is the **config.json** file for **IDCS** configuration.
|
||||
|
||||

|
||||
|
||||
In the **createApi** and **applyValidationApi**, you can work with OpenAPI and Swagger specifications in **JSON** or **YAML** format. This can be done by 2 methods in the code:
|
||||
|
||||

|
||||
|
||||
This methods will be used to mantain the specification in **JSON** default format for all codes.
|
||||
|
||||

|
||||
|
||||
First, we need to import an OpenAPI specification. The **OCI API Gateway** has a REST service to import and validate the spec. We can do it with an **OCI function createApi** .
|
||||
|
||||
## createApi
|
||||
@@ -131,19 +139,131 @@ This is the **IDCS** service authorization by the token passed in BODY and will
|
||||
|
||||
This is the main code for your authorization function and will be described in sequence.
|
||||
|
||||

|
||||

|
||||
|
||||
Authorization function works 2 times
|
||||
The first call to the authorization function needs to validate your token from the **IDCS** and the first call always came with **body_schema_validation** = None.
|
||||
In the second call, the **body_schema_validation** came with some schema value from your OpenAPI spec, so the **IDCS** validation will be skiped.
|
||||
Remember that the API always will be deployed in 2 layers. The first layer will call the second layer.
|
||||
Authorization function works only in the second layer for best performance. This will be explained in the next section (**applyValidationApi**)
|
||||
|
||||

|
||||
|
||||
In the first authorization execution, the validation step will be skiped but in the second execution, the validation occurs with the same logic in the **body_schema_validation**.
|
||||
This is the schema validation for Swagger and Open API 3
|
||||
|
||||

|
||||

|
||||
|
||||
|
||||
|
||||
## Redact Validation Response
|
||||
|
||||
The project has a schema validation from the spec. When the function is working with authentication, there is a routine for validate the body content, thanks to the open-source bravado library.
|
||||
|
||||
The function send the body content and the **Swagger/Open API** specification to bravado libary and this action results in a message. There is a problem here. The results shows the content of the attributes and this need some kind of redaction.
|
||||
|
||||
You can redact the attributes content with these codes.
|
||||
|
||||
First, you need to import the **bravado** library for **validate_object**.
|
||||
|
||||

|
||||
|
||||
This code is responsible to beautify your validation response:
|
||||
|
||||

|
||||
|
||||
The **remove_property**, **replace_escape_chars** and **replace_regex** methods translate some **escape** codes inside the specification. This works as a pre-validation for redaction.
|
||||
|
||||
And you can put in the main function code:
|
||||
|
||||

|
||||
|
||||
You need to use a library called [Redaction.py](./files/authApi/Redaction.py), included in this material. This class find your patterns for attributes that need redaction.
|
||||
|
||||
Declare your patterns and attribute names:
|
||||
|
||||

|
||||
|
||||
So you can use the library like this:
|
||||
|
||||

|
||||
|
||||
When you request an REST service with this body content:
|
||||
|
||||

|
||||
|
||||
The response will be something like this:
|
||||
|
||||

|
||||
|
||||
## Resource Principal
|
||||
|
||||
[Resource Principal](https://docs.oracle.com/en-us/iaas/Content/Functions/Tasks/functionsaccessingociresources.htm) is another authentication type. This type of authentication replaces the use of **config** and **private key** files and do not expose sensitive data inside your **function**.
|
||||
|
||||
If you need, you can authenticate your **function** through **Resource Principal**, that let **OCI** to recognize the policy for your specific function's **OCID**, without exposing your private key or another sensitive data.
|
||||
You will need to declare a **Dynamic Group** with your function **OCID** and a policy allowing the use of the **OCI** resources in your code.
|
||||
|
||||
**Dynamic Group: acme-func-dyn-grp**
|
||||
|
||||

|
||||
|
||||
**Policy**
|
||||
|
||||

|
||||
|
||||
You need to replace your code:
|
||||
|
||||

|
||||
|
||||
with
|
||||
|
||||

|
||||
|
||||
This is the code to change:
|
||||
|
||||
signer = oci.auth.signers.get_resource_principals_signer()
|
||||
logging = oci.loggingingestion.LoggingClient(config={}, signer=signer)
|
||||
|
||||
|
||||
See the [authRPApi.py](./files/authApi/authRPApi.py) code with the changes from **OCI Private Key** and **config** files authorization to **OCI Resource Principal** authorization. Remember to rename the **authRPApi.py** to **func.py** and build your function to test.
|
||||
|
||||
|
||||
## Vault Secret
|
||||
|
||||
Another way to not expose sensitive data is using **OCI Vault**.
|
||||
You can configure a [Vault](https://www.ateam-oracle.com/post/using-the-oci-instance-principals-and-vault-with-python-to-retrieve-a-secret) to store your sensitive data like passwords, endpoints, etc.
|
||||
|
||||

|
||||
|
||||
You can create a **Vault** and the secrets for use in your function code:
|
||||
|
||||

|
||||
|
||||
This is the code to obtain the secret value after the **base64** translation.
|
||||
|
||||

|
||||
|
||||
Now, you can specify the **Secret OCID** to obtain the secret. The code are protected by **Resource Principal**.
|
||||
|
||||
Declare the method to obtain and decode **base64**:
|
||||
|
||||
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
|
||||
|
||||
|
||||
Declare the initialization for your secret client:
|
||||
|
||||
secret_client = oci.secrets.SecretsClient(config={}, signer=signer)
|
||||
|
||||
Then you can obtain the secret value specifying your secret **OCID**:
|
||||
|
||||
ClientId = read_secret_value(secret_client, "ocid1.vaultsecret.oc1.iad.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
|
||||
ClientSecret = read_secret_value(secret_client, "ocid1.vaultsecret.oc1.iad.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
|
||||
|
||||
|
||||
See the [authRPApi.py](./files/authApi/authRPApi.py) code with the changes to obtain your secrets. Remember to rename the **authRPApi.py** to **func.py** and build your function to test.
|
||||
|
||||
## applyValidationApi
|
||||
|
||||
The validation from OpenAPI spec is not possible today. The OCI API Gateway can implement validations with Authorization function. In the process of deploying the API from the OpenAPI spec, we can get the definitions and save it as a HEADER transformation, OCI API Gateway can do it for us, but cannot be used inside the authorization function because the HEADER transformation cannot be loaded in the function runtime execution.
|
||||
@@ -160,7 +280,7 @@ The validation respecting the Swagger 2.0 spec can be done by this component: [S
|
||||
|
||||
The authorization function is deployed in the proxy API deployment and in the real API deployment, but the validation of the spec will be done only in the real API layer and **if** the HEADER **body_schema_validation** has a content.
|
||||
|
||||

|
||||

|
||||
|
||||
You need to deploy the API (you can see the **deployment** file [applyValidationApi.json](./files/applyValidationApi/applyValidationApi.json) in JSON format to understand the parameters):
|
||||
|
||||
@@ -237,6 +357,10 @@ To create an automation to:
|
||||
- In the OpenAPI 3 spec, when there is no path_prefix, the service adopts the first path from the spec. Example: path=/v1/test/service ==> path_prefix will be /v1 and path will be /test/service. Not guarantee that **OCI API Gateway** release adopts this approach
|
||||
- The services does not implement all specifications from Swagger and OpenAPI
|
||||
|
||||
## Disclaimer
|
||||
|
||||
>**IMPORTANT**: The source code must be used at your own risk. There is no support and/or link with any company. The source code is free to modify and was built solely for the purpose of helping the community
|
||||
|
||||
## Acknowledgments
|
||||
|
||||
- Author: Cristiano Hoshikawa (Oracle LAD A-Team Solution Engineer)
|
||||
@@ -253,4 +377,6 @@ To create an automation to:
|
||||
- [Swagger schema validator](https://pypi.org/project/bravado-core/)
|
||||
- [Adding Context Variables to Policies and HTTP Back End Definitions](https://docs.oracle.com/en-us/iaas/Content/APIGateway/Tasks/apigatewaycontextvariables.htm)
|
||||
- [IDCS API Rate Limits](https://docs.oracle.com/en/cloud/paas/identity-cloud/uaids/oracle-identity-cloud-service-pricing-models.html#GUID-C1505A67-9C21-484A-8395-04C4253FA1CD)
|
||||
- [Create Policies to Control Access to Network and API Gateway-Related Resources](https://docs.oracle.com/en-us/iaas/Content/APIGateway/Tasks/apigatewaycreatingpolicies.htm)
|
||||
- [Create Policies to Control Access to Network and API Gateway-Related Resources](https://docs.oracle.com/en-us/iaas/Content/APIGateway/Tasks/apigatewaycreatingpolicies.htm)
|
||||
- [SDK Authentication Methods](https://docs.oracle.com/en-us/iaas/Content/API/Concepts/sdk_authentication_methods.htm)
|
||||
- [Using the OCI Instance Principals and Vault with Python to retrieve a Secret](https://www.ateam-oracle.com/post/using-the-oci-instance-principals-and-vault-with-python-to-retrieve-a-secret)
|
||||
|
||||
BIN
files/.DS_Store
vendored
Normal file
@@ -6,6 +6,9 @@ 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
|
||||
@@ -46,6 +49,60 @@ def find_base_path(strPath):
|
||||
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):
|
||||
@@ -125,12 +182,40 @@ def applyAuthApi(compartmentId, displayName, payload, functionId, host, api_gate
|
||||
routes = [ ]
|
||||
new_routes = [ ]
|
||||
for item in payload:
|
||||
methods = json.loads(json.dumps(item["METHOD"].split(" ")))
|
||||
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"] != ""):
|
||||
callback_url = ("https://" + host + item["PATH_PREFIX"] + "validation-callback" + item["PATH"]).replace("{", "${request.path[").replace("}", "]}")
|
||||
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.amaaaaaanamaaaaaanamaaaaaanamaaaaaanamaaaaaanamaaaaaanamaaaaaan",
|
||||
log_id="ocid1.log.oc1.iad.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
||||
put_logs_details=oci.loggingingestion.models.PutLogsDetails(
|
||||
specversion="EXAMPLE-specversion-Value",
|
||||
log_entry_batches=[
|
||||
@@ -141,6 +226,23 @@ def applyAuthApi(compartmentId, displayName, payload, functionId, host, api_gate
|
||||
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"],
|
||||
@@ -150,14 +252,9 @@ def applyAuthApi(compartmentId, displayName, payload, functionId, host, api_gate
|
||||
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")]),
|
||||
)
|
||||
header_transformations=header_transformation,
|
||||
query_parameter_validations=query_parameter_validation,
|
||||
header_validations=header_validation
|
||||
)))
|
||||
new_routes.append(
|
||||
oci.apigateway.models.ApiSpecificationRoute(
|
||||
@@ -168,19 +265,21 @@ def applyAuthApi(compartmentId, displayName, payload, functionId, host, api_gate
|
||||
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")]),
|
||||
)
|
||||
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(
|
||||
@@ -189,6 +288,7 @@ def applyAuthApi(compartmentId, displayName, payload, functionId, host, api_gate
|
||||
is_ssl_verify_disabled=False),
|
||||
methods=methods))
|
||||
|
||||
|
||||
if (new_routes != [ ]):
|
||||
validation_deployment_details=oci.apigateway.models.UpdateDeploymentDetails(
|
||||
display_name=displayName + "-validation",
|
||||
@@ -202,8 +302,10 @@ def applyAuthApi(compartmentId, displayName, payload, functionId, host, api_gate
|
||||
parameters={
|
||||
'token': 'request.headers[token]',
|
||||
'body': 'request.body',
|
||||
'body_schema_validation': 'request.headers[body_schema_validation]'},
|
||||
cache_key=["token"],
|
||||
'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",
|
||||
@@ -226,8 +328,10 @@ def applyAuthApi(compartmentId, displayName, payload, functionId, host, api_gate
|
||||
parameters={
|
||||
'token': 'request.headers[token]',
|
||||
'body': 'request.body',
|
||||
'body_schema_validation': 'request.headers[body_schema_validation]'},
|
||||
cache_key=["token"],
|
||||
'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",
|
||||
@@ -238,33 +342,12 @@ def applyAuthApi(compartmentId, displayName, payload, functionId, host, api_gate
|
||||
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 != [ ]):
|
||||
# apigateway_client.update_deployment(deployment_id=deployment_id, update_deployment_details=oci.apigateway.models.UpdateDeploymentDetails(
|
||||
# display_name=displayName,
|
||||
# specification=oci.apigateway.models.ApiSpecification(
|
||||
# request_policies=oci.apigateway.models.ApiSpecificationRequestPolicies(
|
||||
# authentication=oci.apigateway.models.CustomAuthenticationPolicy(
|
||||
# type="CUSTOM_AUTHENTICATION",
|
||||
# function_id=functionId,
|
||||
# is_anonymous_access_allowed=False,
|
||||
# parameters={
|
||||
# 'token': 'request.headers[token]',
|
||||
# 'body': 'request.body'},
|
||||
# cache_key=["token"])),
|
||||
# routes=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,
|
||||
authentication=oci.apigateway.models.CustomAuthenticationPolicy(
|
||||
type="CUSTOM_AUTHENTICATION",
|
||||
function_id=functionId,
|
||||
is_anonymous_access_allowed=False,
|
||||
parameters={
|
||||
'token': 'request.headers[token]',
|
||||
'body': 'request.body'},
|
||||
cache_key=["token"])),
|
||||
rate_limiting=rate_limiting),
|
||||
routes=routes))
|
||||
|
||||
create_deployment_details=oci.apigateway.models.CreateDeploymentDetails(
|
||||
@@ -274,67 +357,60 @@ def applyAuthApi(compartmentId, displayName, payload, functionId, host, api_gate
|
||||
path_prefix= path_prefix,
|
||||
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'},
|
||||
cache_key=["token"])),
|
||||
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 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"]:
|
||||
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"]:
|
||||
METHOD = (METHOD + " " + method).lstrip().upper()
|
||||
return METHOD
|
||||
|
||||
def check_endpoint(endpoint):
|
||||
if (endpoint.find("http://") == -1 and endpoint.find("https://") == -1):
|
||||
endpoint = "https://" + endpoint
|
||||
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):
|
||||
config = oci.config.from_file("config")
|
||||
logging = oci.loggingingestion.LoggingClient(config)
|
||||
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"],
|
||||
'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"
|
||||
@@ -365,115 +441,169 @@ def process_api_spec(api_id, compartmentId, environment, swagger, functionId, ho
|
||||
|
||||
json_data_list = []
|
||||
|
||||
endPointOrigin = endPoint
|
||||
for spec in api_spec["routes"]:
|
||||
status = spec["backend"]["status"]
|
||||
if (version == "3"):
|
||||
fullEndpoint = (endPoint + find_base_path(spec["path"]) + find_path(spec["path"])).replace("{", "${request.path[").replace("}", "]}")
|
||||
FULL_PATH = spec["path"]
|
||||
ENDPOINT = fullEndpoint
|
||||
PATH = find_path(spec["path"])
|
||||
PATH_PREFIX = find_base_path(spec["path"])
|
||||
METHOD = accMethods(api_spec["routes"], PATH, status)
|
||||
else:
|
||||
fullEndpoint = check_endpoint((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)
|
||||
specPath = spec["path"]
|
||||
|
||||
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 = ""
|
||||
for method in spec["methods"]:
|
||||
METHOD = method.lstrip().upper()
|
||||
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:
|
||||
|
||||
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 = ""
|
||||
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)
|
||||
put_logs_response = logging.put_logs(
|
||||
log_id="ocid1.log.oc1.iad.amaaaaaanamaaaaaanamaaaaaanamaaaaaanamaaaaaanamaaaaaanamaaaaaan",
|
||||
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,
|
||||
'CONTENT_TYPE': CONTENT_TYPE
|
||||
}),
|
||||
id="ocid1.test.oc1..00000001.EXAMPLE-id-Value")],
|
||||
source="EXAMPLE-source-Value",
|
||||
type="EXAMPLE-type-Value")]))
|
||||
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)
|
||||
json_data_list = { each['PATH'] : each for each in json_data_list}.values()
|
||||
put_logs_response = logging.put_logs(
|
||||
log_id="ocid1.log.oc1.iad.amaaaaaanamaaaaaanamaaaaaanamaaaaaanamaaaaaanamaaaaaanamaaaaaan",
|
||||
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: " + str(json_data_list),
|
||||
data="json_data_list: " + payload,
|
||||
id="ocid1.test.oc1..00000001.EXAMPLE-id-Value")],
|
||||
source="EXAMPLE-source-Value",
|
||||
type="EXAMPLE-type-Value")]))
|
||||
|
||||
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(json_data_list))
|
||||
print(payload)
|
||||
applyAuthApi(compartmentId=compartmentId, displayName=API_NAME, payload=json_data_list, functionId=functionId, host=host, api_gateway_id=api_gateway_id, rate_limit=rate_limit)
|
||||
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:
|
||||
jsonData = 'error parsing json payload: ' + str(ex)
|
||||
put_logs_response = logging.put_logs(
|
||||
log_id="ocid1.log.oc1.iad.amaaaaaanamaaaaaanamaaaaaanamaaaaaanamaaaaaanamaaaaaanamaaaaaan",
|
||||
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(3): " + jsonData,
|
||||
id="ocid1.test.oc1..00000001.EXAMPLE-id-Value")],
|
||||
source="EXAMPLE-source-Value",
|
||||
type="EXAMPLE-type-Value")]))
|
||||
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)
|
||||
|
||||
|
||||
###
|
||||
|
||||
@@ -494,13 +624,13 @@ def handler(ctx, data: io.BytesIO = None):
|
||||
body = dict(json.loads(data.getvalue().decode('utf-8')).get("data"))["body"]
|
||||
# body content
|
||||
swagger = str(body)
|
||||
body = json.loads(body)
|
||||
if (is_json(swagger)):
|
||||
body = json.loads(body)
|
||||
else:
|
||||
body = json.loads(convert_json(swagger))
|
||||
swagger = convert_json(swagger)
|
||||
|
||||
# functions context variables
|
||||
# fn config app ociapigw-app oci_region us-ashburn-1
|
||||
# fn config app ociapigw-app environment QA
|
||||
oci_region = app_context['oci_region']
|
||||
environment = app_context['environment']
|
||||
environment = "DEV"
|
||||
|
||||
# header values
|
||||
access_token = header["token"]
|
||||
@@ -522,7 +652,7 @@ def handler(ctx, data: io.BytesIO = None):
|
||||
except(Exception) as ex1:
|
||||
jsonData = 'error parsing json payload: ' + str(ex1)
|
||||
put_logs_response = logging.put_logs(
|
||||
log_id="ocid1.log.oc1.iad.amaaaaaanamaaaaaanamaaaaaanamaaaaaanamaaaaaanamaaaaaanamaaaaaan",
|
||||
log_id="ocid1.log.oc1.iad.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
||||
put_logs_details=oci.loggingingestion.models.PutLogsDetails(
|
||||
specversion="EXAMPLE-specversion-Value",
|
||||
log_entry_batches=[
|
||||
@@ -547,7 +677,6 @@ def handler(ctx, data: io.BytesIO = None):
|
||||
"active": True,
|
||||
"context": {
|
||||
"environment": environment,
|
||||
"oci_region": oci_region,
|
||||
"api_id": api_id
|
||||
}})
|
||||
|
||||
@@ -560,7 +689,7 @@ def handler(ctx, data: io.BytesIO = None):
|
||||
except(Exception) as ex:
|
||||
jsonData = 'error parsing json payload: ' + str(ex)
|
||||
put_logs_response = logging.put_logs(
|
||||
log_id="ocid1.log.oc1.iad.amaaaaaanamaaaaaanamaaaaaanamaaaaaanamaaaaaanamaaaaaanamaaaaaan",
|
||||
log_id="ocid1.log.oc1.iad.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
||||
put_logs_details=oci.loggingingestion.models.PutLogsDetails(
|
||||
specversion="EXAMPLE-specversion-Value",
|
||||
log_entry_batches=[
|
||||
|
||||
@@ -6,4 +6,4 @@ six
|
||||
PyJWT
|
||||
py3_lru_cache
|
||||
simplejson
|
||||
|
||||
PyYAML
|
||||
|
||||
169
files/authApi/Redaction.py
Normal 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
@@ -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})
|
||||
)
|
||||
@@ -10,6 +10,43 @@ 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
|
||||
@@ -40,6 +77,42 @@ def beautify_str(str_msg):
|
||||
|
||||
###
|
||||
|
||||
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)
|
||||
@@ -57,6 +130,25 @@ def handler(ctx, data: io.BytesIO = None):
|
||||
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)
|
||||
@@ -75,44 +167,43 @@ def handler(ctx, data: io.BytesIO = None):
|
||||
# header values
|
||||
access_token = header["token"]
|
||||
|
||||
if (body_schema_validation == None):
|
||||
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)
|
||||
}})
|
||||
|
||||
authorization = auth_idcs(access_token, url, ClientId, ClientSecret)
|
||||
try:
|
||||
if (authorization.json().get("active") != True):
|
||||
return response.Response(
|
||||
ctx,
|
||||
status_code=401,
|
||||
response_data=rdata
|
||||
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,
|
||||
@@ -124,7 +215,7 @@ def handler(ctx, data: io.BytesIO = None):
|
||||
# Validate API spec
|
||||
if (body_schema_validation != None):
|
||||
if (".apigatewayapi." not in header["body_schema_validation"]):
|
||||
# Version OpenAPI 3
|
||||
# Com validacao direto por propriedades (sem schemas e referencias)
|
||||
try:
|
||||
validate(body, body_schema_validation["schema"])
|
||||
return response.Response(
|
||||
@@ -134,6 +225,8 @@ def handler(ctx, data: io.BytesIO = None):
|
||||
)
|
||||
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(
|
||||
@@ -162,7 +255,7 @@ def handler(ctx, data: io.BytesIO = None):
|
||||
response_data=rdata
|
||||
)
|
||||
else:
|
||||
# Version Swagger 2
|
||||
# Com schema de validação - Tanto swagger como Open API 3
|
||||
try:
|
||||
bravado_config = {
|
||||
'validate_swagger_spec': False,
|
||||
@@ -174,11 +267,21 @@ def handler(ctx, data: io.BytesIO = None):
|
||||
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)
|
||||
schema = spec_dict["definitions"][contents[0]]
|
||||
validate_object(spec, schema, body)
|
||||
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(
|
||||
|
||||
@@ -4,6 +4,8 @@ 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
|
||||
@@ -121,19 +123,27 @@ def process_api_spec(displayName, compartmentId, environment, swagger):
|
||||
return api_id
|
||||
|
||||
except(Exception) as ex:
|
||||
jsonData = 'error parsing json payload: ' + str(ex)
|
||||
put_logs_response = logging.put_logs(
|
||||
log_id="ocid1.log.oc1.iad.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
||||
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")]))
|
||||
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)
|
||||
|
||||
###
|
||||
|
||||
@@ -154,9 +164,13 @@ def handler(ctx, data: io.BytesIO = None):
|
||||
body = dict(json.loads(data.getvalue().decode('utf-8')).get("data"))["body"]
|
||||
# body content
|
||||
swagger = str(body)
|
||||
body = json.loads(body)
|
||||
if (is_json(swagger)):
|
||||
body = json.loads(body)
|
||||
else:
|
||||
body = json.loads(convert_json(swagger))
|
||||
swagger = convert_json(swagger)
|
||||
|
||||
environment = "DEV" #for future development
|
||||
environment = "DEV"
|
||||
|
||||
# header values
|
||||
access_token = header["token"]
|
||||
@@ -174,17 +188,17 @@ def handler(ctx, data: io.BytesIO = None):
|
||||
except(Exception) as ex1:
|
||||
jsonData = 'error parsing json payload: ' + str(ex1)
|
||||
put_logs_response = logging.put_logs(
|
||||
log_id="ocid1.log.oc1.iad.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
||||
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")]))
|
||||
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,
|
||||
@@ -196,23 +210,37 @@ def handler(ctx, data: io.BytesIO = None):
|
||||
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)
|
||||
}})
|
||||
"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}
|
||||
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.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
||||
log_id="ocid1.log.oc1.iad.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
||||
put_logs_details=oci.loggingingestion.models.PutLogsDetails(
|
||||
specversion="EXAMPLE-specversion-Value",
|
||||
log_entry_batches=[
|
||||
|
||||
@@ -6,4 +6,4 @@ six
|
||||
PyJWT
|
||||
py3_lru_cache
|
||||
simplejson
|
||||
|
||||
PyYAML
|
||||
|
||||
7
files/test/config
Normal 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
@@ -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"
|
||||
}
|
||||
27
files/test/oci_api_key.pem
Normal 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-----
|
||||
681
files/test/process_api_spec.py
Normal 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"])
|
||||
9
files/test/requirements.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
fdk>=0.1.54
|
||||
requests
|
||||
oci
|
||||
cryptography
|
||||
six
|
||||
PyJWT
|
||||
py3_lru_cache
|
||||
simplejson
|
||||
PyYAML
|
||||
|
Before Width: | Height: | Size: 242 KiB After Width: | Height: | Size: 489 KiB |
|
Before Width: | Height: | Size: 151 KiB After Width: | Height: | Size: 90 KiB |
BIN
images/base64translatecode.png
Normal file
|
After Width: | Height: | Size: 54 KiB |
BIN
images/img_8.png
|
Before Width: | Height: | Size: 392 KiB After Width: | Height: | Size: 546 KiB |
BIN
images/import-bravado.png
Normal file
|
After Width: | Height: | Size: 39 KiB |
BIN
images/json_yaml_format.png
Normal file
|
After Width: | Height: | Size: 80 KiB |
BIN
images/json_yaml_format_1.png
Normal file
|
After Width: | Height: | Size: 71 KiB |
BIN
images/main-redact-routine.png
Normal file
|
After Width: | Height: | Size: 286 KiB |
BIN
images/redact-code.png
Normal file
|
After Width: | Height: | Size: 246 KiB |
BIN
images/redact-response.png
Normal file
|
After Width: | Height: | Size: 42 KiB |
BIN
images/redaction-1.png
Normal file
|
After Width: | Height: | Size: 224 KiB |
BIN
images/redaction-2.png
Normal file
|
After Width: | Height: | Size: 126 KiB |
BIN
images/redaction-3.png
Normal file
|
After Width: | Height: | Size: 44 KiB |
BIN
images/redaction-4.png
Normal file
|
After Width: | Height: | Size: 65 KiB |
BIN
images/resourceprincipal-1.png
Normal file
|
After Width: | Height: | Size: 6.5 KiB |
BIN
images/resourceprincipal-2.png
Normal file
|
After Width: | Height: | Size: 9.8 KiB |
BIN
images/resourceprincipal-3.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
images/resourceprincipal-4.png
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
images/resourceprincipal-5.png
Normal file
|
After Width: | Height: | Size: 391 KiB |
BIN
images/vault-1.png
Normal file
|
After Width: | Height: | Size: 164 KiB |