Refactor user loading into req_user wrapper

This commit is contained in:
Tim Van Baak 2020-01-28 09:44:01 -08:00
parent 298352caed
commit 272ec492f8
3 changed files with 62 additions and 58 deletions

View File

@ -5,6 +5,7 @@ import traceback
# Module imports
import amanuensis.cli as cli
from amanuensis.cli.helpers import USER_ARGS, USER_KWARGS
import amanuensis.config as config
@ -83,10 +84,7 @@ def get_parser(valid_commands):
metavar="LEXICON",
dest="tl_lexicon",
help="Specify a lexicon to operate on")
parser.add_argument("-u",
metavar="USERNAME",
dest="tl_username",
help="Specify a user to operate on")
parser.add_argument(*USER_ARGS, **USER_KWARGS)
parser.set_defaults(
func=lambda args: repl(args)
if args.tl_lexicon

View File

@ -80,15 +80,19 @@ def requires_lexicon(command):
augmented_command.__dict__['wrapper'] = True
return augmented_command
def requires_username(command):
USER_ARGS = ['--user']
USER_KWARGS = {'metavar': 'USER', 'dest': 'user',
'help': 'Specify a user to operate on'}
def requires_user(command):
"""
Performs all necessary setup and verification for passing a user to a CLI
command.
"""
@wraps(command)
def augmented_command(cmd_args):
# Add user argument in parser pass
if isinstance(cmd_args, ArgumentParser):
cmd_args.add_argument(
"-u", metavar="USERNAME", dest="username",
help="Specify a user to operate on")
cmd_args.add_argument(*USER_ARGS, **USER_KWARGS)
# If there are more command wrappers, pass through to them
if command.__dict__.get('wrapper', False):
command(cmd_args)
@ -96,17 +100,18 @@ def requires_username(command):
return None
# Verify user argument in execute pass
base_val = (hasattr(cmd_args, "tl_username")
and getattr(cmd_args, "tl_lexicon"))
subp_val = (hasattr(cmd_args, "username")
and getattr(cmd_args, "username"))
base_val = (hasattr(cmd_args, "tl_user")
and getattr(cmd_args, "tl_user"))
subp_val = (hasattr(cmd_args, "user")
and getattr(cmd_args, "user"))
val = subp_val or base_val or None
if not val:
from amanuensis.config import logger
logger.error("This command requires specifying a user")
return -1
# from amanuensis.user import UserModel
cmd_args.username = val#UserModel.by(name=val).name TODO
from amanuensis.user import UserModel
cmd_args.user = UserModel.by(name=val)
# TODO more thorough verification of argument val
return command(cmd_args)
augmented_command.__dict__['wrapper'] = True

View File

@ -1,23 +1,28 @@
# Standard imports
import getpass
import json
import os
import shutil
# Module imports
from amanuensis.cli.helpers import (
add_argument, no_argument, requires_username,
add_argument, no_argument, requires_user,
config_get, config_set, CONFIG_GET_ROOT_VALUE)
@requires_username
@add_argument("--email", required=True, help="User's email")
@add_argument("--username", required=True, help="Name of user to create")
@add_argument("--email", help="User's email")
@add_argument("--displayname", help="User's publicly displayed name")
def command_create(args):
"""
Create a user
"""
import json
# Module imports
from amanuensis.config import logger, json_ro
from amanuensis.user import (
UserModel, valid_username, valid_email, create_user)
# Verify or query parameters
# Verify arguments
if not valid_username(args.username):
logger.error("Invalid username: usernames may only contain alphanumer"
"ic characters, dashes, and underscores")
@ -27,48 +32,46 @@ def command_create(args):
return -1
if not args.displayname:
args.displayname = args.username
if not valid_email(args.email):
if args.email and not valid_email(args.email):
logger.error("Invalid email")
return -1
# Create user
# Perform command
new_user, tmp_pw = create_user(args.username, args.displayname, args.email)
with json_ro(new_user.config_path) as js:
print(json.dumps(js, indent=2))
print("Username: {}\nUser ID: {}\nPassword: {}".format(
args.username, new_user.uid, tmp_pw))
# Output
print(tmp_pw)
return 0
@add_argument("--id", required=True, help="id of user to delete")
@requires_user
def command_delete(args):
"""
Delete a user
"""
import os
# Module imports
from amanuensis.config import logger, prepend, json_rw
user_path = prepend('user', args.id)
if not os.path.isdir(user_path):
logger.error("No user with that id")
return -1
# Perform command
user_path = prepend('user', args.user.id)
shutil.rmtree(user_path)
with json_rw('user', 'index.json') as j:
if args.id in j: # TODO this is wrong
del j[args.id]
with json_rw('user', 'index.json') as index:
del index[args.user.username]
# TODO
# TODO resolve user id references in all games
# Output
logger.info("Deleted user {0.username} ({0.id})".format(args.user))
return 0
@no_argument
def command_list(args):
"""List all users"""
import os
# Module imports
from amanuensis.config import prepend, json_ro
# Perform command
user_dirs = os.listdir(prepend('user'))
users = []
for uid in user_dirs:
@ -76,14 +79,16 @@ def command_list(args):
continue
with json_ro('user', uid, 'config.json') as user:
users.append(user)
# Output
users.sort(key=lambda u: u['username'])
for user in users:
print("{0} {1} ({2})".format(
user['uid'], user['displayname'], user['username']))
return 0
@requires_username
@requires_user
@add_argument(
"--get", metavar="PATHSPEC", dest="get",
nargs="?", const=CONFIG_GET_ROOT_VALUE, help="Get the value of a config key")
@ -98,43 +103,39 @@ def command_config(args):
from amanuensis.config import logger, json_ro, json_rw
from amanuensis.user import UserModel
# Verify arguments
if args.get and args.set:
logger.error("Specify one of --get and --set")
return -1
u = UserModel.by(name=args.username)
if not u:
logger.error("User not found")
return -1
# Perform command
if args.get:
with json_ro('user', u.id, 'config.json') as cfg:
config_get(cfg, args.get)
config_get(args.user.config, args.get)
if args.set:
with json_rw('user', u.id, 'config.json') as cfg:
config_set(u.id, cfg, args.set)
with json_rw(args.user.config_path) as cfg:
config_set(args.user.id, cfg, args.set)
# Output
return 0
@add_argument("--username", help="The user to change password for")
@add_argument("--password", help="The password to set. Not recommended")
@requires_user
@add_argument("--password", help="The password to set. Used for scripting; "
"not recommended for general use")
def command_passwd(args):
"""
Set a user's password
"""
import getpass
# Module imports
from amanuensis.config import logger
from amanuensis.user import UserModel
if not args.username:
args.username = input("Username: ")
u = UserModel.by(name=args.username)
if u is None:
logger.error("No user with username '{}'".format(args.username))
return -1
# Verify arguments
pw = args.password or getpass.getpass("Password: ")
u.set_password(pw)
# Perform commands
args.user.set_password(pw)
# Output
return 0