'Given a set of authorizable Sentry objects and a requested action, return a filtered set of objects that the user
has privileges to perform the given action upon.
:param objects: a list of objects that can be converted to Sentry authorizables using the key function;
objects should be converted to either V1 or V2 authorizables that utilize the following format:
V1 - {\'column\': \'total_emp\', \'table\': \'sample_08\', \'db\': \'default\', \'server\': \'server1\', \'URI\': None}
V2 - {\'component\': \'solr\', \'serviceName\': \'server1\', \'type\': \'COLLECTION\', \'name\': \'twitter_demo\', \'URI\': None}
:param action: requested action-level that we should check privileges against (default: READ)
:param key: a function that will be applied to each object in the objects iterable to convert it to a Sentry format'

def filter_objects(self, objects, action='READ', key=(lambda x: x.copy())):

    action = action.upper()
    object_authorizables = self._to_sentry_authorizables(objects=objects, key=key)
    v1_authorizables = [(obj, auth) for (obj, auth) in object_authorizables if ('db' in auth)]
    v2_authorizables = [(obj, auth) for (obj, auth) in object_authorizables if ('component' in auth)]
    if v1_authorizables:
        for (object, authorizable) in v1_authorizables:
            if self._is_object_action_authorized_v1(hierarchy=self.privilege_hierarchy_v1, object=authorizable, action=action):
                (yield object)
    if v2_authorizables:
        for (object, authorizable) in v2_authorizables:
            if self._is_object_action_authorized_v2(hierarchy=self.privilege_hierarchy_v2, object=authorizable, action=action):
                (yield object)
