Esempio n. 1
0
    def current_mongo_prefix(self, resource=None):
        """ Returns the active mongo_prefix that should be used to retrieve
        a valid PyMongo instance from the cache. If 'self.mongo_prefix' is set
        it has precedence over both endpoint (resource) and default drivers.
        This allows Auth classes (for instance) to override default settings to
        use a user-reserved db instance.

        :param resource: endpoint for which a mongo prefix is needed.

        ..versionadded:: 0.6
        """

        # the hack below avoids passing the resource around, which would not be
        # an issue within this module but would force an update to the
        # eve.io.media.MediaStorage interface, possibly breaking compatibility
        # for other database implementations.

        auth = None
        try:
            if resource is None and request and request.endpoint:
                resource = request.endpoint[:request.endpoint.index('|')]
            if request and request.endpoint:
                auth = resource_auth(resource)
        except ValueError:
            pass

        px = auth.get_mongo_prefix() if auth else None
        if px is None:
            if resource:
                px = config.DOMAIN[resource].get('mongo_prefix', 'MONGO')
            else:
                px = 'MONGO'
        return px
Esempio n. 2
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)
Esempio n. 3
0
    def current_mongo_prefix(self, resource=None):
        """ Returns the active mongo_prefix that should be used to retrieve
        a valid PyMongo instance from the cache. If 'self.mongo_prefix' is set
        it has precedence over both endpoint (resource) and default drivers.
        This allows Auth classes (for instance) to override default settings to
        use a user-reserved db instance.

        :param resource: endpoint for which a mongo prefix is needed.

        ..versionadded:: 0.6
        """

        # the hack below avoids passing the resource around, which would not be
        # an issue within this module but would force an update to the
        # eve.io.media.MediaStorage interface, possibly breaking compatibility
        # for other database implementations.

        auth = None
        try:
            if resource is None and request and request.endpoint:
                resource = request.endpoint[:request.endpoint.index('|')]
            if request and request.endpoint:
                auth = resource_auth(resource)
        except ValueError:
            pass

        px = auth.get_mongo_prefix() if auth else None
        if px is None:
            if resource:
                px = config.DOMAIN[resource].get('mongo_prefix', 'MONGO')
            else:
                px = 'MONGO'
        return px
Esempio n. 4
0
def schema_collection_endpoint():
    """ This endpoint is active when SCHEMA_ENDPOINT != None. It returns the
    schema definition for all public or request authenticated resources in
    JSON format.
    """
    schemas = {}
    for resource_name, resource_config in app.config["DOMAIN"].items():
        # skip versioned shadow collections
        if resource_name.endswith(config.VERSIONS):
            continue
        # skip internal resources
        internal = resource_config.get("internal_resource", False)
        if internal:
            continue
        # skip resources for which request does not have read authorization
        auth = resource_auth(resource_name)
        if auth and request.method not in resource_config["public_methods"]:
            roles = list(resource_config["allowed_roles"])
            roles += resource_config["allowed_read_roles"]
            if not auth.authorized(roles, resource_name, request.method):
                continue
        # otherwise include this resource in domain wide schema response
        schemas[resource_name] = resource_config["schema"]

    return send_response(None, (schemas, ))
Esempio n. 5
0
def schema_collection_endpoint():
    """ This endpoint is active when SCHEMA_ENDPOINT != None. It returns the
    schema definition for all public or request authenticated resources in
    JSON format.
    """
    schemas = {}
    for resource_name, resource_config in app.config['DOMAIN'].items():
        # skip versioned shadow collections
        if resource_name.endswith(config.VERSIONS):
            continue
        # skip internal resources
        internal = resource_config.get('internal_resource', False)
        if internal:
            continue
        # skip resources for which request does not have read authorization
        auth = resource_auth(resource_name)
        if auth and request.method not in resource_config['public_methods']:
            roles = list(resource_config['allowed_roles'])
            roles += resource_config['allowed_read_roles']
            if not auth.authorized(roles, resource_name, request.method):
                continue
        # otherwise include this resource in domain wide schema response
        schemas[resource_name] = resource_config['schema']

    return send_response(None, (schemas,))
Esempio n. 6
0
def add_permitted_methods_after_fetch_resource(resource, response):
    """Add link methods with an on_fetched_resource hook."""
    if isinstance(resource_auth(resource), AmivTokenAuth):
        # Item links
        for item in response['_items']:
            add_methods_to_item_links(resource, item)

        # Resource links
        add_methods_to_resource_links(resource, response)
Esempio n. 7
0
def add_permitted_methods_after_fetch_resource(resource, response):
    """Add link methods with an on_fetched_resource hook."""
    if isinstance(resource_auth(resource), AmivTokenAuth):
        # Item links
        for item in response['_items']:
            add_methods_to_item_links(resource, item)

        # Resource links
        add_methods_to_resource_links(resource, response)
