Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix broken implementation of import_from_firstuse #221

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 25 additions & 6 deletions nativeauthenticator/nativeauthenticator.py
Original file line number Diff line number Diff line change
Expand Up @@ -295,19 +295,37 @@ def get_authed_users(self):
def user_exists(self, username):
return self.get_user(username) is not None

def create_user(self, username, password, **kwargs):
def create_user(self, username, password, from_firstuse=False, **kwargs):

# variable added to enable skipping adding existing users
add_to_db = True

username = self.normalize_username(username)

if self.user_exists(username) or not self.validate_username(username):
# fail if the username is not valid
if not self.validate_username(username):
return

# If the user already exists, we normally return an error,
# except if importing from a FirstUseAuthenticator database, in which case it silently fails to import the user.
# This is to handle the case when users do not wish to delete their FirstUseAuthenticator database after the first import,
# in which case the re-import at each hub reload could cause any password changes done after to be overwritten, or constant reload failures.
if self.user_exists(username):
if from_firstuse:
add_to_db = False # only returned when importing passwords.dbm, so it should not affect any other code.
else:
return # fail if the user exists and it is not a FirstUseAuthenticator import

if not self.is_password_strong(password):
return

if not self.enable_signup:
return

encoded_password = bcrypt.hashpw(password.encode(), bcrypt.gensalt())
if not from_firstuse:
encoded_password = bcrypt.hashpw(password.encode(), bcrypt.gensalt())
else:
encoded_password = password.encode()
infos = {"username": username, "password": encoded_password}
infos.update(kwargs)

Expand All @@ -330,8 +348,9 @@ def create_user(self, username, password, **kwargs):
self.send_approval_email(user_info.email, url)
user_info.login_email_sent = True

self.db.add(user_info)
self.db.commit()
if add_to_db:
self.db.add(user_info)
self.db.commit()
return user_info

def generate_approval_url(self, username, when=None):
Expand Down Expand Up @@ -433,7 +452,7 @@ def add_data_from_firstuse(self):
with dbm.open(self.firstuse_db_path, "c", 0o600) as db:
for user in db.keys():
password = db[user].decode()
new_user = self.create_user(user.decode(), password)
new_user = self.create_user(user.decode(), password, from_firstuse=True)
if not new_user:
error = (
f"User {user} was not created. Check password "
Expand Down