diff --git a/src/providers/views.py b/src/providers/views.py index fa28fc7dd51113773d0640e0b1691e6f5839ad7e..9740136b06524eec8de1ddac07ea748ccfce4b55 100644 --- a/src/providers/views.py +++ b/src/providers/views.py @@ -363,19 +363,86 @@ class GetProviderData(APIView): collection = lrs_db["statements"] + active_verbs = list(map(lambda x : x["verb"], list(AnalyticsTokenVerb.objects.filter(analytics_token_id = analytics_token).values()))) + providers = [] + # check for anonymized collection + for analytics_token_verb in AnalyticsTokenVerb.objects.filter(analytics_token_id = analytics_token): + if analytics_token_verb.provider not in providers: + providers.append(analytics_token_verb.provider) + + for provider in providers: + # get verbs that can be collected anonymously and their minimum count + # and get those, whose minimum count is reached + anon_verbs = [] + try: + latest_schema = ProviderSchema.objects.get( + provider=provider, superseded_by__isnull=True + ) + except ObjectDoesNotExist: + return JsonResponse( + { + "message": "No consent provider schema found.", + "provider": provider.name, + }, + safe=False, + status=status.HTTP_500_INTERNAL_SERVER_ERROR, + ) + + + for verb in [verb for verblist in [group["verbs"] for group in latest_schema.groups] for verb in verblist]: + if verb["id"] in active_verbs and verb.get("allowAnonymizedCollection", False): + min_count = verb.get("allowAnonymizedCollectionMinCount", settings.ANONYMIZATION_DEFAULT_MINIMUM_COUNT) + current_count = collection.distinct("actor.mbox", { + "$and": [ + {"verb.id": {"$eq": verb["id"]}}, + {"actor.mbox": {"$exists": True}}, + {"actor.mbox": {"$regex": "^" + settings.ANONYMIZATION_HASH_PREFIX}} + ] + }).length + if current_count >= min_count: + anon_verbs.append(verb) + + # selects for anonymized statements of which there are enough different actors + # or explicitly non-anonymized statements + anon_query = {"$or": [ + # current statement is anonymized and + # enough anonymized statements for this verb exist + {"$and": [ + {"actor.mbox": {"$exists": True}}, + {"actor.mbox": {"$regex": "^" + settings.ANONYMIZATION_HASH_PREFIX}}, + {"verb.id": {"$in": anon_verbs}}, + ]}, + # current statement is not anonymized + {"$or": [ + {"actor.mbox": {"$exists": False}}, + {"$and": [ + {"actor.mbox": {"$exists": False}}, + {"actor.mbox": {"$regex": "^mailto"}}, + ]} + ]} + ]} + query = ( { "$and": [ + {"actor.tan": {"$exists": False}}, # important! flagged statements filtered out here {"_id": {"$gt": ObjectId(last_object_id)}}, - {"verb.id": {"$in": analytics_token.active_verbs}}, + {"verb.id": {"$in": active_verbs}}, + anon_query # for anonymized statements ] } if last_object_id - else {"verb.id": {"$in": analytics_token.active_verbs}} + else { + "$and": [ + {"actor.tan": {"$exists": False}}, + {"verb.id": {"$in": active_verbs}}, + anon_query # for anonymized statements + ] + } ) cursor = collection.find(query).limit(page_size) data = { - "verbs": list(set(analytics_token.active_verbs)), + "verbs": list(set(active_verbs)), "statements": list(cursor), "page_size": page_size, } @@ -414,7 +481,7 @@ class StoreAnalyticsEngineResult(APIView): collection.insert_one( { "created_at": datetime.now(), - "provider_id": analytics_token.provider.id, + #"provider_id": analytics_token.provider.id, "name": analytics_token.name, "analytics_token": token, "result": request.data.get("result"), @@ -570,9 +637,19 @@ class GetAnalyticsEngineResults(APIView): try: analytics_token = AnalyticsToken.objects.get(key=token) - accessible_provider_ids = [ - token.id for token in analytics_token.can_access.all() - ] + [analytics_token.provider.id] + provider_ids = [] + #providers from this token + for analytics_token_verb in AnalyticsTokenVerb.objects.filter(analytics_token_id = analytics_token): + if analytics_token_verb.provider.id not in provider_ids: + provider_ids.append(analytics_token_verb.provider.id) + + #providers from can_acccess tokens + for token in analytics_token.can_access.all(): + for analytics_token_verb in AnalyticsTokenVerb.objects.filter(analytics_token_id = token.id): + if analytics_token_verb.provider.id not in provider_ids: + provider_ids.append(analytics_token_verb.provider.id) + + accessible_provider_ids = provider_ids collection = lrs_db["results"] query = {"provider_id": {"$in": accessible_provider_ids}} @@ -616,7 +693,7 @@ class CreateVisualizationToken(APIView): application_token = serializer.validated_data.get("application_token") if application_token is None or application_token == "": application_token = request.headers.get("Authorization", "").split("Basic ")[-1] - + provider = ProviderAuthorization.objects.filter(key=application_token).first() if provider is None: print("Invald access token: " + application_token)