Esempio n. 1
0
def _confirm_password(caller, user_input):
    password = caller.ndb.new_password
    menutree = caller.ndb._menutree
    if user_input == password:
        # Create the new player account
        playername = menutree.playername
        from evennia.commands.default import unloggedin
        # We make use of the helper functions from the default set here.
        # noinspection PyBroadException
        try:
            permissions = settings.PERMISSION_PLAYER_DEFAULT
            new_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(LOGIN_ERROR)
            logger.log_trace()
        else:
            caller.ndb.passed_account_creation = True
            caller.msg(LOGIN_ACCOUNT_CREATED.format(playername))
            caller.sessionhandler.login(caller, new_player)
    else:
        caller.msg(LOGIN_PASSWORD_MISMATCH)
        caller.ndb.confirm_needed = False
Esempio n. 2
0
def create_password(caller, string_input):
    """Ask the user to create a password.

    This node is at the end of the menu for account creation.  If
    a proper MULTI_SESSION is configured, a character is also
    created with the same name (we try to login into it).

    """
    menutree = caller.ndb._menutree
    text = ""
    options = (
        {"key": "",
         "exec": lambda caller: caller.msg("", options={"echo": True}),
         "goto": "start"},
        {"key": "_default",
         "goto": "create_password"})

    password = string_input.strip()
    playername = menutree.playername

    if len(password) < LEN_PASSWD:
        # The password is too short
        text = dedent("""
            |rYour password must be at least {} characters long.|n
            Enter another password or leave it empty to go back.
        """.strip("\n")).format(LEN_PASSWD)
    else:
        # Everything's OK.  Create the new player account and
        # possibly the character, depending on the multisession mode
        from evennia.commands.default import unloggedin
        # We make use of the helper functions from the default set here.
        try:
            permissions = settings.PERMISSION_PLAYER_DEFAULT
            typeclass = settings.BASE_CHARACTER_TYPECLASS
            new_player = unloggedin._create_player(caller, playername,
                                                   password, permissions)
            if new_player:
                if settings.MULTISESSION_MODE < 2:
                    default_home = ObjectDB.objects.get_id(
                        settings.DEFAULT_HOME)
                    unloggedin._create_character(caller, new_player,
                                                 typeclass, default_home, 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. Try another password or leave
                it empty to go back to the login screen.
            """.strip("\n")))
            logger.log_trace()
        else:
            text = ""
            caller.msg("|gWelcome, your new account has been created!|n")
            caller.msg("", options={"echo": True})
            caller.sessionhandler.login(caller, new_player)

    return text, options
Esempio n. 3
0
    def func(self):
        "Execute  the command"
        password = self.args
        self.caller.msg(echo=False)
        if not hasattr(self.menutree, 'playername'):
            self.caller.msg(
                "{rSomething went wrong! Playername not remembered from previous step!{n"
            )
            self.menutree.goto("node2a")
            return
        playername = self.menutree.playername
        if len(password) < 3:
            # too short password
            string = "{rYour password must be at least 3 characters or longer."
            string += "\n\rFor best security, make it at least 8 characters "
            string += "long, avoid making it a real word and mix numbers "
            string += "into it.{n"
            self.caller.msg(string)
            self.menutree.goto("node2b")
            return
        # everything's ok. Create the new player account and possibly the character
        # depending on the multisession mode

        from evennia.commands.default import unloggedin
        # we make use of the helper functions from the default set here.
        try:
            permissions = settings.PERMISSION_PLAYER_DEFAULT
            typeclass = settings.BASE_CHARACTER_TYPECLASS
            new_player = unloggedin._create_player(self.caller, playername,
                                                   password, permissions)
            if new_player:
                if MULTISESSION_MODE < 2:
                    default_home = ObjectDB.objects.get_id(
                        settings.DEFAULT_HOME)
                    unloggedin._create_character(self.caller, new_player,
                                                 typeclass, default_home,
                                                 permissions)
            # tell the caller everything went well.
            string = "{gA new account '%s' was created. Now go log in from the menu!{n"
            self.caller.msg(string % (playername))
            self.menutree.goto("START")
        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.
            self.caller.msg(
                "An error occurred. Please e-mail an admin if the problem persists."
            )
            logger.log_trace()
Esempio n. 4
0
    def func(self):
        "Execute  the command"
        password = self.args
        self.caller.msg(echo=False)
        if not hasattr(self.menutree, 'playername'):
            self.caller.msg("{rSomething went wrong! Playername not remembered from previous step!{n")
            self.menutree.goto("node2a")
            return
        playername = self.menutree.playername
        if len(password) < 3:
            # too short password
            string = "{rYour password must be at least 3 characters or longer."
            string += "\n\rFor best security, make it at least 8 characters "
            string += "long, avoid making it a real word and mix numbers "
            string += "into it.{n"
            self.caller.msg(string)
            self.menutree.goto("node2b")
            return
        # everything's ok. Create the new player account and possibly the character
        # depending on the multisession mode

        from evennia.commands.default import unloggedin
        # we make use of the helper functions from the default set here.
        try:
            permissions = settings.PERMISSION_PLAYER_DEFAULT
            typeclass = settings.BASE_CHARACTER_TYPECLASS
            new_player = unloggedin._create_player(self.caller, playername,
                                               password, permissions)
            if new_player:
                if MULTISESSION_MODE < 2:
                    default_home = ObjectDB.objects.get_id(settings.DEFAULT_HOME)
                    unloggedin._create_character(self.caller, new_player, typeclass,
                                                 default_home, permissions)
            # tell the caller everything went well.
            string = "{gA new account '%s' was created. Now go log in from the menu!{n"
            self.caller.msg(string % (playername))
            self.menutree.goto("START")
        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.
            string = "%s\nThis is a bug. Please e-mail an admin if the problem persists."
            self.caller.msg(string % (traceback.format_exc()))
            logger.log_errmsg(traceback.format_exc())
Esempio n. 5
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
Esempio n. 6
0
def create_password(caller, string_input):
    """Ask the user to create a password.

    This node is at the end of the menu for account creation.  If
    a proper MULTI_SESSION is configured, a character is also
    created with the same name (we try to login into it).

    """
    menutree = caller.ndb._menutree
    text = ""
    options = (
        {
            "key": "",
            "exec": lambda caller: caller.msg("", options={"echo": True}),
            "goto": "start",
        },
        {
            "key": "_default",
            "goto": "create_password",
        },
    )

    password = string_input.strip()
    playername = menutree.playername

    if len(password) < LEN_PASSWD:
        # The password is too short
        text = dedent("""
            |rYour password must be at least {} characters long.|n
            Enter another password or leave it empty to go back.
        """.strip("\n")).format(LEN_PASSWD)
    else:
        # Everything's OK.  Create the new player account and
        # possibly the character, depending on the multisession mode
        from evennia.commands.default import unloggedin
        # We make use of the helper functions from the default set here.
        try:
            permissions = settings.PERMISSION_PLAYER_DEFAULT
            typeclass = settings.BASE_CHARACTER_TYPECLASS
            new_player = unloggedin._create_player(caller, playername,
                                                   password, permissions)
            if new_player:
                if settings.MULTISESSION_MODE < 2:
                    default_home = ObjectDB.objects.get_id(
                        settings.DEFAULT_HOME)
                    unloggedin._create_character(caller, new_player, typeclass,
                                                 default_home, 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. Try another password or leave
                it empty to go back to the login screen.
            """.strip("\n")))
            logger.log_trace()
        else:
            text = ""
            caller.msg("|gWelcome, your new account has been created!|n")
            caller.msg("", options={"echo": True})
            caller.sessionhandler.login(caller, new_player)

    return text, options
Esempio n. 7
0
    def func(self):
        """
        Uses the Django admin api. Note that unlogged-in commands
        have a unique position in that their func() receives
        a session object instead of a source_object like all
        other types of logged-in commands (this is because
        there is no object yet before the player has logged in)
        """
        session = self.caller

        # check for too many login errors too quick.
        if _throttle(session,
                     maxlim=5,
                     timeout=5 * 60,
                     storage=_LATEST_FAILED_LOGINS):
            # timeout is 5 minutes.
            session.msg(
                "{RВы совершаете слишклм много подключений. Подождите пару минут и попробуйте снова.{n"
            )
            return

        args = self.args
        # extract quoted parts
        parts = [
            part.strip() for part in re.split(r"\"|\'", args) if part.strip()
        ]
        if len(parts) == 1:
            # this was (hopefully) due to no quotes being found, or a guest login
            parts = parts[0].split(None, 1)
            # Guest login
            if len(parts) == 1 and parts[0].lower(
            ) == "guest" and settings.GUEST_ENABLED:
                try:
                    # Find an available guest name.
                    for playername in settings.GUEST_LIST:
                        if not PlayerDB.objects.filter(
                                username__iexact=playername):
                            break
                        playername = None
                    if playername == None:
                        session.msg(
                            "Все гостевые аккаунты сейчас используются. Попробуйте немного позже."
                        )
                        return

                    password = "******" % getrandbits(64)
                    home = ObjectDB.objects.get_id(settings.GUEST_HOME)
                    permissions = settings.PERMISSION_GUEST_DEFAULT
                    typeclass = settings.BASE_CHARACTER_TYPECLASS
                    ptypeclass = settings.BASE_GUEST_TYPECLASS
                    new_player = _create_player(session, playername, password,
                                                permissions, ptypeclass)
                    if new_player:
                        _create_character(session, new_player, typeclass, home,
                                          permissions)
                        session.sessionhandler.login(session, new_player)

                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.
                    string = "%s\nЭто баг. Напишите пожалуйста на почту администратора."
                    session.msg(string % (traceback.format_exc()))
                    logger.log_errmsg(traceback.format_exc())
                finally:
                    return

        if len(parts) != 2:
            session.msg(
                "\n\r Использование (без <>): коннект <имя пользователя> <пароль>. Сокашенные варианты: кон, ко, войти"
            )
            return
        playername, password = parts

        # Match account name and check password
        player = PlayerDB.objects.get_player_from_name(playername)
        pswd = None
        if player:
            pswd = player.check_password(password)

        if not (player and pswd):
            # No playername or password match
            string = "Неверные логин или пароль.\nЕсли в вашем логине или " \
                     "пароле есть пробелы, поместите их в кавычки." \
                     "\nЕсли вы новичек, создайте аккаунт при помощи" \
                     "команды 'создать'."
            session.msg(string)
            # this just updates the throttle
            _throttle(session, storage=_LATEST_FAILED_LOGINS)
            # calls player hook for a failed login if possible.
            if player:
                player.at_failed_login(session)
            return

        # Check IP and/or name bans
        bans = ServerConfig.objects.conf("server_bans")
        if bans and (any(tup[0] == player.name.lower()
                         for tup in bans) or any(tup[2].match(session.address)
                                                 for tup in bans if tup[2])):
            # this is a banned IP or name!
            string = "{rВы были забанены." \
                     "\nЕсли считате, что мы были не правы, пишите на е-маил администратора.{x"
            session.msg(string)
            session.execute_cmd("quit")
            return

        # actually do the login. This will call all other hooks:
        #   session.at_login()
        #   player.at_init()  # always called when object is loaded from disk
        #   player.at_pre_login()
        #   player.at_first_login()  # only once
        #   player.at_post_login(sessid=sessid)
        session.sessionhandler.login(session, player)
Esempio n. 8
0
    def func(self):
        "Do checks and create account"

        session = self.caller
        args = self.args.strip()

        # extract quoted parts
        parts = [
            part.strip() for part in re.split(r"\"|\'", args) if part.strip()
        ]
        if len(parts) == 1:
            # this was (hopefully) due to no quotes being found
            parts = parts[0].split(None, 1)
        if len(parts) != 2:
            string = u"\n Использование (без <>): создать <имя персонажа> <пароль>" \
                     u"\nЕсли <имя персонажа> или <пароль> содержат пробелы, нужно взять их в ковычки"
            session.msg(string)
            return
        playername, password = parts

        # sanity checks
        if not re.findall('^[\w. @+-]+$', playername,
                          re.UNICODE) or not (0 < len(playername) <= 30):
            # this echoes the restrictions made by django's auth
            # module (except not allowing spaces, for convenience of
            # logging in).
            string = u"\n\r Имя персонажа не должно превышать 30 символов. Имя может содержать только, буквы пробелы, цифры и @/./+/-/_"
            #string = "\n\r Playername can max be 30 characters or fewer. Letters, spaces, digits and @/./+/-/_ only."
            session.msg(string)
            return
        # strip excessive spaces in playername
        playername = re.sub(r"\s+", " ", playername).strip()
        if PlayerDB.objects.filter(username__iexact=playername):
            # player already exists (we also ignore capitalization here)
            session.msg(u"Игрок с таким именем '%s' уже есть." % playername)
            return
        # Reserve playernames found in GUEST_LIST
        if settings.GUEST_LIST and playername.lower() in map(
                str.lower, settings.GUEST_LIST):
            string = u"\n\r Это имя зарезервировано. Пожалуйста выберите другое имя."
            session.msg(string)
            return
        if not re.findall('^[\w. @+-]+$', password,
                          re.UNICODE) or not (3 < len(password)):
            string = u"\n\r Пароль должен быть больше трех символов и может состоять только из пробелов, цифр @\.\+\-\_"  \
                     u"\nДля лучшей безопасности выберите пароль от 8 символов "
            session.msg(string)
            return

        # Check IP and/or name bans
        bans = ServerConfig.objects.conf("server_bans")
        if bans and (any(tup[0] == playername.lower()
                         for tup in bans) or any(tup[2].match(session.address)
                                                 for tup in bans if tup[2])):
            # this is a banned IP or name!
            string = u"{rТы забанен{x"
            session.msg(string)
            session.execute_cmd("quit")
            return

        # everything's ok. Create the new player account.
        try:
            permissions = settings.PERMISSION_PLAYER_DEFAULT
            typeclass = settings.BASE_CHARACTER_TYPECLASS
            new_player = _create_player(session, playername, password,
                                        permissions)
            if new_player:
                if MULTISESSION_MODE < 2:
                    default_home = ObjectDB.objects.get_id(
                        settings.DEFAULT_HOME)
                    _create_character(session, new_player, typeclass,
                                      default_home, permissions)
                # tell the caller everything went well.
                string = u"Новый аккаунт создан Добро пожаловать %%USERNAME%%"
                if " " in playername:
                    string += u"\n\nТеперь можно войти в игру 'connect \"%s\" <пароль>'."
                else:
                    string += u"\n\nТеперь можно войти в игру 'connect %s <пароль>'."
                session.msg(string % (playername))

        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.
            string = u"%s\nСлучилась проблема, чиним."
            session.msg(string % (traceback.format_exc()))
            logger.log_errmsg(traceback.format_exc())
Esempio n. 9
0
    def func(self):
        """
        Uses the Django admin api. Note that unlogged-in commands
        have a unique position in that their func() receives
        a session object instead of a source_object like all
        other types of logged-in commands (this is because
        there is no object yet before the player has logged in)
        """
        session = self.caller

        # check for too many login errors too quick.
        if _throttle(session, maxlim=5, timeout=5*60, storage=_LATEST_FAILED_LOGINS):
            # timeout is 5 minutes.
            session.msg("{RВы совершаете слишклм много подключений. Подождите пару минут и попробуйте снова.{n")
            return

        args = self.args
        # extract quoted parts
        parts = [part.strip() for part in re.split(r"\"|\'", args) if part.strip()]
        if len(parts) == 1:
            # this was (hopefully) due to no quotes being found, or a guest login
            parts = parts[0].split(None, 1)
            # Guest login
            if len(parts) == 1 and parts[0].lower() == "guest" and settings.GUEST_ENABLED:
                try:
                    # Find an available guest name.
                    for playername in settings.GUEST_LIST:
                        if not PlayerDB.objects.filter(username__iexact=playername):
                            break
                        playername = None
                    if playername == None:
                        session.msg("Все гостевые аккаунты сейчас используются. Попробуйте немного позже.")
                        return

                    password = "******" % getrandbits(64)
                    home = ObjectDB.objects.get_id(settings.GUEST_HOME)
                    permissions = settings.PERMISSION_GUEST_DEFAULT
                    typeclass = settings.BASE_CHARACTER_TYPECLASS
                    ptypeclass = settings.BASE_GUEST_TYPECLASS
                    new_player = _create_player(session, playername, password,
                                                permissions, ptypeclass)
                    if new_player:
                        _create_character(session, new_player, typeclass,
                                        home, permissions)
                        session.sessionhandler.login(session, new_player)

                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.
                    string = "%s\nЭто баг. Напишите пожалуйста на почту администратора."
                    session.msg(string % (traceback.format_exc()))
                    logger.log_errmsg(traceback.format_exc())
                finally:
                    return

        if len(parts) != 2:
            session.msg("\n\r Использование (без <>): коннект <имя пользователя> <пароль>. Сокашенные варианты: кон, ко, войти")
            return
        playername, password = parts

        # Match account name and check password
        player = PlayerDB.objects.get_player_from_name(playername)
        pswd = None
        if player:
            pswd = player.check_password(password)

        if not (player and pswd):
            # No playername or password match
            string = "Неверные логин или пароль.\nЕсли в вашем логине или " \
                     "пароле есть пробелы, поместите их в кавычки." \
                     "\nЕсли вы новичек, создайте аккаунт при помощи" \
                     "команды 'создать'."
            session.msg(string)
            # this just updates the throttle
            _throttle(session, storage=_LATEST_FAILED_LOGINS)
            # calls player hook for a failed login if possible.
            if player:
                player.at_failed_login(session)
            return

        # Check IP and/or name bans
        bans = ServerConfig.objects.conf("server_bans")
        if bans and (any(tup[0]==player.name.lower() for tup in bans)
                     or
                     any(tup[2].match(session.address) for tup in bans if tup[2])):
            # this is a banned IP or name!
            string = "{rВы были забанены." \
                     "\nЕсли считате, что мы были не правы, пишите на е-маил администратора.{x"
            session.msg(string)
            session.execute_cmd("quit")
            return

        # actually do the login. This will call all other hooks:
        #   session.at_login()
        #   player.at_init()  # always called when object is loaded from disk
        #   player.at_pre_login()
        #   player.at_first_login()  # only once
        #   player.at_post_login(sessid=sessid)
        session.sessionhandler.login(session, player)
Esempio n. 10
0
    def func(self):
        "Do checks and create account"

        session = self.caller
        args = self.args.strip()

        # extract quoted parts
        parts = [part.strip() for part in re.split(r"\"|\'", args) if part.strip()]
        if len(parts) == 1:
            # this was (hopefully) due to no quotes being found
            parts = parts[0].split(None, 1)
        if len(parts) != 2:
            string = u"\n Использование (без <>): создать <имя персонажа> <пароль>" \
                     u"\nЕсли <имя персонажа> или <пароль> содержат пробелы, нужно взять их в ковычки"
            session.msg(string)
            return
        playername, password = parts

        # sanity checks
        if not re.findall('^[\w. @+-]+$', playername,re.UNICODE) or not (0 < len(playername) <= 30):
            # this echoes the restrictions made by django's auth
            # module (except not allowing spaces, for convenience of
            # logging in).
            string = u"\n\r Имя персонажа не должно превышать 30 символов. Имя может содержать только, буквы пробелы, цифры и @/./+/-/_"
            #string = "\n\r Playername can max be 30 characters or fewer. Letters, spaces, digits and @/./+/-/_ only."
            session.msg(string)
            return
        # strip excessive spaces in playername
        playername = re.sub(r"\s+", " ", playername).strip()
        if PlayerDB.objects.filter(username__iexact=playername):
            # player already exists (we also ignore capitalization here)
            session.msg(u"Игрок с таким именем '%s' уже есть." % playername)
            return
        # Reserve playernames found in GUEST_LIST
        if settings.GUEST_LIST and playername.lower() in map(str.lower, settings.GUEST_LIST):
            string = u"\n\r Это имя зарезервировано. Пожалуйста выберите другое имя."
            session.msg(string)
            return
        if not re.findall('^[\w. @+-]+$', password,re.UNICODE) or not (3 < len(password)):
            string = u"\n\r Пароль должен быть больше трех символов и может состоять только из пробелов, цифр @\.\+\-\_"  \
                     u"\nДля лучшей безопасности выберите пароль от 8 символов " 
            session.msg(string)
            return

        # Check IP and/or name bans
        bans = ServerConfig.objects.conf("server_bans")
        if bans and (any(tup[0]==playername.lower() for tup in bans)
                     or
                     any(tup[2].match(session.address) for tup in bans if tup[2])):
            # this is a banned IP or name!
            string = u"{rТы забанен{x"
            session.msg(string)
            session.execute_cmd("quit")
            return

        # everything's ok. Create the new player account.
        try:
            permissions = settings.PERMISSION_PLAYER_DEFAULT
            typeclass = settings.BASE_CHARACTER_TYPECLASS
            new_player = _create_player(session, playername, password, permissions)
            if new_player:
                if MULTISESSION_MODE < 2:
                    default_home = ObjectDB.objects.get_id(settings.DEFAULT_HOME)
                    _create_character(session, new_player, typeclass,
                                    default_home, permissions)
                # tell the caller everything went well.
                string = u"Новый аккаунт создан Добро пожаловать %%USERNAME%%"
                if " " in playername:
                    string += u"\n\nТеперь можно войти в игру 'connect \"%s\" <пароль>'."
                else:
                    string += u"\n\nТеперь можно войти в игру 'connect %s <пароль>'."
                session.msg(string % (playername))

        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.
            string = u"%s\nСлучилась проблема, чиним."
            session.msg(string % (traceback.format_exc()))
            logger.log_errmsg(traceback.format_exc())
Esempio n. 11
0
    def func(self):
        """Do checks and create account"""

        session = self.caller
        try:
            playername, email, password = self.playerinfo
        except ValueError:
            string = "\n\r Usage (without <>): create \"<playername>\" <email> <password>"
            session.msg(string)
            return
        if not email or not password:
            session.msg("\n\r You have to supply an e-mail address followed by a password.")
            return
        if not utils.validate_email_address(email):
            # check so the email at least looks ok.
            session.msg("'%s' is not a valid e-mail address." % email)
            return
        # sanity checks
        if not re.findall(r"^[\w. @+\-']+$", playername) or not (0 < len(playername) <= 30):
            # this echoes the restrictions made by django's auth
            # module (except not allowing spaces, for convenience of
            # logging in).
            string = "\n\r Playername can max be 30 characters or fewer. Letters, spaces, digits and @/./+/-/_/' only."
            session.msg(string)
            return
        # strip excessive spaces in playername
        playername = re.sub(r"\s+", " ", playername).strip()
        if PlayerDB.objects.filter(username__iexact=playername):
            # player already exists (we also ignore capitalization here)
            session.msg("Sorry, there is already a player with the name '%s'." % playername)
            return
        if PlayerDB.objects.get_player_from_email(email):
            # email already set on a player
            session.msg("Sorry, there is already a player with that email address.")
            return
        # Reserve playernames found in GUEST_LIST
        if settings.GUEST_LIST and playername.lower() in (guest.lower() for guest in settings.GUEST_LIST):
            string = "\n\r That name is reserved. Please choose another Playername."
            session.msg(string)
            return
        if not re.findall(r"^[\w. @+\-']+$", password) or not (3 < len(password)):
            string = "\n\r Password should be longer than 3 characers. Letters, spaces, digits and @/./+/-/_/' only." \
                     "\nFor best security, make it longer than 8 characters. You can also use a phrase of" \
                     "\nmany words if you enclose the password in double quotes."
            session.msg(string)
            return

        # Check IP and/or name bans
        bans = ServerConfig.objects.conf("server_bans")
        if bans and (any(tup[0] == playername.lower() for tup in bans)
                     or
                     any(tup[2].match(session.address) for tup in bans if tup[2])):
            # this is a banned IP or name!
            string = "|rYou have been banned and cannot continue from here." \
                     "\nIf you feel this ban is in error, please email an admin.|x"
            session.msg(string)
            session.sessionhandler.disconnect(session, "Good bye! Disconnecting.")
            return

        # everything's ok. Create the new player account.
        try:
            permissions = settings.PERMISSION_PLAYER_DEFAULT
            typeclass = settings.BASE_CHARACTER_TYPECLASS
            new_player = default_unloggedin._create_player(session, playername, password, permissions, email=email)
            if new_player:
                if MULTISESSION_MODE < 2:
                    default_home = ObjectDB.objects.get_id(settings.DEFAULT_HOME)
                    default_unloggedin._create_character(session, new_player, typeclass, default_home, permissions)
                # tell the caller everything went well.
                string = "A new account '%s' was created. Welcome!"
                if " " in playername:
                    string += "\n\nYou can now log in with the command 'connect \"%s\" <your password>'."
                else:
                    string += "\n\nYou can now log with the command 'connect %s <your password>'."
                session.msg(string % (playername, email))

        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.
            session.msg("An error occurred. Please e-mail an admin if the problem persists.")
            logger.log_trace()
            raise
Esempio n. 12
0
    def func(self):
        """Do checks and create account"""

        session = self.caller
        try:
            playername, email, password = self.playerinfo
        except ValueError:
            string = "\n\r Usage (without <>): create \"<playername>\" <email> <password>"
            session.msg(string)
            return
        if not email or not password:
            session.msg("\n\r You have to supply an e-mail address followed by a password.")
            return
        if not utils.validate_email_address(email):
            # check so the email at least looks ok.
            session.msg("'%s' is not a valid e-mail address." % email)
            return
        # sanity checks
        if not re.findall(r"^[\w. @+\-']+$", playername) or not (0 < len(playername) <= 30):
            # this echoes the restrictions made by django's auth
            # module (except not allowing spaces, for convenience of
            # logging in).
            string = "\n\r Playername can max be 30 characters or fewer. Letters, spaces, digits and @/./+/-/_/' only."
            session.msg(string)
            return
        # strip excessive spaces in playername
        playername = re.sub(r"\s+", " ", playername).strip()
        if PlayerDB.objects.filter(username__iexact=playername):
            # player already exists (we also ignore capitalization here)
            session.msg("Sorry, there is already a player with the name '%s'." % playername)
            return
        if PlayerDB.objects.get_player_from_email(email):
            # email already set on a player
            session.msg("Sorry, there is already a player with that email address.")
            return
        # Reserve playernames found in GUEST_LIST
        if settings.GUEST_LIST and playername.lower() in (guest.lower() for guest in settings.GUEST_LIST):
            string = "\n\r That name is reserved. Please choose another Playername."
            session.msg(string)
            return
        if not re.findall(r"^[\w. @+\-']+$", password) or not (3 < len(password)):
            string = "\n\r Password should be longer than 3 characers. Letters, spaces, digits and @/./+/-/_/' only." \
                     "\nFor best security, make it longer than 8 characters. You can also use a phrase of" \
                     "\nmany words if you enclose the password in double quotes."
            session.msg(string)
            return

        # Check IP and/or name bans
        bans = ServerConfig.objects.conf("server_bans")
        if bans and (any(tup[0] == playername.lower() for tup in bans)
                     or
                     any(tup[2].match(session.address) for tup in bans if tup[2])):
            # this is a banned IP or name!
            string = "|rYou have been banned and cannot continue from here." \
                     "\nIf you feel this ban is in error, please email an admin.|x"
            session.msg(string)
            session.sessionhandler.disconnect(session, "Good bye! Disconnecting.")
            return

        # everything's ok. Create the new player account.
        try:
            permissions = settings.PERMISSION_PLAYER_DEFAULT
            typeclass = settings.BASE_CHARACTER_TYPECLASS
            new_player = default_unloggedin._create_player(session, playername, password, permissions, email=email)
            if new_player:
                if MULTISESSION_MODE < 2:
                    default_home = ObjectDB.objects.get_id(settings.DEFAULT_HOME)
                    default_unloggedin._create_character(session, new_player, typeclass, default_home, permissions)
                # tell the caller everything went well.
                string = "A new account '%s' was created. Welcome!"
                if " " in playername:
                    string += "\n\nYou can now log in with the command 'connect \"%s\" <your password>'."
                else:
                    string += "\n\nYou can now log with the command 'connect %s <your password>'."
                session.msg(string % (playername, email))

        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.
            raise
            session.msg("%sAn error occurred. Please e-mail an admin if the problem persists.")
            logger.log_trace()
Esempio n. 13
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