diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 3654d237..8ed3a188 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -8,7 +8,6 @@ - [ ] Onboarding - [ ] Mdz - [ ] Transaction -- [ ] Audit - [ ] Pipeline - [ ] Documentation diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f3352f56..7b919124 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -17,8 +17,6 @@ jobs: strategy: matrix: app: - - name: "midaz-audit" - working_dir: "components/audit" - name: "midaz-onboarding" working_dir: "components/onboarding" - name: "midaz-transaction" diff --git a/.github/workflows/env-vars-pr-notification.yml b/.github/workflows/env-vars-pr-notification.yml index 9ab32be8..905f89c4 100644 --- a/.github/workflows/env-vars-pr-notification.yml +++ b/.github/workflows/env-vars-pr-notification.yml @@ -36,7 +36,7 @@ jobs: CHANGED=false # Verificando se os arquivos .env.example mudaram - for file in $(git diff --name-only $PREVIOUS_COMMIT $CURRENT_COMMIT | grep -E 'components/(audit|auth|infra|ledger|mdz|transaction)/.*\.env.example'); do + for file in $(git diff --name-only $PREVIOUS_COMMIT $CURRENT_COMMIT | grep -E 'components/(auth|infra|ledger|mdz|transaction)/.*\.env.example'); do # Exibindo qual arquivo estamos verificando echo "Checking file: $file" diff --git a/.github/workflows/midaz-update-repos.yml b/.github/workflows/midaz-update-repos.yml index dfc47774..a40dc00a 100644 --- a/.github/workflows/midaz-update-repos.yml +++ b/.github/workflows/midaz-update-repos.yml @@ -112,9 +112,6 @@ jobs: env: GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} run: | - cp midaz/components/audit/api/swagger.json LerianStudio.github.io/audit/ - cp midaz/components/audit/api/openapi.yaml LerianStudio.github.io/audit/ - cp midaz/components/onboarding/api/swagger.json LerianStudio.github.io/onboarding/ cp midaz/components/onboarding/api/openapi.yaml LerianStudio.github.io/onboarding/ @@ -137,7 +134,7 @@ jobs: git remote set-url origin https://${{ secrets.MANAGE_TOKEN }}@github.com/LerianStudio/LerianStudio.github.io.git - git add audit onboarding transaction + git add onboarding transaction git commit -S -m "Update openapi.yaml and swagger.json from Repositories" git push origin main diff --git a/.github/workflows/update-env-version.yml b/.github/workflows/update-env-version.yml index 5101f850..7e31cb33 100644 --- a/.github/workflows/update-env-version.yml +++ b/.github/workflows/update-env-version.yml @@ -67,11 +67,6 @@ jobs: echo "LEDGER version: $VERSION" echo "::set-output name=version::$VERSION" - - name: Update AUDIT Env - if: steps.latest_release.outputs.tag != steps.env_release.outputs.version - run: | - sed -i "s/^VERSION=.*/VERSION=${{ steps.latest_release.outputs.tag }}/" ./components/audit/.env.example - - name: Update ONBOARDING Env if: steps.latest_release.outputs.tag != steps.env_release.outputs.version run: | diff --git a/Makefile b/Makefile index 23c135c3..903da98a 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,3 @@ -AUDIT_DIR := ./components/audit AUTH_DIR := ./components/auth INFRA_DIR := ./components/infra MDZ_DIR := ./components/mdz @@ -65,7 +64,6 @@ help: @echo " make infra Run a command inside the infra app in the components directory to see available commands." @echo " make onboarding Run a command inside the onboarding app in the components directory to see available commands." @echo " make transaction Run a command inside the transaction app in the components directory to see available commands." - @echo " make audit Run a command inside the audit app in the components directory to see available commands." @echo " make set-env Run a command to copy all .env.example to .env into respective folders." @echo " make all-services Run a command to all services passing any individual container command." @echo " make generate-docs-all Run a command to inside the onboarding and transaction app to generate swagger docs." @@ -77,7 +75,6 @@ help: @echo " make infra COMMAND= - Run command in infra service" @echo " make onboarding COMMAND= - Run command in onboarding service" @echo " make transaction COMMAND= - Run command in transaction service" - @echo " make audit COMMAND= - Run command in audit service" @echo " make all-services COMMAND= - Run command across all services" @echo " make clean-docker - Run command to clean docker" @echo "" @@ -157,7 +154,6 @@ set-env: cp -r $(ONBOARDING_DIR)/.env.example $(ONBOARDING_DIR)/.env cp -r $(TRANSACTION_DIR)/.env.example $(TRANSACTION_DIR)/.env cp -r $(MDZ_DIR)/.env.example $(MDZ_DIR)/.env - cp -r $(AUDIT_DIR)/.env.example $(AUDIT_DIR)/.env @echo "$(BLUE)Environment files created successfully$(NC)" .PHONY: up @@ -189,19 +185,13 @@ transaction: @echo "$(BLUE)Executing command in transaction service...$(NC)" $(MAKE) -C $(TRANSACTION_DIR) $(COMMAND) -.PHONY: audit -audit: - @echo "$(BLUE)Executing command in audit service...$(NC)" - $(MAKE) -C $(AUDIT_DIR) $(COMMAND) - .PHONY: all-services all-services: @echo "$(BLUE)Executing command across all services...$(NC)" $(MAKE) -C $(AUTH_DIR) $(COMMAND) && \ $(MAKE) -C $(INFRA_DIR) $(COMMAND) && \ $(MAKE) -C $(ONBOARDING_DIR) $(COMMAND) && \ - $(MAKE) -C $(TRANSACTION_DIR) $(COMMAND) && \ - $(MAKE) -C $(AUDIT_DIR) $(COMMAND) + $(MAKE) -C $(TRANSACTION_DIR) $(COMMAND) .PHONY: clean-docker clean-docker: @@ -225,5 +215,4 @@ tidy: generate-docs-all: @echo "$(BLUE)Executing command to generate swagger...$(NC)" $(MAKE) -C $(ONBOARDING_DIR) generate-docs && \ - $(MAKE) -C $(TRANSACTION_DIR) generate-docs && \ - $(MAKE) -C $(AUDIT_DIR) generate-docs + $(MAKE) -C $(TRANSACTION_DIR) generate-docs diff --git a/STRUCTURE.md b/STRUCTURE.md index fbda177b..649dbd86 100644 --- a/STRUCTURE.md +++ b/STRUCTURE.md @@ -29,58 +29,6 @@ MIDAZ | |-- chocolateyinstall.ps1 | `-- chocolateyuninstall.ps1 |-- components -| |-- audit -| | |-- Dockerfile -| | |-- Makefile -| | |-- api -| | | |-- docs.go -| | | |-- openapi.yaml -| | | |-- swagger.json -| | | `-- swagger.yaml -| | |-- artifacts -| | |-- cmd -| | | `-- app -| | | `-- main.go -| | |-- db -| | | `-- init.sql -| | |-- docker-compose.yml -| | `-- internal -| | |-- adapters -| | | |-- grpc -| | | | |-- in -| | | | `-- out -| | | | |-- trillian.grpc.go -| | | | `-- trillian.mock.go -| | | |-- http -| | | | |-- in -| | | | | |-- response.go -| | | | | |-- routes.go -| | | | | |-- swagger.go -| | | | | `-- trillian.go -| | | | `-- out -| | | |-- mongodb -| | | | `-- audit -| | | | |-- audit.go -| | | | |-- audit.mock.go -| | | | `-- audit.mongodb.go -| | | `-- rabbitmq -| | | |-- consumer.mock.go -| | | `-- consumer.rabbitmq.go -| | |-- bootstrap -| | | |-- config.go -| | | |-- consumer.go -| | | |-- server.go -| | | `-- service.go -| | `-- services -| | |-- create-log.go -| | |-- create-log_test.go -| | |-- get-audit-info.go -| | |-- get-audit-info_test.go -| | |-- get-log-by-hash.go -| | |-- get-log-by-hash_test.go -| | |-- usecase.go -| | |-- validate-log-hash.go -| | `-- validate-log-hash_test.go | |-- auth | | |-- Makefile | | |-- artifacts diff --git a/components/audit/.env.example b/components/audit/.env.example deleted file mode 100644 index dd3ca92f..00000000 --- a/components/audit/.env.example +++ /dev/null @@ -1,68 +0,0 @@ -# DEFAULT local -# ENV_NAME=production - -# APP -VERSION=v1.48.0 -SERVER_PORT=3002 -SERVER_ADDRESS=:${SERVER_PORT} - -# LOG LEVEL -LOG_LEVEL=debug - -# MONGO DB -#MONGO_URI=mongodb+srv -MONGO_URI=mongodb -MONGO_HOST=midaz-mongodb -MONGO_NAME=audit -MONGO_USER=midaz -MONGO_PASSWORD=lerian -MONGO_PORT=5703 - -# CASDOOR -CASDOOR_PORT=8080 -CASDOOR_ADDRESS=http://midaz-casdoor:${CASDOOR_PORT} -CASDOOR_CLIENT_ID=9670e0ca55a29a466d31 -CASDOOR_CLIENT_SECRET=dd03f916cacf4a98c6a413d9c38ba102dce436a9 -CASDOOR_ORGANIZATION_NAME=lerian -CASDOOR_APPLICATION_NAME=app-midaz -CASDOOR_MODEL_NAME=api-model -CASDOOR_JWK_ADDRESS=${CASDOOR_ADDRESS}/.well-known/jwks - -# OPEN TELEMETRY -OTEL_RESOURCE_SERVICE_NAME=audit -OTEL_LIBRARY_NAME=github.com/LerianStudio/midaz/components/audit -OTEL_RESOURCE_SERVICE_VERSION=${VERSION} -OTEL_RESOURCE_DEPLOYMENT_ENVIRONMENT=${ENV_NAME} -OTEL_EXPORTER_OTLP_ENDPOINT_PORT=4317 -OTEL_EXPORTER_OTLP_ENDPOINT=midaz-otel-lgtm:${OTEL_EXPORTER_OTLP_ENDPOINT_PORT} - -# RABBITMQ -RABBITMQ_URI=amqp -RABBITMQ_HOST=midaz-rabbitmq -RABBITMQ_PORT_HOST=3003 -RABBITMQ_PORT_AMPQ=3004 -RABBITMQ_DEFAULT_USER=audit -RABBITMQ_DEFAULT_PASS=lerian -RABBITMQ_QUEUE=audit.append_log.queue - -# TRILLIAN -TRILLIAN_DATABASE_NAME=audit-db -TRILLIAN_DATABASE_USER=midaz -TRILLIAN_DATABASE_PASSWORD=lerian -TRILLIAN_DATABASE_ROOT_PASSWORD=lerian -TRILLIAN_DATABASE_PORT=5705 -TRILLIAN_GRPC_PORT=8082 -TRILLIAN_HTTP_PORT=8083 -TRILLIAN_SIGNER_PORT=8084 -TRILLIAN_GRPC_ADDRESS=midaz-audit-server:${TRILLIAN_GRPC_PORT} -TRILLIAN_HTTP_ADDRESS=http://midaz-audit-server:${TRILLIAN_HTTP_PORT} - -# SWAGGER -SWAGGER_TITLE=Audit API -SWAGGER_DESCRIPTION=Documentation for the Midaz Audit API -SWAGGER_VERSION=${VERSION} -SWAGGER_HOST=${SERVER_ADDRESS} -SWAGGER_BASE_PATH=/ -SWAGGER_SCHEMES=http -SWAGGER_LEFT_DELIMITER={{ -SWAGGER_RIGHT_DELIMITER=}} \ No newline at end of file diff --git a/components/audit/Dockerfile b/components/audit/Dockerfile deleted file mode 100644 index 1359baa4..00000000 --- a/components/audit/Dockerfile +++ /dev/null @@ -1,19 +0,0 @@ -FROM golang:1.23-alpine AS builder - -WORKDIR /audit-app - -COPY go.mod go.sum ./ - -RUN go mod download - -COPY . . - -RUN CGO_ENABLED=0 GOOS=linux go build -a -tags netgo -ldflags '-w -extldflags "-static"' -o /app components/audit/cmd/app/main.go - -FROM gcr.io/distroless/static-debian12 - -COPY --from=builder /app /app - -EXPOSE 3002 - -ENTRYPOINT ["/app"] \ No newline at end of file diff --git a/components/audit/Makefile b/components/audit/Makefile deleted file mode 100644 index a9828017..00000000 --- a/components/audit/Makefile +++ /dev/null @@ -1,95 +0,0 @@ -service_name := audit-service -bin_dir := ./.bin -artifacts_dir := ./artifacts - -$(shell mkdir -p $(artifacts_dir)) - -DOCKER_VERSION := $(shell docker version --format '{{.Server.Version}}') -DOCKER_MIN_VERSION := 20.10.13 - -DOCKER_CMD := $(shell \ - if [ "$(shell printf '%s\n' "$(DOCKER_MIN_VERSION)" "$(DOCKER_VERSION)" | sort -V | head -n1)" = "$(DOCKER_MIN_VERSION)" ]; then \ - echo "docker compose"; \ - else \ - echo "docker-compose"; \ - fi \ -) - -# Display available commands -.PHONY: info -info: - @echo " " - @echo " " - @echo "To run a specific command inside the audit container using make, you can execute: " - @echo " " - @echo "make audit COMMAND=\"any\" " - @echo " " - @echo "This command will run the specified command inside the audit container. Replace \"any\" with the desired command you want to execute. " - @echo " " - @echo "## Docker commands:" - @echo " " - @echo " COMMAND=\"build\" Builds all Docker images defined in docker-compose.yml." - @echo " COMMAND=\"up\" Starts and runs all services defined in docker-compose.yml." - @echo " COMMAND=\"start\" Starts existing containers defined in docker-compose.yml without creating them." - @echo " COMMAND=\"stop\" Stops running containers defined in docker-compose.yml without removing them." - @echo " COMMAND=\"down\" Stops and removes containers, networks, and volumes defined in docker-compose.yml." - @echo " COMMAND=\"destroy\" Stops and removes containers, networks, and volumes (including named volumes) defined in docker-compose.yml." - @echo " COMMAND=\"restart\" Stops and removes containers, networks, and volumes, then starts all services in detached mode." - @echo " COMMAND=\"logs\" Shows the last 100 lines of logs and follows live log output for services defined in docker-compose.yml." - @echo " COMMAND=\"logs-api\" Shows the last 100 lines of logs and follows live log output for the audit service defined in docker-compose.yml." - @echo " COMMAND=\"ps\" Lists the status of containers defined in docker-compose.yml." - @echo " " - @echo "## App commands:" - @echo " " - @echo " COMMAND=\"generate-docs\" Generates Swagger API documentation and an OpenAPI Specification." - @echo " " - @echo " " - -# Docker Compose Commands -.PHONY: build -build: - @$(DOCKER_CMD) -f docker-compose.yml build $(c) - -.PHONY: up -up: - @$(DOCKER_CMD) -f docker-compose.yml up $(c) -d - -.PHONY: start -start: - @docker compose -f docker-compose.yml start $(c) - -.PHONY: down -down: - @$(DOCKER_CMD) -f docker-compose.yml down $(c) - -.PHONY: destroy -destroy: - @$(DOCKER_CMD) -f docker-compose.yml down -v $(c) - -.PHONY: stop -stop: - @$(DOCKER_CMD) -f docker-compose.yml stop $(c) - -.PHONY: restart -restart: - make stop && \ - make up - -.PHONY: logs -logs: - @$(DOCKER_CMD) -f docker-compose.yml logs --tail=100 -f $(c) - -.PHONY: logs-api -logs-api: - @$(DOCKER_CMD) -f docker-compose.yml logs --tail=100 -f midaz-audit - -.PHONY: ps -ps: - @$(DOCKER_CMD) -f docker-compose.yml ps - -.PHONY: generate-docs -generate-docs: - @swag init -g ../../../cmd/app/main.go -d ./internal/adapters/http -o ./api --parseDependency --parseInternal - @docker run --rm -v ./:/audit --user $(shell id -u):$(shell id -g) openapitools/openapi-generator-cli:v5.1.1 generate -i ./audit/api/swagger.json -g openapi-yaml -o ./audit/api - @mv ./api/openapi/openapi.yaml ./api/openapi.yaml - @rm -rf ./api/README.md ./api/.openapi-generator* ./api/openapi \ No newline at end of file diff --git a/components/audit/api/docs.go b/components/audit/api/docs.go deleted file mode 100644 index 0491181e..00000000 --- a/components/audit/api/docs.go +++ /dev/null @@ -1,207 +0,0 @@ -// Package api Code generated by swaggo/swag. DO NOT EDIT -package api - -import "github.com/swaggo/swag" - -const docTemplate = `{ - "schemes": {{ marshal .Schemes }}, - "swagger": "2.0", - "info": { - "description": "{{escape .Description}}", - "title": "{{.Title}}", - "termsOfService": "http://swagger.io/terms/", - "contact": { - "name": "Discord community", - "url": "https://discord.gg/DnhqKwkGv3" - }, - "license": { - "name": "Apache 2.0", - "url": "http://www.apache.org/licenses/LICENSE-2.0.html" - }, - "version": "{{.Version}}" - }, - "host": "{{.Host}}", - "basePath": "{{.BasePath}}", - "paths": { - "/v1/organizations/{organization_id}/ledgers/{ledger_id}/audit/{audit_id}/audit-logs": { - "get": { - "description": "Audit logs to check if any was tampered", - "produces": [ - "application/json" - ], - "tags": [ - "Audit" - ], - "summary": "Audit logs by reference ID", - "parameters": [ - { - "type": "string", - "description": "Authorization Bearer Token", - "name": "Authorization", - "in": "header", - "required": true - }, - { - "type": "string", - "description": "Request ID", - "name": "X-Request-Id", - "in": "header" - }, - { - "type": "string", - "description": "Organization ID", - "name": "organization_id", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Ledger ID", - "name": "ledger_id", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Audit ID", - "name": "audit_id", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/HashValidationResponse" - } - } - } - } - }, - "/v1/organizations/{organization_id}/ledgers/{ledger_id}/audit/{audit_id}/read-logs": { - "get": { - "description": "Get log values from Trillian by reference ID", - "produces": [ - "application/json" - ], - "tags": [ - "Audit" - ], - "summary": "Get \tlogs by reference ID", - "parameters": [ - { - "type": "string", - "description": "Authorization Bearer Token", - "name": "Authorization", - "in": "header", - "required": true - }, - { - "type": "string", - "description": "Request ID", - "name": "X-Request-Id", - "in": "header" - }, - { - "type": "string", - "description": "Organization ID", - "name": "organization_id", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Ledger ID", - "name": "ledger_id", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Audit ID", - "name": "audit_id", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/LogsResponse" - } - } - } - } - } - }, - "definitions": { - "HashValidationResponse": { - "description": "HashValidationResponse show if any of the logs has been tampered", - "type": "object", - "properties": { - "auditId": { - "type": "string" - }, - "calculatedHash": { - "type": "string" - }, - "expectedHash": { - "type": "string" - }, - "isTampered": { - "type": "boolean" - } - } - }, - "Leaf": { - "description": "Leaf stores each audit log", - "type": "object", - "properties": { - "body": { - "type": "array", - "items": { - "type": "integer" - } - }, - "leaf_id": { - "type": "string" - } - } - }, - "LogsResponse": { - "description": "LogsResponse is the response with audit log values", - "type": "object", - "properties": { - "leaves": { - "type": "array", - "items": { - "$ref": "#/definitions/Leaf" - } - }, - "tree_id": { - "type": "integer" - } - } - } - } -}` - -// SwaggerInfo holds exported Swagger Info so clients can modify it -var SwaggerInfo = &swag.Spec{ - Version: "v1.48.0", - Host: "localhost:3002", - BasePath: "/", - Schemes: []string{}, - Title: "Midaz Audit API", - Description: "This is a swagger documentation for the Midaz Audit API", - InfoInstanceName: "swagger", - SwaggerTemplate: docTemplate, - LeftDelim: "{{", - RightDelim: "}}", -} - -func init() { - swag.Register(SwaggerInfo.InstanceName(), SwaggerInfo) -} diff --git a/components/audit/api/openapi.yaml b/components/audit/api/openapi.yaml deleted file mode 100644 index a6b74d6f..00000000 --- a/components/audit/api/openapi.yaml +++ /dev/null @@ -1,157 +0,0 @@ -openapi: 3.0.1 -info: - contact: - name: Discord community - url: https://discord.gg/DnhqKwkGv3 - description: This is a swagger documentation for the Midaz Audit API - license: - name: Apache 2.0 - url: http://www.apache.org/licenses/LICENSE-2.0.html - termsOfService: http://swagger.io/terms/ - title: Midaz Audit API - version: v1.48.0 -servers: -- url: //localhost:3002/ -paths: - /v1/organizations/{organization_id}/ledgers/{ledger_id}/audit/{audit_id}/audit-logs: - get: - description: Audit logs to check if any was tampered - parameters: - - description: Authorization Bearer Token - in: header - name: Authorization - required: true - schema: - type: string - - description: Request ID - in: header - name: X-Request-Id - schema: - type: string - - description: Organization ID - in: path - name: organization_id - required: true - schema: - type: string - - description: Ledger ID - in: path - name: ledger_id - required: true - schema: - type: string - - description: Audit ID - in: path - name: audit_id - required: true - schema: - type: string - responses: - "200": - content: - application/json: - schema: - $ref: '#/components/schemas/HashValidationResponse' - description: OK - summary: Audit logs by reference ID - tags: - - Audit - /v1/organizations/{organization_id}/ledgers/{ledger_id}/audit/{audit_id}/read-logs: - get: - description: Get log values from Trillian by reference ID - parameters: - - description: Authorization Bearer Token - in: header - name: Authorization - required: true - schema: - type: string - - description: Request ID - in: header - name: X-Request-Id - schema: - type: string - - description: Organization ID - in: path - name: organization_id - required: true - schema: - type: string - - description: Ledger ID - in: path - name: ledger_id - required: true - schema: - type: string - - description: Audit ID - in: path - name: audit_id - required: true - schema: - type: string - responses: - "200": - content: - application/json: - schema: - $ref: '#/components/schemas/LogsResponse' - description: OK - summary: "Get \tlogs by reference ID" - tags: - - Audit -components: - schemas: - HashValidationResponse: - description: HashValidationResponse show if any of the logs has been tampered - example: - auditId: auditId - isTampered: true - calculatedHash: calculatedHash - expectedHash: expectedHash - properties: - auditId: - type: string - calculatedHash: - type: string - expectedHash: - type: string - isTampered: - type: boolean - type: object - Leaf: - description: Leaf stores each audit log - example: - body: - - 0 - - 0 - leaf_id: leaf_id - properties: - body: - items: - type: integer - type: array - leaf_id: - type: string - type: object - LogsResponse: - description: LogsResponse is the response with audit log values - example: - leaves: - - body: - - 0 - - 0 - leaf_id: leaf_id - - body: - - 0 - - 0 - leaf_id: leaf_id - tree_id: 6 - properties: - leaves: - items: - $ref: '#/components/schemas/Leaf' - type: array - tree_id: - type: integer - type: object -x-original-swagger-version: "2.0" diff --git a/components/audit/api/swagger.json b/components/audit/api/swagger.json deleted file mode 100644 index a0cbcfcb..00000000 --- a/components/audit/api/swagger.json +++ /dev/null @@ -1,183 +0,0 @@ -{ - "swagger": "2.0", - "info": { - "description": "This is a swagger documentation for the Midaz Audit API", - "title": "Midaz Audit API", - "termsOfService": "http://swagger.io/terms/", - "contact": { - "name": "Discord community", - "url": "https://discord.gg/DnhqKwkGv3" - }, - "license": { - "name": "Apache 2.0", - "url": "http://www.apache.org/licenses/LICENSE-2.0.html" - }, - "version": "v1.48.0" - }, - "host": "localhost:3002", - "basePath": "/", - "paths": { - "/v1/organizations/{organization_id}/ledgers/{ledger_id}/audit/{audit_id}/audit-logs": { - "get": { - "description": "Audit logs to check if any was tampered", - "produces": [ - "application/json" - ], - "tags": [ - "Audit" - ], - "summary": "Audit logs by reference ID", - "parameters": [ - { - "type": "string", - "description": "Authorization Bearer Token", - "name": "Authorization", - "in": "header", - "required": true - }, - { - "type": "string", - "description": "Request ID", - "name": "X-Request-Id", - "in": "header" - }, - { - "type": "string", - "description": "Organization ID", - "name": "organization_id", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Ledger ID", - "name": "ledger_id", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Audit ID", - "name": "audit_id", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/HashValidationResponse" - } - } - } - } - }, - "/v1/organizations/{organization_id}/ledgers/{ledger_id}/audit/{audit_id}/read-logs": { - "get": { - "description": "Get log values from Trillian by reference ID", - "produces": [ - "application/json" - ], - "tags": [ - "Audit" - ], - "summary": "Get \tlogs by reference ID", - "parameters": [ - { - "type": "string", - "description": "Authorization Bearer Token", - "name": "Authorization", - "in": "header", - "required": true - }, - { - "type": "string", - "description": "Request ID", - "name": "X-Request-Id", - "in": "header" - }, - { - "type": "string", - "description": "Organization ID", - "name": "organization_id", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Ledger ID", - "name": "ledger_id", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Audit ID", - "name": "audit_id", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/LogsResponse" - } - } - } - } - } - }, - "definitions": { - "HashValidationResponse": { - "description": "HashValidationResponse show if any of the logs has been tampered", - "type": "object", - "properties": { - "auditId": { - "type": "string" - }, - "calculatedHash": { - "type": "string" - }, - "expectedHash": { - "type": "string" - }, - "isTampered": { - "type": "boolean" - } - } - }, - "Leaf": { - "description": "Leaf stores each audit log", - "type": "object", - "properties": { - "body": { - "type": "array", - "items": { - "type": "integer" - } - }, - "leaf_id": { - "type": "string" - } - } - }, - "LogsResponse": { - "description": "LogsResponse is the response with audit log values", - "type": "object", - "properties": { - "leaves": { - "type": "array", - "items": { - "$ref": "#/definitions/Leaf" - } - }, - "tree_id": { - "type": "integer" - } - } - } - } -} \ No newline at end of file diff --git a/components/audit/api/swagger.yaml b/components/audit/api/swagger.yaml deleted file mode 100644 index 6bbf5139..00000000 --- a/components/audit/api/swagger.yaml +++ /dev/null @@ -1,124 +0,0 @@ -basePath: / -definitions: - HashValidationResponse: - description: HashValidationResponse show if any of the logs has been tampered - properties: - auditId: - type: string - calculatedHash: - type: string - expectedHash: - type: string - isTampered: - type: boolean - type: object - Leaf: - description: Leaf stores each audit log - properties: - body: - items: - type: integer - type: array - leaf_id: - type: string - type: object - LogsResponse: - description: LogsResponse is the response with audit log values - properties: - leaves: - items: - $ref: '#/definitions/Leaf' - type: array - tree_id: - type: integer - type: object -host: localhost:3002 -info: - contact: - name: Discord community - url: https://discord.gg/DnhqKwkGv3 - description: This is a swagger documentation for the Midaz Audit API - license: - name: Apache 2.0 - url: http://www.apache.org/licenses/LICENSE-2.0.html - termsOfService: http://swagger.io/terms/ - title: Midaz Audit API - version: v1.48.0 -paths: - /v1/organizations/{organization_id}/ledgers/{ledger_id}/audit/{audit_id}/audit-logs: - get: - description: Audit logs to check if any was tampered - parameters: - - description: Authorization Bearer Token - in: header - name: Authorization - required: true - type: string - - description: Request ID - in: header - name: X-Request-Id - type: string - - description: Organization ID - in: path - name: organization_id - required: true - type: string - - description: Ledger ID - in: path - name: ledger_id - required: true - type: string - - description: Audit ID - in: path - name: audit_id - required: true - type: string - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/HashValidationResponse' - summary: Audit logs by reference ID - tags: - - Audit - /v1/organizations/{organization_id}/ledgers/{ledger_id}/audit/{audit_id}/read-logs: - get: - description: Get log values from Trillian by reference ID - parameters: - - description: Authorization Bearer Token - in: header - name: Authorization - required: true - type: string - - description: Request ID - in: header - name: X-Request-Id - type: string - - description: Organization ID - in: path - name: organization_id - required: true - type: string - - description: Ledger ID - in: path - name: ledger_id - required: true - type: string - - description: Audit ID - in: path - name: audit_id - required: true - type: string - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/LogsResponse' - summary: "Get \tlogs by reference ID" - tags: - - Audit -swagger: "2.0" diff --git a/components/audit/cmd/app/main.go b/components/audit/cmd/app/main.go deleted file mode 100644 index b8e2e02a..00000000 --- a/components/audit/cmd/app/main.go +++ /dev/null @@ -1,21 +0,0 @@ -package main - -import ( - "github.com/LerianStudio/midaz/components/audit/internal/bootstrap" - "github.com/LerianStudio/midaz/pkg" -) - -// @title Midaz Audit API -// @version v1.48.0 -// @description This is a swagger documentation for the Midaz Audit API -// @termsOfService http://swagger.io/terms/ -// @contact.name Discord community -// @contact.url https://discord.gg/DnhqKwkGv3 -// @license.name Apache 2.0 -// @license.url http://www.apache.org/licenses/LICENSE-2.0.html -// @host localhost:3002 -// @BasePath / -func main() { - pkg.InitLocalEnvConfig() - bootstrap.InitServers().Run() -} diff --git a/components/audit/db/init.sql b/components/audit/db/init.sql deleted file mode 100644 index 5682d9f8..00000000 --- a/components/audit/db/init.sql +++ /dev/null @@ -1,123 +0,0 @@ -/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; -/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; -/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; -/*!40101 SET NAMES utf8mb4 */; -/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; -/*!40103 SET TIME_ZONE='+00:00' */; -/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; -/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; -/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; - -CREATE TABLE IF NOT EXISTS `LeafData` ( - `TreeId` bigint(20) NOT NULL, - `LeafIdentityHash` varbinary(255) NOT NULL, - `LeafValue` longblob NOT NULL, - `ExtraData` longblob DEFAULT NULL, - `QueueTimestampNanos` bigint(20) NOT NULL, - PRIMARY KEY (`TreeId`, `LeafIdentityHash`), - CONSTRAINT `LeafData_ibfk_1` FOREIGN KEY (`TreeId`) REFERENCES `Trees` (`TreeId`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=latin1; - -CREATE TABLE IF NOT EXISTS `MapHead` ( - `TreeId` bigint(20) NOT NULL, - `MapHeadTimestamp` bigint(20) NOT NULL, - `RootHash` varbinary(255) NOT NULL, - `MapRevision` bigint(20) DEFAULT NULL, - `RootSignature` varbinary(1024) NOT NULL, - `MapperData` mediumblob DEFAULT NULL, - PRIMARY KEY (`TreeId`, `MapHeadTimestamp`), - UNIQUE KEY `MapHeadRevisionIdx` (`TreeId`, `MapRevision`), - CONSTRAINT `MapHead_ibfk_1` FOREIGN KEY (`TreeId`) REFERENCES `Trees` (`TreeId`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=latin1; - -CREATE TABLE IF NOT EXISTS `MapLeaf` ( - `TreeId` bigint(20) NOT NULL, - `KeyHash` varbinary(255) NOT NULL, - `MapRevision` bigint(20) NOT NULL, - `LeafValue` longblob NOT NULL, - PRIMARY KEY (`TreeId`, `KeyHash`, `MapRevision`), - CONSTRAINT `MapLeaf_ibfk_1` FOREIGN KEY (`TreeId`) REFERENCES `Trees` (`TreeId`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=latin1; - -CREATE TABLE IF NOT EXISTS `SequencedLeafData` ( - `TreeId` bigint(20) NOT NULL, - `SequenceNumber` bigint(20) unsigned NOT NULL, - `LeafIdentityHash` varbinary(255) NOT NULL, - `MerkleLeafHash` varbinary(255) NOT NULL, - `IntegrateTimestampNanos` bigint(20) NOT NULL, - PRIMARY KEY (`TreeId`, `SequenceNumber`), - KEY `TreeId` (`TreeId`, `LeafIdentityHash`), - KEY `SequencedLeafMerkleIdx` (`TreeId`, `MerkleLeafHash`), - CONSTRAINT `SequencedLeafData_ibfk_1` FOREIGN KEY (`TreeId`) REFERENCES `Trees` (`TreeId`) ON DELETE CASCADE, - CONSTRAINT `SequencedLeafData_ibfk_2` FOREIGN KEY (`TreeId`, `LeafIdentityHash`) REFERENCES `LeafData` (`TreeId`, `LeafIdentityHash`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=latin1; - -CREATE TABLE IF NOT EXISTS `Subtree` ( - `TreeId` bigint(20) NOT NULL, - `SubtreeId` varbinary(255) NOT NULL, - `Nodes` mediumblob NOT NULL, - `SubtreeRevision` int(11) NOT NULL, - PRIMARY KEY (`TreeId`, `SubtreeId`, `SubtreeRevision`), - CONSTRAINT `Subtree_ibfk_1` FOREIGN KEY (`TreeId`) REFERENCES `Trees` (`TreeId`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=latin1; - -CREATE TABLE IF NOT EXISTS `TreeControl` ( - `TreeId` bigint(20) NOT NULL, - `SigningEnabled` tinyint(1) NOT NULL, - `SequencingEnabled` tinyint(1) NOT NULL, - `SequenceIntervalSeconds` int(11) NOT NULL, - PRIMARY KEY (`TreeId`), - CONSTRAINT `TreeControl_ibfk_1` FOREIGN KEY (`TreeId`) REFERENCES `Trees` (`TreeId`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=latin1; - -CREATE TABLE IF NOT EXISTS `TreeHead` ( - `TreeId` bigint(20) NOT NULL, - `TreeHeadTimestamp` bigint(20) NOT NULL, - `TreeSize` bigint(20) DEFAULT NULL, - `RootHash` varbinary(255) NOT NULL, - `RootSignature` varbinary(1024) NOT NULL, - `TreeRevision` bigint(20) DEFAULT NULL, - PRIMARY KEY (`TreeId`, `TreeHeadTimestamp`), - UNIQUE KEY `TreeHeadRevisionIdx` (`TreeId`, `TreeRevision`), - CONSTRAINT `TreeHead_ibfk_1` FOREIGN KEY (`TreeId`) REFERENCES `Trees` (`TreeId`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=latin1; - -CREATE TABLE IF NOT EXISTS `Trees` ( - `TreeId` bigint(20) NOT NULL, - `TreeState` enum('ACTIVE', 'FROZEN', 'DRAINING') NOT NULL, - `TreeType` enum('LOG', 'MAP', 'PREORDERED_LOG') NOT NULL, - `HashStrategy` enum('RFC6962_SHA256', 'TEST_MAP_HASHER', 'OBJECT_RFC6962_SHA256', 'CONIKS_SHA512_256', 'CONIKS_SHA256') NOT NULL, - `HashAlgorithm` enum('SHA256') NOT NULL, - `SignatureAlgorithm` enum('ECDSA', 'RSA') NOT NULL, - `DisplayName` varchar(20) DEFAULT NULL, - `Description` varchar(200) DEFAULT NULL, - `CreateTimeMillis` bigint(20) NOT NULL, - `UpdateTimeMillis` bigint(20) NOT NULL, - `MaxRootDurationMillis` bigint(20) NOT NULL, - `PrivateKey` mediumblob NOT NULL, - `PublicKey` mediumblob NOT NULL, - `Deleted` tinyint(1) DEFAULT NULL, - `DeleteTimeMillis` bigint(20) DEFAULT NULL, - PRIMARY KEY (`TreeId`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; - -CREATE TABLE IF NOT EXISTS `Unsequenced` ( - `TreeId` bigint(20) NOT NULL, - `Bucket` int(11) NOT NULL, - `LeafIdentityHash` varbinary(255) NOT NULL, - `MerkleLeafHash` varbinary(255) NOT NULL, - `QueueTimestampNanos` bigint(20) NOT NULL, - `QueueID` varbinary(32) DEFAULT NULL, - PRIMARY KEY (`TreeId`, `Bucket`, `QueueTimestampNanos`, `LeafIdentityHash`), - UNIQUE KEY `QueueID` (`QueueID`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; - -/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; -/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; -/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; -/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; -/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; -/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; -/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; -/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; \ No newline at end of file diff --git a/components/audit/docker-compose.yml b/components/audit/docker-compose.yml deleted file mode 100644 index 8bdba810..00000000 --- a/components/audit/docker-compose.yml +++ /dev/null @@ -1,95 +0,0 @@ -services: - midaz-audit: - container_name: midaz-audit - restart: always - build: - context: ../../ - dockerfile: ./components/audit/Dockerfile - env_file: - - .env - ports: - - ${SERVER_PORT}:${SERVER_PORT} - volumes: - - .:/usr/src/app - networks: - - audit_network - - infra_network - - auth_network - depends_on: - - midaz-audit-server - - midaz-audit-signer - - midaz-audit-db: - container_name: midaz-audit-db - image: mariadb:latest - environment: - - MYSQL_DATABASE=${TRILLIAN_DATABASE_NAME} - - MYSQL_ROOT_PASSWORD=${TRILLIAN_DATABASE_ROOT_PASSWORD} - - MYSQL_USER=${TRILLIAN_DATABASE_USER} - - MYSQL_PASSWORD=${TRILLIAN_DATABASE_PASSWORD} - - MYSQL_TCP_PORT=${TRILLIAN_DATABASE_PORT} - ports: - - ${TRILLIAN_DATABASE_PORT}:${TRILLIAN_DATABASE_PORT} - volumes: - - audit-data:/var/lib/mysql - - ./db:/docker-entrypoint-initdb.d/:ro - restart: always - healthcheck: - test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-P", "${TRILLIAN_DATABASE_PORT}", "-u", "${TRILLIAN_DATABASE_USER}", "--password=${TRILLIAN_DATABASE_PASSWORD}"] - interval: 10s - timeout: 5s - retries: 5 - networks: - - audit_network - - midaz-audit-server: - container_name: midaz-audit-server - depends_on: - - midaz-audit-db - image: gcr.io/trillian-opensource-ci/log_server - command: [ - "--storage_system=mysql", - "--mysql_uri=${TRILLIAN_DATABASE_USER}:${TRILLIAN_DATABASE_PASSWORD}@tcp(midaz-audit-db:${TRILLIAN_DATABASE_PORT})/${TRILLIAN_DATABASE_NAME}", - "--rpc_endpoint=0.0.0.0:${TRILLIAN_GRPC_PORT}", - "--http_endpoint=0.0.0.0:${TRILLIAN_HTTP_PORT}", - "--alsologtostderr", - ] - restart: always - ports: - - ${TRILLIAN_GRPC_PORT}:${TRILLIAN_GRPC_PORT} - - ${TRILLIAN_HTTP_PORT}:${TRILLIAN_HTTP_PORT} - networks: - - audit_network - - midaz-audit-signer: - container_name: midaz-audit-signer - image: gcr.io/trillian-opensource-ci/log_signer - depends_on: - - midaz-audit-db - command: [ - "--storage_system=mysql", - "--mysql_uri=${TRILLIAN_DATABASE_USER}:${TRILLIAN_DATABASE_PASSWORD}@tcp(midaz-audit-db:${TRILLIAN_DATABASE_PORT})/${TRILLIAN_DATABASE_NAME}", - "--rpc_endpoint=0.0.0.0:${TRILLIAN_GRPC_PORT}", - "--http_endpoint=0.0.0.0:${TRILLIAN_HTTP_PORT}", - "--force_master", - "--alsologtostderr", - ] - restart: always - ports: - - ${TRILLIAN_SIGNER_PORT}:${TRILLIAN_HTTP_PORT} - networks: - - audit_network - -volumes: - audit-data: - -networks: - audit_network: - name: audit_network - driver: bridge - infra_network: - name: infra_network - driver: bridge - auth_network: - name: auth_network - driver: bridge \ No newline at end of file diff --git a/components/audit/internal/adapters/grpc/in/.keep b/components/audit/internal/adapters/grpc/in/.keep deleted file mode 100644 index e69de29b..00000000 diff --git a/components/audit/internal/adapters/grpc/out/trillian.grpc.go b/components/audit/internal/adapters/grpc/out/trillian.grpc.go deleted file mode 100644 index ae69a8b9..00000000 --- a/components/audit/internal/adapters/grpc/out/trillian.grpc.go +++ /dev/null @@ -1,108 +0,0 @@ -package out - -import ( - "context" - "encoding/hex" - "github.com/LerianStudio/midaz/pkg" - "github.com/LerianStudio/midaz/pkg/mopentelemetry" - "github.com/LerianStudio/midaz/pkg/mtrillian" - "github.com/google/trillian" -) - -// Repository provides an interface for gRPC operations related to Trillian -// -//go:generate mockgen --destination=trillian.mock.go --package=out . Repository -type Repository interface { - CreateTree(ctx context.Context, name, description string) (int64, error) - CreateLog(ctx context.Context, treeID int64, logValue []byte) (string, error) - GetLogByHash(ctx context.Context, treeID int64, hash string) (*trillian.LogLeaf, error) -} - -// TrillianRepository interacts with Trillian log server -type TrillianRepository struct { - conn *mtrillian.TrillianConnection -} - -// NewTrillianRepository returns a new instance of TrillianRepository using the given gRPC connection. -func NewTrillianRepository(conn *mtrillian.TrillianConnection) *TrillianRepository { - trillianRepo := &TrillianRepository{ - conn: conn, - } - - _, err := conn.GetNewClient() - if err != nil { - panic("Failed to connect to Trillian gRPC") - } - - return trillianRepo -} - -// CreateTree creates a tree to store logs -func (t TrillianRepository) CreateTree(ctx context.Context, name, description string) (int64, error) { - tracer := pkg.NewTracerFromContext(ctx) - - ctx, span := tracer.Start(ctx, "grpc.trillian.create_tree") - defer span.End() - - ctx, spanCreate := tracer.Start(ctx, "grpc.trillian.create_tree.create") - - treeID, err := t.conn.CreateTree(ctx, name, description) - if err != nil { - mopentelemetry.HandleSpanError(&spanCreate, "Failed to create tree", err) - return 0, err - } - - spanCreate.End() - - ctx, spanInit := tracer.Start(ctx, "grpc.trillian.create_tree.init") - - err = t.conn.InitTree(ctx, treeID) - if err != nil { - mopentelemetry.HandleSpanError(&spanInit, "Failed to init tree", err) - return 0, err - } - - spanInit.End() - - return treeID, nil -} - -// CreateLog creates a log leaf on a tree -func (t TrillianRepository) CreateLog(ctx context.Context, treeID int64, logValue []byte) (string, error) { - tracer := pkg.NewTracerFromContext(ctx) - - ctx, span := tracer.Start(ctx, "grpc.trillian.create_log") - defer span.End() - - logHash, err := t.conn.CreateLog(ctx, treeID, logValue) - if err != nil { - mopentelemetry.HandleSpanError(&span, "Failed to create log", err) - - return "", err - } - - return hex.EncodeToString(logHash), nil -} - -func (t TrillianRepository) GetLogByHash(ctx context.Context, treeID int64, hash string) (*trillian.LogLeaf, error) { - tracer := pkg.NewTracerFromContext(ctx) - - ctx, span := tracer.Start(ctx, "grpc.trillian.get_log_by_hash") - defer span.End() - - proof, err := t.conn.GetInclusionProofByHash(ctx, treeID, hash) - if err != nil { - mopentelemetry.HandleSpanError(&span, "Failed to get inclusion proof", err) - - return nil, err - } - - leaf, err := t.conn.GetLeafByIndex(ctx, treeID, proof[0].GetLeafIndex()) - if err != nil { - mopentelemetry.HandleSpanError(&span, "Failed to get leaf by index", err) - - return nil, err - } - - return leaf, nil -} diff --git a/components/audit/internal/adapters/grpc/out/trillian.mock.go b/components/audit/internal/adapters/grpc/out/trillian.mock.go deleted file mode 100644 index 8c4e7b41..00000000 --- a/components/audit/internal/adapters/grpc/out/trillian.mock.go +++ /dev/null @@ -1,86 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/LerianStudio/midaz/components/audit/internal/adapters/grpc/out (interfaces: Repository) -// -// Generated by this command: -// -// mockgen --destination=trillian.mock.go --package=out . Repository -// - -// Package out is a generated GoMock package. -package out - -import ( - context "context" - reflect "reflect" - - trillian "github.com/google/trillian" - gomock "go.uber.org/mock/gomock" -) - -// MockRepository is a mock of Repository interface. -type MockRepository struct { - ctrl *gomock.Controller - recorder *MockRepositoryMockRecorder -} - -// MockRepositoryMockRecorder is the mock recorder for MockRepository. -type MockRepositoryMockRecorder struct { - mock *MockRepository -} - -// NewMockRepository creates a new mock instance. -func NewMockRepository(ctrl *gomock.Controller) *MockRepository { - mock := &MockRepository{ctrl: ctrl} - mock.recorder = &MockRepositoryMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockRepository) EXPECT() *MockRepositoryMockRecorder { - return m.recorder -} - -// CreateLog mocks base method. -func (m *MockRepository) CreateLog(arg0 context.Context, arg1 int64, arg2 []byte) (string, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CreateLog", arg0, arg1, arg2) - ret0, _ := ret[0].(string) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// CreateLog indicates an expected call of CreateLog. -func (mr *MockRepositoryMockRecorder) CreateLog(arg0, arg1, arg2 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateLog", reflect.TypeOf((*MockRepository)(nil).CreateLog), arg0, arg1, arg2) -} - -// CreateTree mocks base method. -func (m *MockRepository) CreateTree(arg0 context.Context, arg1, arg2 string) (int64, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CreateTree", arg0, arg1, arg2) - ret0, _ := ret[0].(int64) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// CreateTree indicates an expected call of CreateTree. -func (mr *MockRepositoryMockRecorder) CreateTree(arg0, arg1, arg2 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateTree", reflect.TypeOf((*MockRepository)(nil).CreateTree), arg0, arg1, arg2) -} - -// GetLogByHash mocks base method. -func (m *MockRepository) GetLogByHash(arg0 context.Context, arg1 int64, arg2 string) (*trillian.LogLeaf, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetLogByHash", arg0, arg1, arg2) - ret0, _ := ret[0].(*trillian.LogLeaf) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetLogByHash indicates an expected call of GetLogByHash. -func (mr *MockRepositoryMockRecorder) GetLogByHash(arg0, arg1, arg2 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLogByHash", reflect.TypeOf((*MockRepository)(nil).GetLogByHash), arg0, arg1, arg2) -} diff --git a/components/audit/internal/adapters/http/in/response.go b/components/audit/internal/adapters/http/in/response.go deleted file mode 100644 index 7f46d2e4..00000000 --- a/components/audit/internal/adapters/http/in/response.go +++ /dev/null @@ -1,32 +0,0 @@ -package in - -import "encoding/json" - -// LogsResponse is a struct to encapsulate audit logs response -// -// swagger:model LogsResponse -// @Description LogsResponse is the response with audit log values -type LogsResponse struct { - TreeID int64 `json:"tree_id"` - Leaves []Leaf `json:"leaves"` -} // @name LogsResponse - -// Leaf encapsulates audit log values -// -// swagger:model Leaf -// @Description Leaf stores each audit log -type Leaf struct { - LeafID string `json:"leaf_id"` - Body json.RawMessage `json:"body"` -} // @Name Leaf - -// HashValidationResponse encapsulates auditing validation results -// -// swagger:model HashValidationResponse -// @Description HashValidationResponse show if any of the logs has been tampered -type HashValidationResponse struct { - AuditID string `json:"auditId"` - ExpectedHash string `json:"expectedHash"` - CalculatedHash string `json:"calculatedHash"` - IsTampered bool `json:"isTampered"` -} // @Name HashValidationResponse diff --git a/components/audit/internal/adapters/http/in/routes.go b/components/audit/internal/adapters/http/in/routes.go deleted file mode 100644 index f548f7b4..00000000 --- a/components/audit/internal/adapters/http/in/routes.go +++ /dev/null @@ -1,43 +0,0 @@ -package in - -import ( - "github.com/LerianStudio/midaz/pkg/mcasdoor" - "github.com/LerianStudio/midaz/pkg/mlog" - "github.com/LerianStudio/midaz/pkg/mopentelemetry" - "github.com/LerianStudio/midaz/pkg/net/http" - - "github.com/gofiber/fiber/v2" - "github.com/gofiber/fiber/v2/middleware/cors" - fiberSwagger "github.com/swaggo/fiber-swagger" -) - -func NewRouter(lg mlog.Logger, tl *mopentelemetry.Telemetry, cc *mcasdoor.CasdoorConnection, th *TrillianHandler) *fiber.App { - f := fiber.New(fiber.Config{ - DisableStartupMessage: true, - }) - tlMid := http.NewTelemetryMiddleware(tl) - - f.Use(tlMid.WithTelemetry(tl)) - f.Use(cors.New()) - f.Use(http.WithHTTPLogging(http.WithCustomLogger(lg))) - jwt := http.NewJWTMiddleware(cc) - - // -- Routes -- - - // Trillian - f.Get("/v1/organizations/:organization_id/ledgers/:ledger_id/audit/:audit_id/audit-logs", jwt.ProtectHTTP(), jwt.WithPermissionHTTP("audit"), http.ParseUUIDPathParameters, th.AuditLogs) - f.Get("/v1/organizations/:organization_id/ledgers/:ledger_id/audit/:audit_id/read-logs", jwt.ProtectHTTP(), jwt.WithPermissionHTTP("audit"), http.ParseUUIDPathParameters, th.ReadLogs) - - // Health - f.Get("/health", http.Ping) - - // Version - f.Get("/version", http.Version) - - // Doc - f.Get("/swagger/*", WithSwaggerEnvConfig(), fiberSwagger.WrapHandler) - - f.Use(tlMid.EndTracingSpans) - - return f -} diff --git a/components/audit/internal/adapters/http/in/swagger.go b/components/audit/internal/adapters/http/in/swagger.go deleted file mode 100644 index 439acdb0..00000000 --- a/components/audit/internal/adapters/http/in/swagger.go +++ /dev/null @@ -1,41 +0,0 @@ -package in - -import ( - "github.com/LerianStudio/midaz/pkg" - "os" - - "github.com/LerianStudio/midaz/components/audit/api" - - "github.com/gofiber/fiber/v2" -) - -// WithSwaggerEnvConfig sets the Swagger configuration for the API documentation from environment variables if they are set. -func WithSwaggerEnvConfig() fiber.Handler { - return func(c *fiber.Ctx) error { - envVars := map[string]*string{ - "SWAGGER_TITLE": &api.SwaggerInfo.Title, - "SWAGGER_DESCRIPTION": &api.SwaggerInfo.Description, - "SWAGGER_VERSION": &api.SwaggerInfo.Version, - "SWAGGER_HOST": &api.SwaggerInfo.Host, - "SWAGGER_BASE_PATH": &api.SwaggerInfo.BasePath, - "SWAGGER_LEFT_DELIM": &api.SwaggerInfo.LeftDelim, - "SWAGGER_RIGHT_DELIM": &api.SwaggerInfo.RightDelim, - } - - for env, field := range envVars { - if value := os.Getenv(env); !pkg.IsNilOrEmpty(&value) { - if env == "SWAGGER_HOST" && pkg.ValidateServerAddress(value) == "" { - continue - } - - *field = value - } - } - - if schemes := os.Getenv("SWAGGER_SCHEMES"); schemes != "" { - api.SwaggerInfo.Schemes = []string{schemes} - } - - return c.Next() - } -} diff --git a/components/audit/internal/adapters/http/in/trillian.go b/components/audit/internal/adapters/http/in/trillian.go deleted file mode 100644 index 43ad1b42..00000000 --- a/components/audit/internal/adapters/http/in/trillian.go +++ /dev/null @@ -1,139 +0,0 @@ -package in - -import ( - "github.com/LerianStudio/midaz/components/audit/internal/services" - "github.com/LerianStudio/midaz/pkg" - "github.com/LerianStudio/midaz/pkg/mopentelemetry" - "github.com/LerianStudio/midaz/pkg/net/http" - "github.com/gofiber/fiber/v2" - "github.com/google/uuid" -) - -type TrillianHandler struct { - UseCase *services.UseCase -} - -// AuditLogs compares leaf hash with a hash generated from the leaf value -// -// @Summary Audit logs by reference ID -// @Description Audit logs to check if any was tampered -// @Tags Audit -// @Produce json -// @Param Authorization header string true "Authorization Bearer Token" -// @Param X-Request-Id header string false "Request ID" -// @Param organization_id path string true "Organization ID" -// @Param ledger_id path string true "Ledger ID" -// @Param audit_id path string true "Audit ID" -// @Success 200 {object} HashValidationResponse -// @Router /v1/organizations/{organization_id}/ledgers/{ledger_id}/audit/{audit_id}/audit-logs [get] -func (th *TrillianHandler) AuditLogs(c *fiber.Ctx) error { - ctx := c.UserContext() - - logger := pkg.NewLoggerFromContext(ctx) - tracer := pkg.NewTracerFromContext(ctx) - - ctx, span := tracer.Start(ctx, "handler.audit_Logs") - defer span.End() - - organizationID := c.Locals("organization_id").(uuid.UUID) - ledgerID := c.Locals("ledger_id").(uuid.UUID) - id := c.Locals("audit_id").(uuid.UUID) - - auditInfo, err := th.UseCase.GetAuditInfo(ctx, organizationID, ledgerID, id) - if err != nil { - mopentelemetry.HandleSpanError(&span, "Failed to retrieve audit info", err) - - logger.Errorf("Failed to retrieve audit info: %v", err.Error()) - - return http.WithError(c, err) - } - - validations := make([]HashValidationResponse, 0) - - for key, value := range auditInfo.Leaves { - expectedHash, calculatedHash, isTampered, err := th.UseCase.ValidatedLogHash(ctx, auditInfo.TreeID, value) - if err != nil { - mopentelemetry.HandleSpanError(&span, "Failed to retrieve log validation", err) - - logger.Errorf("Failed to retrieve log validation: %v", err.Error()) - - return http.WithError(c, err) - } - - if isTampered { - logger.Warnf("Log for %v has been tampered! Expected: %x, Found: %x\n", key, expectedHash, calculatedHash) - } - - response := &HashValidationResponse{ - AuditID: key, - ExpectedHash: expectedHash, - CalculatedHash: calculatedHash, - IsTampered: isTampered, - } - - validations = append(validations, *response) - } - - return http.OK(c, validations) -} - -// ReadLogs retrieves log values by the audit id -// -// @Summary Get logs by reference ID -// @Description Get log values from Trillian by reference ID -// @Tags Audit -// @Produce json -// @Param Authorization header string true "Authorization Bearer Token" -// @Param X-Request-Id header string false "Request ID" -// @Param organization_id path string true "Organization ID" -// @Param ledger_id path string true "Ledger ID" -// @Param audit_id path string true "Audit ID" -// @Success 200 {object} LogsResponse -// @Router /v1/organizations/{organization_id}/ledgers/{ledger_id}/audit/{audit_id}/read-logs [get] -func (th *TrillianHandler) ReadLogs(c *fiber.Ctx) error { - ctx := c.UserContext() - - logger := pkg.NewLoggerFromContext(ctx) - tracer := pkg.NewTracerFromContext(ctx) - - ctx, span := tracer.Start(ctx, "handler.read_logs") - defer span.End() - - organizationID := c.Locals("organization_id").(uuid.UUID) - ledgerID := c.Locals("ledger_id").(uuid.UUID) - id := c.Locals("audit_id").(uuid.UUID) - - auditInfo, err := th.UseCase.GetAuditInfo(ctx, organizationID, ledgerID, id) - if err != nil { - mopentelemetry.HandleSpanError(&span, "Failed to retrieve audit info", err) - - logger.Errorf("Failed to retrieve audit info: %v", err.Error()) - - return http.WithError(c, err) - } - - leaves := make([]Leaf, 0) - - for _, value := range auditInfo.Leaves { - logHash, logValue, err := th.UseCase.GetLogByHash(ctx, auditInfo.TreeID, value) - if err != nil { - mopentelemetry.HandleSpanError(&span, "Failed to retrieve log by hash", err) - - logger.Errorf("Failed to retrieve log by hash: %v", err.Error()) - - return http.WithError(c, err) - } - - leaves = append(leaves, Leaf{ - LeafID: logHash, - Body: logValue, - }) - } - - response := &LogsResponse{ - TreeID: auditInfo.TreeID, - Leaves: leaves, - } - - return http.OK(c, response) -} diff --git a/components/audit/internal/adapters/http/out/.keep b/components/audit/internal/adapters/http/out/.keep deleted file mode 100644 index e69de29b..00000000 diff --git a/components/audit/internal/adapters/mongodb/audit/audit.go b/components/audit/internal/adapters/mongodb/audit/audit.go deleted file mode 100644 index a4def3bb..00000000 --- a/components/audit/internal/adapters/mongodb/audit/audit.go +++ /dev/null @@ -1,54 +0,0 @@ -package audit - -import ( - "time" -) - -const TreeCollection = "trees" - -// AuditMongoDBModel represents the Audit into mongodb context -type AuditMongoDBModel struct { - ID AuditID `bson:"_id"` - TreeID int64 `bson:"tree_id"` - CreatedAt time.Time `bson:"created_at"` - Leaves map[string]string `bson:"leaves"` -} - -// Audit is a struct designed to encapsulate payload data. -type Audit struct { - ID AuditID `json:"-"` - TreeID int64 - Leaves map[string]string - CreatedAt time.Time `json:"createdAt"` -} - -// AuditID is a struct that represents a composite audit key -type AuditID struct { - OrganizationID string `json:"organizationId" bson:"organization_id"` - LedgerID string `json:"ledgerId" bson:"ledger_id"` - ID string `json:"auditId" bson:"audit_id"` -} - -// ToEntity converts an AuditMongoDBModel to entity.Audit -func (mar *AuditMongoDBModel) ToEntity() *Audit { - id := AuditID{ - OrganizationID: mar.ID.OrganizationID, - LedgerID: mar.ID.LedgerID, - ID: mar.ID.ID, - } - - return &Audit{ - ID: id, - TreeID: mar.TreeID, - CreatedAt: mar.CreatedAt, - Leaves: mar.Leaves, - } -} - -// FromEntity converts an entity.Audit to AuditMongoDBModel -func (mar *AuditMongoDBModel) FromEntity(md *Audit) { - mar.ID = md.ID - mar.TreeID = md.TreeID - mar.CreatedAt = md.CreatedAt - mar.Leaves = md.Leaves -} diff --git a/components/audit/internal/adapters/mongodb/audit/audit.mock.go b/components/audit/internal/adapters/mongodb/audit/audit.mock.go deleted file mode 100644 index 33c2389c..00000000 --- a/components/audit/internal/adapters/mongodb/audit/audit.mock.go +++ /dev/null @@ -1,84 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/LerianStudio/midaz/components/audit/internal/adapters/mongodb/audit (interfaces: Repository) -// -// Generated by this command: -// -// mockgen --destination=audit.mock.go --package=audit . Repository -// - -// Package audit is a generated GoMock package. -package audit - -import ( - context "context" - reflect "reflect" - - gomock "go.uber.org/mock/gomock" -) - -// MockRepository is a mock of Repository interface. -type MockRepository struct { - ctrl *gomock.Controller - recorder *MockRepositoryMockRecorder -} - -// MockRepositoryMockRecorder is the mock recorder for MockRepository. -type MockRepositoryMockRecorder struct { - mock *MockRepository -} - -// NewMockRepository creates a new mock instance. -func NewMockRepository(ctrl *gomock.Controller) *MockRepository { - mock := &MockRepository{ctrl: ctrl} - mock.recorder = &MockRepositoryMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockRepository) EXPECT() *MockRepositoryMockRecorder { - return m.recorder -} - -// Create mocks base method. -func (m *MockRepository) Create(arg0 context.Context, arg1 string, arg2 *Audit) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Create", arg0, arg1, arg2) - ret0, _ := ret[0].(error) - return ret0 -} - -// Create indicates an expected call of Create. -func (mr *MockRepositoryMockRecorder) Create(arg0, arg1, arg2 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Create", reflect.TypeOf((*MockRepository)(nil).Create), arg0, arg1, arg2) -} - -// FindByID mocks base method. -func (m *MockRepository) FindByID(arg0 context.Context, arg1 string, arg2 AuditID) (*Audit, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FindByID", arg0, arg1, arg2) - ret0, _ := ret[0].(*Audit) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// FindByID indicates an expected call of FindByID. -func (mr *MockRepositoryMockRecorder) FindByID(arg0, arg1, arg2 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindByID", reflect.TypeOf((*MockRepository)(nil).FindByID), arg0, arg1, arg2) -} - -// FindOne mocks base method. -func (m *MockRepository) FindOne(arg0 context.Context, arg1 string, arg2 AuditID) (*Audit, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FindOne", arg0, arg1, arg2) - ret0, _ := ret[0].(*Audit) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// FindOne indicates an expected call of FindOne. -func (mr *MockRepositoryMockRecorder) FindOne(arg0, arg1, arg2 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindOne", reflect.TypeOf((*MockRepository)(nil).FindOne), arg0, arg1, arg2) -} diff --git a/components/audit/internal/adapters/mongodb/audit/audit.mongodb.go b/components/audit/internal/adapters/mongodb/audit/audit.mongodb.go deleted file mode 100644 index 16664637..00000000 --- a/components/audit/internal/adapters/mongodb/audit/audit.mongodb.go +++ /dev/null @@ -1,138 +0,0 @@ -package audit - -import ( - "context" - "github.com/LerianStudio/midaz/pkg" - "github.com/LerianStudio/midaz/pkg/mmongo" - "github.com/LerianStudio/midaz/pkg/mopentelemetry" - "go.mongodb.org/mongo-driver/bson" - "strings" -) - -// Repository provides an interface for operations related on mongodb an audit entities. -// -//go:generate mockgen --destination=audit.mock.go --package=audit . Repository -type Repository interface { - Create(ctx context.Context, collection string, audit *Audit) error - FindOne(ctx context.Context, collection string, auditID AuditID) (*Audit, error) - FindByID(ctx context.Context, collection string, auditID AuditID) (*Audit, error) -} - -// AuditMongoDBRepository is a MongoDD-specific implementation of the AuditRepository. -type AuditMongoDBRepository struct { - connection *mmongo.MongoConnection - Database string -} - -// NewAuditMongoDBRepository returns a new instance of AuditMongoDBLRepository using the given MongoDB connection. -func NewAuditMongoDBRepository(mc *mmongo.MongoConnection) *AuditMongoDBRepository { - r := &AuditMongoDBRepository{ - connection: mc, - Database: mc.Database, - } - if _, err := r.connection.GetDB(context.Background()); err != nil { - panic("Failed to connect mongodb") - } - - return r -} - -// FindOne retrieves audit information from mongodb searching by organization and ledger id -func (mar *AuditMongoDBRepository) FindOne(ctx context.Context, collection string, auditID AuditID) (*Audit, error) { - tracer := pkg.NewTracerFromContext(ctx) - - ctx, span := tracer.Start(ctx, "mongodb.find_audit") - defer span.End() - - db, err := mar.connection.GetDB(ctx) - if err != nil { - mopentelemetry.HandleSpanError(&span, "Failed to get database connection", err) - - return nil, err - } - - coll := db.Database(strings.ToLower(mar.Database)).Collection(strings.ToLower(collection)) - - var record AuditMongoDBModel - - ctx, spanFindOne := tracer.Start(ctx, "mongodb.find_audit.find_one") - - filter := bson.M{ - "_id.organization_id": auditID.OrganizationID, - "_id.ledger_id": auditID.LedgerID, - } - - if err = coll.FindOne(ctx, filter).Decode(&record); err != nil { - mopentelemetry.HandleSpanError(&spanFindOne, "Failed to find audit by id", err) - - return nil, err - } - - spanFindOne.End() - - return record.ToEntity(), nil -} - -// FindByID retrieves audit information from mongodb searching by organization and ledger id -func (mar *AuditMongoDBRepository) FindByID(ctx context.Context, collection string, auditID AuditID) (*Audit, error) { - tracer := pkg.NewTracerFromContext(ctx) - - ctx, span := tracer.Start(ctx, "mongodb.find_audit") - defer span.End() - - db, err := mar.connection.GetDB(ctx) - if err != nil { - mopentelemetry.HandleSpanError(&span, "Failed to get database connection", err) - - return nil, err - } - - coll := db.Database(strings.ToLower(mar.Database)).Collection(strings.ToLower(collection)) - - var record AuditMongoDBModel - - ctx, spanFindByID := tracer.Start(ctx, "mongodb.find_audit.find_by_id") - - if err = coll.FindOne(ctx, bson.M{"_id": auditID}).Decode(&record); err != nil { - mopentelemetry.HandleSpanError(&spanFindByID, "Failed to find audit by id", err) - - return nil, err - } - - spanFindByID.End() - - return record.ToEntity(), nil -} - -// Create inserts a new audit entity into mongodb -func (mar *AuditMongoDBRepository) Create(ctx context.Context, collection string, audit *Audit) error { - tracer := pkg.NewTracerFromContext(ctx) - - ctx, span := tracer.Start(ctx, "mongodb.create_audit") - defer span.End() - - db, err := mar.connection.GetDB(ctx) - if err != nil { - mopentelemetry.HandleSpanError(&span, "Failed to get database", err) - - return err - } - - coll := db.Database(strings.ToLower(mar.Database)).Collection(strings.ToLower(collection)) - record := &AuditMongoDBModel{} - - record.FromEntity(audit) - - ctx, spanInsert := tracer.Start(ctx, "mongodb.create_audit.insert") - - _, err = coll.InsertOne(ctx, record) - if err != nil { - mopentelemetry.HandleSpanError(&spanInsert, "Failed to insert audit", err) - - return err - } - - spanInsert.End() - - return nil -} diff --git a/components/audit/internal/adapters/rabbitmq/consumer.mock.go b/components/audit/internal/adapters/rabbitmq/consumer.mock.go deleted file mode 100644 index 8c8b6089..00000000 --- a/components/audit/internal/adapters/rabbitmq/consumer.mock.go +++ /dev/null @@ -1,65 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/LerianStudio/midaz/components/audit/internal/adapters/rabbitmq (interfaces: ConsumerRepository) -// -// Generated by this command: -// -// mockgen --destination=consumer.mock.go --package=rabbitmq . ConsumerRepository -// - -// Package rabbitmq is a generated GoMock package. -package rabbitmq - -import ( - reflect "reflect" - - gomock "go.uber.org/mock/gomock" -) - -// MockConsumerRepository is a mock of ConsumerRepository interface. -type MockConsumerRepository struct { - ctrl *gomock.Controller - recorder *MockConsumerRepositoryMockRecorder -} - -// MockConsumerRepositoryMockRecorder is the mock recorder for MockConsumerRepository. -type MockConsumerRepositoryMockRecorder struct { - mock *MockConsumerRepository -} - -// NewMockConsumerRepository creates a new mock instance. -func NewMockConsumerRepository(ctrl *gomock.Controller) *MockConsumerRepository { - mock := &MockConsumerRepository{ctrl: ctrl} - mock.recorder = &MockConsumerRepositoryMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockConsumerRepository) EXPECT() *MockConsumerRepositoryMockRecorder { - return m.recorder -} - -// Register mocks base method. -func (m *MockConsumerRepository) Register(arg0 string, arg1 QueueHandlerFunc) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "Register", arg0, arg1) -} - -// Register indicates an expected call of Register. -func (mr *MockConsumerRepositoryMockRecorder) Register(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Register", reflect.TypeOf((*MockConsumerRepository)(nil).Register), arg0, arg1) -} - -// RunConsumers mocks base method. -func (m *MockConsumerRepository) RunConsumers() error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "RunConsumers") - ret0, _ := ret[0].(error) - return ret0 -} - -// RunConsumers indicates an expected call of RunConsumers. -func (mr *MockConsumerRepositoryMockRecorder) RunConsumers() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RunConsumers", reflect.TypeOf((*MockConsumerRepository)(nil).RunConsumers)) -} diff --git a/components/audit/internal/adapters/rabbitmq/consumer.rabbitmq.go b/components/audit/internal/adapters/rabbitmq/consumer.rabbitmq.go deleted file mode 100644 index 8dcea85a..00000000 --- a/components/audit/internal/adapters/rabbitmq/consumer.rabbitmq.go +++ /dev/null @@ -1,99 +0,0 @@ -package rabbitmq - -import ( - "context" - "github.com/LerianStudio/midaz/pkg" - "github.com/LerianStudio/midaz/pkg/mlog" - "github.com/LerianStudio/midaz/pkg/mopentelemetry" - "github.com/LerianStudio/midaz/pkg/mrabbitmq" - "github.com/LerianStudio/midaz/pkg/net/http" -) - -// ConsumerRepository provides an interface for Consumer related to rabbitmq. -// -//go:generate mockgen --destination=consumer.mock.go --package=rabbitmq . ConsumerRepository -type ConsumerRepository interface { - Register(queueName string, handler QueueHandlerFunc) - RunConsumers() error -} - -// QueueHandlerFunc is a function that process a specific queue. -type QueueHandlerFunc func(ctx context.Context, body []byte) error - -// ConsumerRoutes struct -type ConsumerRoutes struct { - conn *mrabbitmq.RabbitMQConnection - routes map[string]QueueHandlerFunc - mlog.Logger - mopentelemetry.Telemetry -} - -// NewConsumerRoutes creates a new instance of ConsumerRoutes. -func NewConsumerRoutes(conn *mrabbitmq.RabbitMQConnection, logger mlog.Logger, telemetry *mopentelemetry.Telemetry) *ConsumerRoutes { - cr := &ConsumerRoutes{ - conn: conn, - routes: make(map[string]QueueHandlerFunc), - Logger: logger, - Telemetry: *telemetry, - } - - _, err := conn.GetNewConnect() - if err != nil { - panic("Failed to connect rabbitmq") - } - - return cr -} - -// Register add a new queue to handler. -func (cr *ConsumerRoutes) Register(queueName string, handler QueueHandlerFunc) { - cr.routes[queueName] = handler -} - -// RunConsumers init consume for all registry queues. -func (cr *ConsumerRoutes) RunConsumers() error { - for queueName, handler := range cr.routes { - cr.Logger.Infof("Initializing consumer for queue: %s", queueName) - - messages, err := cr.conn.Channel.Consume( - queueName, - "", - false, - false, - false, - false, - nil, - ) - if err != nil { - return err - } - - go func(queue string, handlerFunc QueueHandlerFunc) { - for msg := range messages { - midazID, found := msg.Headers[http.HeaderMidazID] - if !found { - midazID = pkg.GenerateUUIDv7().String() - } - - log := cr.Logger.WithFields( - http.HeaderMidazID, midazID.(string), - ).WithDefaultMessageTemplate(midazID.(string) + " | ") - - ctx := pkg.ContextWithLogger(pkg.ContextWithMidazID(context.Background(), midazID.(string)), log) - - err := handlerFunc(ctx, msg.Body) - if err != nil { - cr.Logger.Errorf("Error processing message, resend messages to queue %s: %v", queue, err) - - _ = msg.Nack(false, true) - - continue - } - - _ = msg.Ack(false) - } - }(queueName, handler) - } - - return nil -} diff --git a/components/audit/internal/bootstrap/config.go b/components/audit/internal/bootstrap/config.go deleted file mode 100644 index 1d81cc68..00000000 --- a/components/audit/internal/bootstrap/config.go +++ /dev/null @@ -1,138 +0,0 @@ -package bootstrap - -import ( - "fmt" - "github.com/LerianStudio/midaz/components/audit/internal/adapters/rabbitmq" - - "github.com/LerianStudio/midaz/components/audit/internal/adapters/grpc/out" - "github.com/LerianStudio/midaz/components/audit/internal/adapters/http/in" - "github.com/LerianStudio/midaz/components/audit/internal/adapters/mongodb/audit" - "github.com/LerianStudio/midaz/components/audit/internal/services" - "github.com/LerianStudio/midaz/pkg" - "github.com/LerianStudio/midaz/pkg/mcasdoor" - "github.com/LerianStudio/midaz/pkg/mmongo" - "github.com/LerianStudio/midaz/pkg/mopentelemetry" - "github.com/LerianStudio/midaz/pkg/mrabbitmq" - "github.com/LerianStudio/midaz/pkg/mtrillian" - "github.com/LerianStudio/midaz/pkg/mzap" -) - -// Config is the top level configuration struct for the entire application. -type Config struct { - EnvName string `env:"ENV_NAME"` - ServerAddress string `env:"SERVER_ADDRESS"` - LogLevel string `env:"LOG_LEVEL"` - JWKAddress string `env:"CASDOOR_JWK_ADDRESS"` - CasdoorEnforcerName string `env:"CASDOOR_ENFORCER_NAME"` - OtelServiceName string `env:"OTEL_RESOURCE_SERVICE_NAME"` - OtelLibraryName string `env:"OTEL_LIBRARY_NAME"` - OtelServiceVersion string `env:"OTEL_RESOURCE_SERVICE_VERSION"` - OtelDeploymentEnv string `env:"OTEL_RESOURCE_DEPLOYMENT_ENVIRONMENT"` - OtelColExporterEndpoint string `env:"OTEL_EXPORTER_OTLP_ENDPOINT"` - CasdoorAddress string `env:"CASDOOR_ADDRESS"` - CasdoorClientID string `env:"CASDOOR_CLIENT_ID"` - CasdoorClientSecret string `env:"CASDOOR_CLIENT_SECRET"` - CasdoorOrganizationName string `env:"CASDOOR_ORGANIZATION_NAME"` - CasdoorApplicationName string `env:"CASDOOR_APPLICATION_NAME"` - CasdoorModelName string `env:"CASDOOR_MODEL_NAME"` - MongoURI string `env:"MONGO_URI"` - MongoDBHost string `env:"MONGO_HOST"` - MongoDBName string `env:"MONGO_NAME"` - MongoDBUser string `env:"MONGO_USER"` - MongoDBPassword string `env:"MONGO_PASSWORD"` - MongoDBPort string `env:"MONGO_PORT"` - RabbitURI string `env:"RABBITMQ_URI"` - RabbitMQHost string `env:"RABBITMQ_HOST"` - RabbitMQPortHost string `env:"RABBITMQ_PORT_HOST"` - RabbitMQPortAMQP string `env:"RABBITMQ_PORT_AMPQ"` - RabbitMQUser string `env:"RABBITMQ_DEFAULT_USER"` - RabbitMQPass string `env:"RABBITMQ_DEFAULT_PASS"` - RabbitMQQueue string `env:"RABBITMQ_QUEUE"` - TrillianGRPCAddress string `env:"TRILLIAN_GRPC_ADDRESS"` - TrillianHTTPAddress string `env:"TRILLIAN_HTTP_ADDRESS"` -} - -// InitServers initiate http and grpc servers. -func InitServers() *Service { - cfg := &Config{} - - if err := pkg.SetConfigFromEnvVars(cfg); err != nil { - panic(err) - } - - logger := mzap.InitializeLogger() - - telemetry := &mopentelemetry.Telemetry{ - LibraryName: cfg.OtelLibraryName, - ServiceName: cfg.OtelServiceName, - ServiceVersion: cfg.OtelServiceVersion, - DeploymentEnv: cfg.OtelDeploymentEnv, - CollectorExporterEndpoint: cfg.OtelColExporterEndpoint, - } - - casDoorConnection := &mcasdoor.CasdoorConnection{ - JWKUri: cfg.JWKAddress, - Endpoint: cfg.CasdoorAddress, - ClientID: cfg.CasdoorClientID, - ClientSecret: cfg.CasdoorClientSecret, - OrganizationName: cfg.CasdoorOrganizationName, - ApplicationName: cfg.CasdoorApplicationName, - ModelName: cfg.CasdoorModelName, - Logger: logger, - } - - rabbitSource := fmt.Sprintf("%s://%s:%s@%s:%s", - cfg.RabbitURI, cfg.RabbitMQUser, cfg.RabbitMQPass, cfg.RabbitMQHost, cfg.RabbitMQPortHost) - - rabbitMQConnection := &mrabbitmq.RabbitMQConnection{ - ConnectionStringSource: rabbitSource, - Host: cfg.RabbitMQHost, - Port: cfg.RabbitMQPortAMQP, - User: cfg.RabbitMQUser, - Pass: cfg.RabbitMQPass, - Queue: cfg.RabbitMQQueue, - Logger: logger, - } - - trillianConnection := &mtrillian.TrillianConnection{ - AddrGRPC: cfg.TrillianGRPCAddress, - AddrHTTP: cfg.TrillianHTTPAddress, - Logger: logger, - } - - mongoSource := fmt.Sprintf("%s://%s:%s@%s:%s", - cfg.MongoURI, cfg.MongoDBUser, cfg.MongoDBPassword, cfg.MongoDBHost, cfg.MongoDBPort) - - mongoAuditConnection := &mmongo.MongoConnection{ - ConnectionStringSource: mongoSource, - Database: cfg.MongoDBName, - Logger: logger, - } - - trillianRepository := out.NewTrillianRepository(trillianConnection) - - auditMongoDBRepository := audit.NewAuditMongoDBRepository(mongoAuditConnection) - - useCase := &services.UseCase{ - TrillianRepo: trillianRepository, - AuditRepo: auditMongoDBRepository, - } - - trillianHandler := &in.TrillianHandler{ - UseCase: useCase, - } - - routes := rabbitmq.NewConsumerRoutes(rabbitMQConnection, logger, telemetry) - - multiQueueConsumer := NewMultiQueueConsumer(routes, useCase) - - app := in.NewRouter(logger, telemetry, casDoorConnection, trillianHandler) - - server := NewServer(cfg, app, logger, telemetry) - - return &Service{ - Server: server, - MultiQueueConsumer: multiQueueConsumer, - Logger: logger, - } -} diff --git a/components/audit/internal/bootstrap/consumer.go b/components/audit/internal/bootstrap/consumer.go deleted file mode 100644 index c61b5b1e..00000000 --- a/components/audit/internal/bootstrap/consumer.go +++ /dev/null @@ -1,72 +0,0 @@ -package bootstrap - -import ( - "context" - "encoding/json" - "github.com/LerianStudio/midaz/pkg/mmodel" - "github.com/LerianStudio/midaz/pkg/mopentelemetry" - "os" - - "github.com/LerianStudio/midaz/components/audit/internal/adapters/rabbitmq" - "github.com/LerianStudio/midaz/components/audit/internal/services" - "github.com/LerianStudio/midaz/pkg" -) - -// MultiQueueConsumer represents a multi-queue consumer. -type MultiQueueConsumer struct { - consumerRoutes *rabbitmq.ConsumerRoutes - UseCase *services.UseCase -} - -// NewMultiQueueConsumer create a new instance of MultiQueueConsumer. -func NewMultiQueueConsumer(routes *rabbitmq.ConsumerRoutes, useCase *services.UseCase) *MultiQueueConsumer { - consumer := &MultiQueueConsumer{ - consumerRoutes: routes, - UseCase: useCase, - } - - // Registry handlers for each queue - routes.Register(os.Getenv("RABBITMQ_QUEUE"), consumer.handleAuditQueue) - - return consumer -} - -// Run starts consumers for all registered queues. -func (mq *MultiQueueConsumer) Run(l *pkg.Launcher) error { - return mq.consumerRoutes.RunConsumers() -} - -// handleAuditQueue process messages from queue. -func (mq *MultiQueueConsumer) handleAuditQueue(ctx context.Context, body []byte) error { - logger := pkg.NewLoggerFromContext(ctx) - tracer := pkg.NewTracerFromContext(ctx) - - ctx, span := tracer.Start(ctx, "consumer.handleAuditQueue") - defer span.End() - - logger.Info("Processing message from queue") - - var message mmodel.Queue - - err := json.Unmarshal(body, &message) - if err != nil { - mopentelemetry.HandleSpanError(&span, "Error unmarshalling message JSON", err) - - logger.Errorf("Error unmarshalling transaction message JSON: %v", err) - - return err - } - - logger.Infof("Message consumed: %s", message.AuditID) - - err = mq.UseCase.CreateLog(ctx, message.OrganizationID, message.LedgerID, message.AuditID, message.QueueData) - if err != nil { - mopentelemetry.HandleSpanError(&span, "Error creating log", err) - - logger.Errorf("Error creating log: %v", err) - - return err - } - - return nil -} diff --git a/components/audit/internal/bootstrap/server.go b/components/audit/internal/bootstrap/server.go deleted file mode 100644 index 944c3a6a..00000000 --- a/components/audit/internal/bootstrap/server.go +++ /dev/null @@ -1,52 +0,0 @@ -package bootstrap - -import ( - "github.com/LerianStudio/midaz/pkg" - "github.com/LerianStudio/midaz/pkg/mlog" - "github.com/LerianStudio/midaz/pkg/mopentelemetry" - - "github.com/gofiber/fiber/v2" - "github.com/pkg/errors" -) - -// Server represents the http server for Ledger services. -type Server struct { - app *fiber.App - serverAddress string - mlog.Logger - mopentelemetry.Telemetry -} - -// ServerAddress returns is a convenience method to return the server address. -func (s *Server) ServerAddress() string { - return s.serverAddress -} - -// NewServer creates an instance of Server. -func NewServer(cfg *Config, app *fiber.App, logger mlog.Logger, telemetry *mopentelemetry.Telemetry) *Server { - return &Server{ - app: app, - serverAddress: cfg.ServerAddress, - Logger: logger, - Telemetry: *telemetry, - } -} - -// Run runs the server. -func (s *Server) Run(l *pkg.Launcher) error { - s.InitializeTelemetry(s.Logger) - defer s.ShutdownTelemetry() - - defer func() { - if err := s.Logger.Sync(); err != nil { - s.Logger.Fatalf("Failed to sync logger: %s", err) - } - }() - - err := s.app.Listen(s.ServerAddress()) - if err != nil { - return errors.Wrap(err, "failed to run the server") - } - - return nil -} diff --git a/components/audit/internal/bootstrap/service.go b/components/audit/internal/bootstrap/service.go deleted file mode 100644 index 5541ad19..00000000 --- a/components/audit/internal/bootstrap/service.go +++ /dev/null @@ -1,23 +0,0 @@ -package bootstrap - -import ( - "github.com/LerianStudio/midaz/pkg" - "github.com/LerianStudio/midaz/pkg/mlog" -) - -// Service is the application glue where we put all top level components to be used. -type Service struct { - *Server - *MultiQueueConsumer - mlog.Logger -} - -// Run starts the application. -// This is the only necessary code to run an app in main.go -func (app *Service) Run() { - pkg.NewLauncher( - pkg.WithLogger(app.Logger), - pkg.RunApp("HTTP Service", app.Server), - pkg.RunApp("RabbitMQ Consumer", app.MultiQueueConsumer), - ).Run() -} diff --git a/components/audit/internal/services/create-log.go b/components/audit/internal/services/create-log.go deleted file mode 100644 index 495256e6..00000000 --- a/components/audit/internal/services/create-log.go +++ /dev/null @@ -1,87 +0,0 @@ -package services - -import ( - "context" - "errors" - "github.com/LerianStudio/midaz/components/audit/internal/adapters/mongodb/audit" - "github.com/LerianStudio/midaz/pkg" - "github.com/LerianStudio/midaz/pkg/mmodel" - "github.com/LerianStudio/midaz/pkg/mopentelemetry" - "github.com/google/uuid" - "go.mongodb.org/mongo-driver/mongo" - "time" -) - -// CreateLog creates an audit log for the operations of a transaction -func (uc *UseCase) CreateLog(ctx context.Context, organizationID, ledgerID, auditID uuid.UUID, data []mmodel.QueueData) error { - logger := pkg.NewLoggerFromContext(ctx) - tracer := pkg.NewTracerFromContext(ctx) - - ctx, span := tracer.Start(ctx, "services.create_audit_log") - defer span.End() - - logger.Infof("Trying to create log leaves for audit ID: %v", auditID) - - auditObj := audit.Audit{ - ID: audit.AuditID{ - OrganizationID: organizationID.String(), - LedgerID: ledgerID.String(), - ID: auditID.String(), - }, - Leaves: make(map[string]string), - CreatedAt: time.Now(), - } - - one, err := uc.AuditRepo.FindOne(ctx, audit.TreeCollection, auditObj.ID) - if err != nil { - if !errors.Is(err, mongo.ErrNoDocuments) { - mopentelemetry.HandleSpanError(&span, "Failed to get audit info", err) - - logger.Errorf("Failed to get audit info: %v", err) - - return err - } - - ledgerID := auditObj.ID.LedgerID - treeName := ledgerID[len(ledgerID)-12:] - - treeID, err := uc.TrillianRepo.CreateTree(ctx, "Tree "+treeName, ledgerID) - if err != nil { - mopentelemetry.HandleSpanError(&span, "Failed to create audit tree", err) - - logger.Errorf("Error creating audit tree: %v", err) - - return err - } - - auditObj.TreeID = treeID - } else { - auditObj.TreeID = one.TreeID - } - - for _, item := range data { - logger.Infof("Saving leaf for %v", item.ID) - - leaf, err := uc.TrillianRepo.CreateLog(ctx, auditObj.TreeID, item.Value) - if err != nil { - mopentelemetry.HandleSpanError(&span, "Error creating audit log", err) - - logger.Errorf("Error creating audit log %v", err) - - return err - } - - auditObj.Leaves[item.ID.String()] = leaf - } - - err = uc.AuditRepo.Create(ctx, audit.TreeCollection, &auditObj) - if err != nil { - mopentelemetry.HandleSpanError(&span, "Failed to save audit tree info", err) - - logger.Errorf("Error saving %s audit: %v", audit.TreeCollection, err) - - return err - } - - return nil -} diff --git a/components/audit/internal/services/create-log_test.go b/components/audit/internal/services/create-log_test.go deleted file mode 100644 index 35774837..00000000 --- a/components/audit/internal/services/create-log_test.go +++ /dev/null @@ -1,188 +0,0 @@ -package services - -import ( - "context" - "encoding/json" - "errors" - "testing" - "time" - - "github.com/google/uuid" - "github.com/stretchr/testify/assert" - "go.mongodb.org/mongo-driver/mongo" - "go.uber.org/mock/gomock" - - "github.com/LerianStudio/midaz/components/audit/internal/adapters/grpc/out" - "github.com/LerianStudio/midaz/components/audit/internal/adapters/mongodb/audit" - "github.com/LerianStudio/midaz/pkg" - "github.com/LerianStudio/midaz/pkg/mmodel" -) - -func createMockedData() (audit.Audit, []mmodel.QueueData, map[string]string) { - mockedQueueData := []mmodel.QueueData{ - {ID: pkg.GenerateUUIDv7(), Value: json.RawMessage("Log A")}, - {ID: pkg.GenerateUUIDv7(), Value: json.RawMessage("Log B")}, - } - - mockedLeaves := map[string]string{ - mockedQueueData[0].ID.String(): "18240592D5594FB370E73AC81DD5C8E5EC5AB07D5874F40154A8D54BDC390B3C", - mockedQueueData[1].ID.String(): "4EF0C3FAA84E1D3001658CC9A4CA78463B042CA42909456F3DAEF4A94B77FEB7", - } - - mockedAudit := audit.Audit{ - ID: audit.AuditID{ - OrganizationID: pkg.GenerateUUIDv7().String(), - LedgerID: pkg.GenerateUUIDv7().String(), - ID: pkg.GenerateUUIDv7().String(), - }, - TreeID: int64(9080682816463212189), - Leaves: mockedLeaves, - CreatedAt: time.Now(), - } - - return mockedAudit, mockedQueueData, mockedLeaves -} - -func validateAudit(actual, expected *audit.Audit) error { - if actual.TreeID != expected.TreeID || - actual.ID.OrganizationID != expected.ID.OrganizationID || - actual.ID.LedgerID != expected.ID.LedgerID || - actual.ID.ID != expected.ID.ID { - return errors.New("audit ID fields did not match") - } - - if len(actual.Leaves) != len(expected.Leaves) { - return errors.New("leaves length did not match") - } - - for k, v := range actual.Leaves { - if v != expected.Leaves[k] { - return errors.New("leaf mismatch for key: " + k) - } - } - - return nil -} - -func Test_CreateLog(t *testing.T) { - mockedAudit, mockedQueueData, mockedLeaves := createMockedData() - - uc := UseCase{ - AuditRepo: audit.NewMockRepository(gomock.NewController(t)), - TrillianRepo: out.NewMockRepository(gomock.NewController(t)), - } - - // Audit already exists for the organization and ledger - uc.AuditRepo.(*audit.MockRepository). - EXPECT(). - FindOne(gomock.Any(), audit.TreeCollection, mockedAudit.ID). - Return(&mockedAudit, nil). - Times(1) - - // Must not call because the tree already exists - uc.TrillianRepo.(*out.MockRepository). - EXPECT(). - CreateTree(gomock.Any(), gomock.Any(), gomock.Any()). - Times(0) - - for _, data := range mockedQueueData { - uc.TrillianRepo.(*out.MockRepository). - EXPECT(). - CreateLog(gomock.Any(), mockedAudit.TreeID, data.Value). - Return(mockedLeaves[data.ID.String()], nil). - Times(1) - } - - uc.AuditRepo.(*audit.MockRepository). - EXPECT(). - Create(gomock.Any(), audit.TreeCollection, gomock.AssignableToTypeOf(&audit.Audit{})). - DoAndReturn(func(ctx context.Context, collection string, o *audit.Audit) error { - return validateAudit(o, &mockedAudit) - }). - Times(1) - - err := uc.CreateLog(context.TODO(), uuid.MustParse(mockedAudit.ID.OrganizationID), uuid.MustParse(mockedAudit.ID.LedgerID), uuid.MustParse(mockedAudit.ID.ID), mockedQueueData) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } -} - -func Test_CreateLog_NewTree(t *testing.T) { - mockedAudit, mockedQueueData, mockedLeaves := createMockedData() - - uc := UseCase{ - AuditRepo: audit.NewMockRepository(gomock.NewController(t)), - TrillianRepo: out.NewMockRepository(gomock.NewController(t)), - } - - // Audit does not exist yet - uc.AuditRepo.(*audit.MockRepository). - EXPECT(). - FindOne(gomock.Any(), audit.TreeCollection, mockedAudit.ID). - Return(nil, mongo.ErrNoDocuments). - Times(1) - - // Mock tree creation - ledgerID := mockedAudit.ID.LedgerID - treeName := ledgerID[len(ledgerID)-12:] - uc.TrillianRepo.(*out.MockRepository). - EXPECT(). - CreateTree(gomock.Any(), "Tree "+treeName, ledgerID). - Return(mockedAudit.TreeID, nil). - Times(1) - - for _, data := range mockedQueueData { - uc.TrillianRepo.(*out.MockRepository). - EXPECT(). - CreateLog(gomock.Any(), mockedAudit.TreeID, data.Value). - Return(mockedLeaves[data.ID.String()], nil). - Times(1) - } - - uc.AuditRepo.(*audit.MockRepository). - EXPECT(). - Create(gomock.Any(), audit.TreeCollection, gomock.AssignableToTypeOf(&audit.Audit{})). - DoAndReturn(func(ctx context.Context, collection string, o *audit.Audit) error { - return validateAudit(o, &mockedAudit) - }). - Times(1) - - err := uc.CreateLog(context.TODO(), uuid.MustParse(mockedAudit.ID.OrganizationID), uuid.MustParse(mockedAudit.ID.LedgerID), uuid.MustParse(mockedAudit.ID.ID), mockedQueueData) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } -} - -func Test_CreateLog_ErrorFindAudit(t *testing.T) { - mockedAudit, mockedQueueData, _ := createMockedData() - - uc := UseCase{ - AuditRepo: audit.NewMockRepository(gomock.NewController(t)), - TrillianRepo: out.NewMockRepository(gomock.NewController(t)), - } - - uc.AuditRepo.(*audit.MockRepository). - EXPECT(). - FindOne(gomock.Any(), audit.TreeCollection, mockedAudit.ID). - Return(nil, mongo.ErrClientDisconnected). - Times(1) - - uc.TrillianRepo.(*out.MockRepository). - EXPECT(). - CreateTree(gomock.Any(), gomock.Any(), gomock.Any()). - Times(0) - - uc.TrillianRepo.(*out.MockRepository). - EXPECT(). - CreateLog(gomock.Any(), gomock.Any(), gomock.Any()). - Times(0) - - uc.AuditRepo.(*audit.MockRepository). - EXPECT(). - Create(gomock.Any(), gomock.Any(), gomock.Any()). - Times(0) - - err := uc.CreateLog(context.TODO(), uuid.MustParse(mockedAudit.ID.OrganizationID), uuid.MustParse(mockedAudit.ID.LedgerID), uuid.MustParse(mockedAudit.ID.ID), mockedQueueData) - - assert.NotNil(t, err) -} diff --git a/components/audit/internal/services/get-audit-info.go b/components/audit/internal/services/get-audit-info.go deleted file mode 100644 index c7cd43df..00000000 --- a/components/audit/internal/services/get-audit-info.go +++ /dev/null @@ -1,39 +0,0 @@ -package services - -import ( - "context" - "github.com/LerianStudio/midaz/components/audit/internal/adapters/mongodb/audit" - "github.com/LerianStudio/midaz/pkg" - "github.com/LerianStudio/midaz/pkg/constant" - "github.com/LerianStudio/midaz/pkg/mopentelemetry" - "github.com/google/uuid" - "reflect" -) - -// GetAuditInfo retrieves auditing information -func (uc *UseCase) GetAuditInfo(ctx context.Context, organizationID uuid.UUID, ledgerID uuid.UUID, id uuid.UUID) (*audit.Audit, error) { - logger := pkg.NewLoggerFromContext(ctx) - tracer := pkg.NewTracerFromContext(ctx) - - ctx, span := tracer.Start(ctx, "services.get_audit_info") - defer span.End() - - logger.Infof("Retrieving audit info") - - auditID := audit.AuditID{ - OrganizationID: organizationID.String(), - LedgerID: ledgerID.String(), - ID: id.String(), - } - - auditInfo, err := uc.AuditRepo.FindByID(ctx, audit.TreeCollection, auditID) - if err != nil { - mopentelemetry.HandleSpanError(&span, "Failed to get audit info", err) - - logger.Errorf("Error getting audit info: %v", err) - - return nil, pkg.ValidateBusinessError(constant.ErrAuditRecordNotRetrieved, reflect.TypeOf(audit.Audit{}).Name(), id.String()) - } - - return auditInfo, nil -} diff --git a/components/audit/internal/services/get-audit-info_test.go b/components/audit/internal/services/get-audit-info_test.go deleted file mode 100644 index 64bba894..00000000 --- a/components/audit/internal/services/get-audit-info_test.go +++ /dev/null @@ -1,42 +0,0 @@ -package services - -import ( - "context" - "github.com/LerianStudio/midaz/components/audit/internal/adapters/mongodb/audit" - "github.com/LerianStudio/midaz/pkg" - "github.com/stretchr/testify/assert" - "go.uber.org/mock/gomock" - "testing" -) - -func Test_GetAuditInfo(t *testing.T) { - organizationID := pkg.GenerateUUIDv7() - ledgerID := pkg.GenerateUUIDv7() - id := pkg.GenerateUUIDv7() - - mockedAudit := audit.Audit{ - ID: audit.AuditID{ - OrganizationID: organizationID.String(), - LedgerID: ledgerID.String(), - ID: id.String(), - }, - TreeID: int64(9080682816463212189), - } - - uc := UseCase{ - AuditRepo: audit.NewMockRepository(gomock.NewController(t)), - } - - uc.AuditRepo.(*audit.MockRepository). - EXPECT(). - FindByID(gomock.Any(), audit.TreeCollection, mockedAudit.ID). - Return(&mockedAudit, nil). - Times(1) - - info, err := uc.GetAuditInfo(context.TODO(), organizationID, ledgerID, id) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - - assert.Equal(t, mockedAudit, *info) -} diff --git a/components/audit/internal/services/get-log-by-hash.go b/components/audit/internal/services/get-log-by-hash.go deleted file mode 100644 index a174c1d4..00000000 --- a/components/audit/internal/services/get-log-by-hash.go +++ /dev/null @@ -1,32 +0,0 @@ -package services - -import ( - "context" - "encoding/hex" - "github.com/LerianStudio/midaz/pkg" - "github.com/LerianStudio/midaz/pkg/constant" - "github.com/LerianStudio/midaz/pkg/mopentelemetry" - "github.com/google/trillian" - "reflect" - "strings" -) - -// GetLogByHash search for leaf value by the leaf identity hash -func (uc *UseCase) GetLogByHash(ctx context.Context, treeID int64, identityHash string) (string, []byte, error) { - logger := pkg.NewLoggerFromContext(ctx) - tracer := pkg.NewTracerFromContext(ctx) - - ctx, span := tracer.Start(ctx, "services.get_log_by_hash") - defer span.End() - - log, err := uc.TrillianRepo.GetLogByHash(ctx, treeID, identityHash) - if err != nil { - mopentelemetry.HandleSpanError(&span, "Failed to get log by hash", err) - - logger.Errorf("Error getting log by hash: %v", err) - - return "", nil, pkg.ValidateBusinessError(constant.ErrAuditTreeRecordNotFound, reflect.TypeOf(trillian.LogLeaf{}).Name(), identityHash) - } - - return strings.ToUpper(hex.EncodeToString(log.MerkleLeafHash)), log.LeafValue, nil -} diff --git a/components/audit/internal/services/get-log-by-hash_test.go b/components/audit/internal/services/get-log-by-hash_test.go deleted file mode 100644 index 44080ec0..00000000 --- a/components/audit/internal/services/get-log-by-hash_test.go +++ /dev/null @@ -1,40 +0,0 @@ -package services - -import ( - "context" - "encoding/hex" - "github.com/LerianStudio/midaz/components/audit/internal/adapters/grpc/out" - "github.com/google/trillian" - "github.com/stretchr/testify/assert" - "go.uber.org/mock/gomock" - "strings" - "testing" -) - -func Test_GetLogByHash(t *testing.T) { - treeID := int64(9080682816463212189) - identityHash := "18240592D5594FB370E73AC81DD5C8E5EC5AB07D5874F40154A8D54BDC390B3C" - - mockedLogLeaf := &trillian.LogLeaf{ - MerkleLeafHash: []byte(identityHash), - LeafValue: []byte("Log A"), - } - - uc := UseCase{ - TrillianRepo: out.NewMockRepository(gomock.NewController(t)), - } - - uc.TrillianRepo.(*out.MockRepository). - EXPECT(). - GetLogByHash(gomock.Any(), treeID, identityHash). - Return(mockedLogLeaf, nil). - Times(1) - - merkleLeafHash, logValue, err := uc.GetLogByHash(context.TODO(), treeID, identityHash) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - - assert.Equal(t, strings.ToUpper(hex.EncodeToString(mockedLogLeaf.MerkleLeafHash)), merkleLeafHash) - assert.Equal(t, []byte("Log A"), logValue) -} diff --git a/components/audit/internal/services/usecase.go b/components/audit/internal/services/usecase.go deleted file mode 100644 index 1897473c..00000000 --- a/components/audit/internal/services/usecase.go +++ /dev/null @@ -1,15 +0,0 @@ -package services - -import ( - "github.com/LerianStudio/midaz/components/audit/internal/adapters/grpc/out" - "github.com/LerianStudio/midaz/components/audit/internal/adapters/mongodb/audit" -) - -// UseCase is a struct that aggregates various repositories for simplified access in use case implementation. -type UseCase struct { - // TrillianRepo provides an abstraction on top of Trillian gRPC. - TrillianRepo out.Repository - - // AuditRepo provides an abstraction on top of the audit data source - AuditRepo audit.Repository -} diff --git a/components/audit/internal/services/validate-log-hash.go b/components/audit/internal/services/validate-log-hash.go deleted file mode 100644 index 9ce6937f..00000000 --- a/components/audit/internal/services/validate-log-hash.go +++ /dev/null @@ -1,40 +0,0 @@ -package services - -import ( - "bytes" - "context" - "encoding/hex" - "github.com/LerianStudio/midaz/pkg" - "github.com/LerianStudio/midaz/pkg/constant" - "github.com/LerianStudio/midaz/pkg/mopentelemetry" - "github.com/google/trillian" - "github.com/transparency-dev/merkle/rfc6962" - "reflect" - "strings" -) - -// ValidatedLogHash checks if the leaf value was tampered -func (uc *UseCase) ValidatedLogHash(ctx context.Context, treeID int64, identityHash string) (string, string, bool, error) { - logger := pkg.NewLoggerFromContext(ctx) - tracer := pkg.NewTracerFromContext(ctx) - - ctx, span := tracer.Start(ctx, "services.get_validated_log_hash") - defer span.End() - - log, err := uc.TrillianRepo.GetLogByHash(ctx, treeID, identityHash) - if err != nil { - mopentelemetry.HandleSpanError(&span, "Failed to get log by hash", err) - - logger.Errorf("Error getting log by hash: %v", err) - - return "", "", false, pkg.ValidateBusinessError(constant.ErrAuditTreeRecordNotFound, reflect.TypeOf(trillian.LogLeaf{}).Name(), identityHash) - } - - recalculatedHash := rfc6962.DefaultHasher.HashLeaf(log.LeafValue) - - return formatHash(log.MerkleLeafHash), formatHash(recalculatedHash), !bytes.Equal(log.MerkleLeafHash, recalculatedHash), nil -} - -func formatHash(input []byte) string { - return strings.ToUpper(hex.EncodeToString(input)) -} diff --git a/components/audit/internal/services/validate-log-hash_test.go b/components/audit/internal/services/validate-log-hash_test.go deleted file mode 100644 index 41838656..00000000 --- a/components/audit/internal/services/validate-log-hash_test.go +++ /dev/null @@ -1,79 +0,0 @@ -package services - -import ( - "context" - "encoding/hex" - "github.com/LerianStudio/midaz/components/audit/internal/adapters/grpc/out" - "github.com/google/trillian" - "github.com/stretchr/testify/assert" - "github.com/transparency-dev/merkle/rfc6962" - "go.uber.org/mock/gomock" - "strings" - "testing" -) - -func Test_ValidatedLogHash(t *testing.T) { - treeID := int64(9080682816463212189) - logValue := "Log A" - identityHash := rfc6962.DefaultHasher.HashLeaf([]byte(logValue)) - identityHashString := strings.ToUpper(hex.EncodeToString(identityHash)) - - mockedLogLeaf := &trillian.LogLeaf{ - MerkleLeafHash: identityHash, - LeafValue: []byte(logValue), - } - - uc := UseCase{ - TrillianRepo: out.NewMockRepository(gomock.NewController(t)), - } - - uc.TrillianRepo.(*out.MockRepository). - EXPECT(). - GetLogByHash(gomock.Any(), treeID, identityHashString). - Return(mockedLogLeaf, nil). - Times(1) - - merkleLeafHash, recalculatedHash, isTampered, err := uc.ValidatedLogHash(context.TODO(), treeID, identityHashString) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - - assert.Equal(t, identityHashString, merkleLeafHash) - assert.Equal(t, identityHashString, recalculatedHash) - assert.Equal(t, false, isTampered) -} - -func Test_ValidatedLogHash_Tampered(t *testing.T) { - treeID := int64(9080682816463212189) - logValue := "Log A" - identityHash := rfc6962.DefaultHasher.HashLeaf([]byte(logValue)) - identityHashString := strings.ToUpper(hex.EncodeToString(identityHash)) - - tamperedLogValue := "This was tampered" - tamperedIdentityHash := rfc6962.DefaultHasher.HashLeaf([]byte(tamperedLogValue)) - tamperedIdentityHashString := strings.ToUpper(hex.EncodeToString(tamperedIdentityHash)) - - mockedLogLeaf := &trillian.LogLeaf{ - MerkleLeafHash: identityHash, - LeafValue: []byte(tamperedLogValue), - } - - uc := UseCase{ - TrillianRepo: out.NewMockRepository(gomock.NewController(t)), - } - - uc.TrillianRepo.(*out.MockRepository). - EXPECT(). - GetLogByHash(gomock.Any(), treeID, identityHashString). - Return(mockedLogLeaf, nil). - Times(1) - - merkleLeafHash, recalculatedHash, isTampered, err := uc.ValidatedLogHash(context.TODO(), treeID, identityHashString) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - - assert.Equal(t, identityHashString, merkleLeafHash) - assert.Equal(t, tamperedIdentityHashString, recalculatedHash) - assert.Equal(t, true, isTampered) -} diff --git a/components/infra/rabbitmq/etc/definitions.json b/components/infra/rabbitmq/etc/definitions.json index b10e5d85..963b9d28 100644 --- a/components/infra/rabbitmq/etc/definitions.json +++ b/components/infra/rabbitmq/etc/definitions.json @@ -17,12 +17,6 @@ "password_hash":"/xSX/E+2TzPfqRPYnPIdviUpNiXnoQWnAdQR7TS47cJc6GuM", "hashing_algorithm":"rabbit_password_hashing_sha256", "tags":"administrator" - }, - { - "name":"audit", - "password_hash":"/xSX/E+2TzPfqRPYnPIdviUpNiXnoQWnAdQR7TS47cJc6GuM", - "hashing_algorithm":"rabbit_password_hashing_sha256", - "tags":"administrator" } ], "vhosts": [ @@ -51,21 +45,9 @@ "configure": ".*", "write": ".*", "read": ".*" - }, - { - "user": "audit", - "vhost": "/", - "configure": ".*", - "write": ".*", - "read": ".*" } ], "queues": [ - { - "name": "audit.append_log.queue", - "vhost": "/", - "durable": true - }, { "name": "transaction.balance_create.queue", "vhost": "/", @@ -78,12 +60,6 @@ } ], "exchanges": [ - { - "name": "audit.append_log.exchange", - "vhost": "/", - "type": "direct", - "durable": true - }, { "name": "transaction.balance_create.exchange", "vhost": "/", @@ -98,13 +74,6 @@ } ], "bindings": [ - { - "source": "audit.append_log.exchange", - "vhost": "/", - "destination": "audit.append_log.queue", - "destination_type": "queue", - "routing_key": "audit.append_log.key" - }, { "source": "transaction.balance_create.exchange", "vhost": "/", diff --git a/components/transaction/.env.example b/components/transaction/.env.example index f11b6cb1..8aa1c88d 100644 --- a/components/transaction/.env.example +++ b/components/transaction/.env.example @@ -81,13 +81,16 @@ RABBITMQ_PORT_HOST=3003 RABBITMQ_PORT_AMPQ=3004 RABBITMQ_DEFAULT_USER=transaction RABBITMQ_DEFAULT_PASS=lerian -RABBITMQ_AUDIT_EXCHANGE=audit.append_log.exchange -RABBITMQ_AUDIT_KEY=audit.append_log.key RABBITMQ_BALANCE_CREATE_QUEUE=transaction.balance_create.queue RABBITMQ_TRANSACTION_BALANCE_OPERATION_EXCHANGE=transaction.transaction_balance_operation.exchange RABBITMQ_TRANSACTION_BALANCE_OPERATION_KEY=transaction.transaction_balance_operation.key RABBITMQ_TRANSACTION_BALANCE_OPERATION_QUEUE=transaction.transaction_balance_operation.queue +# AUDIT DEFAULT OFF +AUDIT_LOG_ENABLED=false +RABBITMQ_AUDIT_EXCHANGE=audit.append_log.exchange +RABBITMQ_AUDIT_KEY=audit.append_log.key + # SWAGGER SWAGGER_TITLE=Transaction API SWAGGER_DESCRIPTION=Documentation for the Midaz Transaction API @@ -98,9 +101,6 @@ SWAGGER_SCHEMES=http SWAGGER_LEFT_DELIMITER={{ SWAGGER_RIGHT_DELIMITER=}} -# AUDIT -AUDIT_LOG_ENABLED=false - # PAGINATION MAX_PAGINATION_LIMIT=100 MAX_PAGINATION_MONTH_DATE_RANGE=1