Merge remote-tracking branch 'origin/v3.5'

This commit is contained in:
Adolfo Gómez García 2021-10-15 10:58:11 +02:00
commit 11342914cc
5 changed files with 57 additions and 43 deletions

View File

@ -31,7 +31,7 @@ AppDir:
arch: amd64 arch: amd64
sources: sources:
- sourceline: 'deb [arch=amd64] http://ftp.de.debian.org/debian/ bullseye main contrib non-free' - sourceline: 'deb [arch=amd64] http://ftp.de.debian.org/debian/ bullseye main contrib non-free'
key_url: 'http://keyserver.ubuntu.com/pks/lookup?op=get&search=0x04EE7237B7D453EC' key_url: 'http://keyserver.ubuntu.com/pks/lookup?op=get&search=0x648ACFD622F3D138'
include: include:
- python3 - python3

View File

@ -183,7 +183,6 @@ class RestApi:
def _open( def _open(
url: str, certErrorCallback: typing.Optional[CertCallbackType] = None url: str, certErrorCallback: typing.Optional[CertCallbackType] = None
) -> typing.Any: ) -> typing.Any:
print('Open')
ctx = ssl.create_default_context() ctx = ssl.create_default_context()
ctx.check_hostname = False ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE ctx.verify_mode = ssl.CERT_NONE
@ -246,7 +245,6 @@ class RestApi:
def getUrl( def getUrl(
url: str, certErrorCallback: typing.Optional[CertCallbackType] = None url: str, certErrorCallback: typing.Optional[CertCallbackType] = None
) -> bytes: ) -> bytes:
print(url)
with RestApi._open(url, certErrorCallback) as response: with RestApi._open(url, certErrorCallback) as response:
resp = response.read() resp = response.read()

View File

