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'))]
|
'values': [gui.choiceItem('', _('None'))]
|
||||||
+ gui.sortedChoices(
|
+ gui.sortedChoices(
|
||||||
[
|
[
|
||||||
gui.choiceItem(v.uuid, v.name)
|
gui.choiceItem(v.uuid or '', v.name)
|
||||||
for v in MFA.objects.all()
|
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
|
Environmentable is a base class that provides utility method to access a separate Environment for every single
|
||||||
module.
|
module.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ['_uuid']
|
__slots__ = ['_uuid']
|
||||||
# Import variable indicating this module is a base class not a real module
|
# 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
|
# 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
|
Base 64 encoded or raw image, obtained from the specified file at
|
||||||
'iconFile' class attribute
|
'iconFile' class attribute
|
||||||
"""
|
"""
|
||||||
file_ = open(
|
try:
|
||||||
os.path.dirname(typing.cast(str, sys.modules[cls.__module__].__file__)) + '/' + cls.iconFile,
|
with open(
|
||||||
|
os.path.dirname(typing.cast(str, sys.modules[cls.__module__].__file__))
|
||||||
|
+ '/'
|
||||||
|
+ cls.iconFile,
|
||||||
'rb',
|
'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
|
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
|
from django.db import migrations, models
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
|
import uds.core.util.model
|
||||||
import uds.models.notifications
|
import uds.models.notifications
|
||||||
import uds.models.user_service_session
|
import uds.models.user_service_session
|
||||||
import uds.models.util
|
import uds.models.util
|
||||||
@ -52,7 +53,9 @@ class Migration(migrations.Migration):
|
|||||||
(
|
(
|
||||||
"uuid",
|
"uuid",
|
||||||
models.CharField(
|
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)),
|
("data_type", models.CharField(max_length=128)),
|
||||||
@ -66,7 +69,6 @@ class Migration(migrations.Migration):
|
|||||||
default=uds.models.notifications.NotificationLevel["ERROR"]
|
default=uds.models.notifications.NotificationLevel["ERROR"]
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
("tags", models.ManyToManyField(to="uds.tag")),
|
|
||||||
],
|
],
|
||||||
options={
|
options={
|
||||||
"db_table": "uds_notify_prov",
|
"db_table": "uds_notify_prov",
|
||||||
@ -115,6 +117,9 @@ class Migration(migrations.Migration):
|
|||||||
"db_table": "uds__user_service_session",
|
"db_table": "uds__user_service_session",
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
migrations.DeleteModel(
|
||||||
|
name="DBFile",
|
||||||
|
),
|
||||||
migrations.RemoveField(
|
migrations.RemoveField(
|
||||||
model_name="authenticator",
|
model_name="authenticator",
|
||||||
name="visible",
|
name="visible",
|
||||||
@ -175,6 +180,125 @@ class Migration(migrations.Migration):
|
|||||||
name="comments",
|
name="comments",
|
||||||
field=models.CharField(default="", max_length=256),
|
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(
|
migrations.AlterField(
|
||||||
model_name="service",
|
model_name="service",
|
||||||
name="token",
|
name="token",
|
||||||
@ -182,6 +306,55 @@ class Migration(migrations.Migration):
|
|||||||
blank=True, default=None, max_length=64, null=True, unique=True
|
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(
|
migrations.AlterField(
|
||||||
model_name="tunneltoken",
|
model_name="tunneltoken",
|
||||||
name="ip",
|
name="ip",
|
||||||
@ -192,11 +365,25 @@ class Migration(migrations.Migration):
|
|||||||
name="ip_from",
|
name="ip_from",
|
||||||
field=models.CharField(max_length=128),
|
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(
|
migrations.AlterField(
|
||||||
model_name="userservice",
|
model_name="userservice",
|
||||||
name="src_ip",
|
name="src_ip",
|
||||||
field=models.CharField(default="", max_length=128),
|
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(
|
migrations.DeleteModel(
|
||||||
name="Proxy",
|
name="Proxy",
|
||||||
),
|
),
|
||||||
@ -218,6 +405,11 @@ class Migration(migrations.Migration):
|
|||||||
to="uds.service",
|
to="uds.service",
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="notifier",
|
||||||
|
name="tags",
|
||||||
|
field=models.ManyToManyField(to="uds.tag"),
|
||||||
|
),
|
||||||
migrations.AddConstraint(
|
migrations.AddConstraint(
|
||||||
model_name="userservicesession",
|
model_name="userservicesession",
|
||||||
constraint=models.UniqueConstraint(
|
constraint=models.UniqueConstraint(
|
||||||
|
@ -106,9 +106,6 @@ from .account_usage import AccountUsage
|
|||||||
# Tagging
|
# Tagging
|
||||||
from .tag import Tag, TaggingMixin
|
from .tag import Tag, TaggingMixin
|
||||||
|
|
||||||
# Utility
|
|
||||||
from .dbfile import DBFile
|
|
||||||
|
|
||||||
# Tokens
|
# Tokens
|
||||||
from .actor_token import ActorToken
|
from .actor_token import ActorToken
|
||||||
from .tunnel_token import TunnelToken
|
from .tunnel_token import TunnelToken
|
||||||
|
@ -55,7 +55,7 @@ class Account(UUIDModel, TaggingMixin):
|
|||||||
comments = models.CharField(max_length=256, default='')
|
comments = models.CharField(max_length=256, default='')
|
||||||
|
|
||||||
# "fake" declarations for type checking
|
# "fake" declarations for type checking
|
||||||
objects: 'models.manager.Manager["Account"]'
|
#objects: 'models.manager.Manager["Account"]'
|
||||||
usages: 'models.manager.RelatedManager[AccountUsage]'
|
usages: 'models.manager.RelatedManager[AccountUsage]'
|
||||||
|
|
||||||
def startUsageAccounting(self, userService: 'UserService') -> typing.Optional['AccountUsage']:
|
def startUsageAccounting(self, userService: 'UserService') -> typing.Optional['AccountUsage']:
|
||||||
|
@ -54,7 +54,7 @@ class AccountUsage(UUIDModel):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
# "fake" declarations for type checking
|
# "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_name = models.CharField(max_length=128, db_index=True, default='')
|
||||||
user_uuid = models.CharField(max_length=50, 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='')
|
pool_uuid = models.CharField(max_length=50, db_index=True, default='')
|
||||||
start = models.DateTimeField(default=NEVER)
|
start = models.DateTimeField(default=NEVER)
|
||||||
end = models.DateTimeField(default=NEVER)
|
end = models.DateTimeField(default=NEVER)
|
||||||
user_service: 'models.OneToOneField["AccountUsage", UserService]' = (
|
user_service: 'models.OneToOneField[UserService | None]' = (
|
||||||
models.OneToOneField(
|
models.OneToOneField(
|
||||||
UserService,
|
UserService,
|
||||||
null=True,
|
null=True,
|
||||||
@ -71,7 +71,7 @@ class AccountUsage(UUIDModel):
|
|||||||
on_delete=models.SET_NULL,
|
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
|
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
|
stamp = models.DateTimeField() # Date creation or validation of this entry
|
||||||
|
|
||||||
# "fake" declarations for type checking
|
# "fake" declarations for type checking
|
||||||
objects: 'models.manager.Manager[ActorToken]'
|
# objects: 'models.manager.Manager[ActorToken]'
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
app_label = 'uds'
|
app_label = 'uds'
|
||||||
|
@ -76,7 +76,7 @@ class Authenticator(ManagedObjectModel, TaggingMixin):
|
|||||||
net_filtering = models.CharField(max_length=1, default=NO_FILTERING, db_index=True)
|
net_filtering = models.CharField(max_length=1, default=NO_FILTERING, db_index=True)
|
||||||
|
|
||||||
# "fake" relations declarations for type checking
|
# "fake" relations declarations for type checking
|
||||||
objects: 'models.manager.Manager["Authenticator"]'
|
# objects: 'models.manager.Manager["Authenticator"]'
|
||||||
users: 'models.manager.RelatedManager[User]'
|
users: 'models.manager.RelatedManager[User]'
|
||||||
groups: 'models.manager.RelatedManager[Group]'
|
groups: 'models.manager.RelatedManager[Group]'
|
||||||
|
|
||||||
@ -163,7 +163,7 @@ class Authenticator(ManagedObjectModel, TaggingMixin):
|
|||||||
Raises:
|
Raises:
|
||||||
"""
|
"""
|
||||||
user: 'User'
|
user: 'User'
|
||||||
realName = realName if realName is None else username
|
realName = realName or username
|
||||||
user, _ = self.users.get_or_create(
|
user, _ = self.users.get_or_create(
|
||||||
name=username,
|
name=username,
|
||||||
defaults={
|
defaults={
|
||||||
|
@ -49,13 +49,12 @@ class Cache(models.Model):
|
|||||||
owner = models.CharField(max_length=128, db_index=True)
|
owner = models.CharField(max_length=128, db_index=True)
|
||||||
key = models.CharField(max_length=64, primary_key=True)
|
key = models.CharField(max_length=64, primary_key=True)
|
||||||
value = models.TextField(default='')
|
value = models.TextField(default='')
|
||||||
created = (
|
# Date creation or validation of this entry. Set at write time
|
||||||
models.DateTimeField()
|
created = models.DateTimeField()
|
||||||
) # Date creation or validation of this entry. Set at write time
|
|
||||||
validity = models.IntegerField(default=60) # Validity of this entry, in seconds
|
validity = models.IntegerField(default=60) # Validity of this entry, in seconds
|
||||||
|
|
||||||
# "fake" relations declarations for type checking
|
# "fake" relations declarations for type checking
|
||||||
objects: 'models.manager.Manager[Cache]'
|
# objects: 'models.manager.Manager[Cache]'
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
"""
|
"""
|
||||||
|
@ -52,7 +52,7 @@ class Calendar(UUIDModel, TaggingMixin):
|
|||||||
modified = models.DateTimeField(auto_now=True)
|
modified = models.DateTimeField(auto_now=True)
|
||||||
|
|
||||||
# "fake" declarations for type checking
|
# "fake" declarations for type checking
|
||||||
objects: 'models.manager.Manager["Calendar"]'
|
# objects: 'models.manager.Manager["Calendar"]'
|
||||||
rules: 'models.manager.RelatedManager[CalendarRule]'
|
rules: 'models.manager.RelatedManager[CalendarRule]'
|
||||||
calendaraction_set: 'models.manager.RelatedManager[CalendarAction]'
|
calendaraction_set: 'models.manager.RelatedManager[CalendarAction]'
|
||||||
calendaraccess_set: 'models.manager.RelatedManager[CalendarAccess]'
|
calendaraccess_set: 'models.manager.RelatedManager[CalendarAccess]'
|
||||||
|
@ -47,17 +47,17 @@ logger = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
class CalendarAccess(UUIDModel):
|
class CalendarAccess(UUIDModel):
|
||||||
calendar: 'models.ForeignKey[CalendarAccess, Calendar]' = models.ForeignKey(
|
calendar: 'models.ForeignKey[Calendar]' = models.ForeignKey(
|
||||||
Calendar, on_delete=models.CASCADE
|
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
|
ServicePool, related_name='calendarAccess', on_delete=models.CASCADE
|
||||||
)
|
)
|
||||||
access = models.CharField(max_length=8, default=states.action.DENY)
|
access = models.CharField(max_length=8, default=states.action.DENY)
|
||||||
priority = models.IntegerField(default=0, db_index=True)
|
priority = models.IntegerField(default=0, db_index=True)
|
||||||
|
|
||||||
# "fake" declarations for type checking
|
# "fake" declarations for type checking
|
||||||
objects: 'models.manager.Manager[CalendarAccess]'
|
# objects: 'models.manager.Manager[CalendarAccess]'
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
"""
|
"""
|
||||||
|
@ -231,10 +231,10 @@ CALENDAR_ACTION_DICT: typing.Dict[str, typing.Dict] = {
|
|||||||
|
|
||||||
|
|
||||||
class CalendarAction(UUIDModel):
|
class CalendarAction(UUIDModel):
|
||||||
calendar: 'models.ForeignKey[CalendarAction, Calendar]' = models.ForeignKey(
|
calendar: 'models.ForeignKey[Calendar]' = models.ForeignKey(
|
||||||
Calendar, on_delete=models.CASCADE
|
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
|
ServicePool, on_delete=models.CASCADE
|
||||||
)
|
)
|
||||||
action = models.CharField(max_length=64, default='')
|
action = models.CharField(max_length=64, default='')
|
||||||
@ -252,7 +252,7 @@ class CalendarAction(UUIDModel):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# "fake" declarations for type checking
|
# "fake" declarations for type checking
|
||||||
objects: 'models.manager.Manager[CalendarAction]'
|
# objects: 'models.manager.Manager[CalendarAction]'
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
"""
|
"""
|
||||||
|
@ -109,12 +109,12 @@ class CalendarRule(UUIDModel):
|
|||||||
duration = models.IntegerField(default=0) # Duration in "duration_unit" units
|
duration = models.IntegerField(default=0) # Duration in "duration_unit" units
|
||||||
duration_unit = models.CharField(choices=dunits, default='MINUTES', max_length=32)
|
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
|
Calendar, related_name='rules', on_delete=models.CASCADE
|
||||||
)
|
)
|
||||||
|
|
||||||
# "fake" declarations for type checking
|
# "fake" declarations for type checking
|
||||||
objects: 'models.manager.Manager["CalendarRule"]'
|
# objects: 'models.manager.Manager["CalendarRule"]'
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
"""
|
"""
|
||||||
@ -134,7 +134,11 @@ class CalendarRule(UUIDModel):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# If at end of interval is requested, displace dstart to match end of interval
|
# 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:
|
if self.frequency == WEEKDAYS:
|
||||||
dw = []
|
dw = []
|
||||||
|
@ -53,7 +53,7 @@ class Config(models.Model):
|
|||||||
help = models.CharField(max_length=256, default='')
|
help = models.CharField(max_length=256, default='')
|
||||||
|
|
||||||
# "fake" declarations for type checking
|
# "fake" declarations for type checking
|
||||||
objects: 'models.manager.Manager[Config]'
|
# objects: 'models.manager.Manager[Config]'
|
||||||
|
|
||||||
class Meta:
|
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)
|
execution_time = models.DateTimeField(db_index=True)
|
||||||
|
|
||||||
# "fake" declarations for type checking
|
# "fake" declarations for type checking
|
||||||
objects: 'models.manager.Manager[DelayedTask]'
|
# objects: 'models.manager.Manager[DelayedTask]'
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
"""
|
"""
|
||||||
|
@ -56,7 +56,7 @@ class Group(UUIDModel):
|
|||||||
This class represents a group, associated with one authenticator
|
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'
|
Authenticator, on_delete=models.CASCADE, related_name='groups'
|
||||||
)
|
)
|
||||||
name = models.CharField(max_length=128, db_index=True)
|
name = models.CharField(max_length=128, db_index=True)
|
||||||
@ -69,7 +69,7 @@ class Group(UUIDModel):
|
|||||||
created = models.DateTimeField(default=getSqlDatetime, blank=True)
|
created = models.DateTimeField(default=getSqlDatetime, blank=True)
|
||||||
|
|
||||||
# "fake" declarations for type checking
|
# "fake" declarations for type checking
|
||||||
objects: 'models.manager.Manager["Group"]'
|
# objects: 'models.manager.Manager["Group"]'
|
||||||
deployedServices: 'models.manager.RelatedManager[ServicePool]'
|
deployedServices: 'models.manager.RelatedManager[ServicePool]'
|
||||||
permissions: 'models.manager.RelatedManager[Permissions]'
|
permissions: 'models.manager.RelatedManager[Permissions]'
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ class Image(UUIDModel):
|
|||||||
height = models.IntegerField(default=0)
|
height = models.IntegerField(default=0)
|
||||||
|
|
||||||
# "fake" declarations for type checking
|
# "fake" declarations for type checking
|
||||||
objects: 'models.manager.RelatedManager["Image"]'
|
# objects: 'models.manager.RelatedManager["Image"]'
|
||||||
|
|
||||||
deployedServices: 'models.manager.RelatedManager[ServicePool]'
|
deployedServices: 'models.manager.RelatedManager[ServicePool]'
|
||||||
metaPools: 'models.manager.RelatedManager[MetaPool]'
|
metaPools: 'models.manager.RelatedManager[MetaPool]'
|
||||||
|
@ -55,7 +55,7 @@ class Log(models.Model):
|
|||||||
data = models.CharField(max_length=255, default='')
|
data = models.CharField(max_length=255, default='')
|
||||||
|
|
||||||
# "fake" declarations for type checking
|
# "fake" declarations for type checking
|
||||||
objects: 'models.manager.Manager[Log]'
|
# objects: 'models.manager.Manager[Log]'
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
"""
|
"""
|
||||||
|
@ -68,9 +68,11 @@ class ManagedObjectModel(UUIDModel):
|
|||||||
"""
|
"""
|
||||||
Returns an environment valid for the record this object represents
|
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
|
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)
|
ha_policy = models.SmallIntegerField(default=HA_POLICY_DISABLED)
|
||||||
|
|
||||||
# "fake" declarations for type checking
|
# "fake" declarations for type checking
|
||||||
objects: 'models.BaseManager["MetaPool"]'
|
# objects: 'models.BaseManager["MetaPool"]'
|
||||||
calendarAccess: 'models.QuerySet[CalendarAccessMeta]'
|
calendarAccess: 'models.QuerySet[CalendarAccessMeta]'
|
||||||
members: 'models.QuerySet["MetaPoolMember"]'
|
members: 'models.QuerySet["MetaPoolMember"]'
|
||||||
|
|
||||||
@ -182,7 +182,9 @@ class MetaPool(UUIDModel, TaggingMixin): # type: ignore
|
|||||||
|
|
||||||
access = self.fallbackAccess
|
access = self.fallbackAccess
|
||||||
# Let's see if we can access by current datetime
|
# 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):
|
if CalendarChecker(ac.calendar).check(chkDateTime):
|
||||||
access = ac.access
|
access = ac.access
|
||||||
break # Stops on first rule match found
|
break # Stops on first rule match found
|
||||||
@ -278,10 +280,10 @@ signals.pre_delete.connect(MetaPool.beforeDelete, sender=MetaPool)
|
|||||||
|
|
||||||
|
|
||||||
class MetaPoolMember(UUIDModel):
|
class MetaPoolMember(UUIDModel):
|
||||||
pool: 'models.ForeignKey["MetaPoolMember", ServicePool]' = models.ForeignKey(
|
pool: 'models.ForeignKey[ServicePool]' = models.ForeignKey(
|
||||||
ServicePool, related_name='memberOfMeta', on_delete=models.CASCADE
|
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
|
MetaPool, related_name='members', on_delete=models.CASCADE
|
||||||
)
|
)
|
||||||
priority = models.PositiveIntegerField(default=0)
|
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.
|
An OS Manager represents a manager for responding requests for agents inside services.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# "fake" declarations for type checking
|
# Time to remember the device MFA in hours
|
||||||
objects: 'models.BaseManager[MFA]'
|
remember_device = models.IntegerField(default=0)
|
||||||
authenticators: 'models.manager.RelatedManager[Authenticator]'
|
# 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
|
# "fake" declarations for type checking
|
||||||
validity = models.IntegerField(default=0) # Limit of time for this MFA to be used, in seconds
|
# objects: 'models.BaseManager[MFA]'
|
||||||
|
authenticators: 'models.manager.RelatedManager[Authenticator]'
|
||||||
|
|
||||||
def getInstance(
|
def getInstance(
|
||||||
self, values: typing.Optional[typing.Dict[str, str]] = None
|
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))
|
return typing.cast('mfas.MFA', super().getInstance(values=values))
|
||||||
|
|
||||||
def getType(self) -> typing.Type['mfas.MFA']:
|
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:
|
Returns:
|
||||||
The python type for this record object
|
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)
|
# We only need to get info from this, not access specific data (class specific info)
|
||||||
from uds.core import mfas
|
from uds.core import mfas
|
||||||
@ -100,7 +102,11 @@ class MFA(ManagedObjectModel, TaggingMixin): # type: ignore
|
|||||||
s.destroy()
|
s.destroy()
|
||||||
s.env.clearRelatedData()
|
s.env.clearRelatedData()
|
||||||
except Exception as e:
|
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)
|
logger.debug('Before delete mfa provider %s', toDelete)
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ class Network(UUIDModel, TaggingMixin): # type: ignore
|
|||||||
)
|
)
|
||||||
|
|
||||||
# "fake" declarations for type checking
|
# "fake" declarations for type checking
|
||||||
objects: 'models.manager.Manager[Network]'
|
# objects: 'models.manager.Manager[Network]'
|
||||||
|
|
||||||
class Meta(UUIDModel.Meta):
|
class Meta(UUIDModel.Meta):
|
||||||
"""
|
"""
|
||||||
|
@ -73,7 +73,7 @@ class Notification(models.Model):
|
|||||||
processed = models.BooleanField(default=False)
|
processed = models.BooleanField(default=False)
|
||||||
|
|
||||||
# "fake" declarations for type checking
|
# "fake" declarations for type checking
|
||||||
objects: 'models.BaseManager[Notification]'
|
# objects: 'models.BaseManager[Notification]'
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
"""
|
"""
|
||||||
|
@ -52,7 +52,7 @@ class OSManager(ManagedObjectModel, TaggingMixin):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
# "fake" declarations for type checking
|
# "fake" declarations for type checking
|
||||||
objects: 'models.manager.Manager[OSManager]'
|
# objects: 'models.manager.Manager[OSManager]'
|
||||||
deployedServices: 'models.manager.RelatedManager[ServicePool]'
|
deployedServices: 'models.manager.RelatedManager[ServicePool]'
|
||||||
|
|
||||||
class Meta(ManagedObjectModel.Meta):
|
class Meta(ManagedObjectModel.Meta):
|
||||||
|
@ -84,7 +84,7 @@ class Permissions(UUIDModel):
|
|||||||
permission = models.SmallIntegerField(default=PERMISSION_NONE, db_index=True)
|
permission = models.SmallIntegerField(default=PERMISSION_NONE, db_index=True)
|
||||||
|
|
||||||
# "fake" declarations for type checking
|
# "fake" declarations for type checking
|
||||||
objects: 'models.manager.Manager[Permissions]'
|
# objects: 'models.manager.Manager[Permissions]'
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def permissionAsString(perm: int) -> str:
|
def permissionAsString(perm: int) -> str:
|
||||||
|
@ -56,7 +56,7 @@ class Provider(ManagedObjectModel, TaggingMixin): # type: ignore
|
|||||||
maintenance_mode = models.BooleanField(default=False, db_index=True)
|
maintenance_mode = models.BooleanField(default=False, db_index=True)
|
||||||
|
|
||||||
# "fake" declarations for type checking
|
# "fake" declarations for type checking
|
||||||
objects: 'models.manager.Manager[Provider]'
|
# objects: 'models.manager.Manager[Provider]'
|
||||||
services: 'models.manager.RelatedManager[Service]'
|
services: 'models.manager.RelatedManager[Service]'
|
||||||
|
|
||||||
class Meta(ManagedObjectModel.Meta):
|
class Meta(ManagedObjectModel.Meta):
|
||||||
|
@ -73,7 +73,7 @@ class Scheduler(models.Model):
|
|||||||
# primary key id declaration (for type checking)
|
# primary key id declaration (for type checking)
|
||||||
|
|
||||||
# "fake" declarations 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)
|
id: int # Primary key (Autogenerated by model, just for type checking)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
@ -87,7 +87,7 @@ class Scheduler(models.Model):
|
|||||||
"""
|
"""
|
||||||
Returns an environment valid for the record this object represents
|
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]:
|
def getInstance(self) -> typing.Optional[jobs.Job]:
|
||||||
"""
|
"""
|
||||||
|
@ -74,7 +74,7 @@ class Service(ManagedObjectModel, TaggingMixin): # type: ignore
|
|||||||
Server configuration).
|
Server configuration).
|
||||||
"""
|
"""
|
||||||
|
|
||||||
provider: 'models.ForeignKey["Service", Provider]' = models.ForeignKey(
|
provider: 'models.ForeignKey[Provider]' = models.ForeignKey(
|
||||||
Provider, related_name='services', on_delete=models.CASCADE
|
Provider, related_name='services', on_delete=models.CASCADE
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -89,11 +89,10 @@ class Service(ManagedObjectModel, TaggingMixin): # type: ignore
|
|||||||
_cachedInstance: typing.Optional['services.Service'] = None
|
_cachedInstance: typing.Optional['services.Service'] = None
|
||||||
|
|
||||||
# "fake" declarations for type checking
|
# "fake" declarations for type checking
|
||||||
objects: 'models.manager.Manager["Service"]'
|
# objects: 'models.manager.Manager["Service"]'
|
||||||
deployedServices: 'models.manager.RelatedManager[ServicePool]'
|
deployedServices: 'models.manager.RelatedManager[ServicePool]'
|
||||||
aliases: 'models.manager.RelatedManager[ServiceTokenAlias]'
|
aliases: 'models.manager.RelatedManager[ServiceTokenAlias]'
|
||||||
|
|
||||||
|
|
||||||
class Meta(ManagedObjectModel.Meta):
|
class Meta(ManagedObjectModel.Meta):
|
||||||
"""
|
"""
|
||||||
Meta class to declare default order and unique multiple field index
|
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
|
Returns an environment valid for the record this object represents
|
||||||
"""
|
"""
|
||||||
return Environment.getEnvForTableElement(
|
return Environment.getEnvForTableElement(
|
||||||
self._meta.verbose_name,
|
self._meta.verbose_name, # type: ignore
|
||||||
self.id,
|
self.id,
|
||||||
{
|
{
|
||||||
'mac': unique.UniqueMacGenerator,
|
'mac': unique.UniqueMacGenerator,
|
||||||
@ -194,11 +193,9 @@ class Service(ManagedObjectModel, TaggingMixin): # type: ignore
|
|||||||
# Counts EVERYTHING for max limit checking
|
# Counts EVERYTHING for max limit checking
|
||||||
return self.max_services_count_type == 1
|
return self.max_services_count_type == 1
|
||||||
|
|
||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
return '{} of type {} (id:{})'.format(self.name, self.data_type, self.id)
|
return '{} of type {} (id:{})'.format(self.name, self.data_type, self.id)
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def beforeDelete(sender, **kwargs) -> None:
|
def beforeDelete(sender, **kwargs) -> None:
|
||||||
"""
|
"""
|
||||||
|
@ -70,7 +70,7 @@ if typing.TYPE_CHECKING:
|
|||||||
Group,
|
Group,
|
||||||
MetaPoolMember,
|
MetaPoolMember,
|
||||||
CalendarAccess,
|
CalendarAccess,
|
||||||
CalendarAction
|
CalendarAction,
|
||||||
)
|
)
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@ -84,14 +84,14 @@ class ServicePool(UUIDModel, TaggingMixin): # type: ignore
|
|||||||
name = models.CharField(max_length=128, default='')
|
name = models.CharField(max_length=128, default='')
|
||||||
short_name = models.CharField(max_length=32, default='')
|
short_name = models.CharField(max_length=32, default='')
|
||||||
comments = models.CharField(max_length=256, default='')
|
comments = models.CharField(max_length=256, default='')
|
||||||
service: 'models.ForeignKey["ServicePool", Service]' = models.ForeignKey(
|
service: 'models.ForeignKey[Service | None]' = models.ForeignKey(
|
||||||
Service,
|
Service,
|
||||||
null=True,
|
null=True,
|
||||||
blank=True,
|
blank=True,
|
||||||
related_name='deployedServices',
|
related_name='deployedServices',
|
||||||
on_delete=models.CASCADE,
|
on_delete=models.CASCADE,
|
||||||
)
|
)
|
||||||
osmanager: 'models.ForeignKey["ServicePool", OSManager]' = models.ForeignKey(
|
osmanager: 'models.ForeignKey[OSManager | None]' = models.ForeignKey(
|
||||||
OSManager,
|
OSManager,
|
||||||
null=True,
|
null=True,
|
||||||
blank=True,
|
blank=True,
|
||||||
@ -115,7 +115,7 @@ class ServicePool(UUIDModel, TaggingMixin): # type: ignore
|
|||||||
|
|
||||||
ignores_unused = models.BooleanField(default=False)
|
ignores_unused = models.BooleanField(default=False)
|
||||||
|
|
||||||
image: 'models.ForeignKey["ServicePool", Image]' = models.ForeignKey(
|
image: 'models.ForeignKey[Image | None]' = models.ForeignKey(
|
||||||
Image,
|
Image,
|
||||||
null=True,
|
null=True,
|
||||||
blank=True,
|
blank=True,
|
||||||
@ -123,15 +123,13 @@ class ServicePool(UUIDModel, TaggingMixin): # type: ignore
|
|||||||
on_delete=models.SET_NULL,
|
on_delete=models.SET_NULL,
|
||||||
)
|
)
|
||||||
|
|
||||||
servicesPoolGroup: 'models.ForeignKey["ServicePool", ServicePoolGroup]' = (
|
servicesPoolGroup: 'models.ForeignKey[ServicePoolGroup | None]' = models.ForeignKey(
|
||||||
models.ForeignKey(
|
|
||||||
ServicePoolGroup,
|
ServicePoolGroup,
|
||||||
null=True,
|
null=True,
|
||||||
blank=True,
|
blank=True,
|
||||||
related_name='servicesPools',
|
related_name='servicesPools',
|
||||||
on_delete=models.SET_NULL,
|
on_delete=models.SET_NULL,
|
||||||
)
|
)
|
||||||
)
|
|
||||||
|
|
||||||
# Message if access denied
|
# Message if access denied
|
||||||
calendar_message = models.CharField(default='', max_length=256)
|
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)
|
fallbackAccess = models.CharField(default=states.action.ALLOW, max_length=8)
|
||||||
|
|
||||||
# Usage accounting
|
# Usage accounting
|
||||||
account: 'models.ForeignKey["ServicePool", Account]' = models.ForeignKey(
|
account: 'models.ForeignKey[Account | None]' = models.ForeignKey(
|
||||||
Account,
|
Account,
|
||||||
null=True,
|
null=True,
|
||||||
blank=True,
|
blank=True,
|
||||||
@ -162,7 +160,6 @@ class ServicePool(UUIDModel, TaggingMixin): # type: ignore
|
|||||||
calendaraction_set: 'models.manager.RelatedManager[CalendarAction]'
|
calendaraction_set: 'models.manager.RelatedManager[CalendarAction]'
|
||||||
changelog: 'models.manager.RelatedManager[ServicePoolPublicationChangelog]'
|
changelog: 'models.manager.RelatedManager[ServicePoolPublicationChangelog]'
|
||||||
|
|
||||||
|
|
||||||
class Meta(UUIDModel.Meta):
|
class Meta(UUIDModel.Meta):
|
||||||
"""
|
"""
|
||||||
Meta class to declare the name of the table at database
|
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
|
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']:
|
def activePublication(self) -> typing.Optional['ServicePoolPublication']:
|
||||||
"""
|
"""
|
||||||
@ -316,12 +313,16 @@ class ServicePool(UUIDModel, TaggingMixin): # type: ignore
|
|||||||
'UserService',
|
'UserService',
|
||||||
self.assignedUserServices().filter(
|
self.assignedUserServices().filter(
|
||||||
user=forUser, state__in=states.userService.VALID_STATES
|
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:
|
if activePub and found.publication and activePub.id != found.publication.id:
|
||||||
ret = self.recoverValue('toBeReplacedIn')
|
ret = self.recoverValue('toBeReplacedIn')
|
||||||
if ret:
|
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
|
except Exception: # nosec: We don't want to fail if there is any exception
|
||||||
# logger.exception('Recovering publication death line')
|
# logger.exception('Recovering publication death line')
|
||||||
pass
|
pass
|
||||||
@ -337,7 +338,9 @@ class ServicePool(UUIDModel, TaggingMixin): # type: ignore
|
|||||||
|
|
||||||
access = self.fallbackAccess
|
access = self.fallbackAccess
|
||||||
# Let's see if we can access by current datetime
|
# 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):
|
if CalendarChecker(ac.calendar).check(chkDateTime):
|
||||||
access = ac.access
|
access = ac.access
|
||||||
break # Stops on first rule match found
|
break # Stops on first rule match found
|
||||||
@ -498,6 +501,7 @@ class ServicePool(UUIDModel, TaggingMixin): # type: ignore
|
|||||||
"""
|
"""
|
||||||
if (
|
if (
|
||||||
self.activePublication() is None
|
self.activePublication() is None
|
||||||
|
and self.service
|
||||||
and self.service.getType().publicationType is not None
|
and self.service.getType().publicationType is not None
|
||||||
):
|
):
|
||||||
raise InvalidServiceException()
|
raise InvalidServiceException()
|
||||||
@ -599,9 +603,9 @@ class ServicePool(UUIDModel, TaggingMixin): # type: ignore
|
|||||||
)
|
)
|
||||||
servicePool: 'ServicePool'
|
servicePool: 'ServicePool'
|
||||||
for servicePool in query:
|
for servicePool in query:
|
||||||
if (
|
if typing.cast(typing.Any, servicePool).pubs_active or (
|
||||||
typing.cast(typing.Any, servicePool).pubs_active
|
servicePool.service
|
||||||
or servicePool.service.data_type in servicesNotNeedingPub
|
and servicePool.service.data_type in servicesNotNeedingPub
|
||||||
):
|
):
|
||||||
yield servicePool
|
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)
|
cachedValue is used to optimize (if known the number of assigned services, we can avoid to query the db)
|
||||||
"""
|
"""
|
||||||
maxs = self.max_srvs
|
maxs = self.max_srvs
|
||||||
if maxs == 0:
|
if maxs == 0 and self.service:
|
||||||
maxs = self.service.getInstance().maxDeployed
|
maxs = self.service.getInstance().maxDeployed
|
||||||
|
|
||||||
if maxs <= 0:
|
if maxs <= 0:
|
||||||
@ -676,8 +680,10 @@ class ServicePool(UUIDModel, TaggingMixin): # type: ignore
|
|||||||
|
|
||||||
return 100 * cachedValue // maxs
|
return 100 * cachedValue // maxs
|
||||||
|
|
||||||
def testServer(self, host: str, port: typing.Union[str, int], timeout: float=4) -> bool:
|
def testServer(
|
||||||
return self.service.testServer(host, port, timeout)
|
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
|
# Utility for logging
|
||||||
def log(self, message: str, level: int = log.INFO) -> None:
|
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)
|
name = models.CharField(max_length=128, default='', db_index=True, unique=True)
|
||||||
comments = models.CharField(max_length=256, default='')
|
comments = models.CharField(max_length=256, default='')
|
||||||
priority = models.IntegerField(default=0, db_index=True)
|
priority = models.IntegerField(default=0, db_index=True)
|
||||||
image: 'models.ForeignKey[ServicePoolGroup, Image]' = models.ForeignKey(
|
image: 'models.ForeignKey[Image | None]' = models.ForeignKey(
|
||||||
Image,
|
Image,
|
||||||
null=True,
|
null=True,
|
||||||
blank=True,
|
blank=True,
|
||||||
@ -63,7 +63,7 @@ class ServicePoolGroup(UUIDModel):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# "fake" declarations for type checking
|
# "fake" declarations for type checking
|
||||||
objects: 'models.manager.Manager[ServicePoolGroup]'
|
# objects: 'models.manager.Manager[ServicePoolGroup]'
|
||||||
|
|
||||||
class Meta(UUIDModel.Meta):
|
class Meta(UUIDModel.Meta):
|
||||||
"""
|
"""
|
||||||
@ -75,7 +75,7 @@ class ServicePoolGroup(UUIDModel):
|
|||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
return 'Service Pool group {}({}): {}'.format(
|
return 'Service Pool group {}({}): {}'.format(
|
||||||
self.name, self.comments, self.image.name
|
self.name, self.comments, self.image.name if self.image else ''
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -55,17 +55,15 @@ logger = logging.getLogger(__name__)
|
|||||||
|
|
||||||
class ServicePoolPublicationChangelog(models.Model):
|
class ServicePoolPublicationChangelog(models.Model):
|
||||||
# This should be "servicePool"
|
# This should be "servicePool"
|
||||||
publication: 'models.ForeignKey[ServicePoolPublicationChangelog, ServicePool]' = (
|
publication: 'models.ForeignKey[ServicePool]' = models.ForeignKey(
|
||||||
models.ForeignKey(
|
|
||||||
ServicePool, on_delete=models.CASCADE, related_name='changelog'
|
ServicePool, on_delete=models.CASCADE, related_name='changelog'
|
||||||
)
|
)
|
||||||
)
|
|
||||||
stamp = models.DateTimeField()
|
stamp = models.DateTimeField()
|
||||||
revision = models.PositiveIntegerField(default=1)
|
revision = models.PositiveIntegerField(default=1)
|
||||||
log = models.TextField(default='')
|
log = models.TextField(default='')
|
||||||
|
|
||||||
# "fake" declarations for type checking
|
# "fake" declarations for type checking
|
||||||
objects: 'models.manager.Manager[ServicePoolPublicationChangelog]'
|
# objects: 'models.manager.Manager[ServicePoolPublicationChangelog]'
|
||||||
|
|
||||||
class Meta(UUIDModel.Meta):
|
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)
|
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]' = (
|
deployed_service: 'models.ForeignKey[ServicePool]' = models.ForeignKey(
|
||||||
models.ForeignKey(
|
|
||||||
ServicePool, on_delete=models.CASCADE, related_name='publications'
|
ServicePool, on_delete=models.CASCADE, related_name='publications'
|
||||||
)
|
)
|
||||||
)
|
|
||||||
publish_date = models.DateTimeField(db_index=True)
|
publish_date = models.DateTimeField(db_index=True)
|
||||||
# data_type = models.CharField(max_length=128) # The data type is specified by the service itself
|
# data_type = models.CharField(max_length=128) # The data type is specified by the service itself
|
||||||
data = models.TextField(default='')
|
data = models.TextField(default='')
|
||||||
@ -106,7 +102,7 @@ class ServicePoolPublication(UUIDModel):
|
|||||||
revision = models.PositiveIntegerField(default=1)
|
revision = models.PositiveIntegerField(default=1)
|
||||||
|
|
||||||
# "fake" declarations for type checking
|
# "fake" declarations for type checking
|
||||||
objects: 'models.manager.Manager["ServicePoolPublication"]'
|
# objects: 'models.manager.Manager["ServicePoolPublication"]'
|
||||||
userServices: 'models.manager.RelatedManager[UserService]'
|
userServices: 'models.manager.RelatedManager[UserService]'
|
||||||
|
|
||||||
class Meta(UUIDModel.Meta):
|
class Meta(UUIDModel.Meta):
|
||||||
@ -122,7 +118,7 @@ class ServicePoolPublication(UUIDModel):
|
|||||||
"""
|
"""
|
||||||
Returns an environment valid for the record this object represents
|
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':
|
def getInstance(self) -> 'services.Publication':
|
||||||
"""
|
"""
|
||||||
@ -139,6 +135,8 @@ class ServicePoolPublication(UUIDModel):
|
|||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
"""
|
"""
|
||||||
|
if not self.deployed_service.service:
|
||||||
|
raise Exception('No service assigned to publication')
|
||||||
serviceInstance = self.deployed_service.service.getInstance()
|
serviceInstance = self.deployed_service.service.getInstance()
|
||||||
osManager = self.deployed_service.osmanager
|
osManager = self.deployed_service.osmanager
|
||||||
osManagerInstance = osManager.getInstance() if osManager else None
|
osManagerInstance = osManager.getInstance() if osManager else None
|
||||||
|
@ -57,7 +57,7 @@ class StatsCounters(models.Model):
|
|||||||
value = models.IntegerField(db_index=True, default=0)
|
value = models.IntegerField(db_index=True, default=0)
|
||||||
|
|
||||||
# "fake" declarations for type checking
|
# "fake" declarations for type checking
|
||||||
objects: 'models.manager.Manager[StatsCounters]'
|
# objects: 'models.manager.Manager[StatsCounters]'
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
"""
|
"""
|
||||||
@ -125,7 +125,7 @@ class StatsCounters(models.Model):
|
|||||||
|
|
||||||
floor = getSqlFnc('FLOOR')
|
floor = getSqlFnc('FLOOR')
|
||||||
if interval > 0:
|
if interval > 0:
|
||||||
q = q.extra(
|
q = q.extra( # nosec: SQL injection is not possible here, all values are integers
|
||||||
select={
|
select={
|
||||||
'group_by_stamp': f'{floor}(stamp / {interval}) * {interval}',
|
'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')
|
# fnc = getSqlFnc('MAX' if kwargs.get('use_max', False) else 'AVG')
|
||||||
|
|
||||||
query = (
|
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
|
+ stampValue
|
||||||
+ '*{}'.format(interval)
|
+ '*{}'.format(interval)
|
||||||
+ ' AS stamp, '
|
+ ' AS stamp, '
|
||||||
|
@ -60,7 +60,7 @@ class StatsEvents(models.Model):
|
|||||||
fld4 = models.CharField(max_length=128, default='')
|
fld4 = models.CharField(max_length=128, default='')
|
||||||
|
|
||||||
# "fake" declarations for type checking
|
# "fake" declarations for type checking
|
||||||
objects: 'models.manager.Manager[StatsEvents]'
|
# objects: 'models.manager.Manager[StatsEvents]'
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
"""
|
"""
|
||||||
|
@ -51,7 +51,7 @@ class Storage(models.Model):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# "fake" declarations for type checking
|
# "fake" declarations for type checking
|
||||||
objects: 'models.manager.Manager[Storage]'
|
# objects: 'models.manager.Manager[Storage]'
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
"""
|
"""
|
||||||
@ -62,5 +62,5 @@ class Storage(models.Model):
|
|||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
return '{} {} > str= {}, {}'.format(
|
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)
|
tag = models.CharField(max_length=32, db_index=True, unique=True)
|
||||||
|
|
||||||
# "fake" declarations for type checking
|
# "fake" declarations for type checking
|
||||||
objects: 'models.manager.Manager["Tag"]'
|
# objects: 'models.manager.Manager["Tag"]'
|
||||||
|
|
||||||
# Every single related class has a relation with this
|
# Every single related class has a relation with this
|
||||||
# Its inverse is "xxx_set" class
|
# Its inverse is "xxx_set" class
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
.. moduleauthor:: Adolfo Gómez, dkmaster at dkmon dot com
|
.. moduleauthor:: Adolfo Gómez, dkmaster at dkmon dot com
|
||||||
'''
|
'''
|
||||||
import datetime
|
import datetime
|
||||||
import pickle
|
import pickle # nosec: Tickets are generated by us, so we know they are safe
|
||||||
import logging
|
import logging
|
||||||
import typing
|
import typing
|
||||||
|
|
||||||
@ -71,7 +71,7 @@ class TicketStore(UUIDModel):
|
|||||||
) # Associated validator for this ticket
|
) # Associated validator for this ticket
|
||||||
|
|
||||||
# "fake" declarations for type checking
|
# "fake" declarations for type checking
|
||||||
objects: 'models.manager.Manager[TicketStore]'
|
# objects: 'models.manager.Manager[TicketStore]'
|
||||||
|
|
||||||
class InvalidTicket(Exception):
|
class InvalidTicket(Exception):
|
||||||
pass
|
pass
|
||||||
@ -151,11 +151,11 @@ class TicketStore(UUIDModel):
|
|||||||
data, typing.cast(str, owner).encode()
|
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 has validator, execute it
|
||||||
if t.validator:
|
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:
|
if validator(data) is False:
|
||||||
raise TicketStore.InvalidTicket('Validation failed')
|
raise TicketStore.InvalidTicket('Validation failed')
|
||||||
@ -194,7 +194,7 @@ class TicketStore(UUIDModel):
|
|||||||
) -> str:
|
) -> str:
|
||||||
owner = cryptoManager().randomString(length=8)
|
owner = cryptoManager().randomString(length=8)
|
||||||
data = {
|
data = {
|
||||||
'u': userService.user.uuid,
|
'u': userService.user.uuid if userService.user else '',
|
||||||
's': userService.uuid,
|
's': userService.uuid,
|
||||||
'h': host,
|
'h': host,
|
||||||
'p': port,
|
'p': port,
|
||||||
@ -259,7 +259,7 @@ class TicketStore(UUIDModel):
|
|||||||
TicketStore.objects.filter(stamp__lt=cleanSince).delete()
|
TicketStore.objects.filter(stamp__lt=cleanSince).delete()
|
||||||
|
|
||||||
def __str__(self) -> str:
|
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(
|
return 'Ticket id: {}, Owner: {}, Stamp: {}, Validity: {}, Data: {}'.format(
|
||||||
self.uuid,
|
self.uuid,
|
||||||
|
@ -71,7 +71,7 @@ class Transport(ManagedObjectModel, TaggingMixin):
|
|||||||
label = models.CharField(max_length=32, default='', db_index=True)
|
label = models.CharField(max_length=32, default='', db_index=True)
|
||||||
|
|
||||||
# "fake" declarations for type checking
|
# "fake" declarations for type checking
|
||||||
objects: 'models.manager.Manager[Transport]'
|
# objects: 'models.manager.Manager[Transport]'
|
||||||
|
|
||||||
deployedServices: 'models.manager.RelatedManager[ServicePool]'
|
deployedServices: 'models.manager.RelatedManager[ServicePool]'
|
||||||
networks: 'models.manager.RelatedManager[Network]'
|
networks: 'models.manager.RelatedManager[Network]'
|
||||||
|
@ -48,7 +48,7 @@ class TunnelToken(models.Model):
|
|||||||
stamp = models.DateTimeField() # Date creation or validation of this entry
|
stamp = models.DateTimeField() # Date creation or validation of this entry
|
||||||
|
|
||||||
# "fake" declarations for type checking
|
# "fake" declarations for type checking
|
||||||
objects: 'models.manager.Manager[TunnelToken]'
|
# objects: 'models.manager.Manager[TunnelToken]'
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
app_label = 'uds'
|
app_label = 'uds'
|
||||||
|
@ -50,7 +50,7 @@ class UniqueId(models.Model):
|
|||||||
stamp = models.IntegerField(db_index=True, default=0)
|
stamp = models.IntegerField(db_index=True, default=0)
|
||||||
|
|
||||||
# "fake" declarations for type checking
|
# "fake" declarations for type checking
|
||||||
objects: 'models.manager.Manager[UniqueId]'
|
# objects: 'models.manager.Manager[UniqueId]'
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
"""
|
"""
|
||||||
|
@ -57,7 +57,7 @@ class User(UUIDModel):
|
|||||||
This class represents a single user, associated with one authenticator
|
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'
|
Authenticator, on_delete=models.CASCADE, related_name='users'
|
||||||
)
|
)
|
||||||
name = models.CharField(max_length=128, db_index=True)
|
name = models.CharField(max_length=128, db_index=True)
|
||||||
@ -79,7 +79,7 @@ class User(UUIDModel):
|
|||||||
created = models.DateTimeField(default=getSqlDatetime, blank=True)
|
created = models.DateTimeField(default=getSqlDatetime, blank=True)
|
||||||
|
|
||||||
# "fake" declarations for type checking
|
# "fake" declarations for type checking
|
||||||
objects: 'models.manager.Manager["User"]'
|
# objects: 'models.manager.Manager["User"]'
|
||||||
groups: 'models.manager.RelatedManager[Group]'
|
groups: 'models.manager.RelatedManager[Group]'
|
||||||
userServices: 'models.manager.RelatedManager[UserService]'
|
userServices: 'models.manager.RelatedManager[UserService]'
|
||||||
permissions: 'models.manager.RelatedManager[Permissions]'
|
permissions: 'models.manager.RelatedManager[Permissions]'
|
||||||
|
@ -51,7 +51,7 @@ class UserPreference(models.Model):
|
|||||||
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='preferences')
|
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='preferences')
|
||||||
|
|
||||||
# "fake" declarations for type checking
|
# "fake" declarations for type checking
|
||||||
objects: 'models.manager.Manager[UserPreference]'
|
# objects: 'models.manager.Manager[UserPreference]'
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
app_label = 'uds'
|
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
|
# 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
|
# 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'
|
ServicePool, on_delete=models.CASCADE, related_name='userServices'
|
||||||
)
|
)
|
||||||
publication: 'models.ForeignKey["UserService", ServicePoolPublication]' = (
|
publication: 'models.ForeignKey[ServicePoolPublication | None]' = models.ForeignKey(
|
||||||
models.ForeignKey(
|
|
||||||
ServicePoolPublication,
|
ServicePoolPublication,
|
||||||
on_delete=models.CASCADE,
|
on_delete=models.CASCADE,
|
||||||
null=True,
|
null=True,
|
||||||
blank=True,
|
blank=True,
|
||||||
related_name='userServices',
|
related_name='userServices',
|
||||||
)
|
)
|
||||||
)
|
|
||||||
|
|
||||||
unique_id = models.CharField(
|
unique_id = models.CharField(
|
||||||
max_length=128, default='', db_index=True
|
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='')
|
src_ip = models.CharField(max_length=128, default='')
|
||||||
|
|
||||||
# "fake" declarations for type checking
|
# "fake" declarations for type checking
|
||||||
objects: 'models.manager.Manager["UserService"]'
|
# objects: 'models.manager.Manager["UserService"]'
|
||||||
properties: 'models.manager.RelatedManager[UserServiceProperty]'
|
properties: 'models.manager.RelatedManager[UserServiceProperty]'
|
||||||
sessions: 'models.manager.RelatedManager[UserServiceSession]'
|
sessions: 'models.manager.RelatedManager[UserServiceSession]'
|
||||||
accounting: 'AccountUsage'
|
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)
|
(see related classes uds.core.util.unique_name_generator and uds.core.util.unique_mac_generator)
|
||||||
"""
|
"""
|
||||||
return Environment.getEnvForTableElement(
|
return Environment.getEnvForTableElement(
|
||||||
self._meta.verbose_name,
|
self._meta.verbose_name, # type: ignore
|
||||||
self.id,
|
self.id,
|
||||||
{
|
{
|
||||||
'mac': unique.UniqueMacGenerator,
|
'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
|
# We get the service instance, publication instance and osmanager instance
|
||||||
servicePool = self.deployed_service
|
servicePool = self.deployed_service
|
||||||
|
if not servicePool.service:
|
||||||
|
raise Exception('Service not found')
|
||||||
serviceInstance = servicePool.service.getInstance()
|
serviceInstance = servicePool.service.getInstance()
|
||||||
if serviceInstance.needsManager is False or not servicePool.osmanager:
|
if serviceInstance.needsManager is False or not servicePool.osmanager:
|
||||||
osmanagerInstance = None
|
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.
|
:note: This method MUST be invoked by transport before using credentials passed to getJavascript.
|
||||||
"""
|
"""
|
||||||
servicePool = self.deployed_service
|
servicePool = self.deployed_service
|
||||||
|
if not servicePool.service:
|
||||||
|
raise Exception('Service not found')
|
||||||
serviceInstance = servicePool.service.getInstance()
|
serviceInstance = servicePool.service.getInstance()
|
||||||
if serviceInstance.needsManager is False or not servicePool.osmanager:
|
if serviceInstance.needsManager is False or not servicePool.osmanager:
|
||||||
return (username, password)
|
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
|
Returns True if this user service does not needs an publication, or if this deployed service publication is the current one
|
||||||
"""
|
"""
|
||||||
return (
|
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()
|
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
|
# "fake" declarations for type checking
|
||||||
objects: 'models.manager.Manager[UserServiceProperty]'
|
# objects: 'models.manager.Manager[UserServiceProperty]'
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
"""
|
"""
|
||||||
|
@ -58,12 +58,12 @@ class UserServiceSession(models.Model): # pylint: disable=too-many-public-metho
|
|||||||
start = models.DateTimeField(default=getSqlDatetime)
|
start = models.DateTimeField(default=getSqlDatetime)
|
||||||
end = models.DateTimeField(null=True, blank=True)
|
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'
|
UserService, on_delete=models.CASCADE, related_name='sessions'
|
||||||
)
|
)
|
||||||
|
|
||||||
# "fake" declarations for type checking
|
# "fake" declarations for type checking
|
||||||
objects: 'models.manager.Manager["UserServiceSession"]'
|
# objects: 'models.manager.Manager["UserServiceSession"]'
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
"""
|
"""
|
||||||
|
@ -55,14 +55,16 @@ class UnsavedForeignKey(models.ForeignKey):
|
|||||||
|
|
||||||
|
|
||||||
def getSqlDatetime() -> datetime:
|
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:
|
We support get database datetime for:
|
||||||
* mysql
|
* mysql
|
||||||
* sqlite
|
* sqlite
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
datetime: Current datetime of the database server
|
||||||
"""
|
"""
|
||||||
if connection.vendor in ('mysql', 'microsoft'):
|
if connection.vendor in ('mysql', 'microsoft'):
|
||||||
cursor = connection.cursor()
|
cursor = connection.cursor()
|
||||||
@ -72,7 +74,7 @@ def getSqlDatetime() -> datetime:
|
|||||||
else 'SELECT CURRENT_TIMESTAMP'
|
else 'SELECT CURRENT_TIMESTAMP'
|
||||||
)
|
)
|
||||||
cursor.execute(sentence)
|
cursor.execute(sentence)
|
||||||
date = cursor.fetchone()[0]
|
date = (cursor.fetchone() or [datetime.now()])[0]
|
||||||
else:
|
else:
|
||||||
date = (
|
date = (
|
||||||
datetime.now()
|
datetime.now()
|
||||||
@ -82,12 +84,19 @@ def getSqlDatetime() -> datetime:
|
|||||||
|
|
||||||
|
|
||||||
def getSqlDatetimeAsUnix() -> int:
|
def getSqlDatetimeAsUnix() -> int:
|
||||||
|
"""Returns the current date/time of the database server as unix timestamp
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
int: Unix timestamp
|
||||||
|
"""
|
||||||
return int(mktime(getSqlDatetime().timetuple()))
|
return int(mktime(getSqlDatetime().timetuple()))
|
||||||
|
|
||||||
|
|
||||||
def getSqlFnc(fncName: str) -> str:
|
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':
|
if connection.vendor == 'microsoft':
|
||||||
return {'CEIL': 'CEILING'}.get(fncName, fncName)
|
return {'CEIL': 'CEILING'}.get(fncName, fncName)
|
||||||
|
@ -45,7 +45,7 @@ class UUIDModel(models.Model):
|
|||||||
Base abstract model for models that require an uuid
|
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
|
# Automatic field from Model without a defined specific primary_key
|
||||||
# Just a fake declaration to allow type checking
|
# Just a fake declaration to allow type checking
|
||||||
@ -58,9 +58,7 @@ class UUIDModel(models.Model):
|
|||||||
return generateUuid()
|
return generateUuid()
|
||||||
|
|
||||||
# Override default save to add uuid
|
# Override default save to add uuid
|
||||||
def save(
|
def save(self, *args, **kwargs):
|
||||||
self, *args, **kwargs
|
|
||||||
):
|
|
||||||
if not self.uuid:
|
if not self.uuid:
|
||||||
self.uuid = self.genUuid()
|
self.uuid = self.genUuid()
|
||||||
elif self.uuid != self.uuid.lower():
|
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.ui import gui
|
||||||
from uds.core.util import validators
|
from uds.core.util import validators
|
||||||
from uds.core.util.unique_id_generator import UniqueIDGenerator
|
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.cache import Cache
|
||||||
from uds.core.util.decorators import allowCache
|
from uds.core.util.decorators import allowCache
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user