1
0
mirror of https://github.com/dkmstr/openuds.git synced 2025-03-20 06:50:23 +03:00

Added correcto management of "logout" in case of an unmanaged machine "reboot"

This commit is contained in:
Adolfo Gómez García 2021-10-08 12:28:37 +02:00
parent 6f99b63731
commit cd640af37f
3 changed files with 41 additions and 36 deletions

View File

@ -269,24 +269,6 @@ class Initialize(ActorV3Action):
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(
iter(
dbFilter.filter(
@ -657,12 +639,35 @@ class Unmanaged(ActorV3Action):
except Exception:
return ActorV3Action.actorResult(error='Invalid token')
# Build the possible ids and ask service if it recognizes any of it
# If not recognized, will generate anyway the certificate, but will not be saved
idsList = [x['ip'] for x in self._params['id']] + [
x['mac'] for x in self._params['id']
][:10]
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
try:
ip = next(
@ -681,8 +686,12 @@ class Unmanaged(ActorV3Action):
'password': password,
}
if validId:
# Notify service of it "just start" action
service.notifyInitialization(validId)
# 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)
# Store certificate, secret & port with service if validId
service.storeIdInfo(

View File

@ -322,22 +322,12 @@ class Service(Module):
"""
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:
"""
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)
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:
id (str): Id validated through "getValidId"
@ -347,12 +337,13 @@ class Service(Module):
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)
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:
id (str): Id validated through "getValidId"
remote_login (bool): if the login seems to be a remote login
"""
return
@ -364,6 +355,7 @@ class Service(Module):
Args:
id (str): Id validated through "getValidId"
"""
return
def storeIdInfo(self, id: str, data: typing.Any) -> None:
self.storage.putPickle('__nfo_' + id, data)

View File

@ -339,7 +339,7 @@ class IPMachinesService(IPServiceBase):
return userServiceInstance.error('IP already assigned')
def processLogin(self, id: str, remote_login: bool) -> None:
logger.info('Processing login for %s', id)
logger.debug('Processing login for %s: %s', self, id)
# Locate the IP on the storage
theIP = IPServiceBase.getIp(id)
now = getSqlDatetimeAsUnix()
@ -348,7 +348,11 @@ class IPMachinesService(IPServiceBase):
self.storage.putPickle(id, now) # Lock it
def processLogout(self, id: str) -> None:
logger.info('Processing logout for %s', id)
logger.debug('Processing logout for %s: %s', self, id)
self.unassignMachine(id)
def notifyInitialization(self, id: str) -> None:
logger.debug('Notify initialization for %s: %s', self, id)
self.unassignMachine(id)
def getValidId(self, idsList: typing.Iterable[str]) -> typing.Optional[str]: