(feat): Basic user auth
This commit is contained in:
parent
e5976d3c8d
commit
de460fbcbc
6 changed files with 90 additions and 9 deletions
6
.gitignore
vendored
6
.gitignore
vendored
|
|
@ -1 +1,5 @@
|
||||||
.venv
|
.venv
|
||||||
|
.env
|
||||||
|
instance
|
||||||
|
models/__pycache__
|
||||||
|
routes/__pycache__
|
||||||
|
|
|
||||||
5
models/__init__.py
Normal file
5
models/__init__.py
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
from flask_sqlalchemy import SQLAlchemy
|
||||||
|
from flask_bcrypt import Bcrypt
|
||||||
|
|
||||||
|
db = SQLAlchemy()
|
||||||
|
bcrypt = Bcrypt()
|
||||||
25
models/user.py
Normal file
25
models/user.py
Normal file
|
|
@ -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
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
bcc==0.18.0
|
bcc==0.18.0
|
||||||
|
bcrypt==4.2.1
|
||||||
blinker==1.9.0
|
blinker==1.9.0
|
||||||
Brlapi==0.8.3
|
Brlapi==0.8.3
|
||||||
certifi==2020.6.20
|
certifi==2020.6.20
|
||||||
|
|
@ -14,6 +15,8 @@ defer==1.0.6
|
||||||
distro==1.7.0
|
distro==1.7.0
|
||||||
evdev==1.4.0
|
evdev==1.4.0
|
||||||
Flask==3.1.0
|
Flask==3.1.0
|
||||||
|
Flask-Bcrypt==1.0.1
|
||||||
|
Flask-SQLAlchemy==3.1.1
|
||||||
greenlet==3.1.1
|
greenlet==3.1.1
|
||||||
hidpidaemon==18.4.6
|
hidpidaemon==18.4.6
|
||||||
httplib2==0.20.2
|
httplib2==0.20.2
|
||||||
|
|
@ -62,6 +65,7 @@ requests==2.25.1
|
||||||
SecretStorage==3.3.1
|
SecretStorage==3.3.1
|
||||||
sessioninstaller==0.0.0
|
sessioninstaller==0.0.0
|
||||||
six==1.16.0
|
six==1.16.0
|
||||||
|
SQLAlchemy==2.0.36
|
||||||
system76driver==20.4.102
|
system76driver==20.4.102
|
||||||
systemd-python==234
|
systemd-python==234
|
||||||
typing_extensions==4.12.2
|
typing_extensions==4.12.2
|
||||||
|
|
|
||||||
34
routes/auth.py
Normal file
34
routes/auth.py
Normal file
|
|
@ -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
|
||||||
25
server.py
25
server.py
|
|
@ -1,14 +1,23 @@
|
||||||
|
import os
|
||||||
from flask import Flask
|
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 = Flask(__name__)
|
||||||
|
|
||||||
@app.route('/')
|
app.config['SQLALCHEMY_DATABASE_URI'] = os.getenv('DATABASE')
|
||||||
def index():
|
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
|
||||||
return 'Index page'
|
|
||||||
|
|
||||||
@app.route('/login')
|
db.init_app(app)
|
||||||
def login():
|
bcrypt.init_app(app)
|
||||||
return 'Login Page'
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
app.register_blueprint(auth_bp)
|
||||||
app.run()
|
|
||||||
|
with app.app_context():
|
||||||
|
db.create_all()
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
app.run(debug=True)
|
||||||
Loading…
Add table
Add a link
Reference in a new issue