예제 #1
0
def validate_account(caller, input):
    """Prompt the user to enter the received validation code."""
    text = ""
    options = (
        {
            "key": "b",
            "desc": "Go back to the email address menu.",
            "goto": "pre_email_address",
        },
        {
            "key": "_default",
            "desc": "Enter the validation code.",
            "goto": "validate_account",
        },
    )

    account = caller.db._account
    if account.db.validation_code != input.strip():
        text = dedent("""
            |rSorry, the specified validation code {} doesn't match the one stored for this account.
            Is it the code you received by email?  You can try to enter it again,
            Or enter |wb|n to choose a different email address.
        """.strip("\n")).format(input.strip())
    else:
        account.db.valid = True
        account.attributes.remove("validation_code")
        account.record_email_address()
        caller.msg(
            "-----  You will now create the first character of this account. -----"
        )
        _login(caller, account)
        text = ""
        options = ({
            "key": "_default",
            "desc": "Enter your new character's first name.",
            "goto": "create_first_name",
        }, )

    return text, options
예제 #2
0
def confirm_password(caller, input):
    """Ask the user to confirm the account's password.

    The account's password has been saved in the session for the
    time being, as a hashed version.  If the hashed version of
    the retyped password matches, then the player is created.
    If not, ask for another password.

    """
    text = ""
    options = (
        {
            "key": "b",
            "desc": "Go back to the password selection.",
            "goto": "create_password",
        },
        {
            "key": "_default",
            "desc": "Enter your password.",
            "goto": "confirm_password",
        },
    )

    caller.msg(echo=True)
    password = input.strip()

    playername = caller.db._playername
    first_password = caller.db._password
    second_password = sha256(password).hexdigest()
    if first_password != second_password:
        text = dedent("""
            |rThe password you have specified doesn't match the first one.|n
                Type |yb|n to choose a different password.
                Or type the confirmation password again.
        """.strip("\n"))
    else:
        # Creates the new player.
        from evennia.commands.default import unloggedin
        try:
            permissions = settings.PERMISSION_PLAYER_DEFAULT
            player = unloggedin._create_player(caller, playername, password,
                                               permissions)
        except Exception:
            # We are in the middle between logged in and -not, so we have
            # to handle tracebacks ourselves at this point. If we don't, we
            # won't see any errors at all.
            caller.msg(
                dedent("""
                |rAn error occurred.|n  Please e-mail an admin if
                the problem persists.
                    Type |yb|n to go back to the login screen.
                    Or enter another password.
            """.strip("\n")))
            logger.log_trace()
        else:
            caller.db._player = player
            del caller.db._password
            _login(caller, player)
            text = "Your new account was successfully created!"
            text += "\n\n" + text_email_address(player)
            options = ({
                "key": "_default",
                "desc": "Enter a valid e-mail address.",
                "goto": "email_address",
            }, )

    return text, options
예제 #3
0
def password(caller, input):
    """Ask the user to enter the password to this player.

    This is assuming the user exists (see 'create_username' and
    'create_password').  This node "loops" if needed:  if the
    user specifies a wrong password, offers the user to try
    again or to go back by entering 'b'.
    If the password is correct, then login.

    """
    caller.msg(echo=True)
    input = input.strip()
    text = ""
    options = (
        {
            "key": "_default",
            "desc": "Enter your password.",
            "goto": "password",
        },
    )

    # Check the password
    player = caller.db._player
    # If the account is locked, the user has to wait (maximum
    # 3 seconds) before retrying
    if player.db._locked:
        text = "|gPlease wait, you cannot enter your password yet.|n"
        return text, options

    caller.msg(echo=True)
    bans = ServerConfig.objects.conf("server_bans")
    banned = bans and (any(tup[0] == player.name.lower() for tup in bans) \
            or any(tup[2].match(caller.address) for tup in bans if tup[2]))

    if not player.check_password(input):
        caller.msg(echo=False)
        text = dedent("""
            |rIncorrect password.|n
                Type |yb|n to go back to the login screen.
                Or wait 3 seconds before trying a new password.
        """.strip("\n"))

        # Loops on the same node
        player.scripts.add(WrongPassword)
        scripts = player.scripts.get("wrong_password")
        if scripts:
            script = scripts[0]
            script.db.session = caller
        else:
            print "Cannot retrieve the 'wrong_password' script."

        options = (
            {
                "key": "b",
                "desc": "Go back to the login screen.",
                "goto": "start",
            },
            {
                "key": "_default",
                "desc": "Enter your password again.",
                "goto": "password",
            },
        )
    elif banned:
        # This is a banned IP or name!
        string = dedent("""
            |rYou have been banned and cannot continue from here.|n
            If you feel this ban is in error, please email an admin.
        """.strip("\n"))
        caller.msg(string)
        caller.sessionhandler.disconnect(
                caller, "Good bye!  Disconnecting...")
    else:
        # The password is correct, we can log into the player.
        if not player.email:
            # Redirects to the node to set an e-mail address
            text = text_email_address(player)
            options = (
                {
                    "key": "_default",
                    "desc": "Enter your e-mail address.",
                    "goto": "email_address",
                },
            )
        elif not player.db.valid:
            # Redirects to the node for the validation code
            text = "Enter your received validation code."
            options = (
                {
                    "key": "_default",
                    "desc": "Enter your validation code.",
                    "goto": "validate_account",
                },
            )
        else:
            _login(caller, player)
            text = ""
            options = _options_choose_characters(player)

    return text, options
