Example #1
0
def start_plugin():
    """
    开启一个插件
    :return:
    """

    name = request.argget.all('name')
    s, r = arg_verify(reqargs=[(gettext("name"), name)], required=True)
    if not s:
        return r
    find_query = {"plugin_name": name, "error": {"$in": [0, False]}}
    plugin = mdbs["sys"].db.plugin.find_one(find_query)
    if plugin:
        other_plugin = mdbs["sys"].db.plugin.find_one({
            "hook_name":
            plugin["hook_name"],
            "active": {
                "$in": [1, True]
            }
        })
        if other_plugin:
            data = {
                "msg":
                gettext("Plugin[{}] with similar functionality is in use,"
                        " please stop it first").format(
                            other_plugin["plugin_name"]),
                "msg_type":
                "w",
                "custom_status":
                400
            }
            return data
    r = mdbs["sys"].db.plugin.update_one(find_query, {"$set": {"active": 1}})
    register_r = plugin_manager.register_plugin(name)
    if r.modified_count and register_r:
        # 清除缓存
        r = mdbs["sys"].db.plugin.find_one({"plugin_name": name})
        if r:
            cache.delete_autokey(fun="get_plugin_info",
                                 db_type="redis",
                                 hook_name=r['hook_name'])

        data = {
            "msg": gettext("Plug-in activated successfully"),
            "msg_type": "s",
            "custom_status": 201
        }
    elif r.matched_count and register_r:
        data = {
            "msg": gettext("Plug-in is already activated"),
            "msg_type": "w",
            "custom_status": 400
        }
    else:
        data = {
            "msg": gettext("Plug-in activation failed"),
            "msg_type": "w",
            "custom_status": 400
        }
    return data
Example #2
0
def del_navs():
    ids = json_to_pyseq(request.argget.all("ids"))
    s, r = arg_verify([(gettext("ids"), ids)], required=True)
    if not s:
        return r
    del_ids = []
    for id in ids:
        del_ids.append(ObjectId(id))

    r = mdbs["sys"].dbs["theme_nav_setting"].delete_many(
        {"_id": {
            "$in": del_ids
        }})
    if r.deleted_count:
        data = {
            "msg": gettext("Deleted successfully"),
            "msg_type": "s",
            "custom_status": 200
        }
    else:
        data = {
            "msg": gettext("Delete failed"),
            "msg_type": "s",
            "custom_status": 200
        }
    cache.delete_autokey(fun="get_global_theme_navs",
                         theme_name=".*",
                         lang=".*",
                         db_type="redis",
                         key_regex=True)
    return data
Example #3
0
def stop_plugin():
    """
    停用一个插件
    :return:
    """

    name = request.argget.all('name')
    s, r = arg_verify(reqargs=[(gettext("name"), name)], required=True)
    if not s:
        return r
    r = mdbs["sys"].db.plugin.update_one({"plugin_name": name},
                                         {"$set": {
                                             "active": 0
                                         }})
    if r.matched_count:
        # 清除缓存
        r = mdbs["sys"].db.plugin.find_one({"plugin_name": name})
        if r:
            cache.delete_autokey(fun="get_plugin_info",
                                 db_type="redis",
                                 hook_name=r['hook_name'])

        data = {
            "msg": gettext("Plug-in stopped successfully"),
            "msg_type": "s",
            "custom_status": 201
        }
    else:
        data = {
            "msg": gettext("Plug-in failed to stop"),
            "msg_type": "w",
            "custom_status": 400
        }
    return data
Example #4
0
def delete_url():
    """
    删除url, 值允许删除页面路由
    :return:
    """
    ids = json_to_pyseq(request.argget.all("ids", []))

    for i, tid in enumerate(ids):
        ids[i] = ObjectId(tid)

    url_pers = list(mdbs["sys"].db.sys_urls.find(
        {"_id": {"$in": ids}}, {"url": 1}))
    r = mdbs["sys"].db.sys_urls.delete_many(
        {"_id": {"$in": ids}, "create": "manual"})
    if r.deleted_count:
        # 清除缓存
        for url_per in url_pers:
            cache.delete_autokey(
                fun="get_sys_url",
                db_type="redis",
                url=url_per['url'].rstrip("/"))

        data = {
            "msg": gettext("Successfully deleted"),
            "msg_type": "s",
            "custom_status": 204}
    else:
        data = {
            "msg": gettext("Delete failed"),
            "msg_type": "w",
            "custom_status": 400}
    return data
Example #5
0
def delete_user_info_cache(user_id):
    """
    清理user缓存
    :param user_id:
    :return:
    """
    # 清理user信息数据缓存
    cache.delete_autokey(fun="get_user_public_info",
                         user_id=user_id,
                         db_type="mongodb",
                         key_regex=True)
    cache.delete_autokey(fun="get_user_all_info",
                         user_id=user_id,
                         db_type="mongodb",
                         key_regex=True)
Example #6
0
def insert_one_user(updata):
    '''
    插入一条数据
    :param updata:
    :return:
    '''

    r = mdb_user.db.user.insert_one(updata)

    fun_name = "get_one_user"
    cache.delete_autokey(fun=fun_name,
                         db_type="redis",
                         username=updata["username"])
    cache.delete_autokey(fun=fun_name, db_type="redis", email=updata["email"])
    return r
Example #7
0
def update_role_and_api_per(old_per_value, new_per_value=0):
    """
    更新所有使用了old_per的role和api
    :param old_per:
    :param new_per:
    :return:
    """
    # 更新使用了该权限的role
    # 当前所有的用户角色
    updated_rolename = []
    roles = mdbs["user"].db.role.find()
    for role in roles:
        if role["permissions"] & old_per_value and not (
                role["permissions"] & get_permission("ROOT")):
            role_new_per = (role["permissions"] -
                            old_per_value) | new_per_value
            mdbs["user"].db.role.update_many(
                {"_id": role["_id"]}, {"$set": {
                    "permissions": role_new_per
                }})
            updated_rolename.append(role["name"])

    # 更新使用了该权限的url or page
    # 当前所有自定义权限url
    urls = list(mdbs["sys"].db.sys_urls.find(
        {"custom_permission": {
            "$ne": {},
            "$exists": True
        }}))
    for url in urls:
        for method, v in url["custom_permission"].items():
            if v & old_per_value:
                # 修改
                url["custom_permission"][method] = (
                    v - old_per_value) | new_per_value

        # 更新
        mdbs["sys"].db.sys_urls.update_one(
            {"_id": url["_id"]},
            {"$set": {
                "custom_permission": url["custom_permission"]
            }})

        cache.delete_autokey(fun="get_sys_url",
                             db_type="redis",
                             url=url['url'].rstrip("/"))

    return {"updated_rolename": updated_rolename}
Example #8
0
def delete_plugin():
    """
    删除一个插件
    :return:
    """

    name = request.argget.all('name')
    s, r = arg_verify(reqargs=[(gettext("name"), name)], required=True)
    if not s:
        return r

    # 清除缓存
    plug = mdbs["sys"].db.plugin.find_one({"plugin_name": name})

    r = mdbs["sys"].db.plugin.update_one(
        {
            "plugin_name": name,
            "active": {
                "$ne": 1
            }
        }, {"$set": {
            "is_deleted": 1
        }})
    if r.modified_count or r.matched_count:
        data = {
            "msg": gettext("Successfully deleted"),
            "msg_type": "s",
            "custom_status": 204
        }
        # 删除配置
        mdbs["sys"].db.plugin_config.delete_many({"plugin_name": name})

        # 删除缓存,达到更新缓存
        cache.delete(PLUG_IN_CONFIG_CACHE_KEY)
        cache.delete_autokey(fun="get_plugin_info",
                             db_type="redis",
                             hook_name=plug['hook_name'])
    else:
        data = {
            "msg": gettext("Failed to delete"),
            "msg_type": "w",
            "custom_status": 400
        }
    return data
Example #9
0
def clean_get_one_user_cache(user_id=None, user=None):
    '''
    清理get_one_user的cache
    :param user:
    :return:
    '''
    fun_name = "get_one_user"
    if user_id and not user:
        user = mdb_user.db.user.find_one({"_id": ObjectId(user_id)})

    if user:
        cache.delete_autokey(fun=fun_name,
                             db_type="redis",
                             user_id=str(user["_id"]))
        cache.delete_autokey(fun=fun_name,
                             db_type="redis",
                             username=user["username"])
        cache.delete_autokey(fun=fun_name,
                             db_type="redis",
                             email=user["email"])
Example #10
0
def nav_setting():
    """
    Update
    :RETURN:
    """

    cid = request.argget.all("id")
    theme_name = request.argget.all("theme_name")
    lang = request.argget.all("language")
    display_name = request.argget.all("display_name")
    order = str_to_num(request.argget.all("order", 99))
    json_data = json_to_pyseq(request.argget.all("json_data"))
    s, r = arg_verify([(gettext("Display name"), display_name),
                       (gettext("theme name"), theme_name),
                       (gettext("language"), lang),
                       (gettext("Json data"), json_data)],
                      required=True)
    if not s:
        return r

    if not isinstance(json_data, dict):
        data = {
            "msg": gettext('Value must be of type json'),
            "msg_type": "e",
            "custom_status": 400
        }
        return data

    if not cid:
        updata = {
            'theme_name': theme_name,
            'display_name': display_name,
            'language': lang,
            'json_data': json_data,
            "order": order
        }
        r = mdbs["sys"].dbs["theme_nav_setting"].insert_one(updata)
        if r.inserted_id:
            data = {
                "msg": gettext("Navigation added successfully"),
                "msg_type": "s",
                "custom_status": 200
            }
        else:
            data = {
                "msg": gettext("Failed to add navigation"),
                "msg_type": "w",
                "custom_status": 400
            }
    else:
        updata = {
            'theme_name': theme_name,
            'display_name': display_name,
            'language': lang,
            'json_data': json_data,
            "order": order
        }
        r = mdbs["sys"].dbs["theme_nav_setting"].update_one(
            {"_id": ObjectId(cid)}, {"$set": updata})
        if r.modified_count:
            data = {
                "msg": gettext("Updated successfully"),
                "msg_type": "s",
                "custom_status": 200
            }
        elif r.matched_count:
            data = {
                "msg": gettext("Unmodified"),
                "msg_type": "w",
                "custom_status": 200
            }
        else:
            data = {
                "msg": gettext("Update failed"),
                "msg_type": "w",
                "custom_status": 400
            }
    cache.delete_autokey(fun="get_global_theme_navs",
                         theme_name=".*",
                         lang=".*",
                         db_type="redis",
                         key_regex=True)
    return data
