Example #1
0
    def update(self, request, *args, **kwargs):
        """
        Update object
        """
        try:
            self.require_data(request)

            org_key = get_org_key_from_request(request)
            user_key = get_user_key_from_request(request)

            with reversion.create_revision():
                if request.user and request.user.is_authenticated:
                    reversion.set_user(request.user)
                if org_key:
                    reversion.set_comment(f"API-key: {org_key.prefix}")
                if user_key:
                    reversion.set_comment(f"API-key: {user_key.prefix}")

                r = super().update(request, *args, **kwargs)
                if "_grainy" in r.data:
                    del r.data["_grainy"]
                return r

        except PermissionDenied as inst:
            return Response(status=status.HTTP_403_FORBIDDEN)
        except TypeError as inst:
            return Response(status=status.HTTP_400_BAD_REQUEST,
                            data={"detail": str(inst)})
        except ValueError as inst:
            return Response(status=status.HTTP_400_BAD_REQUEST,
                            data={"detail": str(inst)})
        finally:
            self.get_serializer().finalize_update(request)
Example #2
0
    def allow_request(self, request, view):

        # If the parameter specified in cls.filter_name
        # is set in request parameters, set the scope
        # accordingly

        if self.filter_name in request.query_params:
            self.scope = f"filter_{self.filter_name}"
        else:
            return True

        # user either comes from request.user, or user api key
        #
        # it will be None if an organization key is set or request
        # is anonymous
        self.user = user = get_user_from_request(request)
        self.org_key = org_key = get_org_key_from_request(request)

        # Neither user nor organzation key could be identified
        # Get user directly from request, which will likely return
        # an anonymous user instance

        if not org_key and not user:
            self.user = user = request.user

        # require authenticated user to use this filter ?

        require_auth = (getattr(
            settings, f"API_{self.filter_name.upper()}_FILTER_REQUIRE_AUTH",
            False) and user)

        # require verified user to use this filter ?

        require_verified = (getattr(
            settings,
            f"API_{self.filter_name.upper()}_FILTER_REQUIRE_VERIFIED",
            False,
        ) and user)

        if (require_auth or require_verified) and not user.is_authenticated:
            raise PermissionDenied(
                f"Please authenticate to use the `{self.filter_name}` filter")

        if require_verified and not user.is_verified_user:
            raise PermissionDenied(
                f"Please verify your account to use the `{self.filter_name}` filter"
            )

        self.rate = self.get_rate()
        self.num_requests, self.duration = self.parse_rate(self.rate)

        return super().allow_request(request, view)
Example #3
0
def ticket_queue_asnauto_skipvq(request, org, net, rir_data):
    """
    Queue deskro ticket creation for asn automation action: skip vq.
    """

    if isinstance(net, dict):
        net_name = net.get("name")
    else:
        net_name = net.name

    if isinstance(org, dict):
        org_name = org.get("name")
    else:
        org_name = org.name

    user = get_user_from_request(request)
    if user:
        ticket_queue(
            f"[ASNAUTO] Network '{net_name}' approved for existing Org '{org_name}'",
            loader.get_template(
                "email/notify-pdb-admin-asnauto-skipvq.txt").render({
                    "user":
                    user,
                    "org":
                    org,
                    "net":
                    net,
                    "rir_data":
                    rir_data
                }),
            user,
        )
        return

    org_key = get_org_key_from_request(request)
    if org_key:
        ticket_queue_email_only(
            f"[ASNAUTO] Network '{net_name}' approved for existing Org '{org_name}'",
            loader.get_template(
                "email/notify-pdb-admin-asnauto-skipvq-org-key.txt").render({
                    "org_key":
                    org_key,
                    "org":
                    org,
                    "net":
                    net,
                    "rir_data":
                    rir_data
                }),
            org_key.email,
        )
Example #4
0
def ticket_queue_rdap_error(request, asn, error):
    if isinstance(error, RdapNotFoundError):
        return
    error_message = f"{error}"

    if re.match("(.+) returned 400", error_message):
        return

    user = get_user_from_request(request)

    if user:
        subject = f"[RDAP_ERR] {user.username} - AS{asn}"
        ticket_queue(
            subject,
            loader.get_template(
                "email/notify-pdb-admin-rdap-error.txt").render({
                    "user":
                    user,
                    "asn":
                    asn,
                    "error_details":
                    error_message
                }),
            user,
        )
        return

    org_key = get_org_key_from_request(request)
    if org_key:
        subject = f"[RDAP_ERR] {org_key.email} - AS{asn}"
        ticket_queue_email_only(
            subject,
            loader.get_template(
                "email/notify-pdb-admin-rdap-error-org-key.txt").render({
                    "org_key":
                    org_key,
                    "asn":
                    asn,
                    "error_details":
                    error_message
                }),
            org_key.email,
        )
Example #5
0
    def destroy(self, request, pk, format=None):
        """
        Delete object
        """
        try:
            try:
                obj = self.model.objects.get(pk=pk)
            except ValueError:
                return Response(status=status.HTTP_400_BAD_REQUEST,
                                data={"extra": "Invalid id"})
            except self.model.DoesNotExist:
                return Response(status=status.HTTP_204_NO_CONTENT)

            user_key = get_user_key_from_request(request)
            org_key = get_org_key_from_request(request)
            if check_permissions_from_request(request, obj, "d"):
                with reversion.create_revision():
                    if request.user and request.user.is_authenticated:
                        reversion.set_user(request.user)
                    if org_key:
                        reversion.set_comment(f"API-key: {org_key.prefix}")
                    if user_key:
                        reversion.set_comment(f"API-key: {user_key.prefix}")
                    obj.delete()
                return Response(status=status.HTTP_204_NO_CONTENT)
            else:
                return Response(status=status.HTTP_403_FORBIDDEN)
        except ProtectedAction as exc:
            exc_message = f"{exc} - " + _(
                "Please contact {} to help with the deletion of this object"
            ).format(settings.DEFAULT_FROM_EMAIL)

            ticket_queue_deletion_prevented(request, exc.protected_object)

            return Response(status=status.HTTP_403_FORBIDDEN,
                            data={"detail": exc_message})
        finally:
            self.get_serializer().finalize_delete(request)
Example #6
0
def ticket_queue_deletion_prevented(request, instance):
    """
    Queue deskpro ticket to notify the prevented
    deletion of an object #696.
    """

    subject = (f"[PROTECTED] Deletion prevented: "
               f"{instance.HandleRef.tag}-{instance.id} "
               f"{instance}")

    # we don't want to spam DeskPRO with tickets when a user
    # repeatedly clicks the delete button for an object
    #
    # so we check if a ticket has recently been sent for it
    # and opt out if it falls with in the spam protection
    # period defined in settings

    period = settings.PROTECTED_OBJECT_NOTIFICATION_PERIOD
    now = datetime.datetime.now(datetime.timezone.utc)
    max_age = now - datetime.timedelta(hours=period)
    ticket = DeskProTicket.objects.filter(
        subject=f"{settings.EMAIL_SUBJECT_PREFIX}{subject}")
    ticket = ticket.filter(created__gt=max_age)

    # recent ticket for object exists, bail

    if ticket.exists():
        return

    model_name = instance.__class__.__name__.lower()

    # Create ticket if a request was made by user or UserAPIKey
    user = get_user_from_request(request)
    if user:
        ticket_queue(
            subject,
            loader.get_template(
                "email/notify-pdb-admin-deletion-prevented.txt").render({
                    "user":
                    user,
                    "instance":
                    instance,
                    "admin_url":
                    settings.BASE_URL + django.urls.reverse(
                        f"admin:peeringdb_server_{model_name}_change",
                        args=(instance.id, ),
                    ),
                }),
            user,
        )
        return

    # Create ticket if request was made by OrgAPIKey
    org_key = get_org_key_from_request(request)
    if org_key:
        ticket_queue_email_only(
            subject,
            loader.get_template(
                "email/notify-pdb-admin-deletion-prevented-org-key.txt").
            render({
                "org_key":
                org_key,
                "instance":
                instance,
                "admin_url":
                settings.BASE_URL + django.urls.reverse(
                    f"admin:peeringdb_server_{model_name}_change",
                    args=(instance.id, ),
                ),
            }),
            org_key.email,
        )