def _handle(self, request): filename = unquote(request.match_info['filename']) try: filepath = self._directory.joinpath(filename).resolve() if not self._follow_symlinks: filepath.relative_to(self._directory) except (ValueError, FileNotFoundError) as error: # relatively safe raise HTTPNotFound() from error except Exception as error: # perm error or other kind! request.app.logger.exception(error) raise HTTPNotFound() from error # on opening a dir, load it's contents if allowed if filepath.is_dir(): if self._show_index: try: ret = Response(text=self._directory_as_html(filepath), content_type="text/html") except PermissionError: raise HTTPForbidden() else: raise HTTPForbidden() elif filepath.is_file(): ret = FileResponse(filepath, chunk_size=self._chunk_size) else: raise HTTPNotFound return ret
def _permit(request, distribution): """ Permit the request. Authorization is delegated to the optional content-guard associated with the distribution. Args: request (:class:`aiohttp.web.Request`): A request for a published file. distribution (:class:`pulpcore.plugin.models.Distribution`): The matched distribution. Raises: :class:`aiohttp.web_exceptions.HTTPForbidden`: When not permitted. """ guard = distribution.content_guard if not guard: return try: guard.cast().permit(request) except PermissionError as pe: log.debug( _('Path: %(p)s not permitted by guard: "%(g)s" reason: %(r)s'), { 'p': request.path, 'g': guard.name, 'r': str(pe) }) raise HTTPForbidden(reason=str(pe)) except Exception: reason = _('Guard "{g}" failed:').format(g=guard.name) log.debug(reason, exc_info=True) raise HTTPForbidden(reason=reason)
async def wrapper(cls, request): peername = request.transport.get_extra_info('peername') if peername is None: raise ValueError("Can't determine IP") host = None if peername: host, _ = peername if host in ('127.0.0.1', None) and \ request.headers.get('X-FORWARDED-FOR') not in ('127.0.0.1', None): host = request.headers['X-FORWARDED-FOR'] logger.debug('Remote IP: %s', host) if host in self.blocked_ip: logger.info(f'One more request from {host}') return HTTPForbidden() current_key = self.get_current_key(request) if current_key != self.key: logger.warning(f'{host} will be blocked.') self.add_blocked_ip(host) return HTTPForbidden() return await func(cls, request)
async def check_channel_perms(self, request): await self.authenticate_request(request) try: guild: discord.Guild = self.bot.get_guild( int(request.match_info["guild_id"])) # or await self.bot.fetch_guild(request.match_info["guild_id"]) except discord.Forbidden: raise HTTPForbidden(reason="Discord raised Forbidden") if not guild: raise HTTPNotFound(reason="No guild with that ID found") try: member: discord.Member = guild.get_member(int(request.match_info["user_id"])) or \ await guild.fetch_member(int(request.match_info["user_id"])) except discord.Forbidden: raise HTTPForbidden(reason="Discord raised Forbidden") if not member: raise HTTPNotFound(reason="No member with that ID found") try: channel: discord.TextChannel = guild.get_channel( int(request.match_info["channel_id"])) except discord.Forbidden: raise HTTPForbidden(reason="Discord raised Forbidden") if not channel or not isinstance(channel, discord.TextChannel): raise HTTPNotFound(reason="No text channel with that ID found") if channel.permissions_for(member).manage_messages: return web.json_response({"result": "ok", "name": channel.name}) else: return web.json_response({"result": "missing_permissions"})
async def authenticate_request(self, request, channel=None): api_key = request.headers.get('Authorization') if api_key is None: raise HTTPForbidden( reason="No API key provided in Authorization header") api_key = api_key.lower() if api_key in self.config()["global_api_keys"]: return True if channel: db_channel = await get_from_db(channel) channel_api_key = str(db_channel.api_key) if channel_api_key is None: raise HTTPForbidden( reason= "No API key has been generated for this channel yet. Run '/settings api_key " "set' to generate a key.") elif channel_api_key != api_key: raise HTTPForbidden( reason= "The API key provided isn't valid for the specified channel." ) else: return True else: raise HTTPForbidden( reason= "This route requires a GLOBAL api key. Ask the bot owner.")
async def wrapped_function(request: Request) -> StreamResponse: if role is None: return await func(request) if not request['open-id']: return HTTPForbidden(reason='此接口仅支持通过小程序访问') request['user'] = await User.find_one({'wx_open_id': request['open-id']}) if not request['user']: return HTTPForbidden(reason='此接口仅支持小程序用户访问') if role == Auth.weapp: return await func(request) request['user_init'] = await UserInit.find_one_by_user(request['user']) if not request['user_init']: return HTTPForbidden(reason='此接口仅支持已认证用户访问') if request['user_init'].get('state') == 'suspend': return HTTPForbidden(reason='此账户已被管理员停用') if role == Auth.role: return await func(request) if role not in Auth.role: return HTTPForbidden(reason=f'权限代码{role}是错误的') if request['user_init'].role_check(role): return await func(request) else: return web.json_response({'code': -1, 'message': '您没有相应操作的权限'})
async def token_validation(self, request, handler): """Check security access of this layer.""" request_from = None hassio_token = request.headers.get(HEADER_TOKEN) # Blacklist if BLACKLIST.match(request.path): _LOGGER.warning("%s is blacklisted!", request.path) raise HTTPForbidden() # Ignore security check if NO_SECURITY_CHECK.match(request.path): _LOGGER.debug("Passthrough %s", request.path) return await handler(request) # Not token if not hassio_token: _LOGGER.warning("No API token provided for %s", request.path) raise HTTPUnauthorized() # Home-Assistant # UUID check need removed with 131 if hassio_token in (self.sys_homeassistant.uuid, self.sys_homeassistant.hassio_token): _LOGGER.debug("%s access from Home Assistant", request.path) request_from = self.sys_homeassistant # Host if hassio_token == self.sys_machine_id: _LOGGER.debug("%s access from Host", request.path) request_from = self.sys_host # Add-on addon = None if hassio_token and not request_from: addon = self.sys_addons.from_token(hassio_token) # Check Add-on API access if addon and ADDONS_API_BYPASS.match(request.path): _LOGGER.debug("Passthrough %s from %s", request.path, addon.slug) request_from = addon elif addon and addon.access_hassio_api: # Check Role if ADDONS_ROLE_ACCESS[addon.hassio_role].match(request.path): _LOGGER.info("%s access from %s", request.path, addon.slug) request_from = addon else: _LOGGER.warning("%s no role for %s", request.path, addon.slug) if request_from: request[REQUEST_FROM] = request_from return await handler(request) _LOGGER.error("Invalid token for access %s", request.path) raise HTTPForbidden()
async def _handle(self, request: Request) -> StreamResponse: rel_url = request.match_info['filename'] try: filename = Path(rel_url) if filename.anchor: # rel_url is an absolute name like # /static/\\machine_name\c$ or /static/D:\path # where the static dir is totally different raise HTTPForbidden() # alternative directories is the first place for searching alt = False directory = self._directory if self.canonical in self._directory_alt: for v in self._directory_alt[self.canonical]: filepath = v.joinpath(filename).resolve() if filepath.exists(): directory = v alt = True break if not alt: filepath = directory.joinpath(filename).resolve() if not self._follow_symlinks: filepath.relative_to(directory) except (ValueError, FileNotFoundError) as error: # relatively safe raise HTTPNotFound() from error except HTTPForbidden: raise except Exception as error: # perm error or other kind! request.app.logger.exception(error) raise HTTPNotFound() from error # on opening a dir, load its contents if allowed if filepath.is_dir(): if self._show_index: try: return Response(text=self._directory_as_html(filepath), content_type="text/html") except PermissionError: raise HTTPForbidden() else: raise HTTPForbidden() elif filepath.is_file(): return FileResponse(filepath, chunk_size=self._chunk_size) else: raise HTTPNotFound
def aclCheck(app, obj_json, req_action, req_user): log.info(f"aclCheck: {req_action} for user: {req_user}") if isAdminUser(app, req_user): return # allow admin user to do anything if obj_json is None: log.error("aclCheck: no obj json") raise HTTPInternalServerError() # 500 if "acls" not in obj_json: log.error("no acl key") raise HTTPInternalServerError() # 500 acls = obj_json["acls"] log.debug(f"acls: {acls}") if req_action not in ("create", "read", "update", "delete", "readACL", "updateACL"): log.error(f"unexpected req_action: {req_action}") if req_user in acls: acl = acls[req_user] log.debug(f"got acl: {acl} for user: {req_user}") if req_action in acl and acl[req_action]: log.debug("action permitted by user acl") return else: # treat deny for username as authorative deny log.warn( f"Action: {req_action} not permitted for user: {req_user}") raise HTTPForbidden() # 403 if "default" in acls: acl = acls["default"] log.debug(f"got default acl: {acl}") if req_action in acl and acl[req_action]: log.debug("action permitted by default acl") return user_group_db = app["user_group_db"] if req_user in user_group_db: user_groups = user_group_db[req_user] for user_group in user_groups: acl_name = GROUP_PREFIX + user_group log.debug(f"checking group acl: {acl_name}") if acl_name in acls: acl = acls[acl_name] if req_action in acl and acl[req_action]: log.debug(f"action permitted by group acl: {acl_name}") return log.warn(f"Action: {req_action} not permitted for user: {req_user}") raise HTTPForbidden() # 403
async def get_guild_details(self, request): await self.authenticate_request(request) try: guild: discord.Guild = self.bot.get_guild( int(request.match_info["guild_id"])) # or await self.bot.fetch_guild(request.match_info["guild_id"]) except discord.Forbidden: raise HTTPForbidden(reason="Discord raised Forbidden") if not guild: raise HTTPNotFound(reason="No guild with that ID found") try: member: discord.Member = guild.get_member(int(request.match_info["user_id"])) or \ await guild.fetch_member(int(request.match_info["user_id"])) except discord.Forbidden: raise HTTPForbidden(reason="Discord raised Forbidden") if not member: raise HTTPNotFound(reason="No member with that ID found") result = {} channels_with_perms: List[Dict[str, Union[str, int]]] if guild.owner_id == member.id: channels_with_perms = [] for channel in guild.channels: if isinstance(channel, discord.TextChannel): channels_with_perms.append({ "name": channel.name, "id": channel.id }) else: channels_with_perms = [] for channel in guild.channels: if isinstance(channel, discord.TextChannel) and channel.permissions_for( member).manage_messages: channels_with_perms.append({ "name": channel.name, "id": channel.id }) result["channels"] = channels_with_perms db_guild = await get_from_db(guild) result["used_credits"] = db_guild.used_updaters result["total_credits"] = db_guild.total_updaters result[ "available_credits"] = db_guild.total_updaters - db_guild.used_updaters return web.json_response(result)
async def index(request: Request): app: Application = request.app auth_user = await get_auth_user(request) session = await get_session(request) last_visited = session.get('last_visited', 'never') session['last_visited'] = datetime.now().isoformat() errors = [] if request.method == 'POST': if auth_user: raise HTTPForbidden() data = await request.post() username = data['username'] password = data['password'] async with app['db'].acquire() as conn: user = await User.get_by_username(conn, username) if user and user.check_password(password): session['user_id'] = user.id auth_user = user else: errors.append('Invalid username or password') return { 'last_visited': last_visited, 'errors': errors, 'auth_user': auth_user }
def _permit(request, distribution): """ Permit the request. Authorization is delegated to the optional content-guard associated with the distribution. Args: request (:class:`aiohttp.web.Request`): A request for a published file. distribution (detail of :class:`pulpcore.plugin.models.BaseDistribution`): The matched distribution. Raises: :class:`aiohttp.web_exceptions.HTTPForbidden`: When not permitted. """ guard = distribution.content_guard if not guard: return try: guard.cast().permit(request) except PermissionError as pe: log.debug( _('Path: %(p)s not permitted by guard: "%(g)s" reason: %(r)s'), {"p": request.path, "g": guard.name, "r": str(pe)}, ) raise HTTPForbidden(reason=str(pe))
async def _handle(self, request: Request) -> StreamResponse: rel_url = request.match_info["filename"] hass: HomeAssistant = request.app[KEY_HASS] filename = Path(rel_url) if filename.anchor: # rel_url is an absolute name like # /static/\\machine_name\c$ or /static/D:\path # where the static dir is totally different raise HTTPForbidden() try: key = (filename, self._directory, self._follow_symlinks) if (filepath := PATH_CACHE.get(key)) is None: filepath = PATH_CACHE[key] = await hass.async_add_executor_job( _get_file_path, filename, self._directory, self._follow_symlinks) except (ValueError, FileNotFoundError) as error: # relatively safe raise HTTPNotFound() from error except Exception as error: # perm error or other kind! request.app.logger.exception(error) raise HTTPNotFound() from error if filepath: return FileResponse( filepath, chunk_size=self._chunk_size, headers=CACHE_HEADERS, ) return await super()._handle(request)
def aclCheck(obj_json, req_action, req_user): log.info(f"aclCheck: {req_action} for user: {req_user}") admin_user = config.get("admin_user") if req_user == admin_user: return # allow admin user to do anything if obj_json is None: log.error("aclCheck: no obj json") raise HTTPInternalServerError() # 500 if "acls" not in obj_json: log.error("no acl key") raise HTTPInternalServerError() # 500 acls = obj_json["acls"] log.debug(f"acls: {acls}") if req_action not in ("create", "read", "update", "delete", "readACL", "updateACL"): log.error(f"unexpected req_action: {req_action}") acl = None if req_user in acls: acl = acls[req_user] log.debug(f"got acl: {acl} for user: {req_user}") elif "default" in acls: acl = acls["default"] log.debug(f"got default acl: {acl}") else: acl = { } log.debug(f"no acl found") if req_action not in acl or not acl[req_action]: log.warn(f"Action: {req_action} not permitted for user: {req_user}") raise HTTPForbidden() # 403 log.debug("action permitted")
async def __wrapper__(request: Request): user = await get_auth_user(request) if user is None: raise HTTPUnauthorized() if ensure_admin and not user.is_admin: raise HTTPForbidden() return await handler(request)
async def _handle(self, request): rel_url = request.match_info['filename'] try: filename = Path(rel_url) if filename.anchor: # rel_url is an absolute name like # /static/\\machine_name\c$ or /static/D:\path # where the static dir is totally different raise HTTPForbidden() filepath = self._directory.joinpath(filename).resolve() if not self._follow_symlinks: filepath.relative_to(self._directory) except (ValueError, FileNotFoundError) as error: # relatively safe raise HTTPNotFound() from error except Exception as error: # perm error or other kind! request.app.logger.exception(error) raise HTTPNotFound() from error # on opening a dir, load its contents if allowed if filepath.is_dir(): return await super()._handle(request) if filepath.is_file(): return FileResponse(filepath, chunk_size=self._chunk_size, headers=CACHE_HEADERS) raise HTTPNotFound
async def category(request: Request): user = await get_auth_user(request) category_name = request.match_info['cat'] category = await category_dao.get_by_name(request.app, category_name) if not set(user.roles).intersection(category.allowed_roles): raise HTTPForbidden() notes = await note_dao.get_by_category_id(request.app, category.id) return {'notes': notes}
async def wrapper(cls, *args, **kwargs): current_user_role = cls.request['user_role'] current_user_resources = cls.request['user_resources'] if current_user_role != 'tech' or 'family_read' not in current_user_resources: raise HTTPForbidden() return await func(cls, *args, **kwargs)
async def auth_wrapper(request): if 'X-API-KEY' not in request.headers: raise HTTPUnauthorized(text='No API Key provided') key = request.headers['X-API-KEY'] if key != config["API_KEY"] or not config["API_KEY"]: raise HTTPForbidden(text='Wrong API Key') return await func(request)
async def _check_login(self, username, password): """Check User credentials.""" provider = self._get_provider() try: await provider.async_validate_login(username, password) except HomeAssistantError: raise HTTPForbidden() from None
async def check_auth(request, body): if request.version != aiohttp.HttpVersion11: return # if request.headers.get('AUTHORIZATION') is None: # raise HTTPForbidden() if "token" not in body or body["token"] != secrets.AUTH_TOKEN: raise HTTPForbidden() body.pop("token") # prevent logging of sensitive info
async def handle(request): async with aiohttp.ClientSession() as session: session_state = await get_session(request) backend_url = request.app.settings.backend_url url = (request.url.with_scheme(backend_url.scheme).with_host( backend_url.host).with_port(backend_url.port).with_scheme( backend_url.scheme)) if url.scheme == 's3': # This is an S3 backend (s3://bucket/) # Add index.html if we need it file_name = url.path.rstrip('/').split('/')[-1] if '.' not in file_name: url = url.with_path('{}/index.html'.format( url.path.strip('/'))) # Create a signed url url = URL(s3_sign(url.host, url.path.strip('/'))) # Don't pass any headers through, we'll simply get the file headers = {} else: # Otherwise we have a regular backend headers = request.headers.copy() headers['Host'] = '{}:{}'.format(backend_url.host, backend_url.port) headers['Remote-User'] = session_state['aiohttp_cas']['username'] if request.app.settings.require_attribute: if not session_state['aiohttp_cas'].get( request.app.settings.require_attribute): raise HTTPForbidden( text="You do not have permission to view this site") kwargs = dict( method=request.method, url=url, params=getattr(request, 'params', None), headers=headers, auth=getattr(request, 'auth', None), allow_redirects=False, timeout=request.app.settings.timeout, ) async with session.request(**kwargs) as remote_response: print("{} {} -> {}".format(request.method, url, remote_response.status)) response = web.StreamResponse(status=remote_response.status, reason=remote_response.reason, headers=remote_response.headers) await response.prepare(request) while True: chunk = await remote_response.content.read(CHUNK_SIZE) if not chunk: break await response.write(chunk) print("Done") return response
async def post(self, request, data): """Handle new discovery requests.""" hassio_ip = os.environ['HASSIO'].split(':')[0] if request[KEY_REAL_IP] != ip_address(hassio_ip): _LOGGER.error("Invalid auth request from %s", request[KEY_REAL_IP]) raise HTTPForbidden() await self._check_login(data[ATTR_USERNAME], data[ATTR_PASSWORD]) return web.Response(status=200)
async def measurement(self, request): if request.headers.get('AUTHORIZATION') != DEVICE_AUTH: raise HTTPForbidden() device_id = int(request.match_info['device_id']) measurement = Measurement.from_dict(await request.json()) await self.repo.add_measurement(device_id, measurement) return web.json_response((await self.repo.get_config(device_id)).to_dict())
async def get_object(self, key, bucket=None, offset=0, length=None): """ Return data for object at given key. If Range is set, return the given byte range. """ if not bucket: log.error("get_object - bucket not set") raise HTTPInternalServerError() if length: log.info( f"storage range request -- offset: {offset} length: {length}") else: offset = None length = None start_time = time.time() log.debug( f"azureBlobClient.get_object({bucket}/{key} start: {start_time}") try: async with self._client.get_blob_client(container=bucket, blob=key) as blob_client: blob_rsp = await blob_client.download_blob(offset=offset, length=length) data = await blob_rsp.content_as_bytes() finish_time = time.time() log.info( f"azureBlobClient.get_object({key} bucket={bucket}) start={start_time:.4f} finish={finish_time:.4f} elapsed={finish_time-start_time:.4f} bytes={len(data)}" ) except CancelledError as cle: self._azure_stats_increment("error_count") msg = f"azureBlobClient.CancelledError getting get_object {key}: {cle}" log.error(msg) raise HTTPInternalServerError() except Exception as e: if isinstance(e, AzureError): if e.status_code == 404: msg = f"storage key: {key} not found " log.warn(msg) raise HTTPNotFound() elif e.status_code in (401, 403): msg = f"azureBlobClient.access denied for get key: {key}" log.info(msg) raise HTTPForbidden() else: self._azure_stats_increment("error_count") log.error( f"azureBlobClient.got unexpected AzureError for get_object {key}: {e.message}" ) raise HTTPInternalServerError() else: log.error( f"azureBlobClient.Unexpected exception for get_object {key}: {e}" ) raise HTTPInternalServerError() return data
async def DELETE_Group(request): """HTTP method to delete a group resource""" log.request(request) app = request.app meta_cache = app['meta_cache'] group_id = request.match_info.get('id') if not group_id: msg = "Missing group id" log.warn(msg) raise HTTPBadRequest(reason=msg) if not isValidUuid(group_id, "Group"): msg = f"Invalid group id: {group_id}" log.warn(msg) raise HTTPBadRequest(reason=msg) username, pswd = getUserPasswordFromRequest(request) await validateUserPassword(app, username, pswd) domain = getDomainFromRequest(request) if not isValidDomain(domain): msg = f"Invalid domain: {domain}" log.warn(msg) raise HTTPBadRequest(reason=msg) bucket = getBucketForDomain(domain) # get domain JSON domain_json = await getDomainJson(app, domain) # TBD - verify that the obj_id belongs to the given domain await validateAction(app, domain, group_id, username, "delete") if "root" not in domain_json: log.error(f"Expected root key for domain: {domain}") raise HTTPBadRequest(reason="Unexpected Error") if group_id == domain_json["root"]: msg = "Forbidden - deletion of root group is not allowed - delete domain first" log.warn(msg) raise HTTPForbidden() req = getDataNodeUrl(app, group_id) req += "/groups/" + group_id params = {} if bucket: params["bucket"] = bucket log.debug(f"http_delete req: {req} params: {params}") await http_delete(app, req, params=params) if group_id in meta_cache: del meta_cache[group_id] # remove from cache resp = await jsonResponse(request, {}) log.response(request, resp=resp) return resp
async def authMiddleware(request, handler): # This handles preflight CORS requests if request.method == METH_OPTIONS: return await handler(request) authorization_header = request.headers.get(HeaderKeys.authorization) if authorization_header is None: raise HTTPForbidden() token = authorization_header.split(' ')[-1] try: request[RequestContextKeys.auth_user] = auth.verify_id_token(token) response = await handler(request) return response except NotInRoleException as e: print(e) raise HTTPForbidden() except ValueError as e: print(e) raise HTTPForbidden()
def ban_middleware_handler(request): """Verify if IP is not banned.""" ip_address_ = get_real_ip(request) is_banned = any(ip_ban.ip_address == ip_address_ for ip_ban in request.app[KEY_BANNED_IPS]) if is_banned: raise HTTPForbidden() return handler(request)
async def get_object(self, key, bucket=None, range=''): """ Return data for object at given key. If Range is set, return the given byte range. """ if not bucket: log.error("get_object - bucket not set") raise HTTPInternalServerError() start_time = time.time() log.debug(f"s3CLient.get_object({bucket}/{key} start: {start_time}") try: resp = await self._client.get_object(Bucket=bucket, Key=key, Range=range) data = await resp['Body'].read() finish_time = time.time() log.info( f"s3Client.getS3Bytes({key} bucket={bucket}) start={start_time:.4f} finish={finish_time:.4f} elapsed={finish_time-start_time:.4f} bytes={len(data)}" ) resp['Body'].close() except ClientError as ce: # key does not exist? # check for not found status response_code = ce.response["Error"]["Code"] if response_code == "NoSuchKey": msg = f"s3_key: {key} not found " log.warn(msg) raise HTTPNotFound() elif response_code == "NoSuchBucket": msg = f"s3_bucket: {bucket} not fiound" log.info(msg) raise HTTPNotFound() elif response_code == "AccessDenied": msg = f"access denied for s3_bucket: {bucket}" log.info(msg) raise HTTPForbidden() else: self._s3_stats_increment("error_count") log.error( f"got unexpected ClientError on s3 get {key}: {response_code}" ) raise HTTPInternalServerError() except CancelledError as cle: self._s3_stats_increment("error_count") msg = f"CancelledError putting s3 obj {key}: {cle}" log.error(msg) raise HTTPInternalServerError() except Exception as e: self._s3_stats_increment("error_count") msg = f"Unexpected Exception {type(e)} putting s3 obj {key}: {e}" log.error(msg) raise HTTPInternalServerError() return data
async def read(request: Request): user = await get_auth_user(request) note_id = int(request.match_info['id']) note = await note_dao.get(request.app, note_id) if not note: raise HTTPNotFound() category = await category_dao.get(request.app, note.category_id) if not set(user.roles).intersection(category.allowed_roles): raise HTTPForbidden() author = await user_dao.get(request.app, note.author_id) return {'author': author, 'note': note, 'category': category}