diff --git a/server/src/uds/core/exceptions/auth.py b/server/src/uds/core/exceptions/auth.py index 695ee1f29..0cd61b012 100644 --- a/server/src/uds/core/exceptions/auth.py +++ b/server/src/uds/core/exceptions/auth.py @@ -67,3 +67,8 @@ class MFAError(AuthenticatorException): """ This exceptions indicates than an MFA error has ocurred """ + +class PasswordExpired(AuthenticatorException): + """ + This exceptions indicates that the password has expired + """ \ No newline at end of file diff --git a/server/src/uds/models/stats_events.py b/server/src/uds/models/stats_events.py index 43902a332..65b2b98c2 100644 --- a/server/src/uds/models/stats_events.py +++ b/server/src/uds/models/stats_events.py @@ -96,7 +96,7 @@ class StatsEvents(models.Model): if isinstance(owner_id, int): q = q.filter(owner_id=owner_id) - else: + elif owner_id is not None: q = q.filter(owner_id__in=owner_id) if isinstance(since, datetime.datetime): diff --git a/server/src/uds/reports/stats/pool_users_summary.py b/server/src/uds/reports/stats/pool_users_summary.py index 4a884d4b9..5cf7977dc 100644 --- a/server/src/uds/reports/stats/pool_users_summary.py +++ b/server/src/uds/reports/stats/pool_users_summary.py @@ -37,6 +37,7 @@ import typing from django.utils.translation import gettext from django.utils.translation import gettext_lazy as _ +from uds.core import ui from uds.core.managers.stats import StatsManager from uds.core.ui import gui from uds.core.util.stats import events @@ -55,7 +56,13 @@ class UsageSummaryByUsersPool(StatsReport): # UserInterface will ignore all fields that are not from FINAL class # so we must redeclare them here - pool = StatsReport.pool + pool = ui.gui.ChoiceField( + order=1, + label=_('Pool'), + tooltip=_('Pool for report'), + required=True, + ) + start_date = StatsReport.start_date end_date = StatsReport.end_date diff --git a/server/src/uds/reports/stats/pools_performance.py b/server/src/uds/reports/stats/pools_performance.py index 4790f9a99..c350dc030 100644 --- a/server/src/uds/reports/stats/pools_performance.py +++ b/server/src/uds/reports/stats/pools_performance.py @@ -72,12 +72,18 @@ class PoolPerformanceReport(StatsReport): sampling_points = StatsReport.sampling_points def init_gui(self) -> None: - logger.debug('Initializing gui') - vals = [gui.choice_item(v.uuid, v.name) for v in ServicePool.objects.all().order_by('name')] + vals = [gui.choice_item('0-0-0-0', gettext('ALL POOLS'))] + [ + gui.choice_item(v.uuid, v.name) for v in ServicePool.objects.all().order_by('name') if v.uuid + ] self.pools.set_choices(vals) def list_pools(self) -> collections.abc.Iterable[tuple[int, str]]: - for p in ServicePool.objects.filter(uuid__in=self.pools.value): + if '0-0-0-0' in self.pools.value: + pools = ServicePool.objects.all() + else: + pools = ServicePool.objects.filter(uuid__in=self.pools.value) + + for p in pools: yield (p.id, p.name) def get_range_data( @@ -134,7 +140,7 @@ class PoolPerformanceReport(StatsReport): for v in q: accesses += v['cnt'] - data_users.append((key, len(q))) # @UndefinedVariable + data_users.append((key, len(q))) # Store number of users data_accesses.append((key, accesses)) report_data.append( { @@ -167,10 +173,13 @@ class PoolPerformanceReport(StatsReport): # surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, WIDTH, HEIGHT) # @UndefinedVariable # logger.debug('PoolsData: %s', poolsData) - def _tick_fnc1(l: int) -> str: - return filters.date(datetime.datetime.fromtimestamp(l), x_label_format) if int(l) >= 0 else '' - x = [v[0] for v in pools_data[0]['dataUsers']] + + # l is the index of the x value + # returns the date in the x value to be used as label on the x axis + def _tick_fnc1(l: int) -> str: + return filters.date(datetime.datetime.fromtimestamp(x[l]), x_label_format) if int(x[l]) >= 0 else '' + data = { 'title': _('Distinct Users'), 'x': x, @@ -181,11 +190,12 @@ class PoolPerformanceReport(StatsReport): } graphs.bar_chart(SIZE, data, graph1) - - def _tick_fnc2(l: int) -> str: - return filters.date(datetime.datetime.fromtimestamp(l), x_label_format) if int(l) >= 0 else '' x = [v[0] for v in pools_data[0]['dataAccesses']] + + def _tick_fnc2(l: int) -> str: + return filters.date(datetime.datetime.fromtimestamp(x[l]), x_label_format) if int(x[l]) >= 0 else '' + data = { 'title': _('Accesses'), 'x': x,