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
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)
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, ))
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,))
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)
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)
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))
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))
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))
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)
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)
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)
def wrapped(resource, *args): auth = resource_auth(resource) if isinstance(auth, AmivTokenAuth): func(auth, resource, *args) # Add auth to function arguments