Beispiel #1
0
    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
Beispiel #2
0
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)
Beispiel #3
0
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]
Beispiel #4
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
Beispiel #5
0
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,
    }
Beispiel #6
0
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]
    }
Beispiel #7
0
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
Beispiel #8
0
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)
Beispiel #9
0
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
Beispiel #10
0
    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
Beispiel #11
0
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)
Beispiel #12
0
    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
Beispiel #13
0
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)
Beispiel #14
0
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)
Beispiel #15
0
        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)
Beispiel #16
0
    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
Beispiel #17
0
    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)
Beispiel #18
0
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),
    }
Beispiel #19
0
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)
Beispiel #20
0
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
    }
Beispiel #21
0
    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
Beispiel #22
0
    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)
Beispiel #23
0
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
Beispiel #24
0
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}
Beispiel #25
0
 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())
Beispiel #26
0
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
Beispiel #27
0
 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"
         })