@ -269,24 +269,6 @@ class Initialize(ActorV3Action):
state__in=[State.USABLE, State.PREPARING], state__in=[State.USABLE, State.PREPARING],
) )
# If no UserService exists,
# is managed (service exists), then it's a "local login"
if not dbFilter.exists() and service:
# The userService does not exists, try to lock the id on the service
serviceInstance = service.getInstance()
lockedId = serviceInstance.lockId(idsList)
if lockedId:
# Return an "generic" result allowing login/logout processing
return ActorV3Action.actorResult(
{
'own_token': self._params['token'],
'unique_id': lockedId,
'os': None,
}
)
else: # if no lock, return empty result
raise Exception() # Unmanaged host
userService: UserService = next( userService: UserService = next(
iter( iter(
dbFilter.filter( dbFilter.filter(
@ -442,7 +424,7 @@ class Version(ActorV3Action):
class LoginLogout(ActorV3Action): class LoginLogout(ActorV3Action):
name = 'notused' # Not really important, this is not a "leaf" class and will not be directly available name = 'notused' # Not really important, this is not a "leaf" class and will not be directly available
def notifyService(self, login: bool): def notifyService(self, isLogin: bool):
try: try:
# If unmanaged, use Service locator # If unmanaged, use Service locator
service: 'services.Service' = Service.objects.get( service: 'services.Service' = Service.objects.get(
@ -462,9 +444,11 @@ class LoginLogout(ActorV3Action):
if not validId: if not validId:
raise Exception() raise Exception()
# Recover Id Info from service and validId
# idInfo = service.recoverIdInfo(validId)
# Notify Service that someone logged in/out # Notify Service that someone logged in/out
if login: if isLogin:
# Try to guess if this is a remote session # Try to guess if this is a remote session
is_remote = self._params.get('session_type', '')[:4] in ('xrdp', 'RDP-') is_remote = self._params.get('session_type', '')[:4] in ('xrdp', 'RDP-')
service.processLogin(validId, remote_login=is_remote) service.processLogin(validId, remote_login=is_remote)
@ -536,7 +520,7 @@ class Login(LoginLogout):
except Exception: # If unamanaged host, lest do a bit more work looking for a service with the provided parameters... except Exception: # If unamanaged host, lest do a bit more work looking for a service with the provided parameters...
if isManaged: if isManaged:
raise raise
self.notifyService(login=True) self.notifyService(isLogin=True)
return ActorV3Action.actorResult( return ActorV3Action.actorResult(
{'ip': ip, 'hostname': hostname, 'dead_line': deadLine, 'max_idle': maxIdle} {'ip': ip, 'hostname': hostname, 'dead_line': deadLine, 'max_idle': maxIdle}
@ -579,7 +563,7 @@ class Logout(LoginLogout):
except Exception: # If unamanaged host, lest do a bit more work looking for a service with the provided parameters... except Exception: # If unamanaged host, lest do a bit more work looking for a service with the provided parameters...
if isManaged: if isManaged:
raise raise
self.notifyService(login=False) # Logout notification self.notifyService(isLogin=False) # Logout notification
return ActorV3Action.actorResult('ok') return ActorV3Action.actorResult('ok')
@ -663,6 +647,28 @@ class Unmanaged(ActorV3Action):
x['mac'] for x in self._params['id'] x['mac'] for x in self._params['id']
][:10] ][:10]
validId: typing.Optional[str] = service.getValidId(idsList) validId: typing.Optional[str] = service.getValidId(idsList)
# Check if there is already an assigned user service
# To notify it logout
userService: typing.Optional[UserService]
try:
dbFilter = UserService.objects.filter(
unique_id__in=idsList,
state__in=[State.USABLE, State.PREPARING],
)
userService = next(
iter(
dbFilter.filter(
unique_id__in=idsList,
state__in=[State.USABLE, State.PREPARING],
)
)
)
except StopIteration:
userService = None
# Try to infer the ip from the valid id (that could be an IP or a MAC)
ip: str ip: str
try: try:
ip = next( ip = next(
@ -681,7 +687,11 @@ class Unmanaged(ActorV3Action):
'password': password, 'password': password,
} }
if validId: if validId:
# Notify service of it "just start" action # If id is assigned to an user service, notify "logout" to it
if userService:
Logout.process_logout(userService, 'init')
else:
# If it is not assgined to an user service, notify service
service.notifyInitialization(validId) service.notifyInitialization(validId)
# Store certificate, secret & port with service if validId # Store certificate, secret & port with service if validId

View File

@ -322,22 +322,12 @@ class Service(Module):
""" """
return None return None
def lockId(self, id: typing.List[str]) -> typing.Optional[str]:
"""
Locks the id, so it cannot be used by a service pool.
Args:
id (typing.List[str]): Id to lock (list of possible ids)
Returns:
str: Valid id of locked element, or None if no id found
"""
return None
def processLogin(self, id: str, remote_login: bool) -> None: def processLogin(self, id: str, remote_login: bool) -> None:
""" """
In the case that a login is invoked directly on an actor controlled machine with In the case that a login is invoked directly on an actor controlled machine with
an service token, this method will be called with provided info by uds actor (parameters) an service token, this method will be called with provided info by uds actor (parameters)
That is, this method will only be called it UDS does not recognize the invoker, but the invoker
has a valid token and the service has recognized it. (via getValidId)
Args: Args:
id (str): Id validated through "getValidId" id (str): Id validated through "getValidId"
@ -347,12 +337,13 @@ class Service(Module):
def processLogout(self, id: str) -> None: def processLogout(self, id: str) -> None:
""" """
In the case that a login is invoked directly on an actor controlled machine with In the case that a logout is invoked directly on an actor controlled machine with
an service token, this method will be called with provided info by uds actor (parameters) an service token, this method will be called with provided info by uds actor (parameters)
That is, this method will only be called it UDS does not recognize the invoker, but the invoker
has a valid token and the service has recognized it. (via getValidId)
Args: Args:
id (str): Id validated through "getValidId" id (str): Id validated through "getValidId"
remote_login (bool): if the login seems to be a remote login
""" """
return return
@ -364,6 +355,7 @@ class Service(Module):
Args: Args:
id (str): Id validated through "getValidId" id (str): Id validated through "getValidId"
""" """
return
def storeIdInfo(self, id: str, data: typing.Any) -> None: def storeIdInfo(self, id: str, data: typing.Any) -> None:
self.storage.putPickle('__nfo_' + id, data) self.storage.putPickle('__nfo_' + id, data)

View File

@ -339,7 +339,10 @@ class IPMachinesService(IPServiceBase):
return userServiceInstance.error('IP already assigned') return userServiceInstance.error('IP already assigned')
def processLogin(self, id: str, remote_login: bool) -> None: def processLogin(self, id: str, remote_login: bool) -> None:
logger.info('Processing login for %s', id) '''
Process login for a machine not assigned to any user.
'''
logger.debug('Processing login for %s: %s', self, id)
# Locate the IP on the storage # Locate the IP on the storage
theIP = IPServiceBase.getIp(id) theIP = IPServiceBase.getIp(id)
now = getSqlDatetimeAsUnix() now = getSqlDatetimeAsUnix()
@ -348,7 +351,18 @@ class IPMachinesService(IPServiceBase):
self.storage.putPickle(id, now) # Lock it self.storage.putPickle(id, now) # Lock it
def processLogout(self, id: str) -> None: def processLogout(self, id: str) -> None:
logger.info('Processing logout for %s', id) '''
Process logout for a machine not assigned to any user.
'''
logger.debug('Processing logout for %s: %s', self, id)
self.unassignMachine(id)
def notifyInitialization(self, id: str) -> None:
'''
Notify that a machine has been initialized.
Normally, this means that
'''
logger.debug('Notify initialization for %s: %s', self, id)
self.unassignMachine(id) self.unassignMachine(id)
def getValidId(self, idsList: typing.Iterable[str]) -> typing.Optional[str]: def getValidId(self, idsList: typing.Iterable[str]) -> typing.Optional[str]: