Implementação baseada em OAuth 2.0 e JWT.
O código está distribuído em vários repositórios:
Requisitos funcionais:
Requisitos não funcionais:
O acesso é padronizado para microprocessados (aplicações Web) e microcontrolados, baseado em REST API + JSON, uma vez que o sentido das mensagens é, basicamente, do cliente para o servidor.
As aplicações a serem desenvolvidas ao longo do projeto são:
Entre as aplicações em rede:
sequenceDiagram
actor Usuário
box Serviços em nuvem
participant Servidor Web
participant Google
end
Usuário ->>+ Servidor Web: solicita login
Servidor Web ->>+ Google: redireciona login
Google ->>+ Usuário: solitica permissão
Usuário ->>- Google: concede permissão
Google ->>- Servidor Web: gera código de autorização
Servidor Web ->>+ Google: troca código por token de acesso
Google ->>- Servidor Web: gera JWT
Servidor Web ->>- Usuário: retorna JWT
Entre as aplicações em rede:
sequenceDiagram
actor Usuário
box Serviços em nuvem
participant Servidor Web
participant Banco de Dados
end
Usuário ->>+ Servidor Web: envia POST /credit
Servidor Web ->>+ Banco de Dados: DQL SQL
Banco de Dados ->>- Servidor Web: resposta do DQL
Servidor Web -->+ Banco de Dados: DML SQL
Banco de Dados -->- Servidor Web: resposta do DML
Servidor Web ->>- Usuário: resposta do POST
Fluxo de escolha do servidor Web na resposta à requisição do usuário:
flowchart TD
A[Usuário envia POST /credit]
B
C
D[Retorna 401]
E
F[Retorna 400]
G
H[Retorna 402]
I[Retorna 403]
J[Consulta operações recentes no BD]
K
L[Retorna 429]
M[Insere operação de crédito no BD]
N[Retorna 201]
A --> B{JWT válido?}
B -->|Sim| C{Requisição bem formatada?}
B -->|Não| D
C --> |Sim| E{Valor solicitado é inteiro natural?}
C --> |Não| F
E --> |Sim| G{Valor acima do limite?}
E --> |Não| H
G --> |Sim| I
G --> |Não| J
J --> K{Existe crédito recente?}
K --> |Sim| L
K --> |Não| M
M --> N
sequenceDiagram
actor Usuário
box Serviços em nuvem
participant Servidor Web
participant Banco de Dados
end
Usuário ->>+ Servidor Web: envia POST /debit
Servidor Web ->>+ Banco de Dados: DQL SQL
Banco de Dados ->>- Servidor Web: resposta do DQL
Servidor Web -->+ Banco de Dados: DML SQL
Banco de Dados -->- Servidor Web: resposta do DML
Servidor Web ->>- Usuário: resposta do POST
Fluxo de escolha do servidor Web na resposta à requisição do usuário:
flowchart TD
A[Usuário envia POST /debit]
B
C
D[Retorna 401]
E
F[Retorna 400]
G
H[Retorna 403]
I
J[Retorna 403]
K
L[Retorna 402]
M[Retorna 403]
N
P[Retorna 201]
AA[Insere operação não concluída no banco]
AB[Localiza a máquina do produto]
AC[Notifica a máquina para inserir moeda]
VA
VB[Máquina ocupada]
VC[Retorna 403]
VD[Insere operação não concluída no banco]
VE[Localiza slot do produto na máquina]
VF[Localiza nome do comprador]
VG[Notifica a máquina para estado MFA]
A --> B{JWT válido?}
B --> |Sim| C{Requisição bem formatada?}
B --> |Não| D
C --> |Sim| E{Máquina existe?}
C --> |Não| F
E --> |Sim| G{Produto existe?}
E --> |Não| H
G --> |Sim| I{Usuário tem saldo?}
G --> |Não| J
I --> |Sim| K{Máquina ocupada?}
I --> |Não| L
K --> |Sim| M
K --> |Não| N{Tipo de máquina?}
N --> |Vending machine| VA{Tem em estoque?}
N --> |Arcade| AA
AA --> AB
AB --> AC
AC --> P
VA --> |Sim| VB
VA --> |Não| VC
VB --> VD
VD --> VE
VE --> VF
VF --> VG
VG --> P
sequenceDiagram
actor Usuário
box Serviços em nuvem
participant Servidor Web
participant Banco de Dados
end
Usuário ->>+ Servidor Web: envia POST /transfer
Servidor Web ->>+ Banco de Dados: DQL SQL
Banco de Dados ->>- Servidor Web: resposta do DQL
Servidor Web -->+ Banco de Dados: DML SQL
Banco de Dados -->- Servidor Web: resposta do DML
Servidor Web ->>- Usuário: resposta do POST
Fluxo de escolha do servidor Web na resposta à requisição do usuário:
flowchart TD
A[Usuário envia POST /transfer]
B
C
D[Retorna 401]
E[Consulta saldo do usuário no BD]
F
G[Consulta operações recentes no BD]
H[Retorna 403]
I
J[Retorna 429]
K[Insere operação de transferência no BD]
L[Retorna 201]
M[Retorna 400]
N[Retorna 402]
O[Retorna 429]
A --> B{JWT válido?}
B -->|Sim| C{Requisição bem formatada?}
B -->|Não| D
C --> |Sim| E
C --> |Não| M
E --> F{Usuário tem saldo suficiente?}
F --> |Sim| I{Valor de transferência válido?}
F --> |Não| N
I --> |Sim| G
I --> |Não| H
G --> J{Existe transferência recente?}
J --> |Sim| O
J --> |Não| K
K --> L
A máquina de vendas opera com máquina de estados:
stateDiagram-v2
[*] --> idle
idle --> mfa
mfa --> idle
mfa --> releasing
releasing --> idle
idle --> [*]
A REST API está definida em formato OpenAPI 3.0 no arquivo rest-api.json. As operações entre máquinas e banco central são via WebSocket, estendendo a REST API em machine.json (formato AsyncAPI 3.0).
Já o banco está assim modelado (copiado do original):
Para PostgreSQL, os comandos DDL e DML estão no arquivo ddl.sql e dml.sql, respectivamente.
Um exemplo de uso é o melhor cenário de compra de produto na máquina de vendas, onde o usuário faz a operação de débito e confirma com autenticação de dois fatores e, assim, a compra é concluída:
sequenceDiagram
actor Usuário
box Serviços em nuvem
participant Servidor Web
participant Banco de Dados
end
participant Vending Machine
Vending Machine ->>+ Servidor Web: GET /machine
Servidor Web -->> Vending Machine: 101 Switching Protocols
Vending Machine ->> Servidor Web: "stateUpdate": { "state": "idle", "operation": 0 }
Usuário ->>+ Servidor Web: POST /login
Servidor Web ->>- Usuário: 200 OK
Usuário ->>+ Servidor Web: POST /debit
Servidor Web ->>- Usuário: 200 OK
Servidor Web ->>+ Vending Machine: "stateMFA": { "username": "John", "code": 86, "operation": 1000 }
Vending Machine ->>- Servidor Web: "stateUpdate": { "state": "mfa", "operation": 1000 }
Usuário ->>+ Servidor Web: POST /mfa
Servidor Web ->>- Usuário: 200 OK
Servidor Web ->>+ Vending Machine: "stateReleasing": { "product": 1, "operation": 1000 }
Vending Machine ->> Servidor Web: "stateUpdate": { "state": "releasing", "operation": 1000 }
Servidor Web -->> Usuário: Release product
Vending Machine ->>- Servidor Web: "stateUpdate": { "state": "idle", "operation": 1000 }
Servidor Web ->>+ Banco de Dados: SQL DML: atualizar estoque e operação concluída
Banco de Dados ->>- Servidor Web: SQL DML: banco atualizado
Servidor Web ->>- Vending Machine: 200 OK
Um exemplo de uso é o melhor cenário de inserção de moeda no fliperama, onde o usuário faz a operação de débito e a máquina de fliperama atualiza o saldo:
sequenceDiagram
actor Usuário
box Serviços em nuvem
participant Servidor Web
participant Banco de Dados
end
participant Arcade
Arcade ->>+ Servidor Web: GET /machine
Servidor Web -->> Arcade: 101 Switching Protocols
Usuário ->>+ Servidor Web: POST /login
Servidor Web ->>- Usuário: 200 OK
Usuário ->>+ Servidor Web: POST /debit
Servidor Web ->>- Usuário: 200 OK
Servidor Web ->>+ Arcade: "coinInsert": { "arcade": "1", "coins": 1, "operation": 1000 }
Arcade ->>- Servidor Web: "coinInserted": { "arcade": "1", "operation": 1000 }
Servidor Web -->> Usuário: Adição de moedas no fliperama
Servidor Web ->>+ Banco de Dados: SQL DML: operação concluída
Banco de Dados ->>- Servidor Web: SQL DML: banco atualizado
Servidor Web ->>- Arcade: 200 OK