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)
def process_add_public_key(author: AccountId, message: str, server: Server, **kwargs):
    """Processes a message that requests for a public key to be associated with an account."""
    account = assert_is_account(author, server)
    pem = '\n'.join(line for line in message.split('\n')[1:] if line != '' and not line.isspace())
    try:
        key = ECC.import_key(pem)
    except Exception as e:
        raise CommandException("Incorrectly formatted key. Inner error message: %s." % str(e))

    server.add_public_key(account, key)
    return 'Public key added successfully.'
def add_public_key(author: Union[AccountId, str], account: Union[AccountId,
                                                                 str],
                   key: Union[str, ECC.EccKey], server: Server):
    """Add public key to account, with authorization from author"""
    author = _get_account(author, server)
    account = _get_account(account, server)
    _assert_authorized(author, account)
    if not isinstance(key, ECC.EccKey):
        try:
            key = ECC.import_key(key)
        except:
            raise ValueCommandException(key)
    server.add_public_key(account, key)
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