Example #1
0
    def post(self, request, *args, **kwargs):
        """
        request.POST contains following keys:
        - token
        - site_id
        - checksum

        @return: identity data for given site (see site_id in request.POST)
        @rtype: json on success, HttpResponseForbidden on invalid input
        """
        data = self.request.POST
        try:
            site = EntreeSite.objects.get_cached(key=data['site_id'])
        except (EntreeSite.DoesNotExist, KeyError):
            logger.error("requested EntreeSite does not exist", extra={'site_id': data.get('site_id')})
            return HttpResponseForbidden(_("Invalid site id"))

        if not site.is_active:
            return HttpResponseForbidden(_("Origin site is not active"))

        expected_checksum = calc_checksum("%s:%s" % (data['site_id'], data.get('token')), salt=site.secret)
        if expected_checksum != data.get('checksum'):
            logger.error("Invalid token checksum")
            return HttpResponseForbidden(_("Invalid token checksum"))

        try:
            login_token = LoginToken.objects.get_cached(key=data['token'])
        except LoginToken.DoesNotExist:
            logger.error("Requested token doesn't exist", extra={'token': data['token']})
            return HttpResponseForbidden(_("Invalid token"))

        profile_data = SiteProfile.objects.get_data(user=login_token.user, site=site)
        profile_data.update(login_token.user.basic_data)
        return self.render_to_response(profile_data)
Example #2
0
 def _fetch_params(self, token):
     checksum = calc_checksum("%s:%s" % (ENTREE['SITE_ID'], token), salt=ENTREE['SECRET_KEY'])
     return {
         'token': token,
         'checksum': checksum,
         'site_id': ENTREE['SITE_ID'],
     }
Example #3
0
    def post(self, request, *args, **kwargs):
        """
        request.POST contains following keys:
        - token
        - site_id
        - checksum

        @return: identity data for given site (see site_id in request.POST)
        @rtype: json on success, HttpResponseForbidden on invalid input
        """
        data = request.POST
        try:
            site = get_cached_object(EntreeSite, pk=data['site_id'])
        except (EntreeSite.DoesNotExist, KeyError):
            logger.error("requested EntreeSite does not exist", extra={'site_id': data.get('site_id')})
            return HttpResponseForbidden(_("Invalid site id"))

        if not site.is_active:
            return HttpResponseForbidden(_("Origin site is not active"))

        expected_checksum = calc_checksum("%s:%s" % (data['site_id'], data.get('token')), salt=site.secret)
        if expected_checksum != data.get('checksum'):
            logger.error("Invalid token checksum")
            return HttpResponseForbidden(_("Invalid token checksum"))

        try:
            login_token = get_cached_object(LoginToken, value=data['token'])
        except LoginToken.DoesNotExist:
            logger.error("Requested token doesn't exist", extra={'token': data['token']})
            return HttpResponseForbidden(_("Invalid token"))

        profile_data = SiteProfile.objects.get_data(user=login_token.user, site=site)
        profile_data.update(login_token.user.basic_data)
        return self.render_to_response(profile_data)
Example #4
0
 def _fetch_params(self, token):
     checksum = calc_checksum("%s:%s" % (ENTREE['SITE_ID'], token),
                              salt=ENTREE['SECRET_KEY'])
     return {
         'token': token,
         'checksum': checksum,
         'site_id': ENTREE['SITE_ID'],
     }
    def test_process_response_valid_cookie_checksum_calculation(self):
        self.raw_request.entree_user = AnonymousUser()

        cookie_val = 'no checksum value'
        self.raw_request.COOKIES[ECOOKIE['NAME']] = cookie_val
        self.mi.process_response(self.raw_request, self.raw_response)
        expected_cookie = COOKIE_CHECKSUM_SEPARATOR.join([cookie_val, calc_checksum(cookie_val, length=10)])
        set_cookie = self.raw_response.cookies[ ECOOKIE['NAME'] ]
        assert expected_cookie in str(set_cookie)
    def test_process_response_valid_cookie_valid_checksum_dont_set_cookie(self):
        #self.raw_request.entree_user = AnonymousUser()

        cookie_val = 'w/ checksum value'
        expected_cookie = COOKIE_CHECKSUM_SEPARATOR.join([cookie_val, calc_checksum(cookie_val, length=10)])

        self.raw_request.COOKIES[ECOOKIE['NAME']] = expected_cookie
        self.mi.process_response(self.raw_request, self.raw_response)

        assert_equals([], self.raw_response.cookies.keys())
    def test_process_response_cookie_invalid_checksum_set_cookie(self):
        #self.raw_request.entree_user = AnonymousUser()

        cookie_val = 'w/ checksum value'
        expected_cookie = COOKIE_CHECKSUM_SEPARATOR.join([cookie_val, calc_checksum(cookie_val, length=10)])

        self.raw_request.COOKIES[ECOOKIE['NAME']] = expected_cookie[:-1]
        self.mi.process_response(self.raw_request, self.raw_response)

        assert ECOOKIE['INVALID'] in  str( self.raw_response.cookies[ECOOKIE['NAME']] )
Example #8
0
    def test_process_response_valid_cookie_checksum_calculation(self):
        self.raw_request.entree_user = AnonymousUser()

        cookie_val = 'no checksum value'
        self.raw_request.COOKIES[ECOOKIE['NAME']] = cookie_val
        self.mi.process_response(self.raw_request, self.raw_response)
        expected_cookie = COOKIE_CHECKSUM_SEPARATOR.join(
            [cookie_val, calc_checksum(cookie_val, length=10)])
        set_cookie = self.raw_response.cookies[ECOOKIE['NAME']]
        assert expected_cookie in str(set_cookie)
Example #9
0
    def test_process_response_cookie_invalid_checksum_set_cookie(self):
        #self.raw_request.entree_user = AnonymousUser()

        cookie_val = 'w/ checksum value'
        expected_cookie = COOKIE_CHECKSUM_SEPARATOR.join(
            [cookie_val, calc_checksum(cookie_val, length=10)])

        self.raw_request.COOKIES[ECOOKIE['NAME']] = expected_cookie[:-1]
        self.mi.process_response(self.raw_request, self.raw_response)

        assert ECOOKIE['INVALID'] in str(
            self.raw_response.cookies[ECOOKIE['NAME']])
Example #10
0
    def test_process_response_valid_cookie_valid_checksum_dont_set_cookie(
            self):
        #self.raw_request.entree_user = AnonymousUser()

        cookie_val = 'w/ checksum value'
        expected_cookie = COOKIE_CHECKSUM_SEPARATOR.join(
            [cookie_val, calc_checksum(cookie_val, length=10)])

        self.raw_request.COOKIES[ECOOKIE['NAME']] = expected_cookie
        self.mi.process_response(self.raw_request, self.raw_response)

        assert_equals([], self.raw_response.cookies.keys())
Example #11
0
    def process_response(self, request, response):
        #TODO - update comment
        """
        check if login cookie exists
        if not, set anonymous (readable by JS) and do nothing
        if anonymous cookie already set, do nothing
        if user cookie set, check is user is valid
        """
        try:
            token_cookie = request.COOKIES[ECOOKIE['NAME']]
        except KeyError:
            invalid = request.entree_user.__class__ is InvalidUser
            self._set_anonymous_cookie(response, invalid)
            return response

        if token_cookie in (ECOOKIE['ANONYMOUS_VALUE'], ECOOKIE['INVALID']):
            return response

        try:
            token, checksum = token_cookie.split(COOKIE_CHECKSUM_SEPARATOR)
        except ValueError:
            token = token_cookie
            checksum = calc_checksum(token, length=COOKIE_CHECKSUM_LENGTH)
            new_val = COOKIE_CHECKSUM_SEPARATOR.join((token, checksum))

            response.set_cookie(key=ECOOKIE['NAME'],
                                value=new_val,
                                path=ECOOKIE['PATH'],
                                domain=ECOOKIE['DOMAIN'],
                                httponly=True)

        else:
            expected_checksum = calc_checksum(token,
                                              length=COOKIE_CHECKSUM_LENGTH)
            if expected_checksum != checksum:
                if ECOOKIE['NAME'] in request.COOKIES:
                    del request.COOKIES[ECOOKIE['NAME']]
                self._set_anonymous_cookie(response, invalid=True)

        return response
