denvaar
denvaar

Reputation: 2214

Restrict access to view based on if request came from other view

I have a view that schedules a celery task to run when you visit the url:

class ScheduleTask(View):

    def get(self, request, *args, **kwargs):
        obj = get_object_or_404(ObjModel, uuid=kwargs.get('obj', None))
        context = {
            'site': RequestSite(request),
            'secure': request.is_secure()
        }    
        schedule_task.delay(obj.uuid, context) # schedule celery task
        return redirect(reverse(
            'users:user-list',
            kwargs={'user': obj.user.uuid}))

I would like to prevent anyone from just entering this view's url into the browser (Because it would schedule the task.) I would like to raise a permission denied exception if they do. I only want it to be accessible from this other view:

class CompletionView(TemplateView):
    def post(self, request, *args, **kwargs):

        ...

        if 'save_and_submit' in request.POST:
            # This is the only place I would like ScheduleTask to
            # run from.
            return redirect(reverse('users:schedule-task',
                kwargs={'obj': obj_uuid}))

How can I accomplish this? I feel like I should set some sort of token or cookie, but I'm not totally sure. Maybe the ScheduleTask view is not even necessary, and I should just put the code after if 'save_and_submit' in request.POST

Upvotes: 0

Views: 31

Answers (1)

Alireza
Alireza

Reputation: 4516

I guess you can totally achieve what you're doing using only one of those APIs, you can simply call your celery task from your CompletionView.

class CompletionView(TemplateView):
    def post(self, request, *args, **kwargs):

        ...

        if 'save_and_submit' in request.POST:
            # This is the only place I would like ScheduleTask to
            # run from.
             schedule_task.delay(obj.uuid, context)
             return redirect(reverse(
                'users:user-list',
               kwargs={'user': obj.user.uuid}))

In fact if you don't want this API exposed, just Don't expose it.

Upvotes: 1

Related Questions