diff --git a/server/src/uds/REST/methods/client.py b/server/src/uds/REST/methods/client.py index f5b894120..b6a4f6b81 100644 --- a/server/src/uds/REST/methods/client.py +++ b/server/src/uds/REST/methods/client.py @@ -144,13 +144,17 @@ class Client(Handler): logger.debug('Res: %s %s %s %s %s', ip, userService, userServiceInstance, transport, transportInstance) password = cryptoManager().symDecrpyt(data['password'], scrambler) - # userService.setConnectionSource(srcIp, hostname) # Store where we are accessing from so we can notify Service - if not ip: - raise ServiceNotReadyError - # Set "accesedByClient" userService.setProperty('accessedByClient', '1') + # userService.setConnectionSource(srcIp, hostname) # Store where we are accessing from so we can notify Service + if not ip: + raise ServiceNotReadyError() + + # This should never happen, but it's here just in case + if not transportInstance: + raise Exception('No transport instance!!!') + transportScript, signature, params = transportInstance.getEncodedTransportScript(userService, transport, ip, self._request.os, self._request.user, password, self._request) logger.debug('Signature: %s', signature) diff --git a/server/src/uds/REST/methods/tickets.py b/server/src/uds/REST/methods/tickets.py index d5d7bd4c7..90e03b70f 100644 --- a/server/src/uds/REST/methods/tickets.py +++ b/server/src/uds/REST/methods/tickets.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # -# Copyright (c) 2014-2019 Virtual Cable S.L. +# Copyright (c) 2014-2021 Virtual Cable S.L.U. # All rights reserved. # # Redistribution and use in source and binary forms, with or without modification, @@ -45,9 +45,18 @@ from uds.core.util import tools logger = logging.getLogger(__name__) VALID_PARAMS = ( - 'authId', 'authTag', 'authSmallName', 'auth', 'username', - 'realname', 'password', 'groups', 'servicePool', 'transport', - 'force', 'userIp' + 'authId', + 'authTag', + 'authSmallName', + 'auth', + 'username', + 'realname', + 'password', + 'groups', + 'servicePool', + 'transport', + 'force', + 'userIp', ) @@ -72,10 +81,13 @@ class Tickets(Handler): - Groups exists on authenticator - servicePool has these groups in it's allowed list """ + needs_admin = True # By default, staff is lower level needed @staticmethod - def result(result: str = '', error: typing.Optional[str] = None) -> typing.Dict[str, typing.Any]: + def result( + result: str = '', error: typing.Optional[str] = None + ) -> typing.Dict[str, typing.Any]: """ Returns a result for a Ticket request """ @@ -112,7 +124,9 @@ class Tickets(Handler): raise RequestError('Invalid parameters (no auth)') # Must be invoked as '/rest/ticket/create, with "username", ("authId" or ("authSmallName" or "authTag"), "groups" (array) and optionally "time" (in seconds) as paramteres - def put(self): # pylint: disable=too-many-locals,too-many-branches,too-many-statements + def put( + self, + ): # pylint: disable=too-many-locals,too-many-branches,too-many-statements """ Processes put requests, currently only under "create" """ @@ -134,30 +148,48 @@ class Tickets(Handler): authId = self._params.get('authId', None) authName = self._params.get('auth', None) - authTag = self._params.get('authTag', self._params.get('authSmallName', None)) + authTag = self._params.get( + 'authTag', self._params.get('authSmallName', None) + ) # Will raise an exception if no auth found if authId: - auth = models.Authenticator.objects.get(uuid=processUuid(authId.lower())) + auth = models.Authenticator.objects.get( + uuid=processUuid(authId.lower()) + ) elif authName: auth = models.Authenticator.objects.get(name=authName) else: auth = models.Authenticator.objects.get(small_name=authTag) username: str = self._params['username'] - password: str = self._params.get('password', '') # Some machines needs password, depending on configuration + password: str = self._params.get( + 'password', '' + ) # Some machines needs password, depending on configuration groupIds: typing.List[str] = [] for groupName in tools.asList(self._params['groups']): try: groupIds.append(auth.groups.get(name=groupName).uuid) except Exception: - logger.info('Group %s from ticket does not exists on auth %s, forced creation: %s', groupName, auth, force) + logger.info( + 'Group %s from ticket does not exists on auth %s, forced creation: %s', + groupName, + auth, + force, + ) if force: # Force creation by call - groupIds.append(auth.groups.create(name=groupName, comments='Autocreated form ticket by using force paratemeter').uuid) + groupIds.append( + auth.groups.create( + name=groupName, + comments='Autocreated form ticket by using force paratemeter', + ).uuid + ) if not groupIds: # No valid group in groups names - raise RequestError('Authenticator does not contain ANY of the requested groups and force is not used') + raise RequestError( + 'Authenticator does not contain ANY of the requested groups and force is not used' + ) time = int(self._params.get('time', 60)) time = 60 if time < 1 else time @@ -166,39 +198,60 @@ class Tickets(Handler): if 'servicePool' in self._params: # Check if is pool or metapool poolUuid = processUuid(self._params['servicePool']) - pool : typing.Union[models.ServicePool, models.MetaPool] + pool: typing.Union[models.ServicePool, models.MetaPool] try: - pool = typing.cast(models.MetaPool, models.MetaPool.objects.get(uuid=poolUuid)) # If not an metapool uuid, will process it as a servicePool + 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)): + 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 metaMember in pool.members.all(): - # First, add groups to metapool - for addGrp in set(groupIds) - set(metaMember.pool.assignedGroups.values_list('uuid', flat=True)): - metaMember.assignedGroups.add(auth.groups.get(uuid=addGrp)) - + # Now add groups to pools + for addGrp in set(groupIds) - set( + metaMember.pool.assignedGroups.values_list( + 'uuid', flat=True + ) + ): + metaMember.pool.assignedGroups.add( + auth.groups.get(uuid=addGrp) + ) + # For metapool, transport is ignored.. servicePoolId = 'M' + pool.uuid transportId = 'meta' - + except models.MetaPool.DoesNotExist: - pool = typing.cast(models.ServicePool, models.ServicePool.objects.get(uuid=poolUuid)) + pool = typing.cast( + models.ServicePool, + models.ServicePool.objects.get(uuid=poolUuid), + ) # If forced that servicePool must honor groups if force: - for addGrp in set(groupIds) - set(pool.assignedGroups.values_list('uuid', flat=True)): + for addGrp in set(groupIds) - set( + pool.assignedGroups.values_list('uuid', flat=True) + ): pool.assignedGroups.add(auth.groups.get(uuid=addGrp)) if 'transport' in self._params: - transport: models.Transport = models.Transport.objects.get(uuid=processUuid(self._params['transport'])) + 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) + 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) @@ -209,12 +262,20 @@ class Tickets(Handler): 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)) + 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: diff --git a/server/src/uds/REST/methods/tunnel.py b/server/src/uds/REST/methods/tunnel.py index 2e25b6981..3c5e3ab1c 100644 --- a/server/src/uds/REST/methods/tunnel.py +++ b/server/src/uds/REST/methods/tunnel.py @@ -134,8 +134,8 @@ class TunnelTicket(Handler): port=port, host=host, extra={ - 't': self._args[0], # ticket - 'b': models.getSqlDatetimeAsUnix(), # Begin time stamp + 't': self._args[0], # ticket + 'b': models.getSqlDatetimeAsUnix(), # Begin time stamp }, validity=MAX_SESSION_LENGTH, ) diff --git a/server/src/uds/REST/methods/tunnel_token.py b/server/src/uds/REST/methods/tunnel_token.py index 9ab4c1028..9812ac036 100644 --- a/server/src/uds/REST/methods/tunnel_token.py +++ b/server/src/uds/REST/methods/tunnel_token.py @@ -42,9 +42,6 @@ from uds.core.util import permissions logger = logging.getLogger(__name__) -# Enclosed methods under /osm path - - class TunnelTokens(ModelHandler): model = TunnelToken diff --git a/server/src/uds/core/util/config.py b/server/src/uds/core/util/config.py index 6038cbaec..6c1ddd5f9 100644 --- a/server/src/uds/core/util/config.py +++ b/server/src/uds/core/util/config.py @@ -377,7 +377,7 @@ class GlobalConfig: 'maxInitTime', '3601', type=Config.NUMERIC_FIELD ) MAX_REMOVAL_TIME: Config.Value = Config.section(GLOBAL_SECTION).value( - 'maxRemovalTime', '86400', type=Config.NUMERIC_FIELD + 'maxRemovalTime', '14400', type=Config.NUMERIC_FIELD ) # Maximum logs per user service MAX_LOGS_PER_ELEMENT: Config.Value = Config.section(GLOBAL_SECTION).value( diff --git a/server/src/uds/core/util/xml2dict.py b/server/src/uds/core/util/xml2dict.py index aa9b0ded1..ba301789d 100644 --- a/server/src/uds/core/util/xml2dict.py +++ b/server/src/uds/core/util/xml2dict.py @@ -34,9 +34,12 @@ import typing from collections import defaultdict from xml.etree import cElementTree +if typing.TYPE_CHECKING: + from xml.etree.cElementTree import Element -def etree_to_dict(t): - d = {} + +def etree_to_dict(t: 'Element') -> typing.Mapping[str, typing.Any]: + d: typing.MutableMapping[str, typing.Any] = {} if t.attrib: d.update({t.tag: {}}) @@ -59,5 +62,5 @@ def etree_to_dict(t): return d -def parse(xml_string: str) -> typing.Dict: +def parse(xml_string: str) -> typing.Mapping[str, typing.Any]: return etree_to_dict(cElementTree.XML(xml_string)) diff --git a/server/src/uds/services/OpenNebula/on/client.py b/server/src/uds/services/OpenNebula/on/client.py index df52f8d3a..db7af2048 100644 --- a/server/src/uds/services/OpenNebula/on/client.py +++ b/server/src/uds/services/OpenNebula/on/client.py @@ -66,7 +66,7 @@ def checkResultRaw(lst: typing.Any) -> str: return str(lst[1]) -def checkResult(lst: typing.Any) -> typing.Tuple[typing.Dict, str]: +def checkResult(lst: typing.Any) -> typing.Tuple[typing.Mapping[str, typing.Any], str]: return xml2dict.parse(checkResultRaw(lst)), lst[1] diff --git a/server/src/uds/services/OpenNebula/on/common.py b/server/src/uds/services/OpenNebula/on/common.py index 38d77accf..624c7d96c 100644 --- a/server/src/uds/services/OpenNebula/on/common.py +++ b/server/src/uds/services/OpenNebula/on/common.py @@ -39,7 +39,7 @@ import logging logger = logging.getLogger(__name__) # module = sys.modules[__name__] -def sanitizeName(name): +def sanitizeName(name: str) -> str: """ machine names with [a-zA-Z0-9_-] """