Example #12
0
    def test_next_url_overriden_queue_next_url(self, patched_render):

        site = EntreeSite.objects.create(pk=ENTREE['SITE_ID'])

        url = '/foo/'
        next_url = b64encode("%s:%s" % (url, calc_checksum(url, length=SHORT_CHECK) ) )

        self.mixin.entree_login(self.user, site_id=site.pk, next_url=next_url)

        args, kwargs = patched_render.call_args
        template, context = args

        assert_equals(context['next_url'], reverse('profile_edit', kwargs={'site_id': site.pk, 'next_url': next_url}))
Example #13
0
    def test_edit_profile_form_valid_next_url_redirect_there(self):
        self.request.entree_user = self.user
        self.request.method = "POST"
        self.request.POST = {}

        next_url = "/foo/"
        checked_url = "%s:%s" % (next_url, calc_checksum(next_url, salt=self.valid_site.secret, length=SHORT_CHECK))

        ViewClass = csrf_exempt(ProfileEdit.as_view())
        res = ViewClass(self.request, site_id=self.valid_site.pk, next_url=b64encode(checked_url))

        location = "%s%s" % (self.valid_site.url, next_url)

        assert_equals(res["Location"], location)
Example #14
0
    def process_response(self, request, response):
        #TODO - update comment
        """
        check if login cookie exists
        if not, set anonymous (readable by JS) and do nothing
        if anonymous cookie already set, do nothing
        if user cookie set, check is user is valid
        """
        try:
            token_cookie = request.COOKIES[ECOOKIE['NAME']]
        except KeyError:
            invalid = request.entree_user.__class__ is InvalidUser
            self._set_anonymous_cookie(response, invalid)
            return response

        if token_cookie in (ECOOKIE['ANONYMOUS_VALUE'], ECOOKIE['INVALID']):
            return response

        try:
            token, checksum = token_cookie.split(COOKIE_CHECKSUM_SEPARATOR)
        except ValueError:
            token = token_cookie
            checksum = calc_checksum(token, length=COOKIE_CHECKSUM_LENGTH)
            new_val = COOKIE_CHECKSUM_SEPARATOR.join((token, checksum))

            response.set_cookie(key=ECOOKIE['NAME'], value=new_val,
                                path=ECOOKIE['PATH'],
                                domain=ECOOKIE['DOMAIN'], httponly=True)

        else:
            expected_checksum = calc_checksum(token, length=COOKIE_CHECKSUM_LENGTH)
            if expected_checksum != checksum:
                if ECOOKIE['NAME'] in request.COOKIES:
                    del request.COOKIES[ECOOKIE['NAME']]
                self._set_anonymous_cookie(response, invalid=True)

        return response
Example #15
0
    def test_next_url_active_profile_passed(self, patched_render):

        site = EntreeSite.objects.create(pk=ENTREE['SITE_ID'])

        profile = SiteProfile.objects.create(user=self.user, site=site, is_active=True)

        url = '/foo/'
        next_url = b64encode("%s:%s" % (url, calc_checksum(url, length=SHORT_CHECK) ) )

        self.mixin.entree_login(self.user, site_id=site.pk, next_url=next_url)

        args, kwargs = patched_render.call_args
        template, context = args

        assert_equals(context['next_url'], url)
