statistics: lookup service also with their subclass reference_id (#68390)
This commit is contained in:
parent
1b51c4082f
commit
21249f84bb
|
@ -1633,7 +1633,12 @@ class StatisticsAPI(ViewSet):
|
|||
|
||||
if service and 'service' in allowed_filters:
|
||||
service_slug, ou_slug = service
|
||||
kwargs['service'] = get_object_or_404(Service, slug=service_slug, ou__slug=ou_slug)
|
||||
# look for the Service child and parent instances, see #68390 and #64853
|
||||
subclass_service_instance = get_object_or_404(
|
||||
Service.objects.select_subclasses(), slug=service_slug, ou__slug=ou_slug
|
||||
)
|
||||
service_instance = Service(pk=subclass_service_instance.pk)
|
||||
kwargs['service'] = [subclass_service_instance, service_instance]
|
||||
elif services_ou and 'services_ou' in allowed_filters:
|
||||
kwargs['services_ou'] = get_object_or_404(OrganizationalUnit, slug=services_ou)
|
||||
|
||||
|
|
|
@ -14,7 +14,9 @@
|
|||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import functools
|
||||
import logging
|
||||
import operator
|
||||
import re
|
||||
from collections import defaultdict
|
||||
from contextlib import contextmanager
|
||||
|
@ -196,7 +198,12 @@ class EventType(models.Model):
|
|||
class EventQuerySet(QuerySet):
|
||||
@classmethod
|
||||
def _which_references_query(cls, instance_or_model_class_or_queryset):
|
||||
if isinstance(instance_or_model_class_or_queryset, type) and issubclass(
|
||||
if isinstance(instance_or_model_class_or_queryset, list):
|
||||
return functools.reduce(
|
||||
operator.or_,
|
||||
(cls._which_references_query(ref) for ref in instance_or_model_class_or_queryset),
|
||||
)
|
||||
elif isinstance(instance_or_model_class_or_queryset, type) and issubclass(
|
||||
instance_or_model_class_or_queryset, models.Model
|
||||
):
|
||||
ct = ContentType.objects.get_for_model(instance_or_model_class_or_queryset)
|
||||
|
@ -221,6 +228,8 @@ class EventQuerySet(QuerySet):
|
|||
return q
|
||||
|
||||
def which_references(self, instance_or_queryset):
|
||||
if instance_or_queryset == []:
|
||||
return self.none()
|
||||
return self.filter(self._which_references_query(instance_or_queryset))
|
||||
|
||||
def from_cursor(self, cursor):
|
||||
|
|
|
@ -56,13 +56,21 @@ class EventTypeWithHow(EventTypeWithService):
|
|||
def get_method_statistics(
|
||||
cls, group_by_time, service=None, services_ou=None, users_ou=None, start=None, end=None
|
||||
):
|
||||
which_references = None
|
||||
if services_ou and not service:
|
||||
service = Service.objects.filter(ou=services_ou)
|
||||
services = Service.objects.filter(ou=services_ou)
|
||||
if not services:
|
||||
which_references = []
|
||||
else:
|
||||
# look for the Service child and parent instances, see #68390 and #64853
|
||||
which_references = [services, list(services.select_subclasses())]
|
||||
elif service:
|
||||
which_references = service
|
||||
|
||||
qs = cls.get_statistics(
|
||||
group_by_time=group_by_time,
|
||||
group_by_field='how',
|
||||
which_references=service,
|
||||
which_references=which_references,
|
||||
users_ou=users_ou,
|
||||
start=start,
|
||||
end=end,
|
||||
|
|
|
@ -39,6 +39,7 @@ from authentic2.apps.journal.models import Event, EventType
|
|||
from authentic2.custom_user.models import Profile, ProfileType
|
||||
from authentic2.models import APIClient, Attribute, AttributeValue, AuthorizedRole, PasswordReset, Service
|
||||
from authentic2.utils.misc import good_next_url
|
||||
from authentic2_idp_cas.models import Service as CASService
|
||||
from django_rbac.models import SEARCH_OP
|
||||
|
||||
from ..utils import assert_event, basic_authorization_header, get_link_from_mail, login
|
||||
|
@ -2631,7 +2632,10 @@ def test_api_statistics(app, admin, freezer, event_type_name, event_name):
|
|||
user = User.objects.create(username='john.doe', email='john.doe@example.com', ou=get_default_ou())
|
||||
ou = OU.objects.create(name='Second OU', slug='second')
|
||||
portal = Service.objects.create(name='portal', slug='portal', ou=ou)
|
||||
agendas = Service.objects.create(name='agendas', slug='agendas', ou=get_default_ou())
|
||||
agendas = CASService.objects.create(
|
||||
name='agendas', slug='agendas', ou=get_default_ou(), urls='https://agenda.example.net'
|
||||
)
|
||||
agenda_service = Service.objects.get(name='agendas')
|
||||
|
||||
method = {'how': 'password-on-https'}
|
||||
method2 = {'how': 'france-connect'}
|
||||
|
@ -2645,7 +2649,9 @@ def test_api_statistics(app, admin, freezer, event_type_name, event_name):
|
|||
)
|
||||
|
||||
freezer.move_to('2020-03-04 13:00')
|
||||
Event.objects.create(type=event_type, references=[agendas], data=dict(method, service_name=str(agendas)))
|
||||
Event.objects.create(
|
||||
type=event_type, references=[agenda_service], data=dict(method, service_name=str(agendas))
|
||||
)
|
||||
Event.objects.create(type=event_type, references=[portal], data=dict(method2, service_name=str(portal)))
|
||||
|
||||
resp = app.get('/api/statistics/%s/?time_interval=month' % event_name, headers=headers)
|
||||
|
|
Loading…
Reference in New Issue