From e4ee756918293202b69657599bbb09a20cd91e42 Mon Sep 17 00:00:00 2001 From: Sunil Mohan Adapa Date: Tue, 24 Feb 2026 11:57:13 -0800 Subject: [PATCH] bin: Add tool to change FreedomBox password in Django database Tests: - Run 'make build install'. The new binary is available as /usr/bin/freedombox-change-password. Running 'freedombox-change-password tester2' works as expected. - Providing wrong username show proper error message. Signed-off-by: Sunil Mohan Adapa Reviewed-by: James Valleroy --- Makefile | 1 + bin/freedombox-change-password | 61 ++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100755 bin/freedombox-change-password diff --git a/Makefile b/Makefile index 1b85e1c6c..9d0f1c705 100644 --- a/Makefile +++ b/Makefile @@ -106,6 +106,7 @@ install: $(INSTALL) -D -t $(BIN_DIR) bin/plinth $(INSTALL) -D -t $(LIB_DIR)/freedombox bin/freedombox-privileged $(INSTALL) -D -t $(BIN_DIR) bin/freedombox-cmd + $(INSTALL) -D -t $(BIN_DIR) bin/freedombox-change-password # Static web server files rm -rf $(STATIC_FILES_DIRECTORY) diff --git a/bin/freedombox-change-password b/bin/freedombox-change-password new file mode 100755 index 000000000..d9e2f9dac --- /dev/null +++ b/bin/freedombox-change-password @@ -0,0 +1,61 @@ +#!/usr/bin/python3 +# SPDX-License-Identifier: AGPL-3.0-or-later +""" +Utility to change user password in FreedomBox's Django database. + +Usage: +$ freedombox-change-password +""" + +import argparse +import getpass +import sys + +import plinth.web_framework +from plinth.modules.users import privileged + + +def main(): + """Ask for new password, setup Django and update a user's password.""" + try: + plinth.web_framework.init() + except Exception: + _print('Error initializing Django.') + return + + parser = argparse.ArgumentParser() + parser.add_argument('username', + help='Username of the account to change password for') + args = parser.parse_args() + + username = args.username + password = getpass.getpass('Enter new password: ') + + try: + _change_password(username, password) + privileged._set_user_password(username, password) + privileged._set_samba_user(username, password) + _print('Password updated in web interface, LDAP, and samba databases.') + except Exception as exception: + _print('Error setting password:', str(exception)) + + +def _print(*args, **kwargs): + """Write to stderr.""" + print(*args, **kwargs, file=sys.stderr) + + +def _change_password(username: str, password: str): + """Update the password in SQLite database file.""" + from django.contrib.auth.models import User + try: + user = User.objects.get(username=username) + user.set_password(password) + user.save() + except User.DoesNotExist: + _print('User account does not exist:', username) + raise + + +if __name__ == '__main__': + main()