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

View File

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

View File

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