1
0
mirror of https://github.com/dkmstr/openuds.git synced 2024-12-22 13:34:04 +03:00

more linting and refactoring uds.core.managers to remove functions

This commit is contained in:
Adolfo Gómez García 2023-04-19 16:20:30 +02:00
parent cfab4fd29b
commit 60fd7edc7b
No known key found for this signature in database
GPG Key ID: DD1ABF20724CDA23
29 changed files with 354 additions and 307 deletions

View File

@ -51,7 +51,9 @@ if typing.TYPE_CHECKING:
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
AUTH_TOKEN_HEADER: typing.Final[str] = 'HTTP_X_AUTH_TOKEN' # nosec: this is not a password AUTH_TOKEN_HEADER: typing.Final[
str
] = 'HTTP_X_AUTH_TOKEN' # nosec: this is not a password
class Handler: class Handler:
@ -102,9 +104,8 @@ class Handler:
method: str, method: str,
params: typing.MutableMapping[str, typing.Any], params: typing.MutableMapping[str, typing.Any],
*args: str, *args: str,
**kwargs **kwargs,
): ):
logger.debug( logger.debug(
'Data: %s %s %s', self.__class__, self.needs_admin, self.authenticated 'Data: %s %s %s', self.__class__, self.needs_admin, self.authenticated
) )
@ -151,7 +152,6 @@ class Handler:
else: else:
self._user = User() # Empty user for non authenticated handlers self._user = User() # Empty user for non authenticated handlers
def headers(self) -> typing.Dict[str, str]: def headers(self) -> typing.Dict[str, str]:
""" """
Returns the headers of the REST request (all) Returns the headers of the REST request (all)
@ -183,6 +183,27 @@ class Handler:
except Exception: # nosec: intentionally ingoring exception except Exception: # nosec: intentionally ingoring exception
pass # If not found, just ignore it pass # If not found, just ignore it
@property
def request(self) -> 'ExtendedHttpRequestWithUser':
"""
Returns the request object
"""
return self._request
@property
def params(self) -> typing.Any:
"""
Returns the params object
"""
return self._params
@property
def args(self) -> typing.Tuple[str, ...]:
"""
Returns the args object
"""
return self._args
# Auth related # Auth related
def getAuthToken(self) -> typing.Optional[str]: def getAuthToken(self) -> typing.Optional[str]:
""" """
@ -215,7 +236,9 @@ class Handler:
staff_member = True # Make admins also staff members :-) staff_member = True # Make admins also staff members :-)
# crypt password and convert to base64 # crypt password and convert to base64
passwd = codecs.encode(cryptoManager().symCrypt(password, scrambler), 'base64').decode() passwd = codecs.encode(
cryptoManager().symCrypt(password, scrambler), 'base64'
).decode()
session['REST'] = { session['REST'] = {
'auth': id_auth, 'auth': id_auth,

View File

@ -64,13 +64,13 @@ class ActorTokens(ModelHandler):
def item_as_dict(self, item: ActorToken) -> typing.Dict[str, typing.Any]: def item_as_dict(self, item: ActorToken) -> typing.Dict[str, typing.Any]:
return { return {
'id': item.token, 'id': item.token,
'name': _('Token isued by {} from {}').format( 'name': str(_('Token isued by {} from {}')).format(
item.username, item.hostname or item.ip item.username, item.hostname or item.ip
), ),
'stamp': item.stamp, 'stamp': item.stamp,
'username': item.username, 'username': item.username,
'ip': item.ip, 'ip': item.ip,
'host': '{} - {}'.format(item.ip, item.mac), 'host': f'{item.ip} - {item.mac}',
'hostname': item.hostname, 'hostname': item.hostname,
'pre_command': item.pre_command, 'pre_command': item.pre_command,
'post_command': item.post_command, 'post_command': item.post_command,
@ -92,6 +92,6 @@ class ActorTokens(ModelHandler):
try: try:
self.model.objects.get(token=self._args[0]).delete() self.model.objects.get(token=self._args[0]).delete()
except self.model.DoesNotExist: except self.model.DoesNotExist:
raise NotFound('Element do not exists') raise NotFound('Element do not exists') from None
return OK return OK

View File

@ -44,7 +44,8 @@ from uds.models import (
) )
# from uds.core import VERSION # from uds.core import VERSION
from uds.core.managers import userServiceManager, cryptoManager from uds.core.managers.user_service import UserServiceManager
from uds.core.managers.crypto import CryptoManager
from uds.core import osmanagers from uds.core import osmanagers
from uds.core.util import log, security from uds.core.util import log, security
from uds.core.util.state import State from uds.core.util.state import State
@ -107,7 +108,7 @@ def clearIfSuccess(func: typing.Callable) -> typing.Callable:
result = func( result = func(
*args, **kwargs *args, **kwargs
) # If raises any exception, it will be raised and we will not clear the counter ) # If raises any exception, it will be raised and we will not clear the counter
clearFailedIp(_self._request) clearFailedIp(_self._request) # pylint: disable=protected-access
return result return result
return wrapper return wrapper
@ -357,7 +358,7 @@ class Initialize(ActorV3Action):
if service and not alias_token: # Is a service managed by UDS if service and not alias_token: # Is a service managed by UDS
# Create a new alias for it, and save # Create a new alias for it, and save
alias_token = ( alias_token = (
cryptoManager().randomString(40) CryptoManager().randomString(40)
) # fix alias with new token ) # fix alias with new token
service.aliases.create(alias=alias_token) service.aliases.create(alias=alias_token)
@ -366,7 +367,7 @@ class Initialize(ActorV3Action):
userService.uuid, userService.unique_id, osData, alias_token userService.uuid, userService.unique_id, osData, alias_token
) )
except (ActorToken.DoesNotExist, Service.DoesNotExist): except (ActorToken.DoesNotExist, Service.DoesNotExist):
raise BlockAccess() raise BlockAccess() from None
class BaseReadyChange(ActorV3Action): class BaseReadyChange(ActorV3Action):
@ -415,7 +416,7 @@ class BaseReadyChange(ActorV3Action):
if osManager: if osManager:
osManager.toReady(userService) osManager.toReady(userService)
userServiceManager().notifyReadyFromOsManager(userService, '') UserServiceManager().notifyReadyFromOsManager(userService, '')
# Generates a certificate and send it to client. # Generates a certificate and send it to client.
privateKey, cert, password = security.selfSignedCert(self._params['ip']) privateKey, cert, password = security.selfSignedCert(self._params['ip'])

View File

@ -154,7 +154,7 @@ class Authenticators(ModelHandler):
raise Exception() # Not found raise Exception() # Not found
except Exception as e: except Exception as e:
logger.info('Type not found: %s', e) logger.info('Type not found: %s', e)
raise NotFound('type not found') raise NotFound('type not found') from e
def item_as_dict(self, item: Authenticator) -> typing.Dict[str, typing.Any]: def item_as_dict(self, item: Authenticator) -> typing.Dict[str, typing.Any]:
type_ = item.getType() type_ = item.getType()
@ -214,7 +214,6 @@ class Authenticators(ModelHandler):
if type_ == 'user': if type_ == 'user':
return list(auth.searchUsers(term))[:limit] return list(auth.searchUsers(term))[:limit]
else:
return list(auth.searchGroups(term))[:limit] return list(auth.searchGroups(term))[:limit]
except Exception as e: except Exception as e:
logger.exception('Too many results: %s', e) logger.exception('Too many results: %s', e)
@ -222,11 +221,9 @@ class Authenticators(ModelHandler):
# self.invalidResponseException('{}'.format(e)) # self.invalidResponseException('{}'.format(e))
def test(self, type_: str): def test(self, type_: str):
from uds.core.environment import Environment
authType = auths.factory().lookup(type_) authType = auths.factory().lookup(type_)
if not authType: if not authType:
raise self.invalidRequestException('Invalid type: {}'.format(type_)) raise self.invalidRequestException(f'Invalid type: {type_}')
dct = self._params.copy() dct = self._params.copy()
dct['_request'] = self._request dct['_request'] = self._request

View File

@ -39,7 +39,8 @@ from uds.REST import RequestError
from uds.models import TicketStore from uds.models import TicketStore
from uds.models import User from uds.models import User
from uds.web.util import errors from uds.web.util import errors
from uds.core.managers import cryptoManager, userServiceManager from uds.core.managers.user_service import UserServiceManager
from uds.core.managers.crypto import CryptoManager
from uds.core.util.config import GlobalConfig from uds.core.util.config import GlobalConfig
from uds.core.services.exceptions import ServiceNotReadyError from uds.core.services.exceptions import ServiceNotReadyError
from uds.core import VERSION as UDS_VERSION, REQUIRED_CLIENT_VERSION from uds.core import VERSION as UDS_VERSION, REQUIRED_CLIENT_VERSION
@ -140,7 +141,7 @@ class Client(Handler):
userServiceInstance, userServiceInstance,
transport, transport,
transportInstance, transportInstance,
) = userServiceManager().getService( ) = UserServiceManager().getService(
self._request.user, self._request.user,
self._request.os, self._request.os,
self._request.ip, self._request.ip,
@ -156,7 +157,7 @@ class Client(Handler):
transport, transport,
transportInstance, transportInstance,
) )
password = cryptoManager().symDecrpyt(data['password'], scrambler) password = CryptoManager().symDecrpyt(data['password'], scrambler)
# userService.setConnectionSource(srcIp, hostname) # Store where we are accessing from so we can notify Service # userService.setConnectionSource(srcIp, hostname) # Store where we are accessing from so we can notify Service
if not ip: if not ip:

View File

@ -37,8 +37,8 @@ from uds.core.util.request import ExtendedHttpRequestWithUser
from uds.REST import Handler from uds.REST import Handler
from uds.REST import RequestError from uds.REST import RequestError
from uds.core.managers import userServiceManager from uds.core.managers.user_service import UserServiceManager
from uds.core.managers import cryptoManager from uds.core.managers.crypto import CryptoManager
from uds.core.services.exceptions import ServiceNotReadyError from uds.core.services.exceptions import ServiceNotReadyError
from uds.core.util.rest.tools import match from uds.core.util.rest.tools import match
from uds.web.util import errors, services from uds.web.util import errors, services
@ -103,7 +103,7 @@ class Connection(Handler):
_, # iads, _, # iads,
_, #trans, _, #trans,
itrans, itrans,
) = userServiceManager().getService( # pylint: disable=unused-variable ) = UserServiceManager().getService( # pylint: disable=unused-variable
self._user, self._user,
self._request.os, self._request.os,
self._request.ip, self._request.ip,
@ -132,7 +132,7 @@ class Connection(Handler):
def script(self, idService: str, idTransport: str, scrambler: str, hostname: str) -> typing.Dict[str, typing.Any]: def script(self, idService: str, idTransport: str, scrambler: str, hostname: str) -> typing.Dict[str, typing.Any]:
try: try:
res = userServiceManager().getService( res = UserServiceManager().getService(
self._user, self._request.os, self._request.ip, idService, idTransport self._user, self._request.os, self._request.ip, idService, idTransport
) )
logger.debug('Res: %s', res) logger.debug('Res: %s', res)
@ -143,7 +143,7 @@ class Connection(Handler):
transport, transport,
transportInstance, transportInstance,
) = res # pylint: disable=unused-variable ) = res # pylint: disable=unused-variable
password = cryptoManager().symDecrpyt(self.getValue('password'), scrambler) password = CryptoManager().symDecrpyt(self.getValue('password'), scrambler)
userService.setConnectionSource( userService.setConnectionSource(
self._request.ip, hostname self._request.ip, hostname

View File

@ -63,7 +63,7 @@ from uds.models.calendar_action import (
CALENDAR_ACTION_REMOVE_STUCK_USERSERVICES, CALENDAR_ACTION_REMOVE_STUCK_USERSERVICES,
) )
from uds.core.managers import userServiceManager from uds.core.managers.user_service import UserServiceManager
from uds.core.ui.images import DEFAULT_THUMB_BASE64 from uds.core.ui.images import DEFAULT_THUMB_BASE64
from uds.core.util.state import State from uds.core.util.state import State
from uds.core.util.model import processUuid from uds.core.util.model import processUuid
@ -225,8 +225,8 @@ class ServicesPools(ModelHandler):
state = item.state state = item.state
if item.isInMaintenance(): if item.isInMaintenance():
state = State.MAINTENANCE state = State.MAINTENANCE
# This needs a lot of queries, and really does not shows anything important i think... # This needs a lot of queries, and really does not apport anything important to the report
# elif userServiceManager().canInitiateServiceFromDeployedService(item) is False: # elif UserServiceManager().canInitiateServiceFromDeployedService(item) is False:
# state = State.SLOWED_DOWN # state = State.SLOWED_DOWN
val = { val = {
'id': item.uuid, 'id': item.uuid,
@ -506,16 +506,17 @@ class ServicesPools(ModelHandler):
return g return g
def beforeSave( # pylint: disable=too-many-statements
self, fields: typing.Dict[str, typing.Any] def beforeSave(self, fields: typing.Dict[str, typing.Any]) -> None:
) -> None: # pylint: disable=too-many-branches,too-many-statements
# logger.debug(self._params) # logger.debug(self._params)
try: try:
try: try:
service = Service.objects.get(uuid=processUuid(fields['service_id'])) service = Service.objects.get(uuid=processUuid(fields['service_id']))
fields['service_id'] = service.id fields['service_id'] = service.id
except: except Exception:
raise RequestError(gettext('Base service does not exist anymore')) raise RequestError(
gettext('Base service does not exist anymore')
) from None
try: try:
serviceType = service.getType() serviceType = service.getType()
@ -551,7 +552,9 @@ class ServicesPools(ModelHandler):
): ):
fields[k] = 0 fields[k] = 0
else: # uses cache, adjust values else: # uses cache, adjust values
fields['max_srvs'] = int(fields['max_srvs']) or 1 # ensure max_srvs is at least 1 fields['max_srvs'] = (
int(fields['max_srvs']) or 1
) # ensure max_srvs is at least 1
fields['initial_srvs'] = int(fields['initial_srvs']) fields['initial_srvs'] = int(fields['initial_srvs'])
fields['cache_l1_srvs'] = int(fields['cache_l1_srvs']) fields['cache_l1_srvs'] = int(fields['cache_l1_srvs'])
@ -565,10 +568,10 @@ class ServicesPools(ModelHandler):
fields['cache_l1_srvs'] = min( fields['cache_l1_srvs'] = min(
fields['cache_l1_srvs'], serviceType.maxDeployed fields['cache_l1_srvs'], serviceType.maxDeployed
) )
except Exception as e:
raise RequestError(
except Exception: gettext('This service requires an OS Manager')
raise RequestError(gettext('This service requires an OS Manager')) ) from e
# If max < initial or cache_1 or cache_l2 # If max < initial or cache_1 or cache_l2
fields['max_srvs'] = max( fields['max_srvs'] = max(
@ -618,14 +621,14 @@ class ServicesPools(ModelHandler):
except (RequestError, ResponseError): except (RequestError, ResponseError):
raise raise
except Exception as e: except Exception as e:
raise RequestError(str(e)) raise RequestError(str(e)) from e
def afterSave(self, item: ServicePool) -> None: def afterSave(self, item: ServicePool) -> None:
if self._params.get('publish_on_save', False) is True: if self._params.get('publish_on_save', False) is True:
try: try:
item.publish() item.publish()
except Exception as e: except Exception as e:
logger.error('Could not publish service pool %s: %s',item.name, e) logger.error('Could not publish service pool %s: %s', item.name, e)
def deleteItem(self, item: ServicePool) -> None: def deleteItem(self, item: ServicePool) -> None:
try: try:
@ -679,7 +682,7 @@ class ServicesPools(ModelHandler):
CALENDAR_ACTION_DEL_ALL_TRANSPORTS, CALENDAR_ACTION_DEL_ALL_TRANSPORTS,
CALENDAR_ACTION_ADD_GROUP, CALENDAR_ACTION_ADD_GROUP,
CALENDAR_ACTION_DEL_GROUP, CALENDAR_ACTION_DEL_GROUP,
CALENDAR_ACTION_DEL_ALL_GROUPS CALENDAR_ACTION_DEL_ALL_GROUPS,
) )
# Advanced actions # Advanced actions
@ -699,7 +702,7 @@ class ServicesPools(ModelHandler):
return self.invalidRequestException('Invalid parameters') return self.invalidRequestException('Invalid parameters')
logger.debug('Creating from assignable: %s', self._params) logger.debug('Creating from assignable: %s', self._params)
userServiceManager().createFromAssignable( UserServiceManager().createFromAssignable(
item, item,
User.objects.get(uuid=processUuid(self._params['user_id'])), User.objects.get(uuid=processUuid(self._params['user_id'])),
self._params['assignable_id'], self._params['assignable_id'],

View File

@ -58,7 +58,7 @@ class TunnelTokens(ModelHandler):
def item_as_dict(self, item: TunnelToken) -> typing.Dict[str, typing.Any]: def item_as_dict(self, item: TunnelToken) -> typing.Dict[str, typing.Any]:
return { return {
'id': item.token, 'id': item.token,
'name': _('Token isued by {} from {}').format(item.username, item.ip), 'name': str(_('Token isued by {} from {}')).format(item.username, item.ip),
'stamp': item.stamp, 'stamp': item.stamp,
'username': item.username, 'username': item.username,
'ip': item.ip, 'ip': item.ip,
@ -80,6 +80,6 @@ class TunnelTokens(ModelHandler):
try: try:
self.model.objects.get(token=self._args[0]).delete() self.model.objects.get(token=self._args[0]).delete()
except self.model.DoesNotExist: except self.model.DoesNotExist:
raise NotFound('Element do not exists') raise NotFound('Element do not exists') from None
return OK return OK

View File

@ -39,7 +39,7 @@ from uds import models
from uds.core.util.state import State from uds.core.util.state import State
from uds.core.util.model import processUuid from uds.core.util.model import processUuid
from uds.core.util import log, permissions from uds.core.util import log, permissions
from uds.core.managers import userServiceManager from uds.core.managers.user_service import UserServiceManager
from uds.REST.model import DetailHandler from uds.REST.model import DetailHandler
from uds.REST import ResponseError from uds.REST import ResponseError
@ -125,9 +125,9 @@ class AssignedService(DetailHandler):
return AssignedService.itemToDict( return AssignedService.itemToDict(
parent.assignedUserServices().get(processUuid(uuid=processUuid(item))) parent.assignedUserServices().get(processUuid(uuid=processUuid(item)))
) )
except Exception: except Exception as e:
logger.exception('getItems') logger.exception('getItems')
raise self.invalidItemException() raise self.invalidItemException() from e
def getTitle(self, parent: models.ServicePool) -> str: def getTitle(self, parent: models.ServicePool) -> str:
return _('Assigned services') return _('Assigned services')
@ -164,8 +164,8 @@ class AssignedService(DetailHandler):
) )
logger.debug('Getting logs for %s', userService) logger.debug('Getting logs for %s', userService)
return log.getLogs(userService) return log.getLogs(userService)
except Exception: except Exception as e:
raise self.invalidItemException() raise self.invalidItemException() from e
# This is also used by CachedService, so we use "userServices" directly and is valid for both # This is also used by CachedService, so we use "userServices" directly and is valid for both
def deleteItem(self, parent: models.ServicePool, item: str) -> None: def deleteItem(self, parent: models.ServicePool, item: str) -> None:
@ -173,20 +173,14 @@ class AssignedService(DetailHandler):
userService: models.UserService = parent.userServices.get( userService: models.UserService = parent.userServices.get(
uuid=processUuid(item) uuid=processUuid(item)
) )
except Exception: except Exception as e:
logger.exception('deleteItem') logger.exception('deleteItem')
raise self.invalidItemException() raise self.invalidItemException() from e
if userService.user: if userService.user:
logStr = 'Deleted assigned service {} to user {} by {}'.format( logStr = f'Deleted assigned service {userService.friendly_name} to user {userService.user.pretty_name} by {self._user.pretty_name}'
userService.friendly_name,
userService.user.pretty_name,
self._user.pretty_name,
)
else: else:
logStr = 'Deleted cached service {} by {}'.format( logStr = f'Deleted cached service {userService.friendly_name} by {self._user.pretty_name}'
userService.friendly_name, self._user.pretty_name
)
if userService.state in (State.USABLE, State.REMOVING): if userService.state in (State.USABLE, State.REMOVING):
userService.remove() userService.remove()
@ -207,9 +201,7 @@ class AssignedService(DetailHandler):
userService = parent.userServices.get(uuid=processUuid(item)) userService = parent.userServices.get(uuid=processUuid(item))
user = models.User.objects.get(uuid=processUuid(fields['user_id'])) user = models.User.objects.get(uuid=processUuid(fields['user_id']))
logStr = 'Changing ownership of service from {} to {} by {}'.format( logStr = f'Changed ownership of service {userService.friendly_name} from {userService.user} to {user.pretty_name} by {self._user.pretty_name}'
userService.user, user.pretty_name, self._user.pretty_name
)
# If there is another service that has this same owner, raise an exception # If there is another service that has this same owner, raise an exception
if ( if (
@ -220,9 +212,7 @@ class AssignedService(DetailHandler):
> 0 > 0
): ):
raise self.invalidResponseException( raise self.invalidResponseException(
'There is already another user service assigned to {}'.format( f'There is already another user service assigned to {user.pretty_name}'
user.pretty_name
)
) )
userService.user = user # type: ignore userService.user = user # type: ignore
@ -233,7 +223,7 @@ class AssignedService(DetailHandler):
def reset(self, parent: 'models.ServicePool', item: str) -> typing.Any: def reset(self, parent: 'models.ServicePool', item: str) -> typing.Any:
userService = parent.userServices.get(uuid=processUuid(item)) userService = parent.userServices.get(uuid=processUuid(item))
userServiceManager().reset(userService) UserServiceManager().reset(userService)
class CachedService(AssignedService): class CachedService(AssignedService):
@ -259,9 +249,9 @@ class CachedService(AssignedService):
uuid=processUuid(item) uuid=processUuid(item)
) )
return AssignedService.itemToDict(cachedService, True) return AssignedService.itemToDict(cachedService, True)
except Exception: except Exception as e:
logger.exception('getItems') logger.exception('getItems')
raise self.invalidItemException() raise self.invalidItemException() from e
def getTitle(self, parent: models.ServicePool) -> str: def getTitle(self, parent: models.ServicePool) -> str:
return _('Cached services') return _('Cached services')
@ -290,7 +280,7 @@ class CachedService(AssignedService):
logger.debug('Getting logs for %s', item) logger.debug('Getting logs for %s', item)
return log.getLogs(userService) return log.getLogs(userService)
except Exception: except Exception:
raise self.invalidItemException() raise self.invalidItemException() from None
class Groups(DetailHandler): class Groups(DetailHandler):
@ -351,7 +341,7 @@ class Groups(DetailHandler):
log.doLog( log.doLog(
parent, parent,
log.INFO, log.INFO,
"Added group {} by {}".format(group.pretty_name, self._user.pretty_name), f'Added group {group.pretty_name} by {self._user.pretty_name}',
log.ADMIN, log.ADMIN,
) )
@ -361,7 +351,7 @@ class Groups(DetailHandler):
log.doLog( log.doLog(
parent, parent,
log.INFO, log.INFO,
"Removed group {} by {}".format(group.pretty_name, self._user.pretty_name), f'Removed group {group.pretty_name} by {self._user.pretty_name}',
log.ADMIN, log.ADMIN,
) )
@ -410,7 +400,7 @@ class Transports(DetailHandler):
log.doLog( log.doLog(
parent, parent,
log.INFO, log.INFO,
"Added transport {} by {}".format(transport.name, self._user.pretty_name), f'Added transport {transport.name} by {self._user.pretty_name}',
log.ADMIN, log.ADMIN,
) )
@ -422,7 +412,7 @@ class Transports(DetailHandler):
log.doLog( log.doLog(
parent, parent,
log.INFO, log.INFO,
"Removed transport {} by {}".format(transport.name, self._user.pretty_name), f'Removed transport {transport.name} by {self._user.pretty_name}',
log.ADMIN, log.ADMIN,
) )
@ -458,9 +448,7 @@ class Publications(DetailHandler):
log.doLog( log.doLog(
parent, parent,
log.INFO, log.INFO,
"Initated publication v{} by {}".format( f'Initiated publication v{parent.current_pub_revision} by {self._user.pretty_name}',
parent.current_pub_revision, self._user.pretty_name
),
log.ADMIN, log.ADMIN,
) )
@ -486,14 +474,12 @@ class Publications(DetailHandler):
ds = models.ServicePoolPublication.objects.get(uuid=processUuid(uuid)) ds = models.ServicePoolPublication.objects.get(uuid=processUuid(uuid))
ds.cancel() ds.cancel()
except Exception as e: except Exception as e:
raise ResponseError("{}".format(e)) raise ResponseError(str(e)) from e
log.doLog( log.doLog(
parent, parent,
log.INFO, log.INFO,
"Canceled publication v{} by {}".format( f'Canceled publication v{parent.current_pub_revision} by {self._user.pretty_name}',
parent.current_pub_revision, self._user.pretty_name
),
log.ADMIN, log.ADMIN,
) )

View File

@ -77,7 +77,6 @@ def getPoolsForGroups(groups):
class Users(DetailHandler): class Users(DetailHandler):
custom_methods = ['servicesPools', 'userServices', 'cleanRelated'] custom_methods = ['servicesPools', 'userServices', 'cleanRelated']
def getItems(self, parent: Authenticator, item: typing.Optional[str]): def getItems(self, parent: Authenticator, item: typing.Optional[str]):
@ -120,7 +119,6 @@ class Users(DetailHandler):
or _('User') or _('User')
) )
return values return values
else:
u = parent.users.get(uuid=processUuid(item)) u = parent.users.get(uuid=processUuid(item))
res = model_to_dict( res = model_to_dict(
u, u,
@ -146,9 +144,9 @@ class Users(DetailHandler):
res['groups'] = [g.dbGroup().uuid for g in usr.groups()] res['groups'] = [g.dbGroup().uuid for g in usr.groups()]
logger.debug('Item: %s', res) logger.debug('Item: %s', res)
return res return res
except Exception: except Exception as e:
logger.exception('En users') logger.exception('En users')
raise self.invalidItemException() raise self.invalidItemException() from e
def getTitle(self, parent): def getTitle(self, parent):
try: try:
@ -191,7 +189,7 @@ class Users(DetailHandler):
try: try:
user = parent.users.get(uuid=processUuid(item)) user = parent.users.get(uuid=processUuid(item))
except Exception: except Exception:
raise self.invalidItemException() raise self.invalidItemException() from None
return log.getLogs(user) return log.getLogs(user)
@ -247,18 +245,18 @@ class Users(DetailHandler):
if g.is_meta is False if g.is_meta is False
) )
except User.DoesNotExist: except User.DoesNotExist:
raise self.invalidItemException() raise self.invalidItemException() from None
except IntegrityError: # Duplicate key probably except IntegrityError: # Duplicate key probably
raise RequestError(_('User already exists (duplicate key error)')) raise RequestError(_('User already exists (duplicate key error)')) from None
except AuthenticatorException as e: except AuthenticatorException as e:
raise RequestError(str(e)) raise RequestError(str(e)) from e
except ValidationError as e: except ValidationError as e:
raise RequestError(str(e.message)) raise RequestError(str(e.message)) from e
except RequestError: except RequestError:
raise raise
except Exception: except Exception as e:
logger.exception('Saving user') logger.exception('Saving user')
raise self.invalidRequestException() raise self.invalidRequestException() from e
return self.getItems(parent, user.uuid) return self.getItems(parent, user.uuid)
@ -266,9 +264,12 @@ class Users(DetailHandler):
try: try:
user = parent.users.get(uuid=processUuid(item)) user = parent.users.get(uuid=processUuid(item))
if not self._user.is_admin and (user.is_admin or user.staff_member): if not self._user.is_admin and (user.is_admin or user.staff_member):
logger.warn('Removal of user {} denied due to insufficients rights') logger.warning(
'Removal of user %s denied due to insufficients rights',
user.pretty_name,
)
raise self.invalidItemException( raise self.invalidItemException(
'Removal of user {} denied due to insufficients rights' f'Removal of user {user.pretty_name} denied due to insufficients rights'
) )
assignedUserService: 'UserService' assignedUserService: 'UserService'
@ -285,9 +286,9 @@ class Users(DetailHandler):
logger.exception('Saving user on removing error') logger.exception('Saving user on removing error')
user.delete() user.delete()
except Exception: except Exception as e:
logger.exception('Removing user') logger.exception('Removing user')
raise self.invalidItemException() raise self.invalidItemException() from e
return 'deleted' return 'deleted'
@ -334,7 +335,6 @@ class Users(DetailHandler):
class Groups(DetailHandler): class Groups(DetailHandler):
custom_methods = ['servicesPools', 'users'] custom_methods = ['servicesPools', 'users']
def getItems(self, parent: Authenticator, item: typing.Optional[str]): def getItems(self, parent: Authenticator, item: typing.Optional[str]):
@ -364,14 +364,14 @@ class Groups(DetailHandler):
if multi: if multi:
return res return res
if not i: if not i:
raise # Invalid item raise Exception('Item not found')
# Add pools field if 1 item only # Add pools field if 1 item only
result = res[0] result = res[0]
result['pools'] = [v.uuid for v in getPoolsForGroups([i])] result['pools'] = [v.uuid for v in getPoolsForGroups([i])]
return result return result
except Exception: except Exception as e:
logger.exception('REST groups') logger.exception('REST groups')
raise self.invalidItemException() raise self.invalidItemException() from e
def getTitle(self, parent: Authenticator) -> str: def getTitle(self, parent: Authenticator) -> str:
try: try:
@ -409,12 +409,12 @@ class Groups(DetailHandler):
} }
types = [ types = [
{ {
'name': tDct[t]['name'], 'name': v['name'],
'type': t, 'type': k,
'description': tDct[t]['description'], 'description': v['description'],
'icon': '', 'icon': '',
} }
for t in tDct for k, v in tDct.items()
] ]
if forType is None: if forType is None:
@ -423,7 +423,7 @@ class Groups(DetailHandler):
try: try:
return next(filter(lambda x: x['type'] == forType, types)) return next(filter(lambda x: x['type'] == forType, types))
except Exception: except Exception:
raise self.invalidRequestException() raise self.invalidRequestException() from None
def saveItem(self, parent: Authenticator, item: typing.Optional[str]) -> None: def saveItem(self, parent: Authenticator, item: typing.Optional[str]) -> None:
group = None # Avoid warning on reference before assignment group = None # Avoid warning on reference before assignment
@ -467,7 +467,11 @@ class Groups(DetailHandler):
if is_meta: if is_meta:
# Do not allow to add meta groups to meta groups # Do not allow to add meta groups to meta groups
group.groups.set(i for i in parent.groups.filter(uuid__in=self._params['groups']) if i.is_meta is False) group.groups.set(
i
for i in parent.groups.filter(uuid__in=self._params['groups'])
if i.is_meta is False
)
if pools: if pools:
# Update pools # Update pools
@ -475,16 +479,16 @@ class Groups(DetailHandler):
group.save() group.save()
except Group.DoesNotExist: except Group.DoesNotExist:
raise self.invalidItemException() raise self.invalidItemException() from None
except IntegrityError: # Duplicate key probably except IntegrityError: # Duplicate key probably
raise RequestError(_('User already exists (duplicate key error)')) raise RequestError(_('User already exists (duplicate key error)')) from None
except AuthenticatorException as e: except AuthenticatorException as e:
raise RequestError(str(e)) raise RequestError(str(e)) from e
except RequestError: except RequestError:
raise raise
except Exception: except Exception as e:
logger.exception('Saving group') logger.exception('Saving group')
raise self.invalidRequestException() raise self.invalidRequestException() from e
def deleteItem(self, parent: Authenticator, item: str) -> None: def deleteItem(self, parent: Authenticator, item: str) -> None:
try: try:
@ -492,7 +496,7 @@ class Groups(DetailHandler):
group.delete() group.delete()
except Exception: except Exception:
raise self.invalidItemException() raise self.invalidItemException() from None
def servicesPools( def servicesPools(
self, parent: Authenticator, item: str self, parent: Authenticator, item: str
@ -532,11 +536,10 @@ class Groups(DetailHandler):
'last_access': user.last_access, 'last_access': user.last_access,
} }
res: typing.List[typing.Mapping[str, typing.Any]] = []
if group.is_meta: if group.is_meta:
# Get all users for everygroup and # Get all users for everygroup and
groups = getGroupsFromMeta((group,)) groups = getGroupsFromMeta((group,))
tmpSet = None tmpSet: typing.Optional[typing.Set] = None
for g in groups: for g in groups:
gSet = set((i for i in g.users.all())) gSet = set((i for i in g.users.all()))
if tmpSet is None: if tmpSet is None:
@ -549,12 +552,9 @@ class Groups(DetailHandler):
if not tmpSet: if not tmpSet:
break # If already empty, stop break # If already empty, stop
users = list(tmpSet) if tmpSet else list() users = list(tmpSet or {}) if tmpSet else []
tmpSet = None tmpSet = None
else: else:
users = group.users.all() users = group.users.all()
for i in users: return [info(i) for i in users]
res.append(info(i))
return res

View File

@ -31,56 +31,23 @@
""" """
import traceback import traceback
import logging import logging
import enum
import typing import typing
from uds import models
from uds.core.util.config import GlobalConfig
from uds.core.util import singleton from uds.core.util import singleton
from uds.models.util import getSqlDatetime
from uds.models.log import Log
from .objects import MODEL_TO_TYPE, LogObjectType
# Not imported at runtime, just for type checking # Not imported at runtime, just for type checking
if typing.TYPE_CHECKING: if typing.TYPE_CHECKING:
from django.db.models import Model from django.db.models import Model
from uds import models
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class LogObjectType(enum.IntEnum):
USERSERVICE = 0
PUBLICATION = 1
SERVICEPOOL = 2
SERVICE = 3
PROVIDER = 4
USER = 5
GROUP = 6
AUTHENTICATOR = 7
METAPOOL = 8
SYSLOG = 9
def get_max_elements(self) -> int:
"""
if True, this type of log will be limited by number of log entries
"""
if self == LogObjectType.SYSLOG:
return GlobalConfig.SYSLOG_MAX_ELEMENTS.getInt()
return GlobalConfig.MAX_LOGS_PER_ELEMENT.getInt()
# Dict for translations
MODEL_TO_TYPE: typing.Mapping[typing.Type['Model'], LogObjectType] = {
models.UserService: LogObjectType.USERSERVICE,
models.ServicePoolPublication: LogObjectType.PUBLICATION,
models.ServicePool: LogObjectType.SERVICEPOOL,
models.Service: LogObjectType.SERVICE,
models.Provider: LogObjectType.PROVIDER,
models.User: LogObjectType.USER,
models.Group: LogObjectType.GROUP,
models.Authenticator: LogObjectType.AUTHENTICATOR,
models.MetaPool: LogObjectType.METAPOOL,
}
class LogManager(metaclass=singleton.Singleton): class LogManager(metaclass=singleton.Singleton):
""" """
@ -109,7 +76,7 @@ class LogManager(metaclass=singleton.Singleton):
# Ensure message fits on space # Ensure message fits on space
message = str(message)[:255] message = str(message)[:255]
qs = models.Log.objects.filter(owner_id=owner_id, owner_type=owner_type.value) qs = Log.objects.filter(owner_id=owner_id, owner_type=owner_type.value)
# First, ensure we do not have more than requested logs, and we can put one more log item # First, ensure we do not have more than requested logs, and we can put one more log item
max_elements = owner_type.get_max_elements() max_elements = owner_type.get_max_elements()
current_elements = qs.count() current_elements = qs.count()
@ -120,7 +87,7 @@ class LogManager(metaclass=singleton.Singleton):
x.delete() x.delete()
if avoidDuplicates: if avoidDuplicates:
lg: typing.Optional[models.Log] = models.Log.objects.filter( lg: typing.Optional['Log'] = Log.objects.filter(
owner_id=owner_id, owner_type=owner_type.value owner_id=owner_id, owner_type=owner_type.value
).last() ).last()
if lg and lg.data == message: if lg and lg.data == message:
@ -129,10 +96,10 @@ class LogManager(metaclass=singleton.Singleton):
# now, we add new log # now, we add new log
try: try:
models.Log.objects.create( Log.objects.create(
owner_type=owner_type.value, owner_type=owner_type.value,
owner_id=owner_id, owner_id=owner_id,
created=models.getSqlDatetime(), created=getSqlDatetime(),
source=source, source=source,
level=level, level=level,
data=message, data=message,
@ -147,7 +114,7 @@ class LogManager(metaclass=singleton.Singleton):
""" """
Get all logs associated with an user service, ordered by date Get all logs associated with an user service, ordered by date
""" """
qs = models.Log.objects.filter(owner_id=owner_id, owner_type=owner_type.value) qs = Log.objects.filter(owner_id=owner_id, owner_type=owner_type.value)
return [ return [
{'date': x.created, 'level': x.level, 'source': x.source, 'message': x.data} {'date': x.created, 'level': x.level, 'source': x.source, 'message': x.data}
for x in reversed(qs.order_by('-created', '-id')[:limit]) # type: ignore # Slicing is not supported by pylance right now for x in reversed(qs.order_by('-created', '-id')[:limit]) # type: ignore # Slicing is not supported by pylance right now
@ -157,7 +124,7 @@ class LogManager(metaclass=singleton.Singleton):
""" """
Clears ALL logs related to user service Clears ALL logs related to user service
""" """
models.Log.objects.filter(owner_id=owner_id, owner_type=owner_type).delete() Log.objects.filter(owner_id=owner_id, owner_type=owner_type).delete()
def doLog( def doLog(
self, self,
@ -199,7 +166,7 @@ class LogManager(metaclass=singleton.Singleton):
) )
def getLogs( def getLogs(
self, wichObject: typing.Optional['Model'], limit: int self, wichObject: typing.Optional['Model'], limit: int = -1
) -> typing.List[typing.Dict]: ) -> typing.List[typing.Dict]:
""" """
Get the logs associated with "wichObject", limiting to "limit" (default is GlobalConfig.MAX_LOGS_PER_ELEMENT) Get the logs associated with "wichObject", limiting to "limit" (default is GlobalConfig.MAX_LOGS_PER_ELEMENT)
@ -213,7 +180,7 @@ class LogManager(metaclass=singleton.Singleton):
logger.debug('Getting log: %s -> %s', wichObject, owner_type) logger.debug('Getting log: %s -> %s', wichObject, owner_type)
if owner_type: # 0 is valid owner type if owner_type: # 0 is valid owner type
return self.__getLogs(owner_type, getattr(wichObject, 'id', -1), limit) return self.__getLogs(owner_type, getattr(wichObject, 'id', -1), limit if limit != -1 else owner_type.get_max_elements())
logger.debug( logger.debug(
'Requested getLogs for a type of object not covered: %s', wichObject 'Requested getLogs for a type of object not covered: %s', wichObject

View File

@ -0,0 +1,14 @@
import logging
import logging.handlers
class UDSLog(logging.handlers.RotatingFileHandler):
"""
Custom log handler that will log to database before calling to RotatingFileHandler
"""
def emit(self, record: logging.LogRecord) -> None:
# Currently, simply call to parent
msg = self.format(record) # pylint: disable=unused-variable
# TODO: Log message on database and continue as a RotatingFileHandler
return super().emit(record)

View File

@ -0,0 +1,45 @@
import typing
import enum
from uds import models
# Not imported at runtime, just for type checking
if typing.TYPE_CHECKING:
from django.db.models import Model
class LogObjectType(enum.IntEnum):
USERSERVICE = 0
PUBLICATION = 1
SERVICEPOOL = 2
SERVICE = 3
PROVIDER = 4
USER = 5
GROUP = 6
AUTHENTICATOR = 7
METAPOOL = 8
SYSLOG = 9
def get_max_elements(self) -> int:
"""
if True, this type of log will be limited by number of log entries
"""
from uds.core.util.config import GlobalConfig # pylint: disable=import-outside-toplevel
if self == LogObjectType.SYSLOG:
return GlobalConfig.SYSLOG_MAX_ELEMENTS.getInt()
return GlobalConfig.MAX_LOGS_PER_ELEMENT.getInt()
# Dict for translations
MODEL_TO_TYPE: typing.Mapping[typing.Type['Model'], LogObjectType] = {
models.UserService: LogObjectType.USERSERVICE,
models.ServicePoolPublication: LogObjectType.PUBLICATION,
models.ServicePool: LogObjectType.SERVICEPOOL,
models.Service: LogObjectType.SERVICE,
models.Provider: LogObjectType.PROVIDER,
models.User: LogObjectType.USER,
models.Group: LogObjectType.GROUP,
models.Authenticator: LogObjectType.AUTHENTICATOR,
models.MetaPool: LogObjectType.METAPOOL,
}

View File

@ -34,8 +34,6 @@ import logging
import logging.handlers import logging.handlers
import typing import typing
from uds.core.managers import logManager
# Not imported at runtime, just for type checking # Not imported at runtime, just for type checking
if typing.TYPE_CHECKING: if typing.TYPE_CHECKING:
from django.db.models import Model from django.db.models import Model
@ -149,8 +147,11 @@ def doLog(
source: str = UNKNOWN, source: str = UNKNOWN,
avoidDuplicates: bool = True, avoidDuplicates: bool = True,
) -> None: ) -> None:
# pylint: disable=import-outside-toplevel
from uds.core.managers.log import LogManager
logger.debug('%s %s %s', wichObject, level, message) logger.debug('%s %s %s', wichObject, level, message)
logManager().doLog(wichObject, level, message, source, avoidDuplicates) LogManager().doLog(wichObject, level, message, source, avoidDuplicates)
def getLogs( def getLogs(
@ -159,21 +160,34 @@ def getLogs(
""" """
Get the logs associated with "wichObject", limiting to "limit" (default is GlobalConfig.MAX_LOGS_PER_ELEMENT) Get the logs associated with "wichObject", limiting to "limit" (default is GlobalConfig.MAX_LOGS_PER_ELEMENT)
""" """
# pylint: disable=import-outside-toplevel
from uds.core.managers.log import LogManager
from uds.core.util.config import GlobalConfig from uds.core.util.config import GlobalConfig
if limit is None: if limit is None:
limit = GlobalConfig.MAX_LOGS_PER_ELEMENT.getInt() limit = GlobalConfig.MAX_LOGS_PER_ELEMENT.getInt()
return logManager().getLogs(wichObject, limit) return LogManager().getLogs(wichObject, limit)
def clearLogs(wichObject: 'Model') -> None: def clearLogs(wichObject: 'Model') -> None:
""" """
Clears the logs associated with the object using the logManager Clears the logs associated with the object using the logManager
""" """
return logManager().clearLogs(wichObject) # pylint: disable=import-outside-toplevel
from uds.core.managers.log import LogManager
return LogManager().clearLogs(wichObject)
class UDSLogHandler(logging.handlers.RotatingFileHandler): class UDSLogHandler(logging.handlers.RotatingFileHandler):
"""
Custom log handler that will log to database before calling to RotatingFileHandler
"""
def emit(self, record: logging.LogRecord) -> None: def emit(self, record: logging.LogRecord) -> None:
# Currently, simply call to parent # Currently, simply call to parent
msg = self.format(record) # pylint: disable=unused-variable
# TODO: Log message on database and continue as a RotatingFileHandler
return super().emit(record) return super().emit(record)

View File

@ -36,7 +36,7 @@ from django.db import transaction
from django.db.models import Q from django.db.models import Q
from uds.core.util.config import GlobalConfig from uds.core.util.config import GlobalConfig
from uds.core.util.state import State from uds.core.util.state import State
from uds.core.managers import userServiceManager from uds.core.managers.user_service import UserServiceManager
from uds.core.services.exceptions import MaxServicesReachedError from uds.core.services.exceptions import MaxServicesReachedError
from uds.models import ServicePool, ServicePoolPublication, UserService from uds.models import ServicePool, ServicePoolPublication, UserService
from uds.core import services from uds.core import services
@ -122,7 +122,7 @@ class ServiceCacheUpdater(Job):
inCacheL1: int = ( inCacheL1: int = (
servicePool.cachedUserServices() servicePool.cachedUserServices()
.filter( .filter(
userServiceManager().getCacheStateFilter( UserServiceManager().getCacheStateFilter(
servicePool, services.UserDeployment.L1_CACHE servicePool, services.UserDeployment.L1_CACHE
) )
) )
@ -132,7 +132,7 @@ class ServiceCacheUpdater(Job):
inCacheL2: int = ( inCacheL2: int = (
servicePool.cachedUserServices() servicePool.cachedUserServices()
.filter( .filter(
userServiceManager().getCacheStateFilter( UserServiceManager().getCacheStateFilter(
servicePool, services.UserDeployment.L2_CACHE servicePool, services.UserDeployment.L2_CACHE
) )
) )
@ -140,7 +140,7 @@ class ServiceCacheUpdater(Job):
) )
inAssigned: int = ( inAssigned: int = (
servicePool.assignedUserServices() servicePool.assignedUserServices()
.filter(userServiceManager().getStateFilter(servicePool.service)) # type: ignore .filter(UserServiceManager().getStateFilter(servicePool.service)) # type: ignore
.count() .count()
) )
# if we bypasses max cache, we will reduce it in first place. This is so because this will free resources on service provider # if we bypasses max cache, we will reduce it in first place. This is so because this will free resources on service provider
@ -179,7 +179,7 @@ class ServiceCacheUpdater(Job):
continue continue
# If this service don't allows more starting user services, continue # If this service don't allows more starting user services, continue
if not userServiceManager().canGrowServicePool(servicePool): if not UserServiceManager().canGrowServicePool(servicePool):
logger.debug( logger.debug(
'This pool cannot grow rithg now: %s', 'This pool cannot grow rithg now: %s',
servicePool, servicePool,
@ -231,7 +231,7 @@ class ServiceCacheUpdater(Job):
servicePool.cachedUserServices() servicePool.cachedUserServices()
.select_for_update() .select_for_update()
.filter( .filter(
userServiceManager().getCacheStateFilter( UserServiceManager().getCacheStateFilter(
servicePool, services.UserDeployment.L2_CACHE servicePool, services.UserDeployment.L2_CACHE
) )
) )
@ -252,7 +252,7 @@ class ServiceCacheUpdater(Job):
return return
try: try:
# This has a velid publication, or it will not be here # This has a velid publication, or it will not be here
userServiceManager().createCacheFor( UserServiceManager().createCacheFor(
typing.cast(ServicePoolPublication, servicePool.activePublication()), typing.cast(ServicePoolPublication, servicePool.activePublication()),
services.UserDeployment.L1_CACHE, services.UserDeployment.L1_CACHE,
) )
@ -288,7 +288,7 @@ class ServiceCacheUpdater(Job):
logger.debug("Growing L2 cache creating a new service for %s", servicePool.name) logger.debug("Growing L2 cache creating a new service for %s", servicePool.name)
try: try:
# This has a velid publication, or it will not be here # This has a velid publication, or it will not be here
userServiceManager().createCacheFor( UserServiceManager().createCacheFor(
typing.cast(ServicePoolPublication, servicePool.activePublication()), typing.cast(ServicePoolPublication, servicePool.activePublication()),
services.UserDeployment.L2_CACHE, services.UserDeployment.L2_CACHE,
) )
@ -312,7 +312,7 @@ class ServiceCacheUpdater(Job):
cacheItems: typing.List[UserService] = list( cacheItems: typing.List[UserService] = list(
servicePool.cachedUserServices() servicePool.cachedUserServices()
.filter( .filter(
userServiceManager().getCacheStateFilter( UserServiceManager().getCacheStateFilter(
servicePool, services.UserDeployment.L1_CACHE servicePool, services.UserDeployment.L1_CACHE
) )
) )
@ -359,7 +359,7 @@ class ServiceCacheUpdater(Job):
cacheItems = ( cacheItems = (
servicePool.cachedUserServices() servicePool.cachedUserServices()
.filter( .filter(
userServiceManager().getCacheStateFilter( UserServiceManager().getCacheStateFilter(
servicePool, services.UserDeployment.L2_CACHE servicePool, services.UserDeployment.L2_CACHE
) )
) )

View File

@ -34,7 +34,7 @@ import logging
import typing import typing
from django.db import transaction from django.db import transaction
from uds.core import managers from uds.core.managers.user_service import UserServiceManager
from uds.core.util.config import GlobalConfig from uds.core.util.config import GlobalConfig
from uds.models import UserService, getSqlDatetime from uds.models import UserService, getSqlDatetime
from uds.core.util.state import State from uds.core.util.state import State
@ -77,7 +77,7 @@ class UserServiceRemover(Job):
# USER_SERVICE_REMOVAL_LIMIT is the maximum number of items to remove at once # USER_SERVICE_REMOVAL_LIMIT is the maximum number of items to remove at once
# This configuration value is cached at startup, so it is not updated until next reload # This configuration value is cached at startup, so it is not updated until next reload
removeAtOnce: int = GlobalConfig.USER_SERVICE_CLEAN_NUMBER.getInt() removeAtOnce: int = GlobalConfig.USER_SERVICE_CLEAN_NUMBER.getInt()
manager = managers.userServiceManager() manager = UserServiceManager()
with transaction.atomic(): with transaction.atomic():
removeFrom = getSqlDatetime() - timedelta( removeFrom = getSqlDatetime() - timedelta(

View File

@ -43,7 +43,7 @@ from django.db import models
from uds.core.util import calendar from uds.core.util import calendar
from uds.core.util import log from uds.core.util import log
from uds.core.util import state from uds.core.util import state
from uds.core import managers from uds.core.managers.user_service import UserServiceManager
from uds.core import services from uds.core import services
from .calendar import Calendar from .calendar import Calendar
@ -375,7 +375,7 @@ class CalendarAction(UUIDModel):
def clear_cache() -> None: def clear_cache() -> None:
# 4.- Remove all cache_l1_srvs # 4.- Remove all cache_l1_srvs
for i in self.service_pool.cachedUserServices().filter( for i in self.service_pool.cachedUserServices().filter(
managers.userServiceManager().getCacheStateFilter( UserServiceManager().getCacheStateFilter(
self.service_pool, self.service_pool,
services.UserDeployment.L1_CACHE services.UserDeployment.L1_CACHE
if self.action == CALENDAR_ACTION_CLEAN_CACHE_L1['id'] if self.action == CALENDAR_ACTION_CLEAN_CACHE_L1['id']

View File

@ -33,8 +33,6 @@ Author: Adolfo Gómez, dkmaster at dkmon dot com
import logging import logging
from django.db import models from django.db import models
from uds.core.util.log import logStrFromLevel
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -75,6 +73,9 @@ class Log(models.Model):
@property @property
def level_str(self) -> str: def level_str(self) -> str:
# pylint: disable=import-outside-toplevel
from uds.core.util.log import logStrFromLevel
return logStrFromLevel(self.level) return logStrFromLevel(self.level)
def __str__(self) -> str: def __str__(self) -> str:

View File

@ -448,7 +448,7 @@ class UserService(UUIDModel):
:note: If the state is Fase (set to not in use), a check for removal of this deployed service is launched. :note: If the state is Fase (set to not in use), a check for removal of this deployed service is launched.
""" """
# pylint: disable=import-outside-toplevel # pylint: disable=import-outside-toplevel
from uds.core.managers import userServiceManager from uds.core.managers.user_service import UserServiceManager
self.in_use = inUse self.in_use = inUse
self.in_use_date = getSqlDatetime() self.in_use_date = getSqlDatetime()
@ -462,7 +462,7 @@ class UserService(UUIDModel):
if not inUse: # Service released, check y we should mark it for removal if not inUse: # Service released, check y we should mark it for removal
# If our publication is not current, mark this for removal # If our publication is not current, mark this for removal
userServiceManager().checkForRemoval(self) UserServiceManager().checkForRemoval(self)
def startUsageAccounting(self) -> None: def startUsageAccounting(self) -> None:
# 1.- If do not have any account associated, do nothing # 1.- If do not have any account associated, do nothing
@ -526,10 +526,10 @@ class UserService(UUIDModel):
Returns if this service is ready (not preparing or marked for removal) Returns if this service is ready (not preparing or marked for removal)
""" """
# pylint: disable=import-outside-toplevel # pylint: disable=import-outside-toplevel
from uds.core.managers import userServiceManager from uds.core.managers.user_service import UserServiceManager
# Call to isReady of the instance # Call to isReady of the instance
return userServiceManager().isReady(self) return UserServiceManager().isReady(self)
def isInMaintenance(self) -> bool: def isInMaintenance(self) -> bool:
return self.deployed_service.isInMaintenance() return self.deployed_service.isInMaintenance()
@ -551,9 +551,9 @@ class UserService(UUIDModel):
Asks the UserServiceManager to cancel the current operation of this user deployed service. Asks the UserServiceManager to cancel the current operation of this user deployed service.
""" """
# pylint: disable=import-outside-toplevel # pylint: disable=import-outside-toplevel
from uds.core.managers import userServiceManager from uds.core.managers.user_service import UserServiceManager
userServiceManager().cancel(self) UserServiceManager().cancel(self)
def removeOrCancel(self) -> None: def removeOrCancel(self) -> None:
""" """
@ -578,9 +578,9 @@ class UserService(UUIDModel):
cacheLevel: New cache level to put object in cacheLevel: New cache level to put object in
""" """
# pylint: disable=import-outside-toplevel # pylint: disable=import-outside-toplevel
from uds.core.managers import userServiceManager from uds.core.managers.user_service import UserServiceManager
userServiceManager().moveToLevel(self, cacheLevel) UserServiceManager().moveToLevel(self, cacheLevel)
def getProperty( def getProperty(
self, propName: str, default: typing.Optional[str] = None self, propName: str, default: typing.Optional[str] = None

View File

@ -40,7 +40,6 @@ from uds.core.ui import gui
from uds.core import osmanagers from uds.core import osmanagers
from uds.core.util.state import State from uds.core.util.state import State
from uds.core.util import log from uds.core.util import log
from uds.core.managers import userServiceManager
if typing.TYPE_CHECKING: if typing.TYPE_CHECKING:
from uds.models.user_service import UserService from uds.models.user_service import UserService

View File

@ -40,7 +40,6 @@ from uds.core.ui import gui
from uds.core import osmanagers from uds.core import osmanagers
from uds.core.util.state import State from uds.core.util.state import State
from uds.core.util import log from uds.core.util import log
from uds.core.managers import userServiceManager
if typing.TYPE_CHECKING: if typing.TYPE_CHECKING:
from uds.models.user_service import UserService from uds.models.user_service import UserService

View File

@ -16,7 +16,6 @@ from django.utils.translation import gettext_noop as _, gettext_lazy
from uds.core import osmanagers, exceptions from uds.core import osmanagers, exceptions
from uds.core.services import types as serviceTypes from uds.core.services import types as serviceTypes
from uds.core.ui import gui from uds.core.ui import gui
from uds.core.managers import userServiceManager
from uds.core.util.state import State from uds.core.util.state import State
from uds.core.util import log from uds.core.util import log
from uds.models import TicketStore from uds.models import TicketStore

View File

@ -35,7 +35,7 @@ import logging
import typing import typing
from uds.core import services from uds.core import services
from uds.core import managers from uds.core.managers.user_service import UserServiceManager
from uds.core.util.state import State from uds.core.util.state import State
from uds.core.util import log from uds.core.util import log
@ -135,7 +135,9 @@ class OVirtLinkedDeployment(services.UserDeployment):
self._mac = vals[3].decode('utf8') self._mac = vals[3].decode('utf8')
self._vmid = vals[4].decode('utf8') self._vmid = vals[4].decode('utf8')
self._reason = vals[5].decode('utf8') self._reason = vals[5].decode('utf8')
self._queue = pickle.loads(vals[6]) # nosec: not insecure, we are loading our own data self._queue = pickle.loads(
vals[6]
) # nosec: not insecure, we are loading our own data
def getName(self) -> str: def getName(self) -> str:
if self._name == '': if self._name == '':
@ -216,7 +218,7 @@ class OVirtLinkedDeployment(services.UserDeployment):
self.cache.put('ready', '1') self.cache.put('ready', '1')
except Exception as e: except Exception as e:
self.doLog(log.ERROR, 'Error on setReady: {}'.format(e)) self.doLog(log.ERROR, f'Error on setReady: {e}')
# Treat as operation done, maybe the machine is ready and we can continue # Treat as operation done, maybe the machine is ready and we can continue
return State.FINISHED return State.FINISHED
@ -233,19 +235,22 @@ class OVirtLinkedDeployment(services.UserDeployment):
) -> typing.Optional[typing.MutableMapping[str, typing.Any]]: ) -> typing.Optional[typing.MutableMapping[str, typing.Any]]:
return self.service().getConsoleConnection(self._vmid) return self.service().getConsoleConnection(self._vmid)
def desktopLogin(self, username: str, password: str, domain: str = '') -> None: def desktopLogin(
script = '''import sys self,
username: str,
password: str,
domain: str = '', # pylint: disable=unused-argument
) -> None:
script = f'''import sys
if sys.platform == 'win32': if sys.platform == 'win32':
from uds import operations from uds import operations
operations.writeToPipe("\\\\.\\pipe\\VDSMDPipe", struct.pack('!IsIs', 1, '{username}'.encode('utf8'), 2, '{password}'.encode('utf8')), True) operations.writeToPipe("\\\\.\\pipe\\VDSMDPipe", struct.pack('!IsIs', 1, '{username}'.encode('utf8'), 2, '{password}'.encode('utf8')), True)
'''.format( '''
username=username, password=password
)
# Post script to service # Post script to service
# operations.writeToPipe("\\\\.\\pipe\\VDSMDPipe", packet, True) # operations.writeToPipe("\\\\.\\pipe\\VDSMDPipe", packet, True)
dbService = self.dbservice() dbService = self.dbservice()
if dbService: if dbService:
managers.userServiceManager().sendScript(dbService, script) UserServiceManager().sendScript(dbService, script)
def notifyReadyFromOsManager(self, data: typing.Any) -> str: def notifyReadyFromOsManager(self, data: typing.Any) -> str:
# Here we will check for suspending the VM (when full ready) # Here we will check for suspending the VM (when full ready)
@ -273,7 +278,6 @@ if sys.platform == 'win32':
return self.__executeQueue() return self.__executeQueue()
def __initQueueForDeploy(self, forLevel2: bool = False) -> None: def __initQueueForDeploy(self, forLevel2: bool = False) -> None:
if forLevel2 is False: if forLevel2 is False:
self._queue = [opCreate, opChangeMac, opStart, opFinish] self._queue = [opCreate, opChangeMac, opStart, opFinish]
else: else:
@ -322,9 +326,6 @@ if sys.platform == 'win32':
def __pushFrontOp(self, op: int): def __pushFrontOp(self, op: int):
self._queue.insert(0, op) self._queue.insert(0, op)
def __pushBackOp(self, op: int):
self._queue.append(op)
def __error(self, reason: typing.Union[str, Exception]) -> str: def __error(self, reason: typing.Union[str, Exception]) -> str:
""" """
Internal method to set object as error state Internal method to set object as error state
@ -369,7 +370,7 @@ if sys.platform == 'win32':
if execFnc is None: if execFnc is None:
return self.__error( return self.__error(
'Unknown operation found at execution queue ({0})'.format(op) f'Unknown operation found at execution queue ({op})'
) )
execFnc() execFnc()
@ -446,7 +447,7 @@ if sys.platform == 'win32':
if state in UP_STATES: # Already started, return if state in UP_STATES: # Already started, return
return State.RUNNING return State.RUNNING
if state != 'down' and state != 'suspended': if state not in ('down', 'suspended'):
self.__pushFrontOp( self.__pushFrontOp(
opRetry opRetry
) # Will call "check Retry", that will finish inmediatly and again call this one ) # Will call "check Retry", that will finish inmediatly and again call this one
@ -466,7 +467,7 @@ if sys.platform == 'win32':
if state == 'down': # Already stoped, return if state == 'down': # Already stoped, return
return State.RUNNING return State.RUNNING
if state != 'up' and state != 'suspended': if state not in ('up', 'suspended'):
self.__pushFrontOp( self.__pushFrontOp(
opRetry opRetry
) # Will call "check Retry", that will finish inmediatly and again call this one ) # Will call "check Retry", that will finish inmediatly and again call this one
@ -576,7 +577,7 @@ if sys.platform == 'win32':
if chkFnc is None: if chkFnc is None:
return self.__error( return self.__error(
'Unknown operation found at check queue ({0})'.format(op) f'Unknown operation found at check queue ({op})'
) )
state = chkFnc() state = chkFnc()
@ -629,7 +630,7 @@ if sys.platform == 'win32':
if op == opError: if op == opError:
return self.__error('Machine is already in error state!') return self.__error('Machine is already in error state!')
if op == opFinish or op == opWait: if op in (opFinish, opWait):
self._queue = [opStop, opRemove, opFinish] self._queue = [opStop, opRemove, opFinish]
return self.__executeQueue() return self.__executeQueue()

View File

@ -35,7 +35,7 @@ import logging
import typing import typing
from uds.core import services from uds.core import services
from uds.core import managers from uds.core.managers.user_service import UserServiceManager
from uds.core.util.state import State from uds.core.util.state import State
from uds.core.util import log from uds.core.util import log
from uds.models import getSqlDatetimeAsUnix from uds.models import getSqlDatetimeAsUnix
@ -186,7 +186,7 @@ class ProxmoxDeployment(services.UserDeployment):
except client.ProxmoxConnectionError: except client.ProxmoxConnectionError:
raise # If connection fails, let it fail on parent raise # If connection fails, let it fail on parent
except Exception as e: except Exception as e:
return self.__error('Machine not found: {}'.format(e)) return self.__error(f'Machine not found: {e}')
if vmInfo.status == 'stopped': if vmInfo.status == 'stopped':
self._queue = [opStart, opFinish] self._queue = [opStart, opFinish]
@ -210,20 +210,23 @@ class ProxmoxDeployment(services.UserDeployment):
) -> typing.Optional[typing.MutableMapping[str, typing.Any]]: ) -> typing.Optional[typing.MutableMapping[str, typing.Any]]:
return self.service().getConsoleConnection(self._vmid) return self.service().getConsoleConnection(self._vmid)
def desktopLogin(self, username: str, password: str, domain: str = '') -> None: def desktopLogin(
script = '''import sys self,
username: str,
password: str,
domain: str = '', # pylint: disable=unused-argument
) -> None:
script = f'''import sys
if sys.platform == 'win32': if sys.platform == 'win32':
from uds import operations from uds import operations
operations.writeToPipe("\\\\.\\pipe\\VDSMDPipe", struct.pack('!IsIs', 1, '{username}'.encode('utf8'), 2, '{password}'.encode('utf8')), True) operations.writeToPipe("\\\\.\\pipe\\VDSMDPipe", struct.pack('!IsIs', 1, '{username}'.encode('utf8'), 2, '{password}'.encode('utf8')), True)
'''.format( '''
username=username, password=password
)
# Post script to service # Post script to service
# operations.writeToPipe("\\\\.\\pipe\\VDSMDPipe", packet, True) # operations.writeToPipe("\\\\.\\pipe\\VDSMDPipe", packet, True)
dbService = self.dbservice() dbService = self.dbservice()
if dbService: if dbService:
try: try:
managers.userServiceManager().sendScript(dbService, script) UserServiceManager().sendScript(dbService, script)
except Exception as e: except Exception as e:
logger.info('Exception sending loggin to %s: %s', dbService, e) logger.info('Exception sending loggin to %s: %s', dbService, e)
@ -253,7 +256,6 @@ if sys.platform == 'win32':
return self.__executeQueue() return self.__executeQueue()
def __initQueueForDeploy(self, forLevel2: bool = False) -> None: def __initQueueForDeploy(self, forLevel2: bool = False) -> None:
if forLevel2 is False: if forLevel2 is False:
self._queue = [opCreate, opGetMac, opStart, opFinish] self._queue = [opCreate, opGetMac, opStart, opFinish]
else: else:
@ -282,9 +284,6 @@ if sys.platform == 'win32':
def __pushFrontOp(self, op: int): def __pushFrontOp(self, op: int):
self._queue.insert(0, op) self._queue.insert(0, op)
def __pushBackOp(self, op: int):
self._queue.append(op)
def __retryLater(self) -> str: def __retryLater(self) -> str:
self.__pushFrontOp(opRetry) self.__pushFrontOp(opRetry)
return State.RUNNING return State.RUNNING
@ -334,7 +333,7 @@ if sys.platform == 'win32':
if execFnc is None: if execFnc is None:
return self.__error( return self.__error(
'Unknown operation found at execution queue ({0})'.format(op) f'Unknown operation found at execution queue ({op})'
) )
execFnc() execFnc()
@ -387,14 +386,13 @@ if sys.platform == 'win32':
""" """
try: try:
vmInfo = self.service().getMachineInfo(int(self._vmid)) vmInfo = self.service().getMachineInfo(int(self._vmid))
except Exception: except Exception as e:
raise Exception('Machine not found on remove machine') raise Exception('Machine not found on remove machine') from e
if vmInfo.status != 'stopped': if vmInfo.status != 'stopped':
logger.debug('Info status: %s', vmInfo) logger.debug('Info status: %s', vmInfo)
self._queue = [opStop, opRemove, opFinish] self._queue = [opStop, opRemove, opFinish]
return self.__executeQueue() return self.__executeQueue()
else:
self.__setTask(self.service().removeMachine(int(self._vmid))) self.__setTask(self.service().removeMachine(int(self._vmid)))
return State.RUNNING return State.RUNNING
@ -404,8 +402,8 @@ if sys.platform == 'win32':
vmInfo = self.service().getMachineInfo(int(self._vmid)) vmInfo = self.service().getMachineInfo(int(self._vmid))
except client.ProxmoxConnectionError: except client.ProxmoxConnectionError:
return self.__retryLater() return self.__retryLater()
except Exception: except Exception as e:
raise Exception('Machine not found on start machine') raise Exception('Machine not found on start machine') from e
if vmInfo.status == 'stopped': if vmInfo.status == 'stopped':
self.__setTask(self.service().startMachine(int(self._vmid))) self.__setTask(self.service().startMachine(int(self._vmid)))
@ -415,8 +413,8 @@ if sys.platform == 'win32':
def __stopMachine(self) -> str: def __stopMachine(self) -> str:
try: try:
vmInfo = self.service().getMachineInfo(int(self._vmid)) vmInfo = self.service().getMachineInfo(int(self._vmid))
except Exception: except Exception as e:
raise Exception('Machine not found on stop machine') raise Exception('Machine not found on stop machine') from e
if vmInfo.status != 'stopped': if vmInfo.status != 'stopped':
logger.debug('Stopping machine %s', vmInfo) logger.debug('Stopping machine %s', vmInfo)
@ -429,8 +427,8 @@ if sys.platform == 'win32':
vmInfo = self.service().getMachineInfo(int(self._vmid)) vmInfo = self.service().getMachineInfo(int(self._vmid))
except client.ProxmoxConnectionError: except client.ProxmoxConnectionError:
return State.RUNNING # Try again later return State.RUNNING # Try again later
except Exception: except Exception as e:
raise Exception('Machine not found on suspend machine') raise Exception('Machine not found on suspend machine') from e
if vmInfo.status != 'stopped': if vmInfo.status != 'stopped':
self.__setTask(self.service().shutdownMachine(int(self._vmid))) self.__setTask(self.service().shutdownMachine(int(self._vmid)))
@ -463,7 +461,7 @@ if sys.platform == 'win32':
self.service().setVmMac(int(self._vmid), self.getUniqueId()) self.service().setVmMac(int(self._vmid), self.getUniqueId())
except Exception as e: except Exception as e:
logger.exception('Setting HA and MAC on proxmox') logger.exception('Setting HA and MAC on proxmox')
raise Exception('Error setting MAC and HA on proxmox: {}'.format(e)) raise Exception(f'Error setting MAC and HA on proxmox: {e}') from e
return State.RUNNING return State.RUNNING
# Check methods # Check methods
@ -589,7 +587,7 @@ if sys.platform == 'win32':
if chkFnc is None: if chkFnc is None:
return self.__error( return self.__error(
'Unknown operation found at check queue ({0})'.format(op) f'Unknown operation found at check queue ({op})'
) )
state = chkFnc() state = chkFnc()
@ -645,7 +643,7 @@ if sys.platform == 'win32':
lst = [] if not self.service().tryGracelyShutdown() else [opGracelyStop] lst = [] if not self.service().tryGracelyShutdown() else [opGracelyStop]
queue = lst + [opStop, opRemove, opFinish] queue = lst + [opStop, opRemove, opFinish]
if op == opFinish or op == opWait: if op in (opFinish, opWait):
self._queue[:] = queue self._queue[:] = queue
return self.__executeQueue() return self.__executeQueue()

View File

@ -200,7 +200,7 @@ class ProxmoxLinkedService(Service): # pylint: disable=too-many-public-methods
self.machine.setValues( self.machine.setValues(
[ [
gui.choiceItem( gui.choiceItem(
str(m.vmid), '{}\\{} ({})'.format(m.node, m.name or m.vmid, m.vmid) str(m.vmid), f'{m.node}\\{m.name or m.vmid} ({m.vmid})'
) )
for m in self.parent().listMachines() for m in self.parent().listMachines()
if m.name and m.name[:3] != 'UDS' if m.name and m.name[:3] != 'UDS'

View File

@ -38,7 +38,7 @@ import typing
import paramiko import paramiko
from django.utils.translation import gettext_noop as _, gettext_lazy from django.utils.translation import gettext_noop as _, gettext_lazy
from uds.core.managers import userServiceManager from uds.core.managers.user_service import UserServiceManager
from uds.core.managers.user_preferences import CommonPrefs from uds.core.managers.user_preferences import CommonPrefs
from uds.core.ui import gui from uds.core.ui import gui
from uds.core import transports from uds.core import transports
@ -52,7 +52,7 @@ if typing.TYPE_CHECKING:
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
READY_CACHE_TIMEOUT = 30 READY_CACHE_TIMEOUT = 30
SSH_KEY_LENGTH = 1024 SSH_KEY_LENGTH = 2048
class BaseX2GOTransport(transports.Transport): class BaseX2GOTransport(transports.Transport):
@ -269,11 +269,11 @@ class BaseX2GOTransport(transports.Transport):
key.write_private_key(privFile) key.write_private_key(privFile)
priv = privFile.getvalue() priv = privFile.getvalue()
pub = key.get_base64() # 'ssh-rsa {} UDS@X2GOCLIENT'.format(key.get_base64()) pub = key.get_base64()
return priv, pub return priv, pub
def getAuthorizeScript(self, user: str, pubKey: str) -> str: def getAuthorizeScript(self, user: str, pubKey: str) -> str:
with open(os.path.join(os.path.dirname(__file__), 'scripts/authorize.py')) as f: with open(os.path.join(os.path.dirname(__file__), 'scripts/authorize.py'), encoding='utf8') as f:
data = f.read() data = f.read()
return data.replace('__USER__', user).replace('__KEY__', pubKey) return data.replace('__USER__', user).replace('__KEY__', pubKey)
@ -283,5 +283,5 @@ class BaseX2GOTransport(transports.Transport):
) -> typing.Tuple[str, str]: ) -> typing.Tuple[str, str]:
priv, pub = self.genKeyPairForSsh() priv, pub = self.genKeyPairForSsh()
authScript = self.getAuthorizeScript(userName, pub) authScript = self.getAuthorizeScript(userName, pub)
userServiceManager().sendScript(userService, authScript) UserServiceManager().sendScript(userService, authScript)
return priv, pub return priv, pub

View File

@ -46,7 +46,8 @@ from uds.models import (
) )
from uds.core.util.config import GlobalConfig from uds.core.util.config import GlobalConfig
from uds.core.util import html from uds.core.util import html
from uds.core.managers import cryptoManager, userServiceManager from uds.core.managers.user_service import UserServiceManager
from uds.core.managers.crypto import CryptoManager
from uds.core.services.exceptions import ( from uds.core.services.exceptions import (
ServiceNotReadyError, ServiceNotReadyError,
MaxServicesReachedError, MaxServicesReachedError,
@ -66,6 +67,7 @@ if typing.TYPE_CHECKING:
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
# pylint: disable=too-many-arguments
def _serviceInfo( def _serviceInfo(
uuid: str, uuid: str,
is_meta: bool, is_meta: bool,
@ -106,6 +108,7 @@ def _serviceInfo(
} }
# pylint: disable=too-many-locals, too-many-branches, too-many-statements
def getServicesData( def getServicesData(
request: 'ExtendedHttpRequestWithUser', request: 'ExtendedHttpRequestWithUser',
) -> typing.Dict[ ) -> typing.Dict[
@ -172,10 +175,11 @@ def getServicesData(
) )
def buildMetaTransports( def buildMetaTransports(
transports: typing.Iterable[Transport], transports: typing.Iterable[Transport], isLabel: bool, meta: 'MetaPool'
isLabel: bool,
) -> typing.List[typing.Mapping[str, typing.Any]]: ) -> typing.List[typing.Mapping[str, typing.Any]]:
idd = lambda i: i.uuid if not isLabel else 'LABEL:' + i.label def idd(i):
return i.uuid if not isLabel else 'LABEL:' + i.label
return [ return [
{ {
'id': idd(i), 'id': idd(i),
@ -211,7 +215,7 @@ def getServicesData(
inAll = tmpSet inAll = tmpSet
# tmpSet has ALL common transports # tmpSet has ALL common transports
metaTransports = buildMetaTransports( metaTransports = buildMetaTransports(
Transport.objects.filter(uuid__in=inAll or []), isLabel=False Transport.objects.filter(uuid__in=inAll or []), isLabel=False, meta=meta
) )
elif meta.transport_grouping == MetaPool.LABEL_TRANSPORT_SELECT: elif meta.transport_grouping == MetaPool.LABEL_TRANSPORT_SELECT:
ltrans: typing.MutableMapping[str, Transport] = {} ltrans: typing.MutableMapping[str, Transport] = {}
@ -231,7 +235,7 @@ def getServicesData(
inAll = tmpSet inAll = tmpSet
# tmpSet has ALL common transports # tmpSet has ALL common transports
metaTransports = buildMetaTransports( metaTransports = buildMetaTransports(
(v for k, v in ltrans.items() if k in (inAll or set())), isLabel=True (v for k, v in ltrans.items() if k in (inAll or set())), isLabel=True, meta=meta
) )
else: else:
for member in meta.members.all(): for member in meta.members.all():
@ -258,7 +262,7 @@ def getServicesData(
break break
# if not in_use and meta.number_in_use: # Only look for assignation on possible used # if not in_use and meta.number_in_use: # Only look for assignation on possible used
# assignedUserService = userServiceManager().getExistingAssignationForUser(pool, request.user) # assignedUserService = UserServiceManager().getExistingAssignationForUser(pool, request.user)
# if assignedUserService: # if assignedUserService:
# in_use = assignedUserService.in_use # in_use = assignedUserService.in_use
@ -332,7 +336,7 @@ def getServicesData(
# Locate if user service has any already assigned user service for this. Use "pre cached" number of assignations in this pool to optimize # Locate if user service has any already assigned user service for this. Use "pre cached" number of assignations in this pool to optimize
in_use = typing.cast(typing.Any, sPool).number_in_use > 0 in_use = typing.cast(typing.Any, sPool).number_in_use > 0
# if svr.number_in_use: # Anotated value got from getDeployedServicesForGroups(...). If 0, no assignation for this user # if svr.number_in_use: # Anotated value got from getDeployedServicesForGroups(...). If 0, no assignation for this user
# ads = userServiceManager().getExistingAssignationForUser(svr, request.user) # ads = UserServiceManager().getExistingAssignationForUser(svr, request.user)
# if ads: # if ads:
# in_use = ads.in_use # in_use = ads.in_use
@ -366,6 +370,7 @@ def getServicesData(
# if sPool.service.getType().usesCache is False: # if sPool.service.getType().usesCache is False:
# maxDeployed = sPool.service.getInstance().maxDeployed # maxDeployed = sPool.service.getInstance().maxDeployed
# pylint: disable=cell-var-from-loop
def datator(x) -> str: def datator(x) -> str:
return ( return (
x.replace('{use}', use_percent) x.replace('{use}', use_percent)
@ -438,11 +443,11 @@ def enableService(
# If meta service, process and rebuild idService & idTransport # If meta service, process and rebuild idService & idTransport
try: try:
res = userServiceManager().getService( res = UserServiceManager().getService(
request.user, request.os, request.ip, idService, idTransport, doTest=False request.user, request.os, request.ip, idService, idTransport, doTest=False
) )
scrambler = cryptoManager().randomString(32) scrambler = CryptoManager().randomString(32)
password = cryptoManager().symCrypt(webPassword(request), scrambler) password = CryptoManager().symCrypt(webPassword(request), scrambler)
userService, trans = res[1], res[3] userService, trans = res[1], res[3]
@ -470,7 +475,7 @@ def enableService(
# error += ' (code {0:04X})'.format(e.code) # error += ' (code {0:04X})'.format(e.code)
error = gettext( error = gettext(
'Your service is being created, please, wait for a few seconds while we complete it.)' 'Your service is being created, please, wait for a few seconds while we complete it.)'
) + '({}%)'.format(int(e.code * 25)) ) + f'({e.code*25}%)'
except MaxServicesReachedError: except MaxServicesReachedError:
logger.info('Number of service reached MAX for service pool "%s"', idService) logger.info('Number of service reached MAX for service pool "%s"', idService)
error = errors.errorString(errors.MAX_SERVICES_REACHED) error = errors.errorString(errors.MAX_SERVICES_REACHED)

View File

@ -38,7 +38,7 @@ from django.utils.translation import gettext as _
from django.views.decorators.cache import never_cache from django.views.decorators.cache import never_cache
from django.views.decorators.csrf import csrf_exempt from django.views.decorators.csrf import csrf_exempt
import uds.web.util.errors as errors from uds.web.util import errors
from uds.core import auths from uds.core import auths
from uds.core.auths.auth import ( from uds.core.auths.auth import (
webLogin, webLogin,
@ -47,9 +47,9 @@ from uds.core.auths.auth import (
authLogLogin, authLogLogin,
getUDSCookie, getUDSCookie,
) )
from uds.core.managers import userServiceManager, cryptoManager from uds.core.managers.user_service import UserServiceManager
from uds.core.managers.crypto import CryptoManager
from uds.core.services.exceptions import ServiceNotReadyError from uds.core.services.exceptions import ServiceNotReadyError
from uds.core.util import os_detector as OsDetector
from uds.core.util import html from uds.core.util import html
from uds.core.util.state import State from uds.core.util.state import State
from uds.core.util.model import processUuid from uds.core.util.model import processUuid
@ -116,14 +116,14 @@ def authCallback_stage2(
result = authenticateViaCallback(authenticator, params, request) result = authenticateViaCallback(authenticator, params, request)
os = OsDetector.getOsFromUA(request.META['HTTP_USER_AGENT']) # os = OsDetector.getOsFromUA(request.META['HTTP_USER_AGENT'])
if result.url: if result.url:
raise auths.exceptions.Redirect(result.url) raise auths.exceptions.Redirect(result.url)
if result.user is None: if result.user is None:
authLogLogin( authLogLogin(
request, authenticator, '{0}'.format(params), 'Invalid at auth callback' request, authenticator, f'{params}', 'Invalid at auth callback'
) )
raise auths.exceptions.InvalidUserException() raise auths.exceptions.InvalidUserException()
@ -222,10 +222,10 @@ def ticketAuth(
auth = data['auth'] auth = data['auth']
realname = data['realname'] realname = data['realname']
poolUuid = data['servicePool'] poolUuid = data['servicePool']
password = cryptoManager().decrypt(data['password']) password = CryptoManager().decrypt(data['password'])
except Exception: except Exception:
logger.error('Ticket stored is not valid') logger.error('Ticket stored is not valid')
raise auths.exceptions.InvalidUserException() raise auths.exceptions.InvalidUserException() from None
auth = Authenticator.objects.get(uuid=auth) auth = Authenticator.objects.get(uuid=auth)
# If user does not exists in DB, create it right now # If user does not exists in DB, create it right now
@ -264,7 +264,7 @@ def ticketAuth(
# Check if servicePool is part of the ticket # Check if servicePool is part of the ticket
if poolUuid: if poolUuid:
# Request service, with transport = None so it is automatic # Request service, with transport = None so it is automatic
res = userServiceManager().getService( res = UserServiceManager().getService(
request.user, request.os, request.ip, poolUuid, None, False request.user, request.os, request.ip, poolUuid, None, False
) )
_, userService, _, transport, _ = res _, userService, _, transport, _ = res
@ -287,7 +287,7 @@ def ticketAuth(
# Now ensure uds cookie is at response # Now ensure uds cookie is at response
getUDSCookie(request, response, True) getUDSCookie(request, response, True)
return response return response
except ServiceNotReadyError as e: except ServiceNotReadyError:
return errors.errorView(request, errors.SERVICE_NOT_READY) return errors.errorView(request, errors.SERVICE_NOT_READY)
except TicketStore.InvalidTicket: except TicketStore.InvalidTicket:
return errors.errorView(request, errors.RELOAD_NOT_SUPPORTED) return errors.errorView(request, errors.RELOAD_NOT_SUPPORTED)

View File

@ -32,8 +32,6 @@ import json
import logging import logging
import typing import typing
from django.utils.translation import gettext as _
from django.urls import reverse
from django.http import HttpResponse from django.http import HttpResponse
from django.views.decorators.cache import cache_page, never_cache from django.views.decorators.cache import cache_page, never_cache
@ -45,7 +43,6 @@ from uds.models import Transport, Image
from uds.core.util import log from uds.core.util import log
from uds.core.services.exceptions import ServiceNotReadyError from uds.core.services.exceptions import ServiceNotReadyError
from uds.web.util import errors
from uds.web.util import services from uds.web.util import services
# Not imported at runtime, just for type checking # Not imported at runtime, just for type checking
@ -91,10 +88,7 @@ def transportOwnLink(
return HttpResponse(content=json.dumps(response), content_type='application/json') return HttpResponse(content=json.dumps(response), content_type='application/json')
# Will never reach this # pylint: disable=unused-argument
return errors.errorView(request, errors.UNKNOWN_ERROR)
@cache_page(3600, key_prefix='img', cache='memory') @cache_page(3600, key_prefix='img', cache='memory')
def transportIcon(request: 'ExtendedHttpRequest', idTrans: str) -> HttpResponse: def transportIcon(request: 'ExtendedHttpRequest', idTrans: str) -> HttpResponse:
try: try: