Esempio n. 1
0
def edit_per():

    tid = request.argget.all('id').strip()
    name = request.argget.all('name', '').strip()
    explain = request.argget.all('explain', '')
    default = int(request.argget.all('is_default', 0).strip())
    position = str_to_num(request.argget.all('position', 0))

    s, r = arg_verify(reqargs=[(gettext("name"), name),
                               (gettext("position"), position)],
                      required=True)
    if not s:
        return r

    hightest_pos = get_num_digits(SUPER_PER)
    if position > hightest_pos and position < 1:
        data = {
            'msg':
            gettext("Must be an integer greater than 0,"
                    " less than or equal to {}".format(hightest_pos)),
            'msg_type':
            "w",
            "custom_status":
            403
        }
        return data

    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)})
    # 如果当前用户的权限最高位 小于 要修改成的这个角色权重的最高位,是不可以的
    permissions = int(math.pow(2, position - 1))
    if get_num_digits(user_role["permissions"]) <= get_num_digits(permissions):
        return data

    per = {
        "name": name,
        "explain": explain,
        'value': permissions,
        "is_default": default
    }

    if mdbs["user"].db.permission.find_one({
            "name": name,
            "_id": {
                "$ne": ObjectId(tid)
            }
    }):
        data = {
            'msg': gettext("Permission name already exists"),
            'msg_type': "w",
            "custom_status": 403
        }

    elif mdbs["user"].db.permission.find_one({
            "value": permissions,
            "_id": {
                "$ne": ObjectId(tid)
            }
    }):
        data = {
            'msg': gettext('Location has been used'),
            'msg_type': "w",
            "custom_status": 403
        }
    else:
        old_per = mdbs["user"].db.permission.find_one({
            "_id": ObjectId(tid),
            "value": {
                "$exists": True
            }
        })
        if old_per:
            old_per_value = old_per["value"]

            r = mdbs["user"].db.permission.update_one({"_id": ObjectId(tid)},
                                                      {"$set": per})
            if not r.modified_count:
                data = {
                    'msg': gettext("No changes"),
                    'msg_type': "w",
                    "custom_status": 201
                }
            else:
                r = update_role_and_api_per(old_per_value, new_per_value=0)
                updated_rolename = r["updated_rolename"]
                msg_updated_rolename = gettext(
                    "The role of the chain reaction is: \n")
                if updated_rolename:
                    for ur in updated_rolename:
                        msg_updated_rolename = '{}, "{}"'.format(
                            msg_updated_rolename, ur)
                else:
                    msg_updated_rolename = '{} 0'.format(msg_updated_rolename)
                # 刷新缓存
                cache.delete(key=GET_DEFAULT_SYS_PER_CACHE_KEY,
                             db_type="redis")
                cache.delete(key=GET_ALL_PERS_CACHE_KEY, db_type="redis")
                data = {
                    'msg':
                    gettext("The update is successful. {}".format(
                        msg_updated_rolename)),
                    'msg_type':
                    "s",
                    "custom_status":
                    201
                }
        else:
            data = {
                'msg': gettext("Update failed"),
                'msg_type': "w",
                "custom_status": 400
            }
    return data
Esempio n. 2
0
def init_core_module(app, **kwargs):
    """
    初始化核心模块
    :param app:
    :return:
    """
    csrf_enabled = kwargs.get("csrf_enabled")
    is_debug = kwargs.get("is_debug")
    # app config
    web_start_log.info("Initialize the core module")

    # 系统必要配置, 优先导入
    app.config.from_object(ConfDictToClass(CONFIG["system"], key="value"))
    app.config.from_object(ConfDictToClass(CONFIG["key"], key="value"))

    # 数据库
    redis.init_app()

    app.config.from_object(DatabaseConfig())
    for name, mdb in mdbs.items():
        mdb.init_app(app, config_prefix=name.upper())

    # 缓存
    app.config.from_object(ConfDictToClass(CONFIG["cache"], key="value"))
    app.config["CACHE_REDIS"] = redis
    app.config["CACHE_MONGODB_DBS"] = mdbs["sys"].dbs
    cache.init_app(app)

    # Clear CONFIG cache
    if not is_debug:
        version_info = mdbs["sys"].db.sys_config.find_one(
            {"new_version": {
                "$exists": True
            }})
        ago_time = time.time() - 3600 * 24
        ago_time_30m = time.time() - 1800
        if version_info["sys_version_of_config"] >= SYS_CONFIG_VERSION \
                and version_info["update_time"] > ago_time \
                and version_info["update_time"] < ago_time_30m:
            # 系统正在使用的SYS_CONFIG_VERSION版本和当前机器CONFIG的一样,或更高
            # And: 配置24小时内已有更新
            # So: 这次不更新
            msg = " * [sys configs cache]  Not clean cache." \
                  " The system is using the same or higher configuration version.\n" \
                  "   And it was executed within 24 hours."
            start_info_print("\033[33m{}\033[0m".format(msg))
            web_start_log.warning(msg)
        else:
            with app.app_context():
                msg = " * Clean configuration cache successfully"
                cache.delete(CONFIG_CACHE_KEY)
                cache.delete(PLUG_IN_CONFIG_CACHE_KEY)
                web_start_log.info(msg)
                start_info_print(msg)

    # 异常错误信息
    app.config["PRESERVE_CONTEXT_ON_EXCEPTION"] = PRESERVE_CONTEXT_ON_EXCEPTION

    ###################################################
    # 在此之前, 任何程序不能调用utils.get_config.py下的方法
    ###################################################

    from apps.core.utils.get_config import get_configs, get_config
    from apps.core.flask.request import OsrRequestProcess
    from apps.core.flask.errorhandler import ErrorHandler
    from apps.core.blueprint import api, admin_view, theme_view, static_html_view, \
        static, open_api, admin_static_file
    from apps.core.flask.routing import RegexConverter
    from apps.core.flask.routing import push_url_to_db

    # 最大请求大小
    app.config["MAX_CONTENT_LENGTH"] = get_config(
        "system", "MAX_CONTENT_LENGTH") * 1024 * 1024
    # Session会话配置
    session_config = get_configs("session")
    session_config["SESSION_PROTECTION"] = SESSION_PROTECTION
    session_config["SESSION_COOKIE_PATH"] = SESSION_COOKIE_PATH
    session_config["SESSION_COOKIE_HTTPONLY"] = SESSION_COOKIE_HTTPONLY
    session_config["SESSION_COOKIE_SECURE"] = SESSION_COOKIE_SECURE
    session_config["SESSION_USE_SIGNER"] = SESSION_USE_SIGNER
    session_config["SESSION_MONGODB_DB"] = mdbs["sys"].name

    app.config.from_object(ConfDictToClass(session_config))
    app.config["SESSION_REDIS"] = redis
    app.config["SESSION_MONGODB"] = mdbs["sys"].connection
    sess.init_app(app)
    rest_session.init_app(app)

    # 邮件
    app.config.from_object(ConfDictToClass(get_configs("email")))
    mail.init_app(app)

    # Csrf token
    csrf_config = {}
    if csrf_enabled:
        csrf_config["CLIENT_TOKEN_AUTH_ENABLED"] = True
        start_info_print(" * Security authentication is turned on")
    else:
        csrf_config["CLIENT_TOKEN_AUTH_ENABLED"] = False
        start_info_print(
            "\033[31m   WARNING: security verification is turned off\033[0m")

    # 这两个csrf参数这里关闭,request程序会根据CLIENT_TOKEN_AUTH_ENABLED判断处理
    csrf_config["WTF_CSRF_CHECK_DEFAULT"] = False
    csrf_config["CSRF_ENABLED"] = False

    csrf_config["WTF_CSRF_METHODS"] = WTF_CSRF_METHODS
    app.config.from_object(ConfDictToClass(csrf_config))
    csrf.init_app(app)

    # Babel
    app.config.from_object(ConfDictToClass(get_configs("babel")))
    app.config["BABEL_TRANSLATION_DIRECTORIES"] = BABEL_TRANSLATION_DIRECTORIES
    babel.init_app(app)

    # 登录管理
    login_manager.init_app(app)
    # login_manager.anonymous_user = AnonymousUser()
    login_manager.session_protection = SESSION_PROTECTION
    # oauth.init_app(app)
    # 让路由支持正则
    app.url_map.converters['regex'] = RegexConverter

    # 注册蓝图 blueprint
    web_start_log.info("Register blueprint, Initialize the routing")
    app.register_blueprint(api)
    app.register_blueprint(open_api)
    app.register_blueprint(admin_view)
    app.register_blueprint(theme_view)
    app.register_blueprint(static_html_view)
    app.register_blueprint(static)
    app.register_blueprint(admin_static_file)
    if not is_debug:
        st = time.time()
        push_url_to_db(app)
        start_info_print(
            " * Routing updates saved in the database. It tasks time {} sec".
            format(int(time.time() - st)))

    celery.conf.update(app.config)
    # 请求处理
    request_process = OsrRequestProcess()
    request_process.init_request_process(app=app)
    request_process.init_babel_locale_selector(babel=babel)

    # 错误处理
    ErrorHandler(app)

    # Logger
    # Other
    log_udp = LogServerUDP()
    r = log_udp.init_app()
    if r:
        log_udp.log_server()
    weblog = WebLogger()
    weblog.init_app(app)
    if not os.path.exists(TEMP_STATIC_FOLDER):
        os.makedirs(TEMP_STATIC_FOLDER)
Esempio n. 3
0
def push_url_to_db(app):
    """
    同步url到数据库
    :param app:
    :return:
    """
    now_time = time.time()
    for rule in app.url_map.iter_rules():
        if rule.endpoint.startswith("api.") or rule.endpoint.startswith(
                "open_api."):
            type = "api"
        else:
            continue

        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)
            if r["methods"]:
                new_methods.extend(r["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
                }
            })

    urls = mdbs["sys"].dbs["sys_urls"].find({})
    for url in urls:
        if "url" in url:
            cache.delete(key="get_sys_url_url_{}".format(url['url']),
                         db_type="redis")

    # 清理已不存在的api
    mdbs["sys"].dbs["sys_urls"].delete_many({
        "type": {
            "$ne": "page"
        },
        "update_time": {
            "$lt": now_time
        }
    })
Esempio n. 4
0
def import_plugin_config(plugin_name, config):
    """
    导入插件配置到数据库,已存在的则更新时间
    :param plugin_name 插件名
    :param CONFIG:dict
    :return:
    """
    current_time = time.time()
    for k, v in config.items():
        if "value_type" not in v:
            assert Exception(
                'Plugin configuration import database error, missing "value_type"'
            )

        if "reactivate" not in v:
            v["reactivate"] = True
        if "info" not in v:
            v["info"] = ""

        # 查找相同的配置
        r = mdbs["sys"].db.plugin_config.find_one({
            "plugin_name": plugin_name,
            "key": k,
            "value_type": v["value_type"]
        })
        if not r:
            # 如果不存在
            mdbs["sys"].db.plugin_config.insert_one({
                "plugin_name":
                plugin_name,
                "key":
                k,
                "value_type":
                v["value_type"],
                "value":
                v["value"],
                "reactivate":
                v["reactivate"],
                "info":
                v["info"],
                "update_time":
                time.time()
            })
        elif r and r["update_time"] < current_time:
            # 存在, 而且比当前时间前的(防止同时启动多个进程时错乱,导致下面程序当旧数据清理)
            mdbs["sys"].db.plugin_config.update_one(
                {
                    "_id": r["_id"],
                    "update_time": {
                        "$lt": current_time
                    }
                }, {
                    "$set": {
                        "update_time": current_time,
                        "reactivate": v["reactivate"],
                        "info": v["info"]
                    }
                })

    # 删除已不需要的配置
    mdbs["sys"].db.plugin_config.delete_many({
        "plugin_name": plugin_name,
        "update_time": {
            "$lt": current_time
        }
    })
    # 更新插件配置缓存, # 删除缓存,达到更新缓存
    cache.delete(key=PLUG_IN_CONFIG_CACHE_KEY)
Esempio n. 5
0
def sys_config_edit():

    key = request.argget.all('key')
    project = request.argget.all('project')
    value = request.argget.all('value')
    info = request.argget.all('info')
    version = mdb_sys.db.sys_config.find_one(
        {"new_version": {
            "$exists": True
        }}, {"_id": 0})

    s, r = arg_verify(reqargs=[("key", key), ("project", project)],
                      required=True)
    if not s:
        return r

    old_conf = mdb_sys.db.sys_config.find_one({
        "key":
        key,
        "project":
        project,
        "conf_version":
        version["new_version"]
    })
    if not old_conf:
        data = {
            "msg": gettext("There is no such data"),
            "msg_type": "e",
            "http_status": 404
        }
    else:
        try:
            if old_conf["type"] == "int" or old_conf["type"] == "binary":
                value = int(value)
            elif old_conf["type"] == "float":
                value = float(value)
            elif old_conf["type"] == "string":
                value = str(value)
            elif old_conf["type"] == "bool":
                try:
                    value = int(value)
                    if value:
                        value = True
                    else:
                        value = False
                except:
                    pass
                if value or (isinstance(value, str)
                             and value.upper() != "FALSE"):
                    value = True
                else:
                    value = False

            elif old_conf["type"] == "list":
                # 如果不是list类型,则转为list类型
                if not isinstance(value, list):
                    #  "[]"转list
                    value = json.loads(value)
                if not isinstance(value, list):
                    # "aaa,bbb,ccc"转["aaa", "bbb", "ccc"]
                    value = value.strip(",").split(",")
                    value = [v.strip("\n") for v in value]

            elif old_conf["type"] == "dict":
                if not isinstance(value, dict):
                    value = json.loads(value)
                if not isinstance(value, dict):
                    data = {
                        "msg":
                        gettext(
                            'The format of the "value" errors, need a "{}" type'
                        ).format(old_conf["type"]),
                        "msg_type":
                        "e",
                        "http_status":
                        400
                    }
                    return data
            elif old_conf["type"] == "tuple":
                if not isinstance(value, tuple):
                    value = json.loads(value)
                if not isinstance(value, tuple):
                    data = {
                        "msg":
                        gettext(
                            'The format of the "value" errors, need a "{}" type'
                        ).format(old_conf["type"]),
                        "msg_type":
                        "e",
                        "http_status":
                        400
                    }
                    return data
            elif old_conf["type"] == "password":
                value = str(value)
            else:
                data = {
                    "msg": gettext('There is no {}').format(old_conf["type"]),
                    "msg_type": "e",
                    "http_status": 400
                }
                return data
        except Exception as e:
            data = {
                "msg":
                gettext('The format of the "value" errors, need a "{}" type').
                format(old_conf["type"]),
                "msg_type":
                "e",
                "http_status":
                400
            }
            return data
        if not info:
            info = old_conf["info"]
        conf = {"value": value, "update_time": time.time(), "info": info}

        # 更新版本
        # 解释:只要有一台服务器端重启web并更新配置, 则会把重启时最新版本加入到used_version中
        if version["new_version"] in version["used_versions"]:

            # 如果目前的最新版本号在used_version中, 则本次修改就要生成更新的配置版本
            now_version = time_to_utcdate(tformat="%Y_%m_%d_%H_%M_%S")
            old_version = mdb_sys.db.sys_config.find(
                {
                    "project": {
                        "$exists": True
                    },
                    "conf_version": version["new_version"]
                }, {"_id": 0})
            # 生成最新版本配置
            for v in old_version:
                v["conf_version"] = now_version
                mdb_sys.db.sys_config.insert_one(v)

            # 更新当前使用的最新版本号
            mdb_sys.db.sys_config.update_one(
                {"new_version": {
                    "$exists": True
                }}, {"$set": {
                    "new_version": now_version
                }})

            # 删除多余的配置版本
            ver_cnt = len(version["used_versions"])
            if ver_cnt >= 15:
                rm_vers = version["used_versions"][0:ver_cnt - 15]
                mdb_sys.db.sys_config.update_one(
                    {"new_version": {
                        "$exists": True
                    }}, {
                        "$set": {
                            "used_versions":
                            version["used_versions"][ver_cnt - 15:]
                        }
                    })
                mdb_sys.db.sys_config.delete_many(
                    {"version": {
                        "$in": rm_vers
                    }})
        else:
            # 否则, 本次修改暂不生成新配置版本
            now_version = version["new_version"]

        # 更新修改数据
        mdb_sys.db.sys_config.update_one(
            {
                "project": project,
                "key": key,
                "conf_version": now_version
            }, {"$set": conf},
            upsert=True)

        # 删除缓存,达到更新缓存
        cache.delete(CONFIG_CACHE_KEY)
        data = {
            "msg": gettext("Modify the success"),
            "msg_type": "s",
            "http_status": 201
        }
    return data
Esempio n. 6
0
def init_core_module(app):
    """
    初始化核心模块
    :param app:
    :return:
    """
    # app config
    web_start_log.info("Initialize the core module")

    # 系统必要配置, 优先导入
    app.config.from_object(ConfDictToClass(CONFIG["system"], key="value"))
    app.config.from_object(ConfDictToClass(CONFIG["key"], key="value"))

    # 数据库
    app.config.from_object(DatabaseConfig())
    for name, mdb in mdbs.items():
        mdb.init_app(app, config_prefix=name.upper())

    # 缓存
    app.config.from_object(ConfDictToClass(CONFIG["cache"], key="value"))
    app.config["CACHE_REDIS"] = redis
    app.config["CACHE_MONGODB"] = mdbs["sys"].connection
    app.config["CACHE_MONGODB_DB"] = mdbs["sys"].name
    cache.init_app(app)

    # 清除配置CONFIG的cache
    with app.app_context():
        msg = " * Clean configuration cache successfully"
        cache.delete(CONFIG_CACHE_KEY)
        cache.delete(PLUG_IN_CONFIG_CACHE_KEY)
        web_start_log.info(msg)
        print(msg)

    # 异常错误信息
    app.config["PRESERVE_CONTEXT_ON_EXCEPTION"] = PRESERVE_CONTEXT_ON_EXCEPTION

    ###################################################
    # 在此之前, 任何程序不能调用utils.get_config.py下的方法
    ###################################################

    from apps.core.utils.get_config import get_configs, get_config
    from apps.core.flask.request import OsrRequestProcess
    from apps.core.flask.errorhandler import ErrorHandler
    from apps.core.blueprint import api, admin_view, theme_view, static_html_view, static, open_api
    from apps.core.flask.routing import RegexConverter
    from apps.core.flask.routing import push_url_to_db

    # 最大请求大小
    app.config["MAX_CONTENT_LENGTH"] = get_config(
        "system", "MAX_CONTENT_LENGTH") * 1024 * 1024
    # Session会话配置
    session_config = get_configs("session")
    session_config["SESSION_PROTECTION"] = SESSION_PROTECTION
    session_config["SESSION_COOKIE_PATH"] = SESSION_COOKIE_PATH
    session_config["SESSION_COOKIE_HTTPONLY"] = SESSION_COOKIE_HTTPONLY
    session_config["SESSION_COOKIE_SECURE"] = SESSION_COOKIE_SECURE
    session_config["SESSION_USE_SIGNER"] = SESSION_USE_SIGNER
    session_config["SESSION_MONGODB_DB"] = mdbs["sys"].name

    app.config.from_object(ConfDictToClass(session_config))
    app.config["SESSION_REDIS"] = redis
    app.config["SESSION_MONGODB"] = mdbs["sys"].connection
    sess.init_app(app)
    rest_session.init_app(app)

    # 邮件
    app.config.from_object(ConfDictToClass(get_configs("email")))
    mail.init_app(app)

    # Csrf token
    csrf_config = {}
    csrf_config["CSRF_ENABLED"] = CSRF_ENABLED
    csrf_config["WTF_CSRF_CHECK_DEFAULT"] = WTF_CSRF_CHECK_DEFAULT
    csrf_config["WTF_CSRF_METHODS"] = WTF_CSRF_METHODS
    app.config.from_object(ConfDictToClass(csrf_config))
    csrf.init_app(app)

    # Babel
    app.config.from_object(ConfDictToClass(get_configs("babel")))
    app.config["BABEL_TRANSLATION_DIRECTORIES"] = BABEL_TRANSLATION_DIRECTORIES
    babel.init_app(app)

    # 登录管理
    login_manager.init_app(app)
    # login_manager.anonymous_user = AnonymousUser()
    login_manager.session_protection = SESSION_PROTECTION
    oauth.init_app(app)
    # 让路由支持正则
    app.url_map.converters['regex'] = RegexConverter

    # 注册蓝图 blueprint
    web_start_log.info("Register blueprint, Initialize the routing")
    app.register_blueprint(api)
    app.register_blueprint(open_api)
    app.register_blueprint(admin_view)
    app.register_blueprint(theme_view)
    app.register_blueprint(static_html_view)
    app.register_blueprint(static)
    push_url_to_db(app)

    # 请求处理
    request_process = OsrRequestProcess()
    request_process.init_request_process(app=app)
    request_process.init_babel_locale_selector(babel=babel)

    # 错误处理
    ErrorHandler(app)

    # Logger
    # Other
    log_udp = LogServerUDP()
    r = log_udp.init_app()
    if r:
        log_udp.log_server()
    weblog = WebLogger()
    weblog.init_app(app)
Esempio n. 7
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)
Esempio n. 8
0
def update_plugin_setting():
    '''
    获取插件设置
    :return:
    '''

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

    old_conf = mdb_sys.db.plugin_config.find_one({
        "key": key,
        "plugin_name": plugin_name
    })
    if not old_conf:
        data = {
            "msg": gettext("There is no such data"),
            "msg_type": "e",
            "http_status": 404
        }
    else:
        try:
            if old_conf["value_type"] == "int" or old_conf[
                    "value_type"] == "binary":
                value = int(value)
            elif old_conf["value_type"] == "float":
                value = float(value)
            elif old_conf["value_type"] == "string":
                value = str(value)
            elif old_conf["value_type"] == "bool":
                try:
                    value = int(value)
                    if value:
                        value = True
                    else:
                        value = False
                except:
                    pass
                if value or (isinstance(value, str)
                             and value.upper() != "FALSE"):
                    value = True
                else:
                    value = False

            elif old_conf["value_type"] == "list":
                # 如果不是list类型,则转为list类型
                if not isinstance(value, list):
                    #  "[]"转list
                    value = json.loads(value)
                if not isinstance(value, list):
                    # "aaa,bbb,ccc"转["aaa", "bbb", "ccc"]
                    value = value.strip(",").split(",")
                    value = [v.strip("\n") for v in value]

            elif old_conf["value_type"] == "dict":
                if not isinstance(value, dict):
                    value = json.loads(value)
                if not isinstance(value, dict):
                    data = {
                        "msg":
                        gettext(
                            'The format of the "value" errors, need a "{}" type'
                        ).format(old_conf["value_type"]),
                        "msg_type":
                        "e",
                        "http_status":
                        400
                    }
                    return data
            elif old_conf["value_type"] == "tuple":
                if not isinstance(value, tuple):
                    value = json.loads(value)
                if not isinstance(value, tuple):
                    data = {
                        "msg":
                        gettext(
                            'The format of the "value" errors, need a "{}" type'
                        ).format(old_conf["value_type"]),
                        "msg_type":
                        "e",
                        "http_status":
                        400
                    }
                    return data
            elif old_conf["value_type"] == "password":
                value = str(value)
            else:
                data = {
                    "msg":
                    gettext('There is no {}').format(old_conf["value_type"]),
                    "msg_type": "e",
                    "http_status": 400
                }
                return data
        except Exception as e:
            data = {
                "msg":
                gettext('The format of the "value" errors, need a "{}" type').
                format(old_conf["value_type"]),
                "msg_type":
                "e",
                "http_status":
                400
            }
            return data

        conf = {"value": value, "update_time": time.time()}

        # 更新修改数据
        mdb_sys.db.plugin_config.update_one(
            {
                "plugin_name": plugin_name,
                "key": key
            }, {"$set": conf},
            upsert=True)
        # 删除缓存,达到更新缓存
        cache.delete(PLUG_IN_CONFIG_CACHE_KEY)
        data = {
            "msg": gettext("Modify the success"),
            "msg_type": "s",
            "http_status": 201
        }
    return data
Esempio n. 9
0
def switch_theme():
    """
    切换主题
    :return:
    """

    theme_name = request.argget.all('theme_name')

    path = os.path.join(THEME_TEMPLATE_FOLDER, theme_name.strip())
    if not os.path.exists(path):
        data = {
            "msg": gettext("Theme does not exist"),
            "msg_type": "e",
            "http_status": 400
        }
        return data

    s, r = verify_theme(path, theme_name, theme_name)
    if s:
        # 更新主题数据
        mdb_sys.db.sys_config.update_many(
            {
                "project": "theme",
                "key": "CURRENT_THEME_NAME"
            }, {
                "$set": {
                    "value": theme_name.strip(),
                    "update_time": time.time()
                }
            },
            upsert=True)

        theme_info = get_one_theme_info(theme_name)
        if theme_info and "version" in theme_info:
            mdb_sys.db.sys_config.update_many(
                {
                    "project": "theme",
                    "key": "VERSION"
                }, {
                    "$set": {
                        "value": theme_info["version"],
                        "update_time": time.time()
                    }
                },
                upsert=True)

        mdb_sys.db.sys_config.update_many(
            {
                "project": "site_config",
                "key": "STATIC_FILE_VERSION"
            }, {
                "$set": {
                    "value": int(time_to_utcdate(time.time(), "%Y%m%d%H%M%S")),
                    "update_time": time.time()
                }
            },
            upsert=True)

        cache.delete(CONFIG_CACHE_KEY)
        data = {
            "msg": gettext("Switch success"),
            "msg_type": "s",
            "http_status": 201
        }
    else:
        data = {"msg": r, "msg_type": "e", "http_status": 400}
    return data
Esempio n. 10
0
def update_url():
    '''
    更新修改 url权限
    :return:
    '''
    id = 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", id)], 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:
            pass

    # 修改权限验证
    data = {
        "msg":
        gettext(
            "The current user permissions are lower than the permissions you want to modify,"
            " without permission to modify"),
        "msg_type":
        "w",
        "http_status":
        401
    }
    user_role = mdb_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 = mdb_sys.db.sys_urls.find_one({"_id": ObjectId(id)})
    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 = mdb_sys.db.sys_urls.update_one({"_id": ObjectId(id)}, {
        "$set": {
            "custom_permission.{}".format(method): permission,
            "login_auth.{}".format(method): login_auth
        }
    })
    if r.modified_count:
        # 清除缓存
        r = mdb_sys.db.sys_urls.find_one({"_id": ObjectId(id)})
        if r:
            cache.delete(key="get_sys_url_url_{}".format(r['url']),
                         db_type="redis")
        data = {
            "msg": gettext("Modify the success"),
            "msg_type": "s",
            "http_status": 201
        }
    else:
        data = {
            "msg": gettext("No modification"),
            "msg_type": "w",
            "http_status": 400
        }
    return data
Esempio n. 11
0
def add_per():

    name = request.argget.all('name', '').strip()
    explain = request.argget.all('explain')
    default = int(request.argget.all('is_default', 0).strip())
    position = str_to_num(request.argget.all('position', 0))
    data = {
        'msg': gettext("Add a success"),
        'msg_type': "s",
        "custom_status": 201
    }

    s, r = arg_verify(reqargs=[(gettext("name"), name),
                               (gettext("position"), position)],
                      required=True)
    if not s:
        return r

    hightest_pos = get_num_digits(SUPER_PER)
    permissions = int(math.pow(2, position - 1))
    if hightest_pos > hightest_pos and position < 1:
        data = {
            'msg':
            gettext("Must be an integer greater than 0,"
                    " less than or equal to {}".format(hightest_pos)),
            'msg_type':
            "w",
            "custom_status":
            403
        }

    elif mdbs["user"].db.permission.find_one({"name": name}):
        data = {
            'msg': gettext("Permission name or valready exists"),
            'msg_type': "w",
            "custom_status": 403
        }

    elif mdbs["user"].db.permission.find_one({"value": permissions}):
        data = {
            'msg': gettext('Location has been used'),
            'msg_type': "w",
            "custom_status": 403
        }
    else:
        user_role = mdbs["user"].db.role.find_one(
            {"_id": ObjectId(current_user.role_id)})
        if get_num_digits(
                user_role["permissions"]) <= get_num_digits(permissions):
            data = {
                "msg":
                gettext(
                    "The current user permissions are lower than the permissions that you want to add,"
                    " without permission to add"),
                "msg_type":
                "w",
                "custom_status":
                401
            }
            return data

        mdbs["user"].db.permission.insert_one({
            "name": name,
            "explain": explain,
            'value': permissions,
            "is_default": default
        })
        cache.delete(key=GET_DEFAULT_SYS_PER_CACHE_KEY, db_type="redis")
        cache.delete(key=GET_ALL_PERS_CACHE_KEY, db_type="redis")
    return data
Esempio n. 12
0
def delete_per():

    ids = json_to_pyseq(request.argget.all('ids'))
    user_role = mdbs["user"].db.role.find_one(
        {"_id": ObjectId(current_user.role_id)})

    unauth_del_pers = []  # 无权删除的
    preserve = []  # 必须保留的
    need_remove = []
    need_remove_per_value = []

    for tid in ids:
        tid = ObjectId(tid)
        # 权限检查
        old_per = mdbs["user"].db.permission.find_one({"_id": tid})
        # 如果当前用户的权限最高位 小于 要删除角色的权限,也是不可以
        if old_per and get_num_digits(old_per["value"]) >= get_num_digits(
                user_role["permissions"]):
            unauth_del_pers.append(old_per["name"])
            continue
        if old_per["name"] in PRESERVE_PERS or old_per["default"]:
            preserve.append(old_per["name"])
            continue
        need_remove.append(tid)
        need_remove_per_value.append(old_per["permissions"])

    # Delete
    msg_updated_rolename = ""
    if need_remove:

        mdbs["user"].db.permission.delete_many({
            "_id": {
                "$in": need_remove
            },
            "name": {
                "$nin": PRESERVE_PERS
            }
        })
        # 删除后必须更新使用了该权限的role和api&page
        updated_rolename = []
        for v in need_remove_per_value:
            r = update_role_and_api_per(old_per_value=v, new_per_value=0)
            updated_rolename.extend(r["updated_rolename"])

        msg_updated_rolename = gettext("The role of the chain reaction is: \n")
        if updated_rolename:
            updated_rolename = list(set(updated_rolename))
            for ur in updated_rolename:
                msg_updated_rolename = '{}, "{}"'.format(
                    msg_updated_rolename, ur)

        cache.delete(key=GET_DEFAULT_SYS_PER_CACHE_KEY, db_type="redis")
        cache.delete(key=GET_ALL_PERS_CACHE_KEY, db_type="redis")

    if not unauth_del_pers and not preserve:
        data = {
            'msg':
            gettext('Successfully deleted. {}'.format(msg_updated_rolename)),
            'msg_type': 'success',
            "custom_status": 204
        }
    else:
        warning_msg = ""
        if unauth_del_pers:
            warning_msg = gettext('No permission to delete {}. ').format(
                ",".join(unauth_del_pers))
        elif preserve:
            warning_msg = gettext(
                "{}{} are permissions that must be retained.").format(
                    warning_msg, ",".join(preserve))
        data = {
            'msg': warning_msg,
            'msg_type': 'warning',
            "custom_status": 400
        }

    return data
Esempio n. 13
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:
            # 标记插件为出错插件
            mdb_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 = mdb_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:
                    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:
                        # 标记插件为出错插件
                        mdb_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)

                # 更新插件信息到数据库
                mdb_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
                mdb_sys.dbs["plugin"].insert_one(plug_conf)

            # 清理遗留缓存
            cache.delete(key="get_plugin_info_hook_name_{}".format(hook_name),
                         db_type="redis")
            return True, {
                "module": module,
                "hook_name": hook_name,
                "plugin_name": plugin_name
            }
Esempio n. 14
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)
            if r["methods"]:
                new_methods.extend(r["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
                }
            })

    urls = mdbs["sys"].dbs["sys_urls"].find({})
    for url in urls:
        if "url" in url:
            cache.delete(key="get_sys_url_url_{}".format(url['url']),
                         db_type="redis")
    """
    # 清理已不存在的api
    # 时间7天是为了防止多台服务器同时启动时造成误删
    """
    ut = time.time() - 86400 * 7
    mdbs["sys"].dbs["sys_urls"].delete_many({
        "type": {
            "$ne": "page"
        },
        "update_time": {
            "$lt": ut
        }
    })