Ejemplo n.º 1
0
 def __ensure_reloaded(self):
     hlt = self.__storage.get("hookloadtime") or {}
     hlt = {int(k): v for k, v in iteritems(hlt)}
     myself = hlt.get(self._pid, 0)
     if 0 in hlt.values() or (time() - myself) > self.__MAX_RELOAD_TIME:
         self.__hooks = {}
         self.__last_load_time = time()
Ejemplo n.º 2
0
 def get_enabled_map_hooks(self):
     """Get map enabled hooks, return dict"""
     return {
         name: h
         for name, h in iteritems(self.get_map_hooks)
         if h.state == 'enabled'
     }
Ejemplo n.º 3
0
 def __last_load_time(self, timestamp):
     if not isinstance(timestamp, (integer_types, float)):
         raise TypeError("The value of last_load_time type error")
     hlt = self.__storage.get("hookloadtime") or {}
     if timestamp == 0:
         hlt = {k: 0 for k, v in iteritems(hlt)}
     else:
         hlt[self._pid] = timestamp
     self.__storage.set("hookloadtime", hlt)
Ejemplo n.º 4
0
Archivo: api.py Proyecto: qdjx/picbed
def my():
    res = dict(code=1, msg=None)
    ak = rsp("account", g.userinfo.username)
    Action = request.args.get("Action")
    if Action == "updateProfile":
        allowed_fields = ["nickname", "avatar"]
        data = {
            k: v
            for k, v in iteritems(request.form.to_dict())
            if k in allowed_fields
        }
        try:
            data.update(mtime=get_current_timestamp())
            g.rc.hmset(ak, data)
        except RedisError:
            res.update(msg="Program data storage service error")
        else:
            res.update(code=0)
            #: 更新资料触发一次钩子
            current_app.extensions["hookmanager"].call(
                "profile_update", **data
            )
    elif Action == "updatePassword":
        passwd = request.form.get("passwd")
        repasswd = request.form.get("repasswd")
        if passwd and repasswd:
            if len(passwd) < 6:
                res.update(msg="Password must be at least 6 characters")
            else:
                if passwd != repasswd:
                    res.update(msg="Confirm passwords do not match")
                else:
                    try:
                        g.rc.hmset(ak, dict(
                            password=generate_password_hash(passwd),
                        ))
                    except RedisError:
                        res.update(msg="Program data storage service error")
                    else:
                        res.update(code=0)
        else:
            res.update(msg="Parameter error")
    elif Action == "updateUserCfg":
        #: 更新用户设置,为避免覆盖ak字段,所有更新的key必须`ucfg_`开头
        cfgs = request.form.to_dict()
        if cfgs:
            for k in cfgs:
                if not k.startswith("ucfg_"):
                    res.update(msg="The user setting must start with `ucfg_`")
                    return res
            try:
                g.rc.hmset(ak, cfgs)
            except RedisError:
                res.update(msg="Program data storage service error")
            else:
                res.update(code=0)
    return res
Ejemplo n.º 5
0
def my():
    if request.method == "GET":
        return abort(404)
    res = dict(code=1)
    ak = rsp("account", g.userinfo.username)
    Action = request.args.get("Action")
    if Action == "updateProfile":
        allowed_fields = ["nickname", "avatar"]
        data = {
            k: v
            for k, v in iteritems(request.form.to_dict())
            if k in allowed_fields
        }
        try:
            data.update(mtime=get_current_timestamp())
            g.rc.hmset(ak, data)
        except RedisError:
            res.update(msg="Program data storage service error")
        else:
            res.update(code=0)
            #: 更新资料触发一次钩子
            current_app.extensions["hookmanager"].call(
                "profile_update", **data
            )
    elif Action == "updatePassword":
        passwd = request.form.get("passwd")
        repasswd = request.form.get("repasswd")
        if passwd and repasswd:
            if len(passwd) < 6:
                res.update(msg="Password must be at least 6 characters")
            else:
                if passwd != repasswd:
                    res.update(msg="Confirm passwords do not match")
                else:
                    try:
                        g.rc.hmset(ak, dict(
                            password=generate_password_hash(passwd),
                        ))
                    except RedisError:
                        res.update(msg="Program data storage service error")
                    else:
                        res.update(code=0)
        else:
            res.update(msg="Parameter error")
    return res
