Add some security
parent
daf343535e
commit
14fcfff656
|
@ -138,3 +138,5 @@ dmypy.json
|
||||||
# Cython debug symbols
|
# Cython debug symbols
|
||||||
cython_debug/
|
cython_debug/
|
||||||
|
|
||||||
|
# SQLite databases
|
||||||
|
*.sqlite
|
||||||
|
|
|
@ -23,7 +23,8 @@ DEFAULT_CONFIG = {
|
||||||
'SECURITY_SEND_REGISTER_EMAIL': False,
|
'SECURITY_SEND_REGISTER_EMAIL': False,
|
||||||
'SQLALCHEMY_DATABASE_URI': 'sqlite://',
|
'SQLALCHEMY_DATABASE_URI': 'sqlite://',
|
||||||
'SQLALCHEMY_ENGINE_OPTIONS': {'pool_pre_ping': True},
|
'SQLALCHEMY_ENGINE_OPTIONS': {'pool_pre_ping': True},
|
||||||
'SQLALCHEMY_TRACK_MODIFICATIONS': False
|
'SQLALCHEMY_TRACK_MODIFICATIONS': False,
|
||||||
|
'WIKI_MODE': 'PUBLIC'
|
||||||
}
|
}
|
||||||
CONFIG_VARS = [
|
CONFIG_VARS = [
|
||||||
'LIBERTYWIKI_CONFIG',
|
'LIBERTYWIKI_CONFIG',
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
from functools import wraps
|
||||||
|
|
||||||
|
from flask import current_app, request
|
||||||
|
from flask_login import current_user
|
||||||
|
from flask_login.config import EXEMPT_METHODS
|
||||||
|
|
||||||
|
from libertywiki.utils import AccessType, WikiMode
|
||||||
|
|
||||||
|
|
||||||
|
def check_access(access_type):
|
||||||
|
"""Check if a user can access the view method"""
|
||||||
|
|
||||||
|
def wrapper(func):
|
||||||
|
"""Decorator wrapper"""
|
||||||
|
|
||||||
|
@wraps(func)
|
||||||
|
def decorated_view(*args, **kwargs):
|
||||||
|
"""Determine if the decorated view should be run"""
|
||||||
|
wiki_mode = WikiMode[current_app.config.get('WIKI_MODE', 'OPEN').upper()]
|
||||||
|
print(wiki_mode)
|
||||||
|
if request.method in EXEMPT_METHODS or \
|
||||||
|
current_app.config.get('LOGIN_DISABLED'):
|
||||||
|
pass
|
||||||
|
elif (wiki_mode == WikiMode.PRIVATE
|
||||||
|
or (wiki_mode == WikiMode.PUBLIC and access_type == AccessType.READ)) \
|
||||||
|
and not current_user.is_authenticated:
|
||||||
|
return current_app.login_manager.unauthorized()
|
||||||
|
try:
|
||||||
|
# current_app.ensure_sync available in Flask >= 2.0
|
||||||
|
return current_app.ensure_sync(func)(*args, **kwargs)
|
||||||
|
except AttributeError:
|
||||||
|
return func(*args, **kwargs)
|
||||||
|
|
||||||
|
return decorated_view
|
||||||
|
return wrapper
|
|
@ -1,6 +1,20 @@
|
||||||
|
from enum import Enum
|
||||||
|
|
||||||
from flask_bcrypt import Bcrypt
|
from flask_bcrypt import Bcrypt
|
||||||
|
|
||||||
|
|
||||||
|
class AccessType(Enum):
|
||||||
|
READ = 1
|
||||||
|
WRITE = 2
|
||||||
|
|
||||||
|
|
||||||
|
class WikiMode(Enum):
|
||||||
|
OPEN = 1
|
||||||
|
PUBLIC = 2
|
||||||
|
PRIVATE = 3
|
||||||
|
|
||||||
|
|
||||||
bcrypt = Bcrypt()
|
bcrypt = Bcrypt()
|
||||||
|
|
||||||
|
|
||||||
__all__ = ['bcrypt']
|
__all__ = ['AccessType', 'WikiMode', 'bcrypt']
|
||||||
|
|
|
@ -3,13 +3,16 @@ from datetime import datetime
|
||||||
from flask import Blueprint, request, render_template, redirect
|
from flask import Blueprint, request, render_template, redirect
|
||||||
|
|
||||||
from libertywiki.db import session
|
from libertywiki.db import session
|
||||||
|
from libertywiki.decorators import check_access
|
||||||
from libertywiki.models import Page
|
from libertywiki.models import Page
|
||||||
|
from libertywiki.utils import AccessType
|
||||||
|
|
||||||
wiki = Blueprint('wiki', __name__, url_prefix='')
|
wiki = Blueprint('wiki', __name__, url_prefix='')
|
||||||
|
|
||||||
|
|
||||||
@wiki.route('/', defaults={'path': 'Main_Page'}, methods=['GET'])
|
@wiki.route('/', defaults={'path': 'Main_Page'}, methods=['GET'])
|
||||||
@wiki.route('/<path:path>', methods=['GET'])
|
@wiki.route('/<path:path>', methods=['GET'])
|
||||||
|
@check_access(AccessType.READ)
|
||||||
def index(path=None):
|
def index(path=None):
|
||||||
page = Page.query.filter_by(slug=path).first()
|
page = Page.query.filter_by(slug=path).first()
|
||||||
if not page:
|
if not page:
|
||||||
|
@ -18,6 +21,7 @@ def index(path=None):
|
||||||
|
|
||||||
|
|
||||||
@wiki.route('/<path:path>/edit', methods=['GET'])
|
@wiki.route('/<path:path>/edit', methods=['GET'])
|
||||||
|
@check_access(AccessType.WRITE)
|
||||||
def edit(path):
|
def edit(path):
|
||||||
page = Page.query.filter_by(slug=path).first()
|
page = Page.query.filter_by(slug=path).first()
|
||||||
if not page:
|
if not page:
|
||||||
|
@ -26,6 +30,7 @@ def edit(path):
|
||||||
|
|
||||||
|
|
||||||
@wiki.route("/<path:path>/edit", methods=['POST'])
|
@wiki.route("/<path:path>/edit", methods=['POST'])
|
||||||
|
@check_access(AccessType.WRITE)
|
||||||
def save(path):
|
def save(path):
|
||||||
page = Page.query.filter_by(slug=path).first()
|
page = Page.query.filter_by(slug=path).first()
|
||||||
if not page:
|
if not page:
|
||||||
|
|
Loading…
Reference in New Issue