forked from shaba/openuds
Merge remote-tracking branch 'origin/v3.5' into v3.6
This commit is contained in:
commit
e79753748e
@ -198,7 +198,7 @@ class UDSActorClient(threading.Thread): # pylint: disable=too-many-instance-att
|
||||
time.sleep(1.3) # Sleeps between loop iterations
|
||||
|
||||
self._loginInfo = None
|
||||
self.api.logout(platform.operations.getCurrentUser() + self._extraLogoff)
|
||||
self.api.logout(platform.operations.getCurrentUser() + self._extraLogoff, platform.operations.getSessionType())
|
||||
except Exception as e:
|
||||
logger.error('Error on client loop: %s', e)
|
||||
|
||||
|
@ -131,7 +131,7 @@ class UDSApi: # pylint: disable=too-few-public-methods
|
||||
headers=headers,
|
||||
verify=self._validateCert,
|
||||
timeout=TIMEOUT,
|
||||
proxies=NO_PROXY # type: ignore
|
||||
proxies=NO_PROXY # type: ignore
|
||||
if disableProxy
|
||||
else None, # if not proxies wanted, enforce it
|
||||
)
|
||||
@ -351,19 +351,21 @@ class UDSServerApi(UDSApi):
|
||||
actor_type: typing.Optional[str],
|
||||
token: str,
|
||||
username: str,
|
||||
sessionType: str,
|
||||
interfaces: typing.Iterable[types.InterfaceInfoType],
|
||||
secret: typing.Optional[str],
|
||||
) -> None:
|
||||
) -> typing.Optional[str]:
|
||||
if not token:
|
||||
return
|
||||
return None
|
||||
payload = {
|
||||
'type': actor_type or types.MANAGED,
|
||||
'id': [{'mac': i.mac, 'ip': i.ip} for i in interfaces],
|
||||
'token': token,
|
||||
'username': username,
|
||||
'session_type': sessionType,
|
||||
'secret': secret or '',
|
||||
}
|
||||
self._doPost('logout', payload)
|
||||
return self._doPost('logout', payload) # Can be 'ok' or 'notified'
|
||||
|
||||
def log(self, own_token: str, level: int, message: str) -> None:
|
||||
if not own_token:
|
||||
@ -418,8 +420,11 @@ class UDSClientApi(UDSApi):
|
||||
max_idle=result['max_idle'],
|
||||
)
|
||||
|
||||
def logout(self, username: str) -> None:
|
||||
payLoad = {'username': username}
|
||||
def logout(self, username: str, sessionType: typing.Optional[str]) -> None:
|
||||
payLoad = {
|
||||
'username': username,
|
||||
'session_type': sessionType or UNKNOWN
|
||||
}
|
||||
self.post('logout', payLoad)
|
||||
|
||||
def ping(self) -> bool:
|
||||
|
@ -377,6 +377,7 @@ class CommonService: # pylint: disable=too-many-instance-attributes
|
||||
self._cfg.actorType,
|
||||
self._cfg.own_token,
|
||||
'',
|
||||
'',
|
||||
self._interfaces,
|
||||
self._secret,
|
||||
)
|
||||
@ -494,9 +495,12 @@ class CommonService: # pylint: disable=too-many-instance-attributes
|
||||
# If unmanaged, do initialization now, because we don't know before this
|
||||
# Also, even if not initialized, get a "login" notification token
|
||||
if not self.isManaged():
|
||||
self.initialize()
|
||||
master_token = self._cfg.master_token
|
||||
secret = self._secret
|
||||
self._initialized = (
|
||||
self.initialize()
|
||||
) # Maybe it's a local login by an unmanaged host.... On real login, will execute initilize again
|
||||
if self._initialized:
|
||||
master_token = self._cfg.master_token
|
||||
secret = self._secret
|
||||
|
||||
# Own token will not be set if UDS did not assigned the initialized VM to an user
|
||||
# In that case, take master token (if machine is Unamanaged version)
|
||||
@ -518,7 +522,7 @@ class CommonService: # pylint: disable=too-many-instance-attributes
|
||||
|
||||
return result
|
||||
|
||||
def logout(self, username: str) -> None:
|
||||
def logout(self, username: str, sessionType: typing.Optional[str] = None) -> None:
|
||||
self._loggedIn = False
|
||||
|
||||
master_token = self._cfg.master_token
|
||||
@ -527,9 +531,20 @@ class CommonService: # pylint: disable=too-many-instance-attributes
|
||||
# In that case, take master token (if machine is Unamanaged version)
|
||||
token = self._cfg.own_token or master_token
|
||||
if token:
|
||||
self._api.logout(
|
||||
self._cfg.actorType, token, username, self._interfaces, self._secret
|
||||
)
|
||||
# If logout is not processed (that is, not ok result), the logout has not been processed
|
||||
if (
|
||||
self._api.logout(
|
||||
self._cfg.actorType,
|
||||
token,
|
||||
username,
|
||||
sessionType or '',
|
||||
self._interfaces,
|
||||
self._secret,
|
||||
)
|
||||
!= 'ok'
|
||||
):
|
||||
logger.info('Logout from %s ignored as required by uds broker', username)
|
||||
return
|
||||
|
||||
self.onLogout(username)
|
||||
|
||||
|
@ -419,7 +419,7 @@ class Version(ActorV3Action):
|
||||
class LoginLogout(ActorV3Action):
|
||||
name = 'notused' # Not really important, this is not a "leaf" class and will not be directly available
|
||||
|
||||
def notifyService(self, isLogin: bool):
|
||||
def notifyService(self, isLogin: bool) -> None:
|
||||
try:
|
||||
# If unmanaged, use Service locator
|
||||
service: 'services.Service' = Service.objects.get(
|
||||
@ -446,12 +446,12 @@ class LoginLogout(ActorV3Action):
|
||||
# idInfo = service.recoverIdInfo(validId)
|
||||
|
||||
# Notify Service that someone logged in/out
|
||||
is_remote = self._params.get('session_type', '')[:4] in ('xrdp', 'RDP-')
|
||||
if isLogin:
|
||||
# Try to guess if this is a remote session
|
||||
is_remote = self._params.get('session_type', '')[:4] in ('xrdp', 'RDP-')
|
||||
service.processLogin(validId, remote_login=is_remote)
|
||||
else:
|
||||
service.processLogout(validId)
|
||||
service.processLogout(validId, remote_login=is_remote)
|
||||
|
||||
# All right, service notified...
|
||||
except Exception:
|
||||
@ -562,6 +562,7 @@ class Logout(LoginLogout):
|
||||
if isManaged:
|
||||
raise
|
||||
self.notifyService(isLogin=False) # Logout notification
|
||||
return ActorV3Action.actorResult('notified') # Result is that we have not processed the logout in fact, but notified the service
|
||||
|
||||
return ActorV3Action.actorResult('ok')
|
||||
|
||||
|
@ -335,7 +335,7 @@ class Service(Module):
|
||||
"""
|
||||
return
|
||||
|
||||
def processLogout(self, id: str) -> None:
|
||||
def processLogout(self, id: str, remote_login: bool) -> None:
|
||||
"""
|
||||
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)
|
||||
|
@ -231,10 +231,13 @@ class IPMachinesService(IPServiceBase):
|
||||
# Sets maximum services for this
|
||||
self.maxDeployed = len(self._ips)
|
||||
|
||||
def canBeUsed(self, locked: typing.Optional[int], now: int) -> int:
|
||||
def canBeUsed(self, locked: typing.Optional[typing.Union[str, int]], now: int) -> int:
|
||||
# If _maxSessionForMachine is 0, it can be used only if not locked
|
||||
# (that is locked is None)
|
||||
locked = locked or 0
|
||||
if isinstance(locked, str) and not '.' in locked: # Convert to int and treat it as a "locked" element
|
||||
locked = int(locked)
|
||||
|
||||
if self._maxSessionForMachine <= 0:
|
||||
return not bool(locked) # If locked is None, it can be used
|
||||
|
||||
@ -342,19 +345,26 @@ class IPMachinesService(IPServiceBase):
|
||||
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
|
||||
theIP = IPServiceBase.getIp(id)
|
||||
now = getSqlDatetimeAsUnix()
|
||||
locked = self.storage.getPickle(theIP)
|
||||
locked: typing.Union[None, str, int] = self.storage.getPickle(theIP)
|
||||
if self.canBeUsed(locked, now):
|
||||
self.storage.putPickle(theIP, now) # Lock it
|
||||
self.storage.putPickle(theIP, str(now)) # Lock it
|
||||
|
||||
def processLogout(self, id: str) -> None:
|
||||
def processLogout(self, id: str, remote_login: bool) -> None:
|
||||
'''
|
||||
Process logout for a machine not assigned to any user.
|
||||
'''
|
||||
logger.debug('Processing logout for %s: %s', self, id)
|
||||
self.unassignMachine(id)
|
||||
# Locate the IP on the storage
|
||||
theIP = IPServiceBase.getIp(id)
|
||||
locked: typing.Union[None, str, int] = self.storage.getPickle(theIP)
|
||||
# If locked is str, has been locked by processLogin so we can unlock it
|
||||
if isinstance(locked, str):
|
||||
self.unassignMachine(id)
|
||||
# If not proccesed by login, we cannot release it
|
||||
|
||||
def notifyInitialization(self, id: str) -> None:
|
||||
'''
|
||||
|
Loading…
Reference in New Issue
Block a user