def on_post(self, req, resp, organization_code, it_service_instance_id):
        """Adds an instance of IT asset to an organization IT service.

        :param req: See Falcon Request documentation.
        :param resp: See Falcon Response documentation.
        :param organization_code: The code of the organization.
        :param it_service_instance_id: The id of the IT service instance.
        """
        session = Session()
        try:
            it_service_instance = find_it_service_instance(
                it_service_instance_id, organization_code, session)
            if it_service_instance is None:
                raise falcon.HTTPNotFound()

            errors = validate_post(req.media, organization_code,
                                   it_service_instance_id, session)
            if errors:
                raise HTTPUnprocessableEntity(errors)

            accepted_fields = ['it_asset_instance_id', 'relevance_level_id']
            item = OrganizationITServiceITAsset().fromdict(
                req.media, only=accepted_fields)
            item.it_service_instance = it_service_instance
            session.add(item)
            session.commit()

            resp.status = falcon.HTTP_CREATED
            resp.location = req.relative_uri + f'/{item.it_asset_instance_id}'
            resp.media = {'data': custom_asdict(item)}
        finally:
            session.close()
Exemplo n.º 2
0
    def on_post(self, req, resp, organization_code, it_asset_instance_id):
        """Adds a control to an IT asset in order to decrease vulnerability against a security threat.
        However, the security threat against which the control is effective is not relevant here.

        :param req: See Falcon Request documentation.
        :param resp: See Falcon Response documentation.
        :param organization_code: The code of the organization.
        :param it_asset_instance_id: The id of the IT asset instance.
        """
        session = Session()
        try:
            organization_it_asset = find_organization_it_asset(it_asset_instance_id, organization_code, session)
            if organization_it_asset is None:
                raise falcon.HTTPNotFound()

            errors = validate_post(req.media, it_asset_instance_id, organization_code, session)
            if errors:
                raise HTTPUnprocessableEntity(errors)

            accepted_fields = ['mitigation_control_id', 'description']
            item = OrganizationItAssetControl().fromdict(req.media, only=accepted_fields)
            item.organization_it_asset_id = it_asset_instance_id
            session.add(item)
            session.commit()

            resp.status = falcon.HTTP_CREATED
            resp.location = req.relative_uri + f'/{item.id}'
            resp.media = {'data': custom_asdict(item)}
        finally:
            session.close()
    def on_delete(self, req, resp, organization_code, it_service_instance_id,
                  it_asset_instance_id):
        """Removes an instance of IT asset from an organization IT service.
        It doesn't remove the IT asset from the organization.

        :param req: See Falcon Request documentation.
        :param resp: See Falcon Response documentation.
        :param organization_code: The code of the organization.
        :param it_service_instance_id: The id of the IT service instance from which the IT asset should be removed.
        :param it_asset_instance_id: The id of the IT asset instance to be removed.
        """
        session = Session()
        try:
            # Route params are checked in two steps:
            # 1st step: check if IT service is in organization
            # 2nd step: check if IT asset is in organization IT service
            it_service_instance = find_it_service_instance(
                it_service_instance_id, organization_code, session)
            it_service_asset = find_it_service_it_asset(
                it_asset_instance_id, it_service_instance_id, session)
            if it_service_instance is None or it_service_asset is None:
                raise falcon.HTTPNotFound()

            session.delete(it_service_asset)
            session.commit()
        finally:
            session.close()
Exemplo n.º 4
0
    def on_post(self, req, resp, organization_code):
        """Adds a IT asset to an organization's IT service.

        :param req: See Falcon Request documentation.
        :param resp: See Falcon Response documentation.
        :param organization_code: The code of the organization.
        """
        session = Session()
        try:
            organization = session.query(Organization).get(organization_code)
            if organization is None:
                raise falcon.HTTPNotFound()

            errors = validate_post(req.media, organization_code, session)
            if errors:
                raise HTTPUnprocessableEntity(errors)

            accepted_fields = ['it_asset_id', 'external_identifier']
            item = OrganizationITAsset().fromdict(req.media,
                                                  only=accepted_fields)
            item.organization_id = organization_code
            session.add(item)
            session.commit()

            resp.status = falcon.HTTP_CREATED
            resp.location = req.relative_uri + f'/{item.instance_id}'
            resp.media = {'data': custom_asdict(item)}
        finally:
            session.close()
Exemplo n.º 5
0
    def on_patch(self, req, resp, macroprocess_id):
        """Updates (partially) the macroprocess requested.
        All entities that reference the macroprocess will be affected by the update.

        :param req: See Falcon Request documentation.
        :param resp: See Falcon Response documentation.
        :param macroprocess_id: The id of macroprocess to be patched.
        """
        session = Session()
        try:
            macroprocess = session.query(BusinessMacroprocess).get(
                macroprocess_id)
            if macroprocess is None:
                raise falcon.HTTPNotFound()

            errors = validate_patch(req.media, session)
            if errors:
                raise HTTPUnprocessableEntity(errors)

            patch_item(macroprocess, req.media, only=['name'])
            session.commit()

            resp.status = falcon.HTTP_OK
            resp.media = {'data': macroprocess.asdict()}
        finally:
            session.close()
Exemplo n.º 6
0
    def on_post(self, req, resp):
        """Creates a new system user.

        :param req: See Falcon Request documentation.
        :param resp: See Falcon Response documentation.
        """
        session = Session()
        try:
            errors = validate_post(req.media, session)
            if errors:
                raise HTTPUnprocessableEntity(errors)

            # Copy fields from request to a SystemUser object
            item = SystemUser().fromdict(req.media,
                                         only=['email', 'full_name'])

            # Get password and hash it
            password = req.media.get('password')
            item.hashed_password = bcrypt.hashpw(password.encode('UTF-8'),
                                                 bcrypt.gensalt())

            # Add roles to user being created when informed
            add_roles(item, req.media.get('roles'))

            session.add(item)
            session.commit()
            resp.status = falcon.HTTP_CREATED
            resp.location = req.relative_uri + f'/{item.id}'
            resp.media = {'data': custom_asdict(item)}
        finally:
            session.close()
Exemplo n.º 7
0
    def on_patch(self, req, resp, organization_code, security_threat_id):
        """Updates (partially) the security threat requested.
        All entities that reference the security threat will be affected by the update.

        :param req: See Falcon Request documentation.
        :param resp: See Falcon Response documentation.
        :param organization_code: The code of organization containing the security threat.
        :param security_threat_id: The id of security threat to be patched.
        """
        session = Session()
        try:
            security_threat = find_organization_security_threat(
                security_threat_id, organization_code, session)
            if security_threat is None:
                raise falcon.HTTPNotFound()

            errors = validate_patch(req.media, organization_code, session)
            if errors:
                raise HTTPUnprocessableEntity(errors)

            patch_item(security_threat, req.media, only=['threat_level_id'])
            session.commit()

            resp.status = falcon.HTTP_OK
            resp.media = {'data': custom_asdict(security_threat)}
        finally:
            session.close()
Exemplo n.º 8
0
    def on_post(self, req, resp, organization_code):
        """Adds a security threat to an organization.

        :param req: See Falcon Request documentation.
        :param resp: See Falcon Response documentation.
        :param organization_code: The code of the organization.
        """
        session = Session()
        try:
            organization = session.query(Organization).get(organization_code)
            if organization is None:
                raise falcon.HTTPNotFound()

            errors = validate_post(req.media, organization_code, session)
            if errors:
                raise HTTPUnprocessableEntity(errors)

            item = OrganizationSecurityThreat()
            item.organization_id = organization_code
            item.security_threat_id = req.media.get('security_threat_id')
            item.threat_level_id = req.media.get('threat_level_id')
            session.add(item)
            session.commit()

            resp.status = falcon.HTTP_CREATED
            resp.location = req.relative_uri + f'/{item.id}'
            resp.media = {'data': custom_asdict(item)}
        finally:
            session.close()
    def on_patch(self, req, resp, organization_code, it_asset_instance_id,
                 security_threat_id):
        """Updates (partially) the IT asset vulnerability requested.
        All entities that reference the IT asset vulnerability will be affected by the update.

        :param req: See Falcon Request documentation.
        :param resp: See Falcon Response documentation.
        :param organization_code: The code of organization.
        :param it_asset_instance_id: The id of IT asset instance to be patched.
        :param security_threat_id: The id of security threat.
        """
        session = Session()
        try:
            vulnerability = find_it_asset_instance_security_threat(
                security_threat_id, it_asset_instance_id, organization_code,
                session)
            if vulnerability is None:
                raise falcon.HTTPNotFound()

            errors = validate_patch(req.media, session)
            if errors:
                raise HTTPUnprocessableEntity(errors)

            accepted_fields = ['vulnerability_level_id']
            patch_item(vulnerability, req.media, only=accepted_fields)
            session.commit()

            resp.status = falcon.HTTP_OK
            resp.media = {'data': custom_asdict(vulnerability)}
        finally:
            session.close()
