Merge pull request 'v0.1.0-database: Improve Scalability - Migrate to PostgreSQL' (#14) from v0.1.0-database into main

Reviewed-on: https://brew.bsd.cafe/RideAware/rideaware-api/pulls/14
This commit is contained in:
blake 2025-02-16 02:05:02 +01:00
commit d12f933534
7 changed files with 46 additions and 33 deletions

2
.gitignore vendored
View file

@ -1,4 +1,4 @@
.venv/
venv/
.env
instance
models/__pycache__

View file

@ -1,5 +1,22 @@
import os
from flask_sqlalchemy import SQLAlchemy
from flask_bcrypt import Bcrypt
from dotenv import load_dotenv
from urllib.parse import quote_plus
load_dotenv()
PG_USER = quote_plus(os.getenv('PG_USER'))
PG_PASSWORD = quote_plus(os.getenv('PG_PASSWORD'))
PG_HOST = os.getenv('PG_HOST')
PG_PORT = os.getenv('PG_PORT')
PG_DATABASE = os.getenv('PG_DATABASE')
DATABASE_URI = f"postgresql+psycopg2://{PG_USER}:{PG_PASSWORD}@{PG_HOST}:{PG_PORT}/{PG_DATABASE}"
db = SQLAlchemy()
bcrypt = Bcrypt()
def init_db(app):
"""Initialize the SQLAlchemy app with the configuration."""
app.config['SQLALCHEMY_DATABASE_URI'] = DATABASE_URI
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db.init_app(app)

View file

@ -1,8 +1,22 @@
from models import db
from werkzeug.security import generate_password_hash, check_password_hash
class User(db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True, nullable=False)
password = db.Column(db.String(128), nullable=False)
def __init__(self, username, password, hash_password=True):
self.username = username
if hash_password:
self.password = generate_password_hash(password, method="pbkdf2:sha256")
else:
self.password = password
def check_password(self, password):
return check_password_hash(self.password, password)
def __repr__(self):
return f"<User {self.username}>"

View file

@ -3,4 +3,5 @@ flask_bcrypt
flask_cors
flask_sqlalchemy
python-dotenv
werkzeug
werkzeug
psycopg2-binary

View file

@ -15,8 +15,6 @@ def signup():
return jsonify({"message": "User created successfully", "username": new_user.username}), 201
except ValueError as e:
return jsonify({"message": str(e)}), 400
@auth_bp.route('/login', methods=['POST'])
def login():
@ -28,4 +26,4 @@ def login():
user = user_service.verify_user(username, password)
return jsonify({"message": "Login successful", "user_id": user.id}), 200
except ValueError as e:
return jsonify({"error": str(e)}), 401
return jsonify({"error": str(e)}), 401

View file

@ -1,6 +1,6 @@
import os
from flask import Flask
from models import db, bcrypt
from models import db, init_db
from routes.auth import auth_bp
from dotenv import load_dotenv
from flask_cors import CORS
@ -8,14 +8,12 @@ from flask_cors import CORS
load_dotenv()
app = Flask(__name__)
CORS(app)
CORS(app)
app.config['SQLALCHEMY_DATABASE_URI'] = os.getenv('DATABASE')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db.init_app(app)
bcrypt.init_app(app)
init_db(app)
app.register_blueprint(auth_bp)

View file

@ -2,33 +2,18 @@ from werkzeug.security import generate_password_hash, check_password_hash
from models.user import User, db
class UserService:
def __init__(self):
self.db = db
def create_user(self, username, password):
# Check if the user exists
existing_user = User.query.filter_by(username=username).first()
if existing_user:
raise ValueError("User already exists")
# Hash the password before storing
hash_password = generate_password_hash(password)
# Create a new user
new_user = User(username=username, password=hash_password)
self.db.session.add(new_user)
self.db.session.commit()
new_user = User(username=username, password=password)
db.session.add(new_user)
db.session.commit()
return new_user
def verify_user(self, username, password):
# Fetch the user by username
user = User.query.filter_by(username=username).first()
if not user:
if not user or not user.check_password(password):
raise ValueError("Invalid username or password")
# Verify the hashed password
if not check_password_hash(user.password, password):
raise ValueError("Invalid username or password")
return user
return user