1
0
mirror of https://github.com/dkmstr/openuds.git synced 2025-03-20 06:50:23 +03:00

Formating & minor typing fixes

This commit is contained in:
Adolfo Gómez García 2021-08-13 14:53:23 +02:00
parent 8c4b84e7db
commit 03bfb3efbb
41 changed files with 424 additions and 154 deletions

View File

@ -47,12 +47,17 @@ class Environment:
not stored with main module data.
The environment is composed of a "cache" and a "storage". First are volatile data, while second are persistent data.
"""
_key: str
_cache: Cache
_storage: Storage
_idGenerators: typing.Dict[str, UniqueIDGenerator]
def __init__(self, uniqueKey: str, idGenerators: typing.Optional[typing.Dict[str, UniqueIDGenerator]] = None):
def __init__(
self,
uniqueKey: str,
idGenerators: typing.Optional[typing.Dict[str, UniqueIDGenerator]] = None,
):
"""
Initialized the Environment for the specified id
@param uniqueKey: Key for this environment
@ -112,7 +117,11 @@ class Environment:
v.release()
@staticmethod
def getEnvForTableElement(tblName, id_, idGeneratorsTypes: typing.Optional[typing.Dict[str, typing.Any]] = None) -> 'Environment':
def getEnvForTableElement(
tblName,
id_,
idGeneratorsTypes: typing.Optional[typing.Dict[str, typing.Any]] = None,
) -> 'Environment':
"""
From a table name, and a id, tries to load the associated environment or creates a new
one if no environment exists at database. The table name and the id are used to obtain the key
@ -155,7 +164,9 @@ class Environment:
"""
Provides global environment
"""
return Environment(GLOBAL_ENV) # This environment is a global environment for general utility.
return Environment(
GLOBAL_ENV
) # This environment is a global environment for general utility.
class Environmentable:

View File

@ -97,8 +97,11 @@ class Module(UserInterface, Environmentable, Serializable):
Environmentable is a base class that provides utility method to access a separate Environment for every single
module.
"""
# Types
ValuesType = typing.Optional[typing.Dict[str, typing.Any]] # values type value will be str or list[str] int most cases
ValuesType = typing.Optional[
typing.Dict[str, typing.Any]
] # values type value will be str or list[str] int most cases
# : Which coded to use to encode module by default.
# : Basic name used to provide the administrator an "huma readable" form for the module
@ -108,7 +111,9 @@ class Module(UserInterface, Environmentable, Serializable):
# : Description of this module, used at admin level
typeDescription: typing.ClassVar[str] = 'Base Module'
# : Icon file, relative to module folders
iconFile: typing.ClassVar[str] = 'base.png' # This is expected to be png, use this format always
iconFile: typing.ClassVar[
str
] = 'base.png' # This is expected to be png, use this format always
# Not defined, but declared. If module is groupable, this value will contain to which group belongs
group: typing.ClassVar[str]
@ -175,7 +180,10 @@ class Module(UserInterface, Environmentable, Serializable):
Base 64 encoded or raw image, obtained from the specified file at
'iconFile' class attribute
"""
file_ = open(os.path.dirname(sys.modules[cls.__module__].__file__) + '/' + cls.iconFile, 'rb')
file_ = open(
os.path.dirname(sys.modules[cls.__module__].__file__) + '/' + cls.iconFile,
'rb',
)
data = file_.read()
file_.close()
@ -206,7 +214,12 @@ class Module(UserInterface, Environmentable, Serializable):
"""
return [True, _("No connection checking method is implemented.")]
def __init__(self, environment: Environment, values: ValuesType = None, uuid: typing.Optional[str] = None):
def __init__(
self,
environment: Environment,
values: ValuesType = None,
uuid: typing.Optional[str] = None,
):
"""
Do not forget to invoke this in your derived class using
"super(self.__class__, self).__init__(environment, values)".
@ -273,7 +286,7 @@ class Module(UserInterface, Environmentable, Serializable):
Returns:
Internacionalized (using ugettext) string of result of the check.
"""
return _("No check method provided.")
return _("No check method provided.")
def getUuid(self) -> str:
return self._uuid

View File

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2012-2019 Virtual Cable S.L.
# Copyright (c) 2012-2021 Virtual Cable S.L.U.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
@ -12,7 +12,7 @@
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
# * Neither the name of Virtual Cable S.L.U. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
@ -33,6 +33,7 @@
import base64
import typing
class Serializable:
"""
This class represents the interface that all serializable objects must provide.

View File

@ -108,9 +108,9 @@ class StorageAsDict(MutableMapping):
@property
def _db(self) -> typing.Union[models.QuerySet, models.Manager]:
if self._atomic:
return DBStorage.objects.select_for_update()
return DBStorage.objects.select_for_update() # type: ignore
else:
return DBStorage.objects
return DBStorage.objects # type: ignore
@property
def _filtered(self) -> 'models.QuerySet[DBStorage]':

View File

@ -36,11 +36,13 @@ import typing
from django.db import transaction, OperationalError, connection
from django.db.utils import IntegrityError
from django.db.models.query import QuerySet
from uds.models.unique_id import UniqueId
from uds.models.util import getSqlDatetimeAsUnix
if typing.TYPE_CHECKING:
from django.db import models
logger = logging.getLogger(__name__)
MAX_SEQ = 1000000000000000
@ -65,13 +67,13 @@ class UniqueIDGenerator:
def __filter(
self, rangeStart: int, rangeEnd: int = MAX_SEQ, forUpdate: bool = False
) -> QuerySet:
) -> 'models.QuerySet[UniqueId]':
# Order is defined on UniqueId model, and is '-seq' by default (so this gets items in sequence order)
# if not for update, do not use the clause :)
obj = UniqueId.objects.select_for_update() if forUpdate else UniqueId.objects
return obj.filter(
basename=self._baseName, seq__gte=rangeStart, seq__lte=rangeEnd
) # @UndefinedVariable
)
def get(self, rangeStart: int = 0, rangeEnd: int = MAX_SEQ) -> int:
"""

View File

@ -41,6 +41,7 @@ from uds.core.util import log
logger = logging.getLogger(__name__)
class HangedCleaner(Job):
frecuency = 3601
frecuency_cfg = GlobalConfig.MAX_INITIALIZING_TIME
@ -51,9 +52,7 @@ class HangedCleaner(Job):
since_state = now - timedelta(
seconds=GlobalConfig.MAX_INITIALIZING_TIME.getInt()
)
since_removing = now -timedelta(
seconds=GlobalConfig.MAX_REMOVAL_TIME.getInt()
)
since_removing = now - timedelta(seconds=GlobalConfig.MAX_REMOVAL_TIME.getInt())
# Filter for locating machine not ready
flt = Q(state_date__lt=since_state, state=State.PREPARING) | Q(
state_date__lt=since_state, state=State.USABLE, os_state=State.PREPARING
@ -72,7 +71,8 @@ class HangedCleaner(Job):
userServices__state_date__lt=since_state,
userServices__state=State.USABLE,
userServices__os_state=State.PREPARING,
) | Q(
)
| Q(
userServices__state_date__lt=since_removing,
userServices__state=State.REMOVING,
),
@ -95,7 +95,9 @@ class HangedCleaner(Job):
): # It's waiting for removal, skip this very specific case
continue
logger.debug('Found hanged service %s', us)
if us.state == State.REMOVING: # Removing too long, remark it as removable
if (
us.state == State.REMOVING
): # Removing too long, remark it as removable
log.doLog(
us,
log.ERROR,

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2013-2019 Virtual Cable S.L.
# Copyright (c) 2013-2019 Virtual Cable S.L.U.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
@ -11,7 +11,7 @@
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
# * Neither the name of Virtual Cable S.L.U. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
@ -35,6 +35,7 @@ class RequestDebug:
"""
Used for logging some request data on develeopment
"""
def __init__(self, get_response):
self.get_response = get_response

View File

@ -35,7 +35,11 @@ from .views import guacamole
urlpatterns = [
# Authenticated path
url(r'^uds/guacamole/auth/(?P<token>[^/]+)/(?P<tunnelId>.+)$', guacamole, name='dispatcher.guacamole'),
url(
r'^uds/guacamole/auth/(?P<token>[^/]+)/(?P<tunnelId>.+)$',
guacamole,
name='dispatcher.guacamole',
),
# Non authenticated path. Disabled
# url(r'^uds/guacamole/(?P<tunnelId>.+)$', guacamole, name='dispatcher.guacamole.noauth'),
]

View File

@ -54,7 +54,9 @@ def dict2resp(dct: typing.Mapping[typing.Any, typing.Any]) -> str:
return '\r'.join((str(k) + '\t' + str(v) for k, v in dct.items()))
def guacamole(request: ExtendedHttpRequestWithUser, token: str, tunnelId: str) -> HttpResponse:
def guacamole(
request: ExtendedHttpRequestWithUser, token: str, tunnelId: str
) -> HttpResponse:
if not TunnelToken.validateToken(token):
logger.error('Invalid token %s from %s', token, request.ip)
return HttpResponse(ERROR, content_type=CONTENT_TYPE)
@ -65,12 +67,14 @@ def guacamole(request: ExtendedHttpRequestWithUser, token: str, tunnelId: str) -
tunnelId, scrambler = tunnelId.split('.')
# All strings excetp "ticket-info", that is fixed if it exists later
val = typing.cast(typing.MutableMapping[str, str], TicketStore.get(tunnelId, invalidate=False))
val = typing.cast(
typing.MutableMapping[str, str], TicketStore.get(tunnelId, invalidate=False)
)
# Extra check that the ticket data belongs to original requested user service/user
if 'ticket-info' in val:
ti = typing.cast(typing.Mapping[str, str], val['ticket-info'])
del val['ticket-info'] # Do not send this data to guacamole!! :)
del val['ticket-info'] # Do not send this data to guacamole!! :)
try:
userService = UserService.objects.get(uuid=ti['userService'])
@ -85,16 +89,21 @@ def guacamole(request: ExtendedHttpRequestWithUser, token: str, tunnelId: str) -
userService.deployed_service,
events.ET_TUNNEL_OPEN,
username=userService.user.pretty_name,
source='HTML5-' + protocol, # On HTML5, currently src is not provided by Guacamole
source='HTML5-'
+ protocol, # On HTML5, currently src is not provided by Guacamole
dstip=host,
uniqueid=userService.unique_id,
)
except Exception:
logger.error('The requested guacamole userservice does not exists anymore')
logger.error(
'The requested guacamole userservice does not exists anymore'
)
raise
if userService.user.uuid != ti['user']:
logger.error('The requested userservice has changed owner and is not accesible')
logger.error(
'The requested userservice has changed owner and is not accesible'
)
raise Exception()
if 'password' in val:

View File

@ -34,5 +34,9 @@ from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^uds/ognotify/(?P<msg>[a-z]+)/(?P<token>[a-zA-Z0-9-_]+)/(?P<uuid>[a-zA-Z0-9-_]+)$', views.opengnsys, name='dispatcher.opengnsys'),
url(
r'^uds/ognotify/(?P<msg>[a-z]+)/(?P<token>[a-zA-Z0-9-_]+)/(?P<uuid>[a-zA-Z0-9-_]+)$',
views.opengnsys,
name='dispatcher.opengnsys',
),
]

View File

@ -52,7 +52,9 @@ def opengnsys(request: HttpRequest, msg: str, token: str, uuid: str) -> HttpResp
def getUserService() -> typing.Optional[UserService]:
try:
userService = UserService.objects.get(uuid=processUuid(uuid), state=states.userService.USABLE)
userService = UserService.objects.get(
uuid=processUuid(uuid), state=states.userService.USABLE
)
if userService.getProperty('token') == token:
return userService
logger.warning(
@ -63,7 +65,9 @@ def opengnsys(request: HttpRequest, msg: str, token: str, uuid: str) -> HttpResp
# Sleep a while in case of error?
except Exception as e:
# Any exception will stop process
logger.warning('OpenGnsys: invalid userService %s:%s. (Ignored)', token, uuid)
logger.warning(
'OpenGnsys: invalid userService %s:%s. (Ignored)', token, uuid
)
return None
@ -79,9 +83,14 @@ def opengnsys(request: HttpRequest, msg: str, token: str, uuid: str) -> HttpResp
if userService:
# Ignore login to cached machines...
if userService.cache_level != 0:
logger.info('Ignored OpenGnsys login to %s to cached machine', userService.friendly_name)
logger.info(
'Ignored OpenGnsys login to %s to cached machine',
userService.friendly_name,
)
return
logger.debug('Processing login from OpenGnsys %s', userService.friendly_name)
logger.debug(
'Processing login from OpenGnsys %s', userService.friendly_name
)
actor_v3.Login.process_login(userService, 'OpenGnsys')
def logout() -> None:
@ -89,9 +98,14 @@ def opengnsys(request: HttpRequest, msg: str, token: str, uuid: str) -> HttpResp
if userService:
# Ignore logout to cached machines...
if userService.cache_level != 0:
logger.info('Ignored OpenGnsys logout to %s to cached machine', userService.friendly_name)
logger.info(
'Ignored OpenGnsys logout to %s to cached machine',
userService.friendly_name,
)
return
logger.debug('Processing logout from OpenGnsys %s', userService.friendly_name)
logger.debug(
'Processing logout from OpenGnsys %s', userService.friendly_name
)
actor_v3.Logout.process_logout(userService, 'OpenGnsys')
fnc: typing.Optional[typing.Callable[[], None]] = {

View File

@ -54,7 +54,11 @@ def pam(request: ExtendedHttpRequestWithUser) -> HttpResponse:
# If request is not forged...
if len(ids) == 1:
userId = ids[0]
logger.debug("Auth request for user [%s] and pass [%s]", request.GET['id'], request.GET['pass'])
logger.debug(
"Auth request for user [%s] and pass [%s]",
request.GET['id'],
request.GET['pass'],
)
try:
password = TicketStore.get(userId)
if password == request.GET['pass']:
@ -63,7 +67,11 @@ def pam(request: ExtendedHttpRequestWithUser) -> HttpResponse:
# Non existing ticket, log it and stop
logger.info('Invalid access from %s using user %s', request.ip, userId)
else:
logger.warning('Invalid request from %s: %s', request.ip, [v for v in request.GET.lists()])
logger.warning(
'Invalid request from %s: %s',
request.ip,
[v for v in request.GET.lists()],
)
elif 'uid' in request.GET:
# This is an "get name for id" call
logger.debug("NSS Request for id [%s]", request.GET['uid'])

View File

@ -57,7 +57,9 @@ class Command(BaseCommand):
mod, name = first
else:
mod, name = GLOBAL_SECTION, first[0]
if Config.update(mod, name, value) is False: # If not exists, try to store value without any special parameters
if (
Config.update(mod, name, value) is False
): # If not exists, try to store value without any special parameters
Config.section(mod).value(name, value).get()
except Exception as e:
print('The command could not be processed: {}'.format(e))

View File

@ -50,9 +50,15 @@ PID_FILE = 'taskmanager.pid'
def getPidFile():
return settings.BASE_DIR + '/' + PID_FILE
# become_daemon seems te be removed on django 1.9
# This is a copy of posix version from django 1.8
def become_daemon(our_home_dir: str = '.', out_log: str = '/dev/null', err_log: str = '/dev/null', umask: int = 0o022):
def become_daemon(
our_home_dir: str = '.',
out_log: str = '/dev/null',
err_log: str = '/dev/null',
umask: int = 0o022,
):
"""Robustly turn into a UNIX daemon, running in our_home_dir."""
# First fork
try:
@ -93,21 +99,21 @@ class Command(BaseCommand):
action='store_true',
dest='start',
default=False,
help='Starts a new daemon'
help='Starts a new daemon',
)
parser.add_argument(
'--stop',
action='store_true',
dest='stop',
default=False,
help='Stop any running daemon'
help='Stop any running daemon',
)
parser.add_argument(
'--foreground',
action='store_true',
dest='foreground',
default=False,
help='Stop any running daemon'
help='Stop any running daemon',
)
def handle(self, *args, **options) -> None:
@ -141,7 +147,11 @@ class Command(BaseCommand):
logger.info('Starting task manager.')
if not foreground:
become_daemon(settings.BASE_DIR, settings.LOGDIR + '/taskManagerStdout.log', settings.LOGDIR + '/taskManagerStderr.log')
become_daemon(
settings.BASE_DIR,
settings.LOGDIR + '/taskManagerStdout.log',
settings.LOGDIR + '/taskManagerStderr.log',
)
pid = os.getpid()
open(getPidFile(), 'w+').write('{}\n'.format(pid))
@ -149,8 +159,10 @@ class Command(BaseCommand):
manager = taskManager()()
manager.run()
if not start and not stop:
if not start and not stop:
if pid:
sys.stdout.write("Task manager found running (pid file exists: {0})\n".format(pid))
sys.stdout.write(
"Task manager found running (pid file exists: {0})\n".format(pid)
)
else:
sys.stdout.write("Task manager not foud (pid file do not exits)\n")

View File

@ -105,7 +105,7 @@ class Authenticator(ManagedObjectModel, TaggingMixin):
"""
Get the type of the object this record represents.
The type is Python type, it obtains this type from ServiceProviderFactory and associated record field.
The type is Python type, it obtains this type from AuthsFactory and associated record field.
Returns:
The python type for this record object

View File

@ -64,7 +64,7 @@ class Config(models.Model):
constraints = [
models.UniqueConstraint(fields=['section', 'key'], name='u_cfg_section_key')
]
app_label = 'uds'
def __str__(self) -> str:

View File

@ -48,8 +48,11 @@ class DelayedTask(models.Model):
This table contains uds.core.util.jobs.DelayedTask references
"""
type = models.CharField(max_length=128)
tag = models.CharField(max_length=64, db_index=True) # A tag for letting us locate delayed publications...
tag = models.CharField(
max_length=64, db_index=True
) # A tag for letting us locate delayed publications...
instance = models.TextField()
insert_date = models.DateTimeField()
execution_delay = models.PositiveIntegerField()
@ -62,7 +65,10 @@ class DelayedTask(models.Model):
"""
Meta class to declare default order and unique multiple field index
"""
app_label = 'uds'
def __str__(self) -> str:
return "Run Queue task {0} owned by {3},inserted at {1} and with {2} seconds delay".format(self.type, self.insert_date, self.execution_delay, self.execution_time)
return "Run Queue task {0} owned by {3},inserted at {1} and with {2} seconds delay".format(
self.type, self.insert_date, self.execution_delay, self.execution_time
)

View File

@ -79,7 +79,9 @@ class Group(UUIDModel):
app_label = 'uds'
# unique_together = (("manager", "name"),)
constraints = [
models.UniqueConstraint(fields=['manager', 'name'], name='u_grp_manager_name')
models.UniqueConstraint(
fields=['manager', 'name'], name='u_grp_manager_name'
)
]
@property

View File

@ -81,7 +81,7 @@ class MetaPool(UUIDModel, TaggingMixin): # type: ignore
TRANSPORT_SELECT: typing.Mapping[int, str] = {
AUTO_TRANSPORT_SELECT: _('Automatic selection'),
COMMON_TRANSPORT_SELECT: _('Use only common transports'),
LABEL_TRANSPORT_SELECT: _('Group Transports by label')
LABEL_TRANSPORT_SELECT: _('Group Transports by label'),
}
name = models.CharField(max_length=128, default='')

View File

@ -72,7 +72,7 @@ class OSManager(ManagedObjectModel, TaggingMixin): # type: ignore
"""
Get the type of the object this record represents.
The type is Python type, it obtains this type from ServiceProviderFactory and associated record field.
The type is Python type, it obtains this OsManagersFactory and associated record field.
Returns:
The python type for this record object

View File

@ -88,7 +88,9 @@ class Service(ManagedObjectModel, TaggingMixin): # type: ignore
ordering = ('name',)
app_label = 'uds'
constraints = [
models.UniqueConstraint(fields=['provider', 'name'], name='u_srv_provider_name')
models.UniqueConstraint(
fields=['provider', 'name'], name='u_srv_provider_name'
)
]
def getEnvironment(self) -> Environment:
@ -105,7 +107,9 @@ class Service(ManagedObjectModel, TaggingMixin): # type: ignore
},
)
def getInstance(self, values: typing.Optional[typing.Dict[str, str]] = None) -> 'services.Service':
def getInstance(
self, values: typing.Optional[typing.Dict[str, str]] = None
) -> 'services.Service':
"""
Instantiates the object this record contains.

View File

@ -159,7 +159,7 @@ class ServicePool(UUIDModel, TaggingMixin): # type: ignore
userServices: 'models.QuerySet[UserService]'
calendarAccess: 'models.QuerySet[CalendarAccess]'
changelog: 'models.QuerySet[ServicePoolPublicationChangelog]'
calendaraction_set: typing.Any
class Meta(UUIDModel.Meta):

View File

@ -49,11 +49,18 @@ class ServicePoolGroup(UUIDModel):
"""
A deployed service is the Service produced element that is assigned finally to an user (i.e. a Virtual Machine, etc..)
"""
# pylint: disable=model-missing-unicode
name = models.CharField(max_length=128, default='', db_index=True, unique=True)
comments = models.CharField(max_length=256, default='')
priority = models.IntegerField(default=0, db_index=True)
image: 'models.ForeignKey[ServicePoolGroup, Image]' = models.ForeignKey(Image, null=True, blank=True, related_name='servicesPoolsGroup', on_delete=models.SET_NULL)
image: 'models.ForeignKey[ServicePoolGroup, Image]' = models.ForeignKey(
Image,
null=True,
blank=True,
related_name='servicesPoolsGroup',
on_delete=models.SET_NULL,
)
# "fake" declarations for type checking
objects: 'models.BaseManager[ServicePoolGroup]'
@ -62,11 +69,14 @@ class ServicePoolGroup(UUIDModel):
"""
Meta class to declare the name of the table at database
"""
db_table = 'uds__pools_groups'
app_label = 'uds'
def __str__(self) -> str:
return 'Service Pool group {}({}): {}'.format(self.name, self.comments, self.image.name)
return 'Service Pool group {}({}): {}'.format(
self.name, self.comments, self.image.name
)
@property
def as_dict(self) -> typing.MutableMapping[str, typing.Any]:
@ -75,12 +85,12 @@ class ServicePoolGroup(UUIDModel):
'name': self.name,
'comments': self.comments,
'priority': self.priority,
'imageUuid': self.image.uuid if self.image is not None else 'x'
'imageUuid': self.image.uuid if self.image is not None else 'x',
}
@property
def thumb64(self) -> str:
return self.image.thumb64 if self.image else DEFAULT_THUMB_BASE64
return self.image.thumb64 if self.image else DEFAULT_THUMB_BASE64
@staticmethod
def default() -> 'ServicePoolGroup':

View File

@ -109,7 +109,6 @@ class ServicePoolPublication(UUIDModel):
objects: 'models.BaseManager[ServicePoolPublication]'
userServices: 'models.QuerySet[UserService]'
class Meta(UUIDModel.Meta):
"""
Meta class to declare default order and unique multiple field index

View File

@ -73,7 +73,7 @@ class StatsCounters(models.Model):
@staticmethod
def get_grouped(
owner_type: typing.Union[int, typing.Iterable[int]], counter_type: int, **kwargs
) -> 'models.QuerySet[StatsCounters]': # pylint: disable=too-many-locals
) -> 'models.QuerySet[StatsCounters]':
"""
Returns the average stats grouped by interval for owner_type and owner_id (optional)

View File

@ -42,10 +42,13 @@ class Storage(models.Model):
General storage model. Used to store specific instances (transport, service, servicemanager, ...) persistent information
not intended to be serialized/deserialized everytime one object instance is loaded/saved.
"""
owner = models.CharField(max_length=128, db_index=True)
key = models.CharField(max_length=64, primary_key=True)
data = models.TextField(default='')
attr1 = models.CharField(max_length=64, db_index=True, null=True, blank=True, default=None)
attr1 = models.CharField(
max_length=64, db_index=True, null=True, blank=True, default=None
)
# "fake" declarations for type checking
objects: 'models.BaseManager[Storage]'
@ -54,7 +57,10 @@ class Storage(models.Model):
"""
Meta class to declare the name of the table at database
"""
app_label = 'uds'
def __str__(self) -> str:
return '{} {} > str= {}, {}'.format(self.owner, self.key, self.data, '/'.join([self.attr1]))
return '{} {} > str= {}, {}'.format(
self.owner, self.key, self.data, '/'.join([self.attr1])
)

View File

@ -89,7 +89,9 @@ class TicketStore(UUIDModel):
@staticmethod
def generateUuid() -> str:
return cryptoManager().randomString(40).lower() # Temporary fix lower() for compat with 3.0
return (
cryptoManager().randomString(40).lower()
) # Temporary fix lower() for compat with 3.0
@staticmethod
def create(

View File

@ -88,7 +88,7 @@ class Transport(ManagedObjectModel, TaggingMixin):
"""
Get the type of the object this record represents.
The type is Python type, it obtains this type from ServiceProviderFactory and associated record field.
The type is Python type, it obtains this type from TransportsFactory and associated record field.
Returns:
The python type for this record object

View File

@ -33,6 +33,7 @@ import typing
from django.db import models
from uds.core.util.request import ExtendedHttpRequest
class TunnelToken(models.Model):
"""
UDS Tunnel tokens on DB
@ -56,7 +57,9 @@ class TunnelToken(models.Model):
]
@staticmethod
def validateToken(token: str, request: typing.Optional[ExtendedHttpRequest] = None) -> bool:
def validateToken(
token: str, request: typing.Optional[ExtendedHttpRequest] = None
) -> bool:
try:
tt = TunnelToken.objects.get(token=token)
# We could check the request ip here

View File

@ -187,18 +187,18 @@ class User(UUIDModel):
number_belongs_meta=Count('groups', filter=Q(groups__id__in=grps))
) # g.groups.filter(id__in=grps).count()
):
numberGroupsBelongingInMeta: int = g.number_belongs_meta
numberGroupsBelongingInMeta: int = g.number_belongs_meta # type: ignore # anottation
logger.debug('gn = %s', numberGroupsBelongingInMeta)
logger.debug('groups count: %s', g.number_groups)
logger.debug('groups count: %s', g.number_groups) # type: ignore # anottation
if g.meta_if_any is True and numberGroupsBelongingInMeta > 0:
numberGroupsBelongingInMeta = g.number_groups
numberGroupsBelongingInMeta = g.number_groups # type: ignore # anottation
logger.debug('gn after = %s', numberGroupsBelongingInMeta)
# If a meta group is empty, all users belongs to it. we can use gn != 0 to check that if it is empty, is not valid
if numberGroupsBelongingInMeta == g.number_groups:
if numberGroupsBelongingInMeta == g.number_groups: # type: ignore # anottation
# This group matches
yield g

View File

@ -63,7 +63,9 @@ class UserServiceProperty(models.Model): # pylint: disable=too-many-public-meth
db_table = 'uds__user_service_property'
app_label = 'uds'
constraints = [
models.UniqueConstraint(fields=['name', 'user_service'], name='u_uprop_name_userservice')
models.UniqueConstraint(
fields=['name', 'user_service'], name='u_uprop_name_userservice'
)
]
def __str__(self) -> str:

View File

@ -42,6 +42,7 @@ logger = logging.getLogger(__name__)
NEVER = datetime(1972, 7, 1)
NEVER_UNIX = int(mktime(NEVER.timetuple()))
class UnsavedForeignKey(models.ForeignKey):
"""
From 1.8 of django, we need to point to "saved" objects.
@ -49,9 +50,11 @@ class UnsavedForeignKey(models.ForeignKey):
We need to trick in some cases, because for example, root user is not in DB
"""
# Allows pointing to an unsaved object
allow_unsaved_instance_assignment = True
def getSqlDatetime() -> datetime:
"""
Returns the current date/time of the database server.
@ -64,17 +67,25 @@ def getSqlDatetime() -> datetime:
"""
if connection.vendor in ('mysql', 'microsoft'):
cursor = connection.cursor()
sentence = 'SELECT NOW()' if connection.vendor == 'mysql' else 'SELECT CURRENT_TIMESTAMP'
sentence = (
'SELECT NOW()'
if connection.vendor == 'mysql'
else 'SELECT CURRENT_TIMESTAMP'
)
cursor.execute(sentence)
date = cursor.fetchone()[0]
else:
date = datetime.now() # If not know how to get database datetime, returns local datetime (this is fine for sqlite, which is local)
date = (
datetime.now()
) # If not know how to get database datetime, returns local datetime (this is fine for sqlite, which is local)
return date
def getSqlDatetimeAsUnix() -> int:
return int(mktime(getSqlDatetime().timetuple()))
def getSqlFnc(fncName: str) -> str:
"""
Convert different sql functions for different platforms

View File

@ -46,42 +46,60 @@ OSManagersFactory.factory().insert(LinuxRandomPassManager)
downloadsManager().registerDownloadable(
'udsactor_{version}_all.deb'.format(version=VERSION),
_('UDS Actor for Debian, Ubuntu, ... Linux machines <b>(Requires python >= 3.6)</b>'),
os.path.dirname(sys.modules[__package__].__file__) + '/files/udsactor_{version}_all.deb'.format(version=VERSION),
'application/x-debian-package'
_(
'UDS Actor for Debian, Ubuntu, ... Linux machines <b>(Requires python >= 3.6)</b>'
),
os.path.dirname(sys.modules[__package__].__file__)
+ '/files/udsactor_{version}_all.deb'.format(version=VERSION),
'application/x-debian-package',
)
downloadsManager().registerDownloadable(
'udsactor-{version}-1.noarch.rpm'.format(version=VERSION),
_('UDS Actor for Centos, Fedora, RH, Suse, ... Linux machines <b>(Requires python >= 3.6)</b>'),
os.path.dirname(sys.modules[__package__].__file__) + '/files/udsactor-{version}-1.noarch.rpm'.format(version=VERSION),
'application/x-redhat-package-manager'
_(
'UDS Actor for Centos, Fedora, RH, Suse, ... Linux machines <b>(Requires python >= 3.6)</b>'
),
os.path.dirname(sys.modules[__package__].__file__)
+ '/files/udsactor-{version}-1.noarch.rpm'.format(version=VERSION),
'application/x-redhat-package-manager',
)
downloadsManager().registerDownloadable(
'udsactor-unmanaged_{version}_all.deb'.format(version=VERSION),
_('UDS Actor for Debian based Linux machines. Used ONLY for static machines. <b>(Requires python >= 3.6)</b>'),
os.path.dirname(sys.modules[__package__].__file__) + '/files/udsactor-unmanaged_{version}_all.deb'.format(version=VERSION),
'application/x-debian-package'
_(
'UDS Actor for Debian based Linux machines. Used ONLY for static machines. <b>(Requires python >= 3.6)</b>'
),
os.path.dirname(sys.modules[__package__].__file__)
+ '/files/udsactor-unmanaged_{version}_all.deb'.format(version=VERSION),
'application/x-debian-package',
)
downloadsManager().registerDownloadable(
'udsactor_2.2.0_legacy.deb',
_('<b>Legacy</b> UDS Actor for Debian, Ubuntu, ... Linux machines <b>(Requires python 2.7)</b>'),
os.path.dirname(sys.modules[__package__].__file__) + '/files/udsactor_2.2.0_legacy.deb',
'application/x-debian-package'
_(
'<b>Legacy</b> UDS Actor for Debian, Ubuntu, ... Linux machines <b>(Requires python 2.7)</b>'
),
os.path.dirname(sys.modules[__package__].__file__)
+ '/files/udsactor_2.2.0_legacy.deb',
'application/x-debian-package',
)
downloadsManager().registerDownloadable(
'udsactor-legacy-2.2.1-1.noarch.rpm',
_('<b>Legacy</b> UDS Actor for Centos, Fedora, RH, ... Linux machines <b>(Requires python 2.7)</b>'),
os.path.dirname(sys.modules[__package__].__file__) + '/files/udsactor-legacy-2.2.1-1.noarch.rpm',
'application/x-redhat-package-manager'
_(
'<b>Legacy</b> UDS Actor for Centos, Fedora, RH, ... Linux machines <b>(Requires python 2.7)</b>'
),
os.path.dirname(sys.modules[__package__].__file__)
+ '/files/udsactor-legacy-2.2.1-1.noarch.rpm',
'application/x-redhat-package-manager',
)
downloadsManager().registerDownloadable(
'udsactor-opensuse-legacy-2.2.1-1.noarch.rpm',
_('<b>Legacy</b> UDS Actor for OpenSUSE, ... Linux machines <b>(Requires python 2.7)</b>'),
os.path.dirname(sys.modules[__package__].__file__) + '/files/udsactor-opensuse-legacy-2.2.1-1.noarch.rpm',
'application/x-redhat-package-manager'
_(
'<b>Legacy</b> UDS Actor for OpenSUSE, ... Linux machines <b>(Requires python 2.7)</b>'
),
os.path.dirname(sys.modules[__package__].__file__)
+ '/files/udsactor-opensuse-legacy-2.2.1-1.noarch.rpm',
'application/x-redhat-package-manager',
)

View File

@ -65,17 +65,25 @@ class LinuxOsManager(osmanagers.OSManager):
values=[
{'id': 'keep', 'text': ugettext_lazy('Keep service assigned')},
{'id': 'remove', 'text': ugettext_lazy('Remove service')},
{'id': 'keep-always', 'text': ugettext_lazy('Keep service assigned even on new publication')},
{
'id': 'keep-always',
'text': ugettext_lazy('Keep service assigned even on new publication'),
},
],
defvalue='keep')
defvalue='keep',
)
idle = gui.NumericField(
label=_("Max.Idle time"),
length=4,
defvalue=-1,
rdonly=False, order=11,
tooltip=_('Maximum idle time (in seconds) before session is automatically closed to the user (<= 0 means no max idle time).'),
required=True)
rdonly=False,
order=11,
tooltip=_(
'Maximum idle time (in seconds) before session is automatically closed to the user (<= 0 means no max idle time).'
),
required=True,
)
deadLine = gui.CheckBoxField(
label=_('Calendar logout'),
@ -114,7 +122,9 @@ class LinuxOsManager(osmanagers.OSManager):
Says if a machine is removable on logout
'''
if not userService.in_use:
if (self._onLogout == 'remove') or (not userService.isValidPublication() and self._onLogout == 'keep'):
if (self._onLogout == 'remove') or (
not userService.isValidPublication() and self._onLogout == 'keep'
):
return True
return False
@ -174,13 +184,18 @@ class LinuxOsManager(osmanagers.OSManager):
def readyNotified(self, userService):
return
def actorData(self, userService: 'UserService') -> typing.MutableMapping[str, typing.Any]:
return {
'action': 'rename',
'name': userService.getName()
}
def actorData(
self, userService: 'UserService'
) -> typing.MutableMapping[str, typing.Any]:
return {'action': 'rename', 'name': userService.getName()}
def process(self, userService: 'UserService', message: str, data: typing.Any, options: typing.Optional[typing.Dict[str, typing.Any]] = None) -> str:
def process(
self,
userService: 'UserService',
message: str,
data: typing.Any,
options: typing.Optional[typing.Dict[str, typing.Any]] = None,
) -> str:
"""
We understand this messages:
* msg = info, data = None. Get information about name of machine (or domain, in derived WinDomainOsManager class), old method
@ -189,17 +204,24 @@ class LinuxOsManager(osmanagers.OSManager):
* msg = logoff, data = Username, Informs that the username has logged out of the machine
* msg = ready, data = None, Informs machine ready to be used
"""
logger.info("Invoked LinuxOsManager for %s with params: %s, %s", userService, message, data)
logger.info(
"Invoked LinuxOsManager for %s with params: %s, %s",
userService,
message,
data,
)
# We get from storage the name for this userService. If no name, we try to assign a new one
ret = "ok"
notifyReady = False
doRemove = False
state = userService.os_state
if message in ('ready', 'ip'):
if not isinstance(data, dict): # Older actors?, previous to 2.5, convert it information..
if not isinstance(
data, dict
): # Older actors?, previous to 2.5, convert it information..
data = {
'ips': [v.split('=') for v in typing.cast(str, data).split(',')],
'hostname': userService.friendly_name
'hostname': userService.friendly_name,
}
# Old "info" state, will be removed in a near future
@ -246,7 +268,12 @@ class LinuxOsManager(osmanagers.OSManager):
This function can update userService values. Normal operation will be remove machines if this state is not valid
"""
if self.isRemovableOnLogout(userService):
log.doLog(userService, log.INFO, 'Unused user service for too long. Removing due to OS Manager parameters.', log.OSMANAGER)
log.doLog(
userService,
log.INFO,
'Unused user service for too long. Removing due to OS Manager parameters.',
log.OSMANAGER,
)
userService.remove()
def isPersistent(self):
@ -260,7 +287,9 @@ class LinuxOsManager(osmanagers.OSManager):
"""
On production environments, will return no idle for non removable machines
"""
if self._idle <= 0: # or (settings.DEBUG is False and self._onLogout != 'remove'):
if (
self._idle <= 0
): # or (settings.DEBUG is False and self._onLogout != 'remove'):
return None
return self._idle
@ -269,7 +298,9 @@ class LinuxOsManager(osmanagers.OSManager):
"""
Serializes the os manager data so we can store it in database
"""
return '\t'.join(['v3', self._onLogout, str(self._idle), gui.boolToStr(self._deadLine)]).encode('utf8')
return '\t'.join(
['v3', self._onLogout, str(self._idle), gui.boolToStr(self._deadLine)]
).encode('utf8')
def unmarshal(self, data: bytes):
values = data.decode('utf8').split('\t')
@ -280,9 +311,17 @@ class LinuxOsManager(osmanagers.OSManager):
elif values[0] == 'v2':
self._onLogout, self._idle = values[1], int(values[2])
elif values[0] == 'v3':
self._onLogout, self._idle, self._deadLine = values[1], int(values[2]), gui.strToBool(values[3])
self._onLogout, self._idle, self._deadLine = (
values[1],
int(values[2]),
gui.strToBool(values[3]),
)
self.__setProcessUnusedMachines()
def valuesDict(self) -> gui.ValuesDictType:
return {'onLogout': self._onLogout, 'idle': str(self._idle), 'deadLine': gui.boolToStr(self._deadLine) }
return {
'onLogout': self._onLogout,
'idle': str(self._idle),
'deadLine': gui.boolToStr(self._deadLine),
}

View File

@ -48,14 +48,23 @@ logger = logging.getLogger(__name__)
if typing.TYPE_CHECKING:
from uds.models.user_service import UserService
class LinuxRandomPassManager(LinuxOsManager):
typeName = _('Linux Random Password OS Manager')
typeType = 'LinRandomPasswordManager'
typeDescription = _('Os Manager to control linux machines, with user password set randomly.')
typeDescription = _(
'Os Manager to control linux machines, with user password set randomly.'
)
iconFile = 'losmanager.png'
# Apart form data from linux os manager, we need also domain and credentials
userAccount = gui.TextField(length=64, label=_('Account'), order=2, tooltip=_('User account to change password'), required=True)
userAccount = gui.TextField(
length=64,
label=_('Account'),
order=2,
tooltip=_('User account to change password'),
required=True,
)
# Inherits base "onLogout"
onLogout = LinuxOsManager.onLogout
@ -68,12 +77,16 @@ class LinuxRandomPassManager(LinuxOsManager):
super(LinuxRandomPassManager, self).__init__(environment, values)
if values is not None:
if values['userAccount'] == '':
raise osmanagers.OSManager.ValidationException(_('Must provide an user account!!!'))
raise osmanagers.OSManager.ValidationException(
_('Must provide an user account!!!')
)
self._userAccount = values['userAccount']
else:
self._userAccount = ''
def processUserPassword(self, userService: 'UserService', username: str, password: str) -> typing.Tuple[str, str]:
def processUserPassword(
self, userService: 'UserService', username: str, password: str
) -> typing.Tuple[str, str]:
if username == self._userAccount:
return (username, userService.recoverValue('linOsRandomPass'))
return username, password
@ -81,25 +94,39 @@ class LinuxRandomPassManager(LinuxOsManager):
def genPassword(self, service):
randomPass = service.recoverValue('linOsRandomPass')
if randomPass is None:
randomPass = ''.join(random.SystemRandom().choice(string.ascii_letters + string.digits) for _ in range(16))
randomPass = ''.join(
random.SystemRandom().choice(string.ascii_letters + string.digits)
for _ in range(16)
)
service.storeValue('linOsRandomPass', randomPass)
log.doLog(service, log.INFO, "Password set to \"{}\"".format(randomPass), log.OSMANAGER)
log.doLog(
service,
log.INFO,
"Password set to \"{}\"".format(randomPass),
log.OSMANAGER,
)
return randomPass
def infoVal(self, service):
return 'rename:{0}\t{1}\t\t{2}'.format(self.getName(service), self._userAccount, self.genPassword(service))
return 'rename:{0}\t{1}\t\t{2}'.format(
self.getName(service), self._userAccount, self.genPassword(service)
)
def infoValue(self, service):
return 'rename\r{0}\t{1}\t\t{2}'.format(self.getName(service), self._userAccount, self.genPassword(service))
return 'rename\r{0}\t{1}\t\t{2}'.format(
self.getName(service), self._userAccount, self.genPassword(service)
)
def actorData(self, userService: 'UserService') -> typing.MutableMapping[str, typing.Any]:
def actorData(
self, userService: 'UserService'
) -> typing.MutableMapping[str, typing.Any]:
return {
'action': 'rename',
'name': userService.getName(),
'username': self._userAccount,
'password': '', # On linux, user password is not needed so we provide an empty one
'new_password': self.genPassword(userService)
'new_password': self.genPassword(userService),
}
def marshal(self) -> bytes:
@ -107,7 +134,9 @@ class LinuxRandomPassManager(LinuxOsManager):
Serializes the os manager data so we can store it in database
"""
base = LinuxOsManager.marshal(self)
return '\t'.join(['v1', self._userAccount, codecs.encode(base, 'hex').decode()]).encode('utf8')
return '\t'.join(
['v1', self._userAccount, codecs.encode(base, 'hex').decode()]
).encode('utf8')
def unmarshal(self, data: bytes) -> None:
values = data.split(b'\t')

View File

@ -50,11 +50,15 @@ osmanagers.factory().insert(WinRandomPassManager)
managers.downloadsManager().registerDownloadable(
'UDSActorSetup-{version}.exe'.format(version=VERSION),
_('UDS Actor for windows machines'),
os.path.dirname(sys.modules[__package__].__file__) + '/files/UDSActorSetup-{version}.exe'.format(version=VERSION),
'application/x-msdos-program')
os.path.dirname(sys.modules[__package__].__file__)
+ '/files/UDSActorSetup-{version}.exe'.format(version=VERSION),
'application/x-msdos-program',
)
managers.downloadsManager().registerDownloadable(
'UDSActorUnmanagedSetup-{version}.exe'.format(version=VERSION),
_('UDS Actor for Unmanaged windows machines. Used ONLY for static machines.'),
os.path.dirname(sys.modules[__package__].__file__) + '/files/UDSActorUnmanagedSetup-{version}.exe'.format(version=VERSION),
'application/x-msdos-program')
os.path.dirname(sys.modules[__package__].__file__)
+ '/files/UDSActorUnmanagedSetup-{version}.exe'.format(version=VERSION),
'application/x-msdos-program',
)

View File

@ -350,7 +350,9 @@ class WindowsOsManager(osmanagers.OSManager):
"""
Serializes the os manager data so we can store it in database
"""
return '\t'.join(['v3', self._onLogout, str(self._idle), gui.boolToStr(self._deadLine)]).encode('utf8')
return '\t'.join(
['v3', self._onLogout, str(self._idle), gui.boolToStr(self._deadLine)]
).encode('utf8')
def unmarshal(self, data: bytes) -> None:
vals = data.decode('utf8').split('\t')
@ -362,7 +364,11 @@ class WindowsOsManager(osmanagers.OSManager):
elif vals[0] == 'v2':
self._onLogout, self._idle = vals[1], int(vals[2])
elif vals[0] == 'v3':
self._onLogout, self._idle, self._deadLine = vals[1], int(vals[2]), gui.strToBool(vals[3])
self._onLogout, self._idle, self._deadLine = (
vals[1],
int(vals[2]),
gui.strToBool(vals[3]),
)
except Exception:
logger.exception(
'Exception unmarshalling. Some values left as default ones'
@ -371,4 +377,8 @@ class WindowsOsManager(osmanagers.OSManager):
self.__setProcessUnusedMachines()
def valuesDict(self) -> gui.ValuesDictType:
return {'onLogout': self._onLogout, 'idle': str(self._idle), 'deadLine': gui.boolToStr(self._deadLine) }
return {
'onLogout': self._onLogout,
'idle': str(self._idle),
'deadLine': gui.boolToStr(self._deadLine),
}

View File

@ -58,12 +58,26 @@ logger = logging.getLogger(__name__)
class WinRandomPassManager(WindowsOsManager):
typeName = _('Windows Random Password OS Manager')
typeType = 'WinRandomPasswordManager'
typeDescription = _('Os Manager to control windows machines, with user password set randomly.')
typeDescription = _(
'Os Manager to control windows machines, with user password set randomly.'
)
iconFile = 'wosmanager.png'
# Apart form data from windows os manager, we need also domain and credentials
userAccount = gui.TextField(length=64, label=_('Account'), order=2, tooltip=_('User account to change password'), required=True)
password = gui.PasswordField(length=64, label=_('Password'), order=3, tooltip=_('Current (template) password of the user account'), required=True)
userAccount = gui.TextField(
length=64,
label=_('Account'),
order=2,
tooltip=_('User account to change password'),
required=True,
)
password = gui.PasswordField(
length=64,
label=_('Password'),
order=3,
tooltip=_('Current (template) password of the user account'),
required=True,
)
# Inherits base "onLogout"
onLogout = WindowsOsManager.onLogout
@ -74,55 +88,87 @@ class WinRandomPassManager(WindowsOsManager):
super().__init__(environment, values)
if values:
if values['userAccount'] == '':
raise osmanagers.OSManager.ValidationException(_('Must provide an user account!!!'))
raise osmanagers.OSManager.ValidationException(
_('Must provide an user account!!!')
)
if values['password'] == '':
raise osmanagers.OSManager.ValidationException(_('Must provide a password for the account!!!'))
raise osmanagers.OSManager.ValidationException(
_('Must provide a password for the account!!!')
)
self._userAccount = values['userAccount']
self._password = values['password']
else:
self._userAccount = ''
self._password = ""
def processUserPassword(self, userService: 'UserService', username: str, password: str) -> typing.Tuple[str, str]:
def processUserPassword(
self, userService: 'UserService', username: str, password: str
) -> typing.Tuple[str, str]:
if username == self._userAccount:
password = userService.recoverValue('winOsRandomPass')
return WindowsOsManager.processUserPassword(self, userService, username, password)
return WindowsOsManager.processUserPassword(
self, userService, username, password
)
def genPassword(self, userService: 'UserService'):
randomPass = userService.recoverValue('winOsRandomPass')
if not randomPass:
# Generates a password that conforms to complexity
rnd = random.SystemRandom()
base = ''.join(rnd.choice(v) for v in (string.ascii_lowercase, string.ascii_uppercase, string.digits)) + rnd.choice('.+-')
randomPass = ''.join(rnd.choice(string.ascii_letters + string.digits) for _ in range(12))
base = ''.join(
rnd.choice(v)
for v in (string.ascii_lowercase, string.ascii_uppercase, string.digits)
) + rnd.choice('.+-')
randomPass = ''.join(
rnd.choice(string.ascii_letters + string.digits) for _ in range(12)
)
pos = rnd.randrange(0, len(randomPass))
randomPass = randomPass[:pos] + base + randomPass[pos:]
userService.storeValue('winOsRandomPass', randomPass)
log.doLog(userService, log.INFO, "Password set to \"{}\"".format(randomPass), log.OSMANAGER)
log.doLog(
userService,
log.INFO,
"Password set to \"{}\"".format(randomPass),
log.OSMANAGER,
)
return randomPass
def actorData(self, userService: 'UserService') -> typing.MutableMapping[str, typing.Any]:
def actorData(
self, userService: 'UserService'
) -> typing.MutableMapping[str, typing.Any]:
return {
'action': 'rename',
'name': userService.getName(),
'username': self._userAccount,
'password': self._password,
'new_password': self.genPassword(userService)
'new_password': self.genPassword(userService),
}
def infoVal(self, userService: 'UserService') -> str:
return 'rename:{0}\t{1}\t{2}\t{3}'.format(self.getName(userService), self._userAccount, self._password, self.genPassword(userService))
return 'rename:{0}\t{1}\t{2}\t{3}'.format(
self.getName(userService),
self._userAccount,
self._password,
self.genPassword(userService),
)
def infoValue(self, userService: 'UserService') -> str:
return 'rename\r{0}\t{1}\t{2}\t{3}'.format(self.getName(userService), self._userAccount, self._password, self.genPassword(userService))
return 'rename\r{0}\t{1}\t{2}\t{3}'.format(
self.getName(userService),
self._userAccount,
self._password,
self.genPassword(userService),
)
def marshal(self) -> bytes:
'''
Serializes the os manager data so we can store it in database
'''
base = codecs.encode(super().marshal(), 'hex').decode()
return '\t'.join(['v1', self._userAccount, cryptoManager().encrypt(self._password), base]).encode('utf8')
return '\t'.join(
['v1', self._userAccount, cryptoManager().encrypt(self._password), base]
).encode('utf8')
def unmarshal(self, data: bytes) -> None:
values = data.decode('utf8').split('\t')

View File

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2012 Virtual Cable S.L.
# Copyright (c) 2012-2021 Virtual Cable S.L.U.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
@ -12,7 +12,7 @@
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
# * Neither the name of Virtual Cable S.L.U. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
@ -53,7 +53,7 @@ def __init__():
"""
from uds.core import osmanagers
# Dinamycally import children of this package. The __init__.py files must register, if needed, inside ServiceProviderFactory
# Dinamycally import children of this package.
pkgpath = os.path.dirname(sys.modules[__name__].__file__)
for _, name, _ in pkgutil.iter_modules([pkgpath]):
@ -63,7 +63,7 @@ def __init__():
importlib.invalidate_caches()
p = osmanagers.OSManager
# This is marked as error in IDE, but it's not (__subclasses__)
for cls in p.__subclasses__():
osmanagers.factory().insert(cls)

View File

@ -32,7 +32,3 @@
"""
from .provider import PhysicalMachinesProvider
# Now we use __subclasses__ method to locate Service Providers
# and register them inside factory
# ServiceProviderFactory.factory().insert(PhysicalMachinesProvider)

View File

@ -58,7 +58,7 @@ def __init__():
"""
from uds.core import services
# Dinamycally import children of this package. The __init__.py files must register, if needed, inside ServiceProviderFactory
# Dinamycally import children of this package.
pkgpath = os.path.dirname(sys.modules[__name__].__file__)
for _, name, _ in pkgutil.iter_modules([pkgpath]):
# __import__('uds.services.' + name, globals(), locals(), [])