Exemplo n.º 10
0
    def on_patch(self, req, resp, security_threat_id):
        """Updates (partially) the security threat requested.
        All entities that reference the security threat will be affected by the update.

        :param req: See Falcon Request documentation.
        :param resp: See Falcon Response documentation.
        :param security_threat_id: The id of security threat to be patched.
        """
        session = Session()
        try:
            security_threat = session.query(SecurityThreat).get(security_threat_id)
            if security_threat is None:
                raise falcon.HTTPNotFound()

            errors = validate_patch(req.media, session)
            if errors:
                raise HTTPUnprocessableEntity(errors)

            patch_item(security_threat, req.media, only=['name', 'description'])
            session.commit()

            resp.status = falcon.HTTP_OK
            resp.media = {'data': security_threat.asdict()}
        finally:
            session.close()
Exemplo n.º 11
0
    def on_patch(self, req, resp, organization_code, it_asset_instance_id):
        """Updates (partially) the IT asset instance requested.
        All entities that reference the IT asset instance will be affected by the update.

        :param req: See Falcon Request documentation.
        :param resp: See Falcon Response documentation.
        :param organization_code: The code of organization.
        :param it_asset_instance_id: The id of IT asset instance to be patched.
        """
        session = Session()
        try:
            it_asset_instance = find_it_asset_instance(it_asset_instance_id,
                                                       organization_code,
                                                       session)
            if it_asset_instance is None:
                raise falcon.HTTPNotFound()

            errors = validate_patch(req.media, it_asset_instance,
                                    organization_code, session)
            if errors:
                raise HTTPUnprocessableEntity(errors)

            patch_item(it_asset_instance,
                       req.media,
                       only=['external_identifier'])
            session.commit()

            resp.status = falcon.HTTP_OK
            resp.media = {'data': custom_asdict(it_asset_instance)}
        finally:
            session.close()
Exemplo n.º 12
0
    def on_put(self, req, resp, user_id, role_id):
        """Adds a role to a system user.

        :param req: See Falcon Request documentation.
        :param resp: See Falcon Response documentation.
        :param user_id: The id of user.
        :param role_id: The id of role to be added.
        """
        session = Session()
        try:
            user = session.query(SystemUser).get(user_id)
            if user is None:
                raise falcon.HTTPNotFound()

            errors = validate_put(req.media, user_id, role_id, session)
            if errors:
                raise HTTPUnprocessableEntity(errors)

            # Add role if not already there
            user_role = find_user_role(user_id, role_id, session)
            if not user_role:
                user_role = SystemUserRole(user_id=user_id, role_id=role_id)
                session.add(user_role)

            session.commit()
            resp.status = falcon.HTTP_OK
            resp.media = {'data': custom_asdict(user_role)}
        finally:
            session.close()
Exemplo n.º 13
0
    def on_patch(self, req, resp, organization_code, analysis_id):
        """Updates (only allowed properties of) an analysis.

        :param req: See Falcon Request documentation.
        :param resp: See Falcon Response documentation.
        :param organization_code: The code of organization.
        :param analysis_id: The id of the analysis to be patched.
        """
        session = Session()
        try:
            analysis = find_organization_analysis(analysis_id,
                                                  organization_code, session)
            if analysis is None:
                raise falcon.HTTPNotFound()

            errors = validate_patch(req.media)
            if errors:
                raise HTTPUnprocessableEntity(errors)

            patch_item(analysis, req.media, only=['description'])
            session.commit()

            resp.status = falcon.HTTP_OK
            resp.media = {'data': custom_asdict(analysis)}
        finally:
            session.close()
Exemplo n.º 14
0
    def on_patch(self, req, resp, it_asset_category_id):
        """Updates (partially) the IT asset category requested.
        All entities that reference the IT asset category will be affected by the update.

        :param req: See Falcon Request documentation.
        :param resp: See Falcon Response documentation.
        :param it_asset_category_id: The id of IT asset category to be patched.
        """
        session = Session()
        try:
            it_asset_category = session.query(ITAssetCategory).get(
                it_asset_category_id)
            if it_asset_category is None:
                raise falcon.HTTPNotFound()

            errors = validate_patch(req.media, session)
            if errors:
                raise HTTPUnprocessableEntity(errors)

            patch_item(it_asset_category, req.media, only=['name'])
            session.commit()

            resp.status = falcon.HTTP_OK
            resp.media = {'data': it_asset_category.asdict()}
        finally:
            session.close()
