def register_ip(self, zone, ip): """ Actually register a name for a given IP. @returns: A resource or a byte-string depending on the action being successful or not. Possible HTTP codes are: 200 (OK) 400 (Bad request --> no such zone) 403 (Forbidden --> out of subnet) 507 (Insufficient storage --> somehow the name space is kinda full) """ if zone not in self.data: return ErrorPage( 400, "Bad Request", "No such zone, consider hosting your own!" ) try: return self.get_assign_name(zone, ip) + b"." + zone + b"\n" except ValueError: return ForbiddenResource("Your IP is not allowed to use this resource.") except LookupError: return ErrorPage( 507, "Insufficient Storage", "It looks like this zone is getting full. Consider hosting your own!", ) except Exception as ex: log.error("Error registering {zone} | {ip}", zone=zone, ip=ip) log.failure(ex) return ErrorPage(500, "Internal Error", "Something odd happened!")
def _authorizedResource(self, request): # check whether the path of the request exists in the app match = self._matchPath(request) if not match: return UnauthorizedResource() # get authorization header or fail header = request.getHeader(b'authorization') if not header: return util.DeferredResource(self._login(Anonymous())) # parse the authorization header auth_data = self._parseHeader(header) if not auth_data: return UnauthorizedResource() # decode the credentials from the parsed header try: credentials = self._credentialFactory.decode(auth_data, request) except error.LoginFailed: return UnauthorizedResource() except: # If you port this to the newer log facility, be aware that # the tests rely on the error to be logged. log.err(None, "Unexpected failure from credentials factory") return ErrorPage(500, None, None) # make sure the uuid given in path corresponds to the one given in # the credentials request_uuid = match.get('uuid') if request_uuid and request_uuid != credentials.username: return ErrorPage(500, None, None) # if all checks pass, try to login with credentials return util.DeferredResource(self._login(credentials))
class CeilometerV1Samples(Resource): """ /ceilometer/v1/samples/<device id> : accept metrics from ceilometer """ isLeaf = True future_warning = set() def render_POST(self, request): if len(request.postpath) != 1: return NoResource().render(request) device_id = request.postpath[0] if not REGISTRY.has_device(device_id): return NoResource(message="Unrecognized device '%s'" % device_id).render(request) content_type = request.requestHeaders.getRawHeaders('content-type', [None])[0] if content_type != 'application/json': return ErrorPage(415, "Unsupported Media Type", "Unsupported Media Type").render(request) try: payload = json.loads(request.content.getvalue()) except Exception, e: log.error("%s: Error [%s] while parsing JSON data: %s", device_id, e, request.content.getvalue()) return ErrorPage(400, "Bad Request", "Error parsing JSON data: %s" % e).render(request) samples = [] now = time.time() try: for sample in payload: if 'event_type' in sample and 'volume' not in sample: return ErrorPage(422, "Unprocessable Entity", "Misconfigured- sending event data to metric URL").render(request) resourceId = sample['resource_id'] meter = sample['name'] value = sample['volume'] timestamp = amqp_timestamp_to_int(sample['timestamp']) if timestamp > now: if device_id not in self.future_warning: log.debug("%s: [%s/%s] Timestamp (%s) appears to be in the future. Using now instead.", device_id, resourceId, meter, timestamp) self.future_warning.add(device_id) timestamp = now samples.append((resourceId, meter, value, timestamp)) except Exception, e: log.exception("%s: Error processing sample data", device_id) return ErrorPage(422, "Unprocessable Entity", "Error processing data: %s" % e).render(request)
def _authorizedResource(self, request): # check whether the path of the request exists in the app match = self._matchPath(request) if not match: return UnauthorizedResource() # get authorization header or fail header = request.getHeader(b'authorization') if not header: return util.DeferredResource(self._login(Anonymous())) # parse the authorization header auth_data = self._parseHeader(header) if not auth_data: return UnauthorizedResource() # decode the credentials from the parsed header try: credentials = self._credentialFactory.decode(auth_data, request) except error.LoginFailed: return UnauthorizedResource() except Exception: # If you port this to the newer log facility, be aware that # the tests rely on the error to be logged. log.err(None, "Unexpected failure from credentials factory") return ErrorPage(500, None, None) # make sure the uuid given in path corresponds to the one given in # the credentials request_uuid = match.get('uuid') if request_uuid and request_uuid != credentials.username: return ErrorPage(500, None, None) # eventually return a cached resouce sessionData = _sessionData(request) if sessionData.username == credentials.username \ and sessionData.password == credentials.password: return self._portal.realm.auth_resource # if all checks pass, try to login with credentials and cache # credentials in case of success def _cacheSessionData(res): sessionData.username = credentials.username sessionData.password = credentials.password return res d = self._login(credentials) d.addCallback(_cacheSessionData) return util.DeferredResource(d)
def getChild(self, name, req): if isinstance(self.node, ProhibitedNode): raise FileProhibited(self.node.reason) if should_create_intermediate_directories(req): return ErrorPage( http.CONFLICT, u"Cannot create directory %s, because its parent is a file, " u"not a directory" % quote_output(name, encoding='utf-8'), "no details") return ErrorPage( http.BAD_REQUEST, u"Files have no children named %s" % quote_output(name, encoding='utf-8'), "no details", )
def getChildWithDefault(self, path, request): """ Inspect the Authorization HTTP header, and return a deferred which, when fired after successful authentication, will return an authorized C{Avatar}. On authentication failure, an C{UnauthorizedResource} will be returned, essentially halting further dispatch on the wrapped resource and all children """ authheader = request.getHeader('authorization') if not authheader: return util.DeferredResource(self._login(Anonymous())) factory, respString = self._selectParseHeader(authheader) if factory is None: return UnauthorizedResource(self._credentialFactories) try: credentials = factory.decode(respString, request) except error.LoginFailed: return UnauthorizedResource(self._credentialFactories) except: log.err(None, "Unexpected failure from credentials factory") return ErrorPage(500, None, None) else: request.postpath.insert(0, request.prepath.pop()) return util.DeferredResource(self._login(credentials))
def getChild(self, path, request): if path in self.CHILDREN: return self._child(self.CHILDREN[path]) return ErrorPage(status=404, brief="Not found: %r" % (path, ), detail="The resource %r you requested was not found" % (path, ))
def getChild(self, path, request): logger.info('Processing HTTP request: %s', request.path) logger.debug('HTTP request: %s', request) logger.debug('postpath: %s', request.postpath) try: device, pg_id = yield self._process_service.process(request, REQUEST_TYPE_HTTP) except Exception: logger.error('Error while processing HTTP request:', exc_info=True) defer.returnValue(ErrorPage(INTERNAL_SERVER_ERROR, 'Internal processing error', 'Internal processing error')) else: # Here we 'inject' the device object into the request object request.prov_dev = device service = self.default_service if pg_id in self._pg_mgr: plugin = self._pg_mgr[pg_id] if plugin.http_service is not None: _log_sensitive_request(plugin, request, REQUEST_TYPE_HTTP) service = self.service_factory(pg_id, plugin.http_service) # If the plugin specifies a path preprocessing method, use it if hasattr(service, 'path_preprocess'): logger.debug('Rewriting paths to the HTTP Service') service = rewrite.RewriterResource(service, service.path_preprocess) if service.isLeaf: request.postpath.insert(0, request.prepath.pop()) defer.returnValue(service) else: defer.returnValue(service.getChildWithDefault(path, request))
def render(self, request): host = request.getHeader('host') if self.strip_subdomain: parts = host.split('.', 1) name, superhost = ('', host) if len(parts) == 1 else parts else: parts = host.split('.', 1) name = '' if len(parts) == 1 else parts[0] superhost = host if host.startswith(self.host_sub_name): if self.auth: user = request.getUser() password = request.getPassword() if not user or not password or not self.auth(user, password): request.setHeader('WWW-Authenticate', 'Basic realm="www"') page = ErrorPage(http.UNAUTHORIZED, 'Authorization Required', '') return page.render(request) request.setHeader('Content-Type', 'application/json') return self.register_tunnel(superhost, request.args.get('key', [None])[0]) else: if not name in self.tunnels: return NoResource().render(request) request.content.seek(0, 0) clientFactory = self.proxyClientFactoryClass( request.method, request.uri, request.clientproto, request.getAllHeaders(), request.content.read(), request) self.reactor.connectTCP(self.host, self.tunnels[name], clientFactory) return server.NOT_DONE_YET
def bad_request(reason=u"Bad Request"): """ :return IResource: A resource which can be rendered to produce a **BAD REQUEST** response. """ return ErrorPage( BAD_REQUEST, b"Bad Request", reason.encode("utf-8"), )
def _loginFailed(self, result): if result.check(error.Unauthorized, error.LoginFailed): return UnauthorizedResource(self._credentialFactories) else: log.err( result, "HTTPAuthSessionWrapper.getChildWithDefault encountered " "unexpected error") return ErrorPage(500, None, None)
def render_POST(self, request): if len(request.postpath) != 1: return NoResource().render(request) device_id = request.postpath[0] if not REGISTRY.has_device(device_id): return NoResource(message="Unrecognized device '%s'" % device_id).render(request) content_type = request.requestHeaders.getRawHeaders('content-type', [None])[0] if content_type != 'application/json': return ErrorPage(415, "Unsupported Media Type", "Unsupported Media Type").render(request) try: payload = json.loads(request.content.getvalue()) except Exception, e: log.error("%s: Error [%s] while parsing JSON data: %s", device_id, e, request.content.getvalue()) return ErrorPage(400, "Bad Request", "Error parsing JSON data: %s" % e).render(request)
def test_404_not_found(self): """ A 404 HTTP status code translates to a BadStatus result. """ feed = FetchFeed() client = StubTreq(ErrorPage(404, "Not Found", "???")) result = self.successResultOf(poll_feed(feed, self.clock, client)) self.assertEqual(BadStatus(404), result)
def test_410_gone(self): """ A 410 HTTP status code translates to a Gone result. """ feed = FetchFeed() client = StubTreq(ErrorPage(410, "Gone", "Gone")) result = self.successResultOf(poll_feed(feed, self.clock, client)) self.assertEqual(Gone(), result)
def test_write_snapshot_to_tahoe_fails(self, name, contents): """ If any part of a snapshot upload fails then the metadata for that snapshot is retained in the local database and the snapshot content is retained in the stash. """ broken_root = ErrorPage(500, "It's broken.", "It's broken.") f = self.useFixture( RemoteSnapshotCreatorFixture( temp=FilePath(self.mktemp()), author=self.author, root=broken_root, upload_dircap="URI:DIR2:foo:bar", )) config = f.config remote_snapshot_creator = f.remote_snapshot_creator snapshots = [] parents = [] for content in contents: data = io.BytesIO(content) d = create_snapshot( name=name, author=self.author, data_producer=data, snapshot_stash_dir=config.stash_path, parents=parents, ) d.addCallback(snapshots.append) self.assertThat( d, succeeded(Always()), ) parents = [snapshots[-1]] local_snapshot = snapshots[-1] config.store_local_snapshot(snapshots[-1]) d = remote_snapshot_creator.upload_local_snapshots() self.assertThat( d, succeeded(Always()), ) self.eliot_logger.flushTracebacks(TahoeAPIError) self.assertEqual( local_snapshot, config.get_local_snapshot(name), ) self.assertThat( local_snapshot.content_path.getContent(), Equals(content), )
def test_write_snapshot_to_tahoe_fails(self, relpath, contents, upload_dircap): """ If any part of a snapshot upload fails then the metadata for that snapshot is retained in the local database and the snapshot content is retained in the stash. """ broken_root = ErrorPage(500, "It's broken.", "It's broken.") author = create_local_author("alice") f = self.useFixture( MagicFileFactoryFixture( temp=FilePath(self.mktemp()), author=author, root=broken_root, upload_dircap=upload_dircap, )) local_path = f.config.magic_path.child(relpath) mf = f.magic_file_factory.magic_file_for(local_path) retries = [] snapshots = [] def retry(*args, **kw): d = Deferred() retries.append((d, (args, kw))) return d mf._delay_later = retry for content in contents: with local_path.open("w") as local_file: local_file.write(content) d = mf.create_update() d.addCallback(snapshots.append) self.assertThat( d, succeeded(Always()), ) self.eliot_logger.flushTracebacks(TahoeAPIError) local_snapshot = snapshots[-1] self.assertEqual( local_snapshot, f.config.get_local_snapshot(relpath), ) self.assertThat( local_snapshot.content_path.getContent(), Equals(content), ) self.assertThat( len(retries), Equals(1), )
def _loginFailed(self, result): """ Handle login failure by presenting either another challenge (for expected authentication/authorization-related failures) or a server error page (for anything else). """ if result.check(error.Unauthorized, error.LoginFailed): return UnauthorizedResource() else: log.error("HTTPAuthSessionWrapper.getChildWithDefault encountered " "unexpected error (%s)" % (result, )) return ErrorPage(500, None, None)
def getChild(self,name,request): if AuthUser(request).auth_user(): resource=self.get_resource(request.getUser()) return resource else: request.setHeader('WWW-Authenticate', "Basic realm=\"your ip: %s\""% (request.getClientIP())) return ErrorPage(401,"Need authenticated","%s"% (request.getAllHeaders()))
def __init__(self, reactor, threadpool): wsgi = WSGIResource(reactor, threadpool, application) FallbackResource.__init__(self, wsgi) self.putChild(b"csp-report", CSPReportLogger()) self.putChild(b"static", Static()) # Handle requests for /favicon.ico and paths hit by script kiddies at # the Twisted level so that they don't make it down to Django, which # logs 404s as errors: a404 = ErrorPage(404, "Not Found", "") for path in (b"favicon.ico", b"index.php", b"wp-login.php"): self.putChild(path, a404)
def _login_fail(self, result): """ Handle login failure by presenting either another challenge (for expected authentication/authorization-related failures) or a server error page (for anything else). """ if result.check(error.Unauthorized, error.LoginFailed): return UnauthorizezResource(result.getErrorMessage()) else: log.err( result, "SessionManager.getChildWithDefault encountered unexpected " "error") return ErrorPage(500, None, None)
def render_PUT(self, request): if not self.exists: return ErrorPage( http.CONFLICT, "Resource does not exist", "Resource does not exist and cannot be updated.").render( request) try: data = json.loads(request.content.getvalue()) with open(self.path, "w") as f: f.write(data["content"]) request.setResponseCode(http.OK) return json.dumps({'success': True}) except Exception as e: return ServerErrorResource(e).render(request)
def getChildWithDefault(self, project_path_element, request): auth_info = request.auth_info if (not 'authorized_projects' in auth_info or auth_info.get('staff', False) or project_path_element in auth_info['authorized_projects']): request.project = project_path_element try: next_path_element = request.postpath.pop(0) except IndexError: next_path_element = None if next_path_element not in self.children: raise NoResource("No such child resource.") request.prepath.append(project_path_element) return self.children[next_path_element] else: return ErrorPage(403, "Forbidden", "You don't have access to this project.")
def scheensharing(self, request, room_uri): try: room = self.conference._rooms[room_uri] except KeyError: return NoResource('Room not found') request.setHeader('Content-Type', 'text/html; charset=utf-8') if 'image' not in request.args or not request.args.get( 'image', [''])[0].endswith('jpg'): return ErrorPage(400, 'Bad Request', '\"image\" not provided') images_path = os.path.join(ConferenceConfig.screensharing_images_dir, room.uri) image_path = os.path.basename(urllib.unquote(request.args['image'][0])) if not os.path.isfile(os.path.join(images_path, image_path)): return NoResource('Image not found') image = os.path.join('screensharing_img', image_path) width = 'width: 100%' if 'fit' in request.args else '' return self.screensharing_template % dict(image=image, width=width)
def render_POST(self, request): if self.exists: #http://stackoverflow.com/questions/3825990/http-response-code-for-post-when-resource-already-exists return ErrorPage( http.CONFLICT, "Resource already exists", "Resource already exists and cannot be created.").render( request) try: data = json.loads(request.content.getvalue()) filedir = os.path.split(self.path)[0] if not os.path.exists(filedir): os.makedirs(filedir) with open(self.path, "w") as f: f.write(data["content"]) request.setResponseCode(http.CREATED) return json.dumps({'success': True}) except Exception as e: return ServerErrorResource(e).render(request)
def getChild(self, name, request): if name == 'sendCommand': if request.method == 'GET': return File('hamjab/resources/help/sendCommand.html') args = ('command', ) for arg in args: result = ArgUtils._check_arg(arg, request.args) if result: return result (command, ) = ArgUtils._get_args(request, args) try: other_args = dict([(x, request.args[x][0]) for x in request.args if x not in args]) command = command.format(**other_args) except KeyError: return ErrorPage(200, "Command Error", "Missing arguments for command") return SendCommandResource(self.device, command) elif name == 'frontEnd': return File('hamjab/resources/devices/{device}'.format( device=self.device.deviceId)) elif name == 'help': return File('hamjab/resources/help/') elif name == 'getUnsolicited': return GetUnsolicitedResource(self.device) else: self.log.warn("Unknown page requested: {name!r} as part of {path}", name=repr(name), path=request.path) return NoResource()
def set_webhook(self, host: str, port: int): cert_path, pkey_path = get_or_create_root_cert(self.work_dir, host) self.bot.remove_webhook() self.bot.set_webhook(url=f'https://{host}:{port}/{self.token}/', certificate=open(cert_path, 'r')) bot = self.bot class WebhookHandler(Resource): isLeaf = True def render_POST(self, request): request_body_dict = json.load(request.content) update = Update.de_json(request_body_dict) reactor.callInThread(lambda: bot.process_new_updates([update])) return b'' root = ErrorPage(403, 'Forbidden', '') root.putChild(self.token.encode(), WebhookHandler()) site = Site(root) sslcontext = ssl.DefaultOpenSSLContextFactory(str(pkey_path), str(cert_path)) reactor.listenSSL(port, site, sslcontext)
def getChild(self, name, request): if name == "home": templateParser = TemplateFile('hamjab/resources/home/') templateParser.addRenderer( 'index', MainPageRenderer(self.deviceServerFactory)) return templateParser elif name == "toggleStatus": CommandServer.isDisabled = not CommandServer.isDisabled return ErrorPage(200, "Status", "Toggled the site status") elif CommandServer.isDisabled: return ForbiddenResource("The site is disabled") elif name == "listDevices": return DeviceListResource(self.deviceServerFactory) elif name == "macro": result = ArgUtils._check_arg("macroName", request.args) if result: return result (macroName, ) = ArgUtils._get_args(request, ("macroName", )) if macroName not in self.deviceServerFactory.macros: return NoResource() return MacroResource(self.deviceServerFactory, macroName) elif self.deviceServerFactory.isDeviceRegistered( name) and '/' in request.path: device = self.deviceServerFactory.getDevice(name) return DeviceResource(device) return NoResource()
class MonitorResource(ResourceBase): # isLeaf = True CHILDREN = property( lambda self: { 'up': UpResource, 'state': StateResource, 'log': LogResource, 'dashboard': DashboardResource, 'dashboard.html': HtmlDashboardResource, 'favicon.ico': lambda _: ErrorPage( status=404, brief="Not found: favicon.ico", detail=""), }) def __init__(self, *args, **kwargs): ResourceBase.__init__(self, *args, **kwargs) self.putChild( 'static', static.File(os.path.join(os.path.dirname(__file__), 'static'))) def render_GET(self, request): return { 'child-resources': ['%s/' % (x, ) for x in self.CHILDREN.keys()] } def getChild(self, path, request): if path in self.CHILDREN: return self._child(self.CHILDREN[path]) return ErrorPage(status=404, brief="Not found: %r" % (path, ), detail="The resource %r you requested was not found" % (path, ))
def _authorizedResource(self, request): """ Get the L{IResource} which the given request is authorized to receive. If the proper authorization headers are present, the resource will be requested from the portal. If not, an anonymous login attempt will be made. """ authheader = request.getHeader(b'authorization') if not authheader: return util.DeferredResource(self._login(Anonymous())) factory, respString = self._selectParseHeader(authheader) if factory is None: return UnauthorizedResource(self._credentialFactories) try: credentials = factory.decode(respString, request) except error.LoginFailed: return UnauthorizedResource(self._credentialFactories) except: self._log.failure("Unexpected failure from credentials factory") return ErrorPage(500, None, None) else: return util.DeferredResource(self._login(credentials))
def bad_content_type(request): return ErrorPage( UNSUPPORTED_MEDIA_TYPE, b"Unsupported media type", b"Unsupported media type", ).render(request)