36 Commits
v2 ... main

Author SHA1 Message Date
110ba4146a reset 2025-10-29 09:25:48 -03:00
8cce6df501 reset 2025-10-29 09:25:31 -03:00
7ec28a84b7 reset 2025-10-29 09:24:51 -03:00
a9bbb8aba3 adjustments in redaction code 2024-09-10 17:15:03 -03:00
c2385c6cda bug em CONTENT_TYPE 2024-09-10 10:02:47 -03:00
a16bc3fd8d Redaction comments 2024-09-05 08:52:50 -03:00
099174acfb Redaction comments 2024-09-05 08:44:21 -03:00
212c732699 Disclaimer 2024-09-03 21:11:39 -03:00
da001e46ae Funcionalidade Adicional: Autenticação por Resource Principal e Vault. 2024-09-02 08:46:31 -03:00
32aa6cd977 Funcionalidade Adicional: Autenticação por Resource Principal e Vault. 2024-09-02 08:41:31 -03:00
270487ddb5 Funcionalidade Adicional: Autenticação por Resource Principal e Vault. 2024-08-30 20:46:50 -03:00
1871cad962 Funcionalidade Nova: implementação das validações nativas de header e query parameter no API Gateway. Não faz a validação de tipos, apenas as obrigatoriedades 2024-06-27 01:48:43 -03:00
706454f2ba Caso de uso para mesmo PATH com vários métodos. Neste caso, um dos métodos não possui validação de schema e os demais possuem. Antes da correção, há validação de schema para todos os métodos deste mesmo PATH. A correção foi feita para separar o deployment do mesmo PATH em linhas diferentes, para que a validação de schema (body_validation_schema) seja feita apenas aonde deve ser. 2024-06-20 08:02:45 -03:00
8ca2eed36e ajustes, incluindo a opção \. e trocando por [.] 2024-06-06 08:58:47 -03:00
67fbce9fec Adaptação: os patterns na especificação não funcionam corretamente com a \ por problemas de escape characters. JSON e regex não vão funcionar corretamente por problemas de conversão entre as bibliotecas. Foi feita uma adaptação para substituir alguns patterns com \ por outras opções.
- `\d`: Corresponde a qualquer dígito decimal; isso é equivalente à classe `[0-9]`.
- `\D`: Corresponde a qualquer caractere que não seja um dígito decimal; isso é equivalente à classe `[^0-9]`.
- `\w`: Corresponde a qualquer caractere alfanumérico; isso é equivalente à classe `[a-zA-Z0-9_]`.
- `\W`: Corresponde a qualquer caractere não-alfanumérico; isso é equivalente à classe `[^a-zA-Z0-9_]`.
- `\s`: Corresponde a qualquer caractere de espaço em branco; isso é equivalente à classe `[ \t\n\r\f\v]`.
- `\S`: Corresponde a qualquer caractere que não seja um espaço em branco; isso é equivalente à classe `[^ \t\n\r\f\v]`.
- `\b`: Corresponde a uma fronteira de palavra, um lugar onde um caractere `\w` é seguido ou precedido por um caractere `\W`.
- `\B`: Corresponde a um local onde a fronteira de uma palavra não é encontrada.
- `\\`: Corresponde a uma única barra invertida `\`.
- `\A`: Corresponde ao início da string.
- `\Z`: Corresponde ao fim da string.

Como se pode notar, \s, \S, \b, \B, \\, \A e \Z não estão cobertos neste ajuste.
2024-06-05 00:08:17 -03:00
7892d3436e Melhoria: A performance do deployment deve melhorar bastante pois só haverá uma única autenticação por function, na segunda camada. Avaliando o custo-beneficio de ter ou não ter a segunda camada, é melhor SEMPRE ter a segunda camada para permitir autenticar uma unica vez. 2024-05-20 07:38:53 -03:00
dde52b26eb Correção. Não estava ocorrendo a validação de schema_body_validation para open api 3, pois estava validando somente quando a especificação estava configurada para propriedades diretamente. Caso as validações fossem declaradas em schema (requestBody/Content/application/json/schema/$ref/#components/schemas) a validação em authAPI não executava (simplesmente ignora a validação).
É necessário re-executar o applyValidationAPI para reimplantar as APIs pois precisa acertar o schema_body_validation dos headers.
Precisa fazer a autenticação na 1a e na 2a camada de api (validation-callback) pois pode-se chamar a 2a camada diretamente.
2024-05-18 20:26:48 -03:00
6b417d0151 Correção. Não estava ocorrendo a validação de schema_body_validation para open api 3, pois estava validando somente quando a especificação estava configurada para propriedades diretamente. Caso as validações fossem declaradas em schema (requestBody/Content/application/json/schema/$ref/#components/schemas) a validação em authAPI não executava (simplesmente ignora a validação).
É necessário re-executar o applyValidationAPI para reimplantar as APIs pois precisa acertar o schema_body_validation dos headers.
2024-05-18 10:55:28 -03:00
91400737e2 Correção, estava ocorrendo falso-positivo, com mensagem 200 mesmo com erro na validação das especificações. 2024-04-30 11:47:35 -03:00
01f1f73e49 Correção, as APIs implantadas estavam com cache de autorização e se ocorresse erro, a execução seguinte não valida o schema do swagger/open api 3 2024-04-23 07:50:54 -03:00
73560c2fa0 Correção, o appyAuthAPI não estava enviando a ultima transformação (payload), estava enviando o json_data_list. No teste estava ocorrendo corretamente pois não enviava para o API Gateway. 2024-03-30 12:05:40 -03:00
6210668600 Correção, o appyAuthAPI não estava enviando a ultima transformação (payload), estava enviando o json_data_list. No teste estava ocorrendo corretamente pois não enviava para o API Gateway. 2024-03-26 14:53:23 -03:00
5971bfb3f7 Teste para applyValidationAPI() no folder test 2024-03-26 13:59:46 -03:00
bc4276087c Correção: Após a correção da montagem dos paths (paths fazendo parte do próprio host na especificação), faltou corrigir o agrupamento dos métodos. Logo foi criada versão nova acc_methods_v3() para contemplar a correção dos paths. 2024-03-25 21:18:21 -03:00
14b8350ff7 Correção: Após a correção da montagem dos paths (paths fazendo parte do próprio host na especificação), faltou corrigir o agrupamento dos métodos. Logo foi criada versão nova acc_methods_v3() para contemplar a correção dos paths. 2024-03-25 21:18:07 -03:00
a8313cb914 Correção: Após a correção da montagem dos paths (paths fazendo parte do próprio host na especificação), faltou corrigir o agrupamento dos métodos. Logo foi criada versão nova acc_methods_v3() para contemplar a correção dos paths. 2024-03-25 13:07:27 -03:00
2de174b2e4 Correção: Não estava montando o path_prefix correto (obtendo apenas o 1o path) para a versão Swagger 2024-03-22 13:06:50 -03:00
76d7f30e1a Correção: Não estava montando o path_prefix correto (obtendo apenas o 1o path) para a versão Swagger 2024-03-22 07:38:54 -03:00
6343721d66 Correção: Não estava inserindo parte do path do host caso houvesse mais de 1 path aninhado 2024-03-20 20:40:01 -03:00
9f88574064 Correção dos casos:
- Setando como path_prefix o titulo da API ocasiona erro pois o titulo contem espacos em branco
2024-03-18 21:58:29 -03:00
65812cf3da Correção dos casos:
- Setando como path_prefix o titulo da API ocasiona erro pois o titulo contem espacos em branco
2024-03-18 16:54:58 -03:00
2349b97f77 Correção dos casos:
- Setando como path_prefix o titulo da API ocasiona erro pois o titulo contem espacos em branco
2024-03-15 20:39:37 -03:00
b42a644ce3 Correção dos casos:
- Host não pode ser caminho inválido. Melhor optar por IP caso seja um mock-up ao invés de colocar um endpoint inválido pois o API Gateway testa
- schema: Se o host não estiver com http:// ou https:// o serviço não estava pegando de schema. Corrigido
2024-03-11 10:27:31 -03:00
98266a1b7d New Release. This version can import JSON or YAML API format (OpenAPI or Swagger) 2024-02-15 21:35:27 -03:00
15cfd2d2f3 New Release. This version can import JSON or YAML API format (OpenAPI or Swagger) 2024-02-15 13:50:09 -03:00
1fc4aad29d New Release. This version can import JSON or YAML API format (OpenAPI or Swagger) 2024-02-15 10:03:29 -03:00
36 changed files with 1919 additions and 280 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

142
README.md
View File

@@ -69,6 +69,14 @@ And this is the **config.json** file for **IDCS** configuration.
![img.png](images/idcs-config.png)
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:
![img.png](images/json_yaml_format.png)
This methods will be used to mantain the specification in **JSON** default format for all codes.
![img_1.png](images/json_yaml_format_1.png)
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.
![img_1.png](images/authApi_2.png)
![img.png](images/authApi_2.png)
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**)
![img_2.png](images/authApi_3.png)
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
![img_3.png](images/authApi_4.png)
![img.png](images/authApi_4.png)
## 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**.
![import-bravado.png](images/import-bravado.png)
This code is responsible to beautify your validation response:
![redact-code.png](images/redact-code.png)
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:
![main-redact-routine.png](images/main-redact-routine.png)
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:
![redaction-2.png](images/redaction-2.png)
So you can use the library like this:
![redaction-1.png](images/redaction-1.png)
When you request an REST service with this body content:
![img.png](images/redaction-4.png)
The response will be something like this:
![redaction-3.png](images/redaction-3.png)
## 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**
![img.png](images/resourceprincipal-1.png)
**Policy**
![img_1.png](images/resourceprincipal-2.png)
You need to replace your code:
![img_2.png](images/resourceprincipal-3.png)
with
![img_3.png](images/resourceprincipal-4.png)
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.
![img_4.png](images/resourceprincipal-5.png)
You can create a **Vault** and the secrets for use in your function code:
![img_5.png](images/vault-1.png)
This is the code to obtain the secret value after the **base64** translation.
![img.png](images/base64translatecode.png)
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.
![img_8.png](images/img_8.png)
![img.png](images/img_8.png)
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

Binary file not shown.

View 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=[

View File

@@ -6,4 +6,4 @@ six
PyJWT
py3_lru_cache
simplejson
PyYAML

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

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

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

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

View File

@@ -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(

View File

@@ -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=[

View File

@@ -6,4 +6,4 @@ six
PyJWT
py3_lru_cache
simplejson
PyYAML

7
files/test/config Normal file
View File

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

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

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

View File

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

View File

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

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 242 KiB

After

Width:  |  Height:  |  Size: 489 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 151 KiB

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 392 KiB

After

Width:  |  Height:  |  Size: 546 KiB

BIN
images/import-bravado.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

BIN
images/json_yaml_format.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 286 KiB

BIN
images/redact-code.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 246 KiB

BIN
images/redact-response.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

BIN
images/redaction-1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 KiB

BIN
images/redaction-2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

BIN
images/redaction-3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

BIN
images/redaction-4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 391 KiB

BIN
images/vault-1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 KiB