示例#1
0
    def decrypt(self, eid):
        """
        Return the SessionStore to which the encrypted identifier is
        pointing. Raises ValueError if the identifier is invalid.
        """

        try:
            session_id = cipher.decrypt(ub64decode(eid),
                                        self.ciphertext_length)
        except (TypeError, ValueError):
            pass
        else:
            session_id = session_id[self.random_prefix_bytes:]
            session_id = ub64encode(session_id)
            session = SessionStore(session_key=session_id)
            if session.get('encrypted_id') == eid:
                # circular import
                from .models import RevokedToken

                # revoke to prevent replay attacks
                if RevokedToken.add(eid):
                    del session['encrypted_id']
                    session.save()
                    return session
        raise ValueError('Invalid session id')
示例#2
0
def ssl_auth(request):
    """ SSL certificate authentication. """

    ssl_auth_form = SSLCertLoginForm(request.POST)
    if not ssl_auth_form.is_valid():
        return HttpResponseBadRequest('400 Bad Request')

    session_id = cipher.decrypt(
            base64.b64decode(ssl_auth_form.cleaned_data['session_id']),
            32)

    next_uri = ssl_auth_form.cleaned_data['login_uri']

    user = authenticate(request=request)
    if user and user.is_active:
        _login(request, user)
        init_otp(request)
        if request.user.is_verified(): # OTP disabled
            next_uri = ssl_auth_form.cleaned_data['next']
    else:
        messages.error(request, 'Certificate authentication failed')

    # so, django will always start a new session for us. we need to copy
    # the data to the original session and preferably flush the new one.
    session = SessionStore(session_key=session_id)
    session.update(request.session)

    # always logout automatically from SSL-based auth
    # it's easy enough to log back in anyway
    if 'openid_request' in session:
        session['auto_logout'] = True

    session.save()
    request.session.flush()
    return redirect(next_uri)
示例#3
0
    def decrypt(self, eid):
        """
        Return the SessionStore to which the encrypted identifier is
        pointing. Raises ValueError if the identifier is invalid.
        """

        try:
            session_id = cipher.decrypt(ub64decode(eid),
                                        self.ciphertext_length)
        except (TypeError, ValueError):
            pass
        else:
            session_id = session_id[self.random_prefix_bytes:]
            session_id = ub64encode(session_id)
            session = SessionStore(session_key=session_id)
            if session.get('encrypted_id') == eid:
                # circular import
                from .models import RevokedToken

                # revoke to prevent replay attacks
                if RevokedToken.add(eid):
                    del session['encrypted_id']
                    session.save()
                    return session
        raise ValueError('Invalid session id')
示例#4
0
def migrate_sessions(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
    db_alias = schema_editor.connection.alias
    from django.contrib.sessions.backends.cache import KEY_PREFIX, SessionStore
    from django.core.cache import cache

    AuthenticatedSession = apps.get_model("authentik_core", "AuthenticatedSession")
    User = apps.get_model("authentik_core", "user")

    session_keys = cache.keys(KEY_PREFIX + "*")
    for key in session_keys:
        key = key.replace(KEY_PREFIX, "")
        store = SessionStore(key)
        data = store.load()
        if data == {} or "_auth_user_id" not in data:
            continue
        if (
            AuthenticatedSession.objects.using(db_alias)
            .filter(session_key=key)
            .exists()
        ):
            continue
        users = User.objects.using(db_alias).filter(pk=data.get("_auth_user_id"))
        if not users.exists():
            continue
        AuthenticatedSession.objects.using(db_alias).create(
            session_key=key,
            user=users.first(),
            expires=data.get("_session_expiry", now()),
        )
    def test_encrypt_decrypt(self):
        session = SessionStore()
        session['test'] = 'in-test'
        session.save()

        eid = sessionrefcipher.encrypt(session)
        sess = sessionrefcipher.decrypt(eid)
        self.assertEqual(sess.get('test'), 'in-test')
    def test_encrypt_decrypt(self):
        session = SessionStore()
        session['test'] = 'in-test'
        session.save()

        eid = sessionrefcipher.encrypt(session)
        sess = sessionrefcipher.decrypt(eid)
        self.assertEqual(sess.get('test'), 'in-test')
    def test_unique_encrypted_are_generated_after_revocation(self):
        session = SessionStore()
        session['test'] = 'in-test'
        session.save()

        eid1 = sessionrefcipher.encrypt(session)
        session = sessionrefcipher.decrypt(eid1)
        eid2 = sessionrefcipher.encrypt(session)
        self.assertNotEqual(eid1, eid2)
    def test_unique_encrypted_are_generated_after_revocation(self):
        session = SessionStore()
        session['test'] = 'in-test'
        session.save()

        eid1 = sessionrefcipher.encrypt(session)
        session = sessionrefcipher.decrypt(eid1)
        eid2 = sessionrefcipher.encrypt(session)
        self.assertNotEqual(eid1, eid2)
示例#9
0
def punch(request):
    if request.method == "POST":
        try:
            nump = int(request.POST['num_punches'])
        except ValueError:
            return HttpResponse(json.dumps({'error': 'float'}),
                                content_type="application/json")

        settings = SESSION.get_settings(request.session)
        if nump > settings.get("punches_employee"):
            return HttpResponse(json.dumps({
                'error': 'over',
                'limit': nump
            }),
                                content_type="application/json")

        store = SESSION.get_store(request.session)
        data = {
            "store_location_id":\
                SESSION.get_active_store_location_id(request.session),
            "store_id":store.objectId,
            "store_name":str(store.get('store_name')),
            "punch_code":str(request.POST['punch_code']),
            "num_punches":nump,
        }

        # Check if the user is an employee
        employee = request.session.get("employee")
        if employee:
            data['employee_id'] = employee.objectId

        res = cloud_call("punch", data)
        if 'error' not in res:
            res['patron_name'] = res['result']
            # always make sure to get the latest session since the session
            # will be saved on return!!!
            request.session.clear()
            request.session.update(SessionStore(request.session.session_key))
            return HttpResponse(json.dumps(res),
                                content_type="application/json")
        else:
            if res['error'] == "PATRON_NOT_FOUND":
                request.session.clear()
                request.session.update(
                    SessionStore(request.session.session_key))
                return HttpResponse(json.dumps({"error":\
                    "PATRON_NOT_FOUND"}),
                    content_type="application/json")

    # always make sure to get the latest session since the session
    # will be saved on return!!!
    request.session.clear()
    request.session.update(SessionStore(request.session.session_key))
    return HttpResponse(json.dumps({'error': 'error'}),
                        content_type="application/json")
示例#10
0
    def test_revoked_encrypted_id_raises_valueerror(self):
        session = SessionStore()
        session['test'] = 'in-test'
        session.save()

        eid1 = sessionrefcipher.encrypt(session)
        session = sessionrefcipher.decrypt(eid1)
        eid2 = sessionrefcipher.encrypt(session)
        if eid1 == eid2:
            raise SkipTest('Non-unique encrypted IDs generated')
        self.assertRaises(ValueError, sessionrefcipher.decrypt, eid1)
示例#11
0
def checkSessionToken(request):
    """
    验证sessionToken
    """
    session_key = request.COOKIES.get('sid', None)
    session = SessionStore(session_key)
    session_data = session.load()
    if session_data.get('stoken', None):
        session.delete()
    else:
        raise InvestError(3008)
示例#12
0
    def test_revoked_encrypted_id_raises_valueerror(self):
        session = SessionStore()
        session['test'] = 'in-test'
        session.save()

        eid1 = sessionrefcipher.encrypt(session)
        session = sessionrefcipher.decrypt(eid1)
        eid2 = sessionrefcipher.encrypt(session)
        if eid1 == eid2:
            raise SkipTest('Non-unique encrypted IDs generated')
        self.assertRaises(ValueError, sessionrefcipher.decrypt, eid1)
示例#13
0
    def test_request(self):
        user = User.objects.create_user('root', 'root')
        session = SessionStore()
        session.save()

        request = HttpRequest()
        request.user = user
        request.session = session

        usage.log('test', request=request, async=False)
        event = Log.objects.all()[0]
        self.assertEqual(event.user, user)
        self.assertEqual(event.session_key, request.session.session_key)
示例#14
0
def terminate(request):
    """
    Flags the looping thread in the pull view to exit.
    This simply deletes the CometSession bound to this instance.
    """
    if request.method == "GET":
        t = parser.parse(request.GET["timestamp"])
        timestamp = str(t.hour).zfill(2) + ":" +\
            str(t.minute).zfill(2) + ":" + str(t.second).zfill(2)
        uid = request.GET['uid']
        try:
            scomet = CometSession.objects.get(session_key=\
                request.session.session_key,
                timestamp=timestamp, uid=uid)
            scomet.delete()
        except CometSession.DoesNotExist:
            pass  # do nothing

        # make sure that the latest session data is saved!
        request.session.clear()
        request.session.update(SessionStore(\
            request.session.session_key))

        return HttpResponse("ok")
    return HttpResponse("")
示例#15
0
    def get_view_handler_request(self,
                                 view,
                                 user,
                                 handler_name,
                                 method,
                                 url,
                                 data={},
                                 ajax=False):
        factory = RequestFactory()
        f = getattr(factory, method)

        # create request with session store
        request = f(url, data)
        request.session = SessionStore()
        request.META['HTTP_HOST'] = '127.0.0.1'
        request._messages = FallbackStorage(request)

        # user
        if user and user.id:
            self.login(request, user)

        # ajax
        if ajax:
            request.META['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest'

        # user, profile and backend
        request.user = user
        request.user_profile = self.get_user_profile(request.user)
        request.backend = Backend()

        # changelog
        request.changelog = ChangeLogManager(request)

        return request
示例#16
0
 def setUpTestData(cls):
     cls.user = get_user_model().objects.create(username='******')
     request = RequestFactory().get('/')
     request.session = SessionStore()
     request.user = AnonymousUser()
     cls.backend = MojeidOidcBackend()
     cls.backend.request = request
示例#17
0
    def test_user_with_multiple_teams_is_redirected_home_on_successful_signin(
            self):
        user = UserAuth.objects.create_user(username='******',
                                            password='******')
        teams = [
            Profile.objects.create(slug='team1'),
            Profile.objects.create(slug='team2')
        ]
        for team in teams:
            team.members.add(user.profile)
        assert_equal(user.profile.teams.all().count(), 2)

        url = reverse('app-signin')

        user_data = {
            'username': '******',
            'password': '******',
        }

        request = self.factory.post(url, data=user_data)
        request.user = AnonymousUser()
        request.session = SessionStore('session')
        response = signin_view(request)
        assert_equal(response.status_code, 302)
        assert_equal(response.url, reverse('app-user-profile'))
示例#18
0
 def get_decoded_data(self):
     try:
         session_data = SessionStore().decode(self.session_data)
     except:
         session_data = {}
     finally:
         return session_data
示例#19
0
def pytest_request(rf, method, url, user=None, data=None, token=None):
    """
        : Test 를 위한 request 생성하는 함수
        - rf 설명: https://pytest-django.readthedocs.io/en/latest/helpers.html#rf-requestfactory
    """

    content_type = 'application/json'
    caller = getattr(rf, method)
    request = caller(path=url, data=data, content_type=content_type)

    if not hasattr(request, 'session'):
        setattr(request, 'session', SessionStore())

    # todo: Oauth2.0 test 로직 구현 해야함
    force_authenticate(request=request, user=user, token=token)
    request.user = user

    # 실제 호출하는 url 에 대한 view 정보를 가져옴
    _url = url.split('?')  # 쿼리 파라미터를 url 에서 빼줘야함
    resolver_match = resolve(_url[0])
    test_func, test_args, test_kwargs = resolver_match
    request.resolver_match = resolver_match
    response = test_func(request, *test_args, **test_kwargs)

    return response
示例#20
0
    def make_request(self, method, url, data={}, ajax=False, user=None):
        """
        Create a mock request object that supports messaging and session
        handling.
        """
        factory = RequestFactory()
        f = getattr(factory, method)

        request = f(url, data)
        request.session = SessionStore()
        request.META['HTTP_HOST'] = '127.0.0.1'
        request._messages = FallbackStorage(request)

        # ajax
        if ajax:
            request.META['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest'

        # user
        if user:
            request.user = user
            request.user_profile = self.get_user_profile(request.user)

        # changelog
        request.changelog = ChangeLogManager(request)

        return request
示例#21
0
def delete(request, employee_id):
    """ 
    This will also remove the employee from the ACL,
    delete the employee object and also delete the Parse.User object
    if and only if it has no pointer to a Store or a Patron.
    """
    # get from the employees_approved_list in session cache
    employees_approved_list = SESSION.get_employees_approved_list(\
        request.session)
    i_remove, employee = 0, None
    for ind, m in enumerate(employees_approved_list):
        if m.objectId == employee_id:
            employee = m
            i_remove = ind
            break

    if not employee:
        return redirect(reverse('employees_index')+ "?%s" %\
            urllib.urlencode({'success': 'Employee has already been removed.'}))

    employees_approved_list.pop(i_remove)
    request.session['employees_approved_list'] =\
        employees_approved_list

    acc = Account.objects().get(Employee=employee.objectId)
    if not acc:  # employee may have been deleted
        return redirect(reverse('employees_index')+ "?%s" %\
            urllib.urlencode({'success': 'Employee has already been deleted.'}))

    # Always save session first whenever calling a cloud code
    request.session.save()

    res = cloud_call("delete_employee", {"employee_id": employee.objectId})

    request.session.clear()
    request.session.update(SessionStore(request.session.session_key))

    if 'error' not in res:
        store = SESSION.get_store(request.session)
        payload = {COMET_RECEIVE_KEY_NAME: COMET_RECEIVE_KEY}
        if acc.objectId in store.ACL and not store.is_owner(acc):
            del store.ACL[acc.objectId]
            store.update()
            payload["updatedStore"] = store.jsonify()
            request.session['store'] = store

        # only need to pass in the objectId
        deleted_employee = Employee(objectId=employee.objectId)
        payload["deletedEmployee"] = deleted_employee.jsonify()

        comet_receive(store.objectId, payload)

        return redirect(reverse('employees_index')+ "?%s" %\
            urllib.urlencode({'success': 'Employee has been deleted.'}))

    return redirect(reverse('employees_index')+ "?%s" %\
        urllib.urlencode({'success': 'Employee has already been deleted.'}))
示例#22
0
def init_request():
    request = HttpRequest()
    request.method = 'GET'
    request.session = SessionStore()
    request.session.create()
    request._messages = BaseStorage(request)
    request.entree_user = AnonymousUser()

    return request
示例#23
0
 def processSession(skey):
     # get the latest session associated with this object
     session = SessionStore(skey)
     # do not go if the session has already been logged out
     if session.get('account') is None or SESSION_KEY not in session:
         return
         
     processCometReceivedDict(session, postDict)
     
     # need to save session to commit modifications
     session.modified = True
     session.save()
     
     # flag all threads with this session_key about the new stuff
     # same browser - different tabs
     CometSession.objects.update()
     for comet in CometSession.objects.filter(session_key=skey):
         comet.modified = True
         comet.save()
示例#24
0
def test_fflag_for_new_unauthorized_user():
    fflag_set_part('fflag_1', 1)

    middleware = FFlagMiddleware(lambda request: HttpResponse(''))

    req = RequestFactory().get('/')
    req.session = SessionStore()
    middleware(req)

    assert req.fflag_enabled('fflag_1')
示例#25
0
def deny(request, employee_id):
    """ same as delete except this uses the pending list """
    # get from the employees_pending_list in session cache
    employees_pending_list = SESSION.get_employees_pending_list(\
        request.session)
    i_remove, employee = 0, None
    for ind, m in enumerate(employees_pending_list):
        if m.objectId == employee_id:
            employee = m
            i_remove = ind
            break

    if not employee:
        return redirect(reverse('employees_index')+ "?%s" %\
            urllib.urlencode({'success': 'Pending employee not found.'}))

    # update session cache for employees_pending_list
    employees_pending_list.pop(i_remove)
    request.session['employees_pending_list'] =\
        employees_pending_list

    acc = Account.objects().get(Employee=employee.objectId)
    if not acc:  # employee may have been deleted
        return redirect(reverse('employees_index')+ "?show_pending&%s" %\
            urllib.urlencode({'success': 'Employee has already been denied.'}))

    # Always save session first whenever calling a cloud code
    request.session.save()

    res = cloud_call("delete_employee", {"employee_id": employee.objectId})

    request.session.clear()
    request.session.update(SessionStore(request.session.session_key))

    if 'error' not in res:
        payload = {COMET_RECEIVE_KEY_NAME: COMET_RECEIVE_KEY}
        store = SESSION.get_store(request.session)
        # no need to check acl here but just in case
        if acc.objectId in store.ACL and not store.is_owner(acc):
            del store.ACL[acc.objectId]
            store.update()
            payload["updatedStore"] = store.jsonify()
            request.session['store'] = store

        # only need to pass in the objectId
        deleted_employee = Employee(objectId=employee.objectId)
        payload["deletedEmployee"] = deleted_employee.jsonify()

        comet_receive(store.objectId, payload)

        return redirect(reverse('employees_index')+ "?show_pending&%s" %\
            urllib.urlencode({'success': 'Employee has been denied.'}))

    return redirect(reverse('employees_index')+ "?%s" %\
        urllib.urlencode({'success': 'Employee has already been deleted.'}))
示例#26
0
def manage_admin_controls(request):
    """
    To turn on god_mode:
    ...repunch.com/manage/admin-controls?action=god_mode&flag=1&
    [email protected]&key=9p8437wk34z5ymurukdp9w34px7iuhsruhio
    """

    if request.method == "GET":
        params = request.GET.dict()
        key = params.get("key")
        action = params.get("action")

        if key == ADMIN_CONTROL_KEY:
            if action == "god_mode":
                flag = params.get("flag")
                email = params.get("email", "")
                acc = Account.objects().get(email=email,
                                            Store__ne=None,
                                            include="Store.Subscription")
                if not acc:
                    return HttpResponse("User with email %s not found." %\
                        (email,))

                sub = acc.store.subscription
                sub.god_mode = flag != "0"
                sub.update()

                payload = {
                    COMET_RECEIVE_KEY_NAME: COMET_RECEIVE_KEY,
                    "updatedSubscription": sub.jsonify(),
                }
                comet_receive(acc.store.objectId, payload)

                # go out with the latest session in case this user is
                # the one that triggered this action
                request.session.clear()
                request.session.update(
                    SessionStore(request.session.session_key))

                if sub.god_mode:
                    on_off = "on"
                else:
                    on_off = "off"

                return HttpResponse("Successfully turned god mode "+\
                    "%s for user with email %s" % (on_off, email))

            else:
                return HttpResponse("Invalid action: %s" % (action, ))

        else:
            return HttpResponse("Wrong key: %s" % (key, ))

    return HttpResponse("Bad Request")
示例#27
0
def test_fflag_enabled_for_unauthorized_user(user_id, expected):
    fflag_set_part_ids('fflag_1', [12])

    middleware = FFlagMiddleware(lambda request: HttpResponse(''))

    req = RequestFactory().get('/')
    req.session = SessionStore()
    req.session['FFLAG_USER_ID'] = user_id
    middleware(req)

    assert req.fflag_enabled('fflag_1') == expected
示例#28
0
def test_user_login(user_data, user):
    from django.contrib.auth import authenticate, login
    from django.http.request import HttpRequest
    from django.contrib.sessions.backends.cache import SessionStore
    assert user.activate('516bb9061d58280acd0c3900e18feaf5166f02ff')
    request = HttpRequest()
    request.session = SessionStore()
    user = authenticate(username=user_data['username'],
                        password=user_data['password'])
    login(request, user)
    assert user.is_authenticated()
示例#29
0
    def test_lazy_request_args(self):
        # Ensure that request_args can be a lazy-evaluated dictionary.
        request = self.factory.get('/')
        request.user = AnonymousUser()
        request.session = SessionStore()

        info = browserid_info(request)
        d = pq(info)

        info_div = d('#browserid-info')
        self.assertEqual(info_div.attr('data-request-args'),
                         '{"siteName": "asdf"}')
示例#30
0
    def info(self, user=None, backend=None):
        request = self.factory.get('/')
        request.session = SessionStore()
        if user:
            if backend:
                user.backend = '{0}.{1}'.format(backend.__module__,
                                                backend.__class__.__name__)
            auth.login(request, user)
            request.user = user

        info = views.Info.as_view()
        return info(request)
示例#31
0
    def test_backend_should_contain_error_messages_if_errors_have_been_raised(self):
        request = self.factory.get('/admin/')
        request.session = SessionStore()
        request._messages = FallbackStorage(request)

        # add some messages to filter. Add some non-error messages as well
        messages.add_message(request, messages.SUCCESS, 'SUCCESS')
        messages.add_message(request, messages.INFO, 'INFO')
        messages.add_message(request, messages.ERROR, 'ERROR')

        c = backend(request)
        self.assertEqual(['ERROR'], [m.message for m in c.get('error_messages')])
示例#32
0
    def test_defaults(self):
        request = self.factory.get('/')
        request.user = AnonymousUser()
        request.session = SessionStore()

        info = browserid_info(request)
        d = pq(info)

        info_div = d('#browserid-info')
        self.assertEqual(info_div.attr('data-user-email'), '')
        self.assertEqual(info_div.attr('data-request-args'), '{}')

        form = d('#browserid-form')
        self.assertEqual(form.attr('action'), '/browserid/login/')
示例#33
0
def test_authenticated_visiting_user(user_factory, rf, session):
    """
    Check that an authenticated user creates a recognized customer visiting the site.
    """
    user = user_factory()
    with pytest.raises(Customer.DoesNotExist):
        Customer.objects.get(pk=user.pk)
    request = rf.get('/', follow=True)
    request.user = user
    request.session = SessionStore()
    customer = Customer.objects.get_from_request(request)
    assert isinstance(customer, Customer)
    assert customer.is_authenticated() is True
    assert customer.is_recognized() is True
    assert customer.is_registered() is True
示例#34
0
    def test_login_via_form_valid(self):
        data = {
            'username': self.user.email,
            'password': self.user_password,
        }

        self.request.entree_user = AnonymousUser()
        self.request.method = 'POST'
        self.request.POST = data
        self.request.session = SessionStore()

        ViewClass = csrf_exempt(LoginView.as_view())
        ViewClass(self.request, origin_site=self.valid_site.pk)

        assert_equals(self.request.entree_user, self.user)
示例#35
0
    def test_logout_form_valid(self):

        data = {
            'origin_site': self.valid_site.pk,
            'next_url': '/',
        }

        self.request.method = 'POST'
        self.request.POST = data
        self.request.session = SessionStore()

        ViewClass = csrf_exempt(LogoutView.as_view())
        ViewClass(self.request, site_id=self.valid_site.pk)

        assert_equals(self.request.entree_user.__class__, AnonymousUser)
示例#36
0
 def _create_spf_test_form(self):
     s = Settings()
     s.save()
     form = SettingsForm(
         self._create_settings_data(
             s, {
                 'enquiry_email': '*****@*****.**',
                 'enquiry_from': '*****@*****.**',
                 'enquiry_reply': '*****@*****.**'
             }))
     factory = RequestFactory()
     request = factory.post('/')
     request.session = SessionStore()
     request._messages = FallbackStorage(request)
     form.configure(request, s, edit=True)
     return (request, form)
示例#37
0
    def comet(session_copy):
        # used by more than 1 (note that it is ok to retrieve all of 
        # the lists since they are all pointers - not the actual list!
        employees_pending_list_copy =\
            SESSION.get_employees_pending_list(session_copy)
        employees_approved_list_copy =\
            SESSION.get_employees_approved_list(session_copy)
        messages_received_list_copy =\
            SESSION.get_messages_received_list(session_copy)
        redemptions_pending_copy =\
            SESSION.get_redemptions_pending(session_copy)
        redemptions_past_copy =\
            SESSION.get_redemptions_past(session_copy)
        
        # this is the latest session data
        session = SessionStore(request.session.session_key)
        employees_pending_list =\
            SESSION.get_employees_pending_list(session)
        employees_approved_list =\
            SESSION.get_employees_approved_list(session)
        messages_received_list =\
            SESSION.get_messages_received_list(session)
        redemptions_pending =\
            SESSION.get_redemptions_pending(session)
        redemptions_past =\
            SESSION.get_redemptions_past(session)
        
        # put the diffs between session_copy and session here
        data = {}
        
        #############################################################
        # FEEDBACKS_UNREAD ##################################
        fbs_unread_copy = [ fb.objectId for fb in\
            messages_received_list_copy if not fb.is_read ]
        fbs_unread = [ fb.objectId for fb in\
            messages_received_list if not fb.is_read ]
            
        # get the difference between the two
        feedbacks_unread =\
            tuple(set(fbs_unread) - set(fbs_unread_copy))
        if feedbacks_unread:
            fb_unread = []
            messages_received_ids =\
                [ fb.objectId for fb in messages_received_list ]
            for feedback_id in feedbacks_unread:
                for fb in messages_received_list:
                    if fb.objectId == feedback_id:
                        fb_unread.append(fb.jsonify())
                        break
                
            if len(fb_unread) > 0:
                fb_count = 0
                for fb in messages_received_list:
                    if not fb.get("is_read"):
                        fb_count += 1
                data['feedbacks_unread'] = fb_unread
                data['feedback_unread_count'] = fb_count
          
        #############################################################
        # EMPLOYEES_PENDING ##################################
        # must also check if employee is already approved!
        emps_pending_copy = [ emp.objectId for emp in
            employees_pending_list_copy ]
        emps_pending = [ emp.objectId for emp in
            employees_pending_list ]
            
        employees_pending =\
            tuple(set(emps_pending) - set(emps_pending_copy))
            
        if employees_pending:
            pending = []
            for emp_id in employees_pending:
                for emp in employees_pending_list:
                    if emp.objectId == emp_id:
                        pending.append(emp.jsonify())
                        break
                    
            if len(pending) > 0:   
                data['employees_pending_count'] =\
                    len(employees_pending_list)
                data['employees_pending'] = pending
        
        #############################################################
        # EMPLOYEES APPROVED (pending to approved) #################
        emps_approved_copy = [ emp.objectId for emp in\
            employees_approved_list_copy]
        emps_approved = [ emp.objectId for emp in\
            employees_approved_list]
            
        appr_emps =\
            tuple(set(emps_approved) - set(emps_approved_copy))
        
        if appr_emps:
            approved = []
            for appr_emp_id in appr_emps:
                for emp in employees_approved_list:
                    if emp.objectId == appr_emp_id:
                        approved.append(emp.jsonify())
                        break
                        
            if len(approved) > 0:
                data['employees_approved'] = approved
                data['employees_pending_count'] =\
                    len(employees_pending_list)
            
        #############################################################
        # EMPLOYEES DELETED/DENIED/REJECTED (pending/approved to pop)!
        # need to compare approved and pending!
        emps_copy = emps_approved_copy[:]
        emps_copy.extend(emps_pending_copy)
        emps = emps_approved[:]
        emps.extend(emps_pending)
        
        # emps_copy has the same or more items that emps
        del_emps = tuple(set(emps_copy) - set(emps))
        
        if del_emps:
            deleted = []
            for demp_id in del_emps:
                if demp_id in emps_approved_copy:
                    emps_list = employees_approved_list_copy
                else:
                    emps_list = employees_pending_list_copy
                    
                for emp in emps_list:
                    if emp.objectId == demp_id:
                        deleted.append(emp.jsonify())
                        break  
                        
            if len(deleted) > 0:   
                data['employees_pending_count'] =\
                    len(employees_pending_list)
                data['employees_deleted'] = deleted
           
        #############################################################
        # REDEMPTIONS PENDING
        reds_pending_copy = [ r.objectId for r in\
            redemptions_pending_copy ]
        reds_pending = [ r.objectId for r in redemptions_pending ]
        
        reds = tuple(set(reds_pending) - set(reds_pending_copy))
        
        if reds:
            redemps = []
            for r_id in reds:
                for redemp in redemptions_pending:
                    if redemp.objectId == r_id:
                        redemps.append(redemp.jsonify())
                        break
                        
            if len(redemps) > 0:
                data['redemption_pending_count'] =\
                    len(redemptions_pending)
                data['redemptions_pending'] = redemps
                
        #############################################################
        # REDEMPTIONS APPROVED (pending to history)
        reds_past_copy = [ r.objectId for r in\
            redemptions_past_copy ]
        reds_past = [ r.objectId for r in redemptions_past ]
        
        appr_redemps =\
            tuple(set(reds_past) - set(reds_past_copy))
            
        if appr_redemps:   
            redemp_js = []
            for red_id in appr_redemps:
                for redemp in redemptions_past:
                    if redemp.objectId == red_id:
                        redemp_js.append(redemp.jsonify())
                        break
            
            if len(redemp_js) > 0:
                data['redemption_pending_count'] =\
                    len(redemptions_pending)
                data['redemptions_approved'] = redemp_js
            
        #############################################################
        # REDEMPTIONS DELETED ##############################
        # remove from pending (should not be in history!)
        reds_copy = reds_past_copy[:]
        reds_copy.extend(reds_pending_copy)
        reds = reds_past[:]
        reds.extend(reds_pending)
        
        # reds_copy has the same or more items that reds
        del_redemps = tuple(set(reds_copy) - set(reds))
        if del_redemps:
            redemp_js = []
            for red_id in del_redemps:
                reds_list = []
                if red_id in reds_past_copy:
                    reds_list = redemptions_past_copy
                elif red_id in reds_pending_copy:
                    reds_list = redemptions_pending_copy
                    
                for redemp in reds_list:
                    if redemp.objectId == red_id:
                        redemp_js.append(redemp.jsonify())
                        break               
            if len(redemp_js) > 0:
                data['redemption_pending_count'] =\
                    len(redemptions_pending)
                data['redemptions_deleted'] = redemp_js
            
        #############################################################
        # SETTINGS UPDATED ##############################
        settings_copy = session_copy.get("settings")
        settings = session.get("settings")
        if settings_copy.get("retailer_pin") !=\
            settings.get("retailer_pin"):
            data['retailer_pin'] = settings.get("retailer_pin")
        
        #############################################################
        # REWARDS UPDATED ##############################
        rewards_copy = session_copy.get("store").get("rewards")
        rewards_copy =\
            { reward['reward_id']:reward for reward in rewards_copy }
            
        rewards = session.get("store").get("rewards")
        rewards = { reward['reward_id']:reward for reward in rewards }
        updated_rewards = []
        
        for reward_id, rew_copy in rewards_copy.iteritems():
            # Note that some rewards may have been deleted!
            rew = rewards.get(reward_id)
            if rew and rew_copy['redemption_count'] !=\
                rew['redemption_count']:
                # only the redemtpion_count and reward_id are used
                # in the client side
                updated_rewards.append({
                    "reward_id": reward_id,
                    "redemption_count": rew['redemption_count'],
                })
        
        if updated_rewards:
            data['rewards'] = updated_rewards
           
        #############################################################
        # PATRONSTORE_COUNT ##################################
        patronStore_count_copy =int(session_copy["patronStore_count"])
        patronStore_count = int(session["patronStore_count"])
        if patronStore_count_copy != patronStore_count:
            data['patronStore_count'] = patronStore_count
            
            
        #############################################################
        # ACTIVE_STORE_LOCATION_ID ############################
        if session['active_store_location_id'] !=\
            session_copy['active_store_location_id']:
            data['active_store_location_id'] =\
                session['active_store_location_id']
            

        # IMPORTANT! The request.session is the same as the 
        # SessionStore(session_key)! so we must use the 
        # request.session because it is automatically saved at the end
        # of each request- thereby overriding/undoing any changes made
        # to the SessionStore(session_key) key!
        # need to check if we are still logged in
        session = SessionStore(request.session.session_key)
        if 'account' in session and SESSION_KEY in session:
            request.session.clear()
            request.session.update(session)
        else:
            flush(request.session)
        
        ############################################################
        # Respond ###########################################
        try: 
            return HttpResponse(json.dumps(data), 
                        content_type="application/json")
        except (IOError, socket.error) as e: # broken pipe/socket. 
            thread.exit() # exit silently
示例#38
0
def update_balance(request, update_type, obj=None):
    # 创建主题
    if update_type == 'create':
        # 获取当前用户的id
        uid = request.session.get('user_info')['uid']
        # 设置改变值
        change_balance = -20
        # 类型
        balance_type = "创建主题"
        # 描述
        marks = '创建了的主题 > <a href="{_uri}">{_title}</a>'.format(_uri=reverse('topic', args=(obj.topic_sn,)),
                                                                _title=obj.title)

        # 更新数据库中的用户余额
        UserDetails.objects.filter(user_id=uid).update(balance=F('balance') + change_balance)

        # 获取此用户更新后的balance
        user_obj = UserDetails.objects.filter(user_id=uid).first()

        # 创建余额变动清单
        BalanceInfo.objects.create(
            user_id=uid,
            balance_type=balance_type,
            balance=change_balance,
            marks=marks,
            last_balance=user_obj.balance
        )

        # 更新session 中数据
        request.session['user_info']['balance'] = user_obj.balance

    # 创建回复
    elif update_type == 'reply':
        uid = request.session.get('user_info')['uid']
        change_balance = -5
        balance_type = "创建回复"
        marks = '在主题 > <a href="{_uri}">{_title}</a> 中创建了回复'.format(_uri=reverse('topic', args=(obj.topic_sn,)),
                                                                    _title=obj.title)

        # 更新数据库中的用户余额
        UserDetails.objects.filter(user_id=uid).update(balance=F('balance') + change_balance)

        # 获取此用户更新后的balance
        user_obj = UserDetails.objects.filter(user_id=uid).first()

        # 创建余额变动清单
        BalanceInfo.objects.create(
            user_id=uid,
            balance_type=balance_type,
            balance=change_balance,
            marks=marks,
            last_balance=user_obj.balance
        )

        # 更新session 中数据
        request.session['user_info']['balance'] = user_obj.balance

    # 感谢主题
    elif update_type == 'thanks':
        uid = request.session.get('user_info')['uid']
        change_balance = -15
        balance_type = "发送谢意"
        marks = '感谢 <a href="{_member_uri}">{_author}</a> 的 > <a href="{_uri}">{_title}</a> 主题'.format(
            _member_uri=reverse('member', args=(obj.author.username,)), _author=obj.author.username,
            _uri=reverse('topic', args=(obj.topic_sn,)), _title=obj.title)

        # 更新数据库中的用户余额
        UserDetails.objects.filter(user_id=uid).update(balance=F('balance') + change_balance)

        # 获取此用户更新后的balance
        user_obj = UserDetails.objects.filter(user_id=uid).first()

        # 创建余额变动清单
        BalanceInfo.objects.create(
            user_id=uid,
            balance_type=balance_type,
            balance=change_balance,
            marks=marks,
            last_balance=user_obj.balance
        )

        # 更新session 中数据
        request.session['user_info']['balance'] = user_obj.balance

    # 收到感谢
    elif update_type == 'recv_thanks':
        # 获取基础信息
        uid = obj.author_id
        change_balance = 10
        balance_type = "收到谢意"
        marks = '主题 > <a href="{_uri}">{_title}</a> 收到感谢'.format(_uri=reverse('topic', args=(obj.topic_sn,)),
                                                                 _title=obj.title)

        # 更新数据库中的用户余额
        UserDetails.objects.filter(user_id=uid).update(balance=F('balance') + change_balance)

        # 获取此用户更新后的balance
        user_obj = UserDetails.objects.filter(user_id=uid).first()

        # 创建余额变动清单
        BalanceInfo.objects.create(
            user_id=uid,
            balance_type=balance_type,
            balance=change_balance,
            marks=marks,
            last_balance=user_obj.balance
        )

        # 收到感谢,要查找是谁收到感谢,然后更新此用户的session数据
        session = SessionStore(session_key=obj.author.session)
        # 如果用户在线,才更新
        if session.get('user_info', None):
            session['user_info']['balance'] = user_obj.balance
            # 在外边使用session 要调用save 保存数据
            session.save()

    # 主题收到回复
    elif update_type == 'reply_recv':
        uid = obj.author_id
        change_balance = 5
        balance_type = "主题回复收益"
        marks = '主题 > <a href="{_uri}">{_title}</a> 收到了回复'.format(_uri=reverse('topic', args=(obj.topic_sn,)),
                                                                  _title=obj.title)

        # 更新数据库中的用户余额
        UserDetails.objects.filter(user_id=uid).update(balance=F('balance') + change_balance)

        # 获取此用户更新后的balance
        user_obj = UserDetails.objects.filter(user_id=uid).first()

        # 创建余额变动清单
        BalanceInfo.objects.create(
            user_id=uid,
            balance_type=balance_type,
            balance=change_balance,
            marks=marks,
            last_balance=user_obj.balance
        )

        # 收到回复,要查找是谁收到回复,然后更新此用户的session数据
        session = SessionStore(session_key=obj.author.session)
        if session.get('user_info', None):
            session['user_info']['balance'] = user_obj.balance
            # 在外边使用session 要调用save 保存数据
            session.save()

    # 编辑主题
    elif update_type == 'edit':
        uid = obj.author_id
        change_balance = -5
        balance_type = "编辑主题"
        marks = '编辑了主题 > <a href="{_uri}">{_title}</a>'.format(_uri=reverse('topic', args=(obj.topic_sn,)),
                                                               _title=obj.title)

        # 更新数据库中的用户余额
        UserDetails.objects.filter(user_id=uid).update(balance=F('balance') + change_balance)

        # 获取此用户更新后的balance
        user_obj = UserDetails.objects.filter(user_id=uid).first()

        # 创建余额变动清单
        BalanceInfo.objects.create(
            user_id=uid,
            balance_type=balance_type,
            balance=change_balance,
            marks=marks,
            last_balance=user_obj.balance
        )
        # 更新session 中数据
        request.session['user_info']['balance'] = user_obj.balance