Exemplo n.º 15
0
    def on_patch(self, req, resp, mitigation_control_id):
        """Updates (partially) the mitigation control requested.
        All entities that reference the mitigation control will be affected by the update.

        :param req: See Falcon Request documentation.
        :param resp: See Falcon Response documentation.
        :param mitigation_control_id: The id of mitigation control to be patched.
        """
        session = Session()
        try:
            item = session.query(MitigationControl).get(mitigation_control_id)
            if item is None:
                raise falcon.HTTPNotFound()

            errors = validate_patch(req.media, session)
            if errors:
                raise HTTPUnprocessableEntity(errors)

            patch_item(item, req.media, only=['name', 'description'])
            session.commit()

            resp.status = falcon.HTTP_OK
            resp.media = {'data': item.asdict()}
        finally:
            session.close()
Exemplo n.º 16
0
    def on_delete(self, req, resp, user_id, role_id):
        """Removes a role from a system user.

        :param req: See Falcon Request documentation.
        :param resp: See Falcon Response documentation.
        :param user_id: The id of user.
        :param role_id: The id of role to be removed.
        """
        session = Session()
        try:
            item = find_user_role(user_id, role_id, session)
            if item is None:
                raise falcon.HTTPNotFound()

            session.delete(item)
            session.commit()
        finally:
            session.close()
Exemplo n.º 17
0
    def on_delete(self, req, resp, organization_code, department_id):
        """Removes a department from an organization.

        :param req: See Falcon Request documentation.
        :param resp: See Falcon Response documentation.
        :param organization_code: The code of the organization.
        :param department_id: The id of the department to be removed.
        """
        session = Session()
        try:
            item = find_organization_department(department_id, organization_code, session)
            if item is None:
                raise falcon.HTTPNotFound()

            session.delete(item)
            session.commit()
        finally:
            session.close()
Exemplo n.º 18
0
    def on_delete(self, req, resp, organization_code, process_instance_id):
        """Removes a process from an organization's macroprocess instance.

        :param req: See Falcon Request documentation.
        :param resp: See Falcon Response documentation.
        :param organization_code: The code of the organization.
        :param process_instance_id: The id of the process instance to be removed.
        """
        session = Session()
        try:
            item = find_process_instance(process_instance_id, organization_code, session)
            if item is None:
                raise falcon.HTTPNotFound()

            session.delete(item)
            session.commit()
        finally:
            session.close()
Exemplo n.º 19
0
    def on_delete(self, req, resp, organization_code, it_asset_instance_id, control_id):
        """Removes a control from an IT asset.

        :param req: See Falcon Request documentation.
        :param resp: See Falcon Response documentation.
        :param organization_code: The code of the organization.
        :param it_asset_instance_id: The id of the IT asset instance.
        :param control_id: The id of the control to be removed.
        """
        session = Session()
        try:
            item = find_it_asset_control(control_id, it_asset_instance_id, organization_code, session)
            if item is None:
                raise falcon.HTTPNotFound()

            session.delete(item)
            session.commit()
        finally:
            session.close()
Exemplo n.º 20
0
    def on_delete(self, req, resp, organization_code, analysis_id):
        """Deletes an analysis and all its details.

        :param req: See Falcon Request documentation.
        :param resp: See Falcon Response documentation.
        :param organization_code: The code of organization.
        :param analysis_id: The id of the analysis to be deleted.
        """
        session = Session()
        try:
            analysis = find_organization_analysis(analysis_id,
                                                  organization_code, session)
            if analysis is None:
                raise falcon.HTTPNotFound()

            session.delete(analysis)
            session.commit()
        finally:
            session.close()
Exemplo n.º 21
0
    def on_patch(self, req, resp, user_id):
        """Updates (partially) the system user requested.
        All entities that reference the system user will be affected by the update.

        :param req: See Falcon Request documentation.
        :param resp: See Falcon Response documentation.
        :param user_id: The id of user to be patched.
        """
        session = Session()
        try:
            user = session.query(SystemUser).get(user_id)
            if user is None:
                raise falcon.HTTPNotFound()

            errors = validate_patch(req.media, session)
            if errors:
                raise HTTPUnprocessableEntity(errors)

            patch_item(user, req.media, only=['email', 'full_name'])

            # Update password if informed
            if 'password' in req.media:
                password = req.media.get('password')
                user.hashed_password = bcrypt.hashpw(password.encode('UTF-8'),
                                                     bcrypt.gensalt())
                user.last_modified_on = datetime.utcnow()

            # Block / Unblock user if requested
            if 'is_blocked' in req.media:
                is_blocked = req.media.get('is_blocked')
                change_block_state(is_blocked, user)

            # Unlock if requested
            if req.media.get('unlock') is True:
                user.locked_out_on = None
                user.last_modified_on = datetime.utcnow()

            session.commit()
            resp.status = falcon.HTTP_OK
            resp.media = {'data': custom_asdict(user)}
        finally:
            session.close()
