Send patches - preferably formatted by git format-patch - to patches at archlinux32 dot org.
summaryrefslogtreecommitdiff
path: root/archinstall/lib/user_interaction/manage_users_conf.py
diff options
context:
space:
mode:
authorDaniel <blackrabbit256@gmail.com>2022-03-28 22:49:05 +1100
committerGitHub <noreply@github.com>2022-03-28 13:49:05 +0200
commit3dc0d957e838c34b48a0782d2540341e33b24070 (patch)
treec0d4edbc2a9c0b6c05161421c3ad28cec9ab2dc7 /archinstall/lib/user_interaction/manage_users_conf.py
parente85c9b65315498ab4701ea31c079d198eba8d9ac (diff)
Deflate user interactions (#1019)
* Deflate the user interactions file * Fix flake8 Co-authored-by: Daniel Girtler <girtler.daniel@gmail.com>
Diffstat (limited to 'archinstall/lib/user_interaction/manage_users_conf.py')
-rw-r--r--archinstall/lib/user_interaction/manage_users_conf.py169
1 files changed, 169 insertions, 0 deletions
diff --git a/archinstall/lib/user_interaction/manage_users_conf.py b/archinstall/lib/user_interaction/manage_users_conf.py
new file mode 100644
index 00000000..0af0d776
--- /dev/null
+++ b/archinstall/lib/user_interaction/manage_users_conf.py
@@ -0,0 +1,169 @@
+from __future__ import annotations
+
+import logging
+import re
+from typing import Any, Dict, TYPE_CHECKING
+
+from ..menu import Menu
+from ..menu.list_manager import ListManager
+from ..output import log
+from ..storage import storage
+from .utils import get_password
+
+if TYPE_CHECKING:
+ _: Any
+
+
+class UserList(ListManager):
+ """
+ subclass of ListManager for the managing of user accounts
+ """
+
+ def __init__(self, prompt: str, lusers: dict, sudo: bool = None):
+ """
+ param: prompt
+ type: str
+ param: lusers dict with the users already defined for the system
+ type: Dict
+ param: sudo. boolean to determine if we handle superusers or users. If None handles both types
+ """
+ self.sudo = sudo
+ self.actions = [
+ str(_('Add an user')),
+ str(_('Change password')),
+ str(_('Promote/Demote user')),
+ str(_('Delete User'))
+ ]
+ self.default_action = self.actions[0]
+ super().__init__(prompt, lusers, self.actions, self.default_action)
+
+ def reformat(self):
+
+ def format_element(elem):
+ # secret gives away the length of the password
+ if self.data[elem].get('!password'):
+ pwd = '*' * 16
+ # pwd = archinstall.secret(self.data[elem]['!password'])
+ else:
+ pwd = ''
+ if self.data[elem].get('sudoer'):
+ super = 'Superuser'
+ else:
+ super = ' '
+ return f"{elem:16}: password {pwd:16} {super}"
+
+ return list(map(lambda x: format_element(x), self.data))
+
+ def action_list(self):
+ if self.target:
+ active_user = list(self.target.keys())[0]
+ else:
+ active_user = None
+ sudoer = self.target[active_user].get('sudoer', False)
+ if self.sudo is None:
+ return self.actions
+ if self.sudo and sudoer:
+ return self.actions
+ elif self.sudo and not sudoer:
+ return [self.actions[2]]
+ elif not self.sudo and sudoer:
+ return [self.actions[2]]
+ else:
+ return self.actions
+
+ def exec_action(self):
+ if self.target:
+ active_user = list(self.target.keys())[0]
+ else:
+ active_user = None
+
+ if self.action == self.actions[0]: # add
+ new_user = self.add_user()
+ # no unicity check, if exists will be replaced
+ self.data.update(new_user)
+ elif self.action == self.actions[1]: # change password
+ self.data[active_user]['!password'] = get_password(
+ prompt=str(_('Password for user "{}": ').format(active_user)))
+ elif self.action == self.actions[2]: # promote/demote
+ self.data[active_user]['sudoer'] = not self.data[active_user]['sudoer']
+ elif self.action == self.actions[3]: # delete
+ del self.data[active_user]
+
+ def _check_for_correct_username(username: str) -> bool:
+ if re.match(r'^[a-z_][a-z0-9_-]*\$?$', username) and len(username) <= 32:
+ return True
+ log("The username you entered is invalid. Try again", level=logging.WARNING, fg='red')
+ return False
+
+ def add_user(self):
+ print(_('\nDefine a new user\n'))
+ prompt = str(_("User Name : "))
+ while True:
+ userid = input(prompt).strip(' ')
+ if not userid:
+ return {} # end
+ if not self._check_for_correct_username(userid):
+ pass
+ else:
+ break
+ if self.sudo:
+ sudoer = True
+ elif self.sudo is not None and not self.sudo:
+ sudoer = False
+ else:
+ sudoer = False
+ sudo_choice = Menu(str(_('Should {} be a superuser (sudoer)?')).format(userid), ['yes', 'no'],
+ skip=False,
+ preset_values='yes' if sudoer else 'no',
+ default_option='no').run()
+ sudoer = True if sudo_choice == 'yes' else False
+
+ password = get_password(prompt=str(_('Password for user "{}": ').format(userid)))
+
+ return {userid: {"!password": password, "sudoer": sudoer}}
+
+
+def manage_users(prompt: str, sudo: bool) -> tuple[dict, dict]:
+ # TODO Filtering and some kind of simpler code
+ lusers = {}
+ if storage['arguments'].get('!superusers', {}):
+ lusers.update({
+ uid: {
+ '!password': storage['arguments']['!superusers'][uid].get('!password'),
+ 'sudoer': True
+ }
+ for uid in storage['arguments'].get('!superusers', {})
+ })
+ if storage['arguments'].get('!users', {}):
+ lusers.update({
+ uid: {
+ '!password': storage['arguments']['!users'][uid].get('!password'),
+ 'sudoer': False
+ }
+ for uid in storage['arguments'].get('!users', {})
+ })
+ # processing
+ lusers = UserList(prompt, lusers, sudo).run()
+ # return data
+ superusers = {
+ uid: {
+ '!password': lusers[uid].get('!password')
+ }
+ for uid in lusers if lusers[uid].get('sudoer', False)
+ }
+ users = {uid: {'!password': lusers[uid].get('!password')} for uid in lusers if not lusers[uid].get('sudoer', False)}
+ storage['arguments']['!superusers'] = superusers
+ storage['arguments']['!users'] = users
+ return superusers, users
+
+
+def ask_for_superuser_account(prompt: str) -> Dict[str, Dict[str, str]]:
+ prompt = prompt if prompt else str(_('Define users with sudo privilege: '))
+ superusers, dummy = manage_users(prompt, sudo=True)
+ return superusers
+
+
+def ask_for_additional_users(prompt: str = '') -> Dict[str, Dict[str, str | None]]:
+ prompt = prompt if prompt else _('Any additional users to install (leave blank for no users): ')
+ dummy, users = manage_users(prompt, sudo=False)
+ return users