mirror of
https://github.com/evennia/evennia.git
synced 2026-03-16 21:06:30 +01:00
Add unittests to email_login contrib and also update it to work correctly with latest code. Pertains to #1105.
This commit is contained in:
parent
e9a6465c65
commit
1b9016d26a
3 changed files with 67 additions and 78 deletions
|
|
@ -12,7 +12,7 @@ from evennia.objects.models import ObjectDB
|
|||
from evennia.server.models import ServerConfig
|
||||
from evennia.comms.models import ChannelDB
|
||||
|
||||
from evennia.utils import create, logger, utils, ansi
|
||||
from evennia.utils import create, logger, utils
|
||||
from evennia.commands.cmdhandler import CMD_LOGINSTART
|
||||
|
||||
COMMAND_DEFAULT_CLASS = utils.class_from_module(settings.COMMAND_DEFAULT_CLASS)
|
||||
|
|
@ -516,12 +516,12 @@ class CmdUnconnectedScreenreader(COMMAND_DEFAULT_CLASS):
|
|||
self.session.sessionhandler.session_portal_sync(self.session)
|
||||
|
||||
|
||||
def _create_player(session, playername, password, permissions, typeclass=None):
|
||||
def _create_player(session, playername, password, permissions, typeclass=None, email=None):
|
||||
"""
|
||||
Helper function, creates a player of the specified typeclass.
|
||||
"""
|
||||
try:
|
||||
new_player = create.create_player(playername, None, password, permissions=permissions, typeclass=typeclass)
|
||||
new_player = create.create_player(playername, email, password, permissions=permissions, typeclass=typeclass)
|
||||
|
||||
except Exception as e:
|
||||
session.msg("There was an error creating the Player:\n%s\n If this problem persists, contact an admin." % e)
|
||||
|
|
@ -535,7 +535,7 @@ def _create_player(session, playername, password, permissions, typeclass=None):
|
|||
|
||||
# join the new player to the public channel
|
||||
pchannel = ChannelDB.objects.get_channel(settings.DEFAULT_CHANNELS[0]["key"])
|
||||
if not pchannel.connect(new_player):
|
||||
if not pchannel or not pchannel.connect(new_player):
|
||||
string = "New player '%s' could not connect to public channel!" % new_player.key
|
||||
logger.log_err(string)
|
||||
return new_player
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ class CmdUnconnectedConnect(MuxCommand):
|
|||
# actually do the login. This will call all hooks.
|
||||
session.sessionhandler.login(session, player)
|
||||
|
||||
|
||||
from evennia.commands.default import unloggedin as default_unloggedin
|
||||
class CmdUnconnectedCreate(MuxCommand):
|
||||
"""
|
||||
Create a new account.
|
||||
|
|
@ -161,108 +161,86 @@ class CmdUnconnectedCreate(MuxCommand):
|
|||
"""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 re.findall('^[\w. @+-]+$', playername) or not (0 < len(playername) <= 30):
|
||||
session.msg("\n\r Playername can be max 30 characters, or less. Letters, spaces,"
|
||||
" digits and @/./+/-/_ only.") # this echoes the restrictions made by django's auth module.
|
||||
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
|
||||
|
||||
# Run sanity and security checks
|
||||
|
||||
if PlayerDB.objects.filter(username=playername):
|
||||
# player already exists
|
||||
# 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
|
||||
if len(password) < 3:
|
||||
# too short password
|
||||
string = "Your password must be at least 3 characters or longer."
|
||||
string += "\n\rFor best security, make it at least 8 characters long, "
|
||||
string += "avoid making it a real word and mix numbers into it."
|
||||
# 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:
|
||||
default_home = ObjectDB.objects.get_id(settings.DEFAULT_HOME)
|
||||
|
||||
typeclass = settings.BASE_CHARACTER_TYPECLASS
|
||||
permissions = settings.PERMISSION_PLAYER_DEFAULT
|
||||
|
||||
try:
|
||||
new_player = create.create_player(playername, email, password, permissions=permissions)
|
||||
|
||||
except Exception as e:
|
||||
session.msg("There was an error creating the default Player/Character:\n%s\n"
|
||||
" If this problem persists, contact an admin." % e)
|
||||
logger.log_trace()
|
||||
return
|
||||
|
||||
# This needs to be set so the engine knows this player is
|
||||
# logging in for the first time. (so it knows to call the right
|
||||
# hooks during login later)
|
||||
new_player.db.FIRST_LOGIN = True
|
||||
|
||||
# join the new player to the public channel
|
||||
pchanneldef = settings.CHANNEL_PUBLIC
|
||||
if pchanneldef:
|
||||
pchannel = ChannelDB.objects.get_channel(pchanneldef[0])
|
||||
if not pchannel.connect(new_player):
|
||||
string = "New player '%s' could not connect to public channel!" % new_player.key
|
||||
logger.log_err(string)
|
||||
|
||||
if MULTISESSION_MODE < 2:
|
||||
# if we only allow one character, create one with the same name as Player
|
||||
# (in mode 2, the character must be created manually once logging in)
|
||||
new_character = create.create_object(typeclass, key=playername,
|
||||
location=default_home, home=default_home,
|
||||
permissions=permissions)
|
||||
# set playable character list
|
||||
new_player.db._playable_characters.append(new_character)
|
||||
|
||||
# allow only the character itself and the player to puppet this character (and Immortals).
|
||||
new_character.locks.add("puppet:id(%i) or pid(%i) or perm(Immortals) or pperm(Immortals)" %
|
||||
(new_character.id, new_player.id))
|
||||
|
||||
# If no description is set, set a default description
|
||||
if not new_character.db.desc:
|
||||
new_character.db.desc = "This is a Player."
|
||||
# We need to set this to have @ic auto-connect to this character
|
||||
new_player.db._last_puppet = new_character
|
||||
|
||||
# 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))
|
||||
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.")
|
||||
raise
|
||||
session.msg("%sAn error occurred. Please e-mail an admin if the problem persists.")
|
||||
logger.log_trace()
|
||||
|
||||
|
||||
class CmdUnconnectedQuit(MuxCommand):
|
||||
"""
|
||||
We maintain a different version of the `quit` command
|
||||
|
|
@ -276,8 +254,7 @@ class CmdUnconnectedQuit(MuxCommand):
|
|||
def func(self):
|
||||
"""Simply close the connection."""
|
||||
session = self.caller
|
||||
session.msg("Good bye! Disconnecting ...")
|
||||
session.session_disconnect()
|
||||
session.sessionhandler.disconnect(session, "Good bye! Disconnecting.")
|
||||
|
||||
|
||||
class CmdUnconnectedLook(MuxCommand):
|
||||
|
|
|
|||
|
|
@ -489,6 +489,18 @@ class TestDice(CommandTest):
|
|||
self.call(dice.CmdDice(), "100000d1000", "The maximum roll allowed is 10000d10000.")
|
||||
self.call(dice.CmdDice(), "/secret 3d6 + 4", "You roll 3d6 + 4 (secret, not echoed).")
|
||||
|
||||
# Test email-login
|
||||
|
||||
from evennia.contrib import email_login
|
||||
|
||||
|
||||
class TestEmailLogin(CommandTest):
|
||||
def test_connect(self):
|
||||
self.call(email_login.CmdUnconnectedConnect(), "mytest@test.com test", "The email 'mytest@test.com' does not match any accounts.")
|
||||
self.call(email_login.CmdUnconnectedCreate(), '"mytest" mytest@test.com test11111', "A new account 'mytest' was created. Welcome!")
|
||||
self.call(email_login.CmdUnconnectedConnect(), "mytest@test.com test11111", "", caller=self.player.sessions.get()[0])
|
||||
def test_quit(self):
|
||||
self.call(email_login.CmdUnconnectedQuit(), "", "", caller=self.player.sessions.get()[0])
|
||||
def test_unconnectedlook(self):
|
||||
self.call(email_login.CmdUnconnectedLook(), "", "==========")
|
||||
def test_unconnectedhelp(self):
|
||||
self.call(email_login.CmdUnconnectedHelp(), "", "You are not yet logged into the game.")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue