-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp.py
More file actions
97 lines (75 loc) · 2.91 KB
/
Copy pathapp.py
File metadata and controls
97 lines (75 loc) · 2.91 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
from flask import Flask, request, jsonify
from flask_sqlalchemy import SQLAlchemy
from argon2 import PasswordHasher
import uuid
import os
from encryption import encrypt_private_key, decrypt_private_key
from models import db, User, AuthLog
from flask_limiter import Limiter
from flask_limiter.util import get_remote_address
# Initialize the app and the database
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///auth.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db.init_app(app)
# Password hasher instance
ph = PasswordHasher()
# Rate limiter
limiter = Limiter(key_func=get_remote_address, app=app) # Ensuring app is passed here
# Ensure the database tables are created before making requests
@app.before_request
def create_tables():
db.create_all()
@app.route('/register', methods=['POST'])
def register():
data = request.get_json()
# Ensure the necessary fields are provided
username = data.get('username')
email = data.get('email', '')
if not username:
return jsonify({"error": "Username is required"}), 400
existing_user = User.query.filter_by(username=username).first()
if existing_user:
return jsonify({"error": "Username already taken"}), 400
# Generate a secure UUID as a password
password = str(uuid.uuid4())
# Hash the password using Argon2
password_hash = ph.hash(password)
# Store the user details in the database
user = User(username=username, password_hash=password_hash, email=email)
db.session.add(user)
db.session.commit()
return jsonify({"password": password}), 201
@app.before_request
def log_request():
if request.endpoint == 'auth':
ip_address = request.remote_addr
user_id = None
log_entry = AuthLog(request_ip=ip_address, user_id=user_id)
db.session.add(log_entry)
db.session.commit()
@app.route('/auth', methods=['POST'])
@limiter.limit("5 per minute") # Adjusted to a more practical rate limit
def auth():
data = request.get_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.query.filter_by(username=username).first()
if not user:
return jsonify({"error": "User not found"}), 404
# Check password validity
try:
ph.verify(user.password_hash, password)
except:
return jsonify({"error": "Invalid password"}), 401
# Successful authentication (logic here to track the user)
user_id = user.id # Assuming user has an 'id' field
ip_address = request.remote_addr
log_entry = AuthLog(request_ip=ip_address, user_id=user_id)
db.session.add(log_entry)
db.session.commit()
return jsonify({"message": "Authenticated successfully"}), 200
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0', port=8080)