front_ponto_eletronico/routes/auth.py
2025-03-17 15:00:51 -03:00

146 lines
5.7 KiB
Python

from flask import Blueprint, request, jsonify
from flask_jwt_extended import create_access_token, jwt_required, get_jwt_identity, decode_token, create_refresh_token
from flasgger.utils import swag_from
from datetime import datetime
from extensions import db
from models.user import User
from models.contact import Contact
from models.address import Address
from models.permission import Permission # Importa o modelo Permission
from models.user_service_role import UserServiceRole
from models.service_roles import ServiceRole
from models.service_role_permission import ServiceRolePermission
from models.license import License # Importa o modelo License
from collections import defaultdict
from sqlalchemy import or_
from utils import logged_user_id
auth_bp = Blueprint('auth', __name__, url_prefix='/auth')
@auth_bp.route('/login', methods=['POST'])
@swag_from('../docs/auth.yml')
def login():
data = request.get_json()
identifier = data.get('username') # Pode ser username ou e-mail
password = data.get('password')
# Busca usuário por username ou email
user = User.query.filter(
or_(
User.username == identifier,
User.email == identifier
)
).first()
if user and user.check_password(password):
# Tokens de acesso e refresh
access_token = create_access_token(identity=str(user.id))
refresh_token = create_refresh_token(identity=str(user.id))
# Recupera os contatos e endereços do usuário
contacts = Contact.query.filter_by(user_id=user.id).all()
addresses = Address.query.filter_by(user_id=user.id).all()
# Recupera as permissões associadas ao usuário
service_role_permissions = ServiceRolePermission.query.filter_by(user_id=user.id).all()
# Agrupar permissões por service_role_id e service_instance_id
permissions_by_role_and_instance = defaultdict(lambda: defaultdict(list))
# Garantir que estamos capturando também o nome do service_role e service_instance
for srp in service_role_permissions:
# Recuperando nome do service_instance e service_role diretamente da consulta
service_instance_name = srp.service_instance.name
service_role_name = srp.service_role.name
permission = {
'id': srp.permission.id,
'type': srp.permission_type, # Tipo de permissão (read, write, delete)
}
permissions_by_role_and_instance[srp.service_role.id][srp.service_instance.id].append({
'permission': permission,
'service_instance_name': service_instance_name,
'service_role_name': service_role_name,
})
# Criar a resposta agrupada por service_role e service_instance
grouped_permissions = []
for service_role_id, instances in permissions_by_role_and_instance.items():
for service_instance_id, perms in instances.items():
# Recuperar o nome do service_role e service_instance
service_instance_name = perms[0]['service_instance_name']
service_role_name = perms[0]['service_role_name']
grouped_permissions.append({
"service_role_id": service_role_id,
"service_role_name": service_role_name,
"service_instance_id": service_instance_id,
"service_instance_name": service_instance_name,
"permissions": [p['permission'] for p in perms] # As permissões agrupadas aqui
})
# Licenças associadas ao usuário
if user.parent_id:
licenses = License.query.filter_by(user_id=user.parent_id).all()
else:
licenses = License.query.filter_by(user_id=user.id).all()
# Monta o retorno com os dados do usuário, contatos, endereços, permissões e licenças
user_data = {
'id': user.id,
'username': user.username,
'parent_id': user.parent_id,
'email': user.email,
'licenses': [
{
'license_key': license.license_key,
'service_id': license.service.id,
'service_name': license.service.name, # Adicionando o nome do serviço
'start_date': license.start_date,
'end_date': license.end_date
}
for license in licenses
],
'permissions': grouped_permissions,
'contacts': [
{
'phone': contact.phone,
'contact_type': contact.contact_type,
'description': contact.description
}
for contact in contacts
],
'addresses': [
{
'street': address.street,
'city': address.city,
'state': address.state,
'zip_code': address.zip_code,
'country': address.country,
'type': address.address_type.name
}
for address in addresses
],
}
# Retorna os tokens junto com os dados do usuário
return jsonify({
'access_token': access_token,
'refresh_token': refresh_token,
'user': user_data
}), 200
return jsonify({'error': 'Credenciais inválidas'}), 401
@auth_bp.route('/refresh', methods=['POST'])
@logged_user_id
@swag_from('../docs/refresh_token.yml')
def refresh_token():
current_user = logged_user_id
new_access_token = create_access_token(identity=current_user)
return jsonify({'access_token': new_access_token}), 200