def resolve(self, x_api_key: http.Header, player_slug: str = None) -> Player: if not x_api_key: raise BadRequest("Missing header x-old-api-key.") api_key: ApiKey = ApiKey.objects(key=x_api_key) if not api_key: raise BadRequest("Could not find a valid Api Key.") api_key = api_key[0] if player_slug and player_slug != api_key.player.slug: raise Forbidden("You cannot access that player.") return api_key.player
def get_place(id, es: Elasticsearch, indices: IndexNames, settings: Settings, lang=None, type=None, verbosity=DEFAULT_VERBOSITY) -> Place: """Main handler that returns the requested place""" if verbosity not in VERBOSITY_LEVELS: raise BadRequest( status_code=400, detail={"message": f"verbosity {verbosity} does not belong to the set of possible verbosity values={VERBOSITY_LEVELS}"} ) if not lang: lang = settings['DEFAULT_LANGUAGE'] lang = lang.lower() es_place = fetch_es_place(id, es, indices, type) places = { "admin": Admin, "street": Street, "addr": Address, "poi": POI, } loader = places.get(es_place[0].get('_type')) if loader is None: prometheus.exception("FoundPlaceWithWrongType") logger.error("The place with the id {} has a wrong type: {}".format(id, es_place[0].get('_type'))) return None return loader.load_place(es_place[0]['_source'], lang, settings, verbosity)
def fetch_es_place(id, es, indices, type) -> dict: """Returns the raw Place data This function gets from Elasticsearch the entry corresponding to the given id. """ if type is None: index_name = PLACE_DEFAULT_INDEX elif type not in indices: raise BadRequest( status_code=400, detail={"message": f"Wrong type parameter: type={type}"} ) else: index_name = indices.get(type) try: es_places = es.search(index=index_name, body={ "filter": { "term": {"_id": id} } }) except ElasticsearchException as error: logger.warning(f"error with database: {error}") raise HTTPException(detail='database issue', status_code=503) es_place = es_places.get('hits', {}).get('hits', []) if len(es_place) == 0: raise NotFound(detail={'message': f"place {id} not found with type={type}"}) if len(es_place) > 1: logger.warning("Got multiple places with id %s", id) return es_place[0]
def validate_verbosity(verbosity): if verbosity not in ALL_VERBOSITY_LEVELS: raise BadRequest({ "message": f"Unknown verbosity '{verbosity}'. Accepted values are {ALL_VERBOSITY_LEVELS}" }) return verbosity
def list_player_games(auth_player: Player, player_slug: str, filters: http.QueryParams) -> dict: limit = 10 dict_filters = {} for f, v in filters.items(): if "player" in f: raise BadRequest("Cannot filter on player.") # Since we support MongoEngine filters, if we have a filter key with __ we # have to parse the value of the filter as JSON. if "__" in f: v = ujson.loads(v.replace("'", '"')) dict_filters[f] = v order = dict_filters.pop("order", "asc") order_by = dict_filters.pop("order_by", "created_at") page = int(dict_filters.pop("page", 1)) offset = (page - 1) * limit print(offset) games = (Game.objects( **dict_filters).order_by(f"{'-' if order == 'desc' else ''}{order_by}" ).skip(offset).limit(limit).all()) game_count = Game.objects(**dict_filters).count() game_list = [mongo_to_dict(g) for g in games] return { "total": game_count, "page": page, "last_page": ceil(game_count / limit), "games": game_list, }
def get_events_bbox(bbox, query_params: http.QueryParams): if not kuzzle_client.enabled: raise HTTPException("Kuzzle client is not available", status_code=501) try: params = EventQueryParam(**query_params) except ValidationError as e: logger.info(f"Validation Error: {e.json()}") raise BadRequest( detail={"message": e.errors()} ) current_outing_lang = params.category if params.category: current_outing_lang = params.category.get('fr') bbox_places = kuzzle_client.fetch_event_places( bbox=params.bbox, collection='events', category=current_outing_lang, size=params.size ) events_list = [Event(p['_source']) for p in bbox_places] return { "events": [p.load_place(params.lang, params.verbosity) for p in events_list] }
def fetch_es_place(id, es, indices, type) -> list: """Returns the raw Place data This function gets from Elasticsearch the entry corresponding to the given id. """ if type is None: index_name = "munin" elif type not in indices: raise BadRequest( status_code=400, detail={"message": f"Wrong type parameter: type={type}"} ) else: index_name = indices.get(type) es_places = es.search(index=index_name, body={ "filter": { "term": {"_id": id} } }) es_place = es_places.get('hits', {}).get('hits', []) if len(es_place) == 0: raise NotFound(detail={'message': f"place {id} not found with type={type}"}) return es_place
def login(session: Session, request: http.Request, data: LoginType) -> UserType: user = session.query(User).filter(User.username == data.username).first() if not user: raise BadRequest(dict(error='Invalid username/password')) verified = user.verify_password(data.password) if not verified: raise BadRequest(dict(error='Invalid username/password')) user_session = UserSession(user=user) session.add(user_session) cookie = get_session_cookie(request.url, str(user_session.id)) headers = {'Set-Cookie': cookie.output(header='')} prune_expired_sessions(session) return http.JSONResponse(UserType(user), headers=headers)
def get_raw_params(query_params): raw_params = dict(query_params) if 'category' in query_params: raw_params['category'] = query_params.get_list('category') if 'raw_filter' in query_params: raw_params['raw_filter'] = query_params.get_list('raw_filter') if raw_params.get('raw_filter') and raw_params.get('category'): raise BadRequest( detail={"message": "Both \'raw_filter\' and \'category\' parameters cannot be provided together"} ) return raw_params
def has_permission(self, obj_id: int, auth: Auth): obj = get_or_404(self.actesviews.model, obj_id) if obj.created.date() != timezone.localdate(): raise BadRequest("Observation can't be edited another day") if auth.user != obj.owner: raise Forbidden('Only owner can edit an Observation') return True
def create_user(session: Session, user_data: UserInputType, user: User) -> http.JSONResponse: txn = session.begin_nested() new_user = User(**dict(user_data)) if new_user.id is not None: raise BadRequest({'error': 'user ID cannot be set'}) if not can_user_create_user(user, new_user): msg = 'user cannot create user with role "{}"' raise BadRequest({'error': msg.format(new_user.role.name)}) session.add(new_user) try: txn.commit() except IntegrityError: txn.rollback() raise BadRequest({'error': 'username already exists'}) return http.JSONResponse(UserType(new_user), status_code=201)
def __new__(cls, *args, **kwargs): data = super().__new__(cls, *args, **kwargs) expression = None order = "desc" if data.startswith('-') else "asc" try: field_name = re.sub(r'^-', '', data) column = getattr(cls.model, field_name) expression = getattr(column, order) except AttributeError: raise BadRequest() return expression
def register_player(player: RegisterPlayer) -> dict: """ Register a new Overwatch player. """ player.password = hash_pass(player.password.encode("utf-8")) if Player.objects(battletag=player.battletag): raise BadRequest( detail= f"A player with the battletag {player.battletag} already exists.") new_player = Player(**player) new_player.save() return mongo_to_dict(new_player)
def get_directions(f_lon, f_lat, t_lon, t_lat, params: QueryParams): from_position = (f_lon, f_lat) to_position = (t_lon, t_lat) params_dict = dict(params) mode = params_dict.pop('type', '') lang = params_dict.pop('language', '') or 'en' if not mode: raise BadRequest('"type" query param is required') return directions_client.get_directions(from_position, to_position, mode=mode, lang=lang)
def acte_update(obj_id: int, new_data: actes_schemas[self.model].updater, auth: Auth) -> Response: # check against empty data if not new_data: raise BadRequest("empty query") obj = self.model.objects.get(id=obj_id) try: obj.update(**new_data) except AttributeError as e: # request should be for valide fields raise BadRequest from e return Response(actes_schemas[self.model].getter(obj), status=201)
def resolve(self, route: Route, data: http.RequestData, parameter: inspect.Parameter, query_params: http.QueryParams): data = data or query_params if not data: if parameter.default != inspect._empty: data = parameter.default else: raise BadRequest(f"{parameter.name} cannot be empty!") if isinstance(data, ImmutableMultiDict): data = self._change_to_dict(data) try: return parameter.annotation(data) except Exception: return data
def authenticate(self, authorization: http.Header, settings: Settings, db: Db): # Firs we check token validity jwt = get_jwt(authorization, settings) if jwt.payload == {}: raise AuthenticationFailed("payload non validé") # Get User instance user_id = jwt.payload['user_id'] try: user = db.User.objects.get(id=user_id) except ObjectDoesNotExist: raise BadRequest('User in token not found') if not user.is_active: raise Forbidden("User Inactive") return AuthUser(user=user)
async def create_token(data: LoginData, session: Session, settings: Settings): user = session.query(User).filter_by(email=data['username']).first() if not user or not user.password == data['password']: raise BadRequest({"message": "Email and password do not match"}) expires = (datetime.now() + timedelta(days=5)).timestamp() token = jwt.encode({ 'user_id': user.id, 'exp': int(expires) }, settings['JWT_SECRET'], algorithm='HS256') return { 'token_type': 'Bearer', 'access_token': token.decode('utf-8'), 'expires_in': int(expires), }
def closest_address(lat: float, lon: float, es: Elasticsearch, lang=None, verbosity=DEFAULT_VERBOSITY) -> Address: if verbosity not in ALL_VERBOSITY_LEVELS: raise BadRequest({ "message": f"Unknown verbosity '{verbosity}'. Accepted values are {ALL_VERBOSITY_LEVELS}" }) if not lang: lang = settings['DEFAULT_LANGUAGE'] lang = lang.lower() place = get_closest_place(lat, lon, es) return place.load_place(lang, verbosity)
def get_places_bbox(bbox, es: Elasticsearch, indices: IndexNames, settings: Settings, query_params: http.QueryParams): raw_params = get_raw_params(query_params) try: params = PlacesQueryParam(**raw_params) except ValidationError as e: logger.info(f"Validation Error: {e.json()}") raise BadRequest( detail={"message": e.errors()} ) source = params.source if source is None: if params.q: # PJ is currently the only source that accepts arbitrary queries source = SOURCE_PAGESJAUNES elif params.category \ and all(c.get('pj_filters') for c in params.category) \ and pj_source.bbox_is_covered(params.bbox): source = SOURCE_PAGESJAUNES else: source = SOURCE_OSM if source == SOURCE_PAGESJAUNES: all_categories = [pj_category for c in params.category for pj_category in c['pj_filters']] places_list = pj_source.get_places_bbox(all_categories, params.bbox, size=params.size, query=params.q) else: # Default source (OSM) if params.raw_filter: raw_filters = params.raw_filter else: raw_filters = [f for c in params.category for f in c['raw_filters']] bbox_places = fetch_bbox_places( es, indices, raw_filters=raw_filters, bbox=params.bbox, max_size=params.size ) places_list = [POI(p['_source']) for p in bbox_places] return { "places": [p.load_place(params.lang, params.verbosity) for p in places_list], "source": source }
def __new__(cls, *args, **kwargs): data = super().__new__(cls, *args, **kwargs) pairs = data.split(',') expressions = [] for pair in pairs: # finds comparison operators or anything between `~` op = re.search(r'(>(=)?)|(<(=)?)|(==)|(!=)|~(.*)~', pair) try: operator = cls.operator_map.get(op.group()) field_name, value = pair.split(op.group()) column = getattr(cls.model, field_name) comparator = getattr(column, operator) expressions.append(comparator(value)) except AttributeError: raise BadRequest() return expressions
def get_directions(self, from_loc, to_loc, mode, lang, **extra): method = self.directions_qwant if self.MAPBOX_API_ENABLED: method = self.directions_mapbox if mode in ('driving-traffic', 'driving', 'car'): mode = 'driving-traffic' elif mode in ('cycling',): mode = 'cycling' elif mode in ('walking', 'walk'): mode = 'walking' elif mode in ('publictransport', 'taxi', 'vtc', 'carpool'): method = self.directions_combigo mode = mode else: raise BadRequest(f'unknown mode {mode}') return method(from_loc, to_loc, mode, lang, **extra)
def extract_from_text(params: TextExtractionJSONParams, es_client: Elasticsearch) -> dict: """Tag extraction endpoint handler, accepts parameters as JSON.""" if not params.text: raise BadRequest({'content': 'Required and not provided'}) domains = params.domains or TAG_DOMAINS.keys() response = {} for domain in domains: response[domain] = get_domain_tags( domain=domain, es_client=es_client, text=params.text, min_score=params.min_score, constant_score=bool(params.constant_score), offset=params.offset, limit=params.limit, ) return response
def get_places_bbox(bbox, es: Elasticsearch, indices: IndexNames, settings: Settings, query_params: http.QueryParams): raw_params = dict(query_params) if 'raw_filter' in query_params: raw_params['raw_filter'] = query_params.get_list('raw_filter') try: params = PlacesQueryParam(**raw_params) except ValidationError as e: logger.warning(f"Validation Error: {e.json()}") raise BadRequest(detail={"message": e.errors()}) bbox_places = fetch_bbox_places(es, indices, categories=params.raw_filter, bbox=params.bbox, max_size=params.size) places_list = [] for p in bbox_places: poi = POI.load_place(p['_source'], params.lang, settings, params.verbosity) places_list.append(poi) return {"places": places_list}
async def decode(self, receive, content_type): mime_type, mime_options = parse_options_header(content_type) boundary = mime_options.get('boundary') if not boundary: raise BadRequest('Missing boundary') return FileStream(receive, boundary.encode())
def extract_from_form(form_data: MultiPartForm, es_client: Elasticsearch) -> dict: """ Tag extraction endpoint handler, accepting a multi-part form. """ params = dict(form_data) # Convert from ImmutableDict params = {k: v[0] for k, v in params.items()} # Strip array wrappers from fields domains = params.get('domains') if domains: params['domains'] = [d.strip() for d in domains.split(',')] else: params['domains'] = [] try: source = params.pop('source') except KeyError: raise BadRequest({'source': 'Required and not provided'}) params['constant_score'] = False params['limit'] = 10000 if source == 'text': try: params = TextExtractionJSONParams.validate(params, allow_coerce=True) except validators.ValidationError as exc: raise BadRequest(exc.detail) return extract_from_text(params, es_client) elif source == 'url': try: params = URLExtractionJSONParams.validate(params, allow_coerce=True) except validators.ValidationError as exc: raise BadRequest(exc.detail) return extract_from_url(params, es_client) try: file = params.pop('file') except KeyError: raise BadRequest({'file': 'Required and not provided'}) try: params = BaseExtractionJSONParams.validate(params, allow_coerce=True) except validators.ValidationError as exc: raise BadRequest(exc.detail) try: text = extract_text(file.stream) except TextExtractionTimeout: return Response('Text extraction timed out', status_code=500) except TextExtractionError: return Response('Text extraction could not be performed', status_code=500) domains = params.domains or TAG_DOMAINS.keys() response = {} for domain in domains: response[domain] = get_domain_tags( domain=domain, es_client=es_client, text=text, min_score=params.min_score, constant_score=params.constant_score, offset=params.offset, limit=params.limit, ) return response
def __init__(self, **data: Any): super().__init__(**data) if not self.raw_filter and not self.category and not self.q: raise BadRequest({ "message": "One of 'category', 'raw_filter' or 'q' parameter is required" })