コード例 #1
0
def open_account(author: Union[AccountId, str], account: Union[AccountId, str],
                 server: Server):
    """Open account through authorization of author on server.
    Author can be the same account as account"""
    if server.has_account(account):
        raise ValueCommandException(account)
    if server.has_account(author):
        _assert_authorized(_get_account(author, server), None)
    server.open_account(account)
コード例 #2
0
def _get_account(account_id: Union[AccountId, str], server: Server) -> Account:
    """Get account from server, unless it doesn't exist, in which case raise"""
    account_id = parse_account_id(account_id)
    if not server.has_account(account_id):
        raise AccountCommandException(account_id)

    return server.get_account(account_id)
コード例 #3
0
def process_request_alias(author: AccountId, message: str, server: Server, **kwargs):
    """Processes a request for an alias code."""
    account = assert_is_account(author, server)

    split_msg = message.split()
    if len(split_msg) != 2:
        raise CommandException('Incorrect formatting. Expected `request-alias ALIAS_ACCOUNT_NAME`.')

    _, alias_name = split_msg
    alias_id = parse_account_id(alias_name)
    if server.has_account(alias_id):
        raise CommandException(
            'An account has already been associated with %s, so it cannot be an alias for this account.' %
            alias_id.readable())

    # To generate an alias code, we generate an ECC public/private key pair, use the
    # private key to generate a signed version of the aliased account name and associate
    # the public key with the account.
    key = ECC.generate(curve='P-256')
    signature = sign_message(str(alias_id), key)
    server.add_public_key(account, key.public_key())

    # At this point we will allow the private key to be forgotten.

    # Compose a helpful message for as to how the bot can be contacted to link accounts.
    if isinstance(alias_id, RedditAccountId):
        contact_message = 'Send me that exact command as a Reddit Private Message (not a direct chat) from %s.' % alias_id.readable()
    elif isinstance(alias_id, DiscordAccountId):
        contact_message = 'Send me that exact command prefixed with a mention of my name via Discord from account %s.' % alias_id
    else:
        contact_message = ''

    return ('I created an alias request code for you. '
        'Make {0} an alias for this account ({2}) by sending me the following message from {3}.\n\n```\nadd-alias {4} {1}\n```\n\n{5}').format(
            str(alias_id), signature, author.readable(), alias_id.readable(), str(author), contact_message)
コード例 #4
0
def process_open_account(author: AccountId, message: str, server: Server, prefix='', platform_name='Reddit', **kwargs):
    """Processes a message that tries to open a new account."""
    if server.has_account(author):
        return 'Hi there %s. Looks like you already have an account. No need to open another one.' % author.readable()

    server.open_account(author)
    return 'Hi there %s. Your account has been opened successfully. Thank you for your business. %s' % (author.readable(), get_generic_help_message(author, prefix, platform_name))
コード例 #5
0
def process_admin_open_account(author: AccountId, message: str, server: Server, **kwargs):
    """Processes a message that tries to open a new account."""
    assert_authorized(author, server, Authorization.ADMIN)
    account_name = parse_account_name_command(message)
    if server.has_account(account_name):
        raise CommandException('Account `%s` already exists.' % account_name)

    server.open_account(account_name)
    return 'Account `%s` has been opened successfully.' % account_name
コード例 #6
0
def process_balance(author: AccountId, message: str, server: Server, **kwargs):
    """Processes a message requesting the balance on an account."""
    if not server.has_account(author):
        return 'Hi there %s. I can\'t tell you what the balance on your account is because you don\'t have an account yet. ' \
            'You can open one with the `open` command.' % author.readable()

    account = server.get_account(author)
    main_response = 'The balance on your account is %s.' % account.get_balance()
    return 'Hi there %s %s. %s Have a great day.' % (account.get_authorization().name.lower(), author.readable(), main_response)
コード例 #7
0
def assert_is_account(account_name: Union[str, AccountId], server: Server) -> Account:
    """Asserts that a particular account exists. Returns the account."""
    if isinstance(account_name, str):
        account_name = parse_account_id(account_name)

    if not server.has_account(account_name):
        raise CommandException(
            ('Sorry, I can\'t process your request because %s does not have an account yet. '
             'Accounts can be opened using the `open` command.') % account_name.readable())

    return server.get_account(account_name)
コード例 #8
0
def add_alias(author: Union[AccountId, str], account: Union[AccountId, str],
              signature: str, server: Server):
    """Alias author to account using an alias code (signature)"""
    if server.has_account(author):
        raise AccountCommandException(account)

    account = _get_account(account, server)

    if _is_signed_by(account, str(author), signature):
        server.add_account_alias(account, author)
    else:
        raise ValueCommandException(signature)
コード例 #9
0
def request_alias(author: Union[AccountId, str],
                  account: Union[AccountId, str], server: Server) -> str:
    """Generates an alias code for linking accounts together"""
    if server.has_account(account):
        raise AccountCommandException(account)
    author = _get_account(author, server)

    key = ECC.generate(curve='P-256')
    signer = DSS.new(key, 'fips-186-3')
    signature = base64.b64encode(
        signer.sign(SHA3_512.new(
            str(account).encode('utf-8')))).decode('utf-8')
    server.add_public_key(author, key.public_key())

    return signature
コード例 #10
0
def process_help(author: AccountId, message: str, server: Server, prefix='', platform_name='Reddit', **kwargs):
    """Gets the help message for the economy bot."""
    if server.has_account(author):
        return '''Howdy partner! It's always a pleasure to meet an account holder. %s %s''' % (get_how_to_reach_message(platform_name), get_generic_help_message(author, prefix, platform_name))
    else:
        return '''Hi! You look new. {1} If you don't have an account with me yet, you can open one using this command:

> {0}open

Alternatively, if you already have an account then please don't create a new one here.
Instead, link your existing account to {2} by running the following command from a username that's already associated with the account.

> request-alias {3}

(If you're sending me that over Discord you'll also have to ping me at the start of that command.)'''.format(
    prefix, get_how_to_reach_message(platform_name), author.readable(), str(author))
コード例 #11
0
def process_add_alias(author: AccountId, message: str, server: Server, **kwargs):
    """Processes a request to add `author` as an alias to an account."""
    if server.has_account(author):
        raise CommandException(
            'An account has already been associated with %s, so it cannot be an alias for another account.' % author.readable())

    split_msg = message.split()
    if len(split_msg) != 3:
        raise CommandException('Incorrect formatting. Expected `add-alias ALIASED_ACCOUNT ALIAS_REQUEST_CODE`.')

    _, aliased_account_name, signature = split_msg
    aliased_account = assert_is_account(aliased_account_name, server)

    if is_signed_by(aliased_account, str(author), signature):
        server.add_account_alias(aliased_account, author)
        return 'Alias set up successfully. %s and %s now refer to the same account.' % (
            aliased_account_name, author.readable())
    else:
        raise CommandException('Cannot set up alias because the signature is invalid.')
コード例 #12
0
def get_authorization_or_citizen(author: AccountId, server: Server):
    """Gets an account's authorization if it exists and the default citizen authorization otherwise."""
    return server.get_account(author).get_authorization() \
        if server.has_account(author) \
        else Authorization.CITIZEN