Update user cli commands
This commit is contained in:
parent
773e6a23e0
commit
dcf039c9de
|
@ -1,12 +1,20 @@
|
||||||
# Standard library imports
|
# Standard library imports
|
||||||
import getpass
|
import getpass
|
||||||
import os
|
import logging
|
||||||
import shutil
|
# import shutil
|
||||||
|
|
||||||
# Module imports
|
# Module imports
|
||||||
from amanuensis.cli.helpers import (
|
from amanuensis.cli.helpers import (
|
||||||
add_argument, no_argument, requires_user, alias,
|
add_argument,
|
||||||
config_get, config_set, CONFIG_GET_ROOT_VALUE)
|
no_argument,
|
||||||
|
requires_user,
|
||||||
|
alias,
|
||||||
|
config_get,
|
||||||
|
config_set,
|
||||||
|
CONFIG_GET_ROOT_VALUE)
|
||||||
|
from amanuensis.models import UserModel
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@alias('uc')
|
@alias('uc')
|
||||||
|
@ -18,26 +26,34 @@ def command_create(args):
|
||||||
Create a user
|
Create a user
|
||||||
"""
|
"""
|
||||||
# Module imports
|
# Module imports
|
||||||
from amanuensis.config import logger
|
|
||||||
from amanuensis.user import (
|
from amanuensis.user import (
|
||||||
UserModel, valid_username, valid_email, create_user)
|
valid_username, valid_email, create_user)
|
||||||
|
|
||||||
# Verify arguments
|
# 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")
|
||||||
return -1
|
return -1
|
||||||
if UserModel.by(name=args.username) is not None:
|
|
||||||
logger.error("Invalid username: username is already taken")
|
|
||||||
return -1
|
|
||||||
if not args.displayname:
|
if not args.displayname:
|
||||||
args.displayname = args.username
|
args.displayname = args.username
|
||||||
if args.email and 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
|
||||||
|
try:
|
||||||
|
existing_user = args.model_factory.user(args.username)
|
||||||
|
if existing_user is not None:
|
||||||
|
logger.error("Invalid username: username is already taken")
|
||||||
|
return -1
|
||||||
|
except Exception:
|
||||||
|
pass # User doesn't already exist, good to go
|
||||||
|
|
||||||
# Perform command
|
# Perform command
|
||||||
new_user, tmp_pw = create_user(args.username, args.displayname, args.email)
|
new_user, tmp_pw = create_user(
|
||||||
|
args.root,
|
||||||
|
args.model_factory,
|
||||||
|
args.username,
|
||||||
|
args.displayname,
|
||||||
|
args.email)
|
||||||
|
|
||||||
# Output
|
# Output
|
||||||
print(tmp_pw)
|
print(tmp_pw)
|
||||||
|
@ -50,41 +66,43 @@ def command_delete(args):
|
||||||
"""
|
"""
|
||||||
Delete a user
|
Delete a user
|
||||||
"""
|
"""
|
||||||
# Module imports
|
raise NotImplementedError()
|
||||||
from amanuensis.config import logger, prepend, json_rw
|
# # Module imports
|
||||||
|
# from amanuensis.config import logger, prepend, json_rw
|
||||||
|
|
||||||
# Perform command
|
# # Perform command
|
||||||
user_path = prepend('user', args.user.id)
|
# user_path = prepend('user', args.user.id)
|
||||||
shutil.rmtree(user_path)
|
# shutil.rmtree(user_path)
|
||||||
with json_rw('user', 'index.json') as index:
|
# with json_rw('user', 'index.json') as index:
|
||||||
del index[args.user.username]
|
# del index[args.user.username]
|
||||||
|
|
||||||
# TODO resolve user id references in all games
|
# # TODO resolve user id references in all games
|
||||||
|
|
||||||
# Output
|
# # Output
|
||||||
logger.info("Deleted user {0.username} ({0.id})".format(args.user))
|
# logger.info("Deleted user {0.username} ({0.id})".format(args.user))
|
||||||
return 0
|
# return 0
|
||||||
|
|
||||||
|
|
||||||
@alias('ul')
|
@alias('ul')
|
||||||
@no_argument
|
@no_argument
|
||||||
def command_list(args):
|
def command_list(args):
|
||||||
"""List all users"""
|
"""List all users"""
|
||||||
# Module imports
|
raise NotImplementedError()
|
||||||
from amanuensis.config import prepend, json_ro
|
# # Module imports
|
||||||
from amanuensis.user import UserModel
|
# from amanuensis.config import prepend, json_ro
|
||||||
|
# from amanuensis.user import UserModel
|
||||||
|
|
||||||
# Perform command
|
# # Perform command
|
||||||
users = []
|
# users = []
|
||||||
with json_ro('user', 'index.json') as index:
|
# with json_ro('user', 'index.json') as index:
|
||||||
for username, uid in index.items():
|
# for username, uid in index.items():
|
||||||
users.append(UserModel.by(uid=uid))
|
# users.append(UserModel.by(uid=uid))
|
||||||
|
|
||||||
# Output
|
# # 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.id} {0.displayname} ({0.username})".format(user))
|
# print("{0.id} {0.displayname} ({0.username})".format(user))
|
||||||
return 0
|
# return 0
|
||||||
|
|
||||||
|
|
||||||
@alias('un')
|
@alias('un')
|
||||||
|
@ -99,8 +117,7 @@ def command_config(args):
|
||||||
"""
|
"""
|
||||||
Interact with a user's config
|
Interact with a user's config
|
||||||
"""
|
"""
|
||||||
# Module imports
|
user: UserModel = args.user
|
||||||
from amanuensis.config import logger, json_rw
|
|
||||||
|
|
||||||
# Verify arguments
|
# Verify arguments
|
||||||
if args.get and args.set:
|
if args.get and args.set:
|
||||||
|
@ -109,11 +126,11 @@ def command_config(args):
|
||||||
|
|
||||||
# Perform command
|
# Perform command
|
||||||
if args.get:
|
if args.get:
|
||||||
config_get(args.user.config, args.get)
|
config_get(user.cfg, args.get)
|
||||||
|
|
||||||
if args.set:
|
if args.set:
|
||||||
with json_rw(args.user.config_path) as cfg:
|
with user.ctx.edit_config() as cfg:
|
||||||
config_set(args.user.id, cfg, args.set)
|
config_set(user.uid, cfg, args.set)
|
||||||
|
|
||||||
# Output
|
# Output
|
||||||
return 0
|
return 0
|
||||||
|
@ -127,15 +144,14 @@ def command_passwd(args):
|
||||||
"""
|
"""
|
||||||
Set a user's password
|
Set a user's password
|
||||||
"""
|
"""
|
||||||
# Module imports
|
user: UserModel = args.user
|
||||||
from amanuensis.config import logger
|
|
||||||
|
|
||||||
# Verify arguments
|
# Verify arguments
|
||||||
pw = args.password or getpass.getpass("Password: ")
|
password: str = args.password or getpass.getpass("Password: ")
|
||||||
|
|
||||||
# Perform command
|
# Perform command
|
||||||
args.user.set_password(pw)
|
user.set_password(password)
|
||||||
|
|
||||||
# Output
|
# Output
|
||||||
logger.info('Updated password for {}'.format(args.user.username))
|
logger.info('Updated password for {}'.format(user.cfg.username))
|
||||||
return 0
|
return 0
|
||||||
|
|
|
@ -1,77 +0,0 @@
|
||||||
import os
|
|
||||||
import re
|
|
||||||
import time
|
|
||||||
import uuid
|
|
||||||
|
|
||||||
from flask_login import UserMixin, AnonymousUserMixin
|
|
||||||
from werkzeug.security import generate_password_hash, check_password_hash
|
|
||||||
|
|
||||||
from amanuensis.errors import (
|
|
||||||
ArgumentError, MissingConfigError, IndexMismatchError)
|
|
||||||
from amanuensis.config import prepend, json_rw, root
|
|
||||||
from amanuensis.resources import get_stream
|
|
||||||
|
|
||||||
|
|
||||||
class UserModel(UserMixin):
|
|
||||||
@staticmethod
|
|
||||||
def by(uid=None, name=None):
|
|
||||||
"""
|
|
||||||
Gets the UserModel with the given uid or username
|
|
||||||
|
|
||||||
If the uid or name simply does not match an existing user, returns
|
|
||||||
None. If the uid matches the index but there is something wrong with
|
|
||||||
the user's config, raises an error.
|
|
||||||
"""
|
|
||||||
if uid and name:
|
|
||||||
raise ArgumentError("uid and name both specified to UserModel.by()")
|
|
||||||
if not uid and not name:
|
|
||||||
raise ArgumentError("One of uid or name must be not None")
|
|
||||||
if not uid:
|
|
||||||
with root.user.index() as index:
|
|
||||||
uid = index.get(name)
|
|
||||||
if not uid:
|
|
||||||
return None
|
|
||||||
if not os.path.isdir(prepend('user', uid)):
|
|
||||||
raise IndexMismatchError("username={} uid={}".format(name, uid))
|
|
||||||
if not os.path.isfile(prepend('user', uid, 'config.json')):
|
|
||||||
raise MissingConfigError("uid={}".format(uid))
|
|
||||||
return UserModel(uid)
|
|
||||||
|
|
||||||
def __init__(self, uid):
|
|
||||||
"""User model initializer, assume all checks were done by by()"""
|
|
||||||
self.id = str(uid) # Flask-Login checks for this
|
|
||||||
self.config_path = prepend('user', uid, 'config.json')
|
|
||||||
self.ctx = root.user[self.id]
|
|
||||||
with self.ctx.config() as j:
|
|
||||||
self.config = j
|
|
||||||
|
|
||||||
def __getattr__(self, key):
|
|
||||||
if key not in self.config:
|
|
||||||
raise AttributeError(key)
|
|
||||||
return self.config.get(key)
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return '<{0.username}>'.format(self)
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return '<UserModel uid={0.id} username={0.username}>'.format(self)
|
|
||||||
|
|
||||||
def set_password(self, pw):
|
|
||||||
h = generate_password_hash(pw)
|
|
||||||
with self.ctx.config(edit=True) as j:
|
|
||||||
j['password'] = h
|
|
||||||
|
|
||||||
def check_password(self, pw):
|
|
||||||
with self.ctx.config() as cfg:
|
|
||||||
return check_password_hash(cfg.password, pw)
|
|
||||||
|
|
||||||
def in_lexicon(self, lexicon):
|
|
||||||
return self.id in lexicon.join.joined
|
|
||||||
|
|
||||||
|
|
||||||
class AnonymousUserModel(AnonymousUserMixin):
|
|
||||||
is_admin = False
|
|
||||||
|
|
||||||
def in_lexicon(self, lexicon):
|
|
||||||
return False
|
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
from amanuensis.user.signup import create_user
|
from amanuensis.user.signup import (
|
||||||
|
create_user,
|
||||||
|
valid_username,
|
||||||
|
valid_email)
|
||||||
|
|
||||||
__all__ = [member.__name__ for member in [
|
__all__ = [member.__name__ for member in [
|
||||||
create_user
|
create_user,
|
||||||
|
valid_username,
|
||||||
|
valid_email,
|
||||||
]]
|
]]
|
||||||
|
|
Loading…
Reference in New Issue