예제 #4
0
def confirm_password(caller, input):
    """Ask the user to confirm the account's password.

    The account's password has been saved in the session for the
    time being, as a hashed version.  If the hashed version of
    the retyped password matches, then the player is created.
    If not, ask for another password.

    """
    text = ""
    options = (
        {
            "key": "b",
            "desc": "Go back to the password selection.",
            "goto": "create_password",
        },
        {
            "key": "_default",
            "desc": "Enter your password.",
            "goto": "confirm_password",
        },
    )

    caller.msg(echo=True)
    password = input.strip()

    playername = caller.db._playername
    first_password = caller.db._password
    second_password = sha256(password).hexdigest()
    if first_password != second_password:
        text = dedent("""
            |rThe password you have specified doesn't match the first one.|n
                Type |yb|n to choose a different password.
                Or type the confirmation password again.
        """.strip("\n"))
    else:
        # Creates the new player.
        from evennia.commands.default import unloggedin
        try:
            permissions = settings.PERMISSION_PLAYER_DEFAULT
            player = unloggedin._create_player(caller, playername,
                    password, permissions)
        except Exception:
            # We are in the middle between logged in and -not, so we have
            # to handle tracebacks ourselves at this point. If we don't, we
            # won't see any errors at all.
            caller.msg(dedent("""
                |rAn error occurred.|n  Please e-mail an admin if
                the problem persists.
                    Type |yb|n to go back to the login screen.
                    Or enter another password.
            """.strip("\n")))
            logger.log_trace()
        else:
            caller.db._player = player
            del caller.db._password
            _login(caller, player)
            text = "Your new account was successfully created!"
            text += "\n\n" + text_email_address(player)
            options = (
                {
                    "key": "_default",
                    "desc": "Enter a valid e-mail address.",
                    "goto": "email_address",
                },
            )

    return text, options
