Merge pull request #1568 from CarlosNihelton/ad-enhancements-deeng-596
Active Directory API UX Enhancements
This commit is contained in:
commit
bf603d3b3e
|
@ -418,6 +418,12 @@ class API:
|
|||
# POST expects input validated by the check methods below:
|
||||
def POST(data: Payload[ADConnectionInfo]) -> None: ...
|
||||
|
||||
class has_support:
|
||||
""" Whether the live system supports Active Directory or not.
|
||||
Network status is not considered.
|
||||
Clients should call this before showing the AD page. """
|
||||
def GET() -> bool: ...
|
||||
|
||||
class check_domain_name:
|
||||
def GET(domain_name: Payload[str]) \
|
||||
-> List[AdDomainNameValidation]: ...
|
||||
|
|
|
@ -27,6 +27,16 @@ class ADModel:
|
|||
self.do_join = False
|
||||
self.conn_info: Optional[ADConnectionInfo] = None
|
||||
|
||||
def set_domain(self, domain: str):
|
||||
if not domain:
|
||||
return
|
||||
|
||||
if self.conn_info:
|
||||
self.conn_info.domain_name = domain
|
||||
|
||||
else:
|
||||
self.conn_info = ADConnectionInfo(domain_name=domain)
|
||||
|
||||
async def target_packages(self):
|
||||
# NOTE Those packages must be present in the target system to allow
|
||||
# joining to a domain.
|
||||
|
|
|
@ -14,9 +14,11 @@
|
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
from typing import List, Optional, Set
|
||||
from subiquitycore.utils import arun_command
|
||||
from subiquitycore.async_helpers import run_bg_task
|
||||
|
||||
from subiquity.common.apidef import API
|
||||
from subiquity.common.types import (
|
||||
|
@ -43,6 +45,9 @@ class DcPingStrategy:
|
|||
cmd = "/usr/sbin/realm"
|
||||
arg = "discover"
|
||||
|
||||
def has_support(self) -> bool:
|
||||
return os.access(self.cmd, os.X_OK)
|
||||
|
||||
async def ping(self, address: str) -> AdDomainNameValidation:
|
||||
cp = await arun_command([self.cmd, self.arg, address], env={})
|
||||
if cp.returncode:
|
||||
|
@ -50,6 +55,18 @@ class DcPingStrategy:
|
|||
|
||||
return AdDomainNameValidation.OK
|
||||
|
||||
async def discover(self) -> str:
|
||||
""" Attempts to discover a domain through the network.
|
||||
Returns the domain or an empty string on error. """
|
||||
cp = await arun_command([self.cmd, self.arg], env={})
|
||||
discovered = ""
|
||||
if cp.returncode == 0:
|
||||
# A typical output looks like:
|
||||
# 'creative.com\n type: kerberos\n realm-name: CREATIVE.COM\n...'
|
||||
discovered = cp.stdout.split('\n')[0].strip()
|
||||
|
||||
return discovered
|
||||
|
||||
|
||||
class StubDcPingStrategy(DcPingStrategy):
|
||||
""" For testing purpose. This class doesn't talk to the network.
|
||||
|
@ -63,6 +80,12 @@ class StubDcPingStrategy(DcPingStrategy):
|
|||
|
||||
return AdDomainNameValidation.OK
|
||||
|
||||
async def discover(self) -> str:
|
||||
return "ubuntu.com"
|
||||
|
||||
def has_support(self) -> bool:
|
||||
return True
|
||||
|
||||
|
||||
class ADController(SubiquityController):
|
||||
""" Implements the server part of the Active Directory feature. """
|
||||
|
@ -77,6 +100,15 @@ class ADController(SubiquityController):
|
|||
else:
|
||||
self.ping_strgy = DcPingStrategy()
|
||||
|
||||
def start(self):
|
||||
if self.ping_strgy.has_support():
|
||||
run_bg_task(self._try_discover_domain())
|
||||
|
||||
async def _try_discover_domain(self):
|
||||
discovered_domain = await self.ping_strgy.discover()
|
||||
if discovered_domain:
|
||||
self.model.set_domain(discovered_domain)
|
||||
|
||||
async def GET(self) -> Optional[ADConnectionInfo]:
|
||||
"""Returns the currently configured AD settings"""
|
||||
return self.model.conn_info
|
||||
|
@ -104,6 +136,11 @@ class ADController(SubiquityController):
|
|||
async def check_password_GET(self, password: str) -> AdPasswordValidation:
|
||||
return AdValidators.password(password)
|
||||
|
||||
async def has_support_GET(self) -> bool:
|
||||
""" Returns True if the executables required
|
||||
to configure AD are present in the live system."""
|
||||
return self.ping_strgy.has_support()
|
||||
|
||||
|
||||
# Helper out-of-class functions grouped.
|
||||
class AdValidators:
|
||||
|
|
|
@ -1659,8 +1659,8 @@ class TestActiveDirectory(TestAPI):
|
|||
async with start_server('examples/simple.json') as instance:
|
||||
endpoint = '/active_directory'
|
||||
ad_dict = await instance.get(endpoint)
|
||||
# Starts empty
|
||||
self.assertIsNone(ad_dict)
|
||||
# Starts with the detected domain.
|
||||
self.assertEqual('ubuntu.com', ad_dict['domain_name'])
|
||||
|
||||
# Post works by "returning None"
|
||||
ad_dict = {
|
||||
|
|
Loading…
Reference in New Issue