Ejemplo n.º 1
0
    def validate_required_primitive_elements_2851(
            cls,
            values: typing.Dict[str,
                                typing.Any]) -> typing.Dict[str, typing.Any]:
        """https://www.hl7.org/fhir/extensibility.html#Special-Case
        In some cases, implementers might find that they do not have appropriate data for
        an element with minimum cardinality = 1. In this case, the element must be present,
        but unless the resource or a profile on it has made the actual value of the primitive
        data type mandatory, it is possible to provide an extension that explains why
        the primitive value is not present.
        """
        required_fields = [("uid", "uid__ext")]
        _missing = object()

        def _fallback():
            return ""

        errors: typing.List["ErrorWrapper"] = []
        for name, ext in required_fields:
            field = cls.__fields__[name]
            ext_field = cls.__fields__[ext]
            value = values.get(field.alias, _missing)
            if value not in (_missing, None):
                continue
            ext_value = values.get(ext_field.alias, _missing)
            missing_ext = True
            if ext_value not in (_missing, None):
                if isinstance(ext_value, dict):
                    missing_ext = len(ext_value.get("extension", [])) == 0
                elif (getattr(ext_value.__class__, "get_resource_type",
                              _fallback)() == "FHIRPrimitiveExtension"):
                    if ext_value.extension and len(ext_value.extension) > 0:
                        missing_ext = False
                else:
                    validate_pass = True
                    for validator in ext_field.type_.__get_validators__():
                        try:
                            ext_value = validator(v=ext_value)
                        except ValidationError as exc:
                            errors.append(
                                ErrorWrapper(exc, loc=ext_field.alias))
                            validate_pass = False
                    if not validate_pass:
                        continue
                    if ext_value.extension and len(ext_value.extension) > 0:
                        missing_ext = False
            if missing_ext:
                if value is _missing:
                    errors.append(ErrorWrapper(MissingError(),
                                               loc=field.alias))
                else:
                    errors.append(
                        ErrorWrapper(NoneIsNotAllowedError(), loc=field.alias))
        if len(errors) > 0:
            raise ValidationError(errors, cls)  # type: ignore

        return values
Ejemplo n.º 2
0
    def validate_model_attributes_tel(cls, values):
        """
        Validates that model attributes contain correct TEL expressions without cyclic dependencies
        """
        if 'attributes' in values:
            attributes: List[FdqModelAttribute] = values['attributes']

            # get set of available taxon slugs
            available_taxon_slugs = set(
                cls._get_available_attrs_taxon_slugs(attributes))
            # our TEL visitor only verifies here that all available TEL transformations are valid
            # we dont care about the SQL output here

            invalid_taxons_attr = {}
            for attribute in attributes:
                try:
                    # we dont really care from which taxon we start
                    # if there is cyclic reference somewhere, we will run into it eventually
                    taxon_slug = next(filter(None, attribute.field_map))
                except StopIteration:
                    # we dont care, if we dont find the taxon - this check is performed somewhere else
                    continue

                try:
                    # initialize options for the visitor
                    visitor_parameters = AttributeValidationTelVisitorParams(
                        taxon_slug, attributes)

                    tree = ModelTelDialect.parse(attribute.data_reference)
                    visitor = AttributeValidationTelVisitor(visitor_parameters)
                    visitor.visit(tree)

                    # check whether this TEL transformation uses any taxons which arent available in this model
                    additional_taxons = visitor.result.used_taxon_slugs - available_taxon_slugs
                    if len(additional_taxons) > 0:
                        invalid_taxons_attr[
                            attribute.data_reference] = additional_taxons

                except ModelTelCyclicReferenceException:
                    # there's no point in checking other attributes when we run into cyclic reference
                    raise ValueError(
                        f'Data reference "{attribute.data_reference}" contains TEL transformation with cyclic reference'
                    )

            # if we found any attribute with missing taxons, output them all in one error message
            if invalid_taxons_attr:
                attribute_msgs = [
                    f'Data reference "{attr_key}": {", ".join(taxon_slugs)} not available in this model'
                    for attr_key, taxon_slugs in invalid_taxons_attr.items()
                ]

                raise ValidationError([
                    ErrorWrapper(ValueError(msg), 'attributes')
                    for msg in attribute_msgs
                ], cls)

        return values
Ejemplo n.º 3
0
 async def app(request: Request) -> Response:
     try:
         body = None
         if body_field:
             if is_body_form:
                 raw_body = await request.form()
                 form_fields = {}
                 for field, value in raw_body.items():
                     if isinstance(value, UploadFile):
                         form_fields[field] = await value.read()
                     else:
                         form_fields[field] = value
                 if form_fields:
                     body = form_fields
             else:
                 body_bytes = await request.body()
                 if body_bytes:
                     body = await request.json()
     except Exception as e:
         logging.error("Error getting request body", e)
         raise HTTPException(
             status_code=400, detail="There was an error parsing the body"
         )
     values, errors = await solve_dependencies(
         request=request, dependant=dependant, body=body
     )
     if errors:
         errors_out = ValidationError(errors)
         raise HTTPException(
             status_code=HTTP_422_UNPROCESSABLE_ENTITY, detail=errors_out.errors()
         )
     else:
         assert dependant.call is not None, "dependant.call must me a function"
         if is_coroutine:
             raw_response = await dependant.call(**values)
         else:
             raw_response = await run_in_threadpool(dependant.call, **values)
         if isinstance(raw_response, Response):
             return raw_response
         response_data = serialize_response(
             field=response_field, response=raw_response
         )
         return content_type(content=response_data, status_code=status_code)
Ejemplo n.º 4
0
 async def app(request: Request) -> Response:
     try:
         body = None
         if body_field:
             if is_body_form:
                 body = await request.form()
             else:
                 body_bytes = await request.body()
                 if body_bytes:
                     body = await request.json()
     except Exception as e:
         logging.error(f"Error getting request body: {e}")
         raise HTTPException(
             status_code=400, detail="There was an error parsing the body"
         )
     values, errors, background_tasks = await solve_dependencies(
         request=request, dependant=dependant, body=body
     )
     if errors:
         errors_out = ValidationError(errors)
         raise HTTPException(
             status_code=HTTP_422_UNPROCESSABLE_ENTITY, detail=errors_out.errors()
         )
     else:
         assert dependant.call is not None, "dependant.call must me a function"
         if is_coroutine:
             raw_response = await dependant.call(**values)
         else:
             raw_response = await run_in_threadpool(dependant.call, **values)
         if isinstance(raw_response, Response):
             if raw_response.background is None:
                 raw_response.background = background_tasks
             return raw_response
         response_data = serialize_response(
             field=response_field, response=raw_response
         )
         return response_class(
             content=response_data,
             status_code=status_code,
             background=background_tasks,
         )
Ejemplo n.º 5
0
def level2_validation_handler(request: Request, exc: ValidationError):
    """
    Most validation errors are caught immediately, but we do some
    secondary validation when populating our xxx_answers tables
    this catches those and returns a 422
    """
    rslogger.error(exc)

    return JSONResponse(
        status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
        content=jsonable_encoder({"detail": exc.errors()}),
    )
Ejemplo n.º 6
0
async def serialize_response(
    *,
    field: ModelField = None,
    response_content: Any,
    include: Union[SetIntStr, DictIntStrAny] = None,
    exclude: Union[SetIntStr, DictIntStrAny] = set(),
    by_alias: bool = True,
    exclude_unset: bool = False,
    exclude_defaults: bool = False,
    exclude_none: bool = False,
    is_coroutine: bool = True,
) -> Any:
    if field:
        errors = []
        response_content = _prepare_response_content(
            response_content,
            by_alias=by_alias,
            exclude_unset=exclude_unset,
            exclude_defaults=exclude_defaults,
            exclude_none=exclude_none,
        )
        if is_coroutine:
            value, errors_ = field.validate(response_content, {}, loc=("response",))
        else:
            value, errors_ = await run_in_threadpool(
                field.validate, response_content, {}, loc=("response",)
            )
        if isinstance(errors_, ErrorWrapper):
            errors.append(errors_)
        elif isinstance(errors_, list):
            errors.extend(errors_)
        if errors:
            raise ValidationError(errors, field.type_)
        return jsonable_encoder(
            value,
            include=include,
            exclude=exclude,
            by_alias=by_alias,
            exclude_unset=exclude_unset,
            exclude_defaults=exclude_defaults,
            exclude_none=exclude_none,
        )
    else:
        return jsonable_encoder(
            response_content,
            include=include,
            exclude=exclude,
            by_alias=by_alias,
            exclude_unset=exclude_unset,
            exclude_defaults=exclude_defaults,
            exclude_none=exclude_none,
        )
Ejemplo n.º 7
0
def create_workflow(*, db_session: Session = Depends(get_db), workflow_in: WorkflowCreate):
    """Create a new workflow."""
    plugin_instance = plugin_service.get_instance(
        db_session=db_session, plugin_instance_id=workflow_in.plugin_instance.id
    )
    if not plugin_instance:
        raise ValidationError(
            [ErrorWrapper(NotFoundError(msg="No plugin instance found."), loc="plugin_instance")],
            model=WorkflowCreate,
        )

    workflow = create(db_session=db_session, workflow_in=workflow_in)
    return workflow
Ejemplo n.º 8
0
def serialize_response(*, field: Field = None, response: Response) -> Any:
    if field:
        errors = []
        value, errors_ = field.validate(response, {}, loc=("response", ))
        if isinstance(errors_, ErrorWrapper):
            errors.append(errors_)
        elif isinstance(errors_, list):
            errors.extend(errors_)
        if errors:
            raise ValidationError(errors)
        return jsonable_encoder(value)
    else:
        return jsonable_encoder(response)
Ejemplo n.º 9
0
def create_term(*, db_session: Session = Depends(get_db), term_in: TermCreate):
    """Create a new term."""
    term = get_by_text(db_session=db_session, text=term_in.text)
    if term:
        raise ValidationError(
            [
                ErrorWrapper(
                    ExistsError(msg="A term with this name already exists."),
                    loc="name")
            ],
            model=TermCreate,
        )
    term = create(db_session=db_session, term_in=term_in)
    return term
Ejemplo n.º 10
0
    def validate_extension_or_fhir_comment_required(
            cls,
            values: typing.Dict[str,
                                typing.Any]) -> typing.Dict[str, typing.Any]:
        """Conditional Required Validation"""
        errors = list()
        extension = values.get("extension", None)
        fhir_comments = values.get("fhir_comments", None)

        if extension is None and fhir_comments is None:
            errors.append(ErrorWrapper(MissingError(), loc="extension"))
            raise ValidationError(errors, cls)  # type: ignore

        return values
Ejemplo n.º 11
0
def create_search_filter(*,
                         db_session: Session = Depends(get_db),
                         search_filter_in: SearchFilterCreate):
    """Create a new filter."""
    try:
        return create(db_session=db_session, search_filter_in=search_filter_in)
    except IntegrityError:
        raise ValidationError(
            [
                ErrorWrapper(ExistsError(
                    msg="A search filter with this name already exists."),
                             loc="name")
            ],
            model=SearchFilterRead,
        )
Ejemplo n.º 12
0
def get_default_or_raise(*, db_session) -> Organization:
    """Returns the default organization or raise a ValidationError if one doesn't exist."""
    organization = get_default(db_session=db_session)

    if not organization:
        raise ValidationError(
            [
                ErrorWrapper(
                    NotFoundError(msg="No default organization defined."),
                    loc="organization",
                )
            ],
            model=OrganizationRead,
        )
    return organization
Ejemplo n.º 13
0
def get_default_or_raise(*, db_session, project_id: int) -> IncidentType:
    """Returns the default incident_type or raise a ValidationError if one doesn't exist."""
    incident_type = get_default(db_session=db_session, project_id=project_id)

    if not incident_type:
        raise ValidationError(
            [
                ErrorWrapper(
                    NotFoundError(msg="No default incident_type defined."),
                    loc="incident_type",
                )
            ],
            model=IncidentTypeRead,
        )
    return incident_type
Ejemplo n.º 14
0
def create_project(*,
                   db_session: Session = Depends(get_db),
                   project_in: ProjectCreate):
    """Create a new project."""
    project = get_by_name(db_session=db_session, name=project_in.name)
    if project:
        raise ValidationError(
            [
                ErrorWrapper(ExistsError(
                    msg="A project with this name already exists."),
                             loc="name")
            ],
            model=ProjectCreate,
        )

    project = create(db_session=db_session, project_in=project_in)
    return project
Ejemplo n.º 15
0
def update_instance(
        *, db_session, plugin_instance: PluginInstance,
        plugin_instance_in: PluginInstanceUpdate) -> PluginInstance:
    """Updates a plugin instance."""
    plugin_instance_data = plugin_instance.dict()
    update_data = plugin_instance_in.dict(skip_defaults=True)

    if plugin_instance_in.enabled:  # user wants to enable the plugin
        if not plugin_instance.plugin.multiple:
            # we can't have multiple plugins of this type disable the currently enabled one
            enabled_plugin_instances = get_enabled_instances_by_type(
                db_session=db_session,
                project_id=plugin_instance.project_id,
                plugin_type=plugin_instance.plugin.type,
            )
            if enabled_plugin_instances:
                enabled_plugin_instances[0].enabled = False

    if not plugin_instance_in.enabled:  # user wants to disable the plugin
        if plugin_instance.plugin.type == OncallPlugin.type:
            oncall_services = service_service.get_all_by_type_and_status(
                db_session=db_session,
                service_type=plugin_instance.plugin.slug,
                is_active=True)
            if oncall_services:
                raise ValidationError(
                    [
                        ErrorWrapper(
                            InvalidConfigurationError(
                                msg=
                                f"Cannot disable plugin instance: {plugin_instance.plugin.title}. One or more oncall services depend on it. "
                            ),
                            loc="plugin_instance",
                        )
                    ],
                    model=PluginInstanceUpdate,
                )

    for field in plugin_instance_data:
        if field in update_data:
            setattr(plugin_instance, field, update_data[field])

    plugin_instance.configuration = plugin_instance_in.configuration

    db_session.commit()
    return plugin_instance
Ejemplo n.º 16
0
def create_definition(*,
                      db_session: Session = Depends(get_db),
                      definition_in: DefinitionCreate):
    """Create a new definition."""
    definition = get_by_text(db_session=db_session, text=definition_in.text)
    if definition:
        raise ValidationError(
            [
                ErrorWrapper(ExistsError(
                    msg="A description with this text already exists."),
                             loc="text")
            ],
            model=DefinitionRead,
        )

    definition = create(db_session=db_session, definition_in=definition_in)
    return definition
Ejemplo n.º 17
0
def create_tag_type(*,
                    db_session: Session = Depends(get_db),
                    tag_type_in: TagTypeCreate):
    """Create a new tag type."""
    try:
        tag_type = create(db_session=db_session, tag_type_in=tag_type_in)
    except IntegrityError:
        raise ValidationError(
            [
                ErrorWrapper(ExistsError(
                    msg="A tag type with this name already exists."),
                             loc="name")
            ],
            model=TagTypeCreate,
        )

    return tag_type
Ejemplo n.º 18
0
async def validate_hook_url(url: str) -> t.Optional[ValidationError]:
    """Validator for discord webhook urls."""
    async def validate() -> t.Optional[str]:
        if not isinstance(url, str):
            raise ValueError("Webhook URL must be a string.")

        if "discord.com/api/webhooks/" not in url:
            raise ValueError("URL must be a discord webhook.")

        try:
            async with httpx.AsyncClient() as client:
                response = await client.get(url)
                response.raise_for_status()

        except httpx.RequestError as error:
            # Catch exceptions in request format
            raise ValueError(
                f"Encountered error while trying to connect to url: `{error}`")

        except httpx.HTTPStatusError as error:
            # Catch exceptions in response
            status = error.response.status_code

            if status == 401:
                raise ValueError(
                    "Could not authenticate with target. Please check the webhook url."
                )
            elif status == 404:
                raise ValueError(
                    "Target could not find webhook url. Please check the webhook url."
                )
            else:
                raise ValueError(
                    f"Unknown error ({status}) while connecting to target: {error}"
                )

        return url

    # Validate, and return errors, if any
    try:
        await validate()
    except Exception as e:
        loc = (WebHook.__name__.lower(), WebHook.URL.value)

        return ValidationError([ErrorWrapper(e, loc=loc)], _WebHook)
Ejemplo n.º 19
0
def create_team(*,
                db_session: Session = Depends(get_db),
                team_contact_in: TeamContactCreate):
    """Create a new team contact."""
    team = get_by_email(db_session=db_session,
                        email=team_contact_in.email,
                        project_id=team_contact_in.project.id)
    if team:
        raise ValidationError(
            [
                ErrorWrapper(
                    ExistsError(msg="A team with this name already exists."),
                    loc="name")
            ],
            model=TeamContactCreate,
        )
    team = create(db_session=db_session, team_contact_in=team_contact_in)
    return team
Ejemplo n.º 20
0
def get_by_name_or_raise(*, db_session, project_id: int, incident_in: IncidentRead) -> Incident:
    """Returns an incident based on a given name or raises ValidationError"""
    incident = get_by_name(db_session=db_session, project_id=project_id, name=incident_in.name)

    if not incident:
        raise ValidationError(
            [
                ErrorWrapper(
                    NotFoundError(
                        msg="Incident not found.",
                        query=incident_in.name,
                    ),
                    loc="incident",
                )
            ],
            model=IncidentRead,
        )
    return incident
Ejemplo n.º 21
0
def get_by_name_or_raise(*, db_session, alert_in=AlertRead) -> AlertRead:
    """Returns the alert specified or raises ValidationError."""
    alert = get_by_name(db_session=db_session, name=alert_in.name)

    if not alert:
        raise ValidationError(
            [
                ErrorWrapper(
                    NotFoundError(
                        msg="Alert not found.",
                        alert=alert_in.name,
                    ),
                    loc="alert",
                )
            ],
            model=AlertRead,
        )

    return alert
Ejemplo n.º 22
0
    def parse_raw(
        cls: Type["Model"],
        b: StrBytes,
        *,
        content_type:
        str = "application/yaml",  # This is a reasonable default, right?
        encoding: str = "utf-8",
        proto: ExtendedProto = None,
        allow_pickle: bool = False,
    ) -> "Model":
        # NOTE: Type checking this function is a PITA, because we're overriding
        # BaseModel.parse_raw, but not inheriting it due to the MRO problem!

        # Check whether we're specifically asked to parse YAML
        is_yaml = is_yaml_requested(content_type=content_type, proto=proto)

        # Note that JSON is a subset of the YAML 1.2 spec, so we should be OK
        # even if JSON is passed. It will be slower, however.
        if is_yaml:
            try:
                cfg = cast(YamlModelMixinConfig, cls.__config__)
                obj = cfg.yaml_loads(b)
            except RecursionError as e:
                raise ValueError(
                    "YAML files with recursive references are unsupported."
                ) from e
            except ValidationError:
                raise
            except Exception as e:
                raise ValidationError([ErrorWrapper(e, loc=ROOT_KEY)],
                                      cls) from e
        else:
            obj = load_str_bytes(
                b,
                proto=proto,
                content_type=content_type,
                encoding=encoding,
                allow_pickle=allow_pickle,
                json_loads=cls.__config__.json_loads,
            )
        res = cls.parse_obj(obj)  # type: ignore
        return cast("Model", res)
Ejemplo n.º 23
0
def get_by_slug_or_raise(*,
                         db_session,
                         organization_in=OrganizationRead) -> Organization:
    """Returns the organization specified or raises ValidationError."""
    organization = get_by_name(db_session=db_session,
                               name=organization_in.name)

    if not organization:
        raise ValidationError(
            [
                ErrorWrapper(
                    NotFoundError(msg="Organization not found.",
                                  organization=organization_in.name),
                    loc="organization",
                )
            ],
            model=OrganizationRead,
        )

    return organization
Ejemplo n.º 24
0
async def validation_exception_response(request: Request, exc: ValidationError):
    # logger.debug(traceback.format_exc())
    print(traceback.format_exc())
    error = exc.errors()[0]
    try:
        field = error['loc'][1]
    except IndexError:
        field = ''
    err_type = error['type']
    if err_type == 'type_error.enum':
        msg = error['msg'].replace('value', field, 1)
    else:
        msg = f"{error['msg']}: {field}"
    return UJSONResponse(
        status_code=400,
        content={
            'status': 'error',
            'message': msg
        },
    )
Ejemplo n.º 25
0
async def serialize_response(
    *,
    field: ModelField = None,
    response: Response,
    include: Union[SetIntStr, DictIntStrAny] = None,
    exclude=None,
    by_alias: bool = True,
    exclude_unset: bool = False,
    is_coroutine: bool = True,
) -> Any:
    if exclude is None:
        exclude = set()
    if field:
        errors = []
        if exclude_unset and isinstance(response, BaseModel):
            if PYDANTIC_1:
                response = response.dict(exclude_unset=exclude_unset)
            else:
                response = response.dict(
                    skip_defaults=exclude_unset)  # pragma: nocover
        if is_coroutine:
            value, errors_ = field.validate(response, {}, loc=("response", ))
        else:
            value, errors_ = await run_in_threadpool(field.validate,
                                                     response, {},
                                                     loc=("response", ))
        if isinstance(errors_, ErrorWrapper):
            errors.append(errors_)
        elif isinstance(errors_, list):
            errors.extend(errors_)
        if errors:
            raise ValidationError(errors, field.type_)
        return jsonable_encoder(
            value,
            include=include,
            exclude=exclude,
            by_alias=by_alias,
            exclude_unset=exclude_unset,
        )
    else:
        return jsonable_encoder(response)
Ejemplo n.º 26
0
def get_window_sizes_from_args(window_sizes: List[str]) -> List[WindowSize]:
    result = []
    errors = []
    for window_size in window_sizes:
        try:
            width, height = window_size.split(",")
            result.append(WindowSize(width=int(width), height=int(height)))
        except ValueError:
            errors.append(
                ErrorWrapper(
                    BadParameter(
                        message=
                        f"🔥 `{window_size}` is not a valid window size. Must be of type `1920,1080`"
                    ),
                    loc="window_size",
                ))

    if errors:
        raise ValidationError(errors=errors, model=WindowSize)

    return result
Ejemplo n.º 27
0
def get_by_name_or_raise(*,
                         db_session,
                         project_id: int,
                         incident_type_in=IncidentTypeRead) -> IncidentType:
    """Returns the incident_type specified or raises ValidationError."""
    incident_type = get_by_name(db_session=db_session,
                                project_id=project_id,
                                name=incident_type_in.name)

    if not incident_type:
        raise ValidationError(
            [
                ErrorWrapper(
                    NotFoundError(msg="IncidentType not found.",
                                  incident_type=incident_type_in.name),
                    loc="incident_type",
                )
            ],
            model=IncidentTypeRead,
        )

    return incident_type
Ejemplo n.º 28
0
def login_user(
        user_in: UserLogin,
        organization: OrganizationSlug,
        db_session: Session = Depends(get_db),
):
    user = get_by_email(db_session=db_session, email=user_in.email)
    if user and user.check_password(user_in.password):
        return {"token": user.token}

    raise ValidationError(
        [
            ErrorWrapper(
                InvalidUsernameError(msg="Invalid username."),
                loc="username",
            ),
            ErrorWrapper(
                InvalidPasswordError(msg="Invalid password."),
                loc="password",
            ),
        ],
        model=UserLogin,
    )
Ejemplo n.º 29
0
def get_by_name_or_raise(*,
                         db_session,
                         project_id: int,
                         tag_type_in=TagTypeRead) -> TagType:
    """Returns the tag_type specified or raises ValidationError."""
    tag_type = get_by_name(db_session=db_session,
                           project_id=project_id,
                           name=tag_type_in.name)

    if not tag_type:
        raise ValidationError(
            [
                ErrorWrapper(
                    NotFoundError(msg="TagType not found.",
                                  tag_type=tag_type_in.name),
                    loc="tag_type",
                )
            ],
            model=TagTypeRead,
        )

    return tag_type
Ejemplo n.º 30
0
def register_user(
        user_in: UserRegister,
        organization: OrganizationSlug,
        db_session: Session = Depends(get_db),
):
    user = get_by_email(db_session=db_session, email=user_in.email)
    if user:
        raise ValidationError(
            [
                ErrorWrapper(
                    InvalidConfigurationError(
                        msg="A user with this email already exists."),
                    loc="email",
                )
            ],
            model=UserRegister,
        )

    user = create(db_session=db_session,
                  organization=organization,
                  user_in=user_in)
    return user