Reorganização
This commit is contained in:
parent
8aff1b9c4e
commit
fd7525548b
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"python.analysis.extraPaths": [
|
"python.analysis.extraPaths": [
|
||||||
"./app"
|
"./app"
|
||||||
]
|
],
|
||||||
|
"python.analysis.autoImportCompletions": true
|
||||||
}
|
}
|
||||||
Binary file not shown.
@ -1,36 +1,28 @@
|
|||||||
from flask import Flask
|
from flask import Flask
|
||||||
from app.database import db
|
from app.database import db
|
||||||
from app.models.user import User
|
|
||||||
from app.routes.user_routes import user_bp
|
|
||||||
from werkzeug.security import generate_password_hash
|
from werkzeug.security import generate_password_hash
|
||||||
|
|
||||||
def create_default_user():
|
# Importação dos modelos para garantir o mapeamento completo
|
||||||
# Verifica se o banco de dados está vazio
|
from app.models import Usuario, Organizacao
|
||||||
user = User.query.first()
|
|
||||||
|
|
||||||
if not user:
|
# Importação dos blueprints
|
||||||
# Cria um usuário padrão com senha "senha123"
|
from app.routes.usuario import usuarios_bp
|
||||||
default_user = User(
|
from app.routes.organizacao import organizacoes_bp
|
||||||
name="admin",
|
from app.routes.documentos import documentos_bp
|
||||||
email="admin@example.com",
|
|
||||||
password=generate_password_hash("senha123", method="pbkdf2:sha256")
|
|
||||||
)
|
|
||||||
|
|
||||||
# Adiciona o usuário no banco de dados
|
|
||||||
db.session.add(default_user)
|
|
||||||
db.session.commit()
|
|
||||||
|
|
||||||
print("Usuário padrão criado com sucesso!")
|
|
||||||
|
|
||||||
|
|
||||||
def create_app():
|
def create_app():
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
app.config.from_object("config")
|
app.config.from_object("config")
|
||||||
|
|
||||||
|
# Inicializa a extensão SQLAlchemy
|
||||||
db.init_app(app)
|
db.init_app(app)
|
||||||
|
|
||||||
|
# Registra os blueprints
|
||||||
# Registrar Blueprints
|
app.register_blueprint(usuarios_bp)
|
||||||
app.register_blueprint(user_bp, url_prefix="/users")
|
app.register_blueprint(organizacoes_bp)
|
||||||
|
app.register_blueprint(documentos_bp)
|
||||||
|
|
||||||
return app
|
return app
|
||||||
|
|||||||
31
app/auth.py
31
app/auth.py
@ -1,31 +0,0 @@
|
|||||||
from functools import wraps
|
|
||||||
from flask import request, jsonify
|
|
||||||
import jwt
|
|
||||||
|
|
||||||
from app.models.user import User # ou Organization
|
|
||||||
|
|
||||||
SECRET_KEY = "sua_chave_secreta"
|
|
||||||
|
|
||||||
def generate_token(user):
|
|
||||||
token = jwt.encode({"id": user.id}, SECRET_KEY, algorithm="HS256")
|
|
||||||
return token
|
|
||||||
|
|
||||||
def token_required(f):
|
|
||||||
@wraps(f)
|
|
||||||
def decorated(*args, **kwargs):
|
|
||||||
token = None
|
|
||||||
|
|
||||||
if 'Authorization' in request.headers:
|
|
||||||
token = request.headers['Authorization'].split(" ")[1] # Bearer <token>
|
|
||||||
|
|
||||||
if not token:
|
|
||||||
return jsonify({"message": "Token ausente!"}), 401
|
|
||||||
|
|
||||||
try:
|
|
||||||
data = jwt.decode(token, SECRET_KEY, algorithms=["HS256"])
|
|
||||||
current_user = User.query.get(data["id"])
|
|
||||||
except:
|
|
||||||
return jsonify({"message": "Token inválido!"}), 401
|
|
||||||
|
|
||||||
return f(current_user, *args, **kwargs)
|
|
||||||
return decorated
|
|
||||||
@ -1,13 +1,15 @@
|
|||||||
|
# documento.py
|
||||||
from app.database import db
|
from app.database import db
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
class Documento(db.Model):
|
|
||||||
|
class Documento(db.Model): #
|
||||||
__tablename__ = 'documentos'
|
__tablename__ = 'documentos'
|
||||||
|
|
||||||
id = db.Column(db.UUID(as_uuid=True), primary_key=True, default=uuid.uuid4, unique=True, nullable=False)
|
id = db.Column(db.UUID(as_uuid=True), primary_key=True, default=uuid.uuid4, unique=True, nullable=False)
|
||||||
nome_arquivo = db.Column(db.String, nullable=False)
|
nome_arquivo = db.Column(db.String, nullable=False)
|
||||||
caminho_arquivo = db.Column(db.String, nullable=False)
|
caminho_arquivo = db.Column(db.String, nullable=False)
|
||||||
usuario_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
|
usuario_id = db.Column(db.Integer, db.ForeignKey('usuario.id'), nullable=False)
|
||||||
criado_em = db.Column(db.DateTime(timezone=True), server_default=db.func.now(), nullable=False)
|
criado_em = db.Column(db.DateTime(timezone=True), server_default=db.func.now(), nullable=False)
|
||||||
|
|
||||||
usuario = db.relationship('User', back_populates='documentos')
|
usuario = db.relationship('Usuario', back_populates='documentos')
|
||||||
21
app/models/Usuario.py
Normal file
21
app/models/Usuario.py
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# usuario.py
|
||||||
|
from app.database import db
|
||||||
|
|
||||||
|
|
||||||
|
class Usuario(db.Model):
|
||||||
|
__tablename__ = 'usuario'
|
||||||
|
|
||||||
|
id = db.Column(db.Integer, primary_key=True,
|
||||||
|
autoincrement=True, unique=True)
|
||||||
|
nome = db.Column(db.String, nullable=False)
|
||||||
|
email = db.Column(db.String, nullable=False, unique=True)
|
||||||
|
senha_hash = db.Column(db.String, nullable=False)
|
||||||
|
organizacao_id = db.Column(db.Integer, db.ForeignKey(
|
||||||
|
'organizacao.id'), nullable=False)
|
||||||
|
criado_em = db.Column(db.DateTime(timezone=True),
|
||||||
|
server_default=db.func.now(), nullable=False)
|
||||||
|
atualizado_em = db.Column(db.DateTime(
|
||||||
|
timezone=True), onupdate=db.func.now())
|
||||||
|
|
||||||
|
organizacao = db.relationship('Organizacao', back_populates='usuarios')
|
||||||
|
documentos = db.relationship('Documento', back_populates='usuario')
|
||||||
@ -1,10 +1,13 @@
|
|||||||
from app.database import db
|
from app.database import db
|
||||||
|
|
||||||
|
|
||||||
class Organizacao(db.Model):
|
class Organizacao(db.Model):
|
||||||
__tablename__ = 'organizacao'
|
__tablename__ = 'organizacao'
|
||||||
|
|
||||||
id = db.Column(db.Integer, primary_key=True, autoincrement=True, unique=True)
|
id = db.Column(db.Integer, primary_key=True,
|
||||||
|
autoincrement=True, unique=True)
|
||||||
nome = db.Column(db.String, nullable=False, unique=True)
|
nome = db.Column(db.String, nullable=False, unique=True)
|
||||||
criado_em = db.Column(db.DateTime(timezone=True), server_default=db.func.now(), nullable=False)
|
criado_em = db.Column(db.DateTime(timezone=True),
|
||||||
|
server_default=db.func.now(), nullable=False)
|
||||||
|
|
||||||
usuarios = db.relationship('User', back_populates='organizacao')
|
usuarios = db.relationship('Usuario', back_populates='organizacao')
|
||||||
|
|||||||
@ -1,15 +0,0 @@
|
|||||||
from app.database import db
|
|
||||||
|
|
||||||
class User(db.Model):
|
|
||||||
__tablename__ = 'users'
|
|
||||||
|
|
||||||
id = db.Column(db.Integer, primary_key=True, autoincrement=True, unique=True)
|
|
||||||
nome = db.Column(db.String, nullable=False)
|
|
||||||
email = db.Column(db.String, nullable=False, unique=True)
|
|
||||||
senha_hash = db.Column(db.String, nullable=False)
|
|
||||||
organizacao_id = db.Column(db.Integer, db.ForeignKey('organizacao.id'), nullable=False)
|
|
||||||
criado_em = db.Column(db.DateTime(timezone=True), server_default=db.func.now(), nullable=False)
|
|
||||||
atualizado_em = db.Column(db.DateTime(timezone=True), onupdate=db.func.now())
|
|
||||||
|
|
||||||
organizacao = db.relationship('Organizacao', back_populates='usuarios')
|
|
||||||
documentos = db.relationship('Documento', back_populates='usuario')
|
|
||||||
44
app/routes/documentos.py
Normal file
44
app/routes/documentos.py
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
from flask import Blueprint, request, jsonify
|
||||||
|
from app.database import db
|
||||||
|
from app.models import Documento
|
||||||
|
|
||||||
|
|
||||||
|
documentos_bp = Blueprint('documentos', __name__, url_prefix='/documentos')
|
||||||
|
|
||||||
|
@documentos_bp.route('/', methods=['GET'])
|
||||||
|
def get_documentos():
|
||||||
|
documentos = Documento.query.all()
|
||||||
|
documentos_data = [
|
||||||
|
{
|
||||||
|
'id': str(doc.id),
|
||||||
|
'nome_arquivo': doc.nome_arquivo,
|
||||||
|
'caminho_arquivo': doc.caminho_arquivo,
|
||||||
|
'usuario_id': doc.usuario_id,
|
||||||
|
'criado_em': doc.criado_em
|
||||||
|
}
|
||||||
|
for doc in documentos
|
||||||
|
]
|
||||||
|
return jsonify(documentos_data), 200
|
||||||
|
|
||||||
|
@documentos_bp.route('/', methods=['POST'])
|
||||||
|
def create_documento():
|
||||||
|
data = request.get_json()
|
||||||
|
if not all(k in data for k in ('nome_arquivo', 'caminho_arquivo', 'usuario_id')):
|
||||||
|
return jsonify({'error': 'Campos obrigatórios ausentes'}), 400
|
||||||
|
|
||||||
|
try:
|
||||||
|
novo_documento = Documento(
|
||||||
|
nome_arquivo=data['nome_arquivo'],
|
||||||
|
caminho_arquivo=data['caminho_arquivo'],
|
||||||
|
usuario_id=data['usuario_id']
|
||||||
|
)
|
||||||
|
db.session.add(novo_documento)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
return jsonify({
|
||||||
|
'message': 'Documento criado com sucesso',
|
||||||
|
'id': str(novo_documento.id)
|
||||||
|
}), 201
|
||||||
|
except Exception as e:
|
||||||
|
db.session.rollback()
|
||||||
|
return jsonify({'error': str(e)}), 500
|
||||||
@ -1,63 +0,0 @@
|
|||||||
from flask import Blueprint, jsonify, request
|
|
||||||
from app.auth import token_required
|
|
||||||
from app.models.documentos import document
|
|
||||||
from app.database import db
|
|
||||||
|
|
||||||
document_bp = Blueprint("documents", __name__)
|
|
||||||
|
|
||||||
# Listar todos os documentos
|
|
||||||
@document_bp.route("/", methods=["GET"])
|
|
||||||
@token_required
|
|
||||||
def get_documents(self):
|
|
||||||
documents = document.query.all()
|
|
||||||
return jsonify([
|
|
||||||
{"id": d.id, "title": d.title, "content": d.content, "owner_id": d.user_id}
|
|
||||||
for d in documents
|
|
||||||
])
|
|
||||||
|
|
||||||
# Criar um novo documento
|
|
||||||
@document_bp.route("/", methods=["POST"])
|
|
||||||
@token_required
|
|
||||||
def create_document(self):
|
|
||||||
data = request.get_json()
|
|
||||||
title = data.get("title")
|
|
||||||
content = data.get("content")
|
|
||||||
|
|
||||||
new_doc = document(title=title, content=content, user_id=self.id) # self.id vem do token
|
|
||||||
|
|
||||||
db.session.add(new_doc)
|
|
||||||
db.session.commit()
|
|
||||||
|
|
||||||
return jsonify({"message": "Documento criado com sucesso!", "document_id": new_doc.id}), 201
|
|
||||||
|
|
||||||
# Obter um documento específico
|
|
||||||
@document_bp.route("/<int:document_id>", methods=["GET"])
|
|
||||||
@token_required
|
|
||||||
def get_document(self, document_id):
|
|
||||||
document = document.query.get_or_404(document_id)
|
|
||||||
return jsonify({
|
|
||||||
"id": document.id,
|
|
||||||
"title": document.title,
|
|
||||||
"content": document.content,
|
|
||||||
"owner_id": document.user_id
|
|
||||||
})
|
|
||||||
|
|
||||||
# Atualizar um documento
|
|
||||||
@document_bp.route("/<int:document_id>", methods=["PUT"])
|
|
||||||
@token_required
|
|
||||||
def update_document(self, document_id):
|
|
||||||
document = document.query.get_or_404(document_id)
|
|
||||||
data = request.get_json()
|
|
||||||
|
|
||||||
document.title = data.get("title", document.title)
|
|
||||||
document.content = data.get("content", document.content)
|
|
||||||
|
|
||||||
db.session.commit()
|
|
||||||
return jsonify({"message": "Documento atualizado com sucesso!"})
|
|
||||||
|
|
||||||
# Deletar um documento
|
|
||||||
@document_bp.route("/<int:document_id>", methods=["DELETE"])
|
|
||||||
@token_required
|
|
||||||
def delete_document(self, document_id):
|
|
||||||
document = document.query.get_or_404(document_id)
|
|
||||||
db.session.delete(document)
|
|
||||||
40
app/routes/organizacao.py
Normal file
40
app/routes/organizacao.py
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
from flask import Blueprint, request, jsonify
|
||||||
|
from app.database import db
|
||||||
|
from app.models import Organizacao # ajuste conforme sua estrutura
|
||||||
|
|
||||||
|
organizacoes_bp = Blueprint('organizacoes', __name__, url_prefix='/organizacoes')
|
||||||
|
|
||||||
|
@organizacoes_bp.route('/', methods=['GET'])
|
||||||
|
def get_organizacoes():
|
||||||
|
organizacoes = Organizacao.query.all()
|
||||||
|
data = [
|
||||||
|
{
|
||||||
|
'id': org.id,
|
||||||
|
'nome': org.nome,
|
||||||
|
'criado_em': org.criado_em
|
||||||
|
}
|
||||||
|
for org in organizacoes
|
||||||
|
]
|
||||||
|
return jsonify(data), 200
|
||||||
|
|
||||||
|
@organizacoes_bp.route('/', methods=['POST'])
|
||||||
|
def create_organizacao():
|
||||||
|
data = request.get_json()
|
||||||
|
if not data or 'nome' not in data:
|
||||||
|
return jsonify({'error': 'O campo "nome" é obrigatório'}), 400
|
||||||
|
|
||||||
|
if Organizacao.query.filter_by(nome=data['nome']).first():
|
||||||
|
return jsonify({'error': 'Já existe uma organização com este nome'}), 409
|
||||||
|
|
||||||
|
try:
|
||||||
|
nova_org = Organizacao(nome=data['nome'])
|
||||||
|
db.session.add(nova_org)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
return jsonify({
|
||||||
|
'message': 'Organização criada com sucesso',
|
||||||
|
'id': nova_org.id
|
||||||
|
}), 201
|
||||||
|
except Exception as e:
|
||||||
|
db.session.rollback()
|
||||||
|
return jsonify({'error': str(e)}), 500
|
||||||
@ -1,46 +0,0 @@
|
|||||||
from flask import Blueprint, jsonify, request
|
|
||||||
from app.auth import generate_token, token_required
|
|
||||||
from app.models.organizacao import organization
|
|
||||||
from app.database import db
|
|
||||||
from werkzeug.security import generate_password_hash, check_password_hash
|
|
||||||
|
|
||||||
organization_bp = Blueprint("organizations", __name__)
|
|
||||||
|
|
||||||
@organization_bp.route("/", methods=["GET"])
|
|
||||||
@token_required
|
|
||||||
def get_organizations(self):
|
|
||||||
organizations = organization.query.all()
|
|
||||||
return jsonify([{"id": o.id, "name": o.name, "email": o.email} for o in organizations])
|
|
||||||
|
|
||||||
@organization_bp.route("/", methods=["POST"])
|
|
||||||
def create_organization(self):
|
|
||||||
data = request.get_json()
|
|
||||||
name = data.get("name")
|
|
||||||
email = data.get("email")
|
|
||||||
password = data.get("password")
|
|
||||||
|
|
||||||
if organization.query.filter_by(email=email).first():
|
|
||||||
return jsonify({"message": "Organização já existe!"}), 400
|
|
||||||
|
|
||||||
hashed_password = generate_password_hash(password, method="pbkdf2:sha256")
|
|
||||||
|
|
||||||
new_org = organization(name=name, email=email, password=hashed_password)
|
|
||||||
db.session.add(new_org)
|
|
||||||
db.session.commit()
|
|
||||||
|
|
||||||
return jsonify({"message": "Organização registrada com sucesso!"}), 201
|
|
||||||
|
|
||||||
@organization_bp.route("/login", methods=["POST"])
|
|
||||||
def login_organization():
|
|
||||||
data = request.get_json()
|
|
||||||
email = data.get("email")
|
|
||||||
password = data.get("password")
|
|
||||||
|
|
||||||
organization = organization.query.filter_by(email=email).first()
|
|
||||||
|
|
||||||
if not organization or not check_password_hash(organization.password, password):
|
|
||||||
return jsonify({"message": "Credenciais inválidas!"}), 401
|
|
||||||
|
|
||||||
token = generate_token(organization)
|
|
||||||
|
|
||||||
return jsonify({"message": "Login bem-sucedido", "token": token}), 200
|
|
||||||
@ -1,55 +0,0 @@
|
|||||||
from flask import Blueprint, jsonify, request
|
|
||||||
from app.auth import generate_token, token_required
|
|
||||||
from app.models.user import User
|
|
||||||
from app.database import db
|
|
||||||
from werkzeug.security import generate_password_hash, check_password_hash
|
|
||||||
|
|
||||||
user_bp = Blueprint("users", __name__)
|
|
||||||
|
|
||||||
@user_bp.route("/", methods=["GET"])
|
|
||||||
@token_required # Protege a rota
|
|
||||||
def get_users(self):
|
|
||||||
users = User.query.all() # select * from User
|
|
||||||
return jsonify([{"id": u.id, "name": u.name, "email": u.email} for u in users])
|
|
||||||
|
|
||||||
@user_bp.route("/", methods=["POST"])
|
|
||||||
def create_user(self):
|
|
||||||
data = request.get_json()
|
|
||||||
print(data)
|
|
||||||
nome = data.get("nome")
|
|
||||||
email = data.get("email")
|
|
||||||
senha = data.get("senha")
|
|
||||||
|
|
||||||
# Verificar se o usuário já existe
|
|
||||||
if User.query.filter_by(email=email).first():
|
|
||||||
return jsonify({"message": "Usuário já existe!"}), 400
|
|
||||||
|
|
||||||
# Gerar senha criptografada
|
|
||||||
hashed_password = generate_password_hash(senha, method="pbkdf2:sha256")
|
|
||||||
|
|
||||||
# Criar novo usuário
|
|
||||||
new_user = User(nome=nome, email=email, senha=senha)
|
|
||||||
|
|
||||||
# Adicionar e salvar no banco de dados
|
|
||||||
db.session.add(new_user)
|
|
||||||
db.session.commit()
|
|
||||||
|
|
||||||
return jsonify({"message": "Usuário registrado com sucesso!"}), 201
|
|
||||||
|
|
||||||
# Rota para login de usuário
|
|
||||||
@user_bp.route("/login", methods=["POST"])
|
|
||||||
def login_user():
|
|
||||||
data = request.get_json()
|
|
||||||
print(data)
|
|
||||||
|
|
||||||
email = data.get("email")
|
|
||||||
senha = data.get("senha")
|
|
||||||
|
|
||||||
user = User.query.filter_by(email=email).first()
|
|
||||||
|
|
||||||
if not user or not check_password_hash(user.senha, senha):
|
|
||||||
return jsonify({"message": "Credenciais inválidas!"}), 401
|
|
||||||
|
|
||||||
token = generate_token(user)
|
|
||||||
|
|
||||||
return jsonify({"message": "Login bem-sucedido", "token": token}), 200
|
|
||||||
44
app/routes/usuario.py
Normal file
44
app/routes/usuario.py
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
from flask import Blueprint, request, jsonify
|
||||||
|
from app.database import db
|
||||||
|
from app.models import Usuario # nome correto do modelo
|
||||||
|
|
||||||
|
usuarios_bp = Blueprint('usuarios', __name__, url_prefix='/usuarios')
|
||||||
|
|
||||||
|
|
||||||
|
@usuarios_bp.route('/', methods=['GET'])
|
||||||
|
def get_usuarios():
|
||||||
|
usuarios = Usuario.query.all()
|
||||||
|
usuarios_data = [
|
||||||
|
{
|
||||||
|
'id': usuario.id,
|
||||||
|
'nome': usuario.nome,
|
||||||
|
'email': usuario.email,
|
||||||
|
'organizacao_id': usuario.organizacao_id,
|
||||||
|
'criado_em': usuario.criado_em,
|
||||||
|
'atualizado_em': usuario.atualizado_em
|
||||||
|
}
|
||||||
|
for usuario in usuarios
|
||||||
|
]
|
||||||
|
return jsonify(usuarios_data), 200
|
||||||
|
|
||||||
|
|
||||||
|
@usuarios_bp.route('/', methods=['POST'])
|
||||||
|
def create_usuario():
|
||||||
|
data = request.get_json()
|
||||||
|
if not all(k in data for k in ('nome', 'email', 'senha_hash', 'organizacao_id')):
|
||||||
|
return jsonify({'error': 'Campos obrigatórios ausentes'}), 400
|
||||||
|
|
||||||
|
if Usuario.query.filter_by(email=data['email']).first():
|
||||||
|
return jsonify({'error': 'E-mail já está em uso'}), 409
|
||||||
|
|
||||||
|
novo_usuario = Usuario(
|
||||||
|
nome=data['nome'],
|
||||||
|
email=data['email'],
|
||||||
|
senha_hash=data['senha_hash'],
|
||||||
|
organizacao_id=data['organizacao_id']
|
||||||
|
)
|
||||||
|
|
||||||
|
db.session.add(novo_usuario)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
return jsonify({'message': 'Usuário criado com sucesso', 'id': novo_usuario.id}), 201
|
||||||
Binary file not shown.
5
run.py
5
run.py
@ -1,4 +1,4 @@
|
|||||||
from app import create_default_user, create_app
|
from app import create_app
|
||||||
from app.database import db
|
from app.database import db
|
||||||
|
|
||||||
app = create_app()
|
app = create_app()
|
||||||
@ -6,8 +6,7 @@ app = create_app()
|
|||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
with app.app_context():
|
with app.app_context():
|
||||||
db.create_all()
|
db.create_all()
|
||||||
create_default_user()
|
|
||||||
|
|
||||||
print("Banco de dados criado")
|
print("Banco de dados criado")
|
||||||
|
|
||||||
app.run(debug=True, port=5000)
|
app.run(debug=True, port=5000)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user