Ejemplo n.º 1
0
async def get_token(message, config, logger, **kwargs):

    account_info = protobuf.to_account_info(message.account_info)

    token = await logic.find_token(
        account_info,
        expiration_delta=config['custom']['token_expiration_delta'])

    if token.is_error('AccountRemovedByGDPR'):
        raise tt_exceptions.ApiError(
            code='xsolla.get_token.account_removed_by_gdpr',
            message='Account removed by user request and can not be processed')

    if token.is_error():
        logger.info('token not found: %s', token.name)

        xsolla_client = xsolla.get_client(config['custom'], mode=message.mode)

        token = await logic.request_token(account_info, xsolla_client, logger)

    if token.is_error():
        raise tt_exceptions.ApiError(
            code='xsolla.get_token.can_not_receive_token',
            message='Can not receive token from XSolla services')

    return xsolla_pb2.GetTokenResponse(token=token.value.value)
Ejemplo n.º 2
0
async def start_transaction(message, **kwargs):
    logger = log.ContextLogger()

    try:
        transaction_id = await operations.start_transaction(
            operations=[
                protobuf.to_operation(operation)
                for operation in message.operations
            ],
            lifetime=datetime.timedelta(seconds=message.lifetime),
            autocommit=message.autocommit,
            restrictions=protobuf.to_restrictions(message.restrictions),
            logger=logger)

    except exceptions.NoOperationsInTransaction as e:
        raise tt_exceptions.ApiError(
            code='bank.start_transaction.no_operations_specified',
            message=str(e))

    except exceptions.BalanceChangeExceededRestrictions as e:
        raise tt_exceptions.ApiError(
            code='bank.start_transaction.restrictions_exceeded',
            message=str(e))

    return bank_pb2.StartTransactionResponse(transaction_id=transaction_id)
Ejemplo n.º 3
0
async def xsolla_hook(message, config, logger, **kwargs):

    notification_type = message.get('notification_type')

    if notification_type == 'user_validation':
        try:
            account_id = int(message['user']['id'])
        except ValueError:
            raise tt_exceptions.ApiError(
                code='INVALID_USER',
                message='Account with such credentials has not found',
                details={
                    'code':
                    'xsolla.hook.user_validation.wrong_account_id_format'
                })

        is_valid = await logic.validate_user(account_id=account_id)

        if not is_valid:
            raise tt_exceptions.ApiError(
                code='INVALID_USER',
                message='Account with such credentials has not found',
                details={
                    'code': 'xsolla.hook.user_validation.account_not_found'
                })

    elif notification_type == 'payment':
        invoice = logic.invoice_from_xsolla_data(message)

        result = await logic.register_invoice(invoice)

        if result.is_error():
            raise tt_exceptions.ApiError(
                code='xsolla.hook.payment.can_not_register_invoice',
                message=f'Can not register invoice: {result.name}',
                details={
                    'code': 'xsolla.hook.payment.can_not_register_invoice'
                })

    elif notification_type == 'refund':
        result = await logic.register_cancellation(
            xsolla_id=message['transaction']['id'])

        if result.is_error():
            raise tt_exceptions.ApiError(
                code='xsolla.hook.refund.can_not_register_cancelation',
                message=f'Can not register cancelation: {result.name}')

    else:
        raise tt_exceptions.ApiError(
            code='INVALID_PARAMETER',
            message='Service does not expect such notification type',
            details={
                'notification_type': notification_type,
                'code': 'xsolla.hook.unknown_notification_type'
            })

    return {'result': 'ok'}
Ejemplo n.º 4
0
async def place_sell_lot(message, **kwargs):
    try:
        lots_ids = await operations.place_sell_lots(lots=[protobuf.to_sell_lot(lot) for lot in message.lots])
    except exceptions.SellLotForItemAlreadyCreated as e:
        raise tt_exceptions.ApiError(code='market.apply.sell_lot_for_item_already_created', message=str(e))
    except exceptions.SellLotMaximumPriceExceeded as e:
        raise tt_exceptions.ApiError(code='market.apply.sell_lot_maximum_price_exceeded', message=str(e))
    except exceptions.SellLotPriceBelowZero as e:
        raise tt_exceptions.ApiError(code='market.apply.sell_lot_price_below_zero', message=str(e))

    return market_pb2.PlaceSellLotResponse(lots_ids=[lot_id.hex for lot_id in lots_ids])
Ejemplo n.º 5
0
async def change_speed(message, config, **kwargs):

    if str(message.type) not in config['custom']['types']:
        raise tt_exceptions.ApiError(code='timers.change_speed.unknown_type', message='unknown timer type {}'.format(message.type))

    try:
        timer = await operations.change_speed(owner_id=message.owner_id,
                                              entity_id=message.entity_id,
                                              type=message.type,
                                              speed=message.speed)
    except exceptions.TimerNotFound as e:
        raise tt_exceptions.ApiError(code='timers.change_speed.timer_not_found', message=str(e))

    return timers_pb2.ChangeSpeedResponse(timer=protobuf.from_timer(timer))
Ejemplo n.º 6
0
async def xsolla_extractor(request, config, logger):
    content = await request.content.read()

    auth_header = request.headers.get('Authorization', '')

    request_signature = get_auth_signature(auth_header)

    if request_signature is None:
        raise tt_exceptions.ApiError(
            code='INVALID_SIGNATURE',
            message='signature has not found in headers',
            details={
                'AuthorisationHeader': auth_header,
                'code': 'xsolla.hook.signature_has_not_found'
            })

    expected_signature = get_expected_auth_signature(
        content, config['custom']['hooks_key'])

    if request_signature != expected_signature:
        raise tt_exceptions.ApiError(
            code='INVALID_SIGNATURE',
            message='Received signature does not equal to calculated',
            details={
                'AuthorisationHeader': auth_header,
                'code': 'xsolla.hook.unexpected_signature'
            })

    data = s11n.from_json(content)

    if 'settings' not in data:
        raise tt_exceptions.ApiError(
            code='INVALID_PARAMETER',
            message='settings not found in request body',
            details={'code': 'xsolla.hook.no_settings_info'})

    if data['settings'].get('project_id') != config['custom']['project_id']:
        raise tt_exceptions.ApiError(
            code='INVALID_PARAMETER',
            message='Unexpected project_id on request body',
            details={'code': 'xsolla.hook.wrong_project_id'})

    if data['settings'].get('merchant_id') != config['custom']['merchant_id']:
        raise tt_exceptions.ApiError(
            code='INVALID_PARAMETER',
            message='Unexpected merchant_id on request body',
            details={'code': 'xsolla.hook.wrong_merchant_id'})

    return data
Ejemplo n.º 7
0
async def create_battle(message, config, **kwargs):

    try:
        battle_id = await operations.create_battle(
            matchmaker_type=message.matchmaker_type,
            participants_ids=list(message.participants_ids))
    except exceptions.DuplicateBattleParticipants as e:
        raise tt_exceptions.ApiError(
            code='matchmaker.create_battle.duplicate_participants',
            message=str(e))
    except exceptions.BattleParticipantsIntersection as e:
        raise tt_exceptions.ApiError(
            code='matchmaker.create_battle.participants_intersection',
            message=str(e))

    return matchmaker_pb2.CreateBattleResponse(battle_id=battle_id)
Ejemplo n.º 8
0
async def create_timer(message, config, **kwargs):

    if str(message.type) not in config['custom']['types']:
        raise tt_exceptions.ApiError(code='timers.create_timer.unknown_type', message='unknown timer type {}'.format(message.type))

    try:
        timer = await operations.create_timer(owner_id=message.owner_id,
                                              entity_id=message.entity_id,
                                              type=message.type,
                                              speed=message.speed,
                                              border=message.border,
                                              callback_data=message.callback_data,
                                              resources=message.resources)
    except exceptions.TimerAlreadyExists as e:
        raise tt_exceptions.ApiError(code='timers.create_timer.duplicate_timer', message=str(e))

    return timers_pb2.CreateTimerResponse(timer=protobuf.from_timer(timer))
Ejemplo n.º 9
0
async def rollback_transaction(message, **kwargs):
    logger = log.ContextLogger()

    try:
        await operations.rollback_transaction(
            transaction_id=message.transaction_id, logger=logger)
    except exceptions.NoTransactionToRollback as e:
        raise tt_exceptions.ApiError(
            code='bank.rollback_transaction.no_transacton_to_rollback',
            message=str(e))

    except exceptions.BalanceChangeExceededRestrictions as e:
        raise tt_exceptions.ApiError(
            code='bank.start_transaction.restrictions_exceeded',
            message=str(e))

    return bank_pb2.RollbackTransactionResponse()
Ejemplo n.º 10
0
async def data_protection_delete_data(message, config, **kwargs):
    if config['custom']['data_protector']['secret'] != message.secret:
        raise tt_exceptions.ApiError(code='properties.data_protection_delete_data.wrong_secret',
                                     message='wrong secret code')

    await operations.clean_object_properties(object_id=int(message.account_id))

    return data_protector_pb2.PluginDeletionResponse(result=data_protector_pb2.PluginDeletionResponse.ResultType.SUCCESS)
Ejemplo n.º 11
0
async def request_report(message, config, **kwargs):

    if len(message.ids) == 0:
        raise tt_exceptions.ApiError(
            code='data_protector.request_report.no_ids_specified',
            message='no user identifies specified, no data to collect')

    for source_info in message.ids:
        if source_info.source not in config['custom']['sources']:
            raise tt_exceptions.ApiError(
                code='data_protector.request_report.wrong_source_id',
                message=f'unknowm source: {source_info.source}')

    report_id = await operations.create_report_base([
        (source_info.source, source_info.id) for source_info in message.ids
    ])

    return data_protector_pb2.RequestReportResponse(report_id=report_id.hex)
Ejemplo n.º 12
0
async def request_deletion(message, config, **kwargs):

    if len(message.ids) == 0:
        raise tt_exceptions.ApiError(
            code='data_protector.request_deletion.no_ids_specified',
            message='no user identifies specified, no data to collect')

    for source_info in message.ids:
        if source_info.source not in config['custom']['sources']:
            raise tt_exceptions.ApiError(
                code='data_protector.request_deletion.wrong_source_id',
                message=f'unknowm source: {source_info.source}')

    await operations.mark_for_deletion(core_id=message.core_id,
                                       ids=[(source_info.source,
                                             source_info.id)
                                            for source_info in message.ids])

    return data_protector_pb2.RequestDeletionResponse()
Ejemplo n.º 13
0
async def data_protection_collect_data(message, config, **kwargs):

    if config['custom']['data_protector']['secret'] != message.secret:
        raise tt_exceptions.ApiError(code='properties.data_protection_collect_data.wrong_secret',
                                     message='wrong secret code')

    report = await operations.get_data_report(object_id=int(message.account_id))

    return data_protector_pb2.PluginReportResponse(result=data_protector_pb2.PluginReportResponse.ResultType.SUCCESS,
                                                   data=s11n.to_json(report))
Ejemplo n.º 14
0
async def accept_battle_request(message, config, **kwargs):
    try:
        battle_id, participants_ids = await operations.accept_battle_request(
            battle_request_id=message.battle_request_id,
            acceptor_id=message.acceptor_id)
    except exceptions.NoBattleRequestFound as e:
        raise tt_exceptions.ApiError(
            code='matchmaker.accept_battle_request.no_battle_request_found',
            message=str(e))
    except exceptions.DuplicateBattleParticipants as e:
        raise tt_exceptions.ApiError(
            code='matchmaker.accept_battle_request.duplicate_participants',
            message=str(e))
    except exceptions.BattleParticipantsIntersection as e:
        raise tt_exceptions.ApiError(
            code='matchmaker.accept_battle_request.participants_intersection',
            message=str(e))

    return matchmaker_pb2.AcceptBattleRequestResponse(
        battle_id=battle_id, participants_ids=list(participants_ids))
Ejemplo n.º 15
0
async def apply(message, **kwargs):
    try:
        await operations.apply(operations=[
            protobuf.to_operation(operation)
            for operation in message.operations
        ])
    except exceptions.OperationsError as e:
        raise tt_exceptions.ApiError(code='storage.apply.operation_error',
                                     message=str(e))

    return storage_pb2.ApplyResponse()
Ejemplo n.º 16
0
async def commit_transaction(message, **kwargs):
    logger = log.ContextLogger()

    try:
        await operations.commit_transaction(
            transaction_id=message.transaction_id, logger=logger)
    except exceptions.NoTransactionToCommit as e:
        raise tt_exceptions.ApiError(
            code='bank.commit_transaction.no_transacton_to_commit',
            message=str(e))

    return bank_pb2.CommitTransactionResponse()
Ejemplo n.º 17
0
async def data_protection_collect_data(message, config, **kwargs):

    if config['custom']['data_protector']['secret'] != message.secret:
        raise tt_exceptions.ApiError(
            code='discord.data_protection_collect_data.wrong_secret',
            message='wrong secret code')

    account_info = await operations.get_account_info_by_game_id(
        int(message.account_id), create_if_not_exists=False)

    report = await operations.get_data_report(account_info=account_info)

    return data_protector_pb2.PluginReportResponse(
        result=data_protector_pb2.PluginReportResponse.ResultType.SUCCESS,
        data=s11n.to_json(report))
Ejemplo n.º 18
0
async def data_protection_delete_data(message, config, **kwargs):
    if config['custom']['data_protector']['secret'] != message.secret:
        raise tt_exceptions.ApiError(
            code='discord.data_protection_delete_data.wrong_secret',
            message='wrong secret code')

    account_info = await operations.get_account_info_by_game_id(
        int(message.account_id), create_if_not_exists=False)

    if account_info.discord_id is not None:
        await operations.unbind_discord_user(discord_id=account_info.discord_id
                                             )

    return data_protector_pb2.PluginDeletionResponse(
        result=data_protector_pb2.PluginDeletionResponse.ResultType.SUCCESS)