예제 #1
0
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)
예제 #2
0
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')
예제 #3
0
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
예제 #4
0
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
예제 #5
0
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."
예제 #6
0
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
예제 #7
0
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}
예제 #8
0
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()
예제 #9
0
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
예제 #10
0
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
예제 #11
0
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}})
예제 #12
0
def _get_user_obj(sid):
    obj_json = rdb.get(sid)
    if obj_json is None:
        return None
    return loads(obj_json)
예제 #13
0
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)
예제 #14
0
def verify_session(sid, stype):
    ret = rdb.get(sid) == stype.encode()
    return ret
예제 #15
0
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)