Esempio n. 8
0
def add_permitted_methods_after_update(resource, request, response, payload):
    """Add link methods with an on_post_PATCH hook.

    The on_updated hook doesn't work since it doesn't include the links.

    This hook will also be called for errors which do not contain _links.
    => Make sure to only add methods for successful patches (status 200 only)
    """
    if isinstance(resource_auth(resource), AmivTokenAuth):
        add_methods_to_item_links(resource, payload)
Esempio n. 9
0
def _get_item_methods(resource, item):
    res = current_app.config['DOMAIN'][resource]
    user = g.get('current_user')  # TODO: post_internal_problem
    auth = resource_auth(resource)
    is_admin = g.get('resource_admin')

    # If the item is displayed, the read methods are obviously allowed
    methods = ['GET', 'HEAD', 'OPTIONS'] + res['public_item_methods']

    # Admins have access to all methods. For non admins check user permission.
    if is_admin or auth.has_item_write_permission(user, item):
        methods += res['item_methods']

    # Remove duplicates before returning
    return list(set(methods))
Esempio n. 10
0
def _get_item_methods(resource, item):
    res = current_app.config['DOMAIN'][resource]
    user = g.get('current_user')  # TODO: post_internal_problem
    auth = resource_auth(resource)
    is_admin = g.get('resource_admin')

    # If the item is displayed, the read methods are obviously allowed
    methods = ['GET', 'HEAD', 'OPTIONS'] + res['public_item_methods']

    # Admins have access to all methods. For non admins check user permission.
    if is_admin or auth.has_item_write_permission(user, item):
        methods += res['item_methods']

    # Remove duplicates before returning
    return list(set(methods))
Esempio n. 11
0
def _get_resource_methods(resource):
    res = current_app.config['DOMAIN'][resource]
    auth = resource_auth(resource)
    user = g.get('current_user')
    is_admin = g.get('resource_admin')

    # public methods and OPTIONS are always available
    methods = res['public_methods'] + ['OPTIONS']
    if 'GET' in methods:
        methods += ['HEAD']

    # resources may not have public read access, but we still can see the
    # resource on the home endpoint
    if user or is_admin or g.get('resource_admin_readonly'):
        methods += ['GET', 'HEAD']

    # write methods
    if is_admin or auth.has_resource_write_permission(user):
        methods += res['resource_methods']

    # Remove duplicates
    return list(set(methods))
Esempio n. 12
0
def _get_resource_methods(resource):
    res = current_app.config['DOMAIN'][resource]
    auth = resource_auth(resource)
    user = g.get('current_user')
    is_admin = g.get('resource_admin')

    # public methods and OPTIONS are always available
    methods = res['public_methods'] + ['OPTIONS']
    if 'GET' in methods:
        methods += ['HEAD']

    # read for users/admins
    user_read = user and (auth.create_user_lookup_filter(user) is not None)
    if user_read or is_admin or g.get('resource_admin_readonly'):
        methods += ['GET', 'HEAD']

    # write for users/admins
    if is_admin or (user and auth.has_resource_write_permission(user)):
        methods += res['resource_methods']

    # Remove duplicates
    return list(set(methods))
Esempio n. 13
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)
Esempio n. 14
0
def add_permitted_methods_after_fetch_item(resource, item):
    """Add link methods with an on_fetched_item hook."""
    if isinstance(resource_auth(resource), AmivTokenAuth):
        add_methods_to_item_links(resource, item)
Esempio n. 15
0
def add_permitted_methods_after_insert(resource, items):
    """Add link methods with an on_inserted hook."""
    if isinstance(resource_auth(resource), AmivTokenAuth):
        for item in items:
            add_methods_to_item_links(resource, item)
Esempio n. 16
0
 def wrapped(resource, *args):
     auth = resource_auth(resource)
     if isinstance(auth, AmivTokenAuth):
         func(auth, resource, *args)  # Add auth to function arguments
Esempio n. 17
0
def add_permitted_methods_after_fetch_item(resource, item):
    """Add link methods with an on_fetched_item hook."""
    if isinstance(resource_auth(resource), AmivTokenAuth):
        add_methods_to_item_links(resource, item)
Esempio n. 18
0
 def wrapped(resource, *args):
     auth = resource_auth(resource)
     if isinstance(auth, AmivTokenAuth):
         func(auth, resource, *args)  # Add auth to function arguments
Esempio n. 19
0
def add_permitted_methods_after_insert(resource, items):
    """Add link methods with an on_inserted hook."""
    if isinstance(resource_auth(resource), AmivTokenAuth):
        for item in items:
            add_methods_to_item_links(resource, item)