1
0
mirror of https://github.com/dkmstr/openuds.git synced 2024-12-25 23:21:41 +03:00

Added metapool support for UDS Tickets

This commit is contained in:
Adolfo Gómez García 2021-04-26 11:44:31 +02:00
parent 5355c7e420
commit 84ca0b2e41
3 changed files with 60 additions and 34 deletions

View File

@ -129,6 +129,9 @@ class Tickets(Handler):
userIp: typing.Optional[str] = self._params.get('userIp', None)
try:
servicePoolId = None
transportId = None
authId = self._params.get('authId', None)
authName = self._params.get('auth', None)
authTag = self._params.get('authTag', self._params.get('authSmallName', None))
@ -161,39 +164,61 @@ class Tickets(Handler):
realname: str = self._params.get('realname', self._params['username'])
if 'servicePool' in self._params:
servicePool: models.ServicePool = models.ServicePool.objects.get(uuid=processUuid(self._params['servicePool']))
# Check if is pool or metapool
poolUuid = processUuid(self._params['servicePool'])
pool : typing.Union[models.ServicePool, models.MetaPool]
# If forced that servicePool must honor groups
if force:
for addGrp in set(groupIds) - set(servicePool.assignedGroups.values_list('uuid', flat=True)):
servicePool.assignedGroups.add(auth.groups.get(uuid=addGrp))
try:
pool = typing.cast(models.MetaPool, models.MetaPool.objects.get(uuid=poolUuid)) # If not an metapool uuid, will process it as a servicePool
if force:
# First, add groups to metapool
for addGrp in set(groupIds) - set(pool.assignedGroups.values_list('uuid', flat=True)):
pool.assignedGroups.add(auth.groups.get(uuid=addGrp))
# And now, to ALL metapool members
for memberPool in pool.members.all():
# First, add groups to metapool
for addGrp in set(groupIds) - set(memberPool.assignedGroups.values_list('uuid', flat=True)):
memberPool.assignedGroups.add(auth.groups.get(uuid=addGrp))
# For metapool, transport is ignored..
if 'transport' in self._params:
transport: models.Transport = models.Transport.objects.get(uuid=processUuid(self._params['transport']))
try:
servicePool.validateTransport(transport)
except Exception:
logger.error('Transport %s is not valid for Service Pool %s', transport.name, servicePool.name)
raise Exception('Invalid transport for Service Pool')
else:
transport = models.Transport(uuid=None)
if userIp:
for v in servicePool.transports.order_by('priority'):
if v.validForIp(userIp):
transport = v
break
servicePoolId = 'M' + pool.uuid
transportId = 'meta'
except models.MetaPool.DoesNotExist:
pool = typing.cast(models.ServicePool, models.ServicePool.objects.get(uuid=poolUuid))
if transport.uuid is None:
logger.error('Service pool %s does not has valid transports for ip %s', servicePool.name, userIp)
raise Exception('Service pool does not has any valid transports for ip {}'.format(userIp))
# If forced that servicePool must honor groups
if force:
for addGrp in set(groupIds) - set(pool.assignedGroups.values_list('uuid', flat=True)):
pool.assignedGroups.add(auth.groups.get(uuid=addGrp))
servicePool = servicePool.uuid
transport = transport.uuid
if 'transport' in self._params:
transport: models.Transport = models.Transport.objects.get(uuid=processUuid(self._params['transport']))
try:
pool.validateTransport(transport)
except Exception:
logger.error('Transport %s is not valid for Service Pool %s', transport.name, pool.name)
raise Exception('Invalid transport for Service Pool')
else:
transport = models.Transport(uuid=None)
if userIp:
for v in pool.transports.order_by('priority'):
if v.validForIp(userIp):
transport = v
break
if transport.uuid is None:
logger.error('Service pool %s does not has valid transports for ip %s', pool.name, userIp)
raise Exception('Service pool does not has any valid transports for ip {}'.format(userIp))
servicePoolId = 'F' + pool.uuid
transportId = transport.uuid
except models.Authenticator.DoesNotExist:
return Tickets.result(error='Authenticator does not exists')
except models.ServicePool.DoesNotExist:
return Tickets.result(error='Service pool does not exists')
return Tickets.result(error='Service pool (or metapool) does not exists')
except models.Transport.DoesNotExist:
return Tickets.result(error='Transport does not exists')
except Exception as e:
@ -205,8 +230,8 @@ class Tickets(Handler):
'realname': realname,
'groups': groupIds,
'auth': auth.uuid,
'servicePool': servicePool,
'transport': transport,
'servicePool': servicePoolId,
'transport': transportId,
}
ticket = models.TicketStore.create(data)

View File

@ -656,13 +656,14 @@ class UserServiceManager:
if meta.isAccessAllowed() is False:
raise ServiceAccessDeniedByCalendar()
poolMembers = [p for p in meta.members.all() if p.pool.isVisible() and p.pool.isUsable()]
# Sort pools based on meta selection
if meta.policy == MetaPool.PRIORITY_POOL:
sortPools = [(p.priority, p.pool) for p in meta.members.all()]
sortPools = [(p.priority, p.pool) for p in poolMembers]
elif meta.policy == MetaPool.MOST_AVAILABLE_BY_NUMBER:
sortPools = [(p.usage(), p) for p in meta.pools.all()]
sortPools = [(p.usage(), p) for p in poolMembers]
else:
sortPools = [(random.randint(0, 10000), p) for p in meta.pools.all()] # Just shuffle them
sortPools = [(random.randint(0, 10000), p) for p in poolMembers] # Just shuffle them
# Sort pools related to policy now, and xtract only pools, not sort keys
# Remove "full" pools (100%) from result and pools in maintenance mode, not ready pools, etc...

View File

@ -183,7 +183,7 @@ def ticketAuth(request: 'HttpRequest', ticketId: str) -> HttpResponse: # pylint
groups = data['groups']
auth = data['auth']
realname = data['realname']
servicePool = data['servicePool']
poolUuid = data['servicePool']
password = cryptoManager().decrypt(data['password'])
transport = data['transport']
except Exception:
@ -220,12 +220,12 @@ def ticketAuth(request: 'HttpRequest', ticketId: str) -> HttpResponse: # pylint
# Override and recalc transport based on current os
transport = None
logger.debug("Service & transport: %s, %s", servicePool, transport)
logger.debug("Service & transport: %s, %s", poolUuid, transport)
# Check if servicePool is part of the ticket
if servicePool:
if poolUuid:
# If service pool is in there, also is transport
res = userServiceManager().getService(request.user, request.os, request.ip, 'F' + servicePool, transport, False)
res = userServiceManager().getService(request.user, request.os, request.ip, poolUuid, transport, False)
_, userService, _, transport, _ = res
transportInstance = transport.getInstance()