예제 #1
0
def save_user_session_membership(sender, **kwargs):
    session = kwargs.get('instance', None)
    if pkg_resources.get_distribution('channels').version >= '2':
        # If you get into this code block, it means we upgraded channels, but
        # didn't make the settings.SESSIONS_PER_USER feature work
        raise RuntimeError(
            'save_user_session_membership must be updated for channels>=2: '
            'http://channels.readthedocs.io/en/latest/one-to-two.html#requirements'
        )
    if 'runworker' in sys.argv:
        # don't track user session membership for websocket per-channel sessions
        return
    if not session:
        return
    user_id = session.get_decoded().get(SESSION_KEY, None)
    if not user_id:
        return
    if UserSessionMembership.objects.filter(user=user_id,
                                            session=session).exists():
        return
    # check if user_id from session has an id match in User before saving
    if User.objects.filter(id=int(user_id)).exists():
        UserSessionMembership(user_id=user_id,
                              session=session,
                              created=timezone.now()).save()
        expired = UserSessionMembership.get_memberships_over_limit(user_id)
        for membership in expired:
            Session.objects.filter(
                session_key__in=[membership.session_id]).delete()
            membership.delete()
        if len(expired):
            consumers.emit_channel_notification(
                'control-limit_reached_{}'.format(user_id),
                dict(group_name='control', reason='limit_reached'))
예제 #2
0
def test_session_overlimit(admin, post):
    AlwaysPassBackend.user = admin
    with override_settings(
            AUTHENTICATION_BACKENDS=(AlwaysPassBackend.get_backend_path(), ),
            SESSION_COOKIE_NAME='session_id',
            SESSIONS_PER_USER=3):
        sessions_to_deprecate = []
        for _ in range(5):
            response = post('/api/login/',
                            data={
                                'username': admin.username,
                                'password': admin.password,
                                'next': '/api/'
                            },
                            expect=302,
                            middleware=SessionMiddleware(),
                            format='multipart')
            session_key = re.findall(
                r'session_id=[a-zA-z0-9]+',
                str(response.cookies['session_id']))[0][len('session_id='):]
            sessions_to_deprecate.append(
                Session.objects.get(session_key=session_key))
        sessions_to_deprecate[0].expire_date = tz_now() - timedelta(
            seconds=1000)
        sessions_to_deprecate[0].save()
        sessions_overlimit = [
            x.session
            for x in UserSessionMembership.get_memberships_over_limit(admin)
        ]
        assert sessions_to_deprecate[0] not in sessions_overlimit
        assert sessions_to_deprecate[1] in sessions_overlimit
        for session in sessions_to_deprecate[2:]:
            assert session not in sessions_overlimit
예제 #3
0
def save_user_session_membership(sender, **kwargs):
    session = kwargs.get('instance', None)
    if not session:
        return
    user_id = session.get_decoded().get(SESSION_KEY, None)
    if not user_id:
        return
    if UserSessionMembership.objects.filter(user=user_id, session=session).exists():
        return
    # check if user_id from session has an id match in User before saving
    if User.objects.filter(id=int(user_id)).exists():
        UserSessionMembership(user_id=user_id, session=session, created=timezone.now()).save()
        expired = UserSessionMembership.get_memberships_over_limit(user_id)
        for membership in expired:
            Session.objects.filter(session_key__in=[membership.session_id]).delete()
            membership.delete()
        if len(expired):
            consumers.emit_channel_notification('control-limit_reached_{}'.format(user_id), dict(group_name='control', reason='limit_reached'))