fanout / django-eventstream

Server-Sent Events for Django
MIT License
650 stars 85 forks source link

Skipping delivery to certain users on a given channel #28

Open YashAgarwal opened 5 years ago

YashAgarwal commented 5 years ago

I found a skip_user_ids argument in

def send_event(channel, event_type, data, skip_user_ids=[]):
    from .event import Event

which gets passed on to this

def publish_event(channel, event_type, data, pub_id, pub_prev_id,
        skip_user_ids=[]):
    from django_grip import publish

    content_filters = []
    if pub_id:
        event_id = '%I'
        content_filters.append('build-id')
    else:
        event_id = None
    content = sse_encode_event(event_type, data, event_id=event_id, escape=bool(pub_id))
    meta = {}
    if skip_user_ids:
        meta['skip_users'] = ','.join(skip_user_ids)
    publish(
        'events-%s' % quote(channel),
        HttpStreamFormat(content, content_filters=content_filters),
        id=pub_id,
        prev_id=pub_prev_id,
        meta=meta)

To be saved in meta and never to be used again, Is this feature planned in the near future? If not, I would like to spend some time adding this feature. Can anyone point me in the right direction?

jkarneges commented 5 years ago

The meta dict is passed along to the publish() call at the end there, and it should do the right thing already. :) If it doesn't work for you, let me know.

YashAgarwal commented 5 years ago

It doesn't, I guess it doesn't identify my authentication method, How do I get it to work with JWT authentication?

 curl -X GET \
  http://127.0.0.1:8000/v1/chat/user/5/public-room/ \
  -H 'Content-Type: application/json' \
  -H 'Session-Token: User_5_sR0GankxzRN9W9fCicro4fYQyDoiR6xj' \
  -H 'cache-control: no-cache'

So I have a Session-Token in the header and a user_id in the url for authentication.

jkarneges commented 5 years ago

JWT auth should be fine as long as the user is properly Django authed as a result.

Are you using an ASGI deployment with clients connecting directly to it? Or are you using a GRIP proxy in front? I just realized skip_user_ids only works with GRIP at the moment. If you need it for ASGI, it shouldn't be too hard of a task.

Note that skip_user_ids is primarily meant to cover the race condition between the time of revoking a user's permission from a channel and the time that change is actually being applied to the user's connections. The normal way to restrict access to events is to configure a channel manager and implement can_read_channel as described here.

frnhr commented 5 years ago

While this is probably not a problem right now, it would be good to replace that default [] with something that is not mutable, like () or None. Ref: "Python default mutable arguments" issue, e.g: https://docs.python-guide.org/writing/gotchas/

jkarneges commented 5 years ago

Thanks for pointing this out, @frnhr. Fixed in 50c3db72125e1675ad2b5d830723ac6bc8e68d4f