def create_issuing_service( reactor: IReactorTCP, acme_url: str, account_key_file: str, well_known_resource: IResource, ) -> AcmeIssuingService: """Create an ACME issuing service, and attach it to a web Resource Args: reactor: twisted reactor acme_url: URL to use to request certificates account_key_file: where to store the account key well_known_resource: web resource for .well-known. we will attach a child resource for "acme-challenge". Returns: AcmeIssuingService """ responder = HTTP01Responder() well_known_resource.putChild(b"acme-challenge", responder.resource) store = ErsatzStore() return AcmeIssuingService( cert_store=store, client_creator=(lambda: Client.from_url( reactor=reactor, url=URL.from_text(acme_url), key=load_or_create_client_key(account_key_file), alg=RS256, )), clock=reactor, responders=[responder], )
def test_adaptation(self): """ Test that the Collection class can be adapted to an IResource. """ collection = base.Collection() self.assertTrue(ICollection.providedBy(collection)) self.assertTrue(IResource.providedBy(IResource(collection)))
def test_wrapResourceWeb(self): if not getTwistedWeb(): raise SkipTest("This test requires both twisted.web.") from twisted.web.resource import IResource, Resource root = Resource() wrapped = wrapResource(root, [self.checker]) self.assertTrue(IResource.providedBy(wrapped))
def getChild(self, path, request): """ Gets the resource for an element in the collection for this resource. If this is a DELETE request addressing an element this collection, deletes the child. If it is a PUT request addressing an element in this collection which does not exist yet, creates an element accessible at the request path. Otherwise, attempts to return the resource for the appropriate addressed child, by accessing that child and attempting to adapt it to ``IResource``. If that child could not be found, (unless it is being created, of course), returns an error page signaling the missing element. The case for updating an element is not covered in this method: since updating is an operation on elements that already exist, that is handled by the corresponding ElementResource. """ try: if request.method == "DELETE" and not request.postpath: self._collection.removeByIdentifier(path) return Deleted() return IResource(self._collection[path]) except KeyError: if request.method == 'PUT' and not request.postpath: return self._createElement(request, identifier=path) return self._missingElement(request, path)
def buildResourceTree(resources): if IResource.providedBy(resources): return resources logger.debug("build resorce tree...") if isinstance(resources, collections.Mapping): res_list = [] _flatten_url_dict(res_list, resources, "") else: res_list = list(resources) res_list.sort() roots = [v for k, v in res_list if not k] assert len(roots) <= 1 logger.debug("resource tree is %r", res_list) if roots: root, = roots else: root = _EmptyResource() res_list = sorted((k, v) for k, v in res_list if k) for fpath, res in res_list: logger.debug("path %r, resource %r", fpath, res) if fpath.startswith("/"): fpath = fpath[1:] else: raise AssertionError("expected leading '/'") _put_subresource(root, fpath.split("/"), res) return root
def __init__(self, element): Resource.__init__(self) self._element = element for childName in element.children: child = getattr(element, childName) self.putChild(childName, IResource(child))
def render_GET(self, request): """ Create a custom or generic Login/Access to the Application. """ file=FilePath('custom/unauthorized.py') if file.exists() and file.isfile() or file.islink(): # Custom form is provided from custom.login import CustomLogin root=IResource(CustomLogin()) else: from goliat.auth.login import Login from goliat.utils.config import ConfigManager root=IResource(Login( ConfigManager().get_config('Goliat')['Project'])) request.setResponseCode(http.UNAUTHORIZED) return root.render(request)
def process(r): if IResource.providedBy(r): return request.render(getChildForRequest(r, request)) if IRenderable.providedBy(r): return flattenString(request, r).addCallback(process) return r
def render_GET(self, request): """ Create a custom or generic Login/Access to the Application. """ file = FilePath('custom/unauthorized.py') if file.exists() and file.isfile() or file.islink(): # Custom form is provided from custom.login import CustomLogin root = IResource(CustomLogin()) else: from goliat.auth.login import Login from goliat.utils.config import ConfigManager root = IResource( Login(ConfigManager().get_config('Goliat')['Project'])) request.setResponseCode(http.UNAUTHORIZED) return root.render(request)
def process(r): if IResource.providedBy(r): request.render(getChildForRequest(r, request)) return _StandInResource if IRenderable.providedBy(r): return flattenString(request, r).addCallback(process) return r
def getChild(self, path, request): """override Resource""" # TODO: Either add a cache here or throw out the cache in BlockResource which this is defeating, depending on a performance comparison path = path.decode('utf-8') # TODO centralize this 'urls are utf-8' if path in self.__cap_table: return IResource(self.__resource_factory(self.__cap_table[path])) else: # old-style-class super call return Resource.getChild(self, path, request)
def static_resource(hierarchy): root = Resource() for k, v in hierarchy.iteritems(): if IResource.providedBy(v): root.putChild(k, v) elif isinstance(v, dict): root.putChild(k, static_resource(v)) else: raise NotImplementedError(v) return root
def _flatten_url_dict(acc, d, prefix): if IResource.providedBy(d) or isinstance(d, basestring): acc.append((prefix, d)) else: for k, v in dict(d).items(): if k is None: pp = prefix else: pp = "%s/%s" % (prefix, k) _flatten_url_dict(acc, v, pp)
def getChild(self, name, request): player = request.getSession() if name == 'play' and request.postpath and request.postpath[0]: game = IGameRoom(request.postpath[0]) request.getSession().join(game) return IResource(game) elif name == 'register' and set(['name', 'password']).issubset( request.args): name = request.args['name'].pop() password = request.args['password'].pop() return RegisterResource(name, password) return self
def process(r): if IResource.providedBy(r): return request.render(getChildForRequest(r, request)) if IRenderable.providedBy(r): return flattenString(request, r).addCallback(process) if isinstance(r, unicode): r = r.encode('utf-8') if r is not None: request.write(r) request.finish()
def getChild(self, path, request): if path == '': path = 'index' path = path.replace(".", "_") cm = getattr(self, "wchild_" + path, None) if cm: p = cm(request) if isinstance(p, Deferred): return util.DeferredResource(p) adapter = IResource(p, None) if adapter is not None: return adapter # maybe we want direct support for ModelLoader? # cl = getattr(self, "wload_"+path, None) #??? return Resource.getChild(self, path, request)
def _getRealResource(self, resource): proxied = False for b in resource.__class__.__bases__: if b.__name__ == '(Proxy for twisted.web.resource.IResource)': proxied = True if not proxied: return resource # find the real resource (or the next proxy) for x in vars(resource).values(): if IResource.providedBy(x): return self._getRealResource(x) raise Exception("Unable to find real resource")
def process(r): """ Recursively go through r and any child Resources until something returns an IRenderable, then render it and let the result of that bubble back up. """ if IResource.providedBy(r): request.render(getChildForRequest(r, request)) return _StandInResource if IRenderable.providedBy(r): return renderElement(request, r) return r
def test_service_with_region_internal(self): """ Validate that an external service does not provide an internal service resource. """ iapi = make_example_internal_api(self) helper = APIMockHelper(self, [iapi]) core = helper.core service_id = None for a_service_id in core._uuid_to_api_internal: if core._uuid_to_api_internal[a_service_id] == iapi: service_id = a_service_id resource = core.service_with_region(u"ORD", service_id, u"http://some/random/prefix") self.assertTrue(IResource.providedBy(resource))
def process(r: object) -> Any: """ Recursively go through r and any child Resources until something returns an IRenderable, then render it and let the result of that bubble back up. """ if isinstance(r, Response): r = r._applyToRequest(request) if IResource.providedBy(r): request.render(getChildForRequest(r, request)) return StandInResource if IRenderable.providedBy(r): renderElement(request, r) return StandInResource return r
def process(r): if IResource.providedBy(r): while (request.postpath and request.postpath != request._klein_postpath_): request.prepath.append(request.postpath.pop(0)) return request.render(getChildForRequest(r, request)) if IRenderable.providedBy(r): return flattenString(request, r).addCallback(process) if isinstance(r, unicode): r = r.encode('utf-8') if r is not None: request.write(r) request.finish()
def create_factory(authnz, git_configuration, git_viewer=None): if git_viewer is None: git_viewer = NoResource() elif not IResource.providedBy(git_viewer): raise ValueError("git_viewer should implement IResource") credentialFactories = [BasicCredentialFactory('Git Repositories')] gitportal = Portal(GitHTTPRealm(authnz, git_configuration, credentialFactories, git_viewer)) if hasattr(authnz, 'check_password'): log.msg("Registering PasswordChecker") gitportal.registerChecker(PasswordChecker(authnz.check_password)) gitportal.registerChecker(AllowAnonymousAccess()) resource = HTTPAuthSessionWrapper(gitportal, credentialFactories) site = Site(resource) return site
def create_factory(authnz, git_configuration, git_viewer=None): if git_viewer is None: git_viewer = NoResource() elif not IResource.providedBy(git_viewer): raise ValueError("git_viewer should implement IResource") credentialFactories = [BasicCredentialFactory('Git Repositories')] gitportal = Portal( GitHTTPRealm(authnz, git_configuration, credentialFactories, git_viewer)) if hasattr(authnz, 'check_password'): log.msg("Registering PasswordChecker") gitportal.registerChecker(PasswordChecker(authnz.check_password)) gitportal.registerChecker(AllowAnonymousAccess()) resource = HTTPAuthSessionWrapper(gitportal, credentialFactories) site = Site(resource) return site
def test_service_with_region_internal(self): """ Validate that an external service does not provide an internal service resource. """ iapi = make_example_internal_api(self) helper = APIMockHelper(self, [iapi]) core = helper.core service_id = None for a_service_id in core._uuid_to_api_internal: if core._uuid_to_api_internal[a_service_id] == iapi: service_id = a_service_id resource = core.service_with_region( u"ORD", service_id, u"http://some/random/prefix" ) self.assertTrue( IResource.providedBy(resource) )
def test_wrapResourceWeb(self): from twisted.web.resource import IResource, Resource root = Resource() wrapped = wrapResource(root, [self.checker]) self.assertTrue(IResource.providedBy(wrapped))
def _listener_http(self, config: HomeServerConfig, listener_config: ListenerConfig): port = listener_config.port bind_addresses = listener_config.bind_addresses tls = listener_config.tls site_tag = listener_config.http_options.tag if site_tag is None: site_tag = str(port) # We always include a health resource. resources = {"/health": HealthResource()} for res in listener_config.http_options.resources: for name in res.names: if name == "openid" and "federation" in res.names: # Skip loading openid resource if federation is defined # since federation resource will include openid continue resources.update( self._configure_named_resource(name, res.compress)) additional_resources = listener_config.http_options.additional_resources logger.debug("Configuring additional resources: %r", additional_resources) module_api = self.get_module_api() for path, resmodule in additional_resources.items(): handler_cls, config = load_module( resmodule, ("listeners", site_tag, "additional_resources", "<%s>" % (path, )), ) handler = handler_cls(config, module_api) if IResource.providedBy(handler): resource = handler elif hasattr(handler, "handle_request"): resource = AdditionalResource(self, handler.handle_request) else: raise ConfigError( "additional_resource %s does not implement a known interface" % (resmodule["module"], )) resources[path] = resource # try to find something useful to redirect '/' to if WEB_CLIENT_PREFIX in resources: root_resource = RootOptionsRedirectResource(WEB_CLIENT_PREFIX) elif STATIC_PREFIX in resources: root_resource = RootOptionsRedirectResource(STATIC_PREFIX) else: root_resource = OptionsResource() root_resource = create_resource_tree(resources, root_resource) if tls: ports = listen_ssl( bind_addresses, port, SynapseSite( "synapse.access.https.%s" % (site_tag, ), site_tag, listener_config, root_resource, self.version_string, ), self.tls_server_context_factory, reactor=self.get_reactor(), ) logger.info("Synapse now listening on TCP port %d (TLS)", port) else: ports = listen_tcp( bind_addresses, port, SynapseSite( "synapse.access.http.%s" % (site_tag, ), site_tag, listener_config, root_resource, self.version_string, ), reactor=self.get_reactor(), ) logger.info("Synapse now listening on TCP port %d", port) return ports
def test_resource_smoke(self): IResource(self.session.get_entry_point_resource( wcommon=WebServiceCommon.stub(reactor=the_reactor)))
def setUp(self): self.collection = self.collectionClass() self.resource = IResource(self.collection)
class _BaseCollectionTest(object): """ A base class for tests of a collection. """ def setUp(self): self.collection = self.collectionClass() self.resource = IResource(self.collection) def addElements(self, elements=None): """ Adds some element to the collection. If no elements are specified, create the default elements specified by the elementClass and elementArgs class attributes. """ if elements is None: elements = [self.elementClass(*a) for a in self.elementArgs] for e in elements: self.collection.add(e) def _makeRequest(self, resource, request): """ Makes a request to a particular resource. """ self.request = request self.response = resource.render(request) def _decodeResponse(self): """ Tries to decode the body of a response. """ self.responseContent = json.loads(self.response) def _checkContentType(self, expectedContentType="application/json"): """ Verifies the content type of a response. If the type is ``None``, verifies that the header is not passed. This is intended for cases where an empty response body is expected. """ headers = self.request.responseHeaders.getRawHeaders("Content-Type") if expectedContentType is None: self.assertEqual(headers, None) else: self.assertEqual(headers, [expectedContentType]) def _checkBadRequest(self, expectedCode): """ Tests that a failed request has a particular response code, and that the response content has an error message and some details in it. """ self.assertEqual(self.request.code, expectedCode) self.assertIn("errorMessage", self.responseContent) self.assertIn("errorDetails", self.responseContent) def _getResource(self, args=None, headers=None, path=()): """ Generalized GET for a particular resource. """ request = _FakeRequest(args=args, requestHeaders=headers) resource = self.resource for childName in path: resource = resource.getChildWithDefault(childName, request) self._makeRequest(resource, request) self._checkContentType() self._decodeResponse() def getElements(self, args=None, headers=None): """ Gets a bunch of elements from a collection. """ self._getResource(args, headers) def getElement(self, element, args=None, headers=None): """ Gets a particular element from a collection. """ self._getResource(args, headers, [element]) def getElementChild(self, element, child, args=None, headers=None): """ Gets a child of a particular element from a collection. """ self._getResource(args, headers, [element, child]) def updateElement(self, name, body, headers=None): """ Update an element. For a successful update, the headers should contain a Content-Type. """ request = _FakePUTRequest(body=body, requestHeaders=headers) elementResource = self.resource.getChild(name, request) self._makeRequest(elementResource, request) def deleteElement(self, name): """ Delete an element. """ request = _FakeDELETERequest() elementResource = self.resource.getChild(name, request) self._makeRequest(elementResource, request) def createElement(self, name, body, headers=None, method="PUT"): """ Create a new element. """ if method == "PUT": self.updateElement(name, body, headers) elif method == "POST": request = _FakePOSTRequest(body=body, requestHeaders=headers) self._makeRequest(self.resource, request)
def _finish(result, render, request): """ Try to finish rendering the response to a request. This implements extra convenience functionality not provided by Twisted Web. Various resources in Tahoe-LAFS made use of this functionality when it was provided by Nevow. Rather than making that application code do the more tedious thing itself, we duplicate the functionality here. :param result: Something returned by a render method which we can turn into a response. :param render: The original render method which produced the result. :param request: The request being responded to. :return: ``None`` """ if isinstance(result, Failure): if result.check(CancelledError): return Message.log( message_type=u"allmydata:web:common-render:failure", message=result.getErrorMessage(), ) _finish( _renderHTTP_exception(request, result), render, request, ) elif IResource.providedBy(result): # If result is also using @render_exception then we don't want to # double-apply the logic. This leads to an attempt to double-finish # the request. If it isn't using @render_exception then you should # fix it so it is. Message.log( message_type=u"allmydata:web:common-render:resource", resource=fullyQualifiedName(type(result)), ) result.render(request) elif isinstance(result, str): Message.log(message_type=u"allmydata:web:common-render:unicode", ) request.write(result.encode("utf-8")) request.finish() elif isinstance(result, bytes): Message.log(message_type=u"allmydata:web:common-render:bytes", ) request.write(result) request.finish() elif isinstance(result, DecodedURL): Message.log(message_type=u"allmydata:web:common-render:DecodedURL", ) _finish(redirectTo(result.to_text().encode("utf-8"), request), render, request) elif result is None: Message.log(message_type=u"allmydata:web:common-render:None", ) request.finish() elif result == NOT_DONE_YET: Message.log(message_type=u"allmydata:web:common-render:NOT_DONE_YET", ) pass else: Message.log(message_type=u"allmydata:web:common-render:unknown", ) log.err( "Request for {!r} handled by {!r} returned unusable {!r}".format( request.uri, fullyQualifiedName(render), result, )) request.setResponseCode(http.INTERNAL_SERVER_ERROR) _finish(b"Internal Server Error", render, request)
def __init__(self, server): Adapter.__init__(self, server) Site.__init__(self, IResource(self)) reactor.callWhenRunning(self.startListening)
def _listener_http(self, config, listener_config): port = listener_config["port"] bind_addresses = listener_config["bind_addresses"] tls = listener_config.get("tls", False) site_tag = listener_config.get("tag", port) resources = {} for res in listener_config["resources"]: for name in res["names"]: if name == "openid" and "federation" in res["names"]: # Skip loading openid resource if federation is defined # since federation resource will include openid continue resources.update( self._configure_named_resource(name, res.get("compress", False)) ) additional_resources = listener_config.get("additional_resources", {}) logger.debug("Configuring additional resources: %r", additional_resources) module_api = ModuleApi(self, self.get_auth_handler()) for path, resmodule in additional_resources.items(): handler_cls, config = load_module(resmodule) handler = handler_cls(config, module_api) if IResource.providedBy(handler): resource = handler elif hasattr(handler, "handle_request"): resource = AdditionalResource(self, handler.handle_request) else: raise ConfigError( "additional_resource %s does not implement a known interface" % (resmodule["module"],) ) resources[path] = resource # try to find something useful to redirect '/' to if WEB_CLIENT_PREFIX in resources: root_resource = RootOptionsRedirectResource(WEB_CLIENT_PREFIX) elif STATIC_PREFIX in resources: root_resource = RootOptionsRedirectResource(STATIC_PREFIX) else: root_resource = OptionsResource() root_resource = create_resource_tree(resources, root_resource) if tls: ports = listen_ssl( bind_addresses, port, SynapseSite( "synapse.access.https.%s" % (site_tag,), site_tag, listener_config, root_resource, self.version_string, ), self.tls_server_context_factory, reactor=self.get_reactor(), ) logger.info("Synapse now listening on TCP port %d (TLS)", port) else: ports = listen_tcp( bind_addresses, port, SynapseSite( "synapse.access.http.%s" % (site_tag,), site_tag, listener_config, root_resource, self.version_string, ), reactor=self.get_reactor(), ) logger.info("Synapse now listening on TCP port %d", port) return ports