def ssoCreateTicket(self, sid=None, agent=None, ip=None): """创建授权令牌写入redis 说明: 授权令牌:临时鉴别使用,有效期3min,写入令牌集合中。 参数: sid str: 当None时表明未登录,此时ticket是首次产生;当真时,说明已登录,此时ticket非首次产生,其值需要设置为有效的sid """ ticket = gen_requestId() init = dict(last=get_current_timestamp()) if sid else dict( ctime=get_current_timestamp(), agent=agent, ip=ip) sid = sid or md5(ticket) tkey = "passport:sso:ticket:{}".format(ticket) skey = "passport:sso:sid:{}".format(sid) try: pipe = self.redis.pipeline() pipe.set(tkey, sid) #tkey过期,ticket授权令牌过期,应当给个尽可能小的时间,并且ticket使用过后要删除(一次性有效) pipe.expire(tkey, 180) #skey初始化数据 pipe.hmset(skey, init) #skey过期,即cookie过期,设置为jwt过期秒数,每次创建ticket都要更新过期时间 pipe.expire(skey, SYSTEM["SESSION_EXPIRE"]) pipe.execute() except Exception, e: logger.error(e, exc_info=True)
def execute_cleanCrawlHuaban(): """执行清理花瓣网插件目录下过期的压缩文件""" huabandir = os.path.join(basedir, "plugins", "CrawlHuaban") for root in os.listdir(huabandir): board_id, root = root, os.path.join(huabandir, root) if os.path.isdir(root): # 判断是否锁目录中 lock = False if os.path.exists(os.path.join(root, "board.lock")): lock = True logger.cli.info("Locking for {}".format(root)) for f in os.listdir(root): filepath = os.path.join(root, f) if ".zip" == os.path.splitext(f)[-1]: timestamp = int(os.path.splitext(f)[0].split("_")[-1]) if timestamp_after_timestamp( timestamp, hours=24) <= get_current_timestamp(): logger.cli.info("Remove zip file: {}".format(filepath)) try: os.remove(filepath) _sb.mysql_write.update( "update plugin_crawlhuaban set status=2,mtime=%s where board_id=%s and filename=%s", get_current_timestamp(), board_id, f) except Exception, e: logger.cli.error(e, exc_info=True) else: if lock is False: os.remove(filepath) try: os.rmdir(root) except OSError: pass
def Add(self, host, port, user, passwd, sd, ris=''): """添加一个服务 @param host,port,user,passwd,分别对应db的地址:端口:用户:密码 @param sd str: 这个db的描述 @param ris str: 即推荐的inception的地址:端口,例如127.0.0.1:6669,端口默认6669 """ res = dict(msg=None, code=1) if ris: ihost, iport = ris.split(":") if ":" in ris else (ris, 6669) if not ip_check(ihost) or not number_check(iport): res.update(msg="Invaild ris") return res if sd and host and port and user and passwd: if " " in passwd or "%" in passwd: res.update(msg="Password has spaces or %") return res if number_check(port): sql = "INSERT INTO incetops_db (sd,host,port,user,passwd,ris,ctime) VALUES(%s,%s,%s,%s,%s,%s,%s)" try: self.mysql.insert(sql, sd, host, port, user, self.Encrypt(passwd), ris, get_current_timestamp()) except IntegrityError: res.update(msg="DB connection already exists") except Exception, e: logger.error(e, exc_info=True) res.update(msg="System exception") else: res.update(code=0) else: res.update(msg="Invaild db port")
def exec_createuser(username, password, **kwargs): """创建账号""" ak = rsp("accounts") if check_username(username): if not password or len(password) < 6: echo("密码最少6位", "yellow") else: rc = create_redis_engine() if rc.sismember(ak, username): echo("用户名已存在", "red") else: is_admin = kwargs.pop("is_admin", 0) uk = rsp("account", username) pipe = rc.pipeline() pipe.sadd(ak, username) if kwargs: pipe.hmset(uk, kwargs) pipe.hmset( uk, dict(username=username, password=generate_password_hash(password), is_admin=1 if is_true(is_admin) else 0, ctime=get_current_timestamp())) try: pipe.execute() except RedisError as e: echo(e.message, "red") else: echo("注册成功!", "green") finally: rc.connection_pool.disconnect() else: echo("用户名不合法或不允许注册", "yellow")
def test_utils(self): self.assertEqual("900150983cd24fb0d6963f7d28e17f72", md5("abc")) self.assertEqual("a9993e364706816aba3e25717850c26c9cd0d89d", sha1("abc")) self.assertEqual("picbed:a:b", rsp("a", "b")) self.assertEqual(parse_valid_comma("a,b, c,"), ["a", "b", "c"]) self.assertEqual(parse_valid_verticaline("a|b| c"), ["a", "b", "c"]) self.assertTrue(is_true(1)) self.assertTrue(is_true("on")) self.assertTrue(is_true("true")) self.assertFalse(is_true(0)) self.assertIsInstance(get_current_timestamp(), int) self.assertTrue(allowed_file("test.PNG")) self.assertTrue(allowed_file(".jpeg")) self.assertFalse(allowed_file("my.psd")) self.assertFalse(allowed_file("ha.gif", ["jpg"])) self.assertFalse(allowed_file("ha.jpeg", ["jpg"])) self.assertFalse(allowed_file("ha.png", ["jpg"])) self.assertTrue(allowed_file("ha.jpg", ["jpg"])) v = "6afa9046a9579cad143a384c1b564b9a250d27d6f6a63f9f20bf3a7594c9e2c6" self.assertEqual(v, hmac_sha256('key', 'text')) self.assertEqual(v, hmac_sha256(b'key', b'text')) self.assertEqual(v, hmac_sha256(u'key', u'text')) self.assertEqual( "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad", sha256("abc"))
def putClick(): if request.method == "POST": res = dict(success=False, msg=None) try: #site站点,花瓣网1、堆糖网2 site = int(request.form.get("site", 0)) #version脚本版本 version = request.form.get("version", "") #以下board同album,不区分 total_number = int(request.form.get("total_number", 0)) pin_number = int(request.form.get("pin_number", 0)) board_id = str(request.form.get("board_id", "")) user_id = str(request.form.get("user_id", "")) downloadMethod = int(request.form.get("downloadMethod", "0")) if not board_id: raise ValueError except ValueError: res.update(msg="Invalid format") except Exception: res.update(msg="Unknown error") else: pb.asyncQueue.enqueue_call( func=CountDownloadBoard, args=(site, version, total_number, pin_number, board_id, user_id, downloadMethod, get_current_timestamp(), request.headers.get('X-Real-Ip', request.remote_addr), request.headers.get("User-Agent"))) res.update(success=True) logger.sys.info(res) return jsonify(res)
def push_message(self, uid, msgContent, msgType="system"): """ 推送一条站内消息 @param msgContent str: 消息内容,允许部分html标签,参见`ALLOWED_TAGS` @param msgType str: 消息类型 """ res = dict(code=1, msg=None) if uid and msgContent and msgType and isinstance( msgContent, (unicode, str)) and msgType in self.ALLOWED_MSGTYPE: msgId = gen_token().lower() msgTime = get_current_timestamp() msgContent = bleach.clean(msgContent, tags=self.ALLOWED_TAGS, attributes=self.ALLOWED_ATTRIBUTES, styles=self.ALLOWED_STYLES) try: pipe = self.redis.pipeline() pipe.zadd(self.gen_usermsgKey(uid), msgId, msgTime) pipe.hmset( self.gen_usermsgIdKey(msgId), dict(msgId=msgId, msgContent=msgContent, msgTime=msgTime, msgType=msgType, msgStatus=1)) pipe.execute() except Exception, e: logger.error(e, exc_info=True) res.update(msg="System is abnormal", code=2) else: res.update(code=0)
def upload_view(): res = dict(code=-1, msg=None) logger.debug(request.files) f = request.files.get('file') if f and allowed_file(f.filename): filename = secure_filename(gen_rnd_filename() + "." + f.filename.split('.')[-1]) #随机命名 basedir = Upyun['basedir'] if Upyun['basedir'].startswith( '/') else "/" + Upyun['basedir'] imgUrl = os.path.join(basedir, filename) try: upres = api.put(imgUrl, f.stream.read()) except Exception, e: logger.error(e, exc_info=True) res.update(code=2, msg="Storage failure") else: imgId = md5(filename) imgUrl = Upyun['dn'].strip("/") + imgUrl upres.update(ctime=get_current_timestamp(), imgUrl=imgUrl, imgId=imgId) try: pipe = g.redis.pipeline() pipe.sadd(picKey, imgId) pipe.hmset("{}:{}".format(GLOBAL['ProcessName'], imgId), upres) pipe.execute() except Exception, e: logger.error(e, exc_info=True) res.update( code=0, msg= "It has been uploaded, but the server has encountered an unknown error" ) else:
def like(self, blogId, userId, loginStatus): """点赞 @param blogId int: 博客id @param userId str: 登录时用户id,未登录时浏览器指纹 @param loginStatus int: 登录状态,0未登录 1已登录 数据规则: 1. 每个blogId是一个set,set中存userId。 2. 每个userId是一个hash,格式是:{userId: xx, blogId: xx, loginStatus: 0未登录、1已登录, likeTime: 时间戳} 3. 取消赞即删除userId及hash数据 """ res = dict(code=1, msg=None) if self.has(blogId, userId): res.update(code=0, msg="Already praised") else: if self.check(blogId) and loginStatus in (0, 1): key = self.genIndexKey(blogId) pipe = self.redis.pipeline() pipe.sadd(key, userId) pipe.hmset( self.genSecondKey(blogId, userId), dict(userId=userId, blogId=blogId, loginStatus=loginStatus, likeTime=get_current_timestamp())) try: pipe.execute() except Exception, e: self.logger.error(e, exc_info=True) res.update(code=2) else: res.update(code=0) else:
def Record_ip_pv(self, **kwargs): """ 记录ip、ip、uv """ data = { "status_code": kwargs.get("response").status_code, "method": request.method, "ip": g.ip, "url": request.url, "referer": request.headers.get('Referer'), "agent": request.headers.get("User-Agent"), "TimeInterval": "%0.2fs" % float(time.time() - g.startTime), "clickTime": get_current_timestamp() } self.logger.info(data) pvKey = "passport:AccessCount:pv" ipKey = "passport:AccessCount:ip:{}".format(self.get_today) uvKey = "passport:AccessCount:uv" clickKey = "passport:AccessCount:clicklog" pipe = self.redis.pipeline() pipe.hincrby(pvKey, self.get_today, 1) pipe.sadd(ipKey, data.get("ip")) pipe.hincrby(uvKey, request.base_url, 1) pipe.rpush(clickKey, json.dumps(data)) try: pipe.execute() except: pass
def login(): res = dict(code=1, msg=None) usr = request.form.get("username") pwd = request.form.get("password") #: 定义是否设置cookie状态 set_state = is_true(request.form.get("set_state")) is_secure = False if request.url_root.split("://")[0] == "http" else True max_age = 7200 if is_true(request.form.get("remember")): #: Remember me 7d max_age = 604800 #: 登录接口钩子 try: if g.cfg.site_auth: so = current_app.extensions["hookmanager"].proxy(g.cfg.site_auth) if so and hasattr(so, "login_api"): result = so.login_api(usr, pwd, set_state, max_age, is_secure) if result and isinstance(result, Response): return result except (ValueError, TypeError, Exception) as e: logger.warning(e, exc_info=True) if usr and username_pat.match(usr) and pwd and len(pwd) >= 6: ak = rsp("accounts") usr = usr.lower() if g.rc.sismember(ak, usr): userinfo = g.rc.hgetall(rsp("account", usr)) if is_true(g.cfg.disable_login) and \ not is_true(userinfo.get("is_admin")): res.update(msg="Normal user login has been disabled") return res password = userinfo.get("password") if password and check_password_hash(password, pwd): expire = get_current_timestamp() + max_age sid = "%s.%s.%s" % (usr, expire, sha256("%s:%s:%s:%s" % (usr, password, expire, current_app.config["SECRET_KEY"]))) sid = b64encode(sid.encode("utf-8")).decode("utf-8") res.update( code=0, sid=sid, expire=expire, # is_admin=is_true(userinfo.get("is_admin")) ) if set_state: res = make_response(jsonify(res)) res.set_cookie(key="dSid", value=sid, max_age=max_age, httponly=True, secure=is_secure) else: res.update(msg="Password verification failed") else: res.update(msg="No valid username found") else: res.update(msg="The username or password parameter error") return res
def __signUp_transacion(self, guid, identifier, identity_type, certificate, verified, register_ip="", expire_time=0, use_profile_sql=True, define_profile_sql=None): ''' begin的方式使用事务注册账号, 参数: @param guid str: 系统账号唯一标识 @param identifier str: 手机号、邮箱或第三方openid @param identity_type int: 账号类型,参见`oauth2_name2type`函数 @param certificate str: 加盐密码或第三方access_token @param verified int: 是否已验证 0-未验证 1-已验证 @param register_ip str: 注册IP地址 @param expire_time int: 特指OAuth过期时间戳,暂时保留 @param use_profile_sql bool: 定义是否执行define_profile_sql @param define_profile_sql str: 自定义写入`user_profile`表的sql(需要完整可直接执行SQL) 流程: 1、写入`user_auth`表 2、写入`user_profile`表 返回字典: success bool 表示注册是否成功; msg str 表示提示信息。 ''' res = dict(success=False, msg=None) # 校验 if guid and identifier and \ identity_type and \ certificate and \ verified and \ isinstance(guid, (str, unicode)) and \ len(guid) == 22 and \ identity_type in (0, 1, 2, 3, 4, 5, 6, 7, 8, 9) and \ verified in (1, 0): ctime = get_current_timestamp() try: logger.debug("transaction, start") self.db._db.begin() try: sql_1 = "INSERT INTO user_auth (uid, identity_type, identifier, certificate, verified, status, ctime, etime) VALUES (%s, %s, %s, %s, %s, %s, %s, %s)" info = self.db.insert(sql_1, guid, identity_type, identifier, certificate, verified, 1, ctime, expire_time) except IntegrityError: res.update(msg="Account already exists") except Exception, e: logger.error(e, exc_info=True) res.update(msg="System is abnormal") else: if use_profile_sql is True: if define_profile_sql: sql_2 = define_profile_sql logger.info("execute define_profile_sql: {}".format(sql_2)) try: info = self.db.execute(sql_2) except: raise else: sql_2 = "INSERT INTO user_profile (uid, register_source, register_ip, ctime, is_realname, is_admin) VALUES (%s, %s, %s, %s, %s, %s)" try: info = self.db.insert(sql_2, guid, identity_type, register_ip, ctime, 0, 0) except: raise logger.debug('transaction, commit') self.db._db.commit()
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
def gen_token(): return b64encode( ("%s.%s.%s.%s" % ( generate_random(), usr, get_current_timestamp(), hmac_sha256(g.rc.hget(ak, "password"), usr) )).encode("utf-8") ).decode("utf-8") Action = request.args.get("Action")
def index(): if request.method == "GET": """ 下载图片压缩文件 :board_id(str): 下载分类(子)目录,比如attachment、script :filename(str): 下载的实际文件(不需要目录,目录由catalog指定),包含扩展名 当前目录是EauDouce/src/plugins/CrawlHuaban/,作为根。 1. 以board_id为子,进去子目录下载保存; 2. 返回根目录,压缩board_id目录成文件,再移动到board_id下。 """ # 下载画板 board_id = secure_filename(str(request.args.get("board_id", ""))) # 下载文件名 filename = secure_filename(request.args.get("filename", "")) if board_id and filename: # 下载文件存放目录 directory = os.path.join(basedir, board_id) logger.sys.debug( "Want to download a file with directory: {0}, filename: {1}". format(directory, filename)) headers = ("Content-Disposition", "attachment;filename={}".format(filename)) if os.path.isfile(os.path.join(directory, filename)): pb.asyncQueue.enqueue_call(func=DownloadBoardAddTimes, args=(board_id, filename, get_current_timestamp())) response = make_response( send_from_directory(directory=directory, filename=filename, as_attachment=True)) response.headers[headers[0]] = headers[1] else: response = make_response("Not Found File") else: response = make_response("Invalid Download Request") return response else: res = dict(success=False, msg=None) try: #site站点,花瓣网1、堆糖网2 site = int(request.form.get("site", 1)) #version脚本版本 version = request.form.get("version", "") #以下board同album,不区分 board_id = str(request.form.get("board_id", "")) board_pins = json.loads(request.form.get("pins")) board_total = int(request.form.get("board_total", 0)) if board_id and board_pins: if not isinstance(board_pins, (list, tuple)): raise ValueError else: raise ValueError except ValueError: res.update(msg=u"无效数据格式") except Exception, e: logger.sys.error(e, exc_info=True) res.update(msg=u"未知错误, 请联系作者[email protected]反馈,谢谢!") else:
def token(): if request.method == "GET": return abort(404) res = dict(code=1) usr = g.userinfo.username tk = rsp("tokens") ak = rsp("account", usr) #: 生成token gen_token = lambda: b64encode( ("%s.%s.%s.%s" % (generate_random(), usr, get_current_timestamp(), hmac_sha256(g.rc.hget(ak, "password"), usr))).encode( "utf-8")).decode("utf-8") Action = request.args.get("Action") if Action == "create": if g.rc.hget(ak, "token"): res.update(msg="Existing token") else: token = gen_token() try: pipe = g.rc.pipeline() pipe.hset(tk, token, usr) pipe.hset(ak, "token", token) pipe.execute() except RedisError: res.update(msg="Program data storage service error") else: res.update(code=0, token=token) elif Action == "revoke": token = g.rc.hget(ak, "token") if token: try: pipe = g.rc.pipeline() pipe.hdel(tk, token) pipe.hdel(ak, "token") pipe.execute() except RedisError: res.update(msg="Program data storage service error") else: res.update(code=0) else: res.update(msg="No tokens yet") elif Action == "reset": oldToken = g.rc.hget(ak, "token") token = gen_token() try: pipe = g.rc.pipeline() if oldToken: pipe.hdel(tk, oldToken) pipe.hset(tk, token, usr) pipe.hset(ak, "token", token) pipe.execute() except RedisError: res.update(msg="Program data storage service error") else: res.update(code=0, token=token) return res
def gen_token(key): """生成可以用key校验的token""" return b64encode( ("%s.%s.%s.%s" % ( generate_random(), usr, get_current_timestamp(), hmac_sha256(key, usr) )).encode("utf-8") ).decode("utf-8")
def _set_label(label, user): """新建标签""" try: pipe = g.redis.pipeline() pipe.sadd(current_app.config["labelKey"], label) pipe.hmset( "{}:label:{}".format(GLOBAL['ProcessName'], label), dict(user=user, ctime=get_current_timestamp(), label=label)) pipe.execute() except Exception, e: logger.error(e, exc_info=True) return False
def bindEmailOrPhone(): res = dict(success=False) sql = "INSERT INTO user_auth (uid, identity_type, identifier, certificate, verified, status, ctime) VALUES (%s, %s, %s, %s, %s, %s, %s)" try: self.db.insert(sql, uid, identity_type, account, generate_password_hash(password), 1, 1, get_current_timestamp()) except IntegrityError: res.update(msg="Account already bind") except Exception, e: logger.error(e, exc_info=True) res.update(msg="System is abnormal")
def oauth2_signUp(self, openid, register_ip): """OAuth直接登录时注册入系统 @param openid str: 加密的openid,用以获取缓存中数据userinfo,格式是: userinfo dict: 用户信息,必须包含`openid`,`identity_type`,`avatar`,`nick_name` @param register_ip str: 注册IP地址 """ res = dict(msg=None, success=False) userinfo = self.__oauth2_getUserinfo(openid) logger.debug(userinfo) logger.debug(type(userinfo)) if userinfo and isinstance( userinfo, dict ) and "avatar" in userinfo and "nick_name" in userinfo and "openid" in userinfo and "access_token" in userinfo and "identity_type" in userinfo: openid = userinfo["openid"] access_token = userinfo["access_token"] identity_type = int(userinfo["identity_type"]) avatar = userinfo["avatar"] nick_name = userinfo["nick_name"] gender = userinfo.get("gender") or 2 domain_name = userinfo.get("domain_name") or "" signature = userinfo.get("signature") or "" location = userinfo.get("location") or "" expire_time = userinfo.get("expire_time") or 0 guid = gen_uniqueId() logger.debug( "check test: guid length: {}, identifier: {}, identity_type:{}, identity_type: {}, certificate: {}" .format(len(guid), openid, identity_type, type(identity_type), access_token)) define_profile_sql = "INSERT INTO user_profile (uid, register_source, register_ip, nick_name, domain_name, gender, signature, avatar, location, create_time, is_realname, is_admin) VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s')" % ( guid, identity_type, register_ip, nick_name, domain_name, gender, signature, avatar, location, get_current_timestamp(), 0, 0) upts = self.__signUp_transacion( guid=guid, identifier=openid, identity_type=identity_type, certificate=access_token, verified=1, register_ip=register_ip, expire_time=expire_time, define_profile_sql=define_profile_sql) logger.warn(upts) res.update(upts) if res["success"]: self.__oauth2_delUserinfo(openid) res.update(identity_type=identity_type, uid=guid) else: res.update(msg="Check failed") logger.info(res) return res
def upload_view(): res = dict(code=-1, msg=None) label = request.args.get("label") _has_label = lambda label: g.redis.sismember( current_app.config["labelKey"], label ) and g.redis.exists("{}:label:{}".format(GLOBAL['ProcessName'], label) ) or label == current_app.config["labelDefault"] if not label: label = current_app.config["labelDefault"] if label and _has_label(label): f = request.files.get('file') if f and allowed_file(f.filename): filename = secure_filename(gen_rnd_filename() + "." + f.filename.split('.')[-1]) #随机命名 basedir = Upyun['basedir'] if Upyun['basedir'].startswith( '/') else "/" + Upyun['basedir'] imgUrl = os.path.join(basedir, filename) try: upres = api.put(imgUrl, f.stream.read()) except Exception, e: logger.error(e, exc_info=True) res.update(code=2, msg="Storage failure") else: imgId = md5(filename) imgUrl = Upyun['dn'].strip("/") + imgUrl upres.update(ctime=get_current_timestamp(), imgUrl=imgUrl, imgId=imgId, label=label) try: pipe = g.redis.pipeline() pipe.sadd(current_app.config["picKey"], imgId) pipe.hmset("{}:{}".format(GLOBAL['ProcessName'], imgId), upres) pipe.hincrby( "{}:label:{}".format(GLOBAL['ProcessName'], label), "imgNum") pipe.execute() except Exception, e: logger.error(e, exc_info=True) res.update( code=0, msg= "It has been uploaded, but the server has encountered an unknown error" ) else: logger.info( "Upload to Upyun file saved, its url is %s, result is %s, imgId is %s" % (imgUrl, upres, imgId)) res.update(code=0, imgUrl=imgUrl)
def register(): if is_true(g.cfg.register) is False: return abort(404) res = dict(code=1, msg=None) #: Required fields username = request.form.get("username") password = request.form.get("password") if username and password: username = username.lower() if check_username(username): if len(password) < 6: res.update(msg="Password must be at least 6 characters") else: ak = rsp("accounts") if g.rc.sismember(ak, username): res.update(msg="The username already exists") else: #: 用户状态 -1待审核 0禁用 1启用 #: 后台开启审核时默认是-1,否则是1 #: 禁用时无认证权限(无法登陆,无API权限) # ;待审核仅无法上传,允许登录和API调用 status = -1 if is_true(g.cfg.review) else 1 #: 参数校验通过,执行注册 options = dict( username=username, password=generate_password_hash(password), is_admin=0, avatar=request.form.get("avatar") or "", nickname=request.form.get("nickname") or "", ctime=get_current_timestamp(), status=status, ) uk = rsp("account", username) pipe = g.rc.pipeline() pipe.sadd(ak, username) pipe.hmset(uk, options) try: pipe.execute() except RedisError: res.update(msg="Program data storage service error") else: res.update(code=0) else: res.update( msg="The username is invalid or registration is not allowed") else: res.update(msg="Parameter error") return res
def brush_loginlog(self, signInResult, login_ip, user_agent): """ 将登录日志写入redis,需有定时任务每分钟解析入库 @param signInResult dict: 登录接口返回 @param uid str: 用户全局唯一标识id @param identity_type int: 登录类型,参见`oauth2_name2type`函数 @param login_ip str: 登录IP @param user_agent str: 用户代理 """ if isinstance(signInResult, dict): if signInResult["success"]: data = dict(uid=signInResult["uid"], identity_type=signInResult["identity_type"], login_ip=login_ip, user_agent=user_agent, login_time=get_current_timestamp()) key = "passport:loginlog" return self.rc.rpush(key, json.dumps(data))
def novel_post_book(self, name, summary, cover, link=''): """创建一本小说""" res = dict(code=1, msg=None) if name and summary and cover: sql = "INSERT INTO novel_books (book_id,name,summary,cover,ctime,link) VALUES (%s,%s,%s,%s,%s,%s)" try: book_id = md5(name) self.mysql_write.insert(sql, book_id, name, summary, cover, get_current_timestamp(), link) except Exception as e: res.update(msg=str(e)) else: res.update(code=0, book_id=book_id) self.novel_refresh_books() else: res.update(msg="Param error") return res
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
def login(): if request.method == "GET": return abort(404) res = dict(code=1) usr = request.form.get("username") pwd = request.form.get("password") #: 定义是否设置cookie状态 set_state = is_true(request.form.get("set_state")) is_secure = False if request.url_root.split("://")[0] == "http" else True max_age = 7200 if is_true(request.form.get("remember")): #: Remember me 7d max_age = 604800 if usr and pwd and check_username(usr) and len(pwd) >= 6: ak = rsp("accounts") if rc.sismember(ak, usr): userinfo = rc.hgetall(rsp("account", usr)) password = userinfo.get("password") if password and check_password_hash(password, pwd): expire = get_current_timestamp() + max_age sid = "%s.%s.%s" % (usr, expire, sha256("%s:%s:%s:%s" % (usr, password, expire, current_app.config["SECRET_KEY"]))) sid = b64encode(sid.encode("utf-8")).decode("utf-8") res.update( code=0, sid=sid, expire=expire, # is_admin=is_true(userinfo.get("is_admin")) ) if set_state: res = make_response(jsonify(res)) res.set_cookie(key="dSid", value=sid, max_age=max_age, httponly=True, secure=is_secure) else: res.update(msg="Password verification failed") else: res.update(msg="No valid username found") else: res.update(msg="Parameter error") return res
def updateUserApp(self, name, description, app_redirect_url): """更新userapp应用 @param name str: 应用名 @param description str: 应用描述 @param app_redirect_url str: 回调url """ res = dict(msg=None, code=1) if name and description and app_redirect_url and Universal_pat.match(name) and url_pat.match(app_redirect_url): mtime = get_current_timestamp() sql = "UPDATE sso_apps SET description=%s, app_redirect_url=%s, mtime=%s WHERE name=%s" try: self.mysql.update(sql, description, app_redirect_url, mtime, name) except IntegrityError: res.update(msg="Name already exists", code=2) except Exception, e: logger.error(e, exc_info=True) res.update(msg="System is abnormal", code=3) else: res.update(code=0, refreshCache=self.refreshUserApp())
def novel_post_chapter(self, book_id, title, content): """小说上传新章节""" res = dict(code=1, msg=None) if book_id and title and content: if isinstance(content, str): content = content.decode("utf8") word_count = str_count(content) sql = "INSERT INTO novel_chapters (book_id,title,content,word_count,ctime) VALUES (%s,%s,%s,%s,%s)" try: self.mysql_write.insert(sql, book_id, title, content, word_count, get_current_timestamp()) except Exception as e: res.update(msg=str(e)) else: res.update(code=0) self.novel_refresh_chapters(book_id) else: res.update(msg="Param error") return res
def __checkUsersetLock(self, etime): """检查用户某项是否加锁 参数: @param etime str: 有效期,见"规则" 规则: 1. 10位UNIX时间戳,小于当前时间即锁失效,可以修改 2. 结果为0表示加锁,不可以修改;结果为-1表示无锁 返回: True -> 加锁 -> 不可以修改(默认) False -> 无锁 -> 可修改 """ if etime and isinstance(etime, int): if etime == -1: return False elif etime == 0: return True else: if 0 < etime < get_current_timestamp(): return False return True
def createUserApp(self, name, description, app_redirect_url): """新建userapp应用 @param name str: 应用名 @param description str: 应用描述 @param app_redirect_url str: 回调url """ res = dict(msg=None, code=1) if name and description and app_redirect_url and Universal_pat.match(name) and url_pat.match(app_redirect_url): app_id = md5(name) app_secret = gen_token(36) ctime = get_current_timestamp() sql = "INSERT INTO sso_apps (name, description, app_id, app_secret, app_redirect_url, ctime) VALUES (%s, %s, %s, %s, %s, %s)" try: self.mysql.insert(sql, name, description, app_id, app_secret, app_redirect_url, ctime) except IntegrityError: res.update(msg="Name already exists", code=2) except Exception, e: logger.error(e, exc_info=True) res.update(msg="System is abnormal", code=3) else: res.update(code=0, refreshCache=self.refreshUserApp())