Example #11
0
def compatible_processing(mdbs, stage=1):
    """
    兼容上一个版本
    :return:
    """

    if stage == 1:
        # 当前主题设置加上主题名称
        theme = mdbs["sys"].dbs["sys_config"].find_one({"project": "theme", "key": "CURRENT_THEME_NAME"})
        if theme:
            theme_name = theme["value"]
            mdbs["sys"].dbs["theme_display_setting"].update_many({"theme_name": {"$exists": False}},
                                                             {"$set": {"theme_name": theme_name}})

            # 主题设置的数据分类信息转移
            categorys = mdbs["web"].db.category.find({"type": {"$regex": ".+_theme$"}})
            for category in categorys:
                category["type"] = category["type"].replace("_theme", "")
                category["theme_name"] = theme_name
                r = mdbs["web"].db.theme_category.insert_one(category)
                if r.inserted_id:
                    mdbs["web"].db.category.delete_one({"_id": category["_id"]})

            '''
            v2.0之后新功能: 兼容 2.0Beta, v2.0
            '''
            # 判断是第一次部署网站还是升级版本
            its_not_first = mdbs["user"].dbs["permission"].find_one({})
            if its_not_first and not mdbs["sys"].dbs["theme_nav_setting"].find_one({}):
                # 将导航设置迁移到主题导航设置专属模块数据库
                r = mdbs["sys"].dbs["sys_config"].find(
                    {"project": "theme_global_conf", "key": "TOP_NAV"}
                ).sort([("update_time", -1)]).limit(1)
                if r.count(True):
                    for i, v in r[0]["value"].items():
                        display_name = v["nav"]
                        updata = {
                            "order": 1,
                            "display_name": display_name,
                            "theme_name": theme_name,
                            "language": "zh_CN"
                        }
                        del v["nav"]
                        updata["json_data"] = v
                        mdbs["sys"].dbs["theme_nav_setting"].update_one(
                            {"theme_name": theme_name, "display_name": display_name},
                            {"$set": updata},
                            upsert=True
                        )
    elif stage == 2:
        # 2020/1/23 version v2.2
        # 更新最高权限
        is_updated = False
        pers = mdbs["user"].dbs["permission"].find({})
        cnt = pers.count(True)
        if cnt:
            pers = pers.sort([("value", -1)])
            per = pers[0]
            root = 0b10000000000000000000000000000000000000000000000000000
            if per["value"] < root:
                mdbs["user"].dbs["permission"].update_one(
                    {"_id": per["_id"]},
                    {"$set": {"value": root}}
                )
                is_updated = True
            if cnt > 1:
                per = pers[1]
                admin = 0b1000000000000000000000000000000000000000000000000000
                if per["value"] < admin:
                    mdbs["user"].dbs["permission"].update_one(
                        {"_id": per["_id"]},
                        {"$set": {"value": admin}}
                    )
                    is_updated = True

        # 更新root角色
        roles = mdbs["user"].dbs["role"].find({})
        if roles.count(True):
            role = roles.sort([("permissions", -1)])[0]
            if role["permissions"] < SUPER_PER:
                mdbs["user"].dbs["role"].update_one(
                    {"_id": role["_id"]},
                    {"$set": {"permissions": SUPER_PER}}
                )
                is_updated = True
        if is_updated:
            cache.delete(key=GET_DEFAULT_SYS_PER_CACHE_KEY, db_type="redis")
            cache.delete(key=GET_ALL_PERS_CACHE_KEY, db_type="redis")
            cache.delete(key=GET_ALL_PERS_CACHE_KEY, db_type="redis")
            cache.delete_autokey(fun=".*get_one_user.*", db_type="redis", key_regex=True)