Exemplo n.º 22
0
    def on_delete(self, req, resp, organization_code, security_threat_id):
        """Removes a security threat from an organization (hehe not really).

        :param req: See Falcon Request documentation.
        :param resp: See Falcon Response documentation.
        :param organization_code: The code of the organization.
        :param security_threat_id: The id of the security threat to be removed.
        """
        session = Session()
        try:
            item = find_organization_security_threat(security_threat_id,
                                                     organization_code,
                                                     session)
            if item is None:
                raise falcon.HTTPNotFound()

            session.delete(item)
            session.commit()
        finally:
            session.close()
    def on_post(self, req, resp, organization_code, it_asset_instance_id):
        """Adds a vulnerability to an IT asset of an organization.

        This represents how vulnerable an IT asset is to a security threat.
        The security threat must be previously registered for organization.

        :param req: See Falcon Request documentation.
        :param resp: See Falcon Response documentation.
        :param organization_code: The code of the organization.
        :param it_asset_instance_id: The id of the IT asset instance.
        """
        session = Session()
        try:
            it_asset_instance = find_it_asset_instance(it_asset_instance_id,
                                                       organization_code,
                                                       session)
            if it_asset_instance is None:
                raise falcon.HTTPNotFound()

            errors = validate_post(req.media, organization_code,
                                   it_asset_instance_id, session)
            if errors:
                raise HTTPUnprocessableEntity(errors)

            # Get the entry of organization security threat from security threat id supplied
            security_threat_id = req.media['security_threat_id']
            organization_security_threat = find_organization_security_threat(
                security_threat_id, organization_code, session)

            item = OrganizationITAssetVulnerability()
            item.organization_security_threat_id = organization_security_threat.id
            item.it_asset_instance_id = it_asset_instance_id
            item.vulnerability_level_id = req.media['vulnerability_level_id']
            session.add(item)
            session.commit()

            resp.status = falcon.HTTP_CREATED
            resp.location = req.relative_uri + f'/{item.id}'
            resp.media = {'data': custom_asdict(item)}
        finally:
            session.close()
Exemplo n.º 24
0
    def on_delete(self, req, resp, organization_code, macroprocess_instance_id):
        """Removes a macroprocess from an organization department.

        :param req: See Falcon Request documentation.
        :param resp: See Falcon Response documentation.
        :param organization_code: The code of the organization.
        :param macroprocess_instance_id: The id of the macroprocess instance to be removed.
        """
        session = Session()
        try:
            item = session \
                .query(OrganizationMacroprocess) \
                .filter(OrganizationMacroprocess.instance_id == macroprocess_instance_id) \
                .filter(Organization.id == organization_code) \
                .first()
            if item is None:
                raise falcon.HTTPNotFound()

            session.delete(item)
            session.commit()
        finally:
            session.close()
Exemplo n.º 25
0
    def on_post(self, req, resp, organization_code):
        """Creates a new analysis for the organization considering the already filled values
        for relevance, vulnerability and security threat levels in processes, IT services,
        IT assets and security threats.

        :param req: See Falcon Request documentation.
        :param resp: See Falcon Response documentation.
        :param organization_code: The code of the organization.
        """
        session = Session()
        try:
            organization = session.query(Organization).get(organization_code)
            if organization is None:
                raise falcon.HTTPNotFound()

            errors = validate_post(req.media)
            if errors:
                raise HTTPUnprocessableEntity(errors)

            scopes = remove_redundant_scopes(req.media.get('scopes'))
            accepted_fields = ['description']
            item = OrganizationAnalysis().fromdict(req.media,
                                                   only=accepted_fields)
            item.organization_id = organization_code
            item.total_processed_items = process_analysis(
                session, item, organization_code, scopes)

            if item.total_processed_items == 0:
                raise HTTPUnprocessableEntity(
                    [build_error(Message.ERR_NO_ITEMS_TO_ANALYZE)])

            session.add(item)
            session.commit()

            resp.status = falcon.HTTP_CREATED
            resp.location = req.relative_uri + f'/{item.id}'
            resp.media = {'data': create_response_asdict(item)}
        finally:
            session.close()
    def on_delete(self, req, resp, organization_code, it_asset_instance_id,
                  security_threat_id):
        """Removes an IT asset's vulnerability.

        :param req: See Falcon Request documentation.
        :param resp: See Falcon Response documentation.
        :param organization_code: The code of the organization.
        :param it_asset_instance_id: The id of the IT asset instance.
        :param security_threat_id: The id of security threat to be removed.
        """
        session = Session()
        try:
            item = find_it_asset_instance_security_threat(
                security_threat_id, it_asset_instance_id, organization_code,
                session)
            if item is None:
                raise falcon.HTTPNotFound()

            session.delete(item)
            session.commit()
        finally:
            session.close()
