Skip to content

Commit

Permalink
Merge pull request #17 from opengisch/team_member_filtering
Browse files Browse the repository at this point in the history
Team member filtering
  • Loading branch information
suricactus committed May 10, 2021
2 parents 80f51ba + 0716a28 commit 1186721
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 8 deletions.
8 changes: 8 additions & 0 deletions docker-app/qfieldcloud/core/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,14 @@ class Meta:
limit_choices_to=models.Q(user_type=User.TYPE_USER),
)

def clean(self) -> None:
if not self.team.team_organization.members.filter(member=self.member):
raise ValidationError(
_("Cannot add team member that is not an organization member.")
)

return super().clean()

def __str__(self):
return self.team.username + ": " + self.member.username

Expand Down
26 changes: 20 additions & 6 deletions docker-app/qfieldcloud/core/querysets_utils.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import warnings
from functools import reduce
from operator import and_, or_

from django.db.models import Q
from django.db.models.manager import BaseManager
Expand Down Expand Up @@ -69,6 +71,7 @@ def get_users(
organization: Organization = None,
exclude_organizations: bool = False,
exclude_teams: bool = False,
invert: bool = False,
) -> BaseManager:
assert (
project is None or organization is None
Expand All @@ -87,21 +90,32 @@ def get_users(
if exclude_teams:
users = users.exclude(user_type=User.TYPE_TEAM)

# one day conditions can be more than just pk check, please keep it for now
conditions = []
# exclude the already existing collaborators and the project owner
if project:
collaborator_ids = ProjectCollaborator.objects.filter(
project=project
).values_list("collaborator", flat=True)
users = users.exclude(pk__in=collaborator_ids)
users = users.exclude(pk=project.owner.pk)
user_ids = [*collaborator_ids, project.owner.pk]
conditions = [Q(pk__in=user_ids)]

# exclude the already existing members, the organization owner and the organization itself from the returned users
if organization:
elif organization:
member_ids = OrganizationMember.objects.filter(
organization=organization
).values_list("member", flat=True)
users = users.exclude(pk__in=member_ids)
users = users.exclude(pk=organization.organization_owner.pk)
users = users.exclude(pk=organization.user_ptr.pk)
user_ids = [
*member_ids,
organization.organization_owner.pk,
organization.user_ptr.pk,
]
conditions = [Q(pk__in=user_ids)]

if conditions:
if invert:
users = users.filter(reduce(and_, [c for c in conditions]))
else:
users = users.exclude(reduce(or_, [c for c in conditions]))

return users.order_by("-username")
6 changes: 4 additions & 2 deletions docker-app/qfieldcloud/core/views/users_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,16 @@ def get_queryset(self):
# TODO : are these GET paremters documented somewhere ? Shouldn't we use something
# like django_filters.rest_framework.DjangoFilterBackend so they get auto-documented
# in DRF's views, or is that supposedly done with swagger ?
exclude_organizations = bool(int(params.get("exclude_organizations", 0)))
exclude_teams = bool(int(params.get("exclude_teams", 0)))
exclude_organizations = bool(int(params.get("exclude_organizations") or 0))
exclude_teams = bool(int(params.get("exclude_teams") or 0))
invert = bool(int(params.get("invert") or 0))
return querysets_utils.get_users(
query,
project=project,
organization=organization,
exclude_organizations=exclude_organizations,
exclude_teams=exclude_teams,
invert=invert,
)


Expand Down

0 comments on commit 1186721

Please sign in to comment.