diff --git a/.gitignore b/.gitignore index b694934..aa6364a 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,5 @@ -.venv \ No newline at end of file +.venv +.env +instance +models/__pycache__ +routes/__pycache__ diff --git a/models/__init__.py b/models/__init__.py new file mode 100644 index 0000000..96c5d7b --- /dev/null +++ b/models/__init__.py @@ -0,0 +1,5 @@ +from flask_sqlalchemy import SQLAlchemy +from flask_bcrypt import Bcrypt + +db = SQLAlchemy() +bcrypt = Bcrypt() \ No newline at end of file diff --git a/models/user.py b/models/user.py new file mode 100644 index 0000000..dbfa4f8 --- /dev/null +++ b/models/user.py @@ -0,0 +1,25 @@ +from models import db, bcrypt + +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_hash = db.Column(db.String(128), nullable=False) + + @staticmethod + def create_user(username, password): + """Create a new user with a hashed password""" + password_hash = bcrypt.generate_password_hash(password).decode('utf-8') + new_user = User(username=username, password_hash=password_hash) + db.session.add(new_user) + db.session.commit() + return new_user + + @staticmethod + def verify_user(username, password): + """Verify user creds""" + user = User.query.filter_by(username=username).first() + if user and bcrypt.check_password_hash(user.password_hash, password): + return user + return None \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index c652510..7ad209e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,5 @@ bcc==0.18.0 +bcrypt==4.2.1 blinker==1.9.0 Brlapi==0.8.3 certifi==2020.6.20 @@ -14,6 +15,8 @@ defer==1.0.6 distro==1.7.0 evdev==1.4.0 Flask==3.1.0 +Flask-Bcrypt==1.0.1 +Flask-SQLAlchemy==3.1.1 greenlet==3.1.1 hidpidaemon==18.4.6 httplib2==0.20.2 @@ -62,6 +65,7 @@ requests==2.25.1 SecretStorage==3.3.1 sessioninstaller==0.0.0 six==1.16.0 +SQLAlchemy==2.0.36 system76driver==20.4.102 systemd-python==234 typing_extensions==4.12.2 diff --git a/routes/auth.py b/routes/auth.py new file mode 100644 index 0000000..1f37877 --- /dev/null +++ b/routes/auth.py @@ -0,0 +1,34 @@ +from flask import Blueprint, request, jsonify +from models.user import User, db + +auth_bp = Blueprint('auth', __name__) + +@auth_bp.route('/signup', methods=['POST']) +def signup(): + data = request.json + username = data.get('username') + password = data.get('password') + + if not username or not password: + return jsonify({"error": "Username and password are required"}), 400 + + if User.query.filter_by(username=username).first(): + return jsonify({"error": "Username already exists"}), 400 + + User.create_user(username, password) + return jsonify({"message": "User registered successfully"}), 201 + +@auth_bp.route('/login', methods=['POST']) +def login(): + data = request.json + username = data.get('username') + password = data.get('password') + + if not username or not password: + return jsonify({"error": "Username and password are required"}), 400 + + user = User.verify_user(username, password) + if not user: + return jsonify({"error": "Invalid username or password"}), 401 + + return jsonify({"message": f"Welcome, {username}!"}), 200 \ No newline at end of file diff --git a/server.py b/server.py index d29ddd1..b656bba 100644 --- a/server.py +++ b/server.py @@ -1,14 +1,23 @@ +import os from flask import Flask +from models import db, bcrypt +from routes.auth import auth_bp +from dotenv import load_dotenv + +load_dotenv() app = Flask(__name__) -@app.route('/') -def index(): - return 'Index page' +app.config['SQLALCHEMY_DATABASE_URI'] = os.getenv('DATABASE') +app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False -@app.route('/login') -def login(): - return 'Login Page' +db.init_app(app) +bcrypt.init_app(app) -if __name__ == "__main__": - app.run() \ No newline at end of file +app.register_blueprint(auth_bp) + +with app.app_context(): + db.create_all() + +if __name__ == '__main__': + app.run(debug=True) \ No newline at end of file