Ejemplo n.º 6
0
 def setmany(self, **mapping):
     if mapping and isinstance(mapping, dict):
         mapping = {k: json.dumps(v) for k, v in iteritems(mapping)}
         return self._db.hmset(self.index, mapping)
Ejemplo n.º 7
0
 def list(self):
     """list redis hash data"""
     return {
         k: json.loads(v)
         for k, v in iteritems(self._db.hgetall(self.index))
     }
Ejemplo n.º 8
0
 def setmany(self, **mapping):
     if mapping and isinstance(mapping, dict):
         db = self._open()
         for k, v in iteritems(mapping):
             db[self.__ck(k)] = v
         db.close()
Ejemplo n.º 9
0
def link():
    res = dict(code=1, msg=None)
    ltk = rsp("linktokens")
    username = g.userinfo.username

    def check_body():
        """校验post、put参数,返回值有效说明校验不通过"""
        allow_origin = request.form.get("allow_origin")
        allow_ip = request.form.get("allow_ip")
        allow_ep = request.form.get("allow_ep")
        allow_method = request.form.get("allow_method")
        er = request.form.get("exterior_relation")
        ir = request.form.get("interior_relation")
        if allow_origin:
            origins = parse_valid_comma(allow_origin)
            if not origins or not isinstance(origins, (tuple, list)):
                return "Invalid url address"
            for url in origins:
                if url and not check_origin(url):
                    return "Invalid url address"
        if allow_ip:
            ips = parse_valid_comma(allow_ip)
            if not ips or not isinstance(ips, (tuple, list)):
                return "Invalid IP address"
            for ip in ips:
                if ip and not check_ip(ip):
                    return "Invalid IP address"
        if allow_ep:
            eps = parse_valid_comma(allow_ep)
            if not eps or not isinstance(eps, (tuple, list)):
                return "Not found the endpoint"
            for ep in eps:
                if ep and ep not in current_app.view_functions.keys():
                    return "Not found the endpoint"
        if allow_method:
            methods = parse_valid_comma(allow_method)
            if not methods or not isinstance(methods, (tuple, list)):
                return "Invalid HTTP method"
            for md in methods:
                if md and md.upper() not in ["GET", "POST", "PUT", "DELETE"]:
                    return "Invalid HTTP method"
        if er:
            if not er_pat.match(er.strip()):
                return "Invalid exterior_relation"
        if ir:
            if not ir_pat.match(ir.strip()):
                return "Invalid interior_relation"
            else:
                try:
                    check_ir(ir)
                except (ValueError, TypeError):
                    return "Invalid interior_relation"

    if request.method == "GET":
        is_mgr = is_true(request.args.get("is_mgr"))
        linktokens = g.rc.hgetall(ltk)
        pipe = g.rc.pipeline()
        for ltid, usr in iteritems(linktokens):
            if is_mgr and g.is_admin:
                pipe.hgetall(rsp("linktoken", ltid))
            else:
                if username == usr:
                    pipe.hgetall(rsp("linktoken", ltid))
        try:
            result = pipe.execute()
        except RedisError:
            res.update(msg="Program data storage service error")
        else:
            res.update(code=0, data=result, count=len(result))

    elif request.method == "POST":
        comment = request.form.get("comment") or ""
        #: 定义此引用上传图片时默认设置的相册名
        album = request.form.get("album") or ""
        #: 定义以下几个权限之间的允许访问条件,opt and/or/not opt
        er = request.form.get("exterior_relation", "").strip()
        #: 定义权限内部允许访问条件 in/not in:opt,
        ir = request.form.get("interior_relation", "").strip()
        #: 定义权限项及默认值,检测参数时不包含默认值
        allow_origin = request.form.get("allow_origin") or ""
        allow_ip = request.form.get("allow_ip") or ""
        allow_ep = request.form.get("allow_ep") or "api.upload"
        allow_method = request.form.get("allow_method") or "post"
        #: 判断用户是否有token
        ak = rsp("account", username)
        if not g.rc.hget(ak, "token"):
            res.update(msg="No tokens yet")
            return res
        cv = check_body()
        if cv:
            res.update(msg=cv)
            return res
        if allow_origin:
            allow_origin = ",".join([
                get_origin(url) for url in parse_valid_comma(allow_origin)
                if url
            ])
        #: 生成一个引用
        LinkId = gen_uuid()
        LinkSecret = generate_password_hash(LinkId)
        lid = "%s:%s:%s" % (get_current_timestamp(), LinkId,
                            hmac_sha256(LinkId, LinkSecret))
        LinkToken = b64encode(lid.encode("utf-8")).decode("utf-8")
        pipe = g.rc.pipeline()
        pipe.hset(ltk, LinkId, username)
        pipe.hmset(
            rsp("linktoken", LinkId),
            dict(
                LinkId=LinkId,
                LinkSecret=LinkSecret,
                LinkToken=LinkToken,
                ctime=get_current_timestamp(),
                user=username,
                comment=comment,
                album=album,
                status=1,  # 状态,1是启用,0是禁用
                allow_origin=allow_origin,
                allow_ip=allow_ip,
                allow_ep=allow_ep,
                allow_method=allow_method,
                exterior_relation=er,
                interior_relation=ir,
            ))
        try:
            pipe.execute()
        except RedisError:
            res.update(msg="Program data storage service error")
        else:
            res.update(code=0, LinkToken=LinkToken)

    elif request.method == "PUT":
        LinkId = request.form.get("LinkId")
        Action = request.args.get("Action")
        key = rsp("linktoken", LinkId)
        if Action == "disable":
            try:
                g.rc.hset(key, "status", 0)
            except RedisError:
                res.update(msg="Program data storage service error")
            else:
                res.update(code=0)
            return res
        elif Action == "enable":
            try:
                g.rc.hset(key, "status", 1)
            except RedisError:
                res.update(msg="Program data storage service error")
            else:
                res.update(code=0)
            return res
        if LinkId and g.rc.exists(key):
            comment = request.form.get("comment") or ""
            album = request.form.get("album") or ""
            er = request.form.get("exterior_relation", "").strip()
            ir = request.form.get("interior_relation", "").strip()
            allow_origin = request.form.get("allow_origin") or ""
            allow_ip = request.form.get("allow_ip") or ""
            allow_ep = request.form.get("allow_ep") or "api.upload"
            allow_method = request.form.get("allow_method") or "post"
            cv = check_body()
            if cv:
                res.update(msg=cv)
                return res
            if allow_origin:
                allow_origin = ",".join([
                    get_origin(url) for url in parse_valid_comma(allow_origin)
                    if url
                ])
            pipe = g.rc.pipeline()
            pipe.hset(ltk, LinkId, username)
            pipe.hmset(
                key,
                dict(
                    mtime=get_current_timestamp(),
                    comment=comment,
                    album=album,
                    allow_origin=allow_origin,
                    allow_ip=allow_ip,
                    allow_ep=allow_ep,
                    allow_method=allow_method,
                    exterior_relation=er,
                    interior_relation=ir,
                ))
            try:
                pipe.execute()
            except RedisError:
                res.update(msg="Program data storage service error")
            else:
                res.update(code=0)
        else:
            res.update(msg="Not found the LinkId")

    elif request.method == "DELETE":
        LinkId = request.form.get("LinkId")
        if LinkId:
            pipe = g.rc.pipeline()
            pipe.hdel(ltk, LinkId)
            pipe.delete(rsp("linktoken", LinkId))
            try:
                pipe.execute()
            except RedisError:
                res.update(msg="Program data storage service error")
            else:
                res.update(code=0)
        else:
            res.update(msg="Parameter error")

    return res
