From 9a78bdce108c5c78433eaa8cc33c3d597da3eacc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Victor?= Date: Sat, 9 Dec 2023 23:17:32 -0300 Subject: [PATCH 1/6] Atualiza README --- README.md | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 52 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5353dd5..921a526 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,52 @@ -# 2023.2-UnB-TV-Users -Repositório de Backend +# UnB-TV Users + +
+logo UNBTV
+ +## Sobre + +O projeto visa o desenvolvimento de uma aplicação Web e Mobile para a UnB-TV, com o objetivo de centralizar e disponibilizar de forma unificada todo o conteúdo oferecido pela UnB-TV, incluindo vídeos e transmissões ao vivo, sendo desenvolvida no segundo semestre de 2023 pelas disciplinas de EPS e MDS da Universidade de Brasília. + +## Ambientes + +[Documentação](https://github.com/fga-eps-mds/2023.2-UnB-TV-DOC) +[Users](https://github.com/fga-eps-mds/2023.2-UnB-TV-Users) +[Admin](https://github.com/fga-eps-mds/2023.2-UnB-TV-Admin) +[Video](https://github.com/fga-eps-mds/2023.2-UnB-TV-VideoService) +[Gateway](https://github.com/fga-eps-mds/2023.2-UnB-TV-API-Gateway) +[Frontend](https://github.com/fga-eps-mds/2023.2-UnB-TV-Frontend) + +## Acessando o repositório localmente + +### Requisitos + +- docker e docker compose + +Primeiro passo é instalar o docker e docker compose, para isso siga os passos de instalação do [docker](https://docs.docker.com/engine/install/) e [docker compose](https://docs.docker.com/compose/install/). + +Execute o servidor local: + +``` +docker compose up +``` + +Acessar o localhost em: http://localhost:8000 + +## Equipe + +| Foto | Nome | Github | Email | Matrícula | +| :-----------------------------------------------------------------------------------------------------------------------------: | :-------------------------------: | :----------------: | :----------------------------: | :-------: | +| Davi Marinho da Silva Campos | Davi Marinho da Silva Campos | @DaviMarinho | davii_marinho@hotmail.com | 190026600 | +| Diego Carlito Rodrigues de Souza | Diego Carlito Rodrigues de Souza | @Diego-Carlito | <221007690@aluno.unb.br> | 221007690 | +| Eric Akio Lages Nishimura | Eric Akio Lages Nishimura | @eric-kingu | <190105895@aluno.unb.br> | 190105895 | +| Gabriela Tiago de Araujo | Gabriela Tiago de Araujo | @GabrielaTiago | <190028475@aluno.unb.br> | 190028475 | +| Gabrielle Ribeiro Gomes | Gabrielle Ribeiro Gomes | @Gabrielle-Ribeiro | gabrielleribeiro2010@gmail.com | 170011020 | +| Geraldo Victor Alves Barbosa | Geraldo Victor Alves Barbosa | @geraldovictor | geraldovictor@outlook.com | 170011119 | +| Jennifer Costa Cansanção | Jennifer Costa Cansanção | @cansancaojennifer | <221007733@aluno.unb.br> | 221007733 | +| Jennifer Costa Cansanção | João Victor de Oliveira Matos | @joao15victor08 | joao15victor08@gmail.com | 170013987 | +| Lucas da Cunha Andrade | Lucas da Cunha Andrade | @nYCSTs | lucascandrade14@hotmail.com | 180105256 | +| Marcos Antonio Teles de Castilhos | Marcos Antonio Teles de Castilhos | @Marcosatc147 | <221008300@aluno.unb.br> | 221008300 | +| Raissa Andrade Silveira | Raissa Andrade Silveira | @RaisSabeAndrade | <221035077@aluno.unb.br> | 221035077 | +| Ricardo de Castro Loureiro | Ricardo de Castro Loureiro | @castroricardo1 | ricardoloureiro75@gmail.com | 200043111 | +| Ana Carolina Rodrigues Leite | Sávio Cunha de Carvalho | @savioc2 | saviocunha61@gmail.com | 180130889 | +| Vitória Aquere Matos | Vitória Aquere Matos | @vitoriaaquere | <190096616@aluno.unb.br> | 190096616 | From 3a6f57de05d9ba5f29bd49c3faf2affd3445272b Mon Sep 17 00:00:00 2001 From: davimarinho Date: Sun, 10 Dec 2023 00:24:11 -0300 Subject: [PATCH 2/6] =?UTF-8?q?Adiciona=20corre=C3=A7=C3=B5es=20no=20sonar?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: davimarinho --- sonar-project.properties | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sonar-project.properties b/sonar-project.properties index fe0902d..49bca3f 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -1,6 +1,9 @@ sonar.projectKey=fga-eps-mds_2023.2-UnB-TV-Users sonar.organization=fga-eps-mds-1 +sonar.host.url=https://sonarcloud.io +sonar.language=py + sonar.sources=src sonar.tests=tests # sonar.test.inclusions=tests/*.py From 659efb0db734a3c4287a5103b69b2ebd0d1a1cd8 Mon Sep 17 00:00:00 2001 From: lcsAndrade Date: Sun, 10 Dec 2023 17:08:05 -0300 Subject: [PATCH 3/6] Corrige arquivo do sonar Co-authored-by: DaviMarinho --- sonar-project.properties | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/sonar-project.properties b/sonar-project.properties index fe0902d..9e26314 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -1,13 +1,14 @@ sonar.projectKey=fga-eps-mds_2023.2-UnB-TV-Users sonar.organization=fga-eps-mds-1 -sonar.sources=src -sonar.tests=tests -# sonar.test.inclusions=tests/*.py -sonar.exclusions=__pycache__, tests -# sonar.testExecutionReportPaths -sonar.sourceEncoding=UTF-8 +sonar.host.url=https://sonarcloud.io +sonar.language=py +sonar.sources=src +sonar.exclusions=tests sonar.python.version=3.11.5 sonar.python.xunit.reportPath=junit.xml -sonar.python.coverage.reportPaths=coverage.xml \ No newline at end of file +sonar.python.coverage.reportPaths=coverage.xml +sonar.coverage.exclusions=tests/*.py + +sonar.sourceEncoding=UTF-8 \ No newline at end of file From c72d83a6c7ca891e37ea07aabcc4de7d8a4533db Mon Sep 17 00:00:00 2001 From: RaisSabeAndrade Date: Sun, 10 Dec 2023 18:02:41 -0300 Subject: [PATCH 4/6] =?UTF-8?q?Coment=C3=A1rios=20para=20authController?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controller/authController.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/controller/authController.py b/src/controller/authController.py index 80519a4..16c59db 100644 --- a/src/controller/authController.py +++ b/src/controller/authController.py @@ -15,6 +15,7 @@ prefix="/auth" ) + # Retorna conexões disponíveis @auth.get("/vinculo", response_model=authSchema.Connections) def get_connection(): connections = [member.value for member in enumeration.UserConnection] @@ -64,6 +65,7 @@ async def login(data: authSchema.UserLogin, db: Session = Depends(get_db)): return JSONResponse(status_code=200, content={ "access_token": access_token, "refresh_token": refresh_token, "token_type": "bearer" }) + # Recebe os dados do usuário provenientes de uma autenticação social @auth.post("/login/social") async def login_social(user: authSchema.UserSocial, db: Session = Depends(get_db)): existing_user = userRepository.get_user_by_email(db, user.email) @@ -78,7 +80,8 @@ async def login_social(user: authSchema.UserSocial, db: Session = Depends(get_db refresh_token = security.create_refresh_token(data={ "id": existing_user.id }) return JSONResponse(status_code=200, content={ "access_token": access_token, "refresh_token": refresh_token, "token_type": "bearer", "is_new_user": False }) - + + # trata da renovação de tokens de acesso @auth.post("/refresh", response_model=authSchema.RefreshTokenResponse) def refresh_token(token: dict = Depends(security.verify_token)): access_token=security.create_access_token(token) @@ -96,6 +99,7 @@ async def send_new_code(data: authSchema.SendNewCode, db: Session = Depends(get_ res = await send_mail.send_verification_code(email=data.email, code=user.activation_code) return JSONResponse(status_code=201, content={ "status": "success" }) + # Recebe dados de validação de conta @auth.patch('/activate-account') async def validate_account(data: authSchema.AccountValidation, db: Session = Depends(get_db)): user = userRepository.get_user_by_email(db, data.email) From 7ff89b66679e53082b6e9181fbd2ec9db8c279ac Mon Sep 17 00:00:00 2001 From: RaisSabeAndrade Date: Sun, 10 Dec 2023 18:16:49 -0300 Subject: [PATCH 5/6] =?UTF-8?q?Coment=C3=A1rios=20de=20authController?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controller/authController.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/controller/authController.py b/src/controller/authController.py index 16c59db..fa5073a 100644 --- a/src/controller/authController.py +++ b/src/controller/authController.py @@ -47,6 +47,7 @@ async def register(data: authSchema.UserCreate, db: Session = Depends(get_db)): return JSONResponse(status_code=201, content={ "status": "success" }) + # Recebe os dados de login @auth.post("/login", response_model=authSchema.Token) async def login(data: authSchema.UserLogin, db: Session = Depends(get_db)): user = userRepository.get_user_by_email(db, data.email) @@ -144,6 +145,7 @@ async def verify_reset_code(data: authSchema.ResetPasswordVerify, db: Session = return JSONResponse(status_code=200, content={ "status": "success" }) + # Atualizar senha de um usuário após uma solicitação de redefinição @auth.patch('/reset-password/change', response_model=userSchema.User) async def update_user_password(data: authSchema.ResetPasswordUpdate, db: Session = Depends(get_db)): user = userRepository.get_user_by_email(db, data.email) From 8a66a9af8d9b0053b0323ab33a037e25ae2adc43 Mon Sep 17 00:00:00 2001 From: lcsAndrade Date: Sun, 10 Dec 2023 22:05:01 -0300 Subject: [PATCH 6/6] Adiciona comentarios --- src/controller/authController.py | 6 +++++- src/controller/userController.py | 3 +++ src/repository/userRepository.py | 19 +++++++++++++++++++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/controller/authController.py b/src/controller/authController.py index fa5073a..88ba68a 100644 --- a/src/controller/authController.py +++ b/src/controller/authController.py @@ -152,15 +152,19 @@ async def update_user_password(data: authSchema.ResetPasswordUpdate, db: Session if not user: raise HTTPException(status_code=404, detail=errorMessages.USER_NOT_FOUND) + # Valida a senha informada if data.password and not security.validate_password(data.password): raise HTTPException(status_code=400, detail=errorMessages.INVALID_PASSWORD) + # Verifica se o usuario possui um reset code. Se não possuir, a solicitação é invalida e deve ser bloqueada if not user.password_reset_code: raise HTTPException(status_code=401, detail=errorMessages.INVALID_REQUEST) - + + # Verifica se o código corresponde if data.code != user.password_reset_code: raise HTTPException(status_code=400, detail=errorMessages.INVALID_RESET_PASSWORD_CODE) + # Faz procedimento de hash da senha e atualiza usuario hashed_password = security.get_password_hash(data.password) updated_user = userRepository.update_password(db, user, hashed_password) diff --git a/src/controller/userController.py b/src/controller/userController.py index 21756b9..da27673 100644 --- a/src/controller/userController.py +++ b/src/controller/userController.py @@ -71,6 +71,8 @@ async def delete_user(user_id: int, db: Session = Depends(get_db), token: dict = @user.patch("/role/{user_id}", response_model=userSchema.User) def update_role(user_id: int, db: Session = Depends(get_db), token: dict = Depends(security.verify_token)): + # Obtem email do usuario a partir de token. + # Verifica se o usuário é ADMIN user = userRepository.get_user_by_email(db, email=token['email']) if user.role != enumeration.UserRole.ADMIN.value: raise HTTPException(status_code=401, detail=errorMessages.NO_PERMISSION) @@ -81,6 +83,7 @@ def update_role(user_id: int, db: Session = Depends(get_db), token: dict = Depen if not user: raise HTTPException(status_code=404, detail=errorMessages.USER_NOT_FOUND) + # Obtem o valor da outra role e atribui a outra role para o usuario. Caso ele seja um USER => ADMIN, caso seja ADMIN => USER new_role = enumeration.UserRole.ADMIN.value if user.role == enumeration.UserRole.USER.value else enumeration.UserRole.USER.value user = userRepository.update_user_role(db, db_user=user, role=new_role) diff --git a/src/repository/userRepository.py b/src/repository/userRepository.py index b6313d9..7422d77 100644 --- a/src/repository/userRepository.py +++ b/src/repository/userRepository.py @@ -7,12 +7,25 @@ from domain import userSchema from model import userModel +# Obtem usuario a partir do seu ID def get_user(db: Session, user_id: int): return db.query(userModel.User).filter(userModel.User.id == user_id).first() +# Obtem usuario a partir do Email def get_user_by_email(db: Session, email: str): return db.query(userModel.User).filter(userModel.User.email == email).first() +''' +Obtem lista de usuarios. Possui filtragem: +Filtros: +name: filtrar por nome do usuario +email: filtrar por email do usuario +name_or_email: filtragem que aceita tanto nome quanto email (OR) +connection: filtragem pelo vinculo do usuario + +Também aceita offset e limit. Para offset pula a quantidade informada, +para o limit, controla a quantidade de usuarios retornada +''' def get_users(db: Session, users_filter: userSchema.UserListFilter): query = db.query(userModel.User) @@ -26,15 +39,20 @@ def get_users(db: Session, users_filter: userSchema.UserListFilter): if (users_filter.connection): query = query.filter(userModel.User.connection == users_filter.connection) + # Realiza o count para retornar para o front para realizar paginação total_count = query.count() + # Ordena a lista de usuarios por ordem alfabetica pelo nome query = query.order_by(userModel.User.name.asc()) + # Realiza a delimitação por offset if (users_filter.offset): query = query.offset(users_filter.offset) + # Realiza a limitação por quantidade retornada if (users_filter.limit): query = query.limit(users_filter.limit) + # Retorna todos os usuarios filtrados, dentro de eventuais limitações (offset ou limit) e o total (geral) return { "users": query.all(), "total": total_count } def create_user(db: Session, name, connection, email, password, activation_code): @@ -44,6 +62,7 @@ def create_user(db: Session, name, connection, email, password, activation_code) db.refresh(db_user) return db_user +# Cria um usuario por login social. Essa criação é especial pois o usuario criado por rede social não possui SENHA def create_user_social(db: Session, name, email): db_user = userModel.User( name=name,