async def get_login(self, request_obj) -> web.Response: # TODO(pool): add rate limiting launcher_id = request_obj.rel_url.query["launcher_id"] authentication_token = request_obj.rel_url.query["authentication_token"] authentication_token_error = check_authentication_token( launcher_id, authentication_token, self.pool.authentication_token_timeout ) if authentication_token_error is not None: return authentication_token_error farmer_record: Optional[FarmerRecord] = await self.pool.store.get_farmer_record(launcher_id) if farmer_record is None: return error_response(PoolErrorCode.FARMER_NOT_KNOWN, f"Farmer with launcher_id {launcher_id} unknown.") # Validate provided signature signature = request_obj.rel_url.query["signature"] message = std_hash(launcher_id + bytes(authentication_token)) if not AugSchemeMPL.verify(farmer_record.authentication_public_key, message, signature): return error_response( PoolErrorCode.INVALID_SIGNATURE, f"Failed to verify signature {signature} for launcher_id {launcher_id}.", ) self.pool.log.info(f"Login successful for launcher_id: {launcher_id}") # TODO(pool) Do what ever you like with the successful login return obj_to_response({"login_data", "Put server side login information here?"})
async def get_farmer(self, request_obj) -> web.Response: # TODO(pool): add rate limiting launcher_id = hexstr_to_bytes(request_obj.rel_url.query["launcher_id"]) authentication_token = uint64(request_obj.rel_url.query["authentication_token"]) authentication_token_error: Optional[web.Response] = check_authentication_token( launcher_id, authentication_token, self.pool.authentication_token_timeout ) if authentication_token_error is not None: return authentication_token_error farmer_record: Optional[FarmerRecord] = await self.pool.store.get_farmer_record(launcher_id) if farmer_record is None: return error_response( PoolErrorCode.FARMER_NOT_KNOWN, f"Farmer with launcher_id {launcher_id.hex()} unknown." ) # Validate provided signature signature: G2Element = G2Element.from_bytes(hexstr_to_bytes(request_obj.rel_url.query["signature"])) message = std_hash(launcher_id + bytes(authentication_token)) if not AugSchemeMPL.verify(farmer_record.authentication_public_key, message, signature): return error_response( PoolErrorCode.INVALID_SIGNATURE, f"Failed to verify signature {signature} for launcher_id {launcher_id.hex()}.", ) response: GetFarmerResponse = GetFarmerResponse( farmer_record.authentication_public_key, farmer_record.payout_instructions, farmer_record.difficulty, farmer_record.points, ) self.pool.log.info(f"get_farmer response {response.to_json_dict()}, " f"launcher_id: {launcher_id.hex()}") return obj_to_response(response)
def post_login(): if request.json is None: return util.error_response('username and password required') username = request.json.get('username', '') password = request.json.get('password', '') user = User.get_user(username) if user is None: return util.error_response('user "{}" does not exist'.format(username)) if not user.is_password_correct(password): return util.error_response('incorrect password') return _token_response(user.token)
def get_custom_url(path): if not path: return error_response('invalid path') if not path.startswith('/'): path = '/' + path doc = mongodb.doc.find_one({'custom_url': path}) if not doc: return error_response('Oops, not found', 404) return success_response({ 'type': 'blog', 'blog': doc, })
async def get_login(self, request_obj) -> web.Response: # TODO(pool): add rate limiting launcher_id: bytes32 = hexstr_to_bytes( request_obj.rel_url.query["launcher_id"]) authentication_token: uint64 = uint64( request_obj.rel_url.query["authentication_token"]) authentication_token_error = check_authentication_token( launcher_id, authentication_token, self.pool.authentication_token_timeout) if authentication_token_error is not None: return authentication_token_error farmer_record: Optional[ FarmerRecord] = await self.pool.store.get_farmer_record(launcher_id ) if farmer_record is None: return error_response( PoolErrorCode.FARMER_NOT_KNOWN, f"Farmer with launcher_id {launcher_id.hex()} unknown.") # Validate provided signature signature: G2Element = G2Element.from_bytes( hexstr_to_bytes(request_obj.rel_url.query["signature"])) message: bytes32 = std_hash( AuthenticationPayload("get_login", launcher_id, self.pool.default_target_puzzle_hash, authentication_token)) if not AugSchemeMPL.verify(farmer_record.authentication_public_key, message, signature): return error_response( PoolErrorCode.INVALID_SIGNATURE, f"Failed to verify signature {signature} for launcher_id {launcher_id.hex()}.", ) self.pool.log.info( f"Login successful for launcher_id: {launcher_id.hex()}") record: Optional[ FarmerRecord] = await self.pool.store.get_farmer_record(launcher_id ) response = {} if record is not None: response["farmer_record"] = record recent_partials = await self.pool.store.get_recent_partials( launcher_id, 20) response["recent_partials"] = recent_partials # TODO(pool) Do what ever you like with the successful login return obj_to_response(response)
def query_note(): query = request.json if not query: return util.error_response('bad request') if 'url' in query: note = db.get_note_with_url(query['url']) return util.success_response({'note': note}) if 'alias' in query: note = db.get_note_with_alias(query['alias']) return util.success_response({'note': note}) if 'type' in query: notes = db.query_notes_by_type(query['type']) return util.success_response({'notes': notes}) else: return util.error_response('bad request')
async def inner(request) -> aiohttp.web.Response: try: res_object = await f(request) if res_object is None: res_object = {} except Exception as e: tb = traceback.format_exc() self.log.warning(f"Error while handling message: {tb}") if len(e.args) > 0: res_error = error_response(PoolErrorCode.SERVER_EXCEPTION, f"{e.args[0]}") else: res_error = error_response(PoolErrorCode.SERVER_EXCEPTION, f"{e}") return allow_cors(res_error) return allow_cors(res_object)
async def post_partial(self, request_obj) -> web.Response: # TODO(pool): add rate limiting start_time = time.time() request = await request_obj.json() partial: PostPartialRequest = PostPartialRequest.from_json_dict( request) authentication_token_error = check_authentication_token( partial.payload.launcher_id, partial.payload.authentication_token, self.pool.authentication_token_timeout, ) if authentication_token_error is not None: return authentication_token_error farmer_record: Optional[ FarmerRecord] = await self.pool.store.get_farmer_record( partial.payload.launcher_id) if farmer_record is None: return error_response( PoolErrorCode.FARMER_NOT_KNOWN, f"Farmer with launcher_id {partial.payload.launcher_id.hex()} not known.", ) post_partial_response = await self.pool.process_partial( partial, farmer_record, start_time) self.pool.log.info( f"post_partial response {post_partial_response}, time: {time.time() - start_time} " f"launcher_id: {request['payload']['launcher_id']}") return obj_to_response(post_partial_response)
def check_authentication_token(launcher_id: bytes32, token: uint64, timeout: uint8) -> Optional[web.Response]: if not validate_authentication_token(token, timeout): return error_response( PoolErrorCode.INVALID_AUTHENTICATION_TOKEN, f"authentication_token {token} invalid for farmer {launcher_id.hex()}.", ) return None
def post_signup(): if request.json is None: return util.error_response('username and password required') username = request.json.get('username', '') password = request.json.get('password', '') user = User.create(username, password) return _token_response(user.token)
def put_note(note_id): note = request.json print note note['id'] = note_id if noter.put_note(note): return util.success_response() else: return util.error_response('put error')
def get_read(blog_id): return error_response('todo') args = flask.request.args page = int(args.get('page', 1)) page_size = int(args.get('size', 1000)) offset = int(args.get('offset', '0')) user = user_util.current_user() blog = db.query('match (blog:Blog{id: {id}}) return blog', { 'id': blog_id, }, one=True) attrs = json.loads(blog['attrs']) if not blog: return error_response('not found') path = blog['path'] if path.startswith('/'): path = path[1:] if path.startswith('file'): path = path[4:] if path.startswith('/'): path = path[1:] fpath = util.rooted_path(conf.FILES_ROOT, path).encode('utf8') text = load_text(fpath, attrs['encoding']) if 'search' in args: return search_read(text, args['search']) content = get_content(text, page, page_size, offset) return success_response({ 'content': content, 'name': attrs['name'], 'attrs': json.dumps(attrs), })
def search_read(text, pattern): if not pattern.strip(): return error_response('invalid pattern') offsets = [m.start() for m in re.finditer(pattern, text)] more = False if len(offsets) > 100: offsets = offsets[:100] more = True return success_response({ 'occurrences': [{ 'pattern': pattern, 'offset': offset, 'context': text[max(0, offset - 100):offset + 100], 'contextOffset': offset - max(0, offset - 100), } for offset in offsets], 'more': more, })
def delete_note(note_id): if noter.delete_note(note_id): return util.success_response() else: return util.error_response('delete error')
def no_such_api(path): return error_response('no such api', 404)
def post_comment(note_id): comment = request.json if noter.post_comment(note_id, comment): return util.success_response() else: return util.error_response('post comment error')
def delete_comment(note_id, comment_id): if noter.delete_comment(note_id, comment_id): return util.success_response() else: return util.error_response('delete comment error')
def get_note(note_id): note = noter.get_note(note_id) if '.' in note.get('tags', []) and not util.is_visitor_owner(): return util.error_response('Unauthorized') return util.success_response(note)