Implement manual account creation for admins
This commit is contained in:
parent
24961db152
commit
c6f3cfac3b
3 changed files with 136 additions and 0 deletions
0
cwopamud/commands/cwopa/__init__.py
Normal file
0
cwopamud/commands/cwopa/__init__.py
Normal file
133
cwopamud/commands/cwopa/admin.py
Normal file
133
cwopamud/commands/cwopa/admin.py
Normal file
|
@ -0,0 +1,133 @@
|
||||||
|
"""
|
||||||
|
Commands - CWOPA MUD Admin
|
||||||
|
|
||||||
|
Custom commands for an admin account on the CWOPA MUD.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import re
|
||||||
|
import secrets
|
||||||
|
import string
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
from evennia.utils import class_from_module
|
||||||
|
|
||||||
|
|
||||||
|
COMMAND_DEFAULT_CLASS = class_from_module(settings.COMMAND_DEFAULT_CLASS)
|
||||||
|
|
||||||
|
_ALPHABET = string.ascii_letters + string.digits
|
||||||
|
|
||||||
|
|
||||||
|
def generate_password(length: int = 16) -> str:
|
||||||
|
"""Creates a cryptographically safe password."""
|
||||||
|
return "".join(secrets.choice(_ALPHABET) for i in range(length))
|
||||||
|
|
||||||
|
|
||||||
|
class CmdCwopaAdminCreate(COMMAND_DEFAULT_CLASS):
|
||||||
|
"""
|
||||||
|
manually create a new account as an admin
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
admincreate <accountname> [<password>]
|
||||||
|
|
||||||
|
This creates a new account for someone else as an admin. This is useful
|
||||||
|
for situtions where registration is disabled but you still want to make
|
||||||
|
accounts. If a password is not provided, a random 16-character password
|
||||||
|
will be provided. If there are spaces in the username or password, wrap
|
||||||
|
it in double quotes.
|
||||||
|
"""
|
||||||
|
|
||||||
|
key = "admincreate"
|
||||||
|
aliases = ["adcre", "adcr"]
|
||||||
|
locks = "cmd:perm(admincreate) or perm(Admin)"
|
||||||
|
help_category = "Admin"
|
||||||
|
arg_regex = r"\s.*?|$"
|
||||||
|
|
||||||
|
def func(self):
|
||||||
|
"""Create a new account (with character)."""
|
||||||
|
|
||||||
|
session = self.caller
|
||||||
|
args = self.args.strip()
|
||||||
|
|
||||||
|
# Grab the account class
|
||||||
|
Account = class_from_module(settings.BASE_ACCOUNT_TYPECLASS)
|
||||||
|
|
||||||
|
# extract double quoted parts
|
||||||
|
parts = [part.strip() for part in re.split(r"\"", args) if part.strip()]
|
||||||
|
if '"' in args:
|
||||||
|
if len(parts) == 1:
|
||||||
|
username = parts[0]
|
||||||
|
password = generate_password()
|
||||||
|
elif len(parts) == 2:
|
||||||
|
username = parts[0]
|
||||||
|
password = parts[1]
|
||||||
|
else:
|
||||||
|
usage = (
|
||||||
|
"\n Usage (without <>): admincreate <name> <password>"
|
||||||
|
"\nIf <name> or <password> contains spaces, enclose them in double quotes."
|
||||||
|
)
|
||||||
|
session.msg(usage)
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
if len(parts) == 1:
|
||||||
|
parts = parts[0].split(None)
|
||||||
|
if len(parts) == 1:
|
||||||
|
username = parts[0]
|
||||||
|
password = generate_password()
|
||||||
|
elif len(parts) == 2:
|
||||||
|
username = parts[0]
|
||||||
|
password = parts[1]
|
||||||
|
else:
|
||||||
|
usage = (
|
||||||
|
"\n Usage (without <>): admincreate <name> <password>"
|
||||||
|
"\nIf <name> or <password> contains spaces, enclose "
|
||||||
|
"them in double quotes."
|
||||||
|
)
|
||||||
|
session.msg(usage)
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
usage = (
|
||||||
|
"\n Usage (without <>): admincreate <name> <password>"
|
||||||
|
"\nIf <name> or <password> contains spaces, enclose them "
|
||||||
|
"in double quotes."
|
||||||
|
)
|
||||||
|
session.msg(usage)
|
||||||
|
return
|
||||||
|
|
||||||
|
# pre-normalize username so the user know what they get
|
||||||
|
non_normalized_username = username
|
||||||
|
username = Account.normalize_username(username)
|
||||||
|
if non_normalized_username != username:
|
||||||
|
session.msg(
|
||||||
|
"Note: your username was normalized to strip spaces and remove "
|
||||||
|
"characters that could be visually confusing."
|
||||||
|
)
|
||||||
|
|
||||||
|
# have the user verify their new account was what they intended
|
||||||
|
answer = yield (
|
||||||
|
f"You want to create an account '{username}' with password "
|
||||||
|
"'{password}'.\nIs this what you intended? [Y]/N?"
|
||||||
|
)
|
||||||
|
if answer.lower() in ("n", "no"):
|
||||||
|
session.msg(
|
||||||
|
"Aborted. If your user name contains spaces, surround it by quotes."
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
# everything's ok. Create the new player account.
|
||||||
|
account, errors = Account.create(username=username, password=password, ip="")
|
||||||
|
if account:
|
||||||
|
# tell the caller everything went well.
|
||||||
|
success = "A new account '%s' was created."
|
||||||
|
if " " in username:
|
||||||
|
success += (
|
||||||
|
"\n\nYou can now log in with the command "
|
||||||
|
"'connect \"%s\" <your password>'."
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
success += (
|
||||||
|
"\n\nYou can now log with the command "
|
||||||
|
"'connect %s <your password>'."
|
||||||
|
)
|
||||||
|
session.msg(success % (username, username))
|
||||||
|
else:
|
||||||
|
session.msg("|R%s|n" % "\n".join(errors))
|
|
@ -16,6 +16,8 @@ own cmdsets by inheriting from them or directly from `evennia.CmdSet`.
|
||||||
|
|
||||||
from evennia import default_cmds
|
from evennia import default_cmds
|
||||||
|
|
||||||
|
from .cwopa.admin import CmdCwopaAdminCreate
|
||||||
|
|
||||||
|
|
||||||
class CharacterCmdSet(default_cmds.CharacterCmdSet):
|
class CharacterCmdSet(default_cmds.CharacterCmdSet):
|
||||||
"""
|
"""
|
||||||
|
@ -54,6 +56,7 @@ class AccountCmdSet(default_cmds.AccountCmdSet):
|
||||||
#
|
#
|
||||||
# any commands you add below will overload the default ones.
|
# any commands you add below will overload the default ones.
|
||||||
#
|
#
|
||||||
|
self.add(CmdCwopaAdminCreate)
|
||||||
|
|
||||||
|
|
||||||
class UnloggedinCmdSet(default_cmds.UnloggedinCmdSet):
|
class UnloggedinCmdSet(default_cmds.UnloggedinCmdSet):
|
||||||
|
|
Loading…
Reference in a new issue