Skip to content

Commit 5d33393

Browse files
Merge pull request #13 from marshfellow42/main
Terminar os issues que eu tinha na Sprint dessa semana
2 parents e1fafbe + a763a2e commit 5d33393

2 files changed

Lines changed: 166 additions & 55 deletions

File tree

.env.example

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,6 @@ CLIENT_CERT_URL=https://www.googleapis.com/robot/v1/metadata/x509/your-service-a
1313

1414
# Firebase Realtime Database URL
1515
DATABASE_URL=https://your-project-id-default-rtdb.firebaseio.com/
16+
17+
# API key secret word
18+
SECRET_API_WORD = "your_secret_word"

api/main.py

Lines changed: 163 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,24 @@
1-
from fastapi import FastAPI, HTTPException, Request
1+
from fastapi import FastAPI, HTTPException, Request, Depends, Query
22
from fastapi.responses import RedirectResponse
3-
import firebase_admin
3+
44
from firebase_admin import credentials, db, auth
5+
import firebase_admin
6+
57
import phonenumbers
68
from phonenumbers import PhoneNumberFormat
7-
import uuid
9+
10+
from pydantic import BaseModel
11+
from typing import Optional
12+
813
from datetime import datetime
914
import os
10-
from dotenv import load_dotenv
1115
import random
1216
import string
17+
import uuid
18+
import hashlib
19+
import base64
20+
21+
from dotenv import load_dotenv
1322

1423
load_dotenv()
1524

@@ -61,10 +70,20 @@ def check_uid_exists(uid: str):
6170
print(f"⚠️ Error: {e}")
6271
return False
6372

64-
def generate_random_invite_url(length: int = 12) -> str:
73+
def generate_random_invite_key(length: int = 12) -> str:
6574
chars = string.ascii_letters + string.digits # A-Z, a-z, 0-9
6675
return ''.join(random.choices(chars, k=length))
6776

77+
word = os.getenv("SECRET_API_WORD")
78+
hash_bytes = hashlib.sha256(word.encode()).digest()
79+
API_KEY = base64.urlsafe_b64encode(hash_bytes).rstrip(b'=').decode()
80+
API_KEY_NAME = "api_key"
81+
82+
def get_api_key(api_key: str = Query(default=None, alias=API_KEY_NAME)):
83+
if api_key == API_KEY:
84+
return api_key
85+
raise HTTPException(status_code=403, detail="Chave API não autorizada")
86+
6887
STANDARD_RESPONSES = {
6988
400: {"description": "Bad Request"},
7089
401: {"description": "Unauthorized"},
@@ -84,7 +103,11 @@ def generate_random_invite_url(length: int = 12) -> str:
84103
},
85104
]
86105

87-
app = FastAPI(openapi_tags=tags_metadata)
106+
app = FastAPI(title='Cosmos API', openapi_tags=tags_metadata)
107+
108+
class AgendaPatch(BaseModel):
109+
nome_agenda: Optional[str] = None
110+
uid_do_responsável: Optional[str] = None
88111

89112
@app.get("/")
90113
def read_root():
@@ -94,20 +117,20 @@ def read_root():
94117
def testar_o_firebase():
95118
try:
96119
if ref.get():
97-
message = "Conectado com successo ao Firebase"
98-
return {"message": message}
120+
return {"message": "Conectado com successo ao Firebase"}
99121
except Exception as e:
100122
raise HTTPException(status_code=500, detail=f"Falha ao se conectar com o Firebase: {str(e)}")
101123

102-
from fastapi import APIRouter
103-
104-
@app.get("/invite/{uid_da_agenda}", responses=STANDARD_RESPONSES)
105-
def mandar_um_convite_para_entrar_na_turma_tipo_o_whatsapp(uid_da_agenda: str, request: Request):
106-
agenda_node = agenda_ref.child(uid_da_agenda)
124+
@app.get("/invite/{chave_de_convite_da_agenda}", responses=STANDARD_RESPONSES)
125+
def mandar_um_convite_para_entrar_na_turma_tipo_o_whatsapp(chave_de_convite_da_agenda: str, request: Request):
126+
agenda_node = agenda_ref.order_by_child('chave_de_convite').equal_to(chave_de_convite_da_agenda)
107127
agenda_data = agenda_node.get()
108128

109129
if not agenda_data:
110-
raise HTTPException(status_code=404, detail=f"A agenda com o UID {uid_da_agenda} não existe")
130+
raise HTTPException(status_code=404, detail=f"Essa agenda não existe")
131+
132+
for key, val in agenda_data.items():
133+
return (f"UID da Agenda: {key}, Data: {val}")
111134

112135
# Detecta o dispositivo
113136
user_agent = request.headers.get("user-agent", "").lower()
@@ -134,7 +157,7 @@ def mandar_um_convite_para_entrar_na_turma_tipo_o_whatsapp(uid_da_agenda: str, r
134157
return RedirectResponse(play_store_url)
135158

136159
@app.get("/getAllUsers/", tags=["Usuários"], responses=STANDARD_RESPONSES)
137-
def conseguir_todos_os_usuarios_logado_com_o_email_normal_no_firebase():
160+
def conseguir_todos_os_usuarios_logado_com_o_email_normal_no_firebase(api_key: str = Depends(get_api_key)):
138161
users = []
139162
page = auth.list_users()
140163
while page:
@@ -146,60 +169,57 @@ def conseguir_todos_os_usuarios_logado_com_o_email_normal_no_firebase():
146169
"passwordSalt": user.password_salt,
147170
"display_name": user.display_name,
148171
"phone_number": user.phone_number or "",
149-
"invite_url": user.invite_url,
150-
"photo_url": user.photo_url or "",
172+
"photo_url": user.photo_url or ""
151173
})
152174
page = page.get_next_page()
153175
return users
154176

155177
@app.post("/add/user/", tags=["Usuários"], responses=STANDARD_RESPONSES)
156-
async def criar_um_usuario_com_email_e_senha(email: str, password: str, display_name: str, phone_number: str | None = None, photo_url: str | None = None):
178+
async def criar_um_usuario_com_email_e_senha(email: str, password: str, display_name: str, phone_number: str | None = None, photo_url: str | None = None, api_key: str = Depends(get_api_key)):
157179
user = auth.create_user(
158180
email=email,
159181
email_verified=False,
160182
phone_number=to_e164_br(phone_number),
161183
password=password,
162184
display_name=display_name,
163185
photo_url=photo_url,
164-
invite_url=generate_random_invite_url(),
165186
disabled=False)
166-
message = 'Criado um usuário com sucesso. UID: {0}'.format(user.uid)
167-
return {"message": message}
187+
188+
return {"message": 'Criado um usuário com sucesso. UID: {0}'.format(user.uid)}
168189

169190
@app.delete("/delete/user", tags=["Usuários"], responses=STANDARD_RESPONSES)
170-
async def deletar_um_usuario_com_o_uid(uid: str):
191+
async def deletar_um_usuario_com_o_uid(uid: str, api_key: str = Depends(get_api_key)):
171192
if check_uid_exists(uid):
172193
auth.delete_user(uid)
173-
message = f'O usuário com o UID {uid} foi deletado com sucesso.'
174-
return {"message": message}
194+
return {"message": f'O usuário com o UID {uid} foi deletado com sucesso.'}
175195
else:
176196
raise HTTPException(status_code=400, detail="Este usuário não existe no banco de dados")
177197

178198
@app.get("/getAllAgendas", tags=["Agenda"], responses=STANDARD_RESPONSES)
179-
async def mostrar_todas_as_agendas_criadas():
199+
async def mostrar_todas_as_agendas_criadas(api_key: str = Depends(get_api_key)):
180200
if agenda_ref.get() is None:
181-
message = f'Nenhuma agenda foi criada'
182-
return {"message": message}
201+
return {"message": 'Nenhuma agenda foi criada'}
183202
else:
184203
return agenda_ref.get()
185204

186205
@app.post("/add/agenda/", tags=["Agenda"], responses=STANDARD_RESPONSES)
187-
async def criar_uma_agenda(nome_agenda: str, uid_do_responsavel: str):
206+
async def criar_uma_agenda(nome_agenda: str, uid_do_responsavel: str, api_key: str = Depends(get_api_key)):
188207
if check_uid_exists(uid_do_responsavel):
189208
uid = str(uuid.uuid4())
190209
agenda_ref.update({
191210
uid: {
192211
'nome_agenda': nome_agenda,
193-
'uid_do_responsável': uid_do_responsavel
212+
'uid_do_responsável': uid_do_responsavel,
213+
'chave_de_convite': generate_random_invite_key()
194214
}
195215
})
196-
message = f'A agenda {nome_agenda} com o UID {uid} foi criada com sucesso'
197-
return {"message": message}
216+
217+
return {"message": f'A agenda {nome_agenda} com o UID {uid} foi criada com sucesso'}
198218
else:
199219
raise HTTPException(status_code=401, detail="Este usuário não existe no banco de dados")
200220

201221
@app.post("/add/agenda/membro", tags=["Agenda"], responses=STANDARD_RESPONSES)
202-
async def adicionar_um_membro_na_agenda_já_criada(uid_da_agenda: str, uid_do_membro: str):
222+
async def adicionar_um_membro_na_agenda_já_criada(uid_da_agenda: str, uid_do_membro: str, api_key: str = Depends(get_api_key)):
203223
agenda_node = agenda_ref.child(uid_da_agenda)
204224
agenda_data = agenda_node.get()
205225
if not agenda_data:
@@ -216,11 +236,11 @@ async def adicionar_um_membro_na_agenda_já_criada(uid_da_agenda: str, uid_do_me
216236
'nome_do_usuário': user.display_name
217237
}
218238
})
219-
message = f'O membro {user.display} com o UID {user.uid} foi adicionado com sucesso'
220-
return {"message": message}
239+
240+
return {"message": f'O membro {user.display} com o UID {user.uid} foi adicionado com sucesso'}
221241

222242
@app.post("/add/agenda/materia", tags=["Agenda"], responses=STANDARD_RESPONSES)
223-
async def criar_uma_materia_na_agenda_já_criada(uid_da_agenda: str, nome_da_matéria: str, nome_do_professor: str | None = None, horario_de_inicio_da_materia: str | None = None, horario_de_fim_da_materia: str | None = None):
243+
async def criar_uma_materia_na_agenda_já_criada(uid_da_agenda: str, nome_da_matéria: str, nome_do_professor: str | None = None, horario_de_inicio_da_materia: str | None = None, horario_de_fim_da_materia: str | None = None, api_key: str = Depends(get_api_key)):
224244
agenda_node = agenda_ref.child(uid_da_agenda)
225245
agenda_data = agenda_node.get()
226246
if not agenda_data:
@@ -236,11 +256,11 @@ async def criar_uma_materia_na_agenda_já_criada(uid_da_agenda: str, nome_da_mat
236256
"horário_de_fim": horario_de_fim_da_materia
237257
}
238258
})
239-
message = f'A matéria {nome_da_matéria} com o UID {uid} foi criada com sucesso'
240-
return {"message": message}
259+
260+
return {"message": f'A matéria {nome_da_matéria} com o UID {uid} foi criada com sucesso'}
241261

242262
@app.post("/add/agenda/tarefa", tags=["Agenda"], responses=STANDARD_RESPONSES)
243-
async def criar_uma_tarefa_na_agenda_já_criada(uid_da_agenda: str, nome_da_tarefa: str, timestamp: str):
263+
async def criar_uma_tarefa_na_agenda_já_criada(uid_da_agenda: str, nome_da_tarefa: str, timestamp: str, api_key: str = Depends(get_api_key)):
244264
agenda_node = agenda_ref.child(uid_da_agenda)
245265
agenda_data = agenda_node.get()
246266
if not agenda_data:
@@ -254,11 +274,11 @@ async def criar_uma_tarefa_na_agenda_já_criada(uid_da_agenda: str, nome_da_tare
254274
'timestamp': timestamp_formatado(timestamp)
255275
}
256276
})
257-
message = f'A tarefa com o UID {uid} foi criada com sucesso.'
258-
return {"message": message}
277+
278+
return {"message": f'A tarefa com o UID {uid} foi criada com sucesso.'}
259279

260280
@app.post("/add/agenda/evento", tags=["Agenda"], responses=STANDARD_RESPONSES)
261-
async def criar_um_evento_na_agenda_já_criada(uid_da_agenda: str, nome_do_evento: str, timestamp: str):
281+
async def criar_um_evento_na_agenda_já_criada(uid_da_agenda: str, nome_do_evento: str, timestamp: str, api_key: str = Depends(get_api_key)):
262282
agenda_node = agenda_ref.child(uid_da_agenda)
263283
agenda_data = agenda_node.get()
264284
if not agenda_data:
@@ -272,49 +292,137 @@ async def criar_um_evento_na_agenda_já_criada(uid_da_agenda: str, nome_do_event
272292
'timestamp': timestamp_formatado(timestamp)
273293
}
274294
})
275-
message = f'O evento com o UID {uid} foi criado com sucesso.'
276-
return {"message": message}
295+
296+
return {"message": f'O evento com o UID {uid} foi criado com sucesso.'}
277297

278298
@app.delete("/delete/agenda/", tags=["Agenda"], responses=STANDARD_RESPONSES)
279-
async def deletar_uma_agenda_com_o_uid(uid_da_agenda: str):
299+
async def deletar_uma_agenda_com_o_uid(uid_da_agenda: str, api_key: str = Depends(get_api_key)):
280300
agenda_node = agenda_ref.child(uid_da_agenda)
281301
agenda_data = agenda_node.get()
282302
if not agenda_data:
283303
raise HTTPException(status_code=404, detail=f"A agenda com o UID {uid_da_agenda} não existe")
284304

285305
agenda_node.delete()
286-
message = f'A agenda com o UID {uid_da_agenda} foi deletada com sucesso.'
287-
return {"message": message}
306+
307+
return {"message": f'A agenda com o UID {uid_da_agenda} foi deletada com sucesso.'}
288308

289309
@app.delete("/delete/agenda/materia", tags=["Agenda"], responses=STANDARD_RESPONSES)
290-
async def deletar_uma_materia_com_o_uid(uid_da_agenda: str, uid_da_materia: str):
310+
async def deletar_uma_materia_com_o_uid(uid_da_agenda: str, uid_da_materia: str, api_key: str = Depends(get_api_key)):
291311
matéria_node = agenda_ref.child(uid_da_agenda).child("matérias").child(uid_da_materia)
292312
matéria_data = matéria_node.get()
293313
if not matéria_data:
294314
raise HTTPException(status_code=404, detail=f"A matéria com o UID {uid_da_materia} na agenda {uid_da_agenda} não existe")
295315

296316
matéria_node.delete()
297-
message = f'A matéria com o UID {uid_da_materia} foi deletada com sucesso.'
298-
return {"message": message}
317+
318+
return {"message": f'A matéria com o UID {uid_da_materia} foi deletada com sucesso.'}
299319

300320
@app.delete("/delete/agenda/tarefa", tags=["Agenda"], responses=STANDARD_RESPONSES)
301-
async def deletar_uma_tarefa_com_o_uid(uid_da_agenda: str, uid_da_tarefa: str):
321+
async def deletar_uma_tarefa_com_o_uid(uid_da_agenda: str, uid_da_tarefa: str, api_key: str = Depends(get_api_key)):
302322
tarefa_node = agenda_ref.child(uid_da_agenda).child("tarefas").child(uid_da_tarefa)
303323
tarefa_data = tarefa_node.get()
304324
if not tarefa_data:
305325
raise HTTPException(status_code=404, detail=f"A tarefa com o UID {uid_da_tarefa} na agenda {uid_da_agenda} não existe")
306326

307327
tarefa_node.delete()
308-
message = f'A tarefa com o UID {uid_da_tarefa} foi deletada com sucesso.'
309-
return {"message": message}
328+
329+
return {"message": f'A tarefa com o UID {uid_da_tarefa} foi deletada com sucesso.'}
310330

311331
@app.delete("/delete/agenda/evento", tags=["Agenda"], responses=STANDARD_RESPONSES)
312-
async def deletar_um_evento_com_o_uid(uid_da_agenda: str, uid_do_evento: str):
332+
async def deletar_um_evento_com_o_uid(uid_da_agenda: str, uid_do_evento: str, api_key: str = Depends(get_api_key)):
313333
evento_node = agenda_ref.child(uid_da_agenda).child("eventos").child(uid_do_evento)
314334
evento_data = evento_node.get()
315335
if not evento_data:
316336
raise HTTPException(status_code=404, detail=f"O evento com o UID {uid_do_evento} na agenda {uid_da_agenda} não existe")
317337

318338
evento_node.delete()
319-
message = f'O evento com o UID {uid_do_evento} foi deletado com sucesso.'
320-
return {"message": message}
339+
340+
return {"message": f'O evento com o UID {uid_do_evento} foi deletado com sucesso.'}
341+
342+
@app.patch("/update/agenda", tags=["Agenda"], responses=STANDARD_RESPONSES)
343+
async def atualizar_os_dados_da_agenda(uid_da_agenda: str = Query(...), nome_agenda: str = Query(None), uid_do_responsável: str = Query(None), api_key: str = Depends(get_api_key)):
344+
agenda_node = agenda_ref.child(uid_da_agenda)
345+
agenda_data = agenda_node.get()
346+
if not agenda_data:
347+
raise HTTPException(status_code=404, detail=f"A agenda com o UID {uid_da_agenda} não existe")
348+
349+
update_data = {}
350+
if nome_agenda is not None:
351+
update_data["nome_agenda"] = nome_agenda
352+
if uid_do_responsável is not None:
353+
update_data["uid_do_responsável"] = uid_do_responsável
354+
355+
if not update_data:
356+
raise HTTPException(status_code=400, detail="Nenhum dado fornecido para atualização")
357+
358+
agenda_node.update(update_data)
359+
360+
return {"message": "Agenda atualizada com sucesso", "dados": update_data}
361+
362+
@app.patch("/update/agenda/materia", tags=["Agenda"], responses=STANDARD_RESPONSES)
363+
async def atualizar_os_dados_da_agenda(uid_da_agenda: str = Query(...), uid_da_materia: str = Query(...), nome_da_matéria: str = Query(None), nome_do_professor: str = Query(None), horario_de_inicio_da_materia: str = Query(None), horario_de_fim_da_materia: str = Query(None), api_key: str = Depends(get_api_key)):
364+
agenda_node = agenda_ref.child(uid_da_agenda).child("matérias").child(uid_da_materia)
365+
agenda_data = agenda_node.get()
366+
if not matéria_data:
367+
raise HTTPException(status_code=404, detail=f"A matéria com o UID {uid_da_materia} na agenda {uid_da_agenda} não existe")
368+
369+
update_data = {}
370+
if nome_da_matéria is not None:
371+
update_data["nome_matéria"] = nome_da_matéria
372+
if nome_do_professor is not None:
373+
update_data["professor"] = nome_do_professor
374+
if horario_de_inicio_da_materia is not None:
375+
update_data["horario_de_início"] = horario_de_inicio_da_materia
376+
if horario_de_fim_da_materia is not None:
377+
update_data["horario_de_fim"] = horario_de_fim_da_materia
378+
379+
if not update_data:
380+
raise HTTPException(status_code=400, detail="Nenhum dado fornecido para atualização")
381+
382+
agenda_node.update(update_data)
383+
384+
return {"message": "Agenda atualizada com sucesso", "dados": update_data}
385+
386+
@app.patch("/update/agenda/tarefa", tags=["Agenda"], responses=STANDARD_RESPONSES)
387+
async def atualizar_os_dados_da_agenda(uid_da_agenda: str = Query(...), uid_da_tarefa: str = Query(...), nome_da_tarefa: str = Query(None), timestamp: str = Query(None), api_key: str = Depends(get_api_key)):
388+
agenda_node = agenda_ref.child(uid_da_agenda).child("tarefas").child(uid_da_tarefa)
389+
agenda_data = agenda_node.get()
390+
if not matéria_data:
391+
raise HTTPException(status_code=404, detail=f"A tarefa com o UID {uid_da_tarefa} na agenda {uid_da_agenda} não existe")
392+
393+
timestamp_definido = timestamp_formatado(timestamp)
394+
395+
update_data = {}
396+
if nome_da_tarefa is not None:
397+
update_data["nome_da_tarefa"] = nome_da_tarefa
398+
if timestamp_definido is not None:
399+
update_data["timestamp"] = timestamp_definido
400+
401+
if not update_data:
402+
raise HTTPException(status_code=400, detail="Nenhum dado fornecido para atualização")
403+
404+
agenda_node.update(update_data)
405+
406+
return {"message": "Agenda atualizada com sucesso", "dados": update_data}
407+
408+
@app.patch("/update/agenda/evento", tags=["Agenda"], responses=STANDARD_RESPONSES)
409+
async def atualizar_os_dados_da_agenda(uid_da_agenda: str = Query(...), uid_do_evento: str = Query(...), nome_do_evento: str = Query(None), timestamp: str = Query(None), api_key: str = Depends(get_api_key)):
410+
agenda_node = agenda_ref.child(uid_da_agenda).child("eventos").child(uid_do_evento)
411+
agenda_data = agenda_node.get()
412+
if not matéria_data:
413+
raise HTTPException(status_code=404, detail=f"O evento com o UID {uid_do_evento} na agenda {uid_da_agenda} não existe")
414+
415+
timestamp_definido = timestamp_formatado(timestamp)
416+
417+
update_data = {}
418+
if nome_da_tarefa is not None:
419+
update_data["nome_do_evento"] = nome_do_evento
420+
if timestamp_definido is not None:
421+
update_data["timestamp"] = timestamp_definido
422+
423+
if not update_data:
424+
raise HTTPException(status_code=400, detail="Nenhum dado fornecido para atualização")
425+
426+
agenda_node.update(update_data)
427+
428+
return {"message": "Agenda atualizada com sucesso", "dados": update_data}

0 commit comments

Comments
 (0)