Exemple #1
0
 def create(self, request, *args, **kwargs):
     model_name = self.queryset.model._meta.model_name
     app_name = self.queryset.model._meta.app_label
     perm = '{}.add_{}'.format(app_name, model_name)
     with transaction.atomic():
         response = super(PublicProjectViewSet,
                          self).create(request, *args, **kwargs)
         user = request.user
         obj = self.queryset.model.objects.get(pk=response.data['id'])
         project = get_project_for_object(Project, obj)
         # Delete the object if the user doesn't have the right permissions
         # to create this. The object may get created without checking for
         # permissions, since the viewset returns True if the user just has
         # the required role in any organisation. If the newly created
         # object is not a project, and the user doesn't have permissions to
         # create it, we delete the object.
         if obj != project and not (user.has_perm(
                 'rsr.view_project', project) and user.has_perm(perm, obj)):
             obj.delete()
     if obj.pk is None:
         raise exceptions.PermissionDenied
     elif project is not None:
         log_project_changes(request.user, project, obj, {}, 'added')
         delete_project_from_project_directory_cache(project.pk)
         project.schedule_iati_checks()
     return response
Exemple #2
0
 def update(self, request, *args, **kwargs):
     response = super(PublicProjectViewSet,
                      self).update(request, *args, **kwargs)
     obj = self.get_object()
     project = get_project_for_object(Project, obj)
     if project is not None:
         log_project_changes(request.user, project, obj, request.data,
                             'changed')
         delete_project_from_project_directory_cache(project.pk)
         project.schedule_iati_checks()
     return response
Exemple #3
0
 def destroy(self, request, *args, **kwargs):
     obj = self.get_object()
     project = get_project_for_object(Project, obj)
     try:
         response = super(PublicProjectViewSet,
                          self).destroy(request, *args, **kwargs)
     except ProtectedError:
         msg = _("{}s with updates cannot be deleted".format(
             self.queryset.model.__name__))
         return Response(msg, status=status.HTTP_405_METHOD_NOT_ALLOWED)
     if project is not None:
         log_project_changes(request.user, project, obj, {}, 'deleted')
         delete_project_from_project_directory_cache(project.pk)
         project.schedule_iati_checks()
     return response
Exemple #4
0
def project_roles(request, project_pk):
    user = request.user
    project = get_object_or_404(Project, pk=project_pk)

    if not (user.is_admin or user.is_superuser
            or is_reporting_org_admin(user, project)):
        raise PermissionDenied

    status = 200
    if request.method == "PATCH":
        roles = request.data.get("roles", [])
        auth_groups = {role["role"] for role in roles}
        unknown_groups = auth_groups - set(settings.REQUIRED_AUTH_GROUPS)
        if unknown_groups:
            response = {
                "error": "Unknown groups: {}".format(",".join(unknown_groups))
            }
            return Response(response, status=400)

        emails = {role["email"] for role in roles}
        unknown_users = emails - set(
            User.objects.filter(email__in=emails).values_list("email",
                                                              flat=True))
        if unknown_users:
            response = {
                "error": "Unknown users: {}".format(",".join(unknown_users))
            }
            return Response(response, status=400)

        groups = {name: Group.objects.get(name=name) for name in auth_groups}
        users = {email: User.objects.get(email=email) for email in emails}
        new_roles = {
            Role(email=role['email'], role=role['role'])
            for role in roles
        }
        existing_roles = {
            Role(*role)
            for role in project.projectrole_set.values_list(
                "user__email", "group__name").distinct()
        }
        use_project_roles = request.data.get('use_project_roles',
                                             False) or bool(new_roles)

        with transaction.atomic():
            # Set use_project_roles flag on the project
            if project.use_project_roles != use_project_roles:
                project.use_project_roles = use_project_roles
                project.save(update_fields=["use_project_roles"])

            # Delete roles
            for project_role in existing_roles - new_roles:
                deleted_roles = ProjectRole.objects.filter(
                    project=project,
                    user__email=project_role.email,
                    group__name=project_role.role,
                )
                deleted_role = deleted_roles.first()
                deleted_roles.delete()
                if deleted_role:
                    log_project_changes(request.user, project, deleted_role,
                                        {}, 'deleted')

            # Create roles
            created = [
                ProjectRole(
                    project=project,
                    user=users[project_role.email],
                    group=groups[project_role.role],
                ) for project_role in (new_roles - existing_roles)
            ]
            ProjectRole.objects.bulk_create(created)
            for role in created:
                log_project_changes(request.user, project, role, {}, 'added')

    if not project.use_project_roles:
        roles = []
        organisations = OrganisationBasicSerializer(
            project.partners.distinct(), many=True).data
    else:
        roles = ProjectRoleSerializer(project.projectrole_set.distinct(),
                                      many=True).data
        organisations = []

    response = {
        "use_project_roles": project.use_project_roles,
        "roles": roles,
        "organisations": organisations,
        "project": project_pk,
    }
    return Response(response, status=status)