Send patches - preferably formatted by git format-patch - to patches at archlinux32 dot org.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Hvornum <anton@hvornum.se>2021-11-09 17:43:28 +0100
committerAnton Hvornum <anton@hvornum.se>2021-11-09 17:43:28 +0100
commit389aa1080b99b4b0a52a3940e9a344027b5cb9b6 (patch)
tree180b29983c3802f42b630f234db9917542df4385
parentd1716eeeef00d6a8e01a2c3bf5e1de831f50128c (diff)
Adding in storage of user supplied credentials. This separates credentials from user_configuration.json into user_credentials.json. As well as the JSON serializer will omit the credentials from the user_configuration.json by detecting ! in the dictionary keys (which is why they are important). UNSAFE_JSON will leave those keys in there, good for storing credentials in a separate file."
-rw-r--r--archinstall/lib/general.py39
-rw-r--r--examples/guided.py21
2 files changed, 53 insertions, 7 deletions
diff --git a/archinstall/lib/general.py b/archinstall/lib/general.py
index 887a60d3..5ab2181c 100644
--- a/archinstall/lib/general.py
+++ b/archinstall/lib/general.py
@@ -77,6 +77,13 @@ def json_dumps(*args, **kwargs):
class JsonEncoder:
def _encode(obj):
+ """
+ This JSON encoder function will try it's best to convert
+ any archinstall data structures, instances or variables into
+ something that's understandable by the json.parse()/json.loads() lib.
+
+ _encode() will skip any dictionary key starting with an exclamation mark (!)
+ """
if isinstance(obj, dict):
# We'll need to iterate not just the value that default() usually gets passed
# But also iterate manually over each key: value pair in order to trap the keys.
@@ -90,7 +97,7 @@ class JsonEncoder:
val = JsonEncoder._encode(val)
if type(key) == str and key[0] == '!':
- copy[JsonEncoder._encode(key)] = '******'
+ pass
else:
copy[JsonEncoder._encode(key)] = val
return copy
@@ -105,14 +112,44 @@ class JsonEncoder:
else:
return obj
+ def _unsafe_encode(obj):
+ """
+ Same as _encode() but it keeps dictionary keys starting with !
+ """
+ if isinstance(obj, dict):
+ copy = {}
+ for key, val in list(obj.items()):
+ if isinstance(val, dict):
+ # This, is a EXTREMELY ugly hack.. but it's the only quick way I can think of to trigger a encoding of sub-dictionaries.
+ val = json.loads(json.dumps(val, cls=JSON))
+ else:
+ val = JsonEncoder._encode(val)
+
+ copy[JsonEncoder._encode(key)] = val
+ return copy
+ else:
+ return JsonEncoder._encode(obj)
class JSON(json.JSONEncoder, json.JSONDecoder):
+ """
+ A safe JSON encoder that will omit private information in dicts (starting with !)
+ """
def _encode(self, obj):
return JsonEncoder._encode(obj)
def encode(self, obj):
return super(JSON, self).encode(self._encode(obj))
+class UNSAFE_JSON(json.JSONEncoder, json.JSONDecoder):
+ """
+ UNSAFE_JSON will call/encode and keep private information in dicts (starting with !)
+ """
+ def _encode(self, obj):
+ return JsonEncoder._unsafe_encode(obj)
+
+ def encode(self, obj):
+ return super(UNSAFE_JSON, self).encode(self._encode(obj))
+
class SysCommandWorker:
def __init__(self, cmd, callbacks=None, peak_output=False, environment_vars=None, logfile=None, working_directory='./'):
if not callbacks:
diff --git a/examples/guided.py b/examples/guided.py
index b1c34464..a1f30f76 100644
--- a/examples/guided.py
+++ b/examples/guided.py
@@ -138,11 +138,11 @@ def ask_user_questions():
archinstall.arguments['!root-password'] = archinstall.get_password(prompt='Enter root password (leave blank to disable disabled & create superuser): ')
# Ask for additional users (super-user if root pw was not set)
- if not archinstall.arguments.get('!root-password', None) and not archinstall.arguments.get('superusers', None):
- archinstall.arguments['superusers'] = archinstall.ask_for_superuser_account('Create a required super-user with sudo privileges: ', forced=True)
+ if not archinstall.arguments.get('!root-password', None) and not archinstall.arguments.get('!superusers', None):
+ archinstall.arguments['!superusers'] = archinstall.ask_for_superuser_account('Create a required super-user with sudo privileges: ', forced=True)
users, superusers = archinstall.ask_for_additional_users('Enter a username to create an additional user (leave blank to skip & continue): ')
- archinstall.arguments['users'] = users
- archinstall.arguments['superusers'] = {**archinstall.arguments['superusers'], **superusers}
+ archinstall.arguments['!users'] = users
+ archinstall.arguments['!superusers'] = {**archinstall.arguments['!superusers'], **superusers}
# Ask for archinstall-specific profiles (such as desktop environments etc)
if not archinstall.arguments.get('profile', None):
@@ -243,6 +243,15 @@ def perform_filesystem_operations():
fs.load_layout(archinstall.storage['disk_layouts'][drive.path])
def perform_installation(mountpoint):
+ user_credentials = json.dumps({
+ "!users" : archinstall.arguments['!users'],
+ "!superusers" : archinstall.arguments['!users'],
+ "!root-password" : archinstall.arguments['!users'],
+ }, indent=4, sort_keys=True, cls=archinstall.UNSAFE_JSON)
+
+ with open("/var/log/archinstall/user_credentials.json", "w") as config_file:
+ config_file.write(user_credentials)
+
"""
Performs the installation steps on a block device.
Only requirement is that the block devices are
@@ -305,10 +314,10 @@ def perform_installation(mountpoint):
if archinstall.arguments.get('profile', None):
installation.install_profile(archinstall.arguments.get('profile', None))
- for user, user_info in archinstall.arguments.get('users', {}).items():
+ for user, user_info in archinstall.arguments.get('!users', {}).items():
installation.user_create(user, user_info["!password"], sudo=False)
- for superuser, user_info in archinstall.arguments.get('superusers', {}).items():
+ for superuser, user_info in archinstall.arguments.get('!superusers', {}).items():
installation.user_create(superuser, user_info["!password"], sudo=True)
if timezone := archinstall.arguments.get('timezone', None):