Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/api/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,21 @@
db = SQLAlchemy()

class User(db.Model):
__tablename__= 'user'
id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str] = mapped_column(String(90), unique=False, nullable=False)
email: Mapped[str] = mapped_column(String(120), unique=True, nullable=False)
password: Mapped[str] = mapped_column(nullable=False)
is_active: Mapped[bool] = mapped_column(Boolean(), nullable=False)


def __repr__(self):
return f'Usuario {self.name}'

def serialize(self):
return {
"id": self.id,
"name": self.name,
"email": self.email,
# do not serialize the password, its a security breach
}
109 changes: 108 additions & 1 deletion src/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,22 @@
from flask_migrate import Migrate
from flask_swagger import swagger
from api.utils import APIException, generate_sitemap
from api.models import db
from api.models import db, User
from api.routes import api
from api.admin import setup_admin
from api.commands import setup_commands
#from datetime import timedelta
#------import datetime para los refresh
from flask_jwt_extended import create_access_token
from flask_jwt_extended import get_jwt_identity
from flask_jwt_extended import jwt_required
from flask_jwt_extended import JWTManager
# Al importar Bcrypt se tiene que instalar la libreria con el comando \
# : $ pip("pipenv" en este repo) install flask-bcrypt
from flask_bcrypt import Bcrypt

#from flask_jwt_extended import create_refresh_token
#------import refresh------

# from models import Person

Expand All @@ -19,6 +31,21 @@
app = Flask(__name__)
app.url_map.strict_slashes = False

app.config["JWT_SECRET_KEY"] = os.getenv('JWT_KEY')

bcrypt = Bcrypt(app)

#ACCESS_MIN = int(os.getenv("JWT_ACCESS_TOKEN_EXPIRES_MIN", "60"))
#REFRESH_DAYS = int(os.getenv("JWT_REFRESH_TOKEN_EXPIRES_DAYS", "30"))
#----------------------------------------------
# Pruevas para los refrsh tokens /\ \/
#--------------------------------------------------
#app.config["JWT_ACCESS_TOKEN_EXPIRES"] = timedelta(minutes=ACCESS_MIN)
#app.config["JWT_REFRESH_TOKEN_EXPIRES"] = timedelta(days=REFRESH_DAYS)


jwt = JWTManager(app)

# database condiguration
db_url = os.getenv("DATABASE_URL")
if db_url is not None:
Expand Down Expand Up @@ -66,6 +93,86 @@ def serve_any_other_file(path):
return response




@app.route('/api/login', methods=['POST'])
def login():
body = request.get_json(silent=True)
if body is None:
return jsonify({'msg': ' Debes enviar informacion en el body'}), 400
if 'email' not in body:
return jsonify({'msg': 'El campo email es obligatorio'}), 400
if 'password' not in body:
return jsonify({'msg': ' El campo password es obligatorio'}), 400

user = User.query.filter_by(email=body['email']).first()

# var = VarEnModels.query.filer_by(nombredelcampo=body['nombredelcampo']).first()
# para traer el usuario orphan en cascade
##########!!!!! \/
# user = User.query.filter_by(email=body['email'], password=body['password']).first()
# idea de Leon para ahorrarse el if de password!!! Idea alternativa
print(user)
if user is None:
return jsonify({'msg': 'Usuario o contraseña incorrecta'}), 400
is_correct = bcrypt.check_password_hash(user.password, body['password'])
if is_correct == False:
return jsonify({'msg': 'Usuario o contraseña incorrecta'}), 400
#if user.password != body['password']:
# return jsonify({'msg': 'Usuario o contraseña incorrecta'}), 400

acces_token = create_access_token(identity=user.email)
#refresh_token = create_refresh_token(identity=user.email)
#-----refresh token
#print(user)
return jsonify({'msg': 'Usuario logeado correctamente!', \
'token': acces_token}), 200
#'refresh_token': refresh_token,-------
#'access_expires_minutes': ACCESS_MIN,------SOLO PRUEBAS REFRESH
#'refresh_expires_days': REFRESH_DAYS}), 200 ------


