improved structure + error handling
This commit is contained in:
parent
f2a0b836e6
commit
e2328771e6
14 changed files with 221 additions and 251 deletions
16
app.py
16
app.py
|
@ -5,6 +5,9 @@ from routes.userRoutes import userRoutes
|
||||||
from routes.eventRoutes import eventRoutes
|
from routes.eventRoutes import eventRoutes
|
||||||
import config
|
import config
|
||||||
from flask_jwt_extended import JWTManager
|
from flask_jwt_extended import JWTManager
|
||||||
|
from middelwares.errorHandlers import handle_auth_error, handle_invalid_token
|
||||||
|
from flask_jwt_extended.exceptions import NoAuthorizationError
|
||||||
|
from jwt.exceptions import InvalidTokenError
|
||||||
|
|
||||||
class App:
|
class App:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -13,6 +16,7 @@ class App:
|
||||||
self.set_up_db()
|
self.set_up_db()
|
||||||
self.set_up_jwt()
|
self.set_up_jwt()
|
||||||
self.register_blueprints()
|
self.register_blueprints()
|
||||||
|
self.setup_error_handlers()
|
||||||
|
|
||||||
def set_config(self):
|
def set_config(self):
|
||||||
self.app.config.from_object(config.Config)
|
self.app.config.from_object(config.Config)
|
||||||
|
@ -21,6 +25,10 @@ class App:
|
||||||
db.init_app(self.app)
|
db.init_app(self.app)
|
||||||
self.migrate = Migrate(self.app, db)
|
self.migrate = Migrate(self.app, db)
|
||||||
|
|
||||||
|
def setup_error_handlers(self):
|
||||||
|
self.app.register_error_handler(NoAuthorizationError, handle_auth_error)
|
||||||
|
self.app.register_error_handler(InvalidTokenError, handle_invalid_token)
|
||||||
|
|
||||||
def set_up_jwt(self):
|
def set_up_jwt(self):
|
||||||
self.jwt_manager = JWTManager(self.app)
|
self.jwt_manager = JWTManager(self.app)
|
||||||
self.app.config['JWT_TOKEN_LOCATION'] = ['cookies']
|
self.app.config['JWT_TOKEN_LOCATION'] = ['cookies']
|
||||||
|
@ -43,7 +51,9 @@ class App:
|
||||||
function_name = self.app.view_functions[rule.endpoint].__name__
|
function_name = self.app.view_functions[rule.endpoint].__name__
|
||||||
print(f" Function: {function_name}")
|
print(f" Function: {function_name}")
|
||||||
|
|
||||||
|
|
||||||
|
app_class_instance = App()
|
||||||
|
app_instance = app_class_instance.app
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
app_instance = App()
|
app_class_instance.run()
|
||||||
app_instance.print_endpoints()
|
|
||||||
app_instance.run()
|
|
||||||
|
|
11
middelwares/errorHandlers.py
Normal file
11
middelwares/errorHandlers.py
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
from functools import wraps
|
||||||
|
from flask import request, jsonify
|
||||||
|
|
||||||
|
def handle_auth_error(e):
|
||||||
|
return jsonify({"error": "Please login"}), 401
|
||||||
|
|
||||||
|
def handle_invalid_token(e):
|
||||||
|
return jsonify({"error": "Invalid session token"}), 401
|
||||||
|
|
||||||
|
def handle_invalid_header_error(e):
|
||||||
|
return jsonify({"error": "Please login again"}), 401
|
36
middelwares/eventMiddelwares.py
Normal file
36
middelwares/eventMiddelwares.py
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
from functools import wraps
|
||||||
|
from flask import request, jsonify
|
||||||
|
from datetime import datetime
|
||||||
|
from flask_jwt_extended import jwt_required, get_jwt_identity
|
||||||
|
|
||||||
|
def validate_event_post_request(f):
|
||||||
|
@wraps(f)
|
||||||
|
def decorated_function(*args, **kwargs):
|
||||||
|
data = request.get_json()
|
||||||
|
if not data:
|
||||||
|
return jsonify({"message": "No input data provided"}), 400
|
||||||
|
|
||||||
|
# Check required fields
|
||||||
|
required_fields = ['title', 'duedate', 'location', 'description']
|
||||||
|
if not all(field in data for field in required_fields):
|
||||||
|
return jsonify({"message": "Please check your data, you missing some props; visit our docs https://git.dayanhub.com/kfir"}), 400
|
||||||
|
|
||||||
|
# Validate 'title'
|
||||||
|
if not isinstance(data['title'], str) or not data['title'].strip():
|
||||||
|
return jsonify({"message": "Invalid title"}), 400
|
||||||
|
|
||||||
|
# Validate 'description'
|
||||||
|
if not isinstance(data['description'], str):
|
||||||
|
return jsonify({"message": "Invalid description"}), 400
|
||||||
|
# Validate 'time' (ensure it's a valid datetime string)
|
||||||
|
try:
|
||||||
|
datetime.strptime(data['duedate'], '%Y-%m-%dT%H:%M:%S')
|
||||||
|
except ValueError:
|
||||||
|
return jsonify({"message": "Invalid time format. Use YYYY-MM-DDTHH:MM:SS"}), 400
|
||||||
|
|
||||||
|
# Validate 'location'
|
||||||
|
if not isinstance(data['location'], str) or not data['location'].strip():
|
||||||
|
return jsonify({"message": "Invalid location"}), 400
|
||||||
|
|
||||||
|
return f(*args, **kwargs)
|
||||||
|
return decorated_function
|
73
middelwares/userMiddelwares.py
Normal file
73
middelwares/userMiddelwares.py
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
from functools import wraps
|
||||||
|
from flask import request, jsonify, g
|
||||||
|
from flask_jwt_extended import jwt_required, get_jwt_identity
|
||||||
|
|
||||||
|
def validate_user_post_request(f):
|
||||||
|
@wraps(f)
|
||||||
|
def decorated_function(*args, **kwargs):
|
||||||
|
data = request.get_json()
|
||||||
|
if not data:
|
||||||
|
return jsonify({"message": "No input data provided"}), 400
|
||||||
|
|
||||||
|
# Check required fields
|
||||||
|
required_fields = ['username', 'password', 'email', 'location']
|
||||||
|
if not all(field in data for field in required_fields):
|
||||||
|
return jsonify({"message": "Please check your data, you missing some props; visit our docs https://git.dayanhub.com/kfir"}), 400
|
||||||
|
|
||||||
|
# Validate 'username'
|
||||||
|
if not isinstance(data['username'], str) or not data['username'].strip():
|
||||||
|
return jsonify({"message": "Invalid username"}), 400
|
||||||
|
|
||||||
|
# Validate 'password'
|
||||||
|
if not isinstance(data['password'], str) or not data['password'].strip():
|
||||||
|
return jsonify({"message": "Invalid password"}), 400
|
||||||
|
|
||||||
|
# Validate 'email'
|
||||||
|
if not isinstance(data['email'], str) or not data['email'].strip():
|
||||||
|
return jsonify({"message": "Invalid email"}), 400
|
||||||
|
|
||||||
|
# Validate 'location'
|
||||||
|
if not isinstance(data['location'], str) or not data['location'].strip():
|
||||||
|
return jsonify({"message": "Invalid location"}), 400
|
||||||
|
|
||||||
|
return f(*args, **kwargs)
|
||||||
|
return decorated_function
|
||||||
|
|
||||||
|
|
||||||
|
def validate_user_login_request(f):
|
||||||
|
@wraps(f)
|
||||||
|
def decorated_function(*args, **kwargs):
|
||||||
|
data = request.get_json()
|
||||||
|
if not data:
|
||||||
|
return jsonify({"message": "No input data provided"}), 400
|
||||||
|
|
||||||
|
# Check required fields
|
||||||
|
required_fields = ['email', 'password']
|
||||||
|
if not all(field in data for field in required_fields):
|
||||||
|
return jsonify({"message": "Please check your data, you missing some props; visit our docs https://git.dayanhub.com/kfir"}), 400
|
||||||
|
|
||||||
|
# Validate 'email'
|
||||||
|
if not isinstance(data['email'], str) or not data['email'].strip():
|
||||||
|
return jsonify({"message": "Invalid email"}), 400
|
||||||
|
|
||||||
|
# Validate 'password'
|
||||||
|
if not isinstance(data['password'], str) or not data['password'].strip():
|
||||||
|
return jsonify({"message": "Invalid password"}), 400
|
||||||
|
|
||||||
|
return f(*args, **kwargs)
|
||||||
|
return decorated_function
|
||||||
|
|
||||||
|
def authenticate_user(f):
|
||||||
|
@wraps(f)
|
||||||
|
@jwt_required(locations=["cookies"]) # Specify to look for the token in cookies
|
||||||
|
def decorated_function(*args, **kwargs):
|
||||||
|
# Get user identity from JWT
|
||||||
|
user_id = get_jwt_identity()
|
||||||
|
if user_id:
|
||||||
|
g.user_id = user_id
|
||||||
|
else:
|
||||||
|
return jsonify({"error": "Invalid session token"}), 401
|
||||||
|
|
||||||
|
return f(*args, **kwargs)
|
||||||
|
return decorated_function
|
||||||
|
|
107
middlewares.py
107
middlewares.py
|
@ -1,107 +0,0 @@
|
||||||
from functools import wraps
|
|
||||||
from flask import request, jsonify
|
|
||||||
from datetime import datetime
|
|
||||||
from flask_jwt_extended import jwt_required, get_jwt_identity
|
|
||||||
|
|
||||||
|
|
||||||
def validate_user_post_request(f):
|
|
||||||
@wraps(f)
|
|
||||||
def decorated_function(*args, **kwargs):
|
|
||||||
data = request.get_json()
|
|
||||||
if not data:
|
|
||||||
return jsonify({"message": "No input data provided"}), 400
|
|
||||||
|
|
||||||
# Check required fields
|
|
||||||
required_fields = ['username', 'password', 'email', 'location']
|
|
||||||
if not all(field in data for field in required_fields):
|
|
||||||
return jsonify({"message": "Please check your data, you missing some props; visit our docs https://git.dayanhub.com/kfir"}), 400
|
|
||||||
|
|
||||||
# Validate 'username'
|
|
||||||
if not isinstance(data['username'], str) or not data['username'].strip():
|
|
||||||
return jsonify({"message": "Invalid username"}), 400
|
|
||||||
|
|
||||||
# Validate 'password'
|
|
||||||
if not isinstance(data['password'], str) or not data['password'].strip():
|
|
||||||
return jsonify({"message": "Invalid password"}), 400
|
|
||||||
|
|
||||||
# Validate 'email'
|
|
||||||
if not isinstance(data['email'], str) or not data['email'].strip():
|
|
||||||
return jsonify({"message": "Invalid email"}), 400
|
|
||||||
|
|
||||||
# Validate 'location'
|
|
||||||
if not isinstance(data['location'], str) or not data['location'].strip():
|
|
||||||
return jsonify({"message": "Invalid location"}), 400
|
|
||||||
|
|
||||||
return f(*args, **kwargs)
|
|
||||||
return decorated_function
|
|
||||||
|
|
||||||
|
|
||||||
def validate_user_login_request(f):
|
|
||||||
@wraps(f)
|
|
||||||
def decorated_function(*args, **kwargs):
|
|
||||||
data = request.get_json()
|
|
||||||
if not data:
|
|
||||||
return jsonify({"message": "No input data provided"}), 400
|
|
||||||
|
|
||||||
# Check required fields
|
|
||||||
required_fields = ['email', 'password']
|
|
||||||
if not all(field in data for field in required_fields):
|
|
||||||
return jsonify({"message": "Please check your data, you missing some props; visit our docs https://git.dayanhub.com/kfir"}), 400
|
|
||||||
|
|
||||||
# Validate 'email'
|
|
||||||
if not isinstance(data['email'], str) or not data['email'].strip():
|
|
||||||
return jsonify({"message": "Invalid email"}), 400
|
|
||||||
|
|
||||||
# Validate 'password'
|
|
||||||
if not isinstance(data['password'], str) or not data['password'].strip():
|
|
||||||
return jsonify({"message": "Invalid password"}), 400
|
|
||||||
|
|
||||||
return f(*args, **kwargs)
|
|
||||||
return decorated_function
|
|
||||||
|
|
||||||
def validate_event_post_request(f):
|
|
||||||
@wraps(f)
|
|
||||||
def decorated_function(*args, **kwargs):
|
|
||||||
data = request.get_json()
|
|
||||||
if not data:
|
|
||||||
return jsonify({"message": "No input data provided"}), 400
|
|
||||||
|
|
||||||
# Check required fields
|
|
||||||
required_fields = ['title', 'duedate', 'location', 'description']
|
|
||||||
if not all(field in data for field in required_fields):
|
|
||||||
return jsonify({"message": "Please check your data, you missing some props; visit our docs https://git.dayanhub.com/kfir"}), 400
|
|
||||||
|
|
||||||
# Validate 'title'
|
|
||||||
if not isinstance(data['title'], str) or not data['title'].strip():
|
|
||||||
return jsonify({"message": "Invalid title"}), 400
|
|
||||||
|
|
||||||
# Validate 'description'
|
|
||||||
if not isinstance(data['description'], str):
|
|
||||||
return jsonify({"message": "Invalid description"}), 400
|
|
||||||
|
|
||||||
# Validate 'time' (ensure it's a valid datetime string)
|
|
||||||
try:
|
|
||||||
datetime.strptime(data['duedate'], '%Y-%m-%dT%H:%M:%S')
|
|
||||||
except ValueError:
|
|
||||||
return jsonify({"message": "Invalid time format. Use YYYY-MM-DDTHH:MM:SS"}), 400
|
|
||||||
|
|
||||||
# Validate 'location'
|
|
||||||
if not isinstance(data['location'], str) or not data['location'].strip():
|
|
||||||
return jsonify({"message": "Invalid location"}), 400
|
|
||||||
|
|
||||||
return f(*args, **kwargs)
|
|
||||||
return decorated_function
|
|
||||||
|
|
||||||
def authenticate_user(f):
|
|
||||||
@wraps(f)
|
|
||||||
@jwt_required(locations=["cookies"]) # Specify to look for the token in cookies
|
|
||||||
def decorated_function(*args, **kwargs):
|
|
||||||
# Get user identity from JWT
|
|
||||||
user_id = get_jwt_identity()
|
|
||||||
if user_id:
|
|
||||||
request.user_id = user_id
|
|
||||||
else:
|
|
||||||
return jsonify({"error": "Invalid session token"}), 401
|
|
||||||
|
|
||||||
return f(*args, **kwargs)
|
|
||||||
return decorated_function
|
|
|
@ -1,42 +0,0 @@
|
||||||
"""initial migration
|
|
||||||
|
|
||||||
Revision ID: 5569d39a87cf
|
|
||||||
Revises:
|
|
||||||
Create Date: 2024-01-04 13:44:40.811421
|
|
||||||
|
|
||||||
"""
|
|
||||||
from alembic import op
|
|
||||||
import sqlalchemy as sa
|
|
||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
|
||||||
revision = '5569d39a87cf'
|
|
||||||
down_revision = None
|
|
||||||
branch_labels = None
|
|
||||||
depends_on = None
|
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
|
||||||
with op.batch_alter_table('event', schema=None) as batch_op:
|
|
||||||
batch_op.add_column(sa.Column('title', sa.String(length=100), nullable=False))
|
|
||||||
batch_op.add_column(sa.Column('description', sa.String(length=200), nullable=True))
|
|
||||||
batch_op.add_column(sa.Column('location', sa.String(length=100), nullable=True))
|
|
||||||
batch_op.add_column(sa.Column('deleted', sa.Boolean(), nullable=True))
|
|
||||||
batch_op.add_column(sa.Column('duedate', sa.DateTime(), nullable=True))
|
|
||||||
batch_op.add_column(sa.Column('created_at', sa.DateTime(), nullable=True))
|
|
||||||
|
|
||||||
# ### end Alembic commands ###
|
|
||||||
|
|
||||||
|
|
||||||
def downgrade():
|
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
|
||||||
with op.batch_alter_table('event', schema=None) as batch_op:
|
|
||||||
batch_op.drop_column('created_at')
|
|
||||||
batch_op.drop_column('duedate')
|
|
||||||
batch_op.drop_column('deleted')
|
|
||||||
batch_op.drop_column('location')
|
|
||||||
batch_op.drop_column('description')
|
|
||||||
batch_op.drop_column('title')
|
|
||||||
|
|
||||||
# ### end Alembic commands ###
|
|
|
@ -1,46 +0,0 @@
|
||||||
"""empty message
|
|
||||||
|
|
||||||
Revision ID: 9d6b0ea04d2c
|
|
||||||
Revises: 5569d39a87cf
|
|
||||||
Create Date: 2024-01-07 11:34:58.903280
|
|
||||||
|
|
||||||
"""
|
|
||||||
from alembic import op
|
|
||||||
import sqlalchemy as sa
|
|
||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
|
||||||
revision = '9d6b0ea04d2c'
|
|
||||||
down_revision = '5569d39a87cf'
|
|
||||||
branch_labels = None
|
|
||||||
depends_on = None
|
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
|
||||||
with op.batch_alter_table('user', schema=None) as batch_op:
|
|
||||||
batch_op.add_column(sa.Column('name', sa.String(length=100), nullable=True))
|
|
||||||
batch_op.add_column(sa.Column('email', sa.String(length=120), nullable=False))
|
|
||||||
batch_op.add_column(sa.Column('location', sa.String(length=100), nullable=True))
|
|
||||||
batch_op.alter_column('id',
|
|
||||||
existing_type=sa.INTEGER(),
|
|
||||||
type_=sa.String(length=36),
|
|
||||||
existing_nullable=False)
|
|
||||||
batch_op.create_unique_constraint('uq_user_email', ['email']) # Added constraint name here
|
|
||||||
batch_op.drop_column('username')
|
|
||||||
# ### end Alembic commands ###
|
|
||||||
|
|
||||||
def downgrade():
|
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
|
||||||
with op.batch_alter_table('user', schema=None) as batch_op:
|
|
||||||
batch_op.add_column(sa.Column('username', sa.VARCHAR(length=80), nullable=False))
|
|
||||||
batch_op.drop_constraint('uq_user_email', type_='unique') # Updated constraint name here
|
|
||||||
batch_op.alter_column('id',
|
|
||||||
existing_type=sa.String(length=36),
|
|
||||||
type_=sa.INTEGER(),
|
|
||||||
existing_nullable=False)
|
|
||||||
batch_op.drop_column('location')
|
|
||||||
batch_op.drop_column('email')
|
|
||||||
batch_op.drop_column('name')
|
|
||||||
# ### end Alembic commands ###
|
|
||||||
|
|
|
@ -1,36 +0,0 @@
|
||||||
"""empty message
|
|
||||||
|
|
||||||
Revision ID: b962126d3578
|
|
||||||
Revises: 9d6b0ea04d2c
|
|
||||||
Create Date: 2024-01-07 11:41:03.752411
|
|
||||||
|
|
||||||
"""
|
|
||||||
from alembic import op
|
|
||||||
import sqlalchemy as sa
|
|
||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
|
||||||
revision = 'b962126d3578'
|
|
||||||
down_revision = '9d6b0ea04d2c'
|
|
||||||
branch_labels = None
|
|
||||||
depends_on = None
|
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
|
||||||
with op.batch_alter_table('user', schema=None) as batch_op:
|
|
||||||
batch_op.alter_column('location',
|
|
||||||
existing_type=sa.VARCHAR(length=100),
|
|
||||||
nullable=False)
|
|
||||||
|
|
||||||
# ### end Alembic commands ###
|
|
||||||
|
|
||||||
|
|
||||||
def downgrade():
|
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
|
||||||
with op.batch_alter_table('user', schema=None) as batch_op:
|
|
||||||
batch_op.alter_column('location',
|
|
||||||
existing_type=sa.VARCHAR(length=100),
|
|
||||||
nullable=True)
|
|
||||||
|
|
||||||
# ### end Alembic commands ###
|
|
49
migrations/versions/bb3a88007475_initial_migration.py
Normal file
49
migrations/versions/bb3a88007475_initial_migration.py
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
"""initial migration
|
||||||
|
|
||||||
|
Revision ID: bb3a88007475
|
||||||
|
Revises:
|
||||||
|
Create Date: 2024-01-07 14:12:47.164418
|
||||||
|
|
||||||
|
"""
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = 'bb3a88007475'
|
||||||
|
down_revision = None
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.create_table('user',
|
||||||
|
sa.Column('id', sa.String(length=36), nullable=False),
|
||||||
|
sa.Column('name', sa.String(length=100), nullable=True),
|
||||||
|
sa.Column('email', sa.String(length=120), nullable=False),
|
||||||
|
sa.Column('password_hash', sa.String(length=128), nullable=True),
|
||||||
|
sa.Column('location', sa.String(length=100), nullable=False),
|
||||||
|
sa.PrimaryKeyConstraint('id'),
|
||||||
|
sa.UniqueConstraint('email')
|
||||||
|
)
|
||||||
|
op.create_table('event',
|
||||||
|
sa.Column('id', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('title', sa.String(length=100), nullable=False),
|
||||||
|
sa.Column('description', sa.String(length=200), nullable=True),
|
||||||
|
sa.Column('location', sa.String(length=100), nullable=True),
|
||||||
|
sa.Column('deleted', sa.Boolean(), nullable=True),
|
||||||
|
sa.Column('duedate', sa.DateTime(), nullable=True),
|
||||||
|
sa.Column('created_at', sa.DateTime(), nullable=True),
|
||||||
|
sa.Column('user_id', sa.String(length=36), nullable=False),
|
||||||
|
sa.ForeignKeyConstraint(['user_id'], ['user.id'], ),
|
||||||
|
sa.PrimaryKeyConstraint('id')
|
||||||
|
)
|
||||||
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.drop_table('event')
|
||||||
|
op.drop_table('user')
|
||||||
|
# ### end Alembic commands ###
|
|
@ -13,6 +13,7 @@ class Event(db.Model):
|
||||||
deleted = db.Column(db.Boolean, default=False)
|
deleted = db.Column(db.Boolean, default=False)
|
||||||
duedate = db.Column(db.DateTime)
|
duedate = db.Column(db.DateTime)
|
||||||
created_at = db.Column(db.DateTime, default=db.func.now())
|
created_at = db.Column(db.DateTime, default=db.func.now())
|
||||||
|
user_id = db.Column(db.String(36), db.ForeignKey('user.id'), nullable=False)
|
||||||
|
|
||||||
def to_dict(self):
|
def to_dict(self):
|
||||||
return {
|
return {
|
||||||
|
@ -21,7 +22,8 @@ class Event(db.Model):
|
||||||
'description': self.description,
|
'description': self.description,
|
||||||
'location': self.location,
|
'location': self.location,
|
||||||
'duedate': self.duedate.isoformat() if self.duedate else None,
|
'duedate': self.duedate.isoformat() if self.duedate else None,
|
||||||
'created_at': self.created_at.isoformat()
|
'created_at': self.created_at.isoformat(),
|
||||||
|
'user_id': self.user_id
|
||||||
}
|
}
|
||||||
|
|
||||||
class User(db.Model):
|
class User(db.Model):
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
from flask import Blueprint, jsonify, request
|
from flask import Blueprint, jsonify, request, g
|
||||||
from services.EventService import EventService
|
from services.EventService import EventService
|
||||||
from middlewares import validate_event_post_request, authenticate_user
|
from middelwares.userMiddelwares import authenticate_user
|
||||||
|
from middelwares.eventMiddelwares import validate_event_post_request
|
||||||
|
|
||||||
eventRoutes = Blueprint('eventRoutes', __name__)
|
eventRoutes = Blueprint('eventRoutes', __name__)
|
||||||
|
|
||||||
|
@ -12,6 +13,8 @@ eventRoutes = Blueprint('eventRoutes', __name__)
|
||||||
def create_event():
|
def create_event():
|
||||||
try:
|
try:
|
||||||
data = request.json
|
data = request.json
|
||||||
|
data['user_id'] = g.user_id
|
||||||
|
print(data)
|
||||||
new_event = EventService.create_event(data)
|
new_event = EventService.create_event(data)
|
||||||
if new_event:
|
if new_event:
|
||||||
return jsonify(new_event.to_dict()), 201
|
return jsonify(new_event.to_dict()), 201
|
||||||
|
@ -26,7 +29,8 @@ def create_event():
|
||||||
@authenticate_user
|
@authenticate_user
|
||||||
def get_events():
|
def get_events():
|
||||||
try:
|
try:
|
||||||
return {"events": EventService.get_all_events()}, 200
|
user_events = EventService.get_all_user_events(g.user_id)
|
||||||
|
return {"events": user_events, "count": len(user_events)}, 200
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return {"error": str(e)}, 500
|
return {"error": str(e)}, 500
|
||||||
|
|
||||||
|
@ -35,7 +39,7 @@ def get_events():
|
||||||
@authenticate_user
|
@authenticate_user
|
||||||
def get_event(event_id):
|
def get_event(event_id):
|
||||||
try:
|
try:
|
||||||
return {"event": EventService.get_event_by_id(event_id)}, 200
|
return {"event": EventService.get_event_by_id(event_id, g.user_id)}, 200
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return {"error": str(e)}, 500
|
return {"error": str(e)}, 500
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
from flask import Blueprint, jsonify, request
|
from flask import Blueprint, jsonify, request
|
||||||
from services.UserService import UserService
|
from services.UserService import UserService
|
||||||
from flask_jwt_extended import JWTManager, jwt_required, create_access_token, get_jwt_identity
|
from flask_jwt_extended import JWTManager, jwt_required, create_access_token, get_jwt_identity
|
||||||
from middlewares import validate_user_post_request, validate_user_login_request, authenticate_user
|
from middelwares.userMiddelwares import validate_user_post_request, validate_user_login_request
|
||||||
|
from middelwares.eventMiddelwares import validate_event_post_request
|
||||||
|
|
||||||
userRoutes = Blueprint('userRoutes', __name__)
|
userRoutes = Blueprint('userRoutes', __name__)
|
||||||
|
|
||||||
|
|
||||||
@userRoutes.route('/', methods=['GET'])
|
@userRoutes.route('/', methods=['GET'])
|
||||||
@userRoutes.route('', methods=['GET'])
|
@userRoutes.route('', methods=['GET'])
|
||||||
@authenticate_user
|
|
||||||
def allUsers():
|
def allUsers():
|
||||||
users = UserService.get_all_users()
|
users = UserService.get_all_users()
|
||||||
return jsonify(users), 200
|
return jsonify(users), 200
|
||||||
|
@ -36,9 +36,10 @@ def loginUser():
|
||||||
data = request.json
|
data = request.json
|
||||||
user = UserService.verify_user(data)
|
user = UserService.verify_user(data)
|
||||||
if user:
|
if user:
|
||||||
sessionToken = create_access_token(identity=user.id)
|
token = login(user)
|
||||||
response = jsonify(user.to_dict())
|
response = user.to_dict()
|
||||||
response.set_cookie('access_token_cookie', sessionToken, httponly=True, path='/')
|
response['token'] = token
|
||||||
|
response = jsonify(response)
|
||||||
return response, 200
|
return response, 200
|
||||||
else:
|
else:
|
||||||
return jsonify({'error': 'Invalid credentials'}), 400
|
return jsonify({'error': 'Invalid credentials'}), 400
|
||||||
|
@ -55,3 +56,8 @@ def logoutUser():
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return jsonify({'error': str(e)}), 500
|
return jsonify({'error': str(e)}), 500
|
||||||
|
|
||||||
|
def login(user):
|
||||||
|
sessionToken = create_access_token(identity=user.id)
|
||||||
|
response = jsonify(user.to_dict())
|
||||||
|
response.set_cookie('access_token_cookie', sessionToken, httponly=True, path='/')
|
||||||
|
return sessionToken
|
|
@ -4,24 +4,34 @@ from datetime import datetime
|
||||||
class EventService:
|
class EventService:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def create_event(data):
|
def create_event(data):
|
||||||
|
print("#########")
|
||||||
|
print(data)
|
||||||
new_event = Event(
|
new_event = Event(
|
||||||
title=data['title'],
|
title=data['title'],
|
||||||
description=data.get('description', ''),
|
description=data.get('description', ''),
|
||||||
location=data.get('location', ''),
|
location=data.get('location', ''),
|
||||||
duedate=datetime.strptime(data['duedate'], '%Y-%m-%dT%H:%M:%S')
|
duedate=datetime.strptime(data['duedate'], '%Y-%m-%dT%H:%M:%S'),
|
||||||
|
user_id=data['user_id']
|
||||||
)
|
)
|
||||||
db.session.add(new_event)
|
db.session.add(new_event)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
return new_event
|
return new_event
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_all_events():
|
def get_all_user_events(user_id):
|
||||||
events=Event.query.filter_by(deleted=False).all()
|
events=Event.query.filter_by(user_id=user_id, deleted=False).all()
|
||||||
return [event.to_dict() for event in events]
|
if(events):
|
||||||
|
return [event.to_dict() for event in events]
|
||||||
|
else:
|
||||||
|
return []
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_event_by_id(event_id):
|
def get_event_by_id(event_id, user_id):
|
||||||
return Event.query.filter_by(id=event_id, deleted=False).first().to_dict()
|
event = Event.query.filter_by(id=event_id,user_id=user_id, deleted=False).first()
|
||||||
|
if(event):
|
||||||
|
return event.to_dict()
|
||||||
|
else:
|
||||||
|
return []
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def update_event(event_id, data):
|
def update_event(event_id, data):
|
||||||
|
|
|
@ -14,7 +14,7 @@ class UserService:
|
||||||
)
|
)
|
||||||
db.session.add(new_user)
|
db.session.add(new_user)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
return new_user
|
return new_user.to_dict()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_all_users():
|
def get_all_users():
|
||||||
|
|
Loading…
Reference in a new issue