文章目录

  • 权限管理系统
    • 一、 概述
    • 二、 创建表
      • 1、 创建
      • 2、 生成
      • 3、 映射
    • 三、 增删改查
      • 1、 群管理
        • 1.1 增加群
        • 1.2 删除群
        • 1.3 展示功能
      • 2、 权限管理
        • 2.1 展示权限
        • 2.2 修改权限
    • 四、 获取命令
      • 1、 消息分发
      • 2、 解析命令

权限管理系统

一、 概述

在写好我们的智能聊天功能之后,大家有没有感觉很烦呢?感觉这个机器人在群里面一直被艾特,一直被戳一戳。那么,我们有没有一种方法,使得其在群里面的权限可控呢?

或许大家看到这个问题就想到了一个方法,那就是通过python文件,但是使用python文件保存的话有一个缺点,那就是修改配置文件后,需要重新运行我们的项目,这会让我们觉得很麻烦!

那么,还有没有更好的方法呢?给大家一分钟时间思考……好,大家思考出来了吗?我的想法是,将权限存储到数据库中,当我们需要调用这个功能的时候,通过调用数据库,来判断是否有进行这项功能的权限!这里,我们选择的是mysql数据库,关于对数据库的操作,我已经给大家准备好了!

  • mysql数据库的安装:linux 中安装数据库的方法
  • mysql基本语法:关于数据库操作的基本语法
  • SQLAchemy 常用操作:使用ORM操作数据库

看到SQLAchemy,就应该有小伙伴要说了,既然我们看了mysql的基本语法,我们完全可以通过SQL语句来操作我们的数据库,为什么需要使用ORM来操作数据库呢?其实不然,我们使用SQL操作数据库的话,就无法处理一些高并发的操作了,会造成严重的阻塞,使用SQLAchemy可以创建数据库连接池,缓解服务器的压力,同时ORM对于一些不是很熟悉SQL的小伙伴来说比较友好。

好了,相信大家也看完了上面对数据库的操作的文章了,同时也看完了我写的关于flask的全部文章了,废话不多说了,来开始实现我们的权限管理系统

展示一下我的目录结构:

