# Path: opennode/oms/endpoint/httprest/base.py
# class IHttpRestView(Interface):
#     def render(request):
#         pass
# 
#     def render_recursive(request, depth):
#         pass
# 
#     def rw_transaction(request):
#         """Return true if we this request should be committed"""
# 
# class IHttpRestSubViewFactory(Interface):
#     def resolve(path, method):
#         """Resolve a view for a given sub path"""
# 
# Path: opennode/oms/model/traversal.py
# def traverse_path(obj, path):
#     """Starting from the given object, traverses all its descendant
#     objects to find an object that matches the given path.
# 
#     Returns a tuple that contains the object up to which the traversal
#     was successful plus all objects that led to that object, and the
#     part of the path that could not be resolved.
# 
#     """
#     path = parse_path(path)
# 
#     if not path:
#         return [obj], []
# 
#     ret = [obj]
#     while path:
#         name = path[0]
#         try:
#             traverser = ITraverser(ret[-1])
#         except TypeError:
#             break
# 
#         next_obj = follow_symlinks(traverser.traverse(name))
# 
#         if not next_obj:
#             break
# 
#         ret.append(next_obj)
#         path = path[1:]
# 
#     return ret[1:], path
# 
# Path: opennode/oms/security/checker.py
# def proxy_factory(value, interaction):
#     if type(value) is Proxy:
#         return value
#     # ignore proxies on deferreds
#     if isinstance(value, Deferred):
#         return value
# 
#     return Proxy(value, _select_checker(value, interaction))
# 
# Path: opennode/oms/security/interaction.py
# def new_interaction(principal):
#     if not IPrincipal.providedBy(principal):
#         auth = getUtility(IAuthentication, context=None)
#         principal = auth.getPrincipal(principal)
# 
#     interaction = OmsSecurityPolicy()
#     interaction.add(SessionStub(principal))
#     return interaction
# 
# Path: opennode/oms/util.py
# def blocking_yield(deferred, timeout=None):
#     """This utility is part of the HDK (hack development toolkit) use with care and remove its usage asap.
# 
#     Sometimes we have to synchronously wait for a deferred to complete,
#     for example when executing inside db.transact code, which cannot 'yield'
#     because currently db.transact doesn't handle returning a deferred.
# 
#     Or because we are running code inside a handler which cannot return a deferred
#     otherwise we cannot block the caller or rollback the transaction in case of async code
#     throwing exception (scenario: we want to prevent deletion of node)
# 
#     Use this utility only until you refactor the upstream code in order to use pure async code.
#     """
# 
#     q = Queue()
#     deferred.addBoth(q.put)
#     try:
#         ret = q.get(True, timeout or 100)
#     except Empty:
#         raise defer.TimeoutError
#     if isinstance(ret, Failure):
#         ret.raiseException()
#     else:
#         return ret
# 
# Path: opennode/oms/util.py
# class JsonSetEncoder(json.JSONEncoder):
#     def default(self, obj):
#         if isinstance(obj, set):
#             return list(obj)
#         if hasattr(obj, '__str__'):
#             return str(obj)
#         return json.JSONEncoder.default(self, obj)


import functools
import json
import zope.security.interfaces
from twisted.internet import defer
from twisted.python import log, failure
from twisted.web import resource
from twisted.web.server import NOT_DONE_YET
from twisted.python.compat import intToBytes
from zope.component import queryAdapter, getUtility
from opennode.oms.config import get_config
from opennode.oms.endpoint.httprest.base import IHttpRestView, IHttpRestSubViewFactory
from opennode.oms.model.traversal import traverse_path
from opennode.oms.security.checker import proxy_factory
from opennode.oms.security.interaction import new_interaction
from opennode.oms.util import blocking_yield
from opennode.oms.util import JsonSetEncoder
from opennode.oms.zodb import db
        from opennode.oms.endpoint.httprest.auth import IHttpRestAuthenticationUtility
                from opennode.oms.endpoint.httprest.auth import IHttpRestAuthenticationUtility
        from opennode.oms.endpoint.httprest.auth import IHttpRestAuthenticationUtility
            else:
                request.write("%s %s\n" % (exc.status_code, exc.status_description))
            if exc.message:
                request.write("%s\n" % exc.message)
        except Exception:
            request.setHeader('Content-Type', 'text/plain')
            request.setResponseCode(500, "Server Error")
            error_message = "%s %s\n\n" % (500, "Server Error")
            request.setHeader('Content-Length', intToBytes(len(error_message)))
            request.write(error_message)
            log.err(system='httprest')
            failure.Failure().printTraceback(request)
        finally:
            if ret is not NOT_DONE_YET:
                request.finish()

    def get_token(self, request):

        authenticator = getUtility(IHttpRestAuthenticationUtility)

        # XXX: The following is not composable
        http_credentials = authenticator.get_basic_auth_credentials(request)
        # check if keystone token is set, if we support it
        keystone_token = authenticator.get_keystone_auth_credentials(request) \
                            if self.use_keystone_tokens else None
        if http_credentials:
            blocking_yield(authenticator.authenticate(request, http_credentials,
                                                      basic_auth=True))
            return authenticator.generate_token(http_credentials)
        elif keystone_token:

# Path: opennode/oms/endpoint/httprest/base.py
# class IHttpRestView(Interface):
#     def render(request):
#         pass
# 
#     def render_recursive(request, depth):
#         pass
# 
#     def rw_transaction(request):
#         """Return true if we this request should be committed"""
# 
# class IHttpRestSubViewFactory(Interface):
#     def resolve(path, method):
#         """Resolve a view for a given sub path"""
# 
# Path: opennode/oms/model/traversal.py
# def traverse_path(obj, path):
#     """Starting from the given object, traverses all its descendant
#     objects to find an object that matches the given path.
# 
#     Returns a tuple that contains the object up to which the traversal
#     was successful plus all objects that led to that object, and the
#     part of the path that could not be resolved.
# 
#     """
#     path = parse_path(path)
# 
#     if not path:
#         return [obj], []
# 
#     ret = [obj]
#     while path:
#         name = path[0]
#         try:
#             traverser = ITraverser(ret[-1])
#         except TypeError:
#             break
# 
#         next_obj = follow_symlinks(traverser.traverse(name))
# 
#         if not next_obj:
#             break
# 
#         ret.append(next_obj)
#         path = path[1:]
# 
#     return ret[1:], path
# 
# Path: opennode/oms/security/checker.py
# def proxy_factory(value, interaction):
#     if type(value) is Proxy:
#         return value
#     # ignore proxies on deferreds
#     if isinstance(value, Deferred):
#         return value
# 
#     return Proxy(value, _select_checker(value, interaction))
# 
# Path: opennode/oms/security/interaction.py
# def new_interaction(principal):
#     if not IPrincipal.providedBy(principal):
#         auth = getUtility(IAuthentication, context=None)
#         principal = auth.getPrincipal(principal)
# 
#     interaction = OmsSecurityPolicy()
#     interaction.add(SessionStub(principal))
#     return interaction
# 
# Path: opennode/oms/util.py
# def blocking_yield(deferred, timeout=None):
#     """This utility is part of the HDK (hack development toolkit) use with care and remove its usage asap.
# 
#     Sometimes we have to synchronously wait for a deferred to complete,
#     for example when executing inside db.transact code, which cannot 'yield'
#     because currently db.transact doesn't handle returning a deferred.
# 
#     Or because we are running code inside a handler which cannot return a deferred
#     otherwise we cannot block the caller or rollback the transaction in case of async code
#     throwing exception (scenario: we want to prevent deletion of node)
# 
#     Use this utility only until you refactor the upstream code in order to use pure async code.
#     """
# 
#     q = Queue()
#     deferred.addBoth(q.put)
#     try:
#         ret = q.get(True, timeout or 100)
#     except Empty:
#         raise defer.TimeoutError
#     if isinstance(ret, Failure):
#         ret.raiseException()
#     else:
#         return ret
# 
# Path: opennode/oms/util.py
# class JsonSetEncoder(json.JSONEncoder):
#     def default(self, obj):
#         if isinstance(obj, set):
#             return list(obj)
#         if hasattr(obj, '__str__'):
#             return str(obj)
#         return json.JSONEncoder.default(self, obj)


# Path: opennode/oms/endpoint/httprest/root.py
import functools
import json
import zope.security.interfaces
from twisted.internet import defer
from twisted.python import log, failure
from twisted.web import resource
from twisted.web.server import NOT_DONE_YET
from twisted.python.compat import intToBytes
from zope.component import queryAdapter, getUtility
from opennode.oms.config import get_config
from opennode.oms.endpoint.httprest.base import IHttpRestView, IHttpRestSubViewFactory
from opennode.oms.model.traversal import traverse_path
from opennode.oms.security.checker import proxy_factory
from opennode.oms.security.interaction import new_interaction
from opennode.oms.util import blocking_yield
from opennode.oms.util import JsonSetEncoder
from opennode.oms.zodb import db
        from opennode.oms.endpoint.httprest.auth import IHttpRestAuthenticationUtility
                from opennode.oms.endpoint.httprest.auth import IHttpRestAuthenticationUtility
        from opennode.oms.endpoint.httprest.auth import IHttpRestAuthenticationUtility

            else:
                request.write("%s %s\n" % (exc.status_code, exc.status_description))
            if exc.message:
                request.write("%s\n" % exc.message)
        except Exception:
            request.setHeader('Content-Type', 'text/plain')
            request.setResponseCode(500, "Server Error")
            error_message = "%s %s\n\n" % (500, "Server Error")
            request.setHeader('Content-Length', intToBytes(len(error_message)))
            request.write(error_message)
            log.err(system='httprest')
            failure.Failure().printTraceback(request)
        finally:
            if ret is not NOT_DONE_YET:
                request.finish()

    def get_token(self, request):

        authenticator = getUtility(IHttpRestAuthenticationUtility)

        # XXX: The following is not composable
        http_credentials = authenticator.get_basic_auth_credentials(request)
        # check if keystone token is set, if we support it
        keystone_token = authenticator.get_keystone_auth_credentials(request) \
                            if self.use_keystone_tokens else None
        if http_credentials:
            blocking_yield(authenticator.authenticate(request, http_credentials,
                                                      basic_auth=True))
            return authenticator.generate_token(http_credentials)
        elif keystone_token:

            keystone_credential = blocking_yield(authenticator.authenticate_keystone(request,