channels-api icon indicating copy to clipboard operation
channels-api copied to clipboard

Permissions: has_permission() takes 3 positional arguments but 4 were given

Open CoreyTrombley opened this issue 7 years ago • 7 comments

I am getting this error after I updated the package

2017-06-01 02:16:22,002 - ERROR - worker - Error processing message with consumer faceoff_api.routing.APIDemultiplexer:
Traceback (most recent call last):
  File "/Users/coreytrombley/.envs/faceoff_venv/lib/python3.5/site-packages/channels/worker.py", line 119, in run
    consumer(message, **kwargs)
  File "/Users/coreytrombley/.envs/faceoff_venv/lib/python3.5/site-packages/channels/generic/base.py", line 32, in __init__
    self.dispatch(message, **kwargs)
  File "/Users/coreytrombley/.envs/faceoff_venv/lib/python3.5/site-packages/channels/generic/base.py", line 70, in dispatch
    return self.get_handler(message, **kwargs)(message, **kwargs)
  File "/Users/coreytrombley/.envs/faceoff_venv/lib/python3.5/site-packages/channels/generic/websockets.py", line 154, in raw_receive
    self.receive(self.decode_json(message['text']), **kwargs)
  File "/Users/coreytrombley/.envs/faceoff_venv/lib/python3.5/site-packages/channels/generic/websockets.py", line 266, in receive
    consumer(self.message, **kwargs)
  File "/Users/coreytrombley/.envs/faceoff_venv/lib/python3.5/site-packages/channels/binding/base.py", line 240, in consumer
    handler(message, **kwargs)
  File "/Users/coreytrombley/.envs/faceoff_venv/lib/python3.5/site-packages/channels/sessions.py", line 78, in inner
    return func(*args, **kwargs)
  File "/Users/coreytrombley/.envs/faceoff_venv/lib/python3.5/site-packages/channels/auth.py", line 42, in inner
    return func(message, *args, **kwargs)
  File "/Users/coreytrombley/.envs/faceoff_venv/lib/python3.5/site-packages/channels/binding/websockets.py", line 90, in trigger_inbound
    super(WebsocketBinding, cls).trigger_inbound(message, **kwargs)
  File "/Users/coreytrombley/.envs/faceoff_venv/lib/python3.5/site-packages/channels/binding/base.py", line 222, in trigger_inbound
    self.run_action(self.action, self.pk, self.data)
  File "/Users/coreytrombley/.envs/faceoff_venv/lib/python3.5/site-packages/channels_api/bindings.py", line 145, in run_action
    if not self.has_permission(self.user, action, pk):
  File "/Users/coreytrombley/.envs/faceoff_venv/lib/python3.5/site-packages/channels_api/bindings.py", line 111, in has_permission
    if not cls().has_permission(user, action, pk):
TypeError: has_permission() takes 3 positional arguments but 4 were given

CoreyTrombley avatar Jun 01 '17 02:06 CoreyTrombley

Hi there, what version of channels are you using? Can you share a form of your binding class? Thanks

linuxlewis avatar Jun 01 '17 02:06 linuxlewis

@linuxlewis First off thank you so much for this package! Second Thanks for the quick reply.

Channels version

 (faceoff_venv) ~/projects/faceoff/faceoff_api   channels_permissions ●  pip show channels
Name: channels
Version: 1.1.3
Summary: Brings event-driven capabilities to Django with a channel system. Django 1.8 and up only.
Home-page: http://github.com/django/channels
Author: Django Software Foundation
Author-email: [email protected]
License: BSD
Location: /Users/coreytrombley/.envs/faceoff_venv/lib/python3.5/site-packages
Requires: asgiref, Django, daphne

Binding Class

Here is my bindings for my "Friendship" models

from channels_api.bindings import ResourceBinding
from channels_api.permissions import IsAuthenticated

from faceoff_api.permissions import CUserObjectPermission
from friendship.models import FriendshipRequest, Friend
from friendships.serializers import FriendRequestSerializer

class FriendBinding(ResourceBinding):
    model = Friend
    stream = 'friends'
    serializer_class = FriendRequestSerializer
    queryset = Friend.objects.all()

class FriendshipRequestBinding(ResourceBinding):
    model = FriendshipRequest
    stream = 'friendship-request'
    serializer_class = FriendRequestSerializer
    queryset = FriendshipRequest.objects.all()

Routing.py

from channels.generic.websockets import WebsocketDemultiplexer
from channels.routing import route_class
from channels.staticfiles import StaticFilesConsumer

from games.bindings import GameBinding
from notifications.bindings import NotificationBinding
from friendships.bindings import FriendBinding, FriendshipRequestBinding
from teams.bindings import TeamBinding, TeamRequestBinding

class APIDemultiplexer(WebsocketDemultiplexer):

    consumers = {
        'http.request': StaticFilesConsumer,
        'games': GameBinding.consumer,
        'notifications': NotificationBinding.consumer,
        'friends': FriendBinding.consumer,
        'friendship-request': FriendshipRequestBinding.consumer,
        'teams': TeamBinding.consumer,
        'team-requests': TeamRequestBinding.consumer,
    }

channel_routing = [
    route_class(APIDemultiplexer)
]

CoreyTrombley avatar Jun 01 '17 04:06 CoreyTrombley

@linuxlewis I think I found the problem. I didn't have the channels_api default settings in my projects settings file.

CoreyTrombley avatar Jun 01 '17 18:06 CoreyTrombley

I would like to get your thoughts on how I could limit the responses based on the authed user. When I am sub'ed to friendship requests I get all created requests not just the ones pertaining to the authed user.

CoreyTrombley avatar Jun 01 '17 18:06 CoreyTrombley

Can you post your settings or better yet can you reproduce in a test case?

linuxlewis avatar Jun 02 '17 03:06 linuxlewis

To filter the create messages you will need to put the users in a group that is scoped to their user instead of the resource. This can be accomplished by implementing the method _group_name(self, action, id=None) on your binding class to return a string unique to that resource and user. Here's a rough idea

from channels_api.bindings import ResourceBinding

class MyBinding(ResourceBinding):

     def _group_name(self, action, id=None):
           if action == "create":
                  return "{}-{}-{}".format(self.model_label, action, user_id)

linuxlewis avatar Jun 02 '17 03:06 linuxlewis

Hi, I am getting the same error: has_permission() takes 3 positional arguments but 4 were given

I think I have configured everything properly and I am unsure how to fix this error

tonylindsay-h9 avatar Aug 28 '19 10:08 tonylindsay-h9