Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

linting #3

Merged
merged 1 commit into from
Aug 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
linting
  • Loading branch information
Steven Adler committed Aug 20, 2024
commit 032c58a668d846a336dac97aa9800e8bc1ddc47b
32 changes: 13 additions & 19 deletions app/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,49 +27,43 @@ def create_app():

socketio.init_app(flask_app)

connect(host=settings.MONGO_URI, uuidRepresentation='standard')
connect(host=settings.MONGO_URI, uuidRepresentation="standard")

flask_app.register_blueprint(session_bp, url_prefix='/session')
flask_app.register_blueprint(session_bp, url_prefix="/session")

flask_app.register_blueprint(auth_bp, url_prefix='/auth')
flask_app.register_blueprint(user_bp, url_prefix='/users')
flask_app.register_blueprint(rolltable_bp, url_prefix='/rolltables')
flask_app.register_blueprint(room_bp, url_prefix='/rooms')
flask_app.register_blueprint(encounter_bp, url_prefix='/encounters')
flask_app.register_blueprint(roll_bp, url_prefix='/rolls')
flask_app.register_blueprint(item_bp, url_prefix='/items')
flask_app.register_blueprint(auth_bp, url_prefix="/auth")
flask_app.register_blueprint(user_bp, url_prefix="/users")
flask_app.register_blueprint(rolltable_bp, url_prefix="/rolltables")
flask_app.register_blueprint(room_bp, url_prefix="/rooms")
flask_app.register_blueprint(encounter_bp, url_prefix="/encounters")
flask_app.register_blueprint(roll_bp, url_prefix="/rolls")
flask_app.register_blueprint(item_bp, url_prefix="/items")

@flask_app.errorhandler(HTTPException)
def handle_http_exception(e):
logging.warning(f"HTTP error occurred: {e}")
response = {
"error": e.name,
"message": e.description
}
response = {"error": e.name, "message": e.description}
return jsonify(response), e.code

@flask_app.errorhandler(Exception)
def handle_exception(e):
logging.error(f"An error occurred: {e}")
response = {
"error": "Internal Server Error",
"message": str(e)
}
response = {"error": "Internal Server Error", "message": str(e)}
return jsonify(response), 500

@flask_app.errorhandler(404)
def handle_404_error(e):
response = {
"error": "Not Found",
"message": "The requested resource could not be found"
"message": "The requested resource could not be found",
}
return jsonify(response), 404

@flask_app.errorhandler(400)
def handle_400_error(e):
response = {
"error": "Bad Request",
"message": "The request could not be understood or was missing required parameters"
"message": "The request could not be understood or was missing required parameters",
}
return jsonify(response), 400

Expand Down
7 changes: 3 additions & 4 deletions app/models/encounter.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from mongoengine import StringField, IntField
from mongoengine import IntField, StringField

from app.models.rollable import Rollable


Expand All @@ -7,6 +8,4 @@ class Encounter(Rollable):
min_players = IntField(required=True)
max_players = IntField(required=True)

meta = {
'collection': 'rollable_encounters'
}
meta = {"collection": "rollable_encounters"}
6 changes: 2 additions & 4 deletions app/models/item.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from mongoengine import StringField, BooleanField
from mongoengine import BooleanField, StringField

from app.models.rollable import Rollable

Expand All @@ -10,6 +10,4 @@ class Item(Rollable):
has_been_rolled = BooleanField(default=False, required=True)
available = BooleanField(default=True) # for current round of rolling
image_file_location = StringField()
meta = {
'collection': 'rollable_items'
}
meta = {"collection": "rollable_items"}
4 changes: 2 additions & 2 deletions app/models/rollable.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from mongoengine import Document, StringField, IntField
from mongoengine import Document, IntField, StringField


class Rollable(Document):
meta = {'abstract': True}
meta = {"abstract": True}

name = StringField(required=True)
description = StringField(require=True)
Expand Down
13 changes: 8 additions & 5 deletions app/models/rolltable.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,15 @@


class RollTable(Rollable):
tier = StringField(required=True, choices=["Platinum", "Gold", "Silver", "Bronze"])
table_type = StringField(required=True, choices=["Magic Items", "Weapons", "Encounters", "Rooms"])
tier = StringField(
required=True, choices=["Platinum", "Gold", "Silver", "Bronze"]
)
table_type = StringField(
required=True,
choices=["Magic Items", "Weapons", "Encounters", "Rooms"],
)

items = ListField(ReferenceField(Item))
encounters = ListField(ReferenceField(Encounter))
rooms = ListField(ReferenceField(Room))
meta = {
'collection': 'rolltables'
}
meta = {"collection": "rolltables"}
5 changes: 2 additions & 3 deletions app/models/room.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
from mongoengine import StringField

from app.models.rollable import Rollable


class Room(Rollable):
type = StringField(default="Room")
reward_tier = StringField(choices=["Bronze", "Silver", "Gold", "Platinum"])
meta = {
'collection': 'rollable_rooms'
}
meta = {"collection": "rollable_rooms"}
15 changes: 10 additions & 5 deletions app/models/user.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
from mongoengine import StringField, BooleanField, ListField, EmailField, Document, ReferenceField
from werkzeug.security import generate_password_hash, check_password_hash
from mongoengine import (
BooleanField,
Document,
EmailField,
ListField,
ReferenceField,
StringField,
)
from werkzeug.security import check_password_hash, generate_password_hash

from app.models.item import Item

Expand All @@ -12,9 +19,7 @@ class User(Document):
is_active = BooleanField(default=False)
is_dm = BooleanField(default=False, required=True)
items = ListField(ReferenceField(Item))
meta = {
'collection': 'users'
}
meta = {"collection": "users"}

def set_password(self, password):
self.password_hash = generate_password_hash(password)
Expand Down
49 changes: 27 additions & 22 deletions app/utils/auth_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import jwt
from bson import ObjectId
from flask import current_app, request, abort
from flask import abort, current_app, request

from app.models.user import User

Expand All @@ -16,15 +16,13 @@
def encode_auth_token(user_id, is_dm):
try:
payload = {
'exp': datetime.now(timezone.utc) + timedelta(days=1),
'iat': datetime.now(timezone.utc),
'sub': str(user_id),
'is_dm': is_dm
"exp": datetime.now(timezone.utc) + timedelta(days=1),
"iat": datetime.now(timezone.utc),
"sub": str(user_id),
"is_dm": is_dm,
}
return jwt.encode(
payload,
current_app.config.get('SECRET_KEY'),
algorithm='HS256'
payload, current_app.config.get("SECRET_KEY"), algorithm="HS256"
)
except Exception:
logger.exception("Failed to encode auth token")
Expand All @@ -33,51 +31,58 @@ def encode_auth_token(user_id, is_dm):

def decode_auth_token(auth_token):
try:
payload = jwt.decode(auth_token, current_app.config.get('SECRET_KEY'), algorithms=['HS256'])
payload = jwt.decode(
auth_token,
current_app.config.get("SECRET_KEY"),
algorithms=["HS256"],
)
return payload
except jwt.ExpiredSignatureError:
logger.warning("Token expired")
abort(403, description='Signature expired. Please log in again.')
abort(403, description="Signature expired. Please log in again.")
except jwt.InvalidTokenError:
logger.warning("Invalid token")
abort(403, description='Invalid token. Please log in again.')
abort(403, description="Invalid token. Please log in again.")


def token_required(dm_required=False):
def decorator(f):
@wraps(f)
def decorated_function(*args, **kwargs):
auth_header = request.headers.get('Authorization', None)
auth_header = request.headers.get("Authorization", None)
if auth_header is None:
logger.warning("Authorization header is missing")
abort(403, description='Authorization header is missing!')
abort(403, description="Authorization header is missing!")

try:
auth_type, token = auth_header.split()
if auth_type.lower() != 'bearer':
if auth_type.lower() != "bearer":
logger.warning("Invalid token type: %s", auth_type)
abort(403, description='Invalid token type. Expected Bearer token')
abort(
403,
description="Invalid token type. Expected Bearer token",
)
except ValueError:
logger.warning("Invalid Authorization header format")
abort(403, description='Invalid Authorization header format')
abort(403, description="Invalid Authorization header format")

if not token:
logger.warning("Token is missing")
abort(403, description='Token is missing!')
abort(403, description="Token is missing!")

try:
payload = decode_auth_token(token)
user_id = payload['sub']
user_id = payload["sub"]
current_user = User.objects(id=ObjectId(user_id)).first()
kwargs['current_user'] = current_user
kwargs["current_user"] = current_user

if current_user is None:
logger.warning("User not found")
abort(403, description='User not found!')
abort(403, description="User not found!")

if dm_required and not payload.get('is_dm', False):
if dm_required and not payload.get("is_dm", False):
logger.warning("DM required but not provided in token")
abort(403, description='DM required!')
abort(403, description="DM required!")

except Exception as e:
logger.exception("Token validation error")
Expand Down
28 changes: 19 additions & 9 deletions app/utils/crud_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@ def get_document(document_class, doc_id):
try:
document = document_class.objects(id=ObjectId(doc_id)).first()
if not document:
return jsonify({'message': f'{document_class.__name__} not found!'}), 404
return (
jsonify({"message": f"{document_class.__name__} not found!"}),
404,
)
return jsonify(document.to_mongo().to_dict()), 200
except Exception as e:
return jsonify({'message': str(e)}), 400
return jsonify({"message": str(e)}), 400


def create_document(document_class, data):
Expand All @@ -18,19 +21,19 @@ def create_document(document_class, data):
document.save()
return jsonify(document.to_mongo().to_dict()), 201
except Exception as e:
return jsonify({'message': str(e)}), 400
return jsonify({"message": str(e)}), 400


def update_document(document, data):
try:
for key in ['items', 'rooms', 'encounters']:
for key in ["items", "rooms", "encounters"]:
if key in data.keys():
data.pop(key)
document.update(**data)
document.reload() # Reload to get updated document
return jsonify(document.to_mongo().to_dict()), 200
except Exception as e:
return jsonify({'message': str(e)}), 400
return jsonify({"message": str(e)}), 400


def modify_document(document, data):
Expand All @@ -39,20 +42,27 @@ def modify_document(document, data):
document.reload()
return jsonify(document.to_mongo().to_dict()), 200
except Exception as e:
return jsonify({'message': str(e)}), 400
return jsonify({"message": str(e)}), 400


def delete_document(document):
try:
document.delete()
return jsonify({'message': f'{document.__class__.__name__} deleted successfully!'}), 200
return (
jsonify(
{
"message": f"{document.__class__.__name__} deleted successfully!"
}
),
200,
)
except Exception as e:
return jsonify({'message': str(e)}), 400
return jsonify({"message": str(e)}), 400


def get_all_documents(document_class):
try:
documents = document_class.objects()
return jsonify([doc.to_mongo().to_dict() for doc in documents]), 200
except Exception as e:
return jsonify({'message': str(e)}), 400
return jsonify({"message": str(e)}), 400
Loading
Loading