Continuação das fases A e B do Projeto Agrix, que consiste numa API de controle de fazendas e plantações, utilizando Spring Boot, Spring Boot Web, Spring Boot Starter Actuator, Spring Data JPA e Spring Security e MySQL Connector-J.
Chegamos à Fase C do projeto Agrix! Agora que temos um projeto funcional, precisamos começar a nos preocupar com aspectos de segurança.
- Aplicar o conhecimento sobre Spring Security para adicionar autenticação ao projeto.
- Garantir que diferentes rotas atendam a regras específicas de autorização.
- Clone o repositório
- Use o comando:
git clone git@github.com:yurioneix/agrix-fase-c.git
- Entre na pasta do repositório que você acabou de clonar:
cd agrix-fase-c
- Instale as dependências
mvn install -DskipTests
- Suba os containers
docker-compose up -d
- POST
/farms
Cadastra uma nova fazenda
-
Exemplo de requisição:
{ "name": "Fazendinha", "size": 5 }
-
Exemplo de resposta com
status 200
:{ "id": 1, "name": "Fazendinha", "size": 5 }
- GET
/farms
Retorna todas as fazendas cadastradas
-
Exemplo de resposta com
status 200
:[ { "id": 1, "name": "Fazendinha", "size": 5.0 }, { "id": 2, "name": "Fazenda do Júlio", "size": 2.5 } ]
-
Caso não exista uma fazenda com esse
id
, a rota retorna o status HTTP 404 com a mensagemFazenda não encontrada!
no corpo da resposta. -
Caso a pessoa autenticada não possua role de
USER
,MANAGER
ouADMIN
, retorna status 403
- GET
/farms/{id}
Retorna uma fazenda pelo seu id
-
Exemplo de resposta com
status 200
para a rota/farms/3
(supondo que exista uma fazenda comid = 3
):{ "id": 3, "name": "My Cabbages!", "size": 3.49 }
- POST
/farms/{farmId}/crops
Associa uma plantação à uma fazenda, através do id da fazenda
-
Exemplo de requisição na rota
/farms/1/crops
comstatus 201
(supondo que exista uma fazenda comid = 1
):{ "name": "Couve-flor", "plantedArea": 5.43 }
-
Exemplo de resposta:
{ "id": 1, "name": "Couve-flor", "plantedArea": 5.43, "farmId": 1 }
-
Caso não exista uma fazenda com o
id
passado, a rota deve retornar ostatus HTTP 404
com a mensagemFazenda não encontrada!
no corpo da resposta.
- POST
/farms/{farmId}/crops
Associa uma plantação à uma fazenda, através do id da fazenda
-
Ajusta a rota da fase A para receber 2 novos campos com datas.
-
Exemplo de requisição na rota
/farms/1/crops
(supondo que exista uma fazenda comid = 1
):{ "name": "Couve-flor", "plantedArea": 5.43, "plantedDate": "2022-12-05", "harvestDate": "2023-06-08" }
-
Exemplo de resposta com
status 201
:{ "id": 1, "name": "Couve-flor", "plantedArea": 5.43, "plantedDate": "2022-12-05", "harvestDate": "2023-06-08", "farmId": 1 }
- GET
/farms/{farmId}/crops
Retorna uma plantação pelo id da fazenda em que ela está associada
Exemplo de resposta, com status 200
, para a rota /farms/1/crops
(supondo que exista uma fazenda com id = 1
):
[
{
"id": 1,
"name": "Couve-flor",
"plantedArea": 5.43,
"plantedDate": "2022-12-05",
"harvestDate": "2023-06-08",
"farmId": 1
},
{
"id": 2,
"name": "Alface",
"plantedArea": 21.3,
"plantedDate": "2022-02-15",
"harvestDate": "2023-02-20",
"farmId": 1
}
]
- GET
/crops
Retorna todas as plantações cadastradas
-
Exemplo de resposta da requisição:
[ { "id": 1, "name": "Couve-flor", "plantedArea": 5.43, "plantedDate": "2022-02-15", "harvestDate": "2023-02-20", "farmId": 1 }, { "id": 2, "name": "Alface", "plantedArea": 21.3, "plantedDate": "2022-02-15", "harvestDate": "2023-02-20", "farmId": 1 }, { "id": 3, "name": "Tomate", "plantedArea": 1.9, "plantedDate": "2023-05-22", "harvestDate": "2024-01-10", "farmId": 2 } ]
-
Caso a pessoa autenticada não possua a role
MANAGER
ouADMIN
, retorna status 403.
- GET
/crops/{id}
Retorna uma plantação pelo seu id
- Exemplo de resposta para a rota
/crops/3
(supondo que exista uma plantação comid = 3
:
{
"id": 3,
"name": "Tomate",
"plantedArea": 1.9,
"plantedDate": "2023-05-22",
"harvestDate": "2024-01-10",
"farmId": 2
}
- GET
/crops/search
Busca uma plantação pela data de colheita
-
Deve receber dois parâmetros por query string para busca:
start
: data de inícioend
: data de fim
-
Deve retornar uma lista com as plantações nas quais o campo
harvestDate
esteja entre as data de início e de fim. -
Exemplo de resposta para a rota
/crops/search?start=2023-01-07&end=2024-01-10
:[ { "id": 1, "name": "Couve-flor", "plantedArea": 5.43, "plantedDate": "2022-02-15", "harvestDate": "2023-02-20", "farmId": 1 }, { "id": 3, "name": "Tomate", "plantedArea": 1.9, "plantedDate": "2023-05-22", "harvestDate": "2024-01-10", "farmId": 2 } ]
- POST
/fertilizers
Cria um fertilizante
-
Exemplo de requisição:
{ "name": "Compostagem", "brand": "Feita em casa", "composition": "Restos de alimentos" }
-
Exemplo de resposta:
{ "id": 1, "name": "Compostagem", "brand": "Feita em casa", "composition": "Restos de alimentos" }
- GET
/fertilizers
Lista todos os fertilizantes cadastrados
-
Exemplo de resposta:
[ { "id": 1, "name": "Compostagem", "brand": "Feita em casa", "composition": "Restos de alimentos" }, { "id": 2, "name": "Húmus", "brand": "Feito pelas minhocas", "composition": "Muitos nutrientes" }, { "id": 3, "name": "Adubo", "brand": "Feito pelas vaquinhas", "composition": "Esterco" } ]
-
Caso a pessoa autenticada não possua role
ADMIN
, retorna status 403.
- GET
/fertilizers/{id}
Retorna uma fertilizante pelo seu id
-
Exemplo de resposta da rota
/fertilizers/3
(supondo que exista um fertilizante comid = 3
):{ "id": 3, "name": "Adubo", "brand": "Feito pelas vaquinhas", "composition": "Esterco" }
- POST
/crops/{cropId}/fertilizers/{fertilizerId}
Associa uma plantação com um fertilizante
-
Caso não exista uma plantação com o
id
recebido, a rota deve retornar o status HTTP 404 com a mensagemPlantação não encontrada!
no corpo da resposta. -
Caso não exista um fertilizante com o
id
recebido, a rota deve retornar o status HTTP 404 com a mensagemFertilizante não encontrado!
no corpo da resposta. -
Exemplo de resposta para a rota
/crops/1/fertilizers/2
(supondo que exista uma plantação comid = 1
e um fertilizante comid = 2
):
Fertilizante e plantação associados com sucesso!
- POST
/persons
Cadastra novas pessoas no banco
-
Exemplo de requisição na rota POST
/persons
:{ "username": "zerocool", "password": "senhasecreta", "role": "ADMIN" }
-
Exemplo de resposta:
{ "id": 1, "username": "zerocool", "role": "ADMIN" }
- POST
auth/login
Login de usuário cadastrado
-
Deve receber o
username
epassword
no corpo da requisição -
Deve validar os dados passados utilizando as pessoas que foram criadas pela rota
/persons
-
Caso os dados estejam incorretos, deve retornar status 403
-
Caso os dados estejam corretos, deve retornar um campo
token
contendo um JWT gerado -
Exemplo de requisição na rota POST
/auth/login
(suppondo que os dados estejam corretos):{ "username": "zerocool", "password": "senhasecreta" }
-
Exemplo de resposta:
{ "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhZ3JpeCIsInN1YiI6Im1ycm9ib3QiLCJleHAiOjE2ODk5ODY2NTN9.lyha4rMcMhFd_ij-farGCXuJy-1Tun1IpJd5Ot6z_5w" }
src/main/java/com.betrybe.agrix.controller
src/main/java/com.betrybe.agrix.model
src/main/java/com.betrybe.agrix.security
src/main/java/com.betrybe.agrix.service
src/main/java/com.betrybe.agrix.util
docker-compose.yaml
Dockerfile