Move user creation code to new submodule
This commit is contained in:
parent
50216281b2
commit
1dd87fc6f0
@ -75,59 +75,3 @@ class AnonymousUserModel(AnonymousUserMixin):
|
||||
def in_lexicon(self, lexicon):
|
||||
return False
|
||||
|
||||
|
||||
def valid_username(username):
|
||||
"""
|
||||
A valid username is at least three characters long and composed solely of
|
||||
alpahnumerics, dashes, and underscores. Additionally, usernames may not
|
||||
be 32 hex digits, since that may be confused for an internal id.
|
||||
"""
|
||||
length_and_characters = re.match(r"^[A-Za-z0-9-_]{3,}$", username)
|
||||
is_a_guid = re.match(r"^[A-Za-z0-9]{32}$", username)
|
||||
return length_and_characters and not is_a_guid
|
||||
|
||||
|
||||
def valid_email(email):
|
||||
"""Vaguely RFC2822 email verifier"""
|
||||
atom = r"[0-9A-Za-z!#$%&'*+-/=?^_`{|}~]{1,}"
|
||||
dotatom = atom + r"(\." + atom + r")*"
|
||||
addrspec = "^" + dotatom + "@" + dotatom + "$"
|
||||
return re.match(addrspec, email)
|
||||
|
||||
|
||||
def create_user(username, displayname, email):
|
||||
"""
|
||||
Creates a new user
|
||||
"""
|
||||
# Validate arguments
|
||||
if not valid_username(username):
|
||||
raise ValueError("Invalid username: '{}'".format(username))
|
||||
if email and not valid_email(email):
|
||||
raise ValueError("Invalid email: '{}'".format(email))
|
||||
|
||||
# Create the user directory and initialize it with a blank user
|
||||
uid = uuid.uuid4().hex
|
||||
user_dir = prepend("user", uid)
|
||||
os.mkdir(user_dir)
|
||||
with get_stream("user.json") as s:
|
||||
with open(prepend(user_dir, 'config.json'), 'wb') as f:
|
||||
f.write(s.read())
|
||||
|
||||
# Fill out the new user
|
||||
with 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 json_rw('user', 'index.json') as index:
|
||||
index[username] = uid
|
||||
|
||||
# Set a temporary password
|
||||
temp_pw = os.urandom(32).hex()
|
||||
u = UserModel.by(uid=uid)
|
||||
u.set_password(temp_pw)
|
||||
|
||||
return u, temp_pw
|
||||
|
5
amanuensis/user/__init__.py
Normal file
5
amanuensis/user/__init__.py
Normal file
@ -0,0 +1,5 @@
|
||||
from amanuensis.user.signup import create_user
|
||||
|
||||
__all__ = [member.__name__ for member in [
|
||||
create_user
|
||||
]]
|
77
amanuensis/user/signup.py
Normal file
77
amanuensis/user/signup.py
Normal file
@ -0,0 +1,77 @@
|
||||
"""
|
||||
Submodule encapsulating functionality pertaining to creating users in
|
||||
an Amanuensis instance.
|
||||
"""
|
||||
import os
|
||||
import re
|
||||
import time
|
||||
from typing import Tuple
|
||||
import uuid
|
||||
|
||||
from amanuensis.config import RootConfigDirectoryContext
|
||||
from amanuensis.errors import ArgumentError
|
||||
from amanuensis.models import ModelFactory, UserModel
|
||||
from amanuensis.resources import get_stream
|
||||
|
||||
|
||||
def valid_username(username: str) -> bool:
|
||||
"""
|
||||
A valid username is at least three characters long and composed solely of
|
||||
alpahnumerics, dashes, and underscores. Additionally, usernames may not
|
||||
be 32 hex digits, since that may be confused for an internal id.
|
||||
"""
|
||||
length_and_characters = re.match(r'^[A-Za-z0-9-_]{3,}$', username)
|
||||
is_a_guid = re.match(r'^[A-Za-z0-9]{32}$', username)
|
||||
return bool(length_and_characters and not is_a_guid)
|
||||
|
||||
|
||||
def valid_email(email: str) -> bool:
|
||||
"""Vaguely RFC2822 email verifier"""
|
||||
atom = r"[0-9A-Za-z!#$%&'*+-/=?^_`{|}~]{1,}"
|
||||
dotatom = atom + r"(\." + atom + r")*"
|
||||
addrspec = '^' + dotatom + '@' + dotatom + '$'
|
||||
return bool(re.match(addrspec, email))
|
||||
|
||||
|
||||
def create_user(
|
||||
root: RootConfigDirectoryContext,
|
||||
model_factory: ModelFactory,
|
||||
username: str,
|
||||
displayname: str,
|
||||
email: str) -> Tuple[UserModel, str]:
|
||||
"""
|
||||
Creates a new user
|
||||
"""
|
||||
# Validate arguments
|
||||
if not valid_username(username):
|
||||
raise ArgumentError('Invalid username: "{}"'.format(username))
|
||||
if email and not valid_email(email):
|
||||
raise ArgumentError('Invalid email: "{}"'.format(email))
|
||||
|
||||
# Create the user directory and config file
|
||||
uid: str = uuid.uuid4().hex
|
||||
user_dir: str = os.path.join(root.user.path, uid)
|
||||
os.mkdir(user_dir)
|
||||
with get_stream('user.json') as s:
|
||||
path: str = os.path.join(user_dir, 'config.json')
|
||||
with open(path, 'wb') as f:
|
||||
f.write(s.read())
|
||||
|
||||
# Create the user index entry
|
||||
with root.user.edit_index() as index:
|
||||
index[username] = uid
|
||||
|
||||
# Fill out the new user
|
||||
with root.user[uid].edit_config() as cfg:
|
||||
cfg.uid = uid
|
||||
cfg.username = username
|
||||
cfg.displayname = displayname
|
||||
cfg.email = email
|
||||
cfg.created = int(time.time())
|
||||
|
||||
# Load the user model and set a temporary password
|
||||
temporary_password = os.urandom(32).hex()
|
||||
user = model_factory.user(uid)
|
||||
user.set_password(temporary_password)
|
||||
|
||||
return user, temporary_password
|
Loading…
Reference in New Issue
Block a user