From c0bab475d697c6d63e10b307a0ca080654a0f33a Mon Sep 17 00:00:00 2001 From: Griatch Date: Sat, 29 Sep 2018 11:11:41 +0200 Subject: [PATCH] Remove MAX_NR_CHARACTERS=1 enforcement for MULTISESSION_MODEs 0 and 1. --- CHANGELOG.md | 5 +++- evennia/accounts/accounts.py | 38 ++++++++++++++--------------- evennia/commands/default/account.py | 6 ++--- evennia/settings_default.py | 4 +-- 4 files changed, 27 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6dda27e14c..1463f67537 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ - The `evennia istart` option will start/switch the Server in foreground (interactive) mode, where it logs to terminal and can be stopped with Ctrl-C. Using `evennia reload`, or reloading in-game, will return Server to normal daemon operation. +- For validating passwords, use safe Django password-validation backend instead of custom Evennia one. ### Prototype changes @@ -80,11 +81,13 @@ ### General -- Up requirements to Django 1.11.x, Twited 18 and pillow 5.2.0 +- Up requirements to Django 1.11.x, Twisted 18 and pillow 5.2.0 - Start structuring the `CHANGELOG` to list features in more detail. - Docker image `evennia/evennia:develop` is now auto-built, tracking the develop branch. - Inflection and grouping of multiple objects in default room (an box, three boxes) - `evennia.set_trace()` is now a shortcut for launching pdb/pudb on a line in the Evennia event loop. +- Removed the enforcing of `MAX_NR_CHARACTERS=1` for `MULTISESSION_MODE` `0` and `1` by default. +- Add `evennia.utils.logger.log_sec` for logging security-related messages (marked SS in log). ### Contribs diff --git a/evennia/accounts/accounts.py b/evennia/accounts/accounts.py index ba2616f003..2c33e5c1f8 100644 --- a/evennia/accounts/accounts.py +++ b/evennia/accounts/accounts.py @@ -362,63 +362,63 @@ class DefaultAccount(with_metaclass(TypeclassBase, AccountDB)): @classmethod def validate_password(cls, password, account=None): """ - Checks the given password against the list of Django validators enabled + Checks the given password against the list of Django validators enabled in the server.conf file. - + Args: password (str): Password to validate - + Kwargs: account (DefaultAccount, optional): Account object to validate the password for. Optional, but Django includes some validators to - do things like making sure users aren't setting passwords to the + do things like making sure users aren't setting passwords to the same value as their username. If left blank, these user-specific checks are skipped. - + Returns: valid (bool): Whether or not the password passed validation error (ValidationError, None): Any validation error(s) raised. Multiple errors can be nested within a single object. - + """ valid = False error = None - + # Validation returns None on success; invert it and return a more sensible bool - try: + try: valid = not password_validation.validate_password(password, user=account) except ValidationError as e: error = e - + return valid, error - + def set_password(self, password, force=False): """ Applies the given password to the account if it passes validation checks. Can be overridden by using the 'force' flag. - + Args: password (str): Password to set - + Kwargs: force (bool): Sets password without running validation checks. - + Raises: ValidationError - + Returns: None (None): Does not return a value. - + """ if not force: # Run validation checks valid, error = self.validate_password(password, account=self) if error: raise error - + super(DefaultAccount, self).set_password(password) logger.log_info("Password succesfully changed for %s." % self) self.at_password_change() - + def delete(self, *args, **kwargs): """ Deletes the account permanently. @@ -775,7 +775,7 @@ class DefaultAccount(with_metaclass(TypeclassBase, AccountDB)): """ pass - + def at_password_change(self, **kwargs): """ Called after a successful password set/modify. @@ -1022,7 +1022,7 @@ class DefaultAccount(with_metaclass(TypeclassBase, AccountDB)): result.append("\n\n |whelp|n - more commands") result.append("\n |wooc |n - talk on public channel") - charmax = _MAX_NR_CHARACTERS if _MULTISESSION_MODE > 1 else 1 + charmax = _MAX_NR_CHARACTERS if is_su or len(characters) < charmax: if not characters: diff --git a/evennia/commands/default/account.py b/evennia/commands/default/account.py index d81ef8a8f0..b50f55a8e0 100644 --- a/evennia/commands/default/account.py +++ b/evennia/commands/default/account.py @@ -136,7 +136,7 @@ class CmdCharCreate(COMMAND_DEFAULT_CLASS): key = self.lhs desc = self.rhs - charmax = _MAX_NR_CHARACTERS if _MULTISESSION_MODE > 1 else 1 + charmax = _MAX_NR_CHARACTERS if not account.is_superuser and \ (account.db._playable_characters and @@ -627,10 +627,10 @@ class CmdPassword(COMMAND_DEFAULT_CLASS): return oldpass = self.lhslist[0] # Both of these are newpass = self.rhslist[0] # already stripped by parse() - + # Validate password validated, error = account.validate_password(newpass) - + if not account.check_password(oldpass): self.msg("The specified old password isn't correct.") elif not validated: diff --git a/evennia/settings_default.py b/evennia/settings_default.py index 134f37578b..9efbb6314b 100644 --- a/evennia/settings_default.py +++ b/evennia/settings_default.py @@ -552,9 +552,7 @@ PROTOTYPEFUNC_MODULES = ["evennia.utils.prototypefuncs", # 3 - like mode 2, except multiple sessions can puppet one character, each # session getting the same data. MULTISESSION_MODE = 0 -# The maximum number of characters allowed for MULTISESSION_MODE 2, 3. -# This is checked by the default ooc char-creation command. Forced to 1 for -# MULTISESSION_MODE 0 and 1. +# The maximum number of characters allowed by the default ooc char-creation command MAX_NR_CHARACTERS = 1 # The access hierarchy, in climbing order. A higher permission in the # hierarchy includes access of all levels below it. Used by the perm()/pperm()