def _updateUserRedisValue(user_id, updater) : redis_user_key_lookup_key = f"user-{str(user_id)}" redis_user_key_ttl = rdb.ttl(redis_user_key_lookup_key) redis_user_key = rdb.get(redis_user_key_lookup_key) if redis_user_key : redis_user_obj_json = rdb.get(redis_user_key) if redis_user_obj_json : redis_user_obj = loads(redis_user_obj_json) redis_user_obj = updater(redis_user_obj) rdb.set(redis_user_key, dumps(redis_user_obj), ex = redis_user_key_ttl)
def login(username, password, challenge, login_session_id) : log(obj = {'username': username, 'challenge': challenge, 'login_session_id': login_session_id}) if len(username) > UserConfig.MAX_USERNAME_LENGTH : raise UserError('USERNAME_TOO_LONG') if len(username) < UserConfig.MIN_USERNAME_LENGTH : raise UserError('USERNAME_TOO_SHORT') if len(password) > UserConfig.MAX_PASSWORD_LENGTH : raise UserError('PASSWORD_TOO_LONG') if len(password) < UserConfig.MIN_PASSWORD_LENGTH : raise UserError('PASSWORD_TOO_SHORT') if verify_session(login_session_id, 'LOGIN') : user_obj = db.users.find_one({'profile.username': username}) if not user_obj : log(level = 'SEC', obj = {'msg': 'USER_NOT_EXIST'}) raise UserError('INCORRECT_LOGIN') if not verify_password_PBKDF2(password, user_obj['crypto']['salt1'], user_obj['crypto']['password_hashed']) : log(level = 'SEC', obj = {'msg': 'WRONG_PASSWORD'}) raise UserError('INCORRECT_LOGIN') user_id = str(user_obj['_id']) redis_user_key_lookup_key = f"user-{user_id}" redis_user_key = rdb.get(redis_user_key_lookup_key) logged_in = False if redis_user_key : # user already logged in on some other machines redis_user_obj_json_str = rdb.get(redis_user_key) if redis_user_obj_json_str : logged_in = True # reset expire time rdb.set(redis_user_key, redis_user_obj_json_str, ex = UserConfig.LOGIN_EXPIRE_TIME) rdb.set(redis_user_key_lookup_key, redis_user_key, ex = UserConfig.LOGIN_EXPIRE_TIME) if logged_in : return redis_user_key, user_obj['profile'] common_user_obj = { '_id': user_obj['_id'], 'profile': { 'username': user_obj['profile']['username'], 'image': user_obj['profile']['image'], 'desc': user_obj['profile']['desc'] }, 'access_control': user_obj['access_control'], 'settings': user_obj['settings'] } redis_user_value = dumps(common_user_obj) redis_user_key = binascii.hexlify(bytearray(random_bytes(16))).decode() redis_user_key_lookup_key = f"user-{user_obj['_id']}" rdb.set(redis_user_key, redis_user_value, ex = UserConfig.LOGIN_EXPIRE_TIME) rdb.set(redis_user_key_lookup_key, redis_user_key, ex = UserConfig.LOGIN_EXPIRE_TIME) log(obj = {'redis_user_key': redis_user_key, 'user': common_user_obj}) return redis_user_key, common_user_obj['profile'] raise UserError('INCORRECT_SESSION')
def update_userphoto(redis_user_key, user_id, file_key): log(obj={ 'redis_user_key': redis_user_key, 'user_id': user_id, 'file_key': file_key }) photo_file = None if file_key.startswith("upload-image-"): filename = rdb.get(file_key) if filename: photo_file = filename.decode('ascii') if photo_file is None: raise UserError('NO_PHOTO') obj = db.users.find_one({'_id': ObjectId(user_id)}) if obj is None: raise UserError('USER_NOT_EXIST') log(obj={ 'old_photo_file': obj['profile']['image'], 'photo_file': photo_file }) db.users.update_one({'_id': ObjectId(user_id)}, {'$set': { 'profile.image': photo_file }}) def updater(obj): obj['profile']['image'] = photo_file return obj _updateUserRedisValue(user_id, updater) return photo_file
def verify_session(sid, stype) : session_obj = loads(rdb.get(sid).decode('utf-8')) if isinstance(stype, list) : ret = session_obj['type'] in stype else : ret = session_obj['type'] == stype return ret, session_obj
def pages_postresult(rd, job_key): try: job = loads(rdb.get(f'task-{job_key}')) except: return "data", "No such job" if job['finished']: result, obj = job['data']['result'], job['data']['result_obj'] if result == 'SUCCEED': return "redirect", "/video?id=" + str(obj) elif result == 'TOO_MANY_COPIES': return "data", "Too many copies exist for this video, no more than %d copies of the same video are allowed." % VideoConfig.MAX_COPIES elif result == 'VIDEO_ALREADY_EXIST': return "data", 'Video already exist, <a href="/video?id=%s">click me</a> to see.' % obj[ 'aux'] elif result == 'FETCH_FAILED': return "data", "<h1>Failed to fetch video</h1><p>" + str( obj['data']) + "</p>" elif result == 'UNKNOWN': return "data", str(obj) elif result == 'UNAUTHORISED_OPERATION': return "data", "You are not allowed to insert to playlist</br>" + str( obj['data']) elif result == 'PLAYLIST_NOT_EXIST': return "data", "playlist no longer exist" elif result == 'VIDEO_NOT_EXIST': print('!!!!!VIDEO_NOT_EXIST!!!!!', job, file=sys.stderr) return "data", "Contact site admin for help" elif result == 'VIDEO_LIMIT_EXCEEDED': return "data", "Too many videos in one playlist, max %d videos per playlist" % PlaylistConfig.MAX_VIDEO_PER_PLAYLIST elif result == 'OUT_OF_RANGE': return "data", "insert position out of range" return str(job.result), 200 else: return "data", "This post is waiting to be processed, refresh to update."
def postVideoIPFS_new(user, url, tags, copy, pid, rank, desc, title, cover_file_key): log(obj = {'url': url, 'tags': tags, 'copy': copy, 'pid': pid, 'rank': rank}) filterOperation('postVideo', user) tags = [tag.strip() for tag in tags] # TODO: check title and desc clength if not url : raise UserError('EMPTY_URL') if len(url) > VideoConfig.MAX_URL_LENGTH : raise UserError('URL_TOO_LONG') if len(tags) > VideoConfig.MAX_TAGS_PER_VIDEO : raise UserError('TAGS_LIMIT_EXCEEDED') if len(title) > VideoConfig.MAX_TITLE_LENGTH : raise UserError('TITLE_TOO_LONG') if len(desc) > VideoConfig.MAX_DESC_LENGTH : raise UserError('DESC_TOO_LONG') cover_file = None if cover_file_key.startswith("upload-image-") : filename = rdb.get(cover_file_key) if filename : cover_file = filename.decode('ascii') if cover_file is None : raise UserError('NO_COVER') obj, cleanURL = dispatch(url) if obj is None: raise UserError('UNSUPPORTED_WEBSITE') if not cleanURL : raise UserError('EMPTY_URL') if obj.NAME != 'ipfs' : raise UserError('NOT_IPFS') _verifyTags(tags) log(obj = {'url': cleanURL}) task_id = postTask(_createJsonForPosting(cleanURL, tags, copy, pid, rank, [], user, field_overrides = {'title': title, 'desc': desc, 'cover_image_override': cover_file, '__condition': 'any'})) return task_id
async def postPlaylistAsync(url, pid, use_autotag, user, event_id, extend): crawler, _ = dispatch(url) setEventUserAndID(user, event_id) website_pid = crawler.get_pid(self=crawler, url=url) log_e(event_id, user, 'postPlaylistAsync', obj={ 'website_pid': website_pid, 'pid': pid }) videos = [] setEventUserAndID(user, event_id) async for single_video_url in crawler.run(self=crawler, website_pid=website_pid): videos.append(single_video_url) setEventUserAndID(user, event_id) task_ids = await _postVideosBatch(videos, pid, use_autotag, user, event_id) log_e(event_id, user, 'postPlaylistAsync', obj={'video_count': len(videos)}) if len(videos) == 0: raise UserError('EMPTY_PLAYLIST') setEventUserAndID(user, event_id) if not extend: metadata = await crawler.get_metadata(self=crawler, url=url) for _ in range(2 * 60 * 60): val = rdb.get(f'playlist-batch-post-event-{pid}') if val == b'done': break await asyncio.sleep(0.5) setEventUserAndID(user, event_id) updatePlaylistInfo(pid, metadata['title'], metadata['desc'], '', user) return 'SUCCEED', {'task_ids': task_ids}
def updatePlaylistCoverFromFile(pid, user, file_key): log(obj={'pid': pid, 'file_key': file_key}) photo_file = None if file_key.startswith("upload-image-"): filename = rdb.get(file_key) if filename: photo_file = filename.decode('ascii') if photo_file is None: raise UserError('NO_COVER') with redis_lock.Lock(rdb, "playlistEdit:" + str(pid)), MongoTransaction(client) as s: list_obj = playlist_db.retrive_item(pid) log(obj={'playlist': list_obj}) if list_obj is None: raise UserError('PLAYLIST_NOT_EXIST') filterOperation('editPlaylist', user, list_obj) playlist_db.update_item_query(list_obj, {'$set': { "item.cover": photo_file }}, user=makeUserMeta(user), session=s()) s.mark_succeed()
def getTaskParamas(task_id): key = f'task-{task_id}' json_str = rdb.get(key) if json_str: json_obj = loads(json_str) return json_obj['params'] else: return None
def do_login(user_obj) : user_id = str(user_obj['_id']) redis_user_key_lookup_key = f"user-{user_id}" redis_user_key = rdb.get(redis_user_key_lookup_key) logged_in = False if redis_user_key : # user already logged in on some other machines redis_user_obj_json_str = rdb.get(redis_user_key) if redis_user_obj_json_str : logged_in = True # reset expire time rdb.set(redis_user_key, redis_user_obj_json_str, ex = UserConfig.LOGIN_EXPIRE_TIME) rdb.set(redis_user_key_lookup_key, redis_user_key, ex = UserConfig.LOGIN_EXPIRE_TIME) if logged_in : profile = user_obj['profile'] profile['access_control_status'] = user_obj['access_control']['status'] return redis_user_key, profile openid_qq = user_obj['profile']['openid_qq'] if 'openid_qq' in user_obj['profile'] else None common_user_obj = { '_id': user_obj['_id'], 'profile': { 'uid': str(user_obj['_id']), 'username': user_obj['profile']['username'], 'image': user_obj['profile']['image'], 'desc': user_obj['profile']['desc'], 'email': user_obj['profile']['email'], 'bind_qq': True if openid_qq else False }, 'access_control': user_obj['access_control'], 'settings': user_obj['settings'] } redis_user_value = dumps(common_user_obj) redis_user_key = binascii.hexlify(bytearray(random_bytes(16))).decode() redis_user_key_lookup_key = f"user-{user_obj['_id']}" rdb.set(redis_user_key, redis_user_value, ex = UserConfig.LOGIN_EXPIRE_TIME) rdb.set(redis_user_key_lookup_key, redis_user_key, ex = UserConfig.LOGIN_EXPIRE_TIME) log(obj = {'redis_user_key': redis_user_key, 'user': common_user_obj}) profile = common_user_obj['profile'] profile['access_control_status'] = user_obj['access_control']['status'] return redis_user_key, profile
def reset_password(reset_key, new_pass) : if len(new_pass) > UserConfig.MAX_PASSWORD_LENGTH or len(new_pass) < UserConfig.MIN_PASSWORD_LENGTH: raise UserError('PASSWORD_LENGTH') reset_key_content = rdb.get('passreset' + reset_key) try : email = reset_key_content.decode('ascii') assert len(email) > 0 obj = db.users.find_one({'profile.email': email}) assert obj is not None except : raise UserError('INCORRECT_KEY') crypto_method, password_hashed, salt1, salt2, master_key_encryptyed = update_crypto_PBKDF2(None, new_pass, obj['crypto']['salt2'], obj['crypto']['master_key_encryptyed']) crypto = { 'crypto_method': crypto_method, 'password_hashed': password_hashed, 'salt1': salt1, 'salt2': salt2, 'master_key_encryptyed': master_key_encryptyed } db.users.update_one({'_id': obj['_id']}, {'$set': {'crypto': crypto}})
def _get_user_obj(sid): obj_json = rdb.get(sid) if obj_json is None: return None return loads(obj_json)
def logout(redis_user_key): common_user_obj = rdb.get(redis_user_key) log(obj={'redis_user_key': redis_user_key, 'user': common_user_obj}) rdb.delete(redis_user_key)
def verify_session(sid, stype): ret = rdb.get(sid) == stype.encode() return ret
def createOrModifyAuthorRecord(user, author_type, tagid, common_tags, user_spaces, desc, avatar_file_key=None): filterOperation('createOrModifyAuthorRecord', user) log( obj={ 'author_type': author_type, 'tagid': tagid, 'common_tags': common_tags, 'user_spaces': user_spaces, 'desc': desc, 'avatar_file_key': avatar_file_key }) if author_type not in ['individual', 'group']: raise UserError('INCORRECT_AUTHOR_TYPE') if not isinstance(user_spaces, list): raise UserError('INCORRECT_REQUEST_USER_SPACES') if len(desc) > AuthorDB.DESC_MAX_LENGTH: raise UserError('DESC_TOO_LONG') with MongoTransaction(client) as s: tag_obj = tagdb._tag(tagid, session=s()) if tag_obj['category'] != 'Author': raise UserError('TAG_NOT_AUTHOR') existing_record = None log(obj={'tag_obj': tag_obj}) if 'author' in tag_obj: existing_record = db.authors.find_one({'_id': tag_obj['author']}, session=s()) assert existing_record log(obj={'old_record': existing_record}) common_tagids = tagdb.filter_and_translate_tags(common_tags, session=s()) avatar_file = '' if avatar_file_key: if avatar_file_key.startswith("upload-image-"): filename = rdb.get(avatar_file_key) if filename: avatar_file = filename.decode('ascii') if existing_record: record_id = existing_record['_id'] db.authors.update_one({'_id': record_id}, { '$set': { 'type': author_type, 'tagid': tagid, 'common_tagids': common_tagids, 'urls': user_spaces, 'desc': desc, 'avatar': avatar_file } }, session=s()) else: record_id = db.authors.insert_one( { 'type': author_type, 'tagid': tagid, 'common_tagids': common_tagids, 'urls': user_spaces, 'desc': desc, 'avatar': avatar_file }, session=s()).inserted_id record_id = ObjectId(record_id) db.tags.update_one({'_id': tag_obj['_id']}, {'$set': { 'author': record_id }}) s.mark_succeed() return str(record_id)