Example #16
0
def get_next_url(origin_site, next_url=None):
    try:
        site = EntreeSite.objects.get(pk=int(origin_site))
    except (EntreeSite.DoesNotExist, TypeError):
        return reverse('profile')

    try:
        url = b64decode(next_url)
        valid_url, checksum = url.split(':')
    except (KeyError, DecodeError, ValueError, TypeError):
        valid_url = ''
    else:
        if checksum != calc_checksum(valid_url, salt=site.secret, length=SHORT_CHECK):
            valid_url = ''

    return "%s/%s" % (site.url.rstrip('/'), valid_url.lstrip('/'))
Example #17
0
def get_next_url(origin_site, next_url=None):
    try:
        site = EntreeSite.objects.get(pk=int(origin_site))
    except (EntreeSite.DoesNotExist, TypeError):
        return reverse('profile')

    try:
        url = b64decode(next_url)
        valid_url, checksum = url.split(':')
    except (KeyError, DecodeError, ValueError, TypeError):
        valid_url = ''
    else:
        if checksum != calc_checksum(valid_url, salt=site.secret, length=SHORT_CHECK):
            valid_url = ''

    return "%s/%s" % (site.url.rstrip('/'), valid_url.lstrip('/'))
Example #18
0
    def fetch(self, raw_key):
        from entree.client.models import EntreeUser

        try:
            token, inner_checksum = raw_key.split(COOKIE_CHECKSUM_SEPARATOR)
        except ValueError:
            token = raw_key
        else:
            if inner_checksum != calc_checksum(token, length=SHORT_CHECK):
                raise InvalidAuth("Invalid cookie checksum")

        try:
            user = EntreeUser.objects.get_cached(token)
        except EntreeUser.DoesNotExist:
            user = self.perform_fetch(token)

        return user
Example #19
0
    def fetch(self, raw_key):
        from entree.client.models import EntreeUser

        try:
            token, inner_checksum = raw_key.split(COOKIE_CHECKSUM_SEPARATOR)
        except ValueError:
            token = raw_key
        else:
            if inner_checksum != calc_checksum(token, length=SHORT_CHECK):
                raise InvalidAuth("Invalid cookie checksum")

        try:
            user = EntreeUser.objects.get_cached(token)
        except EntreeUser.DoesNotExist:
            user = self.perform_fetch(token)

        return user
Example #20
0
    def test_next_url_active_profile_passed(self, patched_render):

        site = EntreeSite.objects.create(pk=ENTREE['SITE_ID'])

        profile = SiteProfile.objects.create(user=self.user,
                                             site=site,
                                             is_active=True)

        url = '/foo/'
        next_url = b64encode("%s:%s" %
                             (url, calc_checksum(url, length=SHORT_CHECK)))

        self.mixin.entree_login(self.user, site_id=site.pk, next_url=next_url)

        args, kwargs = patched_render.call_args
        template, context = args

        assert_equals(context['next_url'], url)
Example #21
0
    def create_token(self, token_type=DEFAULT_TOKEN, extra_data='{}'):
        """
        Helper for creating LoginToken for given Identity

        @type token_type:   string
        @param token_type:  type of token to create, should be listed in TOKEN_TYPES
        @type extra_data:   dict
        @param extra_data:  custom extra data to store in LoginToken.extra_data

        @rtype:     LoginToken
        @return:    LoginToken w/ data based on input
        """
        if token_type not in dict(TOKEN_TYPES).keys():
            raise ValueError("Unable to create token, unknown type")

        value = calc_checksum(self.email, salt=randint(0, maxint))

        return LoginToken.objects.create(user=self, value=value, token_type=token_type, extra_data=extra_data)
Example #22
0
    def test_edit_profile_form_valid_next_url_redirect_there(self):
        self.request.entree_user = self.user
        self.request.method = 'POST'
        self.request.POST = {}

        next_url = '/foo/'
        checked_url = "%s:%s" % (next_url,
                                 calc_checksum(next_url,
                                               salt=self.valid_site.secret,
                                               length=SHORT_CHECK))

        ViewClass = csrf_exempt(ProfileEdit.as_view())
        res = ViewClass(self.request,
                        site_id=self.valid_site.pk,
                        next_url=b64encode(checked_url))

        location = "%s%s" % (self.valid_site.url, next_url)

        assert_equals(res['Location'], location)
Example #23
0
    def test_next_url_overriden_queue_next_url(self, patched_render):

        site = EntreeSite.objects.create(pk=ENTREE['SITE_ID'])

        url = '/foo/'
        next_url = b64encode("%s:%s" %
                             (url, calc_checksum(url, length=SHORT_CHECK)))

        self.mixin.entree_login(self.user, site_id=site.pk, next_url=next_url)

        args, kwargs = patched_render.call_args
        template, context = args

        assert_equals(
            context['next_url'],
            reverse('profile_edit',
                    kwargs={
                        'site_id': site.pk,
                        'next_url': next_url
                    }))
Example #24
0
    def create_token(self, token_type=DEFAULT_TOKEN, app_data=None):
        """
        Helper for creating LoginToken for given Identity

        @type token_type:   string
        @param token_type:  type of token to create, should be listed in TOKEN_TYPES
        @type app_data:   dict
        @param app_data:  custom extra data to store in LoginToken.app_data

        @rtype:     LoginToken
        @return:    LoginToken based on input data
        """
        app_data = app_data or {}
        if token_type not in dict(TOKEN_TYPES).keys():
            raise ValueError("Unable to create token, unknown type")

        value = calc_checksum(self.email, salt=randint(0, maxint))

        token = LoginToken.objects.create(user=self, value=value, token_type=token_type)
        if app_data:
            token.app_data = app_data
        return token
Example #25
0
 def test_bad_checksum_raises(self):
     cookie_val = 'w/ checksum value'
     invalid_cookie = COOKIE_CHECKSUM_SEPARATOR.join(
         [cookie_val, calc_checksum(cookie_val, length=10)])[:-1]
     assert_raises(InvalidAuth, self.fetcher.fetch, invalid_cookie)
Example #26
0
def enchecksum(text):
    return calc_checksum(text, length=SHORT_CHECK)
 def test_bad_checksum_raises(self):
     cookie_val = 'w/ checksum value'
     invalid_cookie = COOKIE_CHECKSUM_SEPARATOR.join([cookie_val, calc_checksum(cookie_val, length=10)])[:-1]
     assert_raises(InvalidAuth, self.fetcher.fetch, invalid_cookie)
Example #28
0
    def test_token_checksum(self):
        token = 'foo'
        salt = 'bar'
        res = calc_checksum(token, salt)

        assert_equals(res, sha1(token + salt).hexdigest().upper())
Example #29
0
    def test_token_checksum(self):
        token = 'foo'
        salt = 'bar'
        res = calc_checksum(token, salt)

        assert_equals(res, sha1(token + salt).hexdigest().upper())
Example #30
0
def enchecksum(text):
    return calc_checksum(text, length=SHORT_CHECK)
Example #31
0
 def test_next_url_invalid_checksum_return_root(self):
     url = '/foo/'
     next_url = b64encode("%s:%sINVALID" % (url, calc_checksum(url, length=SHORT_CHECK) ) )
     ret = get_next_url(self.valid_site.pk, next_url)
     assert_equals(ret.rstrip('/'), self.valid_site.url.rstrip('/'))
Example #32
0
 def test_next_url_valid_checksum_return_input_url(self):
     url = '/foo/'
     next_url = b64encode("%s:%s" % (url, calc_checksum(url, length=SHORT_CHECK) ) )
     ret = get_next_url(self.valid_site.pk, next_url)
     assert_equals(ret, "%s%s" % (self.valid_site.url, url))