Bring user creation entirely under user module
This commit is contained in:
parent
4c41407d69
commit
58911a2da4
|
@ -18,7 +18,7 @@ def command_create(args):
|
||||||
if not user.valid_username(args.username):
|
if not user.valid_username(args.username):
|
||||||
config.logger.error("Invalid username: usernames may only contain alphanumeric characters, dashes, and underscores")
|
config.logger.error("Invalid username: usernames may only contain alphanumeric characters, dashes, and underscores")
|
||||||
return -1
|
return -1
|
||||||
if user.get_user_by_username(args.username) is not None:
|
if user.uid_from_username(args.username) is not None:
|
||||||
config.logger.error("Invalid username: username is already taken")
|
config.logger.error("Invalid username: username is already taken")
|
||||||
return -1
|
return -1
|
||||||
if not args.displayname:
|
if not args.displayname:
|
||||||
|
@ -28,9 +28,10 @@ def command_create(args):
|
||||||
if not user.valid_email(args.email):
|
if not user.valid_email(args.email):
|
||||||
config.logger.error("Invalid email")
|
config.logger.error("Invalid email")
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
# Create user
|
# Create user
|
||||||
new_user, tmp_pw = user.create_user(args.username, args.displayname, args.email)
|
new_user, tmp_pw = user.create_user(args.username, args.displayname, args.email)
|
||||||
with config.json_ro(new_user.config) as js:
|
with config.json_ro(new_user.config_path) as js:
|
||||||
print(json.dumps(js, indent=2))
|
print(json.dumps(js, indent=2))
|
||||||
print("Username: {}\nUser ID: {}\nPassword: {}".format(args.username, new_user.uid, tmp_pw))
|
print("Username: {}\nUser ID: {}\nPassword: {}".format(args.username, new_user.uid, tmp_pw))
|
||||||
|
|
||||||
|
|
|
@ -56,18 +56,4 @@ def json_ro(*path):
|
||||||
return config.loader.json_ro(prepend(*path))
|
return config.loader.json_ro(prepend(*path))
|
||||||
|
|
||||||
def json_rw(*path):
|
def json_rw(*path):
|
||||||
return config.loader.json_rw(prepend(*path))
|
return config.loader.json_rw(prepend(*path))
|
||||||
|
|
||||||
def new_user(user_json):
|
|
||||||
user_dir = prepend("user", user_json['uid'])
|
|
||||||
# Create user dir and put config in it
|
|
||||||
os.mkdir(user_dir)
|
|
||||||
with open_ex(user_dir, "config.json", mode='w') as f:
|
|
||||||
json.dump(user_json, f, allow_nan=False, indent='\t')
|
|
||||||
# Ensure index exists
|
|
||||||
if not os.path.isfile(prepend('user', 'index.json')):
|
|
||||||
with open_ex('user', 'index.json', mode='w') as f:
|
|
||||||
json.dump({}, f)
|
|
||||||
# Update index
|
|
||||||
with json_rw('user', 'index.json') as j:
|
|
||||||
j[user_json['username']] = user_json['uid']
|
|
|
@ -22,7 +22,7 @@ def get_bp():
|
||||||
@bp.route('/admin/', methods=['GET'])
|
@bp.route('/admin/', methods=['GET'])
|
||||||
@login_required
|
@login_required
|
||||||
def admin():
|
def admin():
|
||||||
if not current_user.admin:
|
if not current_user.is_admin:
|
||||||
return redirect(url_for('home.home'))
|
return redirect(url_for('home.home'))
|
||||||
|
|
||||||
with config.json_ro('config.json') as j:
|
with config.json_ro('config.json') as j:
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
{% block sb_logout %}<a href="{{ url_for('auth.logout') }}">Log out</a>{% endblock %}
|
{% block sb_logout %}<a href="{{ url_for('auth.logout') }}">Log out</a>{% endblock %}
|
||||||
{% set template_sidebar_rows = [self.sb_topline(), self.sb_logout()] %}
|
{% set template_sidebar_rows = [self.sb_topline(), self.sb_logout()] %}
|
||||||
|
|
||||||
{% if current_user.admin %}
|
{% if current_user.is_admin %}
|
||||||
{% block sb_admin %}<a href="{{ url_for('home.admin') }}">Admin</a>{% endblock %}
|
{% block sb_admin %}<a href="{{ url_for('home.admin') }}">Admin</a>{% endblock %}
|
||||||
{% set template_sidebar_rows = template_sidebar_rows + [self.sb_admin()] %}
|
{% set template_sidebar_rows = template_sidebar_rows + [self.sb_admin()] %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
|
@ -7,13 +7,16 @@ from flask_login import UserMixin
|
||||||
from werkzeug.security import generate_password_hash, check_password_hash
|
from werkzeug.security import generate_password_hash, check_password_hash
|
||||||
|
|
||||||
import config
|
import config
|
||||||
|
import resources
|
||||||
|
|
||||||
class User(UserMixin):
|
class User(UserMixin):
|
||||||
def __init__(self, uid):
|
def __init__(self, uid):
|
||||||
if not os.path.isdir(config.prepend('user', uid)):
|
if not os.path.isdir(config.prepend('user', uid)):
|
||||||
raise ValueError("No user with uid {}".format(uid))
|
raise ValueError("No user with uid {}".format(uid))
|
||||||
self.uid = str(uid)
|
if not os.path.isfile(config.prepend('user', uid, 'config.json')):
|
||||||
self.config_path = os.path.join('user', uid, 'config.json')
|
raise FileNotFoundError("User {} missing config.json".format(uid))
|
||||||
|
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:
|
with config.json_ro(self.config_path) as j:
|
||||||
self.config = j
|
self.config = j
|
||||||
|
|
||||||
|
@ -45,26 +48,40 @@ def valid_email(email):
|
||||||
return re.match(addrspec, email)
|
return re.match(addrspec, email)
|
||||||
|
|
||||||
def create_user(username, displayname, email):
|
def create_user(username, displayname, email):
|
||||||
|
"""
|
||||||
|
Creates a new user
|
||||||
|
"""
|
||||||
|
# Validate arguments
|
||||||
if not valid_username(username):
|
if not valid_username(username):
|
||||||
raise ValueError("Invalid username: '{}'".format(username))
|
raise ValueError("Invalid username: '{}'".format(username))
|
||||||
if not valid_email(email):
|
if not valid_email(email):
|
||||||
raise ValueError("Invalid email: '{}'".format(email))
|
raise ValueError("Invalid email: '{}'".format(email))
|
||||||
|
|
||||||
|
# Create the user directory and initialize it with a blank user
|
||||||
uid = uuid.uuid4().hex
|
uid = uuid.uuid4().hex
|
||||||
now = int(time.time())
|
user_dir = config.prepend("user", uid)
|
||||||
|
os.mkdir(user_dir)
|
||||||
|
with resources.get_stream("user.json") as s:
|
||||||
|
with open(config.prepend(user_dir, 'config.json'), 'wb') as f:
|
||||||
|
f.write(s.read())
|
||||||
|
|
||||||
|
# Fill out the new user
|
||||||
|
with config.json_rw(user_dir, 'config.json') as cfg:
|
||||||
|
cfg['uid'] = uid
|
||||||
|
cfg['username'] = username
|
||||||
|
cfg['displayname'] = displayname
|
||||||
|
cfg['email'] = email
|
||||||
|
cfg['created'] = int(time.time())
|
||||||
|
|
||||||
|
# Update the index with the new user
|
||||||
|
with config.json_rw('user', 'index.json') as index:
|
||||||
|
index[username] = uid
|
||||||
|
|
||||||
|
# Set a temporary password
|
||||||
temp_pw = os.urandom(32).hex()
|
temp_pw = os.urandom(32).hex()
|
||||||
user_json = {
|
|
||||||
'uid': uid,
|
|
||||||
'username': username,
|
|
||||||
'displayname': displayname,
|
|
||||||
'email': email,
|
|
||||||
'password': None,
|
|
||||||
'created': now,
|
|
||||||
'newPasswordRequired': True,
|
|
||||||
'admin': False,
|
|
||||||
}
|
|
||||||
config.new_user(user_json)
|
|
||||||
u = User(uid)
|
u = User(uid)
|
||||||
u.set_password(temp_pw)
|
u.set_password(temp_pw)
|
||||||
|
|
||||||
return u, temp_pw
|
return u, temp_pw
|
||||||
|
|
||||||
def uid_from_username(username):
|
def uid_from_username(username):
|
||||||
|
|
Loading…
Reference in New Issue