Ejemplo n.º 10
0
    The program configuration file, the preferred configuration item,
    reads the system environment variable first.

    :copyright: (c) 2019 by staugur.
    :license: BSD 3-Clause, see LICENSE for more details.
"""

from os import getenv, environ
from os.path import isfile, dirname, join
from utils._compat import iteritems, Properties

ENV = join(dirname(__file__), ".env")
if isfile(ENV):
    envs = Properties(ENV).getProperties()
    if envs and isinstance(envs, dict):
        for k, v in iteritems(envs):
            if k and v:
                environ[k] = v

GLOBAL = {

    "ProcessName": "picbed",
    # 自定义进程名.

    "Host": getenv("picbed_host", "127.0.0.1"),
    # 监听地址

    "Port": int(getenv("picbed_port", 9514)),
    # 监听端口

    "LogLevel": getenv("picbed_loglevel", "DEBUG"),
Ejemplo n.º 11
0
def my():
    res = dict(code=1, msg=None)
    ak = rsp("account", g.userinfo.username)
    Action = request.args.get("Action")
    if Action == "updateProfile":
        #: 基于资料本身进行的统一更新
        allowed_fields = ["nickname", "avatar", "email"]
        data = {
            k: v
            for k, v in iteritems(request.form.to_dict())
            if k in allowed_fields
        }
        data.update(mtime=get_current_timestamp())
        if is_true(g.userinfo.email_verified) and \
                data.get("email") != g.userinfo.email:
            data["email_verified"] = 0
        try:
            g.rc.hmset(ak, data)
        except RedisError:
            res.update(msg="Program data storage service error")
        else:
            res.update(code=0)
            #: 更新资料触发一次钩子
            current_app.extensions["hookmanager"].call("profile_update",
                                                       _kwargs=data)
    elif Action == "updatePassword":
        passwd = request.form.get("passwd")
        repasswd = request.form.get("repasswd")
        if passwd and repasswd:
            if len(passwd) < 6:
                res.update(msg="Password must be at least 6 characters")
            else:
                if passwd != repasswd:
                    res.update(msg="Confirm passwords do not match")
                else:
                    try:
                        g.rc.hmset(
                            ak,
                            dict(password=generate_password_hash(passwd), ))
                    except RedisError:
                        res.update(msg="Program data storage service error")
                    else:
                        res.update(code=0)
        else:
            res.update(msg="Parameter error")
    elif Action == "updateUserCfg":
        #: 更新用户设置,为避免覆盖ak字段,所有更新的key必须`ucfg_`开头
        cfgs = request.form.to_dict()
        if cfgs:
            for k in cfgs:
                if not k.startswith("ucfg_"):
                    res.update(msg="The user setting must start with `ucfg_`")
                    return res
            try:
                g.rc.hmset(ak, cfgs)
            except RedisError:
                res.update(msg="Program data storage service error")
            else:
                res.update(code=0)
    elif Action == "leaveMessage":
        message = request.form.get("message")
        if message:
            try:
                g.rc.hset(ak, "message", message)
            except RedisError:
                res.update(msg="Program data storage service error")
            else:
                res.update(code=0)
    elif Action == "verifyEmail":
        html = make_email_tpl("activate_email.html",
                              activate_url=url_for(
                                  "front.activate",
                                  token=generate_activate_token(
                                      dict(
                                          Action=Action,
                                          username=g.userinfo.username,
                                          email=g.userinfo.email,
                                      )),
                                  _external=True,
                              ))
        res = sendmail(
            subject="{}邮箱验证".format(g.cfg.title_name or "picbed图床"),
            message=html,
            to=g.userinfo.email,
        )
    return res
Ejemplo n.º 12
0
def user():
    """Manage users.

    .. versionadded:: 1.6.0
    """
    res = dict(code=1, msg=None)
    ak = rsp("accounts")
    if request.method == "GET":
        #: 查询用户
        sort = request.args.get("sort") or "desc"
        page = request.args.get("page") or 1
        limit = request.args.get("limit") or 10
        try:
            page = int(page) - 1
            limit = int(limit)
            if page < 0:
                raise ValueError
        except (ValueError, TypeError):
            res.update(code=2, msg="Parameter error")
        else:
            fds = ("username", "nickname", "avatar", "ctime", "mtime",
                   "is_admin", "status", "message", "email", "email_verified",
                   "status_reason")
            pipe = g.rc.pipeline()
            for u in g.rc.smembers(ak):
                pipe.hmget(rsp("account", u), *fds)
                pipe.scard(rsp("index", "user", u))
            try:
                data = pipe.execute()
            except RedisError:
                res.update(msg="Program data storage service error")
            else:

                def fmt(d):
                    d, user_pics = d
                    d = dict(zip(fds, d))
                    if d.get("status") is None:
                        d["status"] = 1
                    if d.get("email_verified") is None:
                        d["email_verified"] = 0
                    d.update(
                        is_admin=is_true(d["is_admin"]),
                        ctime=int(d["ctime"]),
                        status=int(d.get("status", 1)),
                        email_verified=int(d.get("email_verified", 1)),
                    )
                    if d.get("mtime"):
                        d["mtime"] = int(d["mtime"])
                    d["pics"] = user_pics
                    return d

                data = [fmt(d) for d in list_equal_split(data, 2)]
                data = sorted(data,
                              key=lambda k: k.get('ctime', 0),
                              reverse=False if sort == "asc" else True)
                count = len(data)
                data = list_equal_split(data, limit)
                pageCount = len(data)
                if page < pageCount:
                    res.update(
                        code=0,
                        count=count,
                        data=data[page],
                        pageCount=pageCount,
                    )
                else:
                    res.update(code=3, msg="No data")
    elif request.method == "DELETE":
        #: 删除用户
        username = request.form.get("username")
        if username:
            #: 不能自己删除自己
            if username == g.userinfo.username:
                res.update(code=4, msg="No valid username found")
                return res
            if g.rc.sismember(ak, username):
                pipe = g.rc.pipeline()
                pipe.srem(ak, username)
                pipe.delete(rsp("account", username))
                #: 删除用户相关数据
                # 删除图片
                uk = rsp("index", "user", username)
                for sha in g.rc.smembers(uk):
                    pipe.delete(rsp("image", sha))
                pipe.delete(uk)
                # 删除linktoken
                lk = rsp("linktokens")
                for ltid, usr in iteritems(g.rc.hgetall(lk)):
                    if usr == username:
                        pipe.hdel(lk, ltid)
                        pipe.delete(rsp("linktoken", ltid))
                # 删除统计
                pipe.delete(rsp("report", "linktokens", username))
                try:
                    pipe.execute()
                except RedisError:
                    res.update(msg="Program data storage service error")
                else:
                    res.update(code=0)
            else:
                res.update(code=3, msg="No valid username found")
        else:
            res.update(code=2, msg="No valid username found")
    elif request.method == "PUT":
        Action = request.args.get("Action")
        username = request.form.get("username")
        if Action in ("reviewOK", "reviewFail", "disable", "enable"):
            if username:
                if g.rc.sismember(ak, username):
                    #: 目前reviewFail时有用,拒绝理由
                    reason = ""
                    if Action == "reviewOK":
                        s = 1
                    elif Action == "reviewFail":
                        s = -2
                        reason = request.form.get("reason")
                    elif Action == "disable":
                        s = 0
                    else:
                        s = 1
                    uk = rsp("account", username)
                    pipe = g.rc.pipeline()
                    pipe.hset(uk, "status", s)
                    if reason:
                        pipe.hset(uk, "status_reason", reason)
                    try:
                        pipe.execute()
                    except RedisError:
                        res.update(msg="Program data storage service error")
                    else:
                        res.update(code=0)
                else:
                    res.update(code=3, msg="No valid username found")
            else:
                res.update(code=2, msg="No valid username found")
        elif Action == "admin":
            adm = 1 if is_true(request.form.get("is_admin")) else 0
            if username:
                if username != g.userinfo.username and \
                        g.rc.sismember(ak, username):
                    try:
                        g.rc.hset(rsp("account", username), "is_admin", adm)
                    except RedisError:
                        res.update(msg="Program data storage service error")
                    else:
                        res.update(code=0)
                else:
                    res.update(code=3, msg="No valid username found")
            else:
                res.update(code=2, msg="No valid username found")
    return res