Skip to content

Commit

Permalink
Merge pull request #57 from OnroerendErfgoed/DEV_0.7.0
Browse files Browse the repository at this point in the history
Dev 0.7.0
  • Loading branch information
claeyswo committed Feb 7, 2019
2 parents f1eac4a + 28210b5 commit c6ee4ba
Show file tree
Hide file tree
Showing 5 changed files with 236 additions and 71 deletions.
6 changes: 6 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
0.7.0 (29-01-2019)
------------------

- Better matching on Accept headers (#18)
- Nieuwe protected decorator toevoegen die de request niet uit de parent haalt maar rechtstreeks (#50)

0.6.0 (2017-06-08)
------------------

Expand Down
2 changes: 2 additions & 0 deletions pyramid_urireferencer/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
)
from zope.interface import Interface

from pyramid_urireferencer import protected_resources
from .referencer import Referencer
from .renderers import json_renderer

Expand All @@ -17,6 +18,7 @@ def includeme(config):
"""this function adds some configuration for the application"""
config.add_route('references', '/references')
_add_referencer(config.registry)
config.add_view_deriver(protected_resources.protected_view)
config.add_renderer('json_item', json_renderer)
config.scan()

Expand Down
169 changes: 108 additions & 61 deletions pyramid_urireferencer/protected_resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
that might be used in external applications.
.. versionadded:: 0.4.0
"""
import functools
import logging

from pyramid.httpexceptions import (
Expand All @@ -16,6 +17,69 @@
log = logging.getLogger(__name__)


def _advice(request):
referencer = pyramid_urireferencer.get_referencer(request.registry)
uri = referencer.get_uri(request)
registery_response = referencer.is_referenced(uri)
if registery_response.has_references:
if 'application/json' in request.accept:
response = Response()
response.status_code = 409
response_json = {
"message": "The uri {0} is still in use by other applications. "
"A total of {1} references have been found.".format(uri, registery_response.count),
"errors": [],
"registry_response": registery_response.to_json()
}
for app_response in registery_response.applications:
if app_response.has_references:
error_string = "{0}: {1} references found, such as {2}" \
.format(app_response.uri,
app_response.count,
', '.join([i.uri for i in app_response.items]))
response_json["errors"].append(error_string)
response.json_body = response_json
response.content_type = 'application/json'
return response
else:
raise HTTPConflict(
detail="Urireferencer: The uri {0} is still in use by other applications. "
"A total of {1} references have been found "
"in the following applications: {2}".format(uri, registery_response.count,
', '.join([app_response.title for app_response in
registery_response.applications
if app_response.has_references])))
elif not registery_response.success:
if 'application/json' in request.accept:
response = Response()
response.status_code = 500
response_json = {
"message": "Unable to verify the uri {0} is no longer being used.".format(uri),
"errors": [],
"registry_response": registery_response.to_json()
}
for app_response in registery_response.applications:
if not app_response.success:
response_json["errors"].append(
"{}: Could not verify the uri is no longer being used.".format(app_response.uri))
response.json_body = response_json
response.content_type = 'application/json'
return response
else:
log.error("Urireferencer: Unable to verify the uri {0} is no longer being used. "
"Could not verify with {1}".format(uri, ', '
.join(["{0} ({1})".format(app_response.uri,
app_response.service_url)
for app_response
in registery_response.applications if
not app_response.success])))
raise HTTPInternalServerError(
detail="Urireferencer: Unable to verify the uri {0} is no longer being used. "
"Could not verify with {1}".format(uri, ', '.join([app_response.uri for app_response
in registery_response.applications if
not app_response.success])))


def protected_operation(fn):
"""
Use this decorator to prevent an operation from being executed
Expand All @@ -28,68 +92,51 @@ def protected_operation(fn):
:raises pyramid.httpexceptions.HTTPInternalServerError: Raised when we were
unable to check that the URI is no longer being used.
"""

@functools.wraps(fn)
def advice(parent_object, *args, **kw):
referencer = pyramid_urireferencer.get_referencer(parent_object.request.registry)
uri = referencer.get_uri(parent_object.request)
registery_response = referencer.is_referenced(uri)
if registery_response.has_references:
if parent_object.request.headers.get("Accept", None) == "application/json":
response = Response()
response.status_code = 409
response_json = {
"message": "The uri {0} is still in use by other applications. "
"A total of {1} references have been found.".format(uri, registery_response.count),
"errors": [],
"registry_response": registery_response.to_json()
}
for app_response in registery_response.applications:
if app_response.has_references:
error_string = "{0}: {1} references found, such as {2}" \
.format(app_response.uri,
app_response.count,
', '.join([i.uri for i in app_response.items]))
response_json["errors"].append(error_string)
response.json_body = response_json
response.content_type = 'application/json'
return response
else:
raise HTTPConflict(
detail="Urireferencer: The uri {0} is still in use by other applications. "
"A total of {1} references have been found "
"in the following applications: {2}".format(uri, registery_response.count,
', '.join([app_response.title for app_response in
registery_response.applications
if app_response.has_references])))
elif not registery_response.success:
if parent_object.request.headers.get("Accept", None) == "application/json":
response = Response()
response.status_code = 500
response_json = {
"message": "Unable to verify the uri {0} is no longer being used.".format(uri),
"errors": [],
"registry_response": registery_response.to_json()
}
for app_response in registery_response.applications:
if not app_response.success:
response_json["errors"].append(
"{}: Could not verify the uri is no longer being used.".format(app_response.uri))
response.json_body = response_json
response.content_type = 'application/json'
response = _advice(parent_object.request)
if response is not None:
return response
else:
return fn(parent_object, *args, **kw)

return advice


def protected_operation_with_request(fn):
"""
Use this decorator to prevent an operation from being executed
when the related uri resource is still in use.
The request must contain a registry.queryUtility(IReferencer)
:raises pyramid.httpexceptions.HTTPConflict: Signals that we don't want to
delete a certain URI because it's still in use somewhere else.
:raises pyramid.httpexceptions.HTTPInternalServerError: Raised when we were
unable to check that the URI is no longer being used.
"""

@functools.wraps(fn)
def wrapped(request, *args, **kwargs):
response = _advice(request)
if response is not None:
return response
else:
return fn(request, *args, **kwargs)

return wrapped


def protected_view(view, info):
"""allows adding `protected=True` to a view_config`"""

if info.options.get('protected'):
def wrapper_view(context, request):
response = _advice(request)
if response is not None:
return response
else:
log.error("Urireferencer: Unable to verify the uri {0} is no longer being used. "
"Could not verify with {1}".format(uri, ', '
.join(["{0} ({1})".format(app_response.uri,
app_response.service_url)
for app_response
in registery_response.applications if
not app_response.success])))
raise HTTPInternalServerError(
detail="Urireferencer: Unable to verify the uri {0} is no longer being used. "
"Could not verify with {1}".format(uri, ', '.join([app_response.uri for app_response
in registery_response.applications if
not app_response.success])))
return fn(parent_object, *args, **kw)
return view(context, request)
return wrapper_view
return view

return advice

protected_view.options = ('protected',)
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
CHANGES = f.read()

setup(name='pyramid_urireferencer',
version='0.6.0',
version='0.7.0',
description='A pyramid plugin to handle referencing external URIs.',
long_description=README + '\n\n' + CHANGES,
classifiers=[
Expand Down
Loading

0 comments on commit c6ee4ba

Please sign in to comment.