Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
M
MBetterd
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Mbetter
MBetterd
Commits
4f9f12bc
Commit
4f9f12bc
authored
Sep 27, 2025
by
Stefy Lanza (nextime / spora )
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add csrf extempts
parent
855f0860
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
54 additions
and
4 deletions
+54
-4
routes.py
app/auth/routes.py
+11
-1
routes.py
app/main/routes.py
+36
-1
routes.py
app/upload/routes.py
+7
-2
No files found.
app/auth/routes.py
View file @
4f9f12bc
...
@@ -5,13 +5,14 @@ from flask_login import login_user, logout_user, login_required, current_user
...
@@ -5,13 +5,14 @@ from flask_login import login_user, logout_user, login_required, current_user
from
flask_jwt_extended
import
create_access_token
,
jwt_required
,
get_jwt_identity
,
get_jwt
from
flask_jwt_extended
import
create_access_token
,
jwt_required
,
get_jwt_identity
,
get_jwt
from
werkzeug.security
import
check_password_hash
from
werkzeug.security
import
check_password_hash
from
app.auth
import
bp
from
app.auth
import
bp
from
app
import
db
from
app
import
db
,
csrf
from
app.auth.forms
import
LoginForm
,
RegistrationForm
from
app.auth.forms
import
LoginForm
,
RegistrationForm
from
app.utils.security
import
validate_password_strength
,
generate_secure_token
,
rate_limit_check
from
app.utils.security
import
validate_password_strength
,
generate_secure_token
,
rate_limit_check
from
app.utils.logging
import
log_security_event
from
app.utils.logging
import
log_security_event
logger
=
logging
.
getLogger
(
__name__
)
logger
=
logging
.
getLogger
(
__name__
)
@
csrf
.
exempt
@
bp
.
route
(
'/login'
,
methods
=
[
'GET'
,
'POST'
])
@
bp
.
route
(
'/login'
,
methods
=
[
'GET'
,
'POST'
])
def
login
():
def
login
():
"""User login endpoint"""
"""User login endpoint"""
...
@@ -67,6 +68,7 @@ def login():
...
@@ -67,6 +68,7 @@ def login():
return
render_template
(
'auth/login.html'
,
form
=
form
)
return
render_template
(
'auth/login.html'
,
form
=
form
)
@
csrf
.
exempt
@
bp
.
route
(
'/logout'
)
@
bp
.
route
(
'/logout'
)
@
login_required
@
login_required
def
logout
():
def
logout
():
...
@@ -87,6 +89,7 @@ def logout():
...
@@ -87,6 +89,7 @@ def logout():
flash
(
'You have been logged out successfully.'
,
'info'
)
flash
(
'You have been logged out successfully.'
,
'info'
)
return
redirect
(
url_for
(
'auth.login'
))
return
redirect
(
url_for
(
'auth.login'
))
@
csrf
.
exempt
@
bp
.
route
(
'/register'
,
methods
=
[
'GET'
,
'POST'
])
@
bp
.
route
(
'/register'
,
methods
=
[
'GET'
,
'POST'
])
def
register
():
def
register
():
"""User registration endpoint (disabled by default, configurable by admin)"""
"""User registration endpoint (disabled by default, configurable by admin)"""
...
@@ -143,6 +146,7 @@ def register():
...
@@ -143,6 +146,7 @@ def register():
return
render_template
(
'auth/register.html'
,
form
=
form
)
return
render_template
(
'auth/register.html'
,
form
=
form
)
@
csrf
.
exempt
@
bp
.
route
(
'/api/login'
,
methods
=
[
'POST'
])
@
bp
.
route
(
'/api/login'
,
methods
=
[
'POST'
])
def
api_login
():
def
api_login
():
"""API login endpoint for JWT authentication"""
"""API login endpoint for JWT authentication"""
...
@@ -199,6 +203,7 @@ def api_login():
...
@@ -199,6 +203,7 @@ def api_login():
logger
.
error
(
f
"API login error: {str(e)}"
)
logger
.
error
(
f
"API login error: {str(e)}"
)
return
jsonify
({
'error'
:
'Internal server error'
}),
500
return
jsonify
({
'error'
:
'Internal server error'
}),
500
@
csrf
.
exempt
@
bp
.
route
(
'/api/logout'
,
methods
=
[
'POST'
])
@
bp
.
route
(
'/api/logout'
,
methods
=
[
'POST'
])
@
jwt_required
()
@
jwt_required
()
def
api_logout
():
def
api_logout
():
...
@@ -228,6 +233,7 @@ def api_logout():
...
@@ -228,6 +233,7 @@ def api_logout():
logger
.
error
(
f
"API logout error: {str(e)}"
)
logger
.
error
(
f
"API logout error: {str(e)}"
)
return
jsonify
({
'error'
:
'Internal server error'
}),
500
return
jsonify
({
'error'
:
'Internal server error'
}),
500
@
csrf
.
exempt
@
bp
.
route
(
'/api/refresh'
,
methods
=
[
'POST'
])
@
bp
.
route
(
'/api/refresh'
,
methods
=
[
'POST'
])
@
jwt_required
()
@
jwt_required
()
def
api_refresh
():
def
api_refresh
():
...
@@ -255,6 +261,7 @@ def api_refresh():
...
@@ -255,6 +261,7 @@ def api_refresh():
logger
.
error
(
f
"Token refresh error: {str(e)}"
)
logger
.
error
(
f
"Token refresh error: {str(e)}"
)
return
jsonify
({
'error'
:
'Internal server error'
}),
500
return
jsonify
({
'error'
:
'Internal server error'
}),
500
@
csrf
.
exempt
@
bp
.
route
(
'/api/profile'
,
methods
=
[
'GET'
])
@
bp
.
route
(
'/api/profile'
,
methods
=
[
'GET'
])
@
jwt_required
()
@
jwt_required
()
def
api_profile
():
def
api_profile
():
...
@@ -273,6 +280,7 @@ def api_profile():
...
@@ -273,6 +280,7 @@ def api_profile():
logger
.
error
(
f
"Profile fetch error: {str(e)}"
)
logger
.
error
(
f
"Profile fetch error: {str(e)}"
)
return
jsonify
({
'error'
:
'Internal server error'
}),
500
return
jsonify
({
'error'
:
'Internal server error'
}),
500
@
csrf
.
exempt
@
bp
.
route
(
'/api/change-password'
,
methods
=
[
'POST'
])
@
bp
.
route
(
'/api/change-password'
,
methods
=
[
'POST'
])
@
jwt_required
()
@
jwt_required
()
def
api_change_password
():
def
api_change_password
():
...
@@ -313,6 +321,7 @@ def api_change_password():
...
@@ -313,6 +321,7 @@ def api_change_password():
logger
.
error
(
f
"Password change error: {str(e)}"
)
logger
.
error
(
f
"Password change error: {str(e)}"
)
return
jsonify
({
'error'
:
'Internal server error'
}),
500
return
jsonify
({
'error'
:
'Internal server error'
}),
500
@
csrf
.
exempt
@
bp
.
route
(
'/api/sessions'
,
methods
=
[
'GET'
])
@
bp
.
route
(
'/api/sessions'
,
methods
=
[
'GET'
])
@
jwt_required
()
@
jwt_required
()
def
api_user_sessions
():
def
api_user_sessions
():
...
@@ -333,6 +342,7 @@ def api_user_sessions():
...
@@ -333,6 +342,7 @@ def api_user_sessions():
logger
.
error
(
f
"Sessions fetch error: {str(e)}"
)
logger
.
error
(
f
"Sessions fetch error: {str(e)}"
)
return
jsonify
({
'error'
:
'Internal server error'
}),
500
return
jsonify
({
'error'
:
'Internal server error'
}),
500
@
csrf
.
exempt
@
bp
.
route
(
'/api/sessions/<session_id>'
,
methods
=
[
'DELETE'
])
@
bp
.
route
(
'/api/sessions/<session_id>'
,
methods
=
[
'DELETE'
])
@
jwt_required
()
@
jwt_required
()
def
api_terminate_session
(
session_id
):
def
api_terminate_session
(
session_id
):
...
...
app/main/routes.py
View file @
4f9f12bc
...
@@ -4,13 +4,14 @@ from datetime import datetime
...
@@ -4,13 +4,14 @@ from datetime import datetime
from
flask
import
render_template
,
request
,
jsonify
,
redirect
,
url_for
,
flash
,
current_app
from
flask
import
render_template
,
request
,
jsonify
,
redirect
,
url_for
,
flash
,
current_app
from
flask_login
import
login_required
,
current_user
from
flask_login
import
login_required
,
current_user
from
app.main
import
bp
from
app.main
import
bp
from
app
import
db
from
app
import
db
,
csrf
from
app.upload.file_handler
import
get_file_upload_handler
from
app.upload.file_handler
import
get_file_upload_handler
from
app.upload.fixture_parser
import
get_fixture_parser
from
app.upload.fixture_parser
import
get_fixture_parser
from
app.utils.security
import
require_admin
,
require_active_user
from
app.utils.security
import
require_admin
,
require_active_user
logger
=
logging
.
getLogger
(
__name__
)
logger
=
logging
.
getLogger
(
__name__
)
@
csrf
.
exempt
@
bp
.
route
(
'/'
)
@
bp
.
route
(
'/'
)
def
index
():
def
index
():
"""Home page"""
"""Home page"""
...
@@ -40,6 +41,7 @@ def index():
...
@@ -40,6 +41,7 @@ def index():
return
redirect
(
url_for
(
'main.dashboard'
))
return
redirect
(
url_for
(
'main.dashboard'
))
return
render_template
(
'main/index.html'
)
return
render_template
(
'main/index.html'
)
@
csrf
.
exempt
@
bp
.
route
(
'/dashboard'
)
@
bp
.
route
(
'/dashboard'
)
@
login_required
@
login_required
@
require_active_user
@
require_active_user
...
@@ -94,6 +96,7 @@ def dashboard():
...
@@ -94,6 +96,7 @@ def dashboard():
flash
(
'Error loading dashboard'
,
'error'
)
flash
(
'Error loading dashboard'
,
'error'
)
return
render_template
(
'main/dashboard.html'
)
return
render_template
(
'main/dashboard.html'
)
@
csrf
.
exempt
@
bp
.
route
(
'/fixtures'
)
@
bp
.
route
(
'/fixtures'
)
@
login_required
@
login_required
@
require_active_user
@
require_active_user
...
@@ -181,6 +184,7 @@ def fixtures():
...
@@ -181,6 +184,7 @@ def fixtures():
return
render_template
(
'main/matches.html'
,
fixtures
=
[],
pagination
=
None
)
return
render_template
(
'main/matches.html'
,
fixtures
=
[],
pagination
=
None
)
# Keep the old /matches route for backward compatibility
# Keep the old /matches route for backward compatibility
@
csrf
.
exempt
@
bp
.
route
(
'/matches'
)
@
bp
.
route
(
'/matches'
)
@
login_required
@
login_required
@
require_active_user
@
require_active_user
...
@@ -188,6 +192,7 @@ def matches():
...
@@ -188,6 +192,7 @@ def matches():
"""Redirect to fixtures for backward compatibility"""
"""Redirect to fixtures for backward compatibility"""
return
redirect
(
url_for
(
'main.fixtures'
))
return
redirect
(
url_for
(
'main.fixtures'
))
@
csrf
.
exempt
@
bp
.
route
(
'/fixture/<fixture_id>'
)
@
bp
.
route
(
'/fixture/<fixture_id>'
)
@
login_required
@
login_required
@
require_active_user
@
require_active_user
...
@@ -230,6 +235,7 @@ def fixture_detail(fixture_id):
...
@@ -230,6 +235,7 @@ def fixture_detail(fixture_id):
flash
(
'Error loading fixture details'
,
'error'
)
flash
(
'Error loading fixture details'
,
'error'
)
return
redirect
(
url_for
(
'main.matches'
))
return
redirect
(
url_for
(
'main.matches'
))
@
csrf
.
exempt
@
bp
.
route
(
'/fixture/<fixture_id>/delete'
,
methods
=
[
'POST'
])
@
bp
.
route
(
'/fixture/<fixture_id>/delete'
,
methods
=
[
'POST'
])
@
login_required
@
login_required
@
require_active_user
@
require_active_user
...
@@ -290,6 +296,7 @@ def delete_fixture(fixture_id):
...
@@ -290,6 +296,7 @@ def delete_fixture(fixture_id):
flash
(
'Error deleting fixture'
,
'error'
)
flash
(
'Error deleting fixture'
,
'error'
)
return
redirect
(
url_for
(
'main.matches'
))
return
redirect
(
url_for
(
'main.matches'
))
@
csrf
.
exempt
@
bp
.
route
(
'/match/<int:id>'
)
@
bp
.
route
(
'/match/<int:id>'
)
@
login_required
@
login_required
@
require_active_user
@
require_active_user
...
@@ -318,6 +325,7 @@ def match_detail(id):
...
@@ -318,6 +325,7 @@ def match_detail(id):
flash
(
'Error loading match details'
,
'error'
)
flash
(
'Error loading match details'
,
'error'
)
return
redirect
(
url_for
(
'main.fixture_detail'
,
fixture_id
=
request
.
args
.
get
(
'fixture_id'
,
''
)))
return
redirect
(
url_for
(
'main.fixture_detail'
,
fixture_id
=
request
.
args
.
get
(
'fixture_id'
,
''
)))
@
csrf
.
exempt
@
bp
.
route
(
'/match/<int:match_id>/outcomes'
,
methods
=
[
'POST'
])
@
bp
.
route
(
'/match/<int:match_id>/outcomes'
,
methods
=
[
'POST'
])
@
login_required
@
login_required
@
require_active_user
@
require_active_user
...
@@ -386,6 +394,7 @@ def update_match_outcomes(match_id):
...
@@ -386,6 +394,7 @@ def update_match_outcomes(match_id):
logger
.
error
(
f
"Update match outcomes error: {str(e)}"
)
logger
.
error
(
f
"Update match outcomes error: {str(e)}"
)
return
jsonify
({
'error'
:
'Failed to update outcomes'
}),
500
return
jsonify
({
'error'
:
'Failed to update outcomes'
}),
500
@
csrf
.
exempt
@
bp
.
route
(
'/match/<int:match_id>/outcomes/<int:outcome_id>'
,
methods
=
[
'DELETE'
])
@
bp
.
route
(
'/match/<int:match_id>/outcomes/<int:outcome_id>'
,
methods
=
[
'DELETE'
])
@
login_required
@
login_required
@
require_active_user
@
require_active_user
...
@@ -424,6 +433,7 @@ def delete_match_outcome(match_id, outcome_id):
...
@@ -424,6 +433,7 @@ def delete_match_outcome(match_id, outcome_id):
logger
.
error
(
f
"Delete match outcome error: {str(e)}"
)
logger
.
error
(
f
"Delete match outcome error: {str(e)}"
)
return
jsonify
({
'error'
:
'Failed to delete outcome'
}),
500
return
jsonify
({
'error'
:
'Failed to delete outcome'
}),
500
@
csrf
.
exempt
@
bp
.
route
(
'/uploads'
)
@
bp
.
route
(
'/uploads'
)
@
login_required
@
login_required
@
require_active_user
@
require_active_user
...
@@ -467,6 +477,7 @@ def uploads():
...
@@ -467,6 +477,7 @@ def uploads():
flash
(
'Error loading uploads'
,
'error'
)
flash
(
'Error loading uploads'
,
'error'
)
return
render_template
(
'main/uploads.html'
,
uploads
=
[],
pagination
=
None
)
return
render_template
(
'main/uploads.html'
,
uploads
=
[],
pagination
=
None
)
@
csrf
.
exempt
@
bp
.
route
(
'/statistics'
)
@
bp
.
route
(
'/statistics'
)
@
login_required
@
login_required
@
require_active_user
@
require_active_user
...
@@ -511,6 +522,7 @@ def statistics():
...
@@ -511,6 +522,7 @@ def statistics():
flash
(
'Error loading statistics'
,
'error'
)
flash
(
'Error loading statistics'
,
'error'
)
return
render_template
(
'main/statistics.html'
)
return
render_template
(
'main/statistics.html'
)
@
csrf
.
exempt
@
bp
.
route
(
'/admin'
)
@
bp
.
route
(
'/admin'
)
@
login_required
@
login_required
@
require_admin
@
require_admin
...
@@ -553,6 +565,7 @@ def admin_panel():
...
@@ -553,6 +565,7 @@ def admin_panel():
flash
(
'Error loading admin panel'
,
'error'
)
flash
(
'Error loading admin panel'
,
'error'
)
return
render_template
(
'main/admin.html'
)
return
render_template
(
'main/admin.html'
)
@
csrf
.
exempt
@
bp
.
route
(
'/admin/users'
)
@
bp
.
route
(
'/admin/users'
)
@
login_required
@
login_required
@
require_admin
@
require_admin
...
@@ -603,6 +616,7 @@ def admin_users():
...
@@ -603,6 +616,7 @@ def admin_users():
flash
(
'Error loading users'
,
'error'
)
flash
(
'Error loading users'
,
'error'
)
return
render_template
(
'main/admin_users.html'
,
users
=
[],
pagination
=
None
)
return
render_template
(
'main/admin_users.html'
,
users
=
[],
pagination
=
None
)
@
csrf
.
exempt
@
bp
.
route
(
'/admin/logs'
)
@
bp
.
route
(
'/admin/logs'
)
@
login_required
@
login_required
@
require_admin
@
require_admin
...
@@ -647,6 +661,7 @@ def admin_logs():
...
@@ -647,6 +661,7 @@ def admin_logs():
flash
(
'Error loading logs'
,
'error'
)
flash
(
'Error loading logs'
,
'error'
)
return
render_template
(
'main/admin_logs.html'
,
logs
=
[],
pagination
=
None
)
return
render_template
(
'main/admin_logs.html'
,
logs
=
[],
pagination
=
None
)
@
csrf
.
exempt
@
bp
.
route
(
'/admin/users/<int:user_id>/edit'
,
methods
=
[
'POST'
])
@
bp
.
route
(
'/admin/users/<int:user_id>/edit'
,
methods
=
[
'POST'
])
@
login_required
@
login_required
@
require_admin
@
require_admin
...
@@ -695,6 +710,7 @@ def admin_edit_user(user_id):
...
@@ -695,6 +710,7 @@ def admin_edit_user(user_id):
logger
.
error
(
f
"Admin edit user error: {str(e)}"
)
logger
.
error
(
f
"Admin edit user error: {str(e)}"
)
return
jsonify
({
'error'
:
'Failed to update user'
}),
500
return
jsonify
({
'error'
:
'Failed to update user'
}),
500
@
csrf
.
exempt
@
bp
.
route
(
'/admin/users/<int:user_id>/delete'
,
methods
=
[
'DELETE'
])
@
bp
.
route
(
'/admin/users/<int:user_id>/delete'
,
methods
=
[
'DELETE'
])
@
login_required
@
login_required
@
require_admin
@
require_admin
...
@@ -719,6 +735,7 @@ def admin_delete_user(user_id):
...
@@ -719,6 +735,7 @@ def admin_delete_user(user_id):
logger
.
error
(
f
"Admin delete user error: {str(e)}"
)
logger
.
error
(
f
"Admin delete user error: {str(e)}"
)
return
jsonify
({
'error'
:
'Failed to delete user'
}),
500
return
jsonify
({
'error'
:
'Failed to delete user'
}),
500
@
csrf
.
exempt
@
bp
.
route
(
'/admin/users/create'
,
methods
=
[
'POST'
])
@
bp
.
route
(
'/admin/users/create'
,
methods
=
[
'POST'
])
@
login_required
@
login_required
@
require_admin
@
require_admin
...
@@ -768,6 +785,7 @@ def admin_create_user():
...
@@ -768,6 +785,7 @@ def admin_create_user():
logger
.
error
(
f
"Admin create user error: {str(e)}"
)
logger
.
error
(
f
"Admin create user error: {str(e)}"
)
return
jsonify
({
'error'
:
'Failed to create user'
}),
500
return
jsonify
({
'error'
:
'Failed to create user'
}),
500
@
csrf
.
exempt
@
bp
.
route
(
'/admin/users/<int:user_id>/reset-password'
,
methods
=
[
'POST'
])
@
bp
.
route
(
'/admin/users/<int:user_id>/reset-password'
,
methods
=
[
'POST'
])
@
login_required
@
login_required
@
require_admin
@
require_admin
...
@@ -797,6 +815,7 @@ def admin_reset_user_password(user_id):
...
@@ -797,6 +815,7 @@ def admin_reset_user_password(user_id):
logger
.
error
(
f
"Admin reset password error: {str(e)}"
)
logger
.
error
(
f
"Admin reset password error: {str(e)}"
)
return
jsonify
({
'error'
:
'Failed to reset password'
}),
500
return
jsonify
({
'error'
:
'Failed to reset password'
}),
500
@
csrf
.
exempt
@
bp
.
route
(
'/admin/settings'
)
@
bp
.
route
(
'/admin/settings'
)
@
login_required
@
login_required
@
require_admin
@
require_admin
...
@@ -819,6 +838,7 @@ def admin_system_settings():
...
@@ -819,6 +838,7 @@ def admin_system_settings():
flash
(
'Error loading system settings'
,
'error'
)
flash
(
'Error loading system settings'
,
'error'
)
return
render_template
(
'main/admin_settings.html'
,
settings
=
{})
return
render_template
(
'main/admin_settings.html'
,
settings
=
{})
@
csrf
.
exempt
@
bp
.
route
(
'/admin/settings/registration'
,
methods
=
[
'GET'
,
'POST'
])
@
bp
.
route
(
'/admin/settings/registration'
,
methods
=
[
'GET'
,
'POST'
])
@
login_required
@
login_required
@
require_admin
@
require_admin
...
@@ -853,6 +873,7 @@ def admin_registration_settings():
...
@@ -853,6 +873,7 @@ def admin_registration_settings():
logger
.
error
(
f
"Admin registration settings error: {str(e)}"
)
logger
.
error
(
f
"Admin registration settings error: {str(e)}"
)
return
jsonify
({
'error'
:
'Failed to update registration settings'
}),
500
return
jsonify
({
'error'
:
'Failed to update registration settings'
}),
500
@
csrf
.
exempt
@
bp
.
route
(
'/admin/settings/<setting_key>'
,
methods
=
[
'GET'
,
'POST'
])
@
bp
.
route
(
'/admin/settings/<setting_key>'
,
methods
=
[
'GET'
,
'POST'
])
@
login_required
@
login_required
@
require_admin
@
require_admin
...
@@ -909,6 +930,7 @@ def admin_setting_detail(setting_key):
...
@@ -909,6 +930,7 @@ def admin_setting_detail(setting_key):
logger
.
error
(
f
"Admin setting detail error: {str(e)}"
)
logger
.
error
(
f
"Admin setting detail error: {str(e)}"
)
return
jsonify
({
'error'
:
'Failed to update setting'
}),
500
return
jsonify
({
'error'
:
'Failed to update setting'
}),
500
@
csrf
.
exempt
@
bp
.
route
(
'/admin/database/migrations'
)
@
bp
.
route
(
'/admin/database/migrations'
)
@
login_required
@
login_required
@
require_admin
@
require_admin
...
@@ -926,6 +948,7 @@ def admin_database_migrations():
...
@@ -926,6 +948,7 @@ def admin_database_migrations():
flash
(
'Error loading migration status'
,
'error'
)
flash
(
'Error loading migration status'
,
'error'
)
return
render_template
(
'main/admin_migrations.html'
,
migration_status
=
{})
return
render_template
(
'main/admin_migrations.html'
,
migration_status
=
{})
@
csrf
.
exempt
@
bp
.
route
(
'/admin/database/migrations/run'
,
methods
=
[
'POST'
])
@
bp
.
route
(
'/admin/database/migrations/run'
,
methods
=
[
'POST'
])
@
login_required
@
login_required
@
require_admin
@
require_admin
...
@@ -965,6 +988,7 @@ def admin_run_migrations():
...
@@ -965,6 +988,7 @@ def admin_run_migrations():
'message'
:
f
'Failed to run migrations: {str(e)}'
'message'
:
f
'Failed to run migrations: {str(e)}'
}),
500
}),
500
@
csrf
.
exempt
@
bp
.
route
(
'/admin/database/migrations/status'
)
@
bp
.
route
(
'/admin/database/migrations/status'
)
@
login_required
@
login_required
@
require_admin
@
require_admin
...
@@ -986,6 +1010,7 @@ def admin_migration_status():
...
@@ -986,6 +1010,7 @@ def admin_migration_status():
'message'
:
f
'Failed to get migration status: {str(e)}'
'message'
:
f
'Failed to get migration status: {str(e)}'
}),
500
}),
500
@
csrf
.
exempt
@
bp
.
route
(
'/health'
)
@
bp
.
route
(
'/health'
)
def
health_check
():
def
health_check
():
"""Health check endpoint"""
"""Health check endpoint"""
...
@@ -1016,6 +1041,7 @@ def health_check():
...
@@ -1016,6 +1041,7 @@ def health_check():
'timestamp'
:
db
.
func
.
now
()
'timestamp'
:
db
.
func
.
now
()
}),
503
}),
503
@
csrf
.
exempt
@
bp
.
route
(
'/api/dashboard-data'
)
@
bp
.
route
(
'/api/dashboard-data'
)
@
login_required
@
login_required
@
require_active_user
@
require_active_user
...
@@ -1054,6 +1080,7 @@ def api_dashboard_data():
...
@@ -1054,6 +1080,7 @@ def api_dashboard_data():
# API Token Management Routes
# API Token Management Routes
@
csrf
.
exempt
@
bp
.
route
(
'/profile/tokens'
)
@
bp
.
route
(
'/profile/tokens'
)
@
login_required
@
login_required
@
require_active_user
@
require_active_user
...
@@ -1073,6 +1100,7 @@ def user_tokens():
...
@@ -1073,6 +1100,7 @@ def user_tokens():
flash
(
'Error loading API tokens'
,
'error'
)
flash
(
'Error loading API tokens'
,
'error'
)
return
render_template
(
'main/user_tokens.html'
,
tokens
=
[])
return
render_template
(
'main/user_tokens.html'
,
tokens
=
[])
@
csrf
.
exempt
@
bp
.
route
(
'/profile/tokens/create'
,
methods
=
[
'POST'
])
@
bp
.
route
(
'/profile/tokens/create'
,
methods
=
[
'POST'
])
@
login_required
@
login_required
@
require_active_user
@
require_active_user
...
@@ -1111,6 +1139,7 @@ def create_api_token():
...
@@ -1111,6 +1139,7 @@ def create_api_token():
logger
.
error
(
f
"Create API token error: {str(e)}"
)
logger
.
error
(
f
"Create API token error: {str(e)}"
)
return
jsonify
({
'error'
:
'Failed to create API token'
}),
500
return
jsonify
({
'error'
:
'Failed to create API token'
}),
500
@
csrf
.
exempt
@
bp
.
route
(
'/profile/tokens/<int:token_id>/delete'
,
methods
=
[
'DELETE'
])
@
bp
.
route
(
'/profile/tokens/<int:token_id>/delete'
,
methods
=
[
'DELETE'
])
@
login_required
@
login_required
@
require_active_user
@
require_active_user
...
@@ -1139,6 +1168,7 @@ def delete_api_token(token_id):
...
@@ -1139,6 +1168,7 @@ def delete_api_token(token_id):
logger
.
error
(
f
"Delete API token error: {str(e)}"
)
logger
.
error
(
f
"Delete API token error: {str(e)}"
)
return
jsonify
({
'error'
:
'Failed to delete API token'
}),
500
return
jsonify
({
'error'
:
'Failed to delete API token'
}),
500
@
csrf
.
exempt
@
bp
.
route
(
'/profile/tokens/<int:token_id>/revoke'
,
methods
=
[
'POST'
])
@
bp
.
route
(
'/profile/tokens/<int:token_id>/revoke'
,
methods
=
[
'POST'
])
@
login_required
@
login_required
@
require_active_user
@
require_active_user
...
@@ -1169,6 +1199,7 @@ def revoke_api_token(token_id):
...
@@ -1169,6 +1199,7 @@ def revoke_api_token(token_id):
logger
.
error
(
f
"Revoke API token error: {str(e)}"
)
logger
.
error
(
f
"Revoke API token error: {str(e)}"
)
return
jsonify
({
'error'
:
'Failed to revoke API token'
}),
500
return
jsonify
({
'error'
:
'Failed to revoke API token'
}),
500
@
csrf
.
exempt
@
bp
.
route
(
'/profile/tokens/<int:token_id>/extend'
,
methods
=
[
'POST'
])
@
bp
.
route
(
'/profile/tokens/<int:token_id>/extend'
,
methods
=
[
'POST'
])
@
login_required
@
login_required
@
require_active_user
@
require_active_user
...
@@ -1205,6 +1236,7 @@ def extend_api_token(token_id):
...
@@ -1205,6 +1236,7 @@ def extend_api_token(token_id):
# API Routes with Token Authentication
# API Routes with Token Authentication
@
csrf
.
exempt
@
bp
.
route
(
'/api/matches'
)
@
bp
.
route
(
'/api/matches'
)
def
api_matches
():
def
api_matches
():
"""API endpoint to list matches (requires API token)"""
"""API endpoint to list matches (requires API token)"""
...
@@ -1260,6 +1292,7 @@ def api_matches():
...
@@ -1260,6 +1292,7 @@ def api_matches():
return
_api_matches
()
return
_api_matches
()
@
csrf
.
exempt
@
bp
.
route
(
'/api/fixtures'
)
@
bp
.
route
(
'/api/fixtures'
)
def
api_fixtures
():
def
api_fixtures
():
"""API endpoint to list fixtures (requires API token)"""
"""API endpoint to list fixtures (requires API token)"""
...
@@ -1313,6 +1346,7 @@ def api_fixtures():
...
@@ -1313,6 +1346,7 @@ def api_fixtures():
return
_api_fixtures
()
return
_api_fixtures
()
@
csrf
.
exempt
@
bp
.
route
(
'/api/match/<int:match_id>'
)
@
bp
.
route
(
'/api/match/<int:match_id>'
)
def
api_match_detail
(
match_id
):
def
api_match_detail
(
match_id
):
"""API endpoint to get match details (requires API token)"""
"""API endpoint to get match details (requires API token)"""
...
@@ -1342,6 +1376,7 @@ def api_match_detail(match_id):
...
@@ -1342,6 +1376,7 @@ def api_match_detail(match_id):
return
_api_match_detail
()
return
_api_match_detail
()
@
csrf
.
exempt
@
bp
.
route
(
'/download/zip/<int:match_id>'
)
@
bp
.
route
(
'/download/zip/<int:match_id>'
)
@
login_required
@
login_required
@
require_active_user
@
require_active_user
...
...
app/upload/routes.py
View file @
4f9f12bc
...
@@ -16,6 +16,7 @@ from app.upload.forms import FixtureUploadForm, ZipUploadForm
...
@@ -16,6 +16,7 @@ from app.upload.forms import FixtureUploadForm, ZipUploadForm
logger
=
logging
.
getLogger
(
__name__
)
logger
=
logging
.
getLogger
(
__name__
)
@
csrf
.
exempt
@
bp
.
route
(
'/fixture'
,
methods
=
[
'GET'
,
'POST'
])
@
bp
.
route
(
'/fixture'
,
methods
=
[
'GET'
,
'POST'
])
@
login_required
@
login_required
@
require_active_user
@
require_active_user
...
@@ -68,6 +69,7 @@ def upload_fixture():
...
@@ -68,6 +69,7 @@ def upload_fixture():
return
render_template
(
'upload/fixture.html'
,
form
=
form
)
return
render_template
(
'upload/fixture.html'
,
form
=
form
)
@
csrf
.
exempt
@
bp
.
route
(
'/zip'
,
methods
=
[
'POST'
])
@
bp
.
route
(
'/zip'
,
methods
=
[
'POST'
])
@
login_required
@
login_required
@
require_active_user
@
require_active_user
...
@@ -131,6 +133,7 @@ def upload_zip():
...
@@ -131,6 +133,7 @@ def upload_zip():
flash
(
'Upload processing failed'
,
'error'
)
flash
(
'Upload processing failed'
,
'error'
)
return
redirect
(
request
.
referrer
or
url_for
(
'main.fixtures'
))
return
redirect
(
request
.
referrer
or
url_for
(
'main.fixtures'
))
@
csrf
.
exempt
@
bp
.
route
(
'/zip/<int:match_id>'
,
methods
=
[
'GET'
,
'POST'
])
@
bp
.
route
(
'/zip/<int:match_id>'
,
methods
=
[
'GET'
,
'POST'
])
@
login_required
@
login_required
@
require_active_user
@
require_active_user
...
@@ -191,6 +194,7 @@ def upload_zip_page(match_id):
...
@@ -191,6 +194,7 @@ def upload_zip_page(match_id):
return
render_template
(
'upload/zip.html'
,
form
=
form
,
match
=
match
)
return
render_template
(
'upload/zip.html'
,
form
=
form
,
match
=
match
)
@
csrf
.
exempt
@
bp
.
route
(
'/zip/<int:match_id>/delete'
,
methods
=
[
'POST'
])
@
bp
.
route
(
'/zip/<int:match_id>/delete'
,
methods
=
[
'POST'
])
@
login_required
@
login_required
@
require_active_user
@
require_active_user
...
@@ -842,6 +846,7 @@ def api_upload_info(upload_id):
...
@@ -842,6 +846,7 @@ def api_upload_info(upload_id):
logger
.
error
(
f
"Upload info error: {str(e)}"
)
logger
.
error
(
f
"Upload info error: {str(e)}"
)
return
jsonify
({
'error'
:
'Failed to get upload info'
}),
500
return
jsonify
({
'error'
:
'Failed to get upload info'
}),
500
@
csrf
.
exempt
@
bp
.
route
(
'/fixture/<fixture_id>/zip'
,
methods
=
[
'POST'
])
@
bp
.
route
(
'/fixture/<fixture_id>/zip'
,
methods
=
[
'POST'
])
@
login_required
@
login_required
@
require_active_user
@
require_active_user
...
@@ -915,8 +920,8 @@ def upload_fixture_zip(fixture_id):
...
@@ -915,8 +920,8 @@ def upload_fixture_zip(fixture_id):
flash
(
'Upload processing failed'
,
'error'
)
flash
(
'Upload processing failed'
,
'error'
)
return
redirect
(
request
.
referrer
or
url_for
(
'main.fixtures'
))
return
redirect
(
request
.
referrer
or
url_for
(
'main.fixtures'
))
@
bp
.
route
(
'/chunk'
,
methods
=
[
'POST'
])
@
csrf
.
exempt
@
csrf
.
exempt
@
bp
.
route
(
'/chunk'
,
methods
=
[
'POST'
])
@
login_required
@
login_required
@
require_active_user
@
require_active_user
def
upload_chunk
():
def
upload_chunk
():
...
@@ -956,8 +961,8 @@ def upload_chunk():
...
@@ -956,8 +961,8 @@ def upload_chunk():
logger
.
error
(
f
"Chunk upload error: {str(e)}"
)
logger
.
error
(
f
"Chunk upload error: {str(e)}"
)
return
jsonify
({
'success'
:
False
,
'error'
:
str
(
e
)}),
500
return
jsonify
({
'success'
:
False
,
'error'
:
str
(
e
)}),
500
@
bp
.
route
(
'/finalize'
,
methods
=
[
'POST'
])
@
csrf
.
exempt
@
csrf
.
exempt
@
bp
.
route
(
'/finalize'
,
methods
=
[
'POST'
])
@
login_required
@
login_required
@
require_active_user
@
require_active_user
def
finalize_upload
():
def
finalize_upload
():
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment