add: markdown permission setting

improve: template
This commit is contained in:
h z
2025-04-25 00:39:01 +01:00
parent cf247231e4
commit 35c8934963
11 changed files with 140 additions and 21 deletions

View File

@@ -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

View File

@@ -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'])

View File

@@ -1,4 +1,3 @@
#api/resource.py
import api
from flask import Blueprint, jsonify, request
from contexts.RequestContext import RequestContext

View File

@@ -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:

View 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

View File

@@ -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

View File

@@ -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(

View 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,
}

View File

@@ -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,
}

View File

@@ -1,4 +1,3 @@
#env_provider.py
import os
from dotenv import load_dotenv

View File

@@ -1,5 +1,3 @@
#logging_handlers/DatabaseLogHandler.py
import logging
from db import get_db
from db.models.Log import Log