# SPDX-License-Identifier: MIT
# SPDX-FileCopyrightText: Copyright 2024 SUSE LLC
# shellcheck shell=bash

user_title=$"User Creation"
user_description=$"Create an unprivileged user account"
user_priority=60

# First parameter is default list of supplemental groups
user_do_config()
{
	local username=""
	local fullname=""
	local groups="$1"
	local errmsg

	# Loop until cancelled or successfully completed.
	while true; do
		local msg="$(
			echo $"If desired, create an additional user account."
			echo $"This is necessary for password-based SSH login and the Cockpit Web UI."
		)"

		d_with_result --title $"User Creation" \
			--insecure \
			--cancel-label $"Skip" \
			--mixedform "${msg}" 9 0 6 \
			$"Username" 1 0 "$username" 1 18 35 0 0 \
			$"Full name" 2 0 "$fullname" 2 18 35 0 0 \
			$"Groups" 3 0 "$groups" 3 18 35 0 0 \
			$"Password" 5 0 "" 5 18 35 0 1 \
			$"Password (again)" 6 0 "" 6 18 35 0 1

		local ret=$?
		if [ "$ret" -eq 1 ]; then
			# Skip button pressed
			return 0
		elif [ "$ret" -eq 255 ]; then
			# ESC
			if d_styled --yesno $"Do you really want to quit?" 0 0; then
				exit 1
			fi
			continue
		fi

		readarray -t input <<<"$result"

		# Collect input
		username="${input[0]}"
		fullname="${input[1]}"
		groups="${input[2]}"
		# Make sure not to pass those as parameters to processes!
		local password="${input[3]}"
		local password_repeat="${input[4]}"

		# Input handling and validation
		if ! [[ "$username" =~ ^[a-z][-_a-z0-9]*$ ]]; then
			d_styled --title $"User Creation" --msgbox $"Invalid username.\nMake sure it starts with a 
				lowercase letter and only contains -, _, digits and lowercase letters." 8 45
			continue
		fi

		if [ -z "$password" ]; then
			d_styled --title $"User Creation" --msgbox $"You have to enter a password" 8 45
			continue
		fi

		if [ "$password" != "$password_repeat" ]; then
			d_styled --title $"User Creation" --msgbox $"Passwords do not match." 8 45
			continue
		fi

		# Password strength check
		errmsg="$(printf "%s" "$password" | cracklib-check 2>&1)"
		# For some reason cracklib-check includes the password in the message.
		# https://github.com/cracklib/cracklib/pull/78 improves this, but it's too new.
		errmsg="${errmsg/*: /}"
		if [ "$errmsg" != "OK" ]; then
			d_styled --title $"User Creation" --msgbox "$(printf $"cracklib-check failed: %s" "$errmsg")" 8 45
			continue
		fi

		errmsg="$(useradd "$username" -c "$fullname" 2>&1)"
		if [ "$?" -ne 0 ]; then
			d_styled --title $"User Creation" --msgbox "$(printf $"useradd failed: %s" "$errmsg")" 8 45
			continue
		fi

		# Set the requested password
		if ! printf "%s:%s" "$username" "$password" | chpasswd; then
			d_styled --title $"User Creation" --msgbox "$(printf $"chpasswd failed, leaving account locked: %s" "$errmsg")" 8 45
			# Nothing we can do here, admin can fix this locally as root
		fi

		local group=""
		for group in $groups; do
			errmsg="$(usermod -a -G "$group" "$username" 2>&1)"
			if [ "$?" -ne 0 ]; then
				d_styled --title $"User Creation" --msgbox "$(printf $"Failed to add the user to the %s group: %s" "$group" "$errmsg")" 8 45
				# Nothing we can do here, admin can fix this locally as root
			fi
		done

		break
	done

	return 0
}

user_systemd_firstboot()
{
	# Add the user created during initial setup to the wheel group by default
	local defaultgroups=""
	if getent group wheel >/dev/null; then
		defaultgroups="wheel"
	fi

	user_do_config "$defaultgroups"
}

user_jeos_config()
{
	user_do_config ""
}