Example #12
0
    def load_plugin(self, plugin_name, is_import=False):
        """
        加载插件 import
        :param plugin_name:
        :return:
        """

        plug_path = os.path.join(self.plugin_path, plugin_name)
        s, r = verify_plugin(plug_path)
        if not s:
            # 标记插件为出错插件
            mdbs["sys"].dbs["plugin"].update_one(
                {
                    "plugin_name": plugin_name,
                    "update_time": {
                        "$lt": self.current_time
                    }
                }, {
                    "$set": {
                        "error": r,
                        "installed_time": self.current_time,
                        "update_time": self.current_time,
                        "active": 0,
                        "require_package_install_result": []
                    }
                },
                upsert=True)
            return s, r

        # 查看是否有需求文件
        if os.path.exists(os.path.join(plug_path, "requirements.txt")):
            requirements_exist = True
        else:
            requirements_exist = False

        # 读取yaml配置
        fpath = os.path.join(plug_path, "conf.yaml")
        with open(fpath) as rf:
            # 读取插件配置文件
            plug_conf = yaml.load(rf)
            hook_name = plug_conf["hook_name"]
            module = None
            current_plug = mdbs["sys"].dbs["plugin"].find_one(
                {"plugin_name": plugin_name})

            freed = False
            # 如果插件存在, 并标记为删除,那就删除插件文件
            if current_plug and "is_deleted" in current_plug and current_plug[
                    "is_deleted"]:
                try:
                    shutil.rmtree(plug_path)
                except BaseException:
                    pass
                freed = True

            if is_import or (current_plug and current_plug["error"]):
                # 需要导入插件模块或者插件模块之前鉴定有错误
                startup_file_name = plug_conf["startup_file_name"]
                plug_main_file_path = os.path.join(plug_path,
                                                   startup_file_name)
                if os.path.exists(plug_main_file_path):
                    module_path = "apps.{}.{}.{}".format(
                        PLUG_IN_FOLDER_NAME, plugin_name,
                        startup_file_name[:-3])
                    try:
                        if module_path in sys.modules:
                            # 如果之前已加载
                            module = reload(sys.modules[module_path])
                        else:
                            module = import_module(module_path)
                    except BaseException as e:
                        # 标记插件为出错插件
                        mdbs["sys"].dbs["plugin"].update_one(
                            {
                                "plugin_name": plugin_name,
                                "update_time": {
                                    "$lt": self.current_time
                                }
                            }, {
                                "$set": {
                                    "error": str(e),
                                    "update_time": self.current_time,
                                    "active": 0,
                                    "requirements_exist": requirements_exist,
                                    "require_package_install_result": []
                                }
                            },
                            upsert=True)

                        return False, str(e)

                else:
                    return False, "{} {}".format(
                        gettext("Plugin startup file does not exist"),
                        plug_main_file_path)

            # 需要更新的数据
            plug_conf["plugin_name"] = plugin_name
            plug_conf["update_time"] = self.current_time
            plug_conf["error"] = 0
            plug_conf["requirements_exist"] = requirements_exist
            # 检测当前插件安装情况
            if current_plug:

                # 如果插件未激活
                if not current_plug["active"]:
                    freed = True

                if freed:
                    # 释放实例对象
                    self.unregister_plugin(plugin_name)

                # 更新插件信息到数据库
                mdbs["sys"].dbs["plugin"].update_one(
                    {
                        "plugin_name": plugin_name,
                        "update_time": {
                            "$lt": self.current_time
                        }
                    }, {"$set": plug_conf})

            else:
                # 插件不存在
                plug_conf["active"] = 0
                plug_conf["is_deleted"] = 0
                plug_conf["installed_time"] = self.current_time
                mdbs["sys"].dbs["plugin"].insert_one(plug_conf)

            # 清理遗留缓存
            cache.delete_autokey(fun="get_plugin_info",
                                 db_type="redis",
                                 hook_name=hook_name)
            return True, {
                "module": module,
                "hook_name": hook_name,
                "plugin_name": plugin_name
            }