@app.route('/api/register', methods=['POST'])
def register_user():
body = request.get_json(silent=True)
if body is None:
return jsonify({'msg': 'Debes enviar informacion en el body'}), 400
if 'email' not in body:
return jsonify({'msg': 'El campo email es obligatorio'}), 400
if 'name' not in body:
return jsonify({'msg': 'Debes proporcionar un nombre'}), 400
if 'password' not in body:
return jsonify({'msg': 'Debes proporcionar una contraseña'}), 400

new_register = User() # Otra opcion seria instanciar todo el body dentro del User \
# asi: new_register = User( email = body['email], name = body['name]...) \
# En este casa lo instanciamos por separado
new_register.name = body['name']
new_register.email = body['email']
hash_password = bcrypt.generate_password_hash(body['password']).decode('utf-8')
#new_register.password = body['password']
new_register.password = hash_password

new_register.is_active = True

db.session.add(new_register)
db.session.commit()

return jsonify({'msg': 'Usuario registrado!', 'register': new_register.serialize()}), 200


#-----ENDPOINTS PROTEGIDOS \/
@app.route('/api/private', methods=['GET'])
@jwt_required()
def privado():
current_user = get_jwt_identity()
#print(current_user)
current_user = User.query.filter_by(email=current_user).first
#----Para autorizar por primera vez un token en Postman /headers -> //crear key// -> Authorization y //Value -> Bearer (espacio) nuevo token
#---Una vez autorizado -> /Authorization/Bearer Token/ poner el token
return jsonify({'msg': 'Gracias por probar que estas logeado'}), 200
#return jsonify({"id": user.email, "username": user.username }), 200

# this only runs if `$ python src/main.py` is executed
if __name__ == '__main__':
PORT = int(os.environ.get('PORT', 3001))
Expand Down
38 changes: 38 additions & 0 deletions src/front/pages/Login.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
import { React, useState, useEffect } from "react";
import { Link, useNavigate } from "react-router-dom";
import useGlobalReducer from "../hooks/useGlobalReducer.jsx";

export const Login = () => {

const { store, dispatch } = useGlobalReducer()
const navigate = useNavigate();

const login = async (username, password) => {
const resp = await fetch(`https://your_api.com/token`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ username, password })
})

if (!resp.ok) throw Error("There was a problem in the login request")

if (resp.status === 401) {
throw ("Invalid credentials")
}
else if (resp.status === 400) {
throw ("Invalid email or password format")
}
const data = await resp.json()
// Guarda el token en la localStorage
// También deberías almacenar el usuario en la store utilizando la función setItem
localStorage.setItem("jwt-token", data.token);

return data
}




}
*/
25 changes: 25 additions & 0 deletions src/front/pages/Register.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
import { React, useState, useEffect } from "react";
import { Link, useNavigate } from "react-router-dom";
import useGlobalReducer from "../hooks/useGlobalReducer.jsx";

export const Register = () => {

const { store, dispatch } = useGlobalReducer()
const navigate = useNavigate();



return(





)




}
*/
4 changes: 4 additions & 0 deletions src/front/routes.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import { Layout } from "./pages/Layout";
import { Home } from "./pages/Home";
import { Single } from "./pages/Single";
import { Demo } from "./pages/Demo";
import { Login } from "./pages/Login";
import { Register } from "./pages/Register";

export const router = createBrowserRouter(
createRoutesFromElements(
Expand All @@ -25,6 +27,8 @@ export const router = createBrowserRouter(
<Route path= "/" element={<Home />} />
<Route path="/single/:theId" element={ <Single />} /> {/* Dynamic route for single items */}
<Route path="/demo" element={<Demo />} />
<Route path="/login" element={<Login />} />
<Route path="/register" element={<Register />} />
</Route>
)
);