SongZihuan 2 роки тому
батько
коміт
ab84255cad
8 змінених файлів з 58 додано та 15 видалено
  1. 5 1
      app/archive.py
  2. 7 0
      app/auth.py
  3. 6 1
      app/comment.py
  4. 13 7
      app/db.py
  5. 14 1
      app/login.py
  6. 1 1
      templates/auth/user.html
  7. 9 3
      templates/auth/yours.html
  8. 3 1
      templates/comment/comment.html

+ 5 - 1
app/archive.py

@@ -4,7 +4,9 @@ from wtforms import StringField, SubmitField
 from wtforms.validators import DataRequired, Length, ValidationError
 from flask_login import login_required
 
-from .db import db, Archive
+from .db import db, Archive, Role
+from .login import role_required
+
 
 archive = Blueprint("archive", __name__)
 
@@ -26,6 +28,7 @@ class CreateArchiveForm(FlaskForm):
 
 
 @archive.route("/all")
+@role_required(Role.CHECK_ARCHIVE)
 def list_all_page():
     page = request.args.get("page", 1, type=int)
     pagination = (Archive.query
@@ -40,6 +43,7 @@ def list_all_page():
 
 @archive.route("/create", methods=["GET", "POST"])
 @login_required
+@role_required(Role.CREATE_ARCHIVE)
 def create_page():
     form = CreateArchiveForm()
     if form.validate_on_submit():

+ 7 - 0
app/auth.py

@@ -15,6 +15,7 @@ from sqlalchemy.exc import IntegrityError
 from .db import db, User, Role, Follow
 from .logger import Logger
 from .mail import send_msg
+from .login import role_required
 
 
 auth = Blueprint("auth", __name__)
@@ -288,6 +289,7 @@ def user_page():
 
 @auth.route("/follower/list")
 @login_required
+@role_required(Role.CHECK_FOLLOW)
 def follower_page():
     if current_user.follower_count == 0:
         return render_template("auth/no_follow.html", title="粉丝", msg="你暂时一个粉丝都没有哦。")
@@ -302,6 +304,7 @@ def follower_page():
 
 @auth.route("/followed/list")
 @login_required
+@role_required(Role.CHECK_FOLLOW)
 def followed_page():
     if current_user.followed_count == 0:
         return render_template("auth/no_follow.html", title="关注", msg="你暂时未关注任何人。")
@@ -316,6 +319,7 @@ def followed_page():
 
 @auth.route("/followed/follow")
 @login_required
+@role_required(Role.FOLLOW)
 def set_follow_page():
     user_id = request.args.get("user", None, type=int)
     if not user_id or user_id == current_user.id:
@@ -338,6 +342,7 @@ def set_follow_page():
 
 @auth.route("/followed/unfollow")
 @login_required
+@role_required(Role.FOLLOW)
 def set_unfollow_page():
     user_id = request.args.get("user", None, type=int)
     if not user_id or user_id == current_user.id:
@@ -355,6 +360,7 @@ def set_unfollow_page():
 
 @auth.route("/block")
 @login_required
+@role_required(Role.BLOCK_USER)
 def set_block_page():
     user_id = request.args.get("user", None, type=int)
     if not user_id or user_id == current_user.id:
@@ -376,6 +382,7 @@ def set_block_page():
 
 @auth.route('/role/user', methods=['GET', 'POST'])
 @login_required
+@role_required(Role.SYSTEM)
 def change_role_page():
     form = ChangeRoleForm()
     if form.validate_on_submit():

+ 6 - 1
app/comment.py

@@ -5,7 +5,8 @@ from wtforms.validators import DataRequired, Length
 from flask_login import current_user, login_required
 
 
-from .db import db, Comment, Archive, User
+from .db import db, Comment, Archive, User, Role
+from .login import role_required
 
 
 comment = Blueprint("comment", __name__)
@@ -34,6 +35,7 @@ class WriteCommentForm(FlaskForm):
 
 
 @comment.route("/")
+@role_required(Role.CHECK_COMMENT)
 def comment_page():
     comment_id = request.args.get("comment", None, type=int)
     if not comment_id:
@@ -48,6 +50,7 @@ def comment_page():
 
 
 @comment.route("/all")
+@role_required(Role.CHECK_COMMENT)
 def list_all_page():
     page = request.args.get("page", 1, type=int)
     archive_id = request.args.get("archive", None, type=int)
@@ -84,6 +87,7 @@ def list_all_page():
 
 
 @comment.route("/user")
+@role_required(Role.CHECK_COMMENT)
 def user_page():
     page = request.args.get("page", 1, type=int)
     user_id = request.args.get("user", None, type=int)
@@ -107,6 +111,7 @@ def user_page():
 
 @comment.route("/create", methods=["GET", "POST"])
 @login_required
+@role_required(Role.CREATE_COMMENT)
 def create_page():
     father_id = request.args.get("father", None, type=int)
 

+ 13 - 7
app/db.py

@@ -1,4 +1,4 @@
-import sqlalchemy
+from flask import abort
 from flask_sqlalchemy import SQLAlchemy
 from flask_login import UserMixin, AnonymousUserMixin
 from datetime import datetime
@@ -25,6 +25,13 @@ class AnonymousUser(AnonymousUserMixin):
     def email(self):
         return None
 
+    @property
+    def role(self):
+        anonymous = Role.query.filter_by(name="anonymous").first()
+        if not anonymous:
+            return abort(500)
+        return anonymous
+
 
 class User(db.Model, UserMixin):
     __tablename__ = "user"
@@ -114,9 +121,7 @@ class Role(db.Model):
     CREATE_ARCHIVE = 32  # 系统权限
     FOLLOW = 64
     BLOCK_USER = 128  # 系统权限
-    DELETE_COMMENT = 256  # 系统权限
-    DELETE_ARCHIVE = 512  # 系统权限
-    SYSTEM = 1024  # 系统权限
+    SYSTEM = 256  # 系统权限
 
     id = db.Column(db.Integer, autoincrement=True, primary_key=True, nullable=False)
     name = db.Column(db.String(32), nullable=False, unique=True)
@@ -185,12 +190,13 @@ def create_all():
     except Exception:
         pass
 
-    admin = Role(name="admin", permission=2047)
-    coordinator = Role(name="coordinator", permission=1023)
+    admin = Role(name="admin", permission=511)
+    coordinator = Role(name="coordinator", permission=255)
     default = Role(name="default")
     block = Role(name="block", permission=0)
+    anonymous = Role(name="anonymous", permission=15)
 
-    db.session.add_all([admin, coordinator, default, block])
+    db.session.add_all([admin, coordinator, default, block, anonymous])
     db.session.commit()
 
 

+ 14 - 1
app/login.py

@@ -1,4 +1,6 @@
-from flask_login import LoginManager
+from functools import wraps
+from flask import abort
+from flask_login import LoginManager, current_user
 from .db import AnonymousUser, User
 
 
@@ -10,3 +12,14 @@ login.login_view = "auth.passwd_login_page"
 @login.user_loader
 def user_loader(user_id: int):
     return User.query.filter_by(id=user_id).first()
+
+
+def role_required(role: int):
+    def required(func):
+        @wraps(func)
+        def new_func(*args, **kwargs):
+            if not current_user.role.has_permission(role):  # 检查相应的权限
+                return abort(403)
+            return func(*args, **kwargs)
+        return new_func
+    return required

+ 1 - 1
templates/auth/user.html

@@ -16,7 +16,7 @@
 
         <div class="text-end">
             <div class="btn-group">
-                {% if user.role.has_permission(Role.USABLE) %}
+                {% if user.role.has_permission(Role.USABLE) and current_user.role.has_permission(Role.BLOCK_USER) %}
                     <a class="btn btn-outline-danger" href="{{ url_for("auth.set_block_page", user=user.id) }}"> 封禁 </a>
                 {% endif %}
 

+ 9 - 3
templates/auth/yours.html

@@ -18,9 +18,15 @@
 
         <div class="text-end">
             <div class="btn-group">
-                <a class="btn btn-outline-danger" href="{{ url_for("auth.change_role_page") }}"> 修改分组 </a>
-                <a class="btn btn-outline-danger" href="{{ url_for("archive.create_page") }}"> 创建新归档 </a>
-                <a class="btn btn-outline-danger" href="{{ url_for("comment.create_page") }}"> 创建新讨论 </a>
+                {% if current_user.role.has_permission(Role.SYSTEM) %}
+                    <a class="btn btn-outline-danger" href="{{ url_for("auth.change_role_page") }}"> 修改分组 </a>
+                {% endif %}
+                {% if current_user.role.has_permission(Role.CREATE_ARCHIVE) %}
+                    <a class="btn btn-outline-danger" href="{{ url_for("archive.create_page") }}"> 创建新归档 </a>
+                {% endif %}
+                {% if current_user.role.has_permission(Role.CREATE_COMMENT) %}
+                    <a class="btn btn-outline-danger" href="{{ url_for("comment.create_page") }}"> 创建新讨论 </a>
+                {% endif %}
                 <a class="btn btn-outline-danger" href="{{ url_for("auth.change_passwd_page") }}"> 修改密码 </a>
                 <a class="btn btn-outline-danger" href="{{ url_for("auth.logout_page") }}"> 退出登录 </a>
             </div>

+ 3 - 1
templates/comment/comment.html

@@ -6,7 +6,9 @@
     <div class="container mt-3">
         <div>
             <span class="h5"> 讨论ID:{{ comment.id }} </span>
-            <a class="btn btn-warning float-end" href="{{ url_for("comment.create_page", father=comment.id) }}"> 添加子讨论 </a>
+            {% if current_user.role.has_permission(Role.CREATE_COMMENT) %}
+                <a class="btn btn-warning float-end" href="{{ url_for("comment.create_page", father=comment.id) }}"> 添加子讨论 </a>
+            {% endif %}
         </div>
 
         <div class="card mt-4">