Example #13
0
def push_url_to_db(app):
    """
    同步url到数据库
    :param app:
    :return:
    """
    # back up
    now_time = time.time()
    ud = time_to_utcdate(now_time, "%Y%m%d%H")
    days_ago_t = now_time - 86400 * 7
    days_ago_d = time_to_utcdate(days_ago_t, "%Y%m%d%H")
    if not mdbs["sys"].dbs["sys_urls_back"].find_one({"backup_time": ud}):
        sys_urls = list(mdbs["sys"].dbs["sys_urls"].find({}, {"_id": 0}))
        for sys_url in sys_urls:
            sys_url["backup_time"] = ud
        mdbs["sys"].dbs["sys_urls_back"].insert(sys_urls)
        mdbs["sys"].dbs["sys_urls_back"].delete_many(
            {"backup_time": {
                "$lt": days_ago_d
            }})

    for rule in app.url_map.iter_rules():
        if rule.endpoint.startswith("api.") or rule.endpoint.startswith(
                "open_api."):
            type = "api"
        else:
            continue
        now_time = time.time()
        r = mdbs["sys"].dbs["sys_urls"].find_one(
            {"url": rule.rule.rstrip("/")})
        if not r:
            # 不存在
            mdbs["sys"].dbs["sys_urls"].insert_one({
                "url":
                rule.rule.rstrip("/"),
                "methods":
                list(rule.methods),
                "endpoint":
                rule.endpoint,
                "custom_permission": {},
                "type":
                type,
                "create":
                "auto",
                "update_time":
                now_time
            })

        elif r:
            new_methods = list(rule.methods)
            old_methods = r["methods"]
            if old_methods:
                new_methods.extend(old_methods)
            else:
                old_methods = []
            new_methods = list(set(new_methods))
            mdbs["sys"].dbs["sys_urls"].update_one({"_id": r["_id"]}, {
                "$set": {
                    "methods": new_methods,
                    "endpoint": rule.endpoint,
                    "type": type,
                    "create": "auto",
                    "update_time": now_time
                }
            })
            new_methods.sort()
            old_methods.sort()
            if new_methods != old_methods or rule.endpoint != r["endpoint"]:
                # 清理缓存
                cache.delete_autokey(fun="get_sys_url",
                                     key_base64=False,
                                     db_type="redis",
                                     url=r["url"])
    """
    # 清理已不存在的api
    # 时间7天是为了防止多台服务器同时启动时造成误删
    """
    ut = time.time() - 86400 * 7
    mdbs["sys"].dbs["sys_urls"].delete_many({
        "type": {
            "$ne": "page"
        },
        "update_time": {
            "$lt": ut
        }
    })
Example #14
0
def update_url():
    """
    更新修改 url权限
    :return:
    """
    tid = request.argget.all("id")
    method = request.argget.all("method")
    login_auth = str_to_num(request.argget.all("login_auth", 0))
    custom_permission = json_to_pyseq(
        request.argget.all("custom_permission", []))
    s, r = arg_verify([("id", tid)], required=True)
    if not s:
        return r

    s, r = arg_verify(
        [(gettext("method"), method)],
        required=True,
        only=["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS", "HEAD"])
    if not s:
        return r

    permission = 0x0
    for i in custom_permission:
        try:
            i = int(i)
            permission = permission | int(i)
        except BaseException:
            pass

    # 修改权限验证
    data = {
        "msg":
        gettext(
            "The current user permissions are lower than the permissions you want to modify,"
            " without permission to modify"),
        "msg_type":
        "w",
        "custom_status":
        401
    }
    user_role = mdbs["user"].db.role.find_one(
        {"_id": ObjectId(current_user.role_id)})
    # 如果当前用户的权限最高位 小于 要修改成的权重的最高位,是不可以的
    if get_num_digits(user_role["permissions"]) <= get_num_digits(permission):
        return data

    old_permission = 0
    old_url_per = mdbs["sys"].db.sys_urls.find_one({"_id": ObjectId(tid)})
    if old_url_per and method in old_url_per["custom_permission"]:
        old_permission = old_url_per["custom_permission"][method]

    # 如果当前用户的权限最高位 小于 要修改url请求的权限,也是不可以
    if get_num_digits(
            user_role["permissions"]) <= get_num_digits(old_permission):
        return data

    r = mdbs["sys"].db.sys_urls.update_one({"_id": ObjectId(tid)}, {
        "$set": {
            "custom_permission.{}".format(method): permission,
            "login_auth.{}".format(method): login_auth
        }
    })
    if r.modified_count:
        # 清除缓存
        r = mdbs["sys"].db.sys_urls.find_one({"_id": ObjectId(tid)})
        if r:
            cache.delete_autokey(fun="get_sys_url",
                                 db_type="redis",
                                 url=r['url'].rstrip("/"))
        data = {
            "msg": gettext("Modify the success"),
            "msg_type": "s",
            "custom_status": 201
        }
    else:
        data = {
            "msg": gettext("No modification"),
            "msg_type": "w",
            "custom_status": 400
        }
    return data