|-- App
|   |-- exts.py
|   |-- __init__.py
|   |-- models.py
|   |-- script.py
|   |-- settings.py
|   `-- views
|       |-- goCqhttp.py
|       |-- __init__.py
|-- app.py

二、 创建表

1、 创建

在实现权限管理系统之前,我们肯定是需要创建相应的数据表来存储我们的数据的

我们使用flask-sqlachemy来实现orm,同时快速生成表

#!/usr/bin/python3
# -*- coding: UTF-8 -*-
__author__ = "A.L.Kun"
__file__ = "models.py"
__time__ = "2022/9/11 19:56"from App.exts import dbclass Group(db.Model):  # 创建一个群的表__tablename__ = "group"id = db.Column(db.INTEGER, primary_key=True, autoincrement=True)name = db.Column(db.String(200), nullable=True)qqId = db.Column(db.String(20), nullable=False, unique=True, index=True)isDetect = db.Column(db.BOOLEAN, default=True)  # 是否开启auth = db.Column(db.SmallInteger, default=0)  # 在群里面的的地位,默认为群成员,1为管理员,2为群主def __init__(self, name, qqId):self.name = nameself.qqId = qqIdclass GroupAuthority(db.Model):  # 创建一个权限管理表__tablename__ = "groupAuth"id = db.Column(db.INTEGER, primary_key=True, autoincrement=True)chat = db.Column(db.INTEGER, default=0, nullable=False)  # 是否开启智能聊天的功能welcome = db.Column(db.INTEGER, default=1, nullable=False)  # 是否开启新成员入群欢迎的功能banTalk = db.Column(db.INTEGER, default=0)  # 群禁言功能,以及消息撤回功能click = db.Column(db.INTEGER, default=1)  # 戳一戳功能,默认开启smallFunction = db.Column(db.INTEGER, default=1)  # 是否开启小功能,如疫情数据查询等dailyBrief = db.Column(db.INTEGER, default=0)  # 是否开启每日简报功能groupId = db.Column(db.INTEGER, db.ForeignKey("group.id", ondelete="CASCADE"), nullable=False)  # 外键约束,同时进行级联删除auth2group = db.relationship("Group", backref=db.backref("group2auth", uselist=False))  # 使用代理,同时使用一对一模型def __init__(self, is_privade=False, chat=None, welcome=None, bantalk=None, click=None, smallFunction=None,dailyBrief=None):if is_privade:self.chat = chatself.welcome = welcomeself.banTalk = bantalkself.click = clickself.smallFunction = smallFunctionself.dailyBrief = dailyBrief

在这里,我使用group表作为主表,用来存放各群的数据,同时将机器人对各群的权限存储到另一张表中,因为是一对一的关系,我们使用同时对表使用外键约束来关联主表以及子表

2、 生成

把表的结构创建完后,我们来创建主程序,用来生成我们创建的表

exts.py文件中写入:

#!/usr/bin/python3
# -*- coding: UTF-8 -*-
__author__ = "A.L.Kun"
__file__ = "exts.py"
__time__ = "2022/9/11 23:39"from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migratedb = SQLAlchemy()  # 操作数据库def init_exts(app):db.init_app(app)Migrate().init_app(app, db)  # 使用app初始化Migrateapp.config["db"] = db

settings.py中写入:

#!/usr/bin/python3
# -*- coding: UTF-8 -*-
__author__ = "A.L.Kun"
__file__ = "settings.py"
__time__ = "2022/9/11 19:17"class Config:"""基础的配置字"""SQLALCHEMY_DATABASE_URI = "mysql+pymysql://root:123456@127.0.0.1:3306/bot?charset=utf8"  SQLALCHEMY_TRACK_MODIFICATIONS = FalseSQLALCHEMY_ECHO = TrueSUPER_USER = ["3500515050", ]  # 超级用户,其可以私发消息给机器人,管理机器人对所有群的权限,当然也可以存储到数据库中,这里为了方便,存储在配置文件中,大家可根据这篇文章执行实现ADMIN = 3500515050  # 开发者class Help:"""帮助文档"""ADMIN_HELP = """开发者命令提示:
1 添加群:\n/admin:add QQ群号 QQ群名
2. 删除功能:\n/admin:delete QQ群号
3 查找功能:\n/admin:get QQ群号
4. 获取所有群:\n/admin:show
5. 修改权限命令:\n/admin:changeAuth QQ群号 |聊天功能|入群欢迎|管理群|戳一戳|拓展功能|定时功能|(比如110011)\n
如果还是有问题,请与开发人员联系哦!"""GROUP_ADMIN = """[CQ:at,qq=%d]命令提示:
1. 查看群权限:\n/admin:get
2. 修改群权限:\n/admin:change |聊天功能|入群欢迎|管理群|戳一戳|拓展功能|定时功能|(比如#admin:change# 110011)\n
如果还是有问题,请与开发人员联系哦!"""class ProductConfig(Config, Mes, Url):"""生产环境配置"""passclass DevelopConfig(Config, Mes, Url):"""开发环境配置"""DEBUG = Trueenvs = {"product": ProductConfig,"develop": DevelopConfig
}

views/__init__.py中写入:

#!/usr/bin/python3
# -*- coding: UTF-8 -*-
__author__ = "A.L.Kun"
__file__ = "__init__.py.py"
__time__ = "2022/9/11 19:30"from App.views.goCqhttp import AcceptMes
from flask_restful import Apidef init_app(app):api = Api(app)api.add_resource(AcceptMes, "/", endpoint="index")

views/goCqhttp.py中写入:

# !/usr/bin/python3
# -*- coding: UTF-8 -*-
__author__ = "A.L.Kun"
__file__ = "goCqhttp.py"
__time__ = "2022/9/11 19:57"from flask_restful import Resource
from flask import request
import asyncio
from App.events.private import PriChatMes
from App.events.group import GroupChatMes
from App.events.groupAndPri import GroupAndPri
from flask import current_app
from App.models import Group
from App.events.groupAndPri import Command
from App.script.requests_tools import Senderclass AcceptMes(Resource):def post(self):pass  # 后面主要是通过这个接口来对消息的分发

App/__init__.py中 写入

#!/usr/bin/python3
# -*- coding: UTF-8 -*-
__author__ = "A.L.Kun"
__file__ = "__init__.py.py"
__time__ = "2022/9/11 14:25"from flask import Flask
from App.settings import envs
from App.views import init_app
from App.exts import init_extsdef create_app(env):app = Flask(__name__)app.config.from_object(envs.get(env))init_exts(app)init_app(app)  # 将路由传入app中return app

app.py中写入:

#!/usr/bin/python3
# -*- coding: UTF-8 -*-
__author__ = "A.L.Kun"
__file__ = "app.py"
__time__ = "2022/9/11 19:17"from App import create_app
from flask_script import Managerapp = create_app("develop")
manage = Manager(app)if __name__ == '__main__':manage.run()

然后,我们的基本框架就搭建好了,就将我们写好的模型映射到数据库中

3、 映射

在项目的根目录运行这个代码:

flask db init  # 初始化操作
flask db migrate  # 迁移操作
flask db upgrade  # 更新操作

然后,我们的数据表就更新完成了

三、 增删改查

首先,我们先不考虑如何监控我们的QQ消息,通过消息来操控我们的数据库,我们先来实现通过代码直接对权限数据的修改

为了方便,我们就直接在script.py中写入我们的函数,可以根据文章的顺序来添加

1、 群管理

1.1 增加群

from flask import current_app
from App.models import Group, GroupAuthority
from base64 import b64decode  # 对中文进行编码async def add(gid, nick):# 传入QQ群号和qq群的昵称就可以添加了session = current_app.config["db"].sessiondata = session.query(Group).filter_by(qqId=gid).first()  # 首先查看一下数据库中是否收录了这个群if data is None:  # 如果没有则添加,同时,也检查其是否有逻辑删除g = Group(nick, gid)  # 创建一个群g.group2auth = GroupAuthority()  # 给群赋予默认的权限session.add(g)  # 添加到数据库中session.commit()  # 提交事务return {  "status": 200}  # 返回状态码# 如果群存在,直接修改群名,以及使其可以检测到data.isDetect = Truedata.name = nicksession.commit()return {"status": 300,"error": "该群号已存在!",}

1.2 删除群

async def close(gid):"""进行逻辑删除"""db = current_app.config["db"]session = db.sessiongroup = session.query(Group).filter(db.and_(Group.qqId == gid, Group.isDetect)).first()if group:group.isDetect = Falsesession.commit()return "该群关闭成功"async def delete(gid):"""彻底删除"""db = current_app.config["db"]session = db.sessiongroup = session.query(Group).filter(Group.qqId == gid).first()if group:session.delete(group.group2auth)session.delete(group)session.commit()return "该群已从数据库中删除"

这里使用的是逻辑删的删除,使得程序无法访问到该数据,即代表删除效果,同时,数据也保存了下来

1.3 展示功能

async def show():session = current_app.config["db"].sessiondata = [f"|{b64decode(i.name).decode()} :: {i.qqId} :: {'yes' if i.isDetect else 'no'} |" for i insession.query(Group).all()]return "\n".join(data)

2、 权限管理

2.1 展示权限

async def get(gid):db = current_app.config["db"]session = db.sessiondata = session.query(Group).filter(db.and_(Group.qqId == gid, Group.isDetect)).first()if data is None:return "在该群不支持,请与开发者联系!"name = b64decode(data.name).decode()  # qq群名称chat = "1. 已开启聊天功能" if data.group2auth.chat else "1. 未开启聊天功能"  # 有没有开启智能聊天的功能welcome = "2. 已开启入群欢迎功能" if data.group2auth.welcome else "2. 未开启入群欢迎功能"  # 是否开启入群欢迎的功能banTalk = "3. 已开启管理群功能" if data.group2auth.banTalk else "3. 未开启管理群功能"  # 是否开启管理员的功能click = "4. 已开启戳一戳功能" if data.group2auth.click else "4. 未开启戳一戳功能"  # 戳一戳功能smallFunction = "5. 已开启拓展功能" if data.group2auth.smallFunction else "5. 未开启拓展功能"  # 是否开启小功能dailyBrief = "6. 已开启定时发消息功能" if data.group2auth.dailyBrief else "6. 未开启定时发消息功能"  # 是否开启每日自动播报的功能return f"{name}\n{chat}\n{welcome}\n{banTalk}\n{click}\n{smallFunction}\n{dailyBrief}\n"

2.2 修改权限

async def changeAuth(gid, data, ty):"""传入群号,要修改的数据其为6位数字,如:"011011",每一个数字代表一个权限,1为真|0为假最后传入的是调用这个函数的类型,是群管理员还是超级管理员"""db = current_app.config["db"]session = db.session  # 获取数据库连接try:for i in data:if int(i) not in [0, 1] or len(data) != 6:raise ValueErrordata = (int(i) for i in data)  # 获取到对应的权限数字group = session.query(Group).filter(db.and_(Group.qqId == gid, Group.isDetect)).first()  # 获取对象if group:session.delete(group.group2auth)  # 先要删除原来的权限组,再添加,防止出现野组group.group2auth = GroupAuthority(True, *data)  # 使用元组拆包的方式来传参session.commit()  # 提交数据_ = await Admin.get(gid)  # 获取到群里面的权限ret = f"[CQ:at,qq=%d]设置成功,设置后的权限为:\n{_}" if ty == "group" else f"设置成功,设置后的权限为:\n{_}"  else: ret = "该群不支持机器人"except Exception as e:ret = "[CQ:at,qq=%d]设置失败,请查看帮助文档!" if ty == "group" else "设置失败,请查看帮助文档!"return ret

那么,我们就把我们的权限管理大概的搭建好了,我们只需要再对消息进行检测,使其机器人可以解析命令就完成了

四、 获取命令

1、 消息分发

这里,我们来结合我们的权限系统,使得机器人可以对修改权限的命令作出回应

# !/usr/bin/python3
# -*- coding: UTF-8 -*-
__author__ = "A.L.Kun"
__file__ = "goCqhttp.py"
__time__ = "2022/9/11 19:57"from flask_restful import Resource
from flask import request
import asyncio
from flask import current_app
from App.models import Group
from App.script import *
from base64 import b64encode# 用于发送信息的函数
async def send(id, message, ty):"""用于发送消息的函数:param id: qq号,或者qq群号:param message: 发送的消息:param ty: 传入的:return: None"""async with httpx.AsyncClient(base_url="http://127.0.0.1:5700") as client:# 如果发送的为私聊消息if ty == "group":params = {"group_id": id,"message": message,}await client.get("/send_group_msg", params=params)elif ty == "private":params = {"user_id": id,"message": message,}await client.get("/send_private_msg", params=params)class AcceptMes(Resource):def post(self):# 这里对消息进行分发,暂时先设置一个简单的分发_ = request.jsonif _.get("message_type") == "private":  # 说明有好友发送信息过来uid = _["sender"]["user_id"]  # 获取发信息的好友qq号message = _["raw_message"]  # 获取发送过来的消息if message.startswith("/admin:") and str(uid) in current_app.config["SUPER_USER"]:# 其为超级用户的命令,通过正则解析出命令,并且做出回应,那么我们就需要创建一个函数,来解析我们的命令,这个函数我们后面来实现asyncio.run(super_command(uid, message))  # 处理私聊的信息elif _.get("message_type") == "group" and message.startswith("/admin:") and resp["sender"]["role"] in ["owner", "admin"]:# 获取群消息,并且,其为群主或者管理员发送的消息的话,并且这个群开启了机器人的功能db = current_app.config["db"]session = db.sessiongroup = session.query(Group).filter(db.and_(Group.qqId == _["group_id"], Group.isDetect)).first()if not group:# 如果群里面不支持机器人的话,直接返回returnuid = _["sender"]["user_id"]  # 获取发信息的好友qq号message = _.get("raw_message")gid = resp["group_id"]  # 获取群号asyncio.run(admin_command(uid, gid, message))  # 这里也是先用一个函数名来占位,我们后面来实现这个函数

2、 解析命令

goCqhttp.py后面继续添加以下内容

超级管理员的命令解析

async def super_command(uid, message):  # 处理开发者的命令com_1 = re.findall(r"/admin:(.*)", message.split()[0])[0]try:com_2 = message.split()[1]  # qq群号except Exception as e:com_2 = Noneif com_1 == "add" and com_2.isdecimal():  # 这说明其为添加qq群com_3 = message.split()[2]  # qq昵称ret = await add(com_2, b64encode(com_3.encode()))if ret["status"] == 200:await send(uid, f"{com_2}添加成功,该群名为{com_3}", "private")else:await send(uid, ret["error"], "private")elif com_1 == "get" and com_2.isdecimal():  # 获取指定的qq群的权限信息ret = await get(com_2)await send(uid, ret, ty="private")elif com_1 == "delete" and com_2.isdecimal():  # 删除qq群ret = await delete(com_2)await send(uid, ret, ty="private")elif com_1 == "changeAuth" and com_2.isdecimal():  # 修改权限data = list(message.split()[2])ret = await changeAuth(com_2, data, "private")await send(uid, ret, "private")elif com_1 == "show":  # 展示所有群信息ret = await show()await send(uid, ret, "private")else:  # 如果都不是的话,发送帮助文档ret = current_app.config["ADMIN_HELP"]await send(uid, ret, "private")

群管理员命令解析

async def admin_command(uid, gid, message):  # 群管理员命令com_1 = re.findall(r"/admin:(.*)", message.split()[0])[0]  # 把命令解析出来if com_1 == "get":  # 获取本群的权限信息ret = await get(gid)await send(gid, ret, ty="group")elif com_1 == "change":  # 修改权限信息data = list(message.split()[1])ret = await changeAuth(gid, data, "group")await send(gid, ret % uid, "group")else:  # 默认为帮助文档ret = current_app.config["GROUP_ADMIN"] % uidawait send(gid, ret, "group")

最后,我们的权限系统就做完啦!大家可以运行项目尝试一下哦!python app.py runserver -p5701

同时里面的每一个权限我也会慢慢的分布实现!

go-cqhttp权限管理相关推荐

  1. 合肥工业大学—SQL Server数据库实验十:用户及其权限管理

    用户及其权限管理 1. 创建登录名Mylog及密码 2. 创建用户user2关联登录名 3. 创建角色role1 4. 对用户user2及角色role1授权 5. 验证用户授权 6. 收回用户权限 1 ...

  2. mongodb权限管理

    说到mongodb就得先谈谈mongodb的用户组,和传统的关系型数据库不一样,mongodb并没有在创建应用时就要求创建权限管理组,所以类似于Robomongo这样的数据库可视化工具在创建conne ...

  3. 一步一步Asp.Net MVC系列_权限管理总结(附MVC权限管理系统源码)

    TZHSWEET:请大家多多反馈问题,我已经在修改中了,已更新版本...... 如果大家遇到数据库附加问题,EF连接字符串问题,请自行配置,如果有bug反馈可以私聊,我的qq:409180955. 项 ...

  4. [Linux] 010 权限管理命令 chmod

    1. 权限管理命令:chmod 命令名称:chmod 命令英文原意:change the permissions mode of a file 命令所在路径:/bin/chmod 执行权限:所有用户 ...

  5. 单一窗口关区备案_单一窗口税费支付权限管理

    企业需先使用法人卡登录"单一窗口"税费支付系统进行业务权限授权后,才可以使用操作员卡查询.支付.打印税单等. "业务权限授权"模块提供税费支付企业相关业务权限( ...

  6. SpringMVC权限管理

    2019独角兽企业重金招聘Python工程师标准>>> 1.DispatcherServlet SpringMVC具有统一的入口DispatcherServlet,所有的请求都通过D ...

  7. 通用权限管理系统组件 (GPM - General Permissions Manager) 权限管理以前我们都是自己开发,可是到下一个系统又不适用,又改,加上人员流动大,管理很混乱...

    为什么80%的码农都做不了架构师?>>>    权限管理以前我们都是自己开发,可是到下一个系统又不适用,又改,加上人员流动大,管理很混乱 Ψ吉日嘎拉 采用通用权限管理系统,这些烦恼就 ...

  8. RBAC新解 - 基于资源的权限管理

    1.什么是角色 当说到程序的权限管理时,人们往往想到角色这一概念.角色是代表一系列可执行的操作或责任的实体,用于限定你在软件系统中能做什么.不能做什么.用户帐号往往与角色相关联,因此,一个用户在软件系 ...

  9. Linux学习笔记—— 权限及权限管理

    权限及权限管理 权限管理: r: w: x: 三类用户: u:属主 g:属组 o:其他用户 chown:改变文件属主(只有管理员可以使用此命令) # chown USERNAME file,... - ...

  10. 博客5:文件,目录以及用户的权限管理

    linux用户与组的相关内容简介:    1.Linux用户:Username/UID 管理员:root,0普通用户:1-65535系统用户:1-499(在centos7上为1-999)作用:对守护进 ...

最新文章

  1. 昌宁一中高考成绩表查询2021,昌宁县一中20182019学年上学期高二数学月考试题含解析.docx...
  2. struts2.0和struts1.x的区别
  3. C++实现矩阵加减乘求转置
  4. CentOS 初体验九:curl 的使用
  5. 现在学python和java哪个好_java和python学习哪个未来发展前景更好?
  6. 【计算机组成原理】英文选择题题库
  7. jsp获取SessionID值
  8. java实现文件夹的复制(包括子文件夹以及子文件)
  9. 机器学习(一) Eviews下载及安装教程
  10. ubuntu截图工具KSnapshot(静态图),peek(动态图)
  11. 3Dmax已渲染的图怎么加载VFB和LUT?
  12. 华为eSight网管平台折腾
  13. astah java版本_astah professional
  14. t.cn短链接是怎么生成的?
  15. (十四)商品详情页实现
  16. 两码一号:整体方案回顾
  17. jmeter持续时间设置
  18. 前进的方向 没有方向就是蒙着眼睛的驴子原地踏步 一年经验混十年
  19. linux安装mysql图解,linux中怎么安装mysql5.6.12版本图解
  20. rabitMQ work模式二 按能力分配任务

热门文章

  1. 引用账户当前已锁定,且可能无法登录”--问题的解决方法(转载)
  2. 函数(递归,迭代实现斐波那契数列)
  3. toojpeg库 添加测试代码
  4. 优学院思想道德修养与法律基础试题及答案
  5. 【风之语.中途岛海战】
  6. Unity/VS/C#Unity工程加密授权开发---LicenseProj
  7. Seurat3.0小提琴图腰围的参数
  8. linux后台启动,不输出日志文件
  9. 双因素组合制图/ArcGIS耦合协调度
  10. HTML5代码调用手机摄像头