add: markdown permission setting
improve: template
This commit is contained in:
@@ -79,6 +79,17 @@ def verify_token(token):
|
||||
print(e)
|
||||
return None
|
||||
|
||||
def is_user_admin():
|
||||
is_admin = False
|
||||
auth_header = request.headers.get('Authorization')
|
||||
if auth_header and auth_header.startswith('Bearer'):
|
||||
token = auth_header.split(" ")[1]
|
||||
decoded = verify_token(token)
|
||||
if decoded:
|
||||
user_roles = decoded.get("resource_access", {}).get(env_provider.KC_CLIENT_ID, {}).get("roles", [])
|
||||
is_admin = 'admin' in user_roles
|
||||
return is_admin
|
||||
|
||||
def require_auth(roles=[]):
|
||||
def decorator(func):
|
||||
@wraps(func)
|
||||
@@ -158,4 +169,3 @@ def etag_response(f):
|
||||
return resp
|
||||
return response
|
||||
return decorator
|
||||
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
from flask import Blueprint, request, jsonify
|
||||
from sqlalchemy import or_
|
||||
from api import limiter
|
||||
from api import require_auth, etag_response
|
||||
from api import require_auth, etag_response, verify_token, is_user_admin
|
||||
from contexts.RequestContext import RequestContext
|
||||
from db import get_db
|
||||
from db.models.Markdown import Markdown
|
||||
from db.models.MarkdownSetting import MarkdownSetting
|
||||
from db.models.MarkdownPermissionSetting import MarkdownPermissionSetting
|
||||
from events import markdown_created, markdown_updated, markdown_deleted
|
||||
import api
|
||||
import env_provider
|
||||
import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -54,10 +57,23 @@ def get_index(path_id):
|
||||
@limiter.limit(api.get_rate_limit)
|
||||
@etag_response
|
||||
def get_markdown(markdown_id):
|
||||
is_admin = is_user_admin()
|
||||
|
||||
with get_db() as session:
|
||||
markdown = session.query(Markdown).get(markdown_id)
|
||||
if markdown is None:
|
||||
return jsonify({"error": "file not found"}), 404
|
||||
|
||||
if not is_admin and markdown.setting_id is not None:
|
||||
setting = session.query(MarkdownSetting).get(markdown.setting_id)
|
||||
if setting and setting.permission_setting_id:
|
||||
permission_setting = session.query(MarkdownPermissionSetting).get(setting.permission_setting_id)
|
||||
if permission_setting:
|
||||
if permission_setting.permission == 'private':
|
||||
return jsonify({"msg": "permission denied"}), 403
|
||||
elif permission_setting.permission == 'protected':
|
||||
return jsonify({"msg": "permission denied"}), 203
|
||||
|
||||
return jsonify(markdown.to_dict()), 200
|
||||
|
||||
@markdown_bp.route('/', methods=['POST'])
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#api/resource.py
|
||||
import api
|
||||
from flask import Blueprint, jsonify, request
|
||||
from contexts.RequestContext import RequestContext
|
||||
|
||||
@@ -23,7 +23,11 @@ def get_markdown_path(setting_id):
|
||||
def create_markdown_setting():
|
||||
data = request.json
|
||||
template_setting_id = data.get('template_setting_id')
|
||||
setting = MarkdownSetting(template_setting_id=template_setting_id)
|
||||
permission_setting_id = data.get('permission_setting_id')
|
||||
setting = MarkdownSetting(
|
||||
template_setting_id=template_setting_id,
|
||||
permission_setting_id=permission_setting_id
|
||||
)
|
||||
try:
|
||||
with get_db() as session:
|
||||
session.add(setting)
|
||||
@@ -42,7 +46,9 @@ def update_markdown_setting(setting_id):
|
||||
if setting is None:
|
||||
return jsonify({"error": "setting not exists"}), 400
|
||||
template_setting_id = data.get('template_setting_id', setting.template_setting_id)
|
||||
permission_setting_id = data.get('permission_setting_id', setting.permission_setting_id)
|
||||
setting.template_setting_id = template_setting_id
|
||||
setting.permission_setting_id = permission_setting_id
|
||||
session.commit()
|
||||
return jsonify(setting.to_dict()), 200
|
||||
except Exception as e:
|
||||
|
||||
56
api/setting/markdown/permission.py
Normal file
56
api/setting/markdown/permission.py
Normal file
@@ -0,0 +1,56 @@
|
||||
from flask import jsonify, request
|
||||
import api
|
||||
from api import etag_response, limiter, require_auth
|
||||
from api.setting import setting_bp
|
||||
from db import get_db
|
||||
from db.models.MarkdownPermissionSetting import MarkdownPermissionSetting
|
||||
|
||||
|
||||
@setting_bp.route('/markdown/permission/<int:setting_id>/', methods=['GET'])
|
||||
@etag_response
|
||||
@limiter.limit(api.get_rate_limit)
|
||||
def get_permission_setting(setting_id):
|
||||
with get_db() as session:
|
||||
setting = session.query(MarkdownPermissionSetting).get(setting_id)
|
||||
if not setting:
|
||||
return jsonify({}), 204
|
||||
return jsonify(setting.to_dict()), 200
|
||||
|
||||
|
||||
@setting_bp.route('/markdown/permission/', methods=['POST'])
|
||||
@require_auth(roles=['admin'])
|
||||
def create_permission_setting():
|
||||
data = request.json
|
||||
permission = data.get('permission')
|
||||
new_setting = MarkdownPermissionSetting(permission=permission)
|
||||
with get_db() as session:
|
||||
session.add(new_setting)
|
||||
session.commit()
|
||||
return jsonify(new_setting.to_dict()), 201
|
||||
|
||||
|
||||
@setting_bp.route('/markdown/permission/<int:setting_id>', methods=['PUT', 'PATCH'])
|
||||
@require_auth(roles=['admin'])
|
||||
def update_permission_setting(setting_id):
|
||||
with get_db() as session:
|
||||
setting = session.get(MarkdownPermissionSetting, setting_id)
|
||||
if setting is None:
|
||||
return jsonify({"error": "permission setting not found"}), 404
|
||||
data = request.json
|
||||
if request.method == 'PUT':
|
||||
setting.permission = data.get('permission')
|
||||
elif request.method == 'PATCH':
|
||||
if 'permission' in data:
|
||||
setting.permission = data.get('permission')
|
||||
session.commit()
|
||||
return jsonify(setting.to_dict()), 200
|
||||
|
||||
@setting_bp.route('/markdown/permission/<int:setting_id>', methods=['DELETE'])
|
||||
@require_auth(roles=['admin'])
|
||||
def delete_permission_setting(setting_id):
|
||||
with get_db() as session:
|
||||
setting = session.get(MarkdownPermissionSetting, setting_id)
|
||||
st = setting.to_dict()
|
||||
session.delete(setting)
|
||||
session.commit()
|
||||
return jsonify(st), 200
|
||||
@@ -59,8 +59,5 @@ def delete_template_setting(setting_id):
|
||||
setting = session.get(MarkdownTemplateSetting, setting_id)
|
||||
st = setting.to_dict()
|
||||
session.delete(setting)
|
||||
session.commit()
|
||||
return jsonify(st), 200
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
38
api/tree.py
38
api/tree.py
@@ -1,27 +1,49 @@
|
||||
from flask import Blueprint, request, jsonify
|
||||
from sqlalchemy.orm import Session
|
||||
from sqlalchemy import and_, or_
|
||||
|
||||
import api
|
||||
from api import etag_response
|
||||
from api import etag_response, verify_token, is_user_admin
|
||||
from db import get_db
|
||||
from db.models.Markdown import Markdown
|
||||
from db.models.Path import Path
|
||||
from db.models.MarkdownSetting import MarkdownSetting
|
||||
from db.models.MarkdownPermissionSetting import MarkdownPermissionSetting
|
||||
from api import limiter
|
||||
import env_provider
|
||||
import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
tree_bp = Blueprint('tree', __name__, url_prefix='/api/tree')
|
||||
|
||||
|
||||
def build_tree(db: Session, parent_id: int = None):
|
||||
def build_tree(db: Session, parent_id: int = None, is_admin=False):
|
||||
path_nodes = db.query(Path).filter(Path.parent_id == parent_id).all()
|
||||
md_nodes = db.query(
|
||||
|
||||
markdown_query = db.query(
|
||||
Markdown.id,
|
||||
Markdown.title,
|
||||
Markdown.order,
|
||||
Markdown.shortcut,
|
||||
Markdown.setting_id
|
||||
).filter(Markdown.path_id == parent_id).all()
|
||||
).filter(Markdown.path_id == parent_id)
|
||||
|
||||
if not is_admin:
|
||||
markdown_query = markdown_query.outerjoin(
|
||||
MarkdownSetting,
|
||||
Markdown.setting_id == MarkdownSetting.id
|
||||
).outerjoin(
|
||||
MarkdownPermissionSetting,
|
||||
MarkdownSetting.permission_setting_id == MarkdownPermissionSetting.id
|
||||
).filter(
|
||||
or_(
|
||||
MarkdownPermissionSetting.permission != 'private',
|
||||
MarkdownPermissionSetting.permission == None
|
||||
)
|
||||
)
|
||||
|
||||
md_nodes = markdown_query.all()
|
||||
|
||||
t0 = [
|
||||
{
|
||||
"id": node.id,
|
||||
@@ -32,7 +54,7 @@ def build_tree(db: Session, parent_id: int = None):
|
||||
} for node in md_nodes
|
||||
]
|
||||
t1 = [
|
||||
{**node.to_dict(), "type": "path", "children": build_tree(db, node.id)} for node in path_nodes
|
||||
{**node.to_dict(), "type": "path", "children": build_tree(db, node.id, is_admin)} for node in path_nodes
|
||||
]
|
||||
for node in t1:
|
||||
for child in node["children"]:
|
||||
@@ -45,8 +67,10 @@ def build_tree(db: Session, parent_id: int = None):
|
||||
@limiter.limit(api.get_rate_limit)
|
||||
@etag_response
|
||||
def get_tree():
|
||||
is_admin = is_user_admin()
|
||||
|
||||
with get_db() as session:
|
||||
children = build_tree(session, 1)
|
||||
children = build_tree(session, 1, is_admin)
|
||||
root = session.query(Path).get(1)
|
||||
|
||||
return jsonify(
|
||||
@@ -56,4 +80,4 @@ def get_tree():
|
||||
"index": any("title" in child.keys() and child["title"] == "index" for child in children),
|
||||
"children": children
|
||||
}
|
||||
), 200
|
||||
), 200
|
||||
|
||||
15
db/models/MarkdownPermissionSetting.py
Normal file
15
db/models/MarkdownPermissionSetting.py
Normal file
@@ -0,0 +1,15 @@
|
||||
from sqlalchemy import Column, Integer, ForeignKey, String
|
||||
|
||||
from db.models import Base
|
||||
|
||||
|
||||
class MarkdownPermissionSetting(Base):
|
||||
__tablename__ = 'markdown_permission_setting'
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
permission = Column(String(255), nullable=True)
|
||||
|
||||
def to_dict(self):
|
||||
return {
|
||||
"id": self.id,
|
||||
"permission": self.permission,
|
||||
}
|
||||
@@ -1,15 +1,14 @@
|
||||
from sqlalchemy import Column, Integer, ForeignKey
|
||||
|
||||
from db.models import Base
|
||||
|
||||
|
||||
class MarkdownSetting(Base):
|
||||
__tablename__ = 'markdown_setting'
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
template_setting_id = Column(Integer, ForeignKey('markdown_template_setting.id'), nullable=True)
|
||||
|
||||
permission_setting_id = Column(Integer, ForeignKey('markdown_permission_setting.id'), nullable=True)
|
||||
def to_dict(self):
|
||||
return {
|
||||
"id": self.id,
|
||||
"template_setting_id": self.template_setting_id,
|
||||
"permission_setting_id": self.permission_setting_id,
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
#env_provider.py
|
||||
import os
|
||||
from dotenv import load_dotenv
|
||||
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
#logging_handlers/DatabaseLogHandler.py
|
||||
|
||||
import logging
|
||||
from db import get_db
|
||||
from db.models.Log import Log
|
||||
|
||||
Reference in New Issue
Block a user