feat(): Criado endpoint SEE/SESSIONS - Autenticação do cartório

This commit is contained in:
Kenio 2025-12-30 16:21:09 -03:00
parent d2954b6691
commit cae68daa70
9 changed files with 240 additions and 7 deletions

View file

@ -145,7 +145,7 @@ A execução em produção varia conforme o sistema operacional.
### **Windows (modo produção simulado)**
O **Gunicorn** não é compatível com Windows, pois depende do módulo `fcntl` exclusivo de sistemas Unix.
Portanto, em ambiente Windows, recomenda-se usar o **Uvicorn** diretamente com múltiplos *workers*:
Portanto, em ambiente Windows, recomenda-se usar o **Uvicorn** diretamente com múltiplos _workers_:
```bash
uvicorn main:app --host 0.0.0.0 --port 8000 --workers 4
@ -260,7 +260,7 @@ gunicorn main:app \
| --------------------------- | ------------------------------------------------------------------------------------ |
| Clonar projeto | `git clone https://git.oriustecnologia.com/OriusTecnologia/saas_api.git` |
| Criar venv | `python -m venv venv` |
| Ativar venv | `venv\Scripts\activate` *(Windows)*<br>`source venv/bin/activate` *(Linux/Mac)* |
| Ativar venv | `venv\Scripts\activate` _(Windows)_<br>`source venv/bin/activate` _(Linux/Mac)_ |
| Instalar dependências | `pip install -r requirements.txt` |
| Rodar em desenvolvimento | `uvicorn main:app --reload` |
| Rodar em produção (Windows) | `uvicorn main:app --host 0.0.0.0 --port 8000 --workers 4` |
@ -271,11 +271,27 @@ gunicorn main:app \
## 12. Recomendações Finais
* Em **Windows**, use Uvicorn ou Hypercorn apenas para testes e ambientes locais.
* Para **produção real**, use **Linux** com Gunicorn + Uvicorn Worker, idealmente em container **Docker**.
* Monitore o consumo de CPU/RAM e ajuste o número de *workers* conforme o ambiente.
* Automatize o serviço em produção via **systemd** (ex: `/etc/systemd/system/saas_api.service`) para iniciar junto com o servidor.
- Em **Windows**, use Uvicorn ou Hypercorn apenas para testes e ambientes locais.
- Para **produção real**, use **Linux** com Gunicorn + Uvicorn Worker, idealmente em container **Docker**.
- Monitore o consumo de CPU/RAM e ajuste o número de _workers_ conforme o ambiente.
- Automatize o serviço em produção via **systemd** (ex: `/etc/systemd/system/saas_api.service`) para iniciar junto com o servidor.
---
uvicorn main:app --host 0.0.0.0 --port 8000
## 13. Configuração de acesso ao Firebird
1. Configurar o Firebird para aceitar conexões remotas:
Como o Firebird está "fora" do Docker, ele pode estar configurado para ouvir apenas em localhost. Para o Docker conseguir conectar, o Firebird precisa ouvir na interface de rede do Docker ou em todas as interfaces.
No arquivo firebird.conf (geralmente em /opt/firebird), verifique a linha: RemoteBindAddress =
Mude para: RemoteBindAddress = 0.0.0.0 (ou apenas para o IP 172.17.0.1).
Reinicie o serviço do Firebird.
2. Configurar as Variáveis no Easypanel:
Na aba Environment do seu serviço no Easypanel, configure sua conexão assim:
ORIUS_API_FDB_HOST=172.17.0.1

View file

@ -53,6 +53,7 @@ from packages.v1.servicos.balcao.endpoints import (
t_servico_itempedido_endpoint,
t_servico_pedido_endpoint,
)
from packages.v1.selos.endpoints import see_endpoint
# Cria uma instância do APIRouter que vai agregar todas as rotas da API
api_router = APIRouter()
@ -383,3 +384,10 @@ api_router.include_router(
prefix="/administrativo/t_biometria_pessoa",
tags=["Pessoa Cartao"],
)
# Inclui as rotas de g_emolumento periodo
api_router.include_router(
see_endpoint.router,
prefix="/selos/see",
tags=["Sistema Extrajudicial Eletrônico (SEE)"],
)

View file

@ -0,0 +1,16 @@
from abstracts.action import BaseAction
from packages.v1.selos.schemas.see_schema import CartorioAuthenticateSchema
from packages.v1.selos.repositories.see.sessions_repository import (
SessionsRepository,
)
class SessionsAction(BaseAction):
async def execute(self, cartorio_authenticate_schema=CartorioAuthenticateSchema):
# Importação do repositório
sessions_repository = SessionsRepository()
# Execução do repositório
return await sessions_repository.execute(cartorio_authenticate_schema)

View file

@ -0,0 +1,42 @@
from fastapi import Request
from actions.dynamic_import.dynamic_import import DynamicImport
from packages.v1.selos.schemas.see_schema import CartorioAuthenticateSchema
class SeeController:
def __init__(self):
# Action responsável por carregar as services de acodo com o estado
self.dynamic_import = DynamicImport()
# Define o pacote que deve ser carregado
self.dynamic_import.set_package("selos")
# Define a tabela que o pacote pertence
self.dynamic_import.set_table("see")
pass
# Efetua o acesso junto ao sistema por um determinado usuário
async def authenticate(
self,
request: Request,
cartorio_authenticate_schema: CartorioAuthenticateSchema,
):
# Importação de service de Authenticate
authenticate_service = self.dynamic_import.service(
"sessions_service", "SessionsService"
)
# Instânciamento da service
self.authenticate_service = authenticate_service()
# Retorna o usuário logado
return {
"message": "Usuário localizado com sucesso",
"data": {
"token": await self.authenticate_service.execute(
request, cartorio_authenticate_schema
)
},
}

View file

@ -0,0 +1,34 @@
# Importação de bibliotecas
from fastapi import APIRouter, Depends, status, Request
from actions.data.get_url_params import get_url_params
from actions.jwt.get_current_user import get_current_user
from packages.v1.selos.controllers.see_controller import (
SeeController,
)
from packages.v1.selos.schemas.see_schema import (
CartorioAuthenticateSchema,
)
# Inicializa o roteador para as rotas de usuário
router = APIRouter()
# Instânciamento do controller desejado
see_controller = SeeController()
# Autenticação de usuário
@router.post(
"/sessions",
status_code=status.HTTP_200_OK,
summary="Cria o token de acesso do usuário",
response_description="Retorna o token de acesso do usuário junto ao SEE",
)
async def authenticate(
request: Request, cartorio_authenticate_schema: CartorioAuthenticateSchema
):
# Efetua a autenticação de um usuário junto ao sistema
response = await see_controller.authenticate(request, cartorio_authenticate_schema)
# Retorna os dados localizados
return response

View file

@ -0,0 +1,45 @@
import httpx
from fastapi import HTTPException, status
from abstracts.repository import BaseRepository
from packages.v1.selos.schemas.see_schema import CartorioAuthenticateSchema
class SessionsRepository(BaseRepository):
def __init__(self):
self.url_externa = "https://portal-hextrajudicial.tjgo.jus.br/api/v1/sessions"
async def execute(self, cartorio_authenticate_schema: CartorioAuthenticateSchema):
"""
Consome o endpoint de autenticação do TJGO.
"""
# Converte o schema Pydantic para um dicionário (JSON)
payload = {
"email": cartorio_authenticate_schema.email,
"password": cartorio_authenticate_schema.password,
"hash_cartorio": cartorio_authenticate_schema.hash_cartorio,
}
try:
# Utiliza o cliente HTTP assíncrono para não bloquear a API SaaS
async with httpx.AsyncClient() as client:
response = await client.post(
self.url_externa, json=payload, timeout=10.0 # Timeout de segurança
)
# Verifica se a requisição foi bem-sucedida (status 200)
if response.status_code == 200 or response.status_code == 201:
return response.json()
# Caso a API externa retorne erro de credenciais ou outro
raise HTTPException(
status_code=response.status_code,
detail=f"Erro na API externa: {response.text}",
)
except httpx.RequestError as exc:
# Erro de conexão (ex: servidor fora do ar)
raise HTTPException(
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
detail=f"Não foi possível conectar ao portal TJGO: {exc}",
)

View file

@ -0,0 +1,45 @@
from pydantic import BaseModel, field_validator, EmailStr
from fastapi import HTTPException, status
# Funções para sanitização de entradas (evitar XSS, SQLi etc.)
from actions.validations.text import Text
class CartorioAuthenticateSchema(BaseModel):
# Campos utilizados
email: EmailStr # Utiliza EmailStr para validação nativa de formato
password: str
hash_cartorio: str
# Validação e sanitização do email
@field_validator("email", mode="before")
def validar_e_sanitizar_email(cls, v):
if not v:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, detail="Informe o e-mail"
)
# Sanitiza a entrada (convertendo para string caso venha outro tipo no 'before')
return Text.sanitize_input(str(v)).lower().strip()
# Validação e sanitização da senha
@field_validator("password")
def validar_e_sanitizar_password(cls, v):
if not v:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, detail="Informe a senha"
)
return Text.sanitize_input(v)
# Validação e sanitização do hash_cartorio
@field_validator("hash_cartorio")
def validar_e_sanitizar_hash(cls, v):
if not v:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Informe o hash do cartório",
)
return Text.sanitize_input(v)
class Config:
from_attributes = True

View file

@ -0,0 +1,22 @@
from fastapi import HTTPException, status, Request
from packages.v1.selos.schemas.see_schema import CartorioAuthenticateSchema
from packages.v1.selos.actions.see.sessions_action import (
SessionsAction,
)
class SessionsService:
async def execute(
self, request: Request, cartorio_authenticate_schema: CartorioAuthenticateSchema
):
# Instânciamento de ação
session_action = SessionsAction()
# Executa a ação em questão
data = await session_action.execute(cartorio_authenticate_schema)
# Retorno da informação
return data

View file

@ -1,6 +1,6 @@
annotated-types==0.7.0
anyio==4.10.0
bcrypt==3.1.7
bcrypt==5.0.0
certifi==2025.10.5
cffi==1.17.1
click==8.2.1
@ -14,7 +14,12 @@ firebird-driver==2.0.2
greenlet==3.2.4
gunicorn==23.0.0
h11==0.16.0
h2==4.3.0
hpack==4.1.0
html2text==2025.4.15
httpcore==1.0.9
httpx==0.28.1
hyperframe==6.1.0
idna==3.10
itsdangerous==2.2.0
lxml==6.0.2