Exemplo n.º 27
0
    def on_post(self, req, resp):
        """Creates a new security threat in catalog.

        :param req: See Falcon Request documentation.
        :param resp: See Falcon Response documentation.
        """
        session = Session()
        try:
            errors = validate_post(req.media, session)
            if errors:
                raise HTTPUnprocessableEntity(errors)

            # Copy fields from request to a SecurityThreat object
            item = SecurityThreat().fromdict(req.media, only=['name', 'description'])

            session.add(item)
            session.commit()
            resp.status = falcon.HTTP_CREATED
            resp.location = req.relative_uri + f'/{item.id}'
            resp.media = {'data': item.asdict()}
        finally:
            session.close()
Exemplo n.º 28
0
    def on_post(self, req, resp):
        """Creates a new organization.

        :param req: See Falcon Request documentation.
        :param resp: See Falcon Response documentation.
        """
        session = Session()
        try:
            errors = validate_post(req.media, session)
            if errors:
                raise HTTPUnprocessableEntity(errors)

            # Copy fields from request to an Organization object
            accepted_fields = ['tax_id', 'legal_name', 'trade_name']
            item = Organization().fromdict(req.media, only=accepted_fields)

            session.add(item)
            session.commit()
            resp.status = falcon.HTTP_CREATED
            resp.location = req.relative_uri + f'/{item.id}'
            resp.media = {'data': item.asdict()}
        finally:
            session.close()
Exemplo n.º 29
0
    def on_post(self, req, resp):
        """Process login request and return access token if successful.

        :param req: See Falcon Request documentation.
        :param resp: See Falcon Response documentation.
        """
        session = Session()
        try:
            errors = validate_post(req.media)
            if errors:
                raise HTTPUnprocessableEntity(errors)

            errors, user = authenticate_user(req.media, session)

            # If user was found let's save some info whether the are errors or not
            if user:
                user_login = SystemUserLogin()
                user_login.system_user_id = user.id
                user_login.attempted_on = datetime.utcnow()
                user_login.was_successful = False if errors else True
                session.add(user_login)
                session.commit()

            # Now errors can be evaluated
            if errors:
                raise HTTPUnauthorized(errors)

            # Login successful
            id_token = generate_id_token(user)
            access_token = generate_access_token(user)

            resp.media = {
                'id_token': id_token,
                'access_token': access_token
            }
        finally:
            session.close()
    def on_patch(self, req, resp, organization_code, it_service_instance_id,
                 it_asset_instance_id):
        """Updates (partially) the relationship IT service-IT asset requested.
        All entities that reference the relationship will be affected by the update.

        :param req: See Falcon Request documentation.
        :param resp: See Falcon Response documentation.
        :param organization_code: The code of the organization.
        :param it_service_instance_id: The id of the IT service instance to be patched.
        :param it_asset_instance_id: The id of the IT asset instance to be patched.
        """
        session = Session()
        try:
            # Route params are checked in two steps:
            # 1st step: check if IT service is in organization
            # 2nd step: check if IT asset is in organization IT service
            it_service_instance = find_it_service_instance(
                it_service_instance_id, organization_code, session)
            it_service_asset = find_it_service_it_asset(
                it_asset_instance_id, it_service_instance_id, session)
            if it_service_instance is None or it_service_asset is None:
                raise falcon.HTTPNotFound()

            errors = validate_patch(req.media, organization_code, session)
            if errors:
                raise HTTPUnprocessableEntity(errors)

            patch_item(it_service_asset,
                       req.media,
                       only=['relevance_level_id'])
            session.commit()

            resp.status = falcon.HTTP_OK
            resp.media = {'data': custom_asdict(it_service_asset)}
        finally:
            session.close()