(feat): Added PostgreSQL connection string encoding.
This commit is contained in:
parent
32dcace985
commit
51f154ab73
5 changed files with 45 additions and 32 deletions
|
|
@ -1,5 +1,22 @@
|
||||||
|
import os
|
||||||
from flask_sqlalchemy import SQLAlchemy
|
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()
|
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)
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,23 @@
|
||||||
from models import db
|
from models import db
|
||||||
|
from werkzeug.security import generate_password_hash, check_password_hash
|
||||||
|
|
||||||
class User(db.Model):
|
class User(db.Model):
|
||||||
__tablename__ = 'users'
|
__tablename__ = 'users'
|
||||||
|
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
username = db.Column(db.String(80), unique=True, nullable=False)
|
username = db.Column(db.String(80), unique=True, nullable=False)
|
||||||
password = db.Column(db.String(128), nullable=False)
|
password = db.Column(db.String(128), nullable=False)
|
||||||
|
|
||||||
|
def __init__(self, username, password, hash_password=True):
|
||||||
|
self.username = username
|
||||||
|
# Optionally hash the password automatically.
|
||||||
|
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}>"
|
||||||
|
|
@ -15,8 +15,6 @@ def signup():
|
||||||
return jsonify({"message": "User created successfully", "username": new_user.username}), 201
|
return jsonify({"message": "User created successfully", "username": new_user.username}), 201
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
return jsonify({"message": str(e)}), 400
|
return jsonify({"message": str(e)}), 400
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@auth_bp.route('/login', methods=['POST'])
|
@auth_bp.route('/login', methods=['POST'])
|
||||||
def login():
|
def login():
|
||||||
|
|
@ -28,4 +26,4 @@ def login():
|
||||||
user = user_service.verify_user(username, password)
|
user = user_service.verify_user(username, password)
|
||||||
return jsonify({"message": "Login successful", "user_id": user.id}), 200
|
return jsonify({"message": "Login successful", "user_id": user.id}), 200
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
return jsonify({"error": str(e)}), 401
|
return jsonify({"error": str(e)}), 401
|
||||||
|
|
|
||||||
10
server.py
10
server.py
|
|
@ -1,6 +1,6 @@
|
||||||
import os
|
import os
|
||||||
from flask import Flask
|
from flask import Flask
|
||||||
from models import db, bcrypt
|
from models import db, init_db
|
||||||
from routes.auth import auth_bp
|
from routes.auth import auth_bp
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
from flask_cors import CORS
|
from flask_cors import CORS
|
||||||
|
|
@ -8,14 +8,12 @@ from flask_cors import CORS
|
||||||
load_dotenv()
|
load_dotenv()
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
|
CORS(app)
|
||||||
|
|
||||||
CORS(app)
|
app.config['SQLALCHEMY_DATABASE_URI'] = os.getenv('DATABASE') # Or use DATABASE_URI from models
|
||||||
|
|
||||||
app.config['SQLALCHEMY_DATABASE_URI'] = os.getenv('DATABASE')
|
|
||||||
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
|
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
|
||||||
|
|
||||||
db.init_app(app)
|
init_db(app)
|
||||||
bcrypt.init_app(app)
|
|
||||||
|
|
||||||
app.register_blueprint(auth_bp)
|
app.register_blueprint(auth_bp)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,33 +2,18 @@ from werkzeug.security import generate_password_hash, check_password_hash
|
||||||
from models.user import User, db
|
from models.user import User, db
|
||||||
|
|
||||||
class UserService:
|
class UserService:
|
||||||
def __init__(self):
|
|
||||||
self.db = db
|
|
||||||
|
|
||||||
def create_user(self, username, password):
|
def create_user(self, username, password):
|
||||||
# Check if the user exists
|
|
||||||
existing_user = User.query.filter_by(username=username).first()
|
existing_user = User.query.filter_by(username=username).first()
|
||||||
if existing_user:
|
if existing_user:
|
||||||
raise ValueError("User already exists")
|
raise ValueError("User already exists")
|
||||||
|
|
||||||
# Hash the password before storing
|
new_user = User(username=username, password=password)
|
||||||
hash_password = generate_password_hash(password)
|
db.session.add(new_user)
|
||||||
|
db.session.commit()
|
||||||
# Create a new user
|
|
||||||
new_user = User(username=username, password=hash_password)
|
|
||||||
self.db.session.add(new_user)
|
|
||||||
self.db.session.commit()
|
|
||||||
|
|
||||||
return new_user
|
return new_user
|
||||||
|
|
||||||
def verify_user(self, username, password):
|
def verify_user(self, username, password):
|
||||||
# Fetch the user by username
|
|
||||||
user = User.query.filter_by(username=username).first()
|
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")
|
raise ValueError("Invalid username or password")
|
||||||
|
return user
|
||||||
# Verify the hashed password
|
|
||||||
if not check_password_hash(user.password, password):
|
|
||||||
raise ValueError("Invalid username or password")
|
|
||||||
|
|
||||||
return user
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue