From f64fa2bd1251280d148379e06d09800aca0a7fe4 Mon Sep 17 00:00:00 2001 From: JEEVITHA KANNAN K S Date: Thu, 19 Sep 2024 07:18:42 +0530 Subject: [PATCH] feat: Add User Manager (#393) * Add User Control Panel * Fix non posix * Split script * Update userguide.md * Update utility_functions.sh * Remove clear * Add checkEnv --- docs/userguide.md | 8 ++ tabs/utils/tab_data.toml | 25 ++++- .../user-account-manager/add_to_group.sh | 35 ++++++ tabs/utils/user-account-manager/add_user.sh | 26 +++++ .../user-account-manager/change_password.sh | 19 ++++ .../utils/user-account-manager/delete_user.sh | 26 +++++ .../user-account-manager/remove_from_group.sh | 30 ++++++ .../user-account-manager/utility_functions.sh | 100 ++++++++++++++++++ 8 files changed, 268 insertions(+), 1 deletion(-) create mode 100755 tabs/utils/user-account-manager/add_to_group.sh create mode 100755 tabs/utils/user-account-manager/add_user.sh create mode 100755 tabs/utils/user-account-manager/change_password.sh create mode 100755 tabs/utils/user-account-manager/delete_user.sh create mode 100755 tabs/utils/user-account-manager/remove_from_group.sh create mode 100755 tabs/utils/user-account-manager/utility_functions.sh diff --git a/docs/userguide.md b/docs/userguide.md index 8fc385f5..57af97e1 100644 --- a/docs/userguide.md +++ b/docs/userguide.md @@ -30,3 +30,11 @@ ## Security Features - **Firewall Baselines**: Sets up firewall rules. + +## Utilities + +- **Monitor Control**: Controls monitor settings on X11. +- **Bluetooth Control**: Controls Bluetooth settings. +- **Wifi Control**: Controls WiFi settings. +- **Numlock Control**: Sets up Numlock on boot. +- **User Account Manager**: Manage users and groups. diff --git a/tabs/utils/tab_data.toml b/tabs/utils/tab_data.toml index 012ec341..d09496ff 100644 --- a/tabs/utils/tab_data.toml +++ b/tabs/utils/tab_data.toml @@ -112,4 +112,27 @@ matches = true [[data.entries]] name = "Set Brightness" script = "monitor-control/set_brightness.sh" -matches = true \ No newline at end of file +matches = true + +[[data]] +name = "User Account Manager" + +[[data.entries]] +name = "Add User" +script = "user-account-manager/add_user.sh" + +[[data.entries]] +name = "Change Password" +script = "user-account-manager/change_password.sh" + +[[data.entries]] +name = "Delete User" +script = "user-account-manager/delete_user.sh" + +[[data.entries]] +name = "Add User To Groups" +script = "user-account-manager/add_to_group.sh" + +[[data.entries]] +name = "Remove User From Groups" +script = "user-account-manager/remove_from_group.sh" \ No newline at end of file diff --git a/tabs/utils/user-account-manager/add_to_group.sh b/tabs/utils/user-account-manager/add_to_group.sh new file mode 100755 index 00000000..dd8a2a74 --- /dev/null +++ b/tabs/utils/user-account-manager/add_to_group.sh @@ -0,0 +1,35 @@ +#!/bin/sh -e + +. ../../common-script.sh +. ./utility_functions.sh + +clear +printf "%b\n" "${YELLOW}Add to group${RC}" +printf "%b\n" "${YELLOW}=================${RC}" + +username=$(promptUsername "" "non-root") || exit 1 +user_groups=$(groups "$username" | cut -d: -f2 | sort | tr '\n' ' ') + +printf "%b\n" "${YELLOW}Groups user $username is in:${RC} $user_groups" +printf "%b\n" "${YELLOW}=================${RC}" + +available_groups=$(cut -d: -f1 /etc/group | sort | tr '\n' ' ') + +printf "%b\n" "${YELLOW}Available groups:${RC} $available_groups" +printf "%b\n" "${YELLOW}=================${RC}" + +read -p "Enter the groups you want to add user $username to (space-separated): " groups + +checkEmpty "$groups" || exit 1 +checkGroupAvailabe "$groups" "$available_groups" || exit 1 + +groups_to_add=$(echo "$groups" | tr ' ' ',') + +read -p "Are you sure you want to add user $username to $groups_to_add? [Y/N]: " confirm +confirmAction || exit 1 + +$ESCALATION_TOOL usermod -aG $groups_to_add "$username" + +printf "%b\n" "${GREEN}User successfully added to the $groups_to_add${RC}" + +checkEnv \ No newline at end of file diff --git a/tabs/utils/user-account-manager/add_user.sh b/tabs/utils/user-account-manager/add_user.sh new file mode 100755 index 00000000..83f31ca4 --- /dev/null +++ b/tabs/utils/user-account-manager/add_user.sh @@ -0,0 +1,26 @@ +#!/bin/sh -e + +. ../../common-script.sh +. ./utility_functions.sh + +clear +printf "%b\n" "${YELLOW}Create a new user${RC}" +printf "%b\n" "${YELLOW}=================${RC}" + +username=$(promptUsername "add" "non-root") || exit 1 + +# Check if username is valid +if ! echo "$username" | grep '^[a-z][-a-z0-9_]*$' > /dev/null; then + printf "%b\n" "${RED}Username must only contain letters, numbers, hyphens, and underscores. It cannot start with a number or contain spaces.${RC}" + exit 1 +fi + +password=$(promptPassword) || exit 1 + +$ESCALATION_TOOL useradd -m "$username" -g users -s /bin/bash +echo "$username:$password" | $ESCALATION_TOOL chpasswd + +printf "%b\n" "${GREEN}User $username created successfully${RC}" +printf "%b\n" "${GREEN}To add additional groups use Add User To Groups${RC}" + +checkEnv diff --git a/tabs/utils/user-account-manager/change_password.sh b/tabs/utils/user-account-manager/change_password.sh new file mode 100755 index 00000000..ef05a55b --- /dev/null +++ b/tabs/utils/user-account-manager/change_password.sh @@ -0,0 +1,19 @@ +#!/bin/sh -e + +. ../../common-script.sh +. ./utility_functions.sh + +clear +printf "%b\n" "${YELLOW}Change password${RC}" +printf "%b\n" "${YELLOW}=================${RC}" + +username=$(promptUsername "" "root") || exit 1 +password=$(promptPassword) || exit 1 + +read -p "Are you sure you want to change password for $username? [Y/N]: " confirm +confirmAction || exit 1 + +echo "$username:$password" | $ESCALATION_TOOL chpasswd +printf "%b\n" "${GREEN}Password changed successfully${RC}" + +checkEnv \ No newline at end of file diff --git a/tabs/utils/user-account-manager/delete_user.sh b/tabs/utils/user-account-manager/delete_user.sh new file mode 100755 index 00000000..cb68bdf9 --- /dev/null +++ b/tabs/utils/user-account-manager/delete_user.sh @@ -0,0 +1,26 @@ +#!/bin/sh -e + +. ../../common-script.sh +. ./utility_functions.sh + +clear +printf "%b\n" "${YELLOW}Delete a user${RC}" +printf "%b\n" "${YELLOW}=================${RC}" + +username=$(promptUsername "" "non-root") || exit 1 + +# Check if current user +if [ "$username" = "$USER" ]; then + printf "%b\n" "${RED}Cannot delete the current user${RC}" + printf "%b\n" "${RED}Press [Enter] to continue...${RC}" + read dummy + return +fi + +read -p "Are you sure you want to delete user $username? [Y/N]: " confirm +confirmAction || exit 1 + +$ESCALATION_TOOL userdel --remove "$username" 2>/dev/null +printf "%b\n" "${GREEN}User $username deleted successfully${RC}" + +checkEnv \ No newline at end of file diff --git a/tabs/utils/user-account-manager/remove_from_group.sh b/tabs/utils/user-account-manager/remove_from_group.sh new file mode 100755 index 00000000..4d3c65c3 --- /dev/null +++ b/tabs/utils/user-account-manager/remove_from_group.sh @@ -0,0 +1,30 @@ +#!/bin/sh -e + +. ../../common-script.sh +. ./utility_functions.sh + +clear +printf "%b\n" "${YELLOW}Remove from group${RC}" +printf "%b\n" "${YELLOW}=================${RC}" + +username=$(promptUsername "" "non-root") || exit 1 +user_groups=$(groups "$username" | cut -d: -f2 | sort | tr '\n' ' ') + +printf "%b\n" "${YELLOW}Groups user $username is in:${RC} $user_groups" +printf "%b\n" "${YELLOW}=================${RC}" + +read -p "Enter the groups you want to remove user from $username (space-separated): " groups + +checkEmpty "$groups" || exit 1 +checkGroupAvailabe "$groups" "$user_groups" || exit 1 + +groups_to_remove=$(echo "$groups" | tr ' ' ',') + +read -p "Are you sure you want to remove user $username from $groups_to_remove? [Y/N]: " confirm +confirmAction || exit 1 + +$ESCALATION_TOOL usermod -rG $groups_to_remove "$username" + +printf "%b\n" "${GREEN}User successfully removed from $groups_to_remove${RC}" + +checkEnv \ No newline at end of file diff --git a/tabs/utils/user-account-manager/utility_functions.sh b/tabs/utils/user-account-manager/utility_functions.sh new file mode 100755 index 00000000..0dedd7e6 --- /dev/null +++ b/tabs/utils/user-account-manager/utility_functions.sh @@ -0,0 +1,100 @@ +#!/bin/sh -e + +. ../../common-script.sh + +# Prompt for username +promptUsername() { + read -p "Enter the username: " username + + checkEmpty "$username"; + + if [ "$1" = "add" ]; then + checkUserExistence "$username" "$1" + else + checkUserExistence "$username" "$1" + checkReservedUsername "$username" "$2" + fi + echo "$username" +} + + +# Prompt for password +promptPassword() { + stty -echo + read -p "Enter the password (PASSWORD IS HIDDEN): " password1 + echo >&2 + read -p "Re-enter the password (PASSWORD IS HIDDEN): " password2 + echo >&2 + stty echo + + if ! checkEmpty "$password1"; then + promptPassword + fi + + if [ "$password1" != "$password2" ]; then + printf "%b\n" "${RED}Passwords do not match${RC}" >&2 + promptPassword + else + echo $password1 + fi +} + +# Check if input is empty +checkEmpty() { + if [ -z "$1" ]; then + printf "%b\n" "${RED}Empty value is not allowed${RC}" >&2 + exit 1 + fi +} + +# Check if user exists +checkUserExistence() { + if [ "$2" = "add" ]; then + if id "$1" > /dev/null 2>&1; then + printf "%b\n" "${RED}User already exists${RC}" >&2 + exit 1 + fi + else + if ! id "$1" > /dev/null 2>&1; then + printf "%b\n" "${RED}User does not exist${RC}" >&2 + exit 1 + fi + fi +} + +# Check if user is reserved +checkReservedUsername() { + uid=$(id -u "$1") + if [ "$2" = "root" ]; then + if [ "$uid" -le 999 ] && [ "$uid" -ne 0 ]; then + printf "%b\n" "${RED}Cannot modify system users${RC}" >&2 + exit 1 + fi + else + if [ "$(id -u "$1")" -le 999 ]; then + printf "%b\n" "${RED}Cannot modify system users${RC}" >&2 + exit 1 + fi + fi +} + +# Check if user is reserved +confirmAction() { + if [ "$confirm" != "y" ] && [ "$confirm" != "Y" ]; then + printf "%b\n" "${RED}Cancelled operation...${RC}" >&2 + exit 1 + fi +} + +# Check if group is available +checkGroupAvailabe() { + for group in $1; do + if ! echo "$2" | grep -wq "$group"; then + printf "%b\n" "${RED}Group $group not avaiable${RC}" >&2 + exit 1 + fi + done +} + +checkEnv +checkEscalationTool