feat: xkcdpass password generation with configurable options

- Move settings_dictionary.yml to services/jupyterhub/conf/
- Replace hardcoded word list with xkcdpass library
- Add JUPYTERHUB_AUTOGENERATED_PASSWORD_WORDS (default: 4)
- Add JUPYTERHUB_AUTOGENERATED_PASSWORD_DELIMITER (default: "-")
- Fix ENABLE_SIGNUP to JUPYTERHUB_SIGNUP_ENABLED in Dockerfile
This commit is contained in:
stellarshenson
2026-01-14 17:11:27 +01:00
parent f7770d5e3a
commit 9e52c3c36a
4 changed files with 26 additions and 11 deletions

View File

@@ -147,3 +147,6 @@ This journal tracks substantive work on documents, diagrams, and documentation c
48. **Task - Settings dictionary YAML**: Externalized settings metadata to config/settings_dictionary.yml<br>
**Result**: Created settings_dictionary.yml with categories as top-level keys (JupyterHub Core, Docker Spawner, GPU, Services, Idle Culler, Branding), each containing list of settings with name, description, default, and optional empty_display. Updated SettingsPageHandler to load from YAML instead of hardcoded values. Added pyyaml to Dockerfile pip install. Dockerfile now copies settings_dictionary.yml to /srv/jupyterhub/
49. **Task - xkcdpass password generation**: Replaced custom word list with xkcdpass library for auto-generated passwords<br>
**Result**: Moved settings_dictionary.yml to services/jupyterhub/conf/ for proper image baking. Replaced hardcoded word list with xkcdpass library for memorable password generation. Added configurable env vars: JUPYTERHUB_AUTOGENERATED_PASSWORD_WORDS (default 4) and JUPYTERHUB_AUTOGENERATED_PASSWORD_DELIMITER (default "-"). Added xkcdpass to Dockerfile pip install. Fixed ENABLE_SIGNUP to JUPYTERHUB_SIGNUP_ENABLED in Dockerfile defaults

View File

@@ -88,11 +88,11 @@ def sync_nativeauth_on_rename(target, value, oldvalue, initiator):
@event.listens_for(orm.User, 'after_insert')
def create_nativeauth_on_user_insert(mapper, connection, target):
"""Auto-create NativeAuthenticator UserInfo when a new User is created via admin panel.
Generates a memorable password and auto-approves the user."""
Generates a memorable password using xkcdpass and auto-approves the user."""
username = target.name
try:
import bcrypt
import random
from xkcdpass import xkcd_password as xp
from sqlalchemy import text
# Check if UserInfo already exists (user might have signed up normally)
@@ -104,11 +104,12 @@ def create_nativeauth_on_user_insert(mapper, connection, target):
print(f"[NativeAuth Auto-Create] UserInfo already exists for: {username}")
return
# Generate memorable 3-word password
words = ['apple', 'beach', 'cloud', 'dance', 'eagle', 'flame', 'grape', 'happy',
'ivory', 'jolly', 'karma', 'lemon', 'mango', 'noble', 'ocean', 'piano',
'quest', 'river', 'storm', 'tiger', 'urban', 'vivid', 'water', 'zebra']
password = '-'.join(random.sample(words, 3))
# Generate memorable password using xkcdpass (configurable via env)
num_words = int(os.environ.get('JUPYTERHUB_AUTOGENERATED_PASSWORD_WORDS', 4))
delimiter = os.environ.get('JUPYTERHUB_AUTOGENERATED_PASSWORD_DELIMITER', '-')
wordfile = xp.locate_wordfile()
words = xp.generate_wordlist(wordfile=wordfile, min_length=4, max_length=6)
password = xp.generate_xkcdpassword(words, numwords=num_words, delimiter=delimiter)
# Hash password with bcrypt
hashed_password = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt())

View File

@@ -42,9 +42,9 @@ COPY --chmod=600 services/jupyterhub/templates/certs /mnt/certs
COPY --chmod=644 services/jupyterhub/templates_enhanced/*.html /srv/jupyterhub/templates/
COPY --chmod=644 services/jupyterhub/templates_enhanced/static/custom.css /tmp/custom.css
COPY --chmod=644 config/jupyterhub_config.py /srv/jupyterhub/jupyterhub_config.py
COPY --chmod=644 config/settings_dictionary.yml /srv/jupyterhub/settings_dictionary.yml
COPY --chmod=644 services/jupyterhub/conf/settings_dictionary.yml /srv/jupyterhub/settings_dictionary.yml
## install dockerspawner, nativeauthenticator, idle-culler, pyyaml
## install dockerspawner, nativeauthenticator, idle-culler, pyyaml, xkcdpass
RUN <<-EOF
echo "installing core jupyterhub python packages"
pip install -U --no-cache-dir \
@@ -52,7 +52,8 @@ RUN <<-EOF
dockerspawner \
jupyterhub-nativeauthenticator \
jupyterhub-idle-culler \
pyyaml
pyyaml \
xkcdpass
EOF
## copy custom.css to JupyterHub's static directory
@@ -62,7 +63,9 @@ RUN <<-EOF
EOF
## default environment variables
ENV ENABLE_SIGNUP=1
ENV JUPYTERHUB_SIGNUP_ENABLED=1
ENV JUPYTERHUB_AUTOGENERATED_PASSWORD_WORDS=4
ENV JUPYTERHUB_AUTOGENERATED_PASSWORD_DELIMITER="-"
ENV STELLARS_JUPYTERHUB_VERSION=${VERSION}
ENV JUPYTERHUB_CUSTOM_LOGO_URI=""

View File

@@ -20,6 +20,14 @@ JupyterHub Core:
description: SSL/TLS (0=disabled, 1=enabled)
default: "1"
- name: JUPYTERHUB_AUTOGENERATED_PASSWORD_WORDS
description: Number of words in auto-generated passwords
default: "4"
- name: JUPYTERHUB_AUTOGENERATED_PASSWORD_DELIMITER
description: Delimiter between words in auto-generated passwords
default: "-"
Docker Spawner:
- name: JUPYTERHUB_NOTEBOOK_IMAGE
description: User container image