async def wrapped_view(**values): if not request.authorization and not app.config['BIND_DN']: return quart.Response('Please log in', 401, UNAUTHORIZED) try: # Set up LDAP connection request.ldap = ldap.initialize(app.config['LDAP_URL']) if app.config['BIND_DN'] and app.config['BIND_PASSWORD']: dn = app.config['BIND_DN'] pw = app.config['BIND_PASSWORD'] elif app.config['BIND_PATTERN']: dn = app.config['BIND_PATTERN'] % ( request.authorization.username) pw = request.authorization.password else: # Search user in HTTP headers pw = request.authorization.password try: dn, _attrs = await unique( request.ldap.search( app.config['BASE_DN'], ldap.SCOPE_SUBTREE, '(%s=%s)' % (app.config['LOGIN_ATTR'], request.authorization.username))) except ValueError: raise ldap.INVALID_CREDENTIALS({ 'desc': 'Invalid user', 'info': "User '%s' unknown" % request.authorization.username }) # Try authenticating await empty(request.ldap.simple_bind(dn, pw)) # On success, call the view function and release connection data = await view(**values) request.ldap.unbind_s() return data except ldap.INVALID_CREDENTIALS: return quart.Response('Please log in', 401, UNAUTHORIZED) except ldap.LDAPError as err: args = err.args[0] raise HTTPException(500, args.get('info', ''), args.get('desc', ''))
async def blob(attr: str, index: int, dn: str): try: _dn, attrs = await unique(request.ldap.search(dn, ldap.SCOPE_BASE)) except ValueError: quart.abort(404) if request.method == 'GET': if attr not in attrs or len(attrs[attr]) <= index: quart.abort(404) resp = quart.Response(attrs[attr][index], content_type='application/octet-stream') resp.headers['Content-Disposition'] = \ 'attachment; filename="%s-%d.bin"' % (attr, index) return resp elif request.method == 'PUT': data = [(await request.files)['blob'].read()] if attr in attrs: await empty( request.ldap.modify(dn, [(1, attr, None), (0, attr, data + attrs[attr])])) else: await empty(request.ldap.modify(dn, [(0, attr, data)])) elif request.method == 'DELETE': if attr not in attrs or len(attrs[attr]) <= index: quart.abort(404) await empty(request.ldap.modify(dn, [(1, attr, None)])) data = attrs[attr][:index] + attrs[attr][index + 1:] if data: await empty(request.ldap.modify(dn, [(0, attr, data)])) return { 'changed' : [attr] } # dummy
async def companies(employees): global dbObj if dbObj==None: dbObj = DBMotorIO.DBMotorIO() companies = dbObj.get_companies(employees) mylist= (await companies.to_list(length=100)) return webFW.Response(dumps(mylist), status=200)
async def get() -> quart.Response: if not _wwwAuth.verifyAuth(quart.request.authorization): return _wwwAuth.getLoginResponse() response = quart.Response(await quart.render_template('index.html')) pageId = quart.request.cookies.get('pageId') if not serverMix.innerSession.hasPageId(pageId): pageId = serverMix.innerSession.open(_getDefaultPageSession()) response.set_cookie('pageId', pageId) return response
async def generic_http_error( exc: quart.exceptions.HTTPException, ) -> quart.Response: return quart.Response( await render_template( "generic_http_error.html", status=exc.status_code, description=exc.description, name=exc.name, ), status=exc.status_code, )
async def ldifDump(dn: str) -> quart.Response: 'Dump an entry as LDIF' out = io.StringIO() writer = ldif.LDIFWriter(out) async for dn, attrs in result(request.ldap.search(dn, ldap.SCOPE_SUBTREE)): writer.unparse(dn, attrs) resp = quart.Response(out.getvalue(), content_type='text/plain') resp.headers['Content-Disposition'] = \ 'attachment; filename="%s.ldif"' % dn.split(',')[0].split('=')[1] return resp
async def backend_error_handler(exc: Exception) -> quart.Response: error_id = infra.generate_error_id() current_app.logger.error( "error_id=%s returning 503 status page for exception", error_id, exc_info=exc, ) return quart.Response( await render_exception_template( "backend_error.html", exc, error_id, ), status=503, )
async def post(application: str, environment: str) -> quart.Response: """A POST handles modifications to an existing application and environment's targets and / or labels. If the application and environment do not currently have a file on disk, it will be created, i.e., it is not an error. On success, which means that the changes were persisted to disk, a JSON response with the updated target information will be returned """ target_config = maybe_find_target_config(application, environment, REST_APP.config["target_configs"]) request_targets = await targets_in_request(quart.request) request_labels = await labels_in_request(quart.request) if target_config is not None: if not (request_targets or request_labels): raise InvalidUsage("Must provide either targets or labels") if request_targets is not None and not request_targets: raise InvalidUsage("Cannot provide empty list of targets") if request_labels is not None and not request_labels: raise InvalidUsage("Cannot provide empty list of labels") if request_targets and not target_config.update_with_new_targets( request_targets): raise InvalidUsage("Some of the targets specified already exist") if request_labels and not target_config.update_with_new_labels( request_labels): raise InvalidUsage("Some of the labels specified already exist") elif not request_targets: raise InvalidUsage("Must provide at least one target") else: target_config = TargetConfig( application=application, environment=environment, targets=request_targets or [], labels=request_labels or {}, ) await target_config.write_to_file(file_sd_directory()) save_in_app_config(target_config) return quart.Response(target_config.json, status=200, mimetype=json_mimetype())
async def get(application: str, environment: str) -> quart.Response: """GET requests return the contents of the current file for the given application and environment It is not an error to request an application and environment without any defined labels """ target_config = maybe_find_target_config(application, environment, REST_APP.config["target_configs"]) if target_config is not None: response = target_config.json else: response = json.dumps([]) return quart.Response(response, status=200, mimetype=json_mimetype())
async def delete(application: str, environment: str) -> quart.Response: """A DELETE handles getting rid of the target config, either whole or in-part, for an application and environment A request without any targets or labels will delete the entire config file A request with targets will delete any of the targets provided as long as at least one target would be left and all the provided targets are currently in the list of targets A request with labels will delete any of the label names provided (label keys are ignored) """ target_config = maybe_find_target_config(application, environment, REST_APP.config["target_configs"]) if target_config is None: raise InvalidUsage( f"No targets defined for {application}/{environment}") request_targets = await targets_in_request(quart.request) request_labels = await labels_in_request(quart.request) if request_targets is not None and not request_targets: raise InvalidUsage("Cannot provide empty targets list") if request_labels is not None and not request_labels: raise InvalidUsage("Cannot provide empty labels dict") if request_targets and not target_config.delete_from_targets( request_targets): raise InvalidUsage("Cannot delete all targets") if request_labels and not target_config.delete_from_labels(request_labels): raise InvalidUsage("Cannot delete job or env labels") if not (request_targets or request_labels): await target_config.delete_file(file_sd_directory()) delete_from_app_config(target_config) else: await target_config.write_to_file(file_sd_directory()) save_in_app_config(target_config) return quart.Response(target_config.json, status=200, mimetype=json_mimetype())
async def sse_node_update() -> typing.Tuple[typing.AsyncGenerator[ bytes, None], typing.Dict[str, str]]: """ Establishes a central co-routine that updates at a defined rate and sends server generated events at each iteration. The specific event to be sent depends on what the event scheduler thread defines, according to the defined timestamps on the session description. """ async def send_event( rate: float) -> typing.AsyncGenerator[bytes, None]: while True: await asyncio.sleep(1 / rate) yield self.event.encode() return quart.Response(send_event(30.0), mimetype="text/event-stream")
async def put(application: str, environment: str) -> quart.Response: """A PUT handles replacing the data for a given application and environment entirely with whatever is contained in the request. This makes it, unlike the POST handler, idempotent. On success, which means that the changes were persisted to disk, a JSON response with the updated target information will be returned """ request_targets = await targets_in_request(quart.request) request_labels = await labels_in_request(quart.request) if request_targets and request_labels: target_config = TargetConfig( application=application, environment=environment, targets=request_targets, labels=request_labels, ) else: target_config = find_or_create_target_config( application, environment, REST_APP.config["target_configs"]) if request_targets: for request_target in request_targets: target_config.validate_target(request_target) target_config.targets = request_targets if request_labels: replace_labels_for_put(target_config, request_labels) await target_config.write_to_file(file_sd_directory()) save_in_app_config(target_config) return quart.Response(target_config.json, status=200, mimetype=json_mimetype())
def not_found(_): return quart.Response("The page was not found.", status=404)
def getLoginResponse() -> quart.Response: return quart.Response( 'Could not verify your access level for that URL.\n' 'You have to login with proper credentials', 401, {'WWW-Authenticate': 'Basic realm="Login Required"'})
async def not_found() -> quart.Response: """Returns page not found.""" return quart.Response("The page was not found", status=404)