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