Rname User to UserModel, revamp factory function
This commit is contained in:
parent
5972a309f1
commit
8e99788fcd
|
@ -17,11 +17,10 @@ def command_create(args):
|
|||
settings are as desired before opening the lexicon for player joins.
|
||||
"""
|
||||
from lexicon.manage import create_lexicon
|
||||
import user
|
||||
from user import UserModel
|
||||
# TODO verify args
|
||||
uid = user.uid_from_username(args.editor)
|
||||
u = user.user_from_uid(uid)
|
||||
create_lexicon(args.name, u)
|
||||
editor = UserModel.by(name=args.editor)
|
||||
create_lexicon(args.name, editor)
|
||||
|
||||
@requires_lexicon
|
||||
def command_delete(args):
|
||||
|
|
|
@ -2,9 +2,9 @@ from cli.helpers import (
|
|||
add_argument, no_argument, requires_username,
|
||||
config_get, config_set, CONFIG_GET_ROOT_VALUE)
|
||||
|
||||
@add_argument("--username", help="User's login handle")
|
||||
@requires_username
|
||||
@add_argument("--email", required=True, help="User's email")
|
||||
@add_argument("--displayname", help="User's publicly displayed name")
|
||||
@add_argument("--email", help="User's email")
|
||||
def command_create(args):
|
||||
"""
|
||||
Create a user
|
||||
|
@ -15,18 +15,14 @@ def command_create(args):
|
|||
import config
|
||||
|
||||
# Verify or query parameters
|
||||
if not args.username:
|
||||
args.username = input("username: ").strip()
|
||||
if not user.valid_username(args.username):
|
||||
config.logger.error("Invalid username: usernames may only contain alphanumeric characters, dashes, and underscores")
|
||||
return -1
|
||||
if user.uid_from_username(args.username) is not None:
|
||||
if user.UserModel.by(name=args.username) is not None:
|
||||
config.logger.error("Invalid username: username is already taken")
|
||||
return -1
|
||||
if not args.displayname:
|
||||
args.displayname = args.username
|
||||
if not args.email:
|
||||
args.email = input("email: ").strip()
|
||||
if not user.valid_email(args.email):
|
||||
config.logger.error("Invalid email")
|
||||
return -1
|
||||
|
@ -37,7 +33,7 @@ def command_create(args):
|
|||
print(json.dumps(js, indent=2))
|
||||
print("Username: {}\nUser ID: {}\nPassword: {}".format(args.username, new_user.uid, tmp_pw))
|
||||
|
||||
@add_argument("--id", help="id of user to delete")
|
||||
@add_argument("--id", required=True, help="id of user to delete")
|
||||
def command_delete(args):
|
||||
"""
|
||||
Delete a user
|
||||
|
@ -84,23 +80,23 @@ def command_config(args):
|
|||
"""
|
||||
import json
|
||||
import config
|
||||
import user
|
||||
from user import UserModel
|
||||
|
||||
if args.get and args.set:
|
||||
config.logger.error("Specify one of --get and --set")
|
||||
return -1
|
||||
|
||||
uid = user.uid_from_username(args.username)
|
||||
if not uid:
|
||||
u = UserModel.by(name=args.username)
|
||||
if not u:
|
||||
config.logger.error("User not found")
|
||||
return -1
|
||||
|
||||
if args.get:
|
||||
with config.json_ro('user', uid, 'config.json') as cfg:
|
||||
with config.json_ro('user', u.id, 'config.json') as cfg:
|
||||
config_get(cfg, args.get)
|
||||
|
||||
if args.set:
|
||||
with config.json_rw('user', uid, 'config.json') as cfg:
|
||||
with config.json_rw('user', u.id, 'config.json') as cfg:
|
||||
config_set(cfg, args.set)
|
||||
|
||||
@add_argument("--username", help="The user to change password for")
|
||||
|
@ -112,14 +108,13 @@ def command_passwd(args):
|
|||
import os
|
||||
|
||||
import config
|
||||
import user
|
||||
from user import UserModel
|
||||
|
||||
if not args.username:
|
||||
args.username = input("Username: ")
|
||||
uid = user.uid_from_username(args.username)
|
||||
if uid is None:
|
||||
u = UserModel.by(name=args.username)
|
||||
if u is None:
|
||||
config.logger.error("No user with username '{}'".format(args.username))
|
||||
return -1
|
||||
u = user.user_from_uid(uid)
|
||||
pw = getpass.getpass("Password: ")
|
||||
u.set_password(pw)
|
||||
|
|
|
@ -5,7 +5,7 @@ from wtforms.validators import DataRequired
|
|||
from flask_login import current_user, login_user, logout_user, login_required
|
||||
|
||||
import config
|
||||
import user
|
||||
from user import UserModel
|
||||
|
||||
class LoginForm(FlaskForm):
|
||||
username = StringField('Username', validators=[DataRequired()])
|
||||
|
@ -19,25 +19,21 @@ def get_bp(login_manager):
|
|||
|
||||
@login_manager.user_loader
|
||||
def load_user(uid):
|
||||
return user.user_from_uid(str(uid))
|
||||
return UserModel.by(uid=str(uid))
|
||||
|
||||
@bp.route('/login/', methods=['GET', 'POST'])
|
||||
def login():
|
||||
form = LoginForm()
|
||||
if form.validate_on_submit():
|
||||
username = form.username.data
|
||||
uid = user.uid_from_username(username)
|
||||
if uid is not None:
|
||||
u = user.user_from_uid(uid)
|
||||
if u.check_password(form.password.data):
|
||||
u = UserModel.by(name=username)
|
||||
if u is not None and u.check_password(form.password.data):
|
||||
remember_me = form.remember.data
|
||||
login_user(u, remember=remember_me)
|
||||
config.logger.info("Logged in user '{}' ({})".format(
|
||||
u.username, u.uid))
|
||||
return redirect(url_for('home.home'))
|
||||
flash("Login not recognized")
|
||||
else:
|
||||
pass
|
||||
return render_template('auth/login.html', form=form)
|
||||
|
||||
@bp.route("/logout/", methods=['GET'])
|
||||
|
|
|
@ -6,15 +6,37 @@ import uuid
|
|||
from flask_login import UserMixin
|
||||
from werkzeug.security import generate_password_hash, check_password_hash
|
||||
|
||||
from errors import InternalMisuseError, MissingConfigError, IndexMismatchError
|
||||
import config
|
||||
import resources
|
||||
|
||||
class User(UserMixin):
|
||||
def __init__(self, uid):
|
||||
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 InternalMisuseError("uid and name both specified to UserModel.by()")
|
||||
if not uid and not name:
|
||||
raise ValueError("One of uid or name must be not None")
|
||||
if not uid:
|
||||
with config.json_ro('user', 'index.json') as index:
|
||||
uid = index.get(name)
|
||||
if not uid:
|
||||
return None
|
||||
if not os.path.isdir(config.prepend('user', uid)):
|
||||
raise ValueError("No user with uid {}".format(uid))
|
||||
raise IndexMismatchError("username={} uid={}".format(name, uid))
|
||||
if not os.path.isfile(config.prepend('user', uid, 'config.json')):
|
||||
raise FileNotFoundError("User {} missing config.json".format(uid))
|
||||
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 = config.prepend('user', uid, 'config.json')
|
||||
with config.json_ro(self.config_path) as j:
|
||||
|
@ -76,25 +98,7 @@ def create_user(username, displayname, email):
|
|||
|
||||
# Set a temporary password
|
||||
temp_pw = os.urandom(32).hex()
|
||||
u = User(uid)
|
||||
u = UserModel.by(uid=uid)
|
||||
u.set_password(temp_pw)
|
||||
|
||||
return u, temp_pw
|
||||
|
||||
def uid_from_username(username):
|
||||
"""Gets the internal uid of a user given a username"""
|
||||
if username is None:
|
||||
raise ValueError("username must not be None")
|
||||
if not username:
|
||||
raise ValueError("username must not be empty")
|
||||
with config.json_ro('user', 'index.json') as index:
|
||||
uid = index.get(username)
|
||||
if uid is None:
|
||||
config.logger.debug("uid_from_username('{}') returned None".format(username))
|
||||
return uid
|
||||
|
||||
def user_from_uid(uid):
|
||||
if not os.path.isdir(config.prepend('user', uid)):
|
||||
config.logger.debug("No user with uid '{}'".format(uid))
|
||||
return None
|
||||
return User(uid)
|
||||
|
|
Loading…
Reference in New Issue