Checking how we can allow some TCs to use UDS as broker, i have detected some of them that asks for credentials when listing the machines. As UDS uses credentials to access the machine at the time the user access it (at time of listing, maybe that even the service is not created for that user), we can't provide credentials BEFORE assigning the machine.

In order to allow this kind of TCs to use UDS, we have implemented a mechanism that allows to know if a deployed service (or an service) transforms the credentials and, if so, the dispatcher for that TC can "skip" those services with that kind of os manager.
This commit is contained in:
Adolfo Gómez 2012-12-03 10:42:18 +00:00
parent 2716707952
commit baecf526a1
5 changed files with 82 additions and 4 deletions

View File

@ -116,6 +116,14 @@ class OSManager(Module):
''' '''
pass pass
@classmethod
def transformsUserOrPasswordForService(cls):
'''
Helper method that informs if the os manager transforms the username and/or the password.
This is used from DeployedService
'''
return cls.processUserPassword != OSManager.processUserPassword
def processUserPassword(self, service, username, password): def processUserPassword(self, service, username, password):
''' '''
This will be invoked prior to passsing username/password to Transport. This will be invoked prior to passsing username/password to Transport.

View File

@ -109,7 +109,7 @@ class Transport(Module):
''' '''
return cls.getConnectionInfo != Transport.getConnectionInfo return cls.getConnectionInfo != Transport.getConnectionInfo
def getConnectionInfo(self, userService, user, password): def getConnectionInfo(self, service, user, password):
''' '''
This method must provide information about connection. This method must provide information about connection.
We don't have to implement it, but if we wont to allow some types of connections We don't have to implement it, but if we wont to allow some types of connections
@ -117,7 +117,7 @@ class Transport(Module):
kind of terminals/application will not work kind of terminals/application will not work
Args: Args:
userService: DeployedUserService for witch we are rendering the connection (db model) userService: DeployedUserService for witch we are rendering the connection (db model), or DeployedService (db model)
user: user (dbUser) logged in user: user (dbUser) logged in
pass: password used in authentication pass: password used in authentication
@ -125,8 +125,14 @@ class Transport(Module):
'protocol': protocol to use, (there are a few standard defined in 'protocols.py', if yours does not fit those, use your own name 'protocol': protocol to use, (there are a few standard defined in 'protocols.py', if yours does not fit those, use your own name
'username': username (transformed if needed to) used to login to service 'username': username (transformed if needed to) used to login to service
'password': password (transformed if needed to) used to login to service 'password': password (transformed if needed to) used to login to service
'domain': domain (extracted from username or wherever) that will be used. (Not necesarily an AD domain)
:note: The provided service can be an user service or an deployed service (parent of user services).
I have implemented processUserPassword in both so in most cases we do not need if the service is
DeployedService or UserService. In case of processUserPassword for an DeployedService, no transformation
is done, because there is no relation at that level between user and service.
''' '''
return {'protocol': protocols.NONE, 'usename': '', 'password': ''} return {'protocol': protocols.NONE, 'username': '', 'password': '', 'domain': ''}
def renderForHtml(self, userService, id, ip, os, user, password): def renderForHtml(self, userService, id, ip, os, user, password):
''' '''

View File

@ -41,4 +41,5 @@ REMOTEFX = 'remotefx'
HDX = 'hdx' HDX = 'hdx'
ICA = 'ica' ICA = 'ica'
NX = 'nx' NX = 'nx'
X11 = 'x11' X11 = 'x11'
OTHER = 'other'

View File

@ -832,6 +832,20 @@ class DeployedService(models.Model):
except Exception: except Exception:
return None return None
def transformsUserOrPasswordForService(self):
return self.osmanager.getType().transformsUserOrPasswordForService()
def processUserPassword(self, username, password):
'''
This method is provided for consistency between UserService and DeployedService
There is no posibility to check the username and password that a user will use to
connect to a service at this level, because here there is no relation between both.
The only function of this method is allow Transport to transform username/password in
getConnectionInfo without knowing if it is requested by a DeployedService or an UserService
'''
return [username, password]
def setState(self, state, save = True): def setState(self, state, save = True):
''' '''
Updates the state of this object and, optionally, saves it Updates the state of this object and, optionally, saves it
@ -1280,7 +1294,31 @@ class UserService(models.Model):
''' '''
return self.getEnvironment().storage().get(name) return self.getEnvironment().storage().get(name)
def transformsUserOrPasswordForService(self):
'''
If the os manager changes the username or the password, this will return True
'''
return self.deployed_service.transformsUserOrPasswordForService()
def processUserPassword(self, username, password): def processUserPassword(self, username, password):
'''
Before accessing a service by a transport, we can request
the service to "transform" the username & password that the transport
will use to connect to that service.
This method is here so transport USE it before using the username/password
provided by user or by own transport configuration.
Args:
username: the username that will be used to connect to service
password: the password that will be used to connect to service
Return:
An array of two elements, first is transformed username, second is
transformed password.
:note: This method MUST be invoked by transport before using credentials passed to getHtml.
'''
ds = self.deployed_service ds = self.deployed_service
serviceInstance = ds.service.getInstance() serviceInstance = ds.service.getInstance()
if serviceInstance.needsManager is False: if serviceInstance.needsManager is False:

View File

@ -105,6 +105,31 @@ class RDPTransport(Transport):
self.cache().put(ip, 'N', READY_CACHE_TIMEOUT) self.cache().put(ip, 'N', READY_CACHE_TIMEOUT)
return ready == 'Y' return ready == 'Y'
def getConnectionInfo(self, service, user, password):
from uds.core.transports import protocols
username = user.getUsernameForAuth()
proc = username.split('@')
if len(proc) > 1:
domain = proc[1]
else:
domain = ''
username = proc[0]
if self._fixedName is not '':
username = self._fixedName
if self._fixedPassword is not '':
password = self._fixedPassword
if self._fixedDomain is not '':
domain = self._fixedDomain;
if self._useEmptyCreds is True:
username, password, domain = '','',''
username, password = service.processUserPassword(username, password)
return {'protocol': protocols.RDP, 'username': username, 'password': password, 'domain': domain}
def renderForHtml(self, userService, id, ip, os, user, password): def renderForHtml(self, userService, id, ip, os, user, password):
# We use helper to keep this clean # We use helper to keep this clean
username = user.getUsernameForAuth() username = user.getUsernameForAuth()