예제 #5
0
def email_address(caller, input):
    """Prompt the user to enter a valid email address."""
    text = ""
    options = ({
        "key": "_default",
        "desc": "Enter a valid email address.",
        "goto": "email_address",
    }, )

    email_address = input.strip()
    account = caller.db._account

    # Search for accounts with an identical email address
    identical = list(Account.objects.filter(email__iexact=email_address))

    if account in identical:
        identical.remove(account)

    # Try to validate the email address
    try:
        validate_email(email_address)
    except ValidationError:
        valid = False
    else:
        valid = True

    if not valid:
        # The email address doesn't seem to be valid
        text = dedent("""
            |rSorry, the specified email address {} cannot be accepted as a valid one.|n

            Please enter another email address.
        """.strip("\n")).format(email_address)
    elif identical:
        # The email address is already used
        text = dedent("""
            |rThe email address you have entered is already being used by another account.

            Please enter another email address.
        """.strip("\n"))
    else:
        account.email = email_address
        account.save()

        # Generates the 4-digit validation code
        numbers = "012345678"
        code = ""
        for i in range(4):
            code += choice(numbers)

        # Sends an email with the code
        subject = "[Avenew] Account validation"
        body = dedent("""
            You have successfully created the account {} on Avenew.

            In order to validate it and begin to play, you need to enter the following four-digit
            code in your MUD client.  If you have been disconnected, just login again, entering
            your account's name and password, the validation screen will appear.

            Four-digit code: {}
        """.strip("\n")).format(account.name, code)
        recipient = email_address
        account.db.valid = False
        account.db.validation_code = code
        try:
            assert not settings.TEST_SESSION
            send_email("NOREPLY", recipient, subject, body, store=False)
        except AssertionError:
            account.db.valid = True
            account.attributes.remove("validation_code")
            caller.msg(
                dedent("""
                Avenew is in a test session mode, your account has been validated automatically.
            """.strip("\n")).format(email_address))
            caller.msg(
                "-----  You will now create the first character of this account. -----"
            )
            _login(caller, account)
            text = ""
            options = ({
                "key": "_default",
                "desc": "Enter your new character's first name.",
                "goto": "create_first_name",
            }, )
        except (SMTPException, socket.error):
            # The email could not be sent
            account.db.valid = True
            account.attributes.remove("validation_code")
            caller.msg(
                dedent("""
                Avenew couldn't send your email containing your validation code to {}.
                This is probably due to Avenew's failure to connect to the SMTP server.
                Your account has been validated automatically.
            """.strip("\n")).format(email_address))
            caller.msg(
                "-----  You will now create the first character of this account. -----"
            )
            _login(caller, account)
            text = ""
            options = ({
                "key": "_default",
                "desc": "Enter your new character's first name.",
                "goto": "create_first_name",
            }, )
        else:
            text = dedent("""
                An email has been sent to {}.  It contains your validation code which you'll need in
                order to finish creating your account.  If you haven't received the validation email
                after some minutes have passed, check your spam folder to see if it's inside of it.
                If not, you might want to select another email address, or contact an Avenew administrator.

                From here you can:
                    Type |wb|n to choose a different email address.
                    Enter your 4-digit validation code.
                """.strip("\n")).format(email_address)
            options = (
                {
                    "key": "b",
                    "desc": "Go back to the email address selection.",
                    "goto": "pre_email_address",
                },
                {
                    "key": "_default",
                    "desc": "Enter your validation code.",
                    "goto": "validate_account",
                },
            )

    return text, options
예제 #6
0
def password(caller, input):
    """Ask the user to enter the password to this account.

    This is assuming the user exists (see 'create_username' and
    'create_password').  This node "loops" if needed:  if the
    user specifies a wrong password, offers the user to try
    again or to go back by entering 'b'.
    If the password is correct, then login.

    """
    input = input.strip()
    text = ""
    options = ({
        "key": "_default",
        "desc": "Enter your password.",
        "goto": "password",
    }, )

    # Check the password
    account = caller.db._account

    # If the account is locked, the user has to wait (maximum
    # 3 seconds) before retrying
    if account.db._locked:
        text = "|gPlease wait, you cannot enter your password yet.|n"
        return text, options

    bans = ServerConfig.objects.conf("server_bans")
    banned = bans and (any(tup[0] == account.name.lower() for tup in bans) \
            or any(tup[2].match(caller.address) for tup in bans if tup[2]))

    if not account.check_password(input):
        text = dedent("""
            |rIncorrect password.|n
                Type |wb|n to go back to the login screen.
                Or wait 3 seconds before trying a new password.
        """.strip("\n"))

        # Loops on the same node, lock for 3 seconds
        account.db._locked = True
        delay(3, _wrong_password, account)
        options = (
            {
                "key": "b",
                "desc": "Go back to the login screen.",
                "goto": "pre_start",
            },
            {
                "key": "_default",
                "desc": "Enter your password again.",
                "goto": "password",
            },
        )
    elif banned:
        # This is a banned IP or name
        string = dedent("""
            |rYou have been banned and cannot continue from here.|n
            If you feel this ban is in error, please email an admin.
        """.strip("\n"))
        caller.msg(string)
        caller.sessionhandler.disconnect(caller, "Good bye!  Disconnecting...")
    else:
        # The password is correct, we can log into the account.
        caller.msg(echo=True)
        if not account.email:
            # Redirects to the node to set an email address
            text = _text_email_address(account)
            options = ({
                "key": "_default",
                "desc": "Enter your email address.",
                "goto": "email_address",
            }, )
        elif not account.db.valid:
            # Redirects to the node for the validation code
            text = "Enter your 4-digit validation code."
            options = ({
                "key": "_default",
                "desc": "Enter your validation code.",
                "goto": "validate_account",
            }, )
        else:
            _login(caller, account)
            text = ""
            options = _options_choose_characters(account)
            if not account.db._playable_characters:
                options = ({
                    "key": "_default",
                    "desc": "Enter your new character's first name.",
                    "goto": "create_first_name",
                }, )

    return text, options