forked from shaba/openuds
Several Fixes:
* Upgraded typing information on models * Removed unused DBFile * renamed osmanager.png wrong name
This commit is contained in:
parent
8c40320b64
commit
57f2c35af0
@ -129,7 +129,7 @@ class Authenticators(ModelHandler):
|
||||
'values': [gui.choiceItem('', _('None'))]
|
||||
+ gui.sortedChoices(
|
||||
[
|
||||
gui.choiceItem(v.uuid, v.name)
|
||||
gui.choiceItem(v.uuid or '', v.name)
|
||||
for v in MFA.objects.all()
|
||||
]
|
||||
),
|
||||
|
@ -97,6 +97,7 @@ class Module(UserInterface, Environmentable, Serializable):
|
||||
Environmentable is a base class that provides utility method to access a separate Environment for every single
|
||||
module.
|
||||
"""
|
||||
|
||||
__slots__ = ['_uuid']
|
||||
# Import variable indicating this module is a base class not a real module
|
||||
# Note that Module is not a real module, but a base class for all modules so isBase is not used on this class
|
||||
@ -184,12 +185,25 @@ 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(typing.cast(str, sys.modules[cls.__module__].__file__)) + '/' + cls.iconFile,
|
||||
try:
|
||||
with open(
|
||||
os.path.dirname(typing.cast(str, sys.modules[cls.__module__].__file__))
|
||||
+ '/'
|
||||
+ cls.iconFile,
|
||||
'rb',
|
||||
) as f:
|
||||
data = f.read()
|
||||
except Exception as e:
|
||||
logger.error('Error reading icon file for module %s: %s', cls.type(), e)
|
||||
# blank png bytes
|
||||
data = codecs.decode(
|
||||
(
|
||||
b'iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAY0lEQVR42u3QAREAAAQEMJKL'
|
||||
b'/nI4W4R1KlOPtQABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAg'
|
||||
b'AABAgQIECBAgAABAgQIECBAgAABAgQIEHDfAvLdn4FABR1mAAAAAElFTkSuQmCC'
|
||||
),
|
||||
'base64',
|
||||
)
|
||||
data = file_.read()
|
||||
file_.close()
|
||||
|
||||
return data
|
||||
|
||||
|
@ -1,7 +1,8 @@
|
||||
# Generated by Django 4.1 on 2022-09-01 14:46
|
||||
# Generated by Django 4.1 on 2022-10-01 06:23
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import uds.core.util.model
|
||||
import uds.models.notifications
|
||||
import uds.models.user_service_session
|
||||
import uds.models.util
|
||||
@ -52,7 +53,9 @@ class Migration(migrations.Migration):
|
||||
(
|
||||
"uuid",
|
||||
models.CharField(
|
||||
default=None, max_length=50, null=True, unique=True
|
||||
default=uds.core.util.model.generateUuid,
|
||||
max_length=50,
|
||||
unique=True,
|
||||
),
|
||||
),
|
||||
("data_type", models.CharField(max_length=128)),
|
||||
@ -66,7 +69,6 @@ class Migration(migrations.Migration):
|
||||
default=uds.models.notifications.NotificationLevel["ERROR"]
|
||||
),
|
||||
),
|
||||
("tags", models.ManyToManyField(to="uds.tag")),
|
||||
],
|
||||
options={
|
||||
"db_table": "uds_notify_prov",
|
||||
@ -115,6 +117,9 @@ class Migration(migrations.Migration):
|
||||
"db_table": "uds__user_service_session",
|
||||
},
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name="DBFile",
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name="authenticator",
|
||||
name="visible",
|
||||
@ -175,6 +180,125 @@ class Migration(migrations.Migration):
|
||||
name="comments",
|
||||
field=models.CharField(default="", max_length=256),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="account",
|
||||
name="uuid",
|
||||
field=models.CharField(
|
||||
default=uds.core.util.model.generateUuid, max_length=50, unique=True
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="accountusage",
|
||||
name="uuid",
|
||||
field=models.CharField(
|
||||
default=uds.core.util.model.generateUuid, max_length=50, unique=True
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="authenticator",
|
||||
name="uuid",
|
||||
field=models.CharField(
|
||||
default=uds.core.util.model.generateUuid, max_length=50, unique=True
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="calendar",
|
||||
name="uuid",
|
||||
field=models.CharField(
|
||||
default=uds.core.util.model.generateUuid, max_length=50, unique=True
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="calendaraccess",
|
||||
name="uuid",
|
||||
field=models.CharField(
|
||||
default=uds.core.util.model.generateUuid, max_length=50, unique=True
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="calendaraccessmeta",
|
||||
name="uuid",
|
||||
field=models.CharField(
|
||||
default=uds.core.util.model.generateUuid, max_length=50, unique=True
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="calendaraction",
|
||||
name="uuid",
|
||||
field=models.CharField(
|
||||
default=uds.core.util.model.generateUuid, max_length=50, unique=True
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="calendarrule",
|
||||
name="uuid",
|
||||
field=models.CharField(
|
||||
default=uds.core.util.model.generateUuid, max_length=50, unique=True
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="group",
|
||||
name="uuid",
|
||||
field=models.CharField(
|
||||
default=uds.core.util.model.generateUuid, max_length=50, unique=True
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="image",
|
||||
name="uuid",
|
||||
field=models.CharField(
|
||||
default=uds.core.util.model.generateUuid, max_length=50, unique=True
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="metapool",
|
||||
name="uuid",
|
||||
field=models.CharField(
|
||||
default=uds.core.util.model.generateUuid, max_length=50, unique=True
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="metapoolmember",
|
||||
name="uuid",
|
||||
field=models.CharField(
|
||||
default=uds.core.util.model.generateUuid, max_length=50, unique=True
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="mfa",
|
||||
name="uuid",
|
||||
field=models.CharField(
|
||||
default=uds.core.util.model.generateUuid, max_length=50, unique=True
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="network",
|
||||
name="uuid",
|
||||
field=models.CharField(
|
||||
default=uds.core.util.model.generateUuid, max_length=50, unique=True
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="osmanager",
|
||||
name="uuid",
|
||||
field=models.CharField(
|
||||
default=uds.core.util.model.generateUuid, max_length=50, unique=True
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="permissions",
|
||||
name="uuid",
|
||||
field=models.CharField(
|
||||
default=uds.core.util.model.generateUuid, max_length=50, unique=True
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="provider",
|
||||
name="uuid",
|
||||
field=models.CharField(
|
||||
default=uds.core.util.model.generateUuid, max_length=50, unique=True
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="service",
|
||||
name="token",
|
||||
@ -182,6 +306,55 @@ class Migration(migrations.Migration):
|
||||
blank=True, default=None, max_length=64, null=True, unique=True
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="service",
|
||||
name="uuid",
|
||||
field=models.CharField(
|
||||
default=uds.core.util.model.generateUuid, max_length=50, unique=True
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="servicepool",
|
||||
name="uuid",
|
||||
field=models.CharField(
|
||||
default=uds.core.util.model.generateUuid, max_length=50, unique=True
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="servicepoolgroup",
|
||||
name="uuid",
|
||||
field=models.CharField(
|
||||
default=uds.core.util.model.generateUuid, max_length=50, unique=True
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="servicepoolpublication",
|
||||
name="uuid",
|
||||
field=models.CharField(
|
||||
default=uds.core.util.model.generateUuid, max_length=50, unique=True
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="tag",
|
||||
name="uuid",
|
||||
field=models.CharField(
|
||||
default=uds.core.util.model.generateUuid, max_length=50, unique=True
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="ticketstore",
|
||||
name="uuid",
|
||||
field=models.CharField(
|
||||
default=uds.core.util.model.generateUuid, max_length=50, unique=True
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="transport",
|
||||
name="uuid",
|
||||
field=models.CharField(
|
||||
default=uds.core.util.model.generateUuid, max_length=50, unique=True
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="tunneltoken",
|
||||
name="ip",
|
||||
@ -192,11 +365,25 @@ class Migration(migrations.Migration):
|
||||
name="ip_from",
|
||||
field=models.CharField(max_length=128),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="user",
|
||||
name="uuid",
|
||||
field=models.CharField(
|
||||
default=uds.core.util.model.generateUuid, max_length=50, unique=True
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="userservice",
|
||||
name="src_ip",
|
||||
field=models.CharField(default="", max_length=128),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="userservice",
|
||||
name="uuid",
|
||||
field=models.CharField(
|
||||
default=uds.core.util.model.generateUuid, max_length=50, unique=True
|
||||
),
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name="Proxy",
|
||||
),
|
||||
@ -218,6 +405,11 @@ class Migration(migrations.Migration):
|
||||
to="uds.service",
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="notifier",
|
||||
name="tags",
|
||||
field=models.ManyToManyField(to="uds.tag"),
|
||||
),
|
||||
migrations.AddConstraint(
|
||||
model_name="userservicesession",
|
||||
constraint=models.UniqueConstraint(
|
||||
|
@ -106,9 +106,6 @@ from .account_usage import AccountUsage
|
||||
# Tagging
|
||||
from .tag import Tag, TaggingMixin
|
||||
|
||||
# Utility
|
||||
from .dbfile import DBFile
|
||||
|
||||
# Tokens
|
||||
from .actor_token import ActorToken
|
||||
from .tunnel_token import TunnelToken
|
||||
|
@ -55,7 +55,7 @@ class Account(UUIDModel, TaggingMixin):
|
||||
comments = models.CharField(max_length=256, default='')
|
||||
|
||||
# "fake" declarations for type checking
|
||||
objects: 'models.manager.Manager["Account"]'
|
||||
#objects: 'models.manager.Manager["Account"]'
|
||||
usages: 'models.manager.RelatedManager[AccountUsage]'
|
||||
|
||||
def startUsageAccounting(self, userService: 'UserService') -> typing.Optional['AccountUsage']:
|
||||
|
@ -54,7 +54,7 @@ class AccountUsage(UUIDModel):
|
||||
"""
|
||||
|
||||
# "fake" declarations for type checking
|
||||
objects: 'models.manager.Manager["AccountUsage"]'
|
||||
# objects: 'models.manager.Manager["AccountUsage"]'
|
||||
|
||||
user_name = models.CharField(max_length=128, db_index=True, default='')
|
||||
user_uuid = models.CharField(max_length=50, db_index=True, default='')
|
||||
@ -62,7 +62,7 @@ class AccountUsage(UUIDModel):
|
||||
pool_uuid = models.CharField(max_length=50, db_index=True, default='')
|
||||
start = models.DateTimeField(default=NEVER)
|
||||
end = models.DateTimeField(default=NEVER)
|
||||
user_service: 'models.OneToOneField["AccountUsage", UserService]' = (
|
||||
user_service: 'models.OneToOneField[UserService | None]' = (
|
||||
models.OneToOneField(
|
||||
UserService,
|
||||
null=True,
|
||||
@ -71,7 +71,7 @@ class AccountUsage(UUIDModel):
|
||||
on_delete=models.SET_NULL,
|
||||
)
|
||||
)
|
||||
account: 'models.ForeignKey["AccountUsage", Account]' = models.ForeignKey(
|
||||
account: 'models.ForeignKey[Account]' = models.ForeignKey(
|
||||
Account, related_name='usages', on_delete=models.CASCADE
|
||||
)
|
||||
|
||||
|
@ -50,7 +50,7 @@ class ActorToken(models.Model):
|
||||
stamp = models.DateTimeField() # Date creation or validation of this entry
|
||||
|
||||
# "fake" declarations for type checking
|
||||
objects: 'models.manager.Manager[ActorToken]'
|
||||
# objects: 'models.manager.Manager[ActorToken]'
|
||||
|
||||
class Meta:
|
||||
app_label = 'uds'
|
||||
|
@ -76,7 +76,7 @@ class Authenticator(ManagedObjectModel, TaggingMixin):
|
||||
net_filtering = models.CharField(max_length=1, default=NO_FILTERING, db_index=True)
|
||||
|
||||
# "fake" relations declarations for type checking
|
||||
objects: 'models.manager.Manager["Authenticator"]'
|
||||
# objects: 'models.manager.Manager["Authenticator"]'
|
||||
users: 'models.manager.RelatedManager[User]'
|
||||
groups: 'models.manager.RelatedManager[Group]'
|
||||
|
||||
@ -163,7 +163,7 @@ class Authenticator(ManagedObjectModel, TaggingMixin):
|
||||
Raises:
|
||||
"""
|
||||
user: 'User'
|
||||
realName = realName if realName is None else username
|
||||
realName = realName or username
|
||||
user, _ = self.users.get_or_create(
|
||||
name=username,
|
||||
defaults={
|
||||
|
@ -49,13 +49,12 @@ class Cache(models.Model):
|
||||
owner = models.CharField(max_length=128, db_index=True)
|
||||
key = models.CharField(max_length=64, primary_key=True)
|
||||
value = models.TextField(default='')
|
||||
created = (
|
||||
models.DateTimeField()
|
||||
) # Date creation or validation of this entry. Set at write time
|
||||
# Date creation or validation of this entry. Set at write time
|
||||
created = models.DateTimeField()
|
||||
validity = models.IntegerField(default=60) # Validity of this entry, in seconds
|
||||
|
||||
# "fake" relations declarations for type checking
|
||||
objects: 'models.manager.Manager[Cache]'
|
||||
# objects: 'models.manager.Manager[Cache]'
|
||||
|
||||
class Meta:
|
||||
"""
|
||||
|
@ -52,7 +52,7 @@ class Calendar(UUIDModel, TaggingMixin):
|
||||
modified = models.DateTimeField(auto_now=True)
|
||||
|
||||
# "fake" declarations for type checking
|
||||
objects: 'models.manager.Manager["Calendar"]'
|
||||
# objects: 'models.manager.Manager["Calendar"]'
|
||||
rules: 'models.manager.RelatedManager[CalendarRule]'
|
||||
calendaraction_set: 'models.manager.RelatedManager[CalendarAction]'
|
||||
calendaraccess_set: 'models.manager.RelatedManager[CalendarAccess]'
|
||||
|
@ -47,17 +47,17 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class CalendarAccess(UUIDModel):
|
||||
calendar: 'models.ForeignKey[CalendarAccess, Calendar]' = models.ForeignKey(
|
||||
calendar: 'models.ForeignKey[Calendar]' = models.ForeignKey(
|
||||
Calendar, on_delete=models.CASCADE
|
||||
)
|
||||
service_pool: 'models.ForeignKey[CalendarAccess, ServicePool]' = models.ForeignKey(
|
||||
service_pool: 'models.ForeignKey[ServicePool]' = models.ForeignKey(
|
||||
ServicePool, related_name='calendarAccess', on_delete=models.CASCADE
|
||||
)
|
||||
access = models.CharField(max_length=8, default=states.action.DENY)
|
||||
priority = models.IntegerField(default=0, db_index=True)
|
||||
|
||||
# "fake" declarations for type checking
|
||||
objects: 'models.manager.Manager[CalendarAccess]'
|
||||
# objects: 'models.manager.Manager[CalendarAccess]'
|
||||
|
||||
class Meta:
|
||||
"""
|
||||
|
@ -231,10 +231,10 @@ CALENDAR_ACTION_DICT: typing.Dict[str, typing.Dict] = {
|
||||
|
||||
|
||||
class CalendarAction(UUIDModel):
|
||||
calendar: 'models.ForeignKey[CalendarAction, Calendar]' = models.ForeignKey(
|
||||
calendar: 'models.ForeignKey[Calendar]' = models.ForeignKey(
|
||||
Calendar, on_delete=models.CASCADE
|
||||
)
|
||||
service_pool: 'models.ForeignKey[CalendarAction, ServicePool]' = models.ForeignKey(
|
||||
service_pool: 'models.ForeignKey[ServicePool]' = models.ForeignKey(
|
||||
ServicePool, on_delete=models.CASCADE
|
||||
)
|
||||
action = models.CharField(max_length=64, default='')
|
||||
@ -252,7 +252,7 @@ class CalendarAction(UUIDModel):
|
||||
)
|
||||
|
||||
# "fake" declarations for type checking
|
||||
objects: 'models.manager.Manager[CalendarAction]'
|
||||
# objects: 'models.manager.Manager[CalendarAction]'
|
||||
|
||||
class Meta:
|
||||
"""
|
||||
|
@ -109,12 +109,12 @@ class CalendarRule(UUIDModel):
|
||||
duration = models.IntegerField(default=0) # Duration in "duration_unit" units
|
||||
duration_unit = models.CharField(choices=dunits, default='MINUTES', max_length=32)
|
||||
|
||||
calendar: 'models.ForeignKey["CalendarRule", Calendar]' = models.ForeignKey(
|
||||
calendar: 'models.ForeignKey[Calendar]' = models.ForeignKey(
|
||||
Calendar, related_name='rules', on_delete=models.CASCADE
|
||||
)
|
||||
|
||||
# "fake" declarations for type checking
|
||||
objects: 'models.manager.Manager["CalendarRule"]'
|
||||
# objects: 'models.manager.Manager["CalendarRule"]'
|
||||
|
||||
class Meta:
|
||||
"""
|
||||
@ -134,7 +134,11 @@ class CalendarRule(UUIDModel):
|
||||
)
|
||||
|
||||
# If at end of interval is requested, displace dstart to match end of interval
|
||||
dstart = self.start if not atEnd else self.start + datetime.timedelta(minutes=self.duration_as_minutes)
|
||||
dstart = (
|
||||
self.start
|
||||
if not atEnd
|
||||
else self.start + datetime.timedelta(minutes=self.duration_as_minutes)
|
||||
)
|
||||
|
||||
if self.frequency == WEEKDAYS:
|
||||
dw = []
|
||||
|
@ -53,7 +53,7 @@ class Config(models.Model):
|
||||
help = models.CharField(max_length=256, default='')
|
||||
|
||||
# "fake" declarations for type checking
|
||||
objects: 'models.manager.Manager[Config]'
|
||||
# objects: 'models.manager.Manager[Config]'
|
||||
|
||||
class Meta:
|
||||
"""
|
||||
|
@ -1,78 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Model based on https://github.com/llazzaro/django-scheduler
|
||||
#
|
||||
# Copyright (c) 2016-2020 Virtual Cable S.L.U.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
# * 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
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
"""
|
||||
.. moduleauthor:: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
"""
|
||||
import codecs
|
||||
import logging
|
||||
|
||||
from django.db import models
|
||||
|
||||
from .uuid_model import UUIDModel
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class DBFile(UUIDModel):
|
||||
|
||||
# Not indexed, used for cleanups only
|
||||
owner = models.CharField(max_length=32, default='')
|
||||
name = models.CharField(max_length=255, primary_key=True)
|
||||
content = models.TextField(blank=True)
|
||||
size = models.IntegerField(default=0)
|
||||
created = models.DateTimeField()
|
||||
modified = models.DateTimeField()
|
||||
|
||||
# "fake" declarations for type checking
|
||||
objects: 'models.manager.Manager[DBFile]'
|
||||
|
||||
@property
|
||||
def data(self) -> bytes:
|
||||
try:
|
||||
return codecs.decode(codecs.decode(self.content.encode(), 'base64'), 'zip')
|
||||
except Exception:
|
||||
logger.error('DBFile %s has errors and cannot be used', self.name)
|
||||
try:
|
||||
self.delete() # Autodelete, invalid...
|
||||
except Exception:
|
||||
logger.error('Could not even delete %s!!', self.name)
|
||||
|
||||
return b''
|
||||
|
||||
@data.setter
|
||||
def data(self, value: bytes):
|
||||
self.size = len(value)
|
||||
self.content = codecs.encode(codecs.encode(value, 'zip'), 'base64').decode()
|
||||
|
||||
def __str__(self) -> str:
|
||||
return 'File: {} {} {} {}'.format(
|
||||
self.name, self.size, self.created, self.modified
|
||||
)
|
@ -59,7 +59,7 @@ class DelayedTask(models.Model):
|
||||
execution_time = models.DateTimeField(db_index=True)
|
||||
|
||||
# "fake" declarations for type checking
|
||||
objects: 'models.manager.Manager[DelayedTask]'
|
||||
# objects: 'models.manager.Manager[DelayedTask]'
|
||||
|
||||
class Meta:
|
||||
"""
|
||||
|
@ -56,7 +56,7 @@ class Group(UUIDModel):
|
||||
This class represents a group, associated with one authenticator
|
||||
"""
|
||||
|
||||
manager: 'models.ForeignKey["Group", Authenticator]' = UnsavedForeignKey(
|
||||
manager: 'models.ForeignKey[Authenticator]' = UnsavedForeignKey(
|
||||
Authenticator, on_delete=models.CASCADE, related_name='groups'
|
||||
)
|
||||
name = models.CharField(max_length=128, db_index=True)
|
||||
@ -69,7 +69,7 @@ class Group(UUIDModel):
|
||||
created = models.DateTimeField(default=getSqlDatetime, blank=True)
|
||||
|
||||
# "fake" declarations for type checking
|
||||
objects: 'models.manager.Manager["Group"]'
|
||||
# objects: 'models.manager.Manager["Group"]'
|
||||
deployedServices: 'models.manager.RelatedManager[ServicePool]'
|
||||
permissions: 'models.manager.RelatedManager[Permissions]'
|
||||
|
||||
|
@ -71,7 +71,7 @@ class Image(UUIDModel):
|
||||
height = models.IntegerField(default=0)
|
||||
|
||||
# "fake" declarations for type checking
|
||||
objects: 'models.manager.RelatedManager["Image"]'
|
||||
# objects: 'models.manager.RelatedManager["Image"]'
|
||||
|
||||
deployedServices: 'models.manager.RelatedManager[ServicePool]'
|
||||
metaPools: 'models.manager.RelatedManager[MetaPool]'
|
||||
|
@ -55,7 +55,7 @@ class Log(models.Model):
|
||||
data = models.CharField(max_length=255, default='')
|
||||
|
||||
# "fake" declarations for type checking
|
||||
objects: 'models.manager.Manager[Log]'
|
||||
# objects: 'models.manager.Manager[Log]'
|
||||
|
||||
class Meta:
|
||||
"""
|
||||
|
@ -68,9 +68,11 @@ class ManagedObjectModel(UUIDModel):
|
||||
"""
|
||||
Returns an environment valid for the record this object represents
|
||||
"""
|
||||
return Environment.getEnvForTableElement(self._meta.verbose_name, self.id)
|
||||
return Environment.getEnvForTableElement(self._meta.verbose_name, self.id) # type: ignore
|
||||
|
||||
def deserialize(self, obj: Module, values: typing.Optional[typing.Mapping[str, str]]):
|
||||
def deserialize(
|
||||
self, obj: Module, values: typing.Optional[typing.Mapping[str, str]]
|
||||
):
|
||||
"""
|
||||
Conditionally deserializes obj if not initialized via user interface and data holds something
|
||||
"""
|
||||
|
@ -129,7 +129,7 @@ class MetaPool(UUIDModel, TaggingMixin): # type: ignore
|
||||
ha_policy = models.SmallIntegerField(default=HA_POLICY_DISABLED)
|
||||
|
||||
# "fake" declarations for type checking
|
||||
objects: 'models.BaseManager["MetaPool"]'
|
||||
# objects: 'models.BaseManager["MetaPool"]'
|
||||
calendarAccess: 'models.QuerySet[CalendarAccessMeta]'
|
||||
members: 'models.QuerySet["MetaPoolMember"]'
|
||||
|
||||
@ -182,7 +182,9 @@ class MetaPool(UUIDModel, TaggingMixin): # type: ignore
|
||||
|
||||
access = self.fallbackAccess
|
||||
# Let's see if we can access by current datetime
|
||||
for ac in sorted(self.calendarAccess.all(), key=operator.attrgetter('priority')):
|
||||
for ac in sorted(
|
||||
self.calendarAccess.all(), key=operator.attrgetter('priority')
|
||||
):
|
||||
if CalendarChecker(ac.calendar).check(chkDateTime):
|
||||
access = ac.access
|
||||
break # Stops on first rule match found
|
||||
@ -278,10 +280,10 @@ signals.pre_delete.connect(MetaPool.beforeDelete, sender=MetaPool)
|
||||
|
||||
|
||||
class MetaPoolMember(UUIDModel):
|
||||
pool: 'models.ForeignKey["MetaPoolMember", ServicePool]' = models.ForeignKey(
|
||||
pool: 'models.ForeignKey[ServicePool]' = models.ForeignKey(
|
||||
ServicePool, related_name='memberOfMeta', on_delete=models.CASCADE
|
||||
)
|
||||
meta_pool: 'models.ForeignKey["MetaPoolMember", MetaPool]' = models.ForeignKey(
|
||||
meta_pool: 'models.ForeignKey[MetaPool]' = models.ForeignKey(
|
||||
MetaPool, related_name='members', on_delete=models.CASCADE
|
||||
)
|
||||
priority = models.PositiveIntegerField(default=0)
|
||||
|
@ -51,12 +51,14 @@ class MFA(ManagedObjectModel, TaggingMixin): # type: ignore
|
||||
An OS Manager represents a manager for responding requests for agents inside services.
|
||||
"""
|
||||
|
||||
# "fake" declarations for type checking
|
||||
objects: 'models.BaseManager[MFA]'
|
||||
authenticators: 'models.manager.RelatedManager[Authenticator]'
|
||||
# Time to remember the device MFA in hours
|
||||
remember_device = models.IntegerField(default=0)
|
||||
# Limit of time for this MFA to be used, in seconds
|
||||
validity = models.IntegerField(default=0)
|
||||
|
||||
remember_device = models.IntegerField(default=0) # Time to remember the device MFA in hours
|
||||
validity = models.IntegerField(default=0) # Limit of time for this MFA to be used, in seconds
|
||||
# "fake" declarations for type checking
|
||||
# objects: 'models.BaseManager[MFA]'
|
||||
authenticators: 'models.manager.RelatedManager[Authenticator]'
|
||||
|
||||
def getInstance(
|
||||
self, values: typing.Optional[typing.Dict[str, str]] = None
|
||||
@ -64,15 +66,15 @@ class MFA(ManagedObjectModel, TaggingMixin): # type: ignore
|
||||
return typing.cast('mfas.MFA', super().getInstance(values=values))
|
||||
|
||||
def getType(self) -> typing.Type['mfas.MFA']:
|
||||
"""
|
||||
Get the type of the object this record represents.
|
||||
"""Get the type of the object this record represents.
|
||||
|
||||
The type is Python type, it obtains this OsManagersFactory and associated record field.
|
||||
The type is a Python type, it obtains this MFA and associated record field.
|
||||
|
||||
Returns:
|
||||
The python type for this record object
|
||||
|
||||
:note: We only need to get info from this, not access specific data (class specific info)
|
||||
Note:
|
||||
We only need to get info from this, not access specific data (class specific info)
|
||||
"""
|
||||
# We only need to get info from this, not access specific data (class specific info)
|
||||
from uds.core import mfas
|
||||
@ -100,7 +102,11 @@ class MFA(ManagedObjectModel, TaggingMixin): # type: ignore
|
||||
s.destroy()
|
||||
s.env.clearRelatedData()
|
||||
except Exception as e:
|
||||
logger.error('Error processing deletion of notifier %s: %s (forced deletion)', toDelete.name, e)
|
||||
logger.error(
|
||||
'Error processing deletion of notifier %s: %s (forced deletion)',
|
||||
toDelete.name,
|
||||
e,
|
||||
)
|
||||
|
||||
logger.debug('Before delete mfa provider %s', toDelete)
|
||||
|
||||
|
@ -63,7 +63,7 @@ class Network(UUIDModel, TaggingMixin): # type: ignore
|
||||
)
|
||||
|
||||
# "fake" declarations for type checking
|
||||
objects: 'models.manager.Manager[Network]'
|
||||
# objects: 'models.manager.Manager[Network]'
|
||||
|
||||
class Meta(UUIDModel.Meta):
|
||||
"""
|
||||
|
@ -73,7 +73,7 @@ class Notification(models.Model):
|
||||
processed = models.BooleanField(default=False)
|
||||
|
||||
# "fake" declarations for type checking
|
||||
objects: 'models.BaseManager[Notification]'
|
||||
# objects: 'models.BaseManager[Notification]'
|
||||
|
||||
class Meta:
|
||||
"""
|
||||
|
@ -52,7 +52,7 @@ class OSManager(ManagedObjectModel, TaggingMixin):
|
||||
"""
|
||||
|
||||
# "fake" declarations for type checking
|
||||
objects: 'models.manager.Manager[OSManager]'
|
||||
# objects: 'models.manager.Manager[OSManager]'
|
||||
deployedServices: 'models.manager.RelatedManager[ServicePool]'
|
||||
|
||||
class Meta(ManagedObjectModel.Meta):
|
||||
|
@ -84,7 +84,7 @@ class Permissions(UUIDModel):
|
||||
permission = models.SmallIntegerField(default=PERMISSION_NONE, db_index=True)
|
||||
|
||||
# "fake" declarations for type checking
|
||||
objects: 'models.manager.Manager[Permissions]'
|
||||
# objects: 'models.manager.Manager[Permissions]'
|
||||
|
||||
@staticmethod
|
||||
def permissionAsString(perm: int) -> str:
|
||||
|
@ -56,7 +56,7 @@ class Provider(ManagedObjectModel, TaggingMixin): # type: ignore
|
||||
maintenance_mode = models.BooleanField(default=False, db_index=True)
|
||||
|
||||
# "fake" declarations for type checking
|
||||
objects: 'models.manager.Manager[Provider]'
|
||||
# objects: 'models.manager.Manager[Provider]'
|
||||
services: 'models.manager.RelatedManager[Service]'
|
||||
|
||||
class Meta(ManagedObjectModel.Meta):
|
||||
|
@ -73,7 +73,7 @@ class Scheduler(models.Model):
|
||||
# primary key id declaration (for type checking)
|
||||
|
||||
# "fake" declarations for type checking
|
||||
objects: 'models.manager.Manager[Scheduler]'
|
||||
# objects: 'models.manager.Manager[Scheduler]'
|
||||
id: int # Primary key (Autogenerated by model, just for type checking)
|
||||
|
||||
class Meta:
|
||||
@ -87,7 +87,7 @@ class Scheduler(models.Model):
|
||||
"""
|
||||
Returns an environment valid for the record this object represents
|
||||
"""
|
||||
return Environment.getEnvForTableElement(self._meta.verbose_name, self.id)
|
||||
return Environment.getEnvForTableElement(self._meta.verbose_name, self.id) # type: ignore
|
||||
|
||||
def getInstance(self) -> typing.Optional[jobs.Job]:
|
||||
"""
|
||||
|
@ -74,7 +74,7 @@ class Service(ManagedObjectModel, TaggingMixin): # type: ignore
|
||||
Server configuration).
|
||||
"""
|
||||
|
||||
provider: 'models.ForeignKey["Service", Provider]' = models.ForeignKey(
|
||||
provider: 'models.ForeignKey[Provider]' = models.ForeignKey(
|
||||
Provider, related_name='services', on_delete=models.CASCADE
|
||||
)
|
||||
|
||||
@ -89,11 +89,10 @@ class Service(ManagedObjectModel, TaggingMixin): # type: ignore
|
||||
_cachedInstance: typing.Optional['services.Service'] = None
|
||||
|
||||
# "fake" declarations for type checking
|
||||
objects: 'models.manager.Manager["Service"]'
|
||||
# objects: 'models.manager.Manager["Service"]'
|
||||
deployedServices: 'models.manager.RelatedManager[ServicePool]'
|
||||
aliases: 'models.manager.RelatedManager[ServiceTokenAlias]'
|
||||
|
||||
|
||||
class Meta(ManagedObjectModel.Meta):
|
||||
"""
|
||||
Meta class to declare default order and unique multiple field index
|
||||
@ -112,7 +111,7 @@ class Service(ManagedObjectModel, TaggingMixin): # type: ignore
|
||||
Returns an environment valid for the record this object represents
|
||||
"""
|
||||
return Environment.getEnvForTableElement(
|
||||
self._meta.verbose_name,
|
||||
self._meta.verbose_name, # type: ignore
|
||||
self.id,
|
||||
{
|
||||
'mac': unique.UniqueMacGenerator,
|
||||
@ -194,11 +193,9 @@ class Service(ManagedObjectModel, TaggingMixin): # type: ignore
|
||||
# Counts EVERYTHING for max limit checking
|
||||
return self.max_services_count_type == 1
|
||||
|
||||
|
||||
def __str__(self) -> str:
|
||||
return '{} of type {} (id:{})'.format(self.name, self.data_type, self.id)
|
||||
|
||||
|
||||
@staticmethod
|
||||
def beforeDelete(sender, **kwargs) -> None:
|
||||
"""
|
||||
|
@ -70,7 +70,7 @@ if typing.TYPE_CHECKING:
|
||||
Group,
|
||||
MetaPoolMember,
|
||||
CalendarAccess,
|
||||
CalendarAction
|
||||
CalendarAction,
|
||||
)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@ -84,14 +84,14 @@ class ServicePool(UUIDModel, TaggingMixin): # type: ignore
|
||||
name = models.CharField(max_length=128, default='')
|
||||
short_name = models.CharField(max_length=32, default='')
|
||||
comments = models.CharField(max_length=256, default='')
|
||||
service: 'models.ForeignKey["ServicePool", Service]' = models.ForeignKey(
|
||||
service: 'models.ForeignKey[Service | None]' = models.ForeignKey(
|
||||
Service,
|
||||
null=True,
|
||||
blank=True,
|
||||
related_name='deployedServices',
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
osmanager: 'models.ForeignKey["ServicePool", OSManager]' = models.ForeignKey(
|
||||
osmanager: 'models.ForeignKey[OSManager | None]' = models.ForeignKey(
|
||||
OSManager,
|
||||
null=True,
|
||||
blank=True,
|
||||
@ -115,7 +115,7 @@ class ServicePool(UUIDModel, TaggingMixin): # type: ignore
|
||||
|
||||
ignores_unused = models.BooleanField(default=False)
|
||||
|
||||
image: 'models.ForeignKey["ServicePool", Image]' = models.ForeignKey(
|
||||
image: 'models.ForeignKey[Image | None]' = models.ForeignKey(
|
||||
Image,
|
||||
null=True,
|
||||
blank=True,
|
||||
@ -123,15 +123,13 @@ class ServicePool(UUIDModel, TaggingMixin): # type: ignore
|
||||
on_delete=models.SET_NULL,
|
||||
)
|
||||
|
||||
servicesPoolGroup: 'models.ForeignKey["ServicePool", ServicePoolGroup]' = (
|
||||
models.ForeignKey(
|
||||
servicesPoolGroup: 'models.ForeignKey[ServicePoolGroup | None]' = models.ForeignKey(
|
||||
ServicePoolGroup,
|
||||
null=True,
|
||||
blank=True,
|
||||
related_name='servicesPools',
|
||||
on_delete=models.SET_NULL,
|
||||
)
|
||||
)
|
||||
|
||||
# Message if access denied
|
||||
calendar_message = models.CharField(default='', max_length=256)
|
||||
@ -139,7 +137,7 @@ class ServicePool(UUIDModel, TaggingMixin): # type: ignore
|
||||
fallbackAccess = models.CharField(default=states.action.ALLOW, max_length=8)
|
||||
|
||||
# Usage accounting
|
||||
account: 'models.ForeignKey["ServicePool", Account]' = models.ForeignKey(
|
||||
account: 'models.ForeignKey[Account | None]' = models.ForeignKey(
|
||||
Account,
|
||||
null=True,
|
||||
blank=True,
|
||||
@ -162,7 +160,6 @@ class ServicePool(UUIDModel, TaggingMixin): # type: ignore
|
||||
calendaraction_set: 'models.manager.RelatedManager[CalendarAction]'
|
||||
changelog: 'models.manager.RelatedManager[ServicePoolPublicationChangelog]'
|
||||
|
||||
|
||||
class Meta(UUIDModel.Meta):
|
||||
"""
|
||||
Meta class to declare the name of the table at database
|
||||
@ -175,7 +172,7 @@ class ServicePool(UUIDModel, TaggingMixin): # type: ignore
|
||||
"""
|
||||
Returns an environment valid for the record this object represents
|
||||
"""
|
||||
return Environment.getEnvForTableElement(self._meta.verbose_name, self.id)
|
||||
return Environment.getEnvForTableElement(self._meta.verbose_name, self.id) # type: ignore
|
||||
|
||||
def activePublication(self) -> typing.Optional['ServicePoolPublication']:
|
||||
"""
|
||||
@ -316,12 +313,16 @@ class ServicePool(UUIDModel, TaggingMixin): # type: ignore
|
||||
'UserService',
|
||||
self.assignedUserServices().filter(
|
||||
user=forUser, state__in=states.userService.VALID_STATES
|
||||
)[0], # type: ignore # Slicing is not supported by pylance right now
|
||||
)[
|
||||
0
|
||||
], # type: ignore # Slicing is not supported by pylance right now
|
||||
)
|
||||
if activePub and found.publication and activePub.id != found.publication.id:
|
||||
ret = self.recoverValue('toBeReplacedIn')
|
||||
if ret:
|
||||
return pickle.loads(ret) # nosec: Value is safe because it is generated by the system
|
||||
return pickle.loads( # nosec: Value is safe because it is generated by the system
|
||||
ret
|
||||
)
|
||||
except Exception: # nosec: We don't want to fail if there is any exception
|
||||
# logger.exception('Recovering publication death line')
|
||||
pass
|
||||
@ -337,7 +338,9 @@ class ServicePool(UUIDModel, TaggingMixin): # type: ignore
|
||||
|
||||
access = self.fallbackAccess
|
||||
# Let's see if we can access by current datetime
|
||||
for ac in sorted(self.calendarAccess.all(), key=operator.attrgetter('priority')):
|
||||
for ac in sorted(
|
||||
self.calendarAccess.all(), key=operator.attrgetter('priority')
|
||||
):
|
||||
if CalendarChecker(ac.calendar).check(chkDateTime):
|
||||
access = ac.access
|
||||
break # Stops on first rule match found
|
||||
@ -498,6 +501,7 @@ class ServicePool(UUIDModel, TaggingMixin): # type: ignore
|
||||
"""
|
||||
if (
|
||||
self.activePublication() is None
|
||||
and self.service
|
||||
and self.service.getType().publicationType is not None
|
||||
):
|
||||
raise InvalidServiceException()
|
||||
@ -599,9 +603,9 @@ class ServicePool(UUIDModel, TaggingMixin): # type: ignore
|
||||
)
|
||||
servicePool: 'ServicePool'
|
||||
for servicePool in query:
|
||||
if (
|
||||
typing.cast(typing.Any, servicePool).pubs_active
|
||||
or servicePool.service.data_type in servicesNotNeedingPub
|
||||
if typing.cast(typing.Any, servicePool).pubs_active or (
|
||||
servicePool.service
|
||||
and servicePool.service.data_type in servicesNotNeedingPub
|
||||
):
|
||||
yield servicePool
|
||||
|
||||
@ -661,7 +665,7 @@ class ServicePool(UUIDModel, TaggingMixin): # type: ignore
|
||||
cachedValue is used to optimize (if known the number of assigned services, we can avoid to query the db)
|
||||
"""
|
||||
maxs = self.max_srvs
|
||||
if maxs == 0:
|
||||
if maxs == 0 and self.service:
|
||||
maxs = self.service.getInstance().maxDeployed
|
||||
|
||||
if maxs <= 0:
|
||||
@ -676,8 +680,10 @@ class ServicePool(UUIDModel, TaggingMixin): # type: ignore
|
||||
|
||||
return 100 * cachedValue // maxs
|
||||
|
||||
def testServer(self, host: str, port: typing.Union[str, int], timeout: float=4) -> bool:
|
||||
return self.service.testServer(host, port, timeout)
|
||||
def testServer(
|
||||
self, host: str, port: typing.Union[str, int], timeout: float = 4
|
||||
) -> bool:
|
||||
return bool(self.service) and self.service.testServer(host, port, timeout)
|
||||
|
||||
# Utility for logging
|
||||
def log(self, message: str, level: int = log.INFO) -> None:
|
||||
|
@ -54,7 +54,7 @@ class ServicePoolGroup(UUIDModel):
|
||||
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: 'models.ForeignKey[Image | None]' = models.ForeignKey(
|
||||
Image,
|
||||
null=True,
|
||||
blank=True,
|
||||
@ -63,7 +63,7 @@ class ServicePoolGroup(UUIDModel):
|
||||
)
|
||||
|
||||
# "fake" declarations for type checking
|
||||
objects: 'models.manager.Manager[ServicePoolGroup]'
|
||||
# objects: 'models.manager.Manager[ServicePoolGroup]'
|
||||
|
||||
class Meta(UUIDModel.Meta):
|
||||
"""
|
||||
@ -75,7 +75,7 @@ class ServicePoolGroup(UUIDModel):
|
||||
|
||||
def __str__(self) -> str:
|
||||
return 'Service Pool group {}({}): {}'.format(
|
||||
self.name, self.comments, self.image.name
|
||||
self.name, self.comments, self.image.name if self.image else ''
|
||||
)
|
||||
|
||||
@property
|
||||
|
@ -55,17 +55,15 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
class ServicePoolPublicationChangelog(models.Model):
|
||||
# This should be "servicePool"
|
||||
publication: 'models.ForeignKey[ServicePoolPublicationChangelog, ServicePool]' = (
|
||||
models.ForeignKey(
|
||||
publication: 'models.ForeignKey[ServicePool]' = models.ForeignKey(
|
||||
ServicePool, on_delete=models.CASCADE, related_name='changelog'
|
||||
)
|
||||
)
|
||||
stamp = models.DateTimeField()
|
||||
revision = models.PositiveIntegerField(default=1)
|
||||
log = models.TextField(default='')
|
||||
|
||||
# "fake" declarations for type checking
|
||||
objects: 'models.manager.Manager[ServicePoolPublicationChangelog]'
|
||||
# objects: 'models.manager.Manager[ServicePoolPublicationChangelog]'
|
||||
|
||||
class Meta(UUIDModel.Meta):
|
||||
"""
|
||||
@ -86,11 +84,9 @@ class ServicePoolPublication(UUIDModel):
|
||||
A deployed service publication keep track of data needed by services that needs "preparation". (i.e. Virtual machine --> base machine --> children of base machines)
|
||||
"""
|
||||
|
||||
deployed_service: 'models.ForeignKey["ServicePoolPublication", ServicePool]' = (
|
||||
models.ForeignKey(
|
||||
deployed_service: 'models.ForeignKey[ServicePool]' = models.ForeignKey(
|
||||
ServicePool, on_delete=models.CASCADE, related_name='publications'
|
||||
)
|
||||
)
|
||||
publish_date = models.DateTimeField(db_index=True)
|
||||
# data_type = models.CharField(max_length=128) # The data type is specified by the service itself
|
||||
data = models.TextField(default='')
|
||||
@ -106,7 +102,7 @@ class ServicePoolPublication(UUIDModel):
|
||||
revision = models.PositiveIntegerField(default=1)
|
||||
|
||||
# "fake" declarations for type checking
|
||||
objects: 'models.manager.Manager["ServicePoolPublication"]'
|
||||
# objects: 'models.manager.Manager["ServicePoolPublication"]'
|
||||
userServices: 'models.manager.RelatedManager[UserService]'
|
||||
|
||||
class Meta(UUIDModel.Meta):
|
||||
@ -122,7 +118,7 @@ class ServicePoolPublication(UUIDModel):
|
||||
"""
|
||||
Returns an environment valid for the record this object represents
|
||||
"""
|
||||
return Environment.getEnvForTableElement(self._meta.verbose_name, self.id)
|
||||
return Environment.getEnvForTableElement(self._meta.verbose_name, self.id) # type: ignore
|
||||
|
||||
def getInstance(self) -> 'services.Publication':
|
||||
"""
|
||||
@ -139,6 +135,8 @@ class ServicePoolPublication(UUIDModel):
|
||||
|
||||
Raises:
|
||||
"""
|
||||
if not self.deployed_service.service:
|
||||
raise Exception('No service assigned to publication')
|
||||
serviceInstance = self.deployed_service.service.getInstance()
|
||||
osManager = self.deployed_service.osmanager
|
||||
osManagerInstance = osManager.getInstance() if osManager else None
|
||||
|
@ -57,7 +57,7 @@ class StatsCounters(models.Model):
|
||||
value = models.IntegerField(db_index=True, default=0)
|
||||
|
||||
# "fake" declarations for type checking
|
||||
objects: 'models.manager.Manager[StatsCounters]'
|
||||
# objects: 'models.manager.Manager[StatsCounters]'
|
||||
|
||||
class Meta:
|
||||
"""
|
||||
@ -125,7 +125,7 @@ class StatsCounters(models.Model):
|
||||
|
||||
floor = getSqlFnc('FLOOR')
|
||||
if interval > 0:
|
||||
q = q.extra(
|
||||
q = q.extra( # nosec: SQL injection is not possible here, all values are integers
|
||||
select={
|
||||
'group_by_stamp': f'{floor}(stamp / {interval}) * {interval}',
|
||||
},
|
||||
@ -227,7 +227,7 @@ class StatsCounters(models.Model):
|
||||
# fnc = getSqlFnc('MAX' if kwargs.get('use_max', False) else 'AVG')
|
||||
|
||||
query = (
|
||||
'SELECT -1 as id,-1 as owner_id,-1 as owner_type,-1 as counter_type, '
|
||||
'SELECT -1 as id,-1 as owner_id,-1 as owner_type,-1 as counter_type, ' # nosec: SQL injection is not possible here, all values are controlled
|
||||
+ stampValue
|
||||
+ '*{}'.format(interval)
|
||||
+ ' AS stamp, '
|
||||
|
@ -60,7 +60,7 @@ class StatsEvents(models.Model):
|
||||
fld4 = models.CharField(max_length=128, default='')
|
||||
|
||||
# "fake" declarations for type checking
|
||||
objects: 'models.manager.Manager[StatsEvents]'
|
||||
# objects: 'models.manager.Manager[StatsEvents]'
|
||||
|
||||
class Meta:
|
||||
"""
|
||||
|
@ -51,7 +51,7 @@ class Storage(models.Model):
|
||||
)
|
||||
|
||||
# "fake" declarations for type checking
|
||||
objects: 'models.manager.Manager[Storage]'
|
||||
# objects: 'models.manager.Manager[Storage]'
|
||||
|
||||
class Meta:
|
||||
"""
|
||||
@ -62,5 +62,5 @@ class Storage(models.Model):
|
||||
|
||||
def __str__(self) -> str:
|
||||
return '{} {} > str= {}, {}'.format(
|
||||
self.owner, self.key, self.data, '/'.join([self.attr1])
|
||||
self.owner, self.key, self.data, '/'.join([self.attr1 or ''])
|
||||
)
|
||||
|
@ -65,7 +65,7 @@ class Tag(UUIDModel):
|
||||
tag = models.CharField(max_length=32, db_index=True, unique=True)
|
||||
|
||||
# "fake" declarations for type checking
|
||||
objects: 'models.manager.Manager["Tag"]'
|
||||
# objects: 'models.manager.Manager["Tag"]'
|
||||
|
||||
# Every single related class has a relation with this
|
||||
# Its inverse is "xxx_set" class
|
||||
|
@ -29,7 +29,7 @@
|
||||
.. moduleauthor:: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
import datetime
|
||||
import pickle
|
||||
import pickle # nosec: Tickets are generated by us, so we know they are safe
|
||||
import logging
|
||||
import typing
|
||||
|
||||
@ -71,7 +71,7 @@ class TicketStore(UUIDModel):
|
||||
) # Associated validator for this ticket
|
||||
|
||||
# "fake" declarations for type checking
|
||||
objects: 'models.manager.Manager[TicketStore]'
|
||||
# objects: 'models.manager.Manager[TicketStore]'
|
||||
|
||||
class InvalidTicket(Exception):
|
||||
pass
|
||||
@ -151,11 +151,11 @@ class TicketStore(UUIDModel):
|
||||
data, typing.cast(str, owner).encode()
|
||||
)
|
||||
|
||||
data = pickle.loads(data)
|
||||
data = pickle.loads(data) # nosec: Tickets are generated by us, so we know they are safe
|
||||
|
||||
# If has validator, execute it
|
||||
if t.validator:
|
||||
validator: ValidatorType = pickle.loads(t.validator)
|
||||
validator: ValidatorType = pickle.loads(t.validator) # nosec: Tickets are generated by us, so we know they are safe
|
||||
|
||||
if validator(data) is False:
|
||||
raise TicketStore.InvalidTicket('Validation failed')
|
||||
@ -194,7 +194,7 @@ class TicketStore(UUIDModel):
|
||||
) -> str:
|
||||
owner = cryptoManager().randomString(length=8)
|
||||
data = {
|
||||
'u': userService.user.uuid,
|
||||
'u': userService.user.uuid if userService.user else '',
|
||||
's': userService.uuid,
|
||||
'h': host,
|
||||
'p': port,
|
||||
@ -259,7 +259,7 @@ class TicketStore(UUIDModel):
|
||||
TicketStore.objects.filter(stamp__lt=cleanSince).delete()
|
||||
|
||||
def __str__(self) -> str:
|
||||
data = pickle.loads(self.data) if self.owner != SECURED else '{Secure Ticket}'
|
||||
data = pickle.loads(self.data) if self.owner != SECURED else '{Secure Ticket}' # nosec: Tickets are generated by us, so we know they are safe
|
||||
|
||||
return 'Ticket id: {}, Owner: {}, Stamp: {}, Validity: {}, Data: {}'.format(
|
||||
self.uuid,
|
||||
|
@ -71,7 +71,7 @@ class Transport(ManagedObjectModel, TaggingMixin):
|
||||
label = models.CharField(max_length=32, default='', db_index=True)
|
||||
|
||||
# "fake" declarations for type checking
|
||||
objects: 'models.manager.Manager[Transport]'
|
||||
# objects: 'models.manager.Manager[Transport]'
|
||||
|
||||
deployedServices: 'models.manager.RelatedManager[ServicePool]'
|
||||
networks: 'models.manager.RelatedManager[Network]'
|
||||
|
@ -48,7 +48,7 @@ class TunnelToken(models.Model):
|
||||
stamp = models.DateTimeField() # Date creation or validation of this entry
|
||||
|
||||
# "fake" declarations for type checking
|
||||
objects: 'models.manager.Manager[TunnelToken]'
|
||||
# objects: 'models.manager.Manager[TunnelToken]'
|
||||
|
||||
class Meta:
|
||||
app_label = 'uds'
|
||||
|
@ -50,7 +50,7 @@ class UniqueId(models.Model):
|
||||
stamp = models.IntegerField(db_index=True, default=0)
|
||||
|
||||
# "fake" declarations for type checking
|
||||
objects: 'models.manager.Manager[UniqueId]'
|
||||
# objects: 'models.manager.Manager[UniqueId]'
|
||||
|
||||
class Meta:
|
||||
"""
|
||||
|
@ -57,7 +57,7 @@ class User(UUIDModel):
|
||||
This class represents a single user, associated with one authenticator
|
||||
"""
|
||||
|
||||
manager: 'models.ForeignKey["User", Authenticator]' = UnsavedForeignKey(
|
||||
manager: 'models.ForeignKey[Authenticator]' = UnsavedForeignKey(
|
||||
Authenticator, on_delete=models.CASCADE, related_name='users'
|
||||
)
|
||||
name = models.CharField(max_length=128, db_index=True)
|
||||
@ -79,7 +79,7 @@ class User(UUIDModel):
|
||||
created = models.DateTimeField(default=getSqlDatetime, blank=True)
|
||||
|
||||
# "fake" declarations for type checking
|
||||
objects: 'models.manager.Manager["User"]'
|
||||
# objects: 'models.manager.Manager["User"]'
|
||||
groups: 'models.manager.RelatedManager[Group]'
|
||||
userServices: 'models.manager.RelatedManager[UserService]'
|
||||
permissions: 'models.manager.RelatedManager[Permissions]'
|
||||
|
@ -51,7 +51,7 @@ class UserPreference(models.Model):
|
||||
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='preferences')
|
||||
|
||||
# "fake" declarations for type checking
|
||||
objects: 'models.manager.Manager[UserPreference]'
|
||||
# objects: 'models.manager.Manager[UserPreference]'
|
||||
|
||||
class Meta:
|
||||
app_label = 'uds'
|
||||
|
@ -71,18 +71,16 @@ class UserService(UUIDModel): # pylint: disable=too-many-public-methods
|
||||
|
||||
# The reference to deployed service is used to accelerate the queries for different methods, in fact its redundant cause we can access to the deployed service
|
||||
# through publication, but queries are much more simple
|
||||
deployed_service: 'models.ForeignKey["UserService", ServicePool]' = models.ForeignKey(
|
||||
deployed_service: 'models.ForeignKey["ServicePool"]' = models.ForeignKey(
|
||||
ServicePool, on_delete=models.CASCADE, related_name='userServices'
|
||||
)
|
||||
publication: 'models.ForeignKey["UserService", ServicePoolPublication]' = (
|
||||
models.ForeignKey(
|
||||
publication: 'models.ForeignKey[ServicePoolPublication | None]' = models.ForeignKey(
|
||||
ServicePoolPublication,
|
||||
on_delete=models.CASCADE,
|
||||
null=True,
|
||||
blank=True,
|
||||
related_name='userServices',
|
||||
)
|
||||
)
|
||||
|
||||
unique_id = models.CharField(
|
||||
max_length=128, default='', db_index=True
|
||||
@ -116,7 +114,7 @@ class UserService(UUIDModel): # pylint: disable=too-many-public-methods
|
||||
src_ip = models.CharField(max_length=128, default='')
|
||||
|
||||
# "fake" declarations for type checking
|
||||
objects: 'models.manager.Manager["UserService"]'
|
||||
# objects: 'models.manager.Manager["UserService"]'
|
||||
properties: 'models.manager.RelatedManager[UserServiceProperty]'
|
||||
sessions: 'models.manager.RelatedManager[UserServiceSession]'
|
||||
accounting: 'AccountUsage'
|
||||
@ -174,7 +172,7 @@ class UserService(UUIDModel): # pylint: disable=too-many-public-methods
|
||||
(see related classes uds.core.util.unique_name_generator and uds.core.util.unique_mac_generator)
|
||||
"""
|
||||
return Environment.getEnvForTableElement(
|
||||
self._meta.verbose_name,
|
||||
self._meta.verbose_name, # type: ignore
|
||||
self.id,
|
||||
{
|
||||
'mac': unique.UniqueMacGenerator,
|
||||
@ -201,6 +199,8 @@ class UserService(UUIDModel): # pylint: disable=too-many-public-methods
|
||||
"""
|
||||
# We get the service instance, publication instance and osmanager instance
|
||||
servicePool = self.deployed_service
|
||||
if not servicePool.service:
|
||||
raise Exception('Service not found')
|
||||
serviceInstance = servicePool.service.getInstance()
|
||||
if serviceInstance.needsManager is False or not servicePool.osmanager:
|
||||
osmanagerInstance = None
|
||||
@ -374,6 +374,8 @@ class UserService(UUIDModel): # pylint: disable=too-many-public-methods
|
||||
:note: This method MUST be invoked by transport before using credentials passed to getJavascript.
|
||||
"""
|
||||
servicePool = self.deployed_service
|
||||
if not servicePool.service:
|
||||
raise Exception('Service not found')
|
||||
serviceInstance = servicePool.service.getInstance()
|
||||
if serviceInstance.needsManager is False or not servicePool.osmanager:
|
||||
return (username, password)
|
||||
@ -615,7 +617,7 @@ class UserService(UUIDModel): # pylint: disable=too-many-public-methods
|
||||
Returns True if this user service does not needs an publication, or if this deployed service publication is the current one
|
||||
"""
|
||||
return (
|
||||
self.deployed_service.service.getType().publicationType is None
|
||||
(self.deployed_service.service and self.deployed_service.service.getType().publicationType is None)
|
||||
or self.publication == self.deployed_service.activePublication()
|
||||
)
|
||||
|
||||
|
@ -53,7 +53,7 @@ class UserServiceProperty(models.Model): # pylint: disable=too-many-public-meth
|
||||
)
|
||||
|
||||
# "fake" declarations for type checking
|
||||
objects: 'models.manager.Manager[UserServiceProperty]'
|
||||
# objects: 'models.manager.Manager[UserServiceProperty]'
|
||||
|
||||
class Meta:
|
||||
"""
|
||||
|
@ -58,12 +58,12 @@ class UserServiceSession(models.Model): # pylint: disable=too-many-public-metho
|
||||
start = models.DateTimeField(default=getSqlDatetime)
|
||||
end = models.DateTimeField(null=True, blank=True)
|
||||
|
||||
user_service = models.ForeignKey(
|
||||
user_service: 'models.ForeignKey[UserService]' = models.ForeignKey(
|
||||
UserService, on_delete=models.CASCADE, related_name='sessions'
|
||||
)
|
||||
|
||||
# "fake" declarations for type checking
|
||||
objects: 'models.manager.Manager["UserServiceSession"]'
|
||||
# objects: 'models.manager.Manager["UserServiceSession"]'
|
||||
|
||||
class Meta:
|
||||
"""
|
||||
|
@ -55,14 +55,16 @@ class UnsavedForeignKey(models.ForeignKey):
|
||||
|
||||
|
||||
def getSqlDatetime() -> datetime:
|
||||
"""
|
||||
Returns the current date/time of the database server.
|
||||
"""Returns the current date/time of the database server.
|
||||
|
||||
We use this time as method of keeping all operations betwen different servers in sync.
|
||||
We use this time as method to keep all operations betwen different servers in sync.
|
||||
|
||||
We support get database datetime for:
|
||||
* mysql
|
||||
* sqlite
|
||||
|
||||
Returns:
|
||||
datetime: Current datetime of the database server
|
||||
"""
|
||||
if connection.vendor in ('mysql', 'microsoft'):
|
||||
cursor = connection.cursor()
|
||||
@ -72,7 +74,7 @@ def getSqlDatetime() -> datetime:
|
||||
else 'SELECT CURRENT_TIMESTAMP'
|
||||
)
|
||||
cursor.execute(sentence)
|
||||
date = cursor.fetchone()[0]
|
||||
date = (cursor.fetchone() or [datetime.now()])[0]
|
||||
else:
|
||||
date = (
|
||||
datetime.now()
|
||||
@ -82,12 +84,19 @@ def getSqlDatetime() -> datetime:
|
||||
|
||||
|
||||
def getSqlDatetimeAsUnix() -> int:
|
||||
"""Returns the current date/time of the database server as unix timestamp
|
||||
|
||||
Returns:
|
||||
int: Unix timestamp
|
||||
"""
|
||||
return int(mktime(getSqlDatetime().timetuple()))
|
||||
|
||||
|
||||
def getSqlFnc(fncName: str) -> str:
|
||||
"""
|
||||
Convert different sql functions for different platforms
|
||||
"""Convert different sql functions for different platforms
|
||||
|
||||
i.e. CEIL --> CEILING on mssql
|
||||
|
||||
"""
|
||||
if connection.vendor == 'microsoft':
|
||||
return {'CEIL': 'CEILING'}.get(fncName, fncName)
|
||||
|
@ -45,7 +45,7 @@ class UUIDModel(models.Model):
|
||||
Base abstract model for models that require an uuid
|
||||
"""
|
||||
|
||||
uuid = models.CharField(max_length=50, default=None, null=True, unique=True)
|
||||
uuid = models.CharField(max_length=50, unique=True, default=generateUuid)
|
||||
|
||||
# Automatic field from Model without a defined specific primary_key
|
||||
# Just a fake declaration to allow type checking
|
||||
@ -58,9 +58,7 @@ class UUIDModel(models.Model):
|
||||
return generateUuid()
|
||||
|
||||
# Override default save to add uuid
|
||||
def save(
|
||||
self, *args, **kwargs
|
||||
):
|
||||
def save(self, *args, **kwargs):
|
||||
if not self.uuid:
|
||||
self.uuid = self.genUuid()
|
||||
elif self.uuid != self.uuid.lower():
|
||||
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
@ -36,6 +36,7 @@ from uds.core import services
|
||||
from uds.core.ui import gui
|
||||
from uds.core.util import validators
|
||||
from uds.core.util.unique_id_generator import UniqueIDGenerator
|
||||
from uds.core.util.unique_mac_generator import UniqueMacGenerator
|
||||
from uds.core.util.cache import Cache
|
||||
from uds.core.util.decorators import allowCache
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user