Let `existing_usernames` be a customisation point.

Initializes it with just 'root' by default.
Server variants may find appropriate ways to initialize it.
Reading the passwd database of the target is not a reliable thing to do.
Need to find a stronger way before placing that in the main server.
This commit is contained in:
Carlos Nihelton 2022-05-12 17:01:23 -03:00
parent a0f82f0b5b
commit 7a4356c29f
No known key found for this signature in database
GPG Key ID: 6FE346D245197E9A
2 changed files with 11 additions and 55 deletions

View File

@ -16,7 +16,6 @@
import logging
import attr
import os
import re
from typing import Set
@ -35,46 +34,13 @@ USERNAME_REGEX = r'[a-z_][a-z0-9_-]*'
def _reserved_names_from_file(path: str) -> Set[str]:
names = set()
try:
with open(path, "r") as f:
for line in f:
line = line.strip()
if not line or line.startswith('#'):
continue
names.add(line.split()[0])
except FileNotFoundError:
log.error("Could not find %s", path)
except OSError:
log.error("Failed to process %s", path)
except Exception:
log.error("Unexpected error happened when attempted to read %s",
path)
return names
def _existing_user_names(path: str) -> Set[str]:
names = set()
try:
with open(path, "r") as f:
for line in f:
line = line.strip()
if not line:
continue
names.add(line.split(":")[0])
except FileNotFoundError:
log.error("Could not find passwd database %s", path)
except OSError:
log.error("Failed to process %s", path)
except Exception:
log.error("Unexpected error happened when attempted to read %s",
path)
# The absence of this file is an installer bug.
with open(path, "r") as f:
for line in f:
line = line.strip()
if not line or line.startswith('#'):
continue
names.add(line.split()[0])
return names
@ -101,15 +67,9 @@ class IdentityController(SubiquityController):
core_reserved_path = resource_path("reserved-usernames")
self._system_reserved_names = \
_reserved_names_from_file(core_reserved_path)
self._system_reserved_names.add('root')
self._existing_usernames = _existing_user_names(self._passwd_path())
def _passwd_path(self) -> str:
if self.app.opts.dry_run:
return resource_path("passwd")
else:
return os.path.join(self.app.base_model.target, "etc/passwd")
# Let this field be the customisation point for variants.
self.existing_usernames = {'root'}
def load_autoinstall_data(self, data):
if data is not None:
@ -153,7 +113,7 @@ class IdentityController(SubiquityController):
await self.configured()
async def validate_username_GET(self, username: str) -> UsernameValidation:
if username in self._existing_usernames:
if username in self.existing_usernames:
return UsernameValidation.ALREADY_IN_USE
if username in self._system_reserved_names:

View File

@ -1068,13 +1068,9 @@ class TestIdentityValidation(TestAPI):
username='plugdev')
self.assertEqual(resp, 'SYSTEM_RESERVED')
resp = await inst.get('/identity/validate_username',
username='gdm')
self.assertEqual(resp, 'ALREADY_IN_USE')
resp = await inst.get('/identity/validate_username',
username='root')
self.assertNotEqual(resp, 'OK')
self.assertEqual(resp, 'ALREADY_IN_USE')
resp = await inst.get('/identity/validate_username',
username='r'*33)