예제 #1
0
def add_permitted_methods_for_home(resource, request, response):
    """Add link methods to home endpoint with an on_post_GET hook.

    The home endpoint doesn't call any database hooks and no on_pre_GET hook.
    Therefore authentication needs to be done manually so we can check
    permissions.
    """
    if resource is None:
        authenticate()

        data = _get_data(response)

        try:
            links = data['_links']['child']
        except KeyError:
            # Other endpoints like `schemaendpoint` might end u here, but don't
            # have the same 'link' layout as home, so we can just ignore them
            pass
        else:
            # Add links for home
            for res_link in links:
                res_name = res_link['title']  # title equals resource
                if isinstance(resource_auth(res_name), AmivTokenAuth):
                    check_if_admin(res_name)
                    res_link['methods'] = _get_resource_methods(res_name)

            _set_data(response, data)
예제 #2
0
    def test_token_parsing_in_authentication(self):
        """Test all possible ways to send a token.

        1. As Basic Authorization header with token as user and no password
        2. As Authorization Header: 'Token <token>' (also lowercase)
        3. A Authorization Header: 'Bearer <token>' (also lowercase)
        4. Authorization header with only 'token'

        Also test that no or incomplete auth header results in
        `g.current_token = None`
        """
        # No Header
        with self.app.test_request_context():
            authenticate()
            self.assertIsNone(g.current_token)

        token = "ThisIsATokenYeahItIsTheContentDoesntReallyMatter"
        # Encoding dance for py 2/3 compatibility
        b64token = b64encode((token + ":").encode('utf-8')).decode('utf-8')

        # Header variations
        for header in (token, "Token " + token, "Bearer " + token,
                       "SomeotherKeyword " + token, "Basic " + b64token):

            with self.app.test_request_context(
                    headers={'Authorization': header}):
                # Call authenticate, the token should be found and put in g
                authenticate()
                self.assertEqual(g.current_token, token)
예제 #3
0
    def test_token_parsing_in_authentication(self):
        """Test all possible ways to send a token.

        1. As Basic Authorization header with token as user and no password
        2. As Authorization Header: 'Token <token>' (also lowercase)
        3. A Authorization Header: 'Bearer <token>' (also lowercase)
        4. Authorization header with only 'token'

        Also test that no or incomplete auth header results in
        `g.current_token = None`
        """
        # No Header
        with self.app.test_request_context():
            authenticate()
            self.assertIsNone(g.current_token)

        token = "ThisIsATokenYeahItIsTheContentDoesntReallyMatter"
        # Encoding dance for py 2/3 compatibility
        b64token = b64encode((token + ":").encode('utf-8')).decode('utf-8')

        # Header variations
        for header in (
                token,
                "Token " + token,
                "Bearer " + token,
                "SomeotherKeyword " + token,
                "Basic " + b64token):

            with self.app.test_request_context(
                    headers={'Authorization': header}):
                # Call authenticate, the token should be found and put in g
                authenticate()
                self.assertEqual(g.current_token, token)
예제 #4
0
    def test_session_lookup_in_authentication(self):
        """Test that sessions associated with a token are found correctly.

        If there is no session, `current_session` and `current_user` will be
        None, otherwise `current_session` will be the data as stored in the db
        and `current_user` the `user` field taken from the session.

        Also check that if a session is found the timestamp is updated
        """
        collection = self.db['sessions']
        # Provide everything for mongo, doesn't matter that we are not using
        # proper ObjectIds
        data = [{
            u'_id': u'a',
            u'user': ObjectId(24 * 'a'),
            u'token': u'sometoken',
            u'_updated': datetime.utcnow() - timedelta(seconds=1)
        }, {
            u'_id': u'b',
            u'user': ObjectId(24 * 'b'),
            u'token': u'othertoken',
            u'_updated': datetime.utcnow() - timedelta(seconds=1)
        }]

        # Put into db
        collection.insert_many(data)

        for session in data:
            with self.app.test_request_context(
                    headers={'Authorization': session['token']}):
                authenticate()

                # g.current_user shoudl be a string
                expected_user = str(session['user'])

                session_in_db = \
                    self.db['sessions'].find_one({'_id': session['_id']})
                self.assertEqual(g.current_session, session_in_db)

                for key in '_id', 'user', 'token':
                    self.assertEqual(g.current_session[key], session[key])
                self.assertEqual(g.current_user, expected_user)

                # Normally Eve would deal with timezones for us,
                # here we have to remove the tzinfo to be able to compare the
                # time (everything is utc anyways)
                g.current_session['_updated'] = \
                    g.current_session['_updated'].replace(tzinfo=None)
                self.assertGreater(g.current_session['_updated'],
                                   session['_updated'])
예제 #5
0
    def test_session_lookup_in_authentication(self):
        """Test that sessions associated with a token are found correctly.

        If there is no session, `current_session` and `current_user` will be
        None, otherwise `current_session` will be the data as stored in the db
        and `current_user` the `user` field taken from the session.

        Also check that if a session is found the timestamp is updated
        """
        collection = self.db['sessions']
        # Provide everything for mongo, doesn't matter that we are not using
        # proper ObjectIds
        data = [
            {u'_id': u'a',
             u'user': ObjectId(24 * 'a'),
             u'token': u'sometoken',
             u'_updated': datetime.utcnow() - timedelta(seconds=1)},
            {u'_id': u'b',
             u'user': ObjectId(24 * 'b'),
             u'token': u'othertoken',
             u'_updated': datetime.utcnow() - timedelta(seconds=1)}
        ]

        # Put into db
        collection.insert(data)

        for session in data:
            with self.app.test_request_context(
                    headers={'Authorization': session['token']}):
                authenticate()

                # g.current_user shoudl be a string
                expected_user = str(session['user'])

                session_in_db = \
                    self.db['sessions'].find_one({'_id': session['_id']})
                self.assertEqual(g.current_session, session_in_db)

                for key in '_id', 'user', 'token':
                    self.assertEqual(g.current_session[key], session[key])
                self.assertEqual(g.current_user, expected_user)

                # Normally Eve would deal with timezones for us,
                # here we have to remove the tzinfo to be able to compare the
                # time (everything is utc anyways)
                g.current_session['_updated'] = \
                    g.current_session['_updated'].replace(tzinfo=None)
                self.assertGreater(g.current_session['_updated'],
                                   session['_updated'])
예제 #6
0
    def test_authentication_defaults(self):
        """Make sure authenticate sets defaults for all auth values."""
        expect_none = 'current_token', 'current_user', 'current_session'
        expect_false = 'resource_admin', 'resource_admin_readonly'

        with self.app.test_request_context():
            # Nothing there before
            for item in expect_none + expect_false:
                with self.assertRaises(AttributeError):
                    getattr(g, item)

            authenticate()
            for item in expect_none:
                self.assertIsNone(getattr(g, item))

            check_if_admin('someresource')
            for item in expect_false:
                self.assertFalse(getattr(g, item))
예제 #7
0
    def test_authentication_defaults(self):
        """Make sure authenticate sets defaults for all auth values."""
        expect_none = 'current_token', 'current_user', 'current_session'
        expect_false = 'resource_admin', 'resource_admin_readonly'

        with self.app.test_request_context():
            # Nothing there before
            for item in expect_none + expect_false:
                with self.assertRaises(AttributeError):
                    getattr(g, item)

            authenticate()
            for item in expect_none:
                self.assertIsNone(getattr(g, item))

            check_if_admin('someresource')
            for item in expect_false:
                self.assertFalse(getattr(g, item))
예제 #8
0
def add_permitted_methods_for_home(resource, request, response, payload):
    """Add link methods to home endpoint with an on_post_GET hook.

    The home endpoint doesn't call any database hooks and no on_pre_GET hook.
    Therefore authentication needs to be done manually so we can check
    permissions.
    """
    if resource is None:
        authenticate()

        try:
            links = payload['_links']['child']
        except KeyError:
            # Other endpoints like `schemaendpoint` end up here, but don't
            # have the same 'link' layout as home, so we can just ignore them
            pass
        else:
            # Add links for home
            for res_link in links:
                res_name = res_link['href']  # href equals resource
                if isinstance(resource_auth(res_name), AmivTokenAuth):
                    check_if_admin(res_name)
                    res_link['methods'] = _get_resource_methods(res_name)