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:
parent
a0f82f0b5b
commit
7a4356c29f
|
@ -16,7 +16,6 @@
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
import attr
|
import attr
|
||||||
import os
|
|
||||||
import re
|
import re
|
||||||
from typing import Set
|
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]:
|
def _reserved_names_from_file(path: str) -> Set[str]:
|
||||||
names = set()
|
names = set()
|
||||||
try:
|
# The absence of this file is an installer bug.
|
||||||
with open(path, "r") as f:
|
with open(path, "r") as f:
|
||||||
for line in f:
|
for line in f:
|
||||||
line = line.strip()
|
line = line.strip()
|
||||||
if not line or line.startswith('#'):
|
if not line or line.startswith('#'):
|
||||||
continue
|
continue
|
||||||
names.add(line.split()[0])
|
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)
|
|
||||||
|
|
||||||
return names
|
return names
|
||||||
|
|
||||||
|
@ -101,15 +67,9 @@ class IdentityController(SubiquityController):
|
||||||
core_reserved_path = resource_path("reserved-usernames")
|
core_reserved_path = resource_path("reserved-usernames")
|
||||||
self._system_reserved_names = \
|
self._system_reserved_names = \
|
||||||
_reserved_names_from_file(core_reserved_path)
|
_reserved_names_from_file(core_reserved_path)
|
||||||
self._system_reserved_names.add('root')
|
|
||||||
|
|
||||||
self._existing_usernames = _existing_user_names(self._passwd_path())
|
# Let this field be the customisation point for variants.
|
||||||
|
self.existing_usernames = {'root'}
|
||||||
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")
|
|
||||||
|
|
||||||
def load_autoinstall_data(self, data):
|
def load_autoinstall_data(self, data):
|
||||||
if data is not None:
|
if data is not None:
|
||||||
|
@ -153,7 +113,7 @@ class IdentityController(SubiquityController):
|
||||||
await self.configured()
|
await self.configured()
|
||||||
|
|
||||||
async def validate_username_GET(self, username: str) -> UsernameValidation:
|
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
|
return UsernameValidation.ALREADY_IN_USE
|
||||||
|
|
||||||
if username in self._system_reserved_names:
|
if username in self._system_reserved_names:
|
||||||
|
|
|
@ -1068,13 +1068,9 @@ class TestIdentityValidation(TestAPI):
|
||||||
username='plugdev')
|
username='plugdev')
|
||||||
self.assertEqual(resp, 'SYSTEM_RESERVED')
|
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',
|
resp = await inst.get('/identity/validate_username',
|
||||||
username='root')
|
username='root')
|
||||||
self.assertNotEqual(resp, 'OK')
|
self.assertEqual(resp, 'ALREADY_IN_USE')
|
||||||
|
|
||||||
resp = await inst.get('/identity/validate_username',
|
resp = await inst.get('/identity/validate_username',
|
||||||
username='r'*33)
|
username='r'*33)
|
||||||
|
|
Loading…
Reference in New Issue