Ejemplo n.º 1
0
    def __init__(self,
                 msg_id: int = None,
                 basetable: str = None,
                 serverpk: int = None,
                 hl7run: HL7Run = None,
                 recipient_def: RecipientDefinition = None,
                 show_queue_only: bool = False) -> None:
        """Initializes.

        Use either:
            HL7Message(msg_id)
        or:
            HL7Message(basetable, serverpk, hl7run, recipient_def)
        """
        if basetable and serverpk and recipient_def:
            # HL7Message(basetable, serverpk, hl7run, recipient_def)
            rnc_db.blank_object(self, HL7Message.FIELDS)
            self.basetable = basetable
            self.serverpk = serverpk
            self.hl7run = hl7run
            if self.hl7run:
                self.run_id = self.hl7run.run_id
            self.recipient_def = recipient_def
            self.show_queue_only = show_queue_only
            self.no_saving = show_queue_only
            self.task = cc_task.task_factory(self.basetable, self.serverpk)
        else:
            # HL7Message(msg_id)
            pls.db.fetch_object_from_db_by_pk(self, HL7Message.TABLENAME,
                                              HL7Message.FIELDS, msg_id)
            self.hl7run = HL7Run(self.run_id)
Ejemplo n.º 2
0
    def __init__(self,
                 pk: int = None,
                 token: str = None,
                 ip_address: str = None) -> None:
        """Initialize. Fetch existing session from database, or create a new
        session. Perform security checks if retrieving an existing session."""
        # Fetch-or-create process. Fetching requires a PK and a matching token.
        pls.db.fetch_object_from_db_by_pk(self, Session.TABLENAME,
                                          Session.FIELDS, pk)
        expiry_if_before = pls.NOW_UTC_NO_TZ - pls.SESSION_TIMEOUT
        make_new_session = False
        if self.id is None:  # couldn't find one...
            log.debug("session id missing")
            make_new_session = True
        elif self.token is None:  # something went wrong...
            log.debug("no token")
            make_new_session = True
        elif self.token != token:  # token not what we were expecting
            log.debug(
                "token mismatch (existing = {}, incoming = {})".format(
                    self.token, token))
            make_new_session = True
        elif self.ip_address != ip_address:  # from wrong IP address
            log.debug(
                "IP address mismatch (existing = {}, incoming = {}".format(
                    self.ip_address, ip_address))
            make_new_session = True
        elif self.last_activity_utc < expiry_if_before:  # expired
            log.debug("session expired")
            make_new_session = True
        else:
            log.debug("session {} successfully loaded".format(pk))

        if make_new_session:
            # new one (meaning new not-logged-in one) for you!
            rnc_db.blank_object(self, Session.FIELDS)
            self.__set_defaults()
            self.token = generate_token()
            self.ip_address = ip_address
        self.save()  # assigns self.id if it was blank
        if make_new_session:  # after self.id has been set
            log.debug("Making new session. ID: {}. Token: {}".format(
                self.id, self.token))

        if self.user_id:
            self.userobject = cc_user.User(self.user_id)
            if self.userobject.id is not None:
                log.debug("found user: {}".format(self.username))
            else:
                log.debug("userobject had blank ID; wiping user")
                self.userobject = None
        else:
            log.debug("no user yet associated with this session")
            self.userobject = None
Ejemplo n.º 3
0
    def __init__(self, param: Union[RecipientDefinition, int]) -> None:
        if isinstance(param, RecipientDefinition):
            rnc_db.blank_object(self, HL7Run.FIELDS)
            # Copy all attributes from the RecipientDefinition
            self.__dict__.update(param.__dict__)

            self.start_at_utc = cc_dt.get_now_utc_notz()
            self.finish_at_utc = None
            self.save()
        else:
            pls.db.fetch_object_from_db_by_pk(self, HL7Run.TABLENAME,
                                              HL7Run.FIELDS, param)
Ejemplo n.º 4
0
 def anonymise(self) -> None:
     """Wipes the object's patient-identifiable content.
     Does NOT write to database."""
     # Save temporarily
     sex = self.sex
     dob = self.get_dob()
     # Wipe
     rnc_db.blank_object(self, Patient.FIELDS)
     # Replace selected values
     self.sex = sex
     if dob:
         dob = dob.replace(day=1)  # set DOB to first of the month
         self.dob = cc_dt.format_datetime(dob,
                                          DATEFORMAT.ISO8601_DATE_ONLY)
Ejemplo n.º 5
0
    def logout(self) -> None:
        """Log out, wiping session details. Also, perform periodic
        maintenance for the server, as this is a good time."""
        # First, the logout process.
        pk = self.id
        rnc_db.blank_object(self, Session.FIELDS)
        # ... wipes out any user details, plus the token, so there's no way
        # this token is being re-used
        self.id = pk
        self.save()

        # Secondly, some other things unrelated to logging out. Users will not
        # always log out manually. But sometimes they will. So we may as well
        # do some slow non-critical things:
        delete_old_sessions()
        cc_user.delete_old_account_lockouts()
        cc_user.clear_dummy_login_failures_if_necessary()
        cc_analytics.send_analytics_if_necessary()
Ejemplo n.º 6
0
def manually_erase_record_object_and_save(obj: T,
                                          table: str,
                                          fields: Iterable[str],
                                          user_id: int) -> None:
    """Manually erases a standard record and marks it so erased.
    The object remains _current, as a placeholder, but its contents are wiped.
    WRITES TO DATABASE."""
    if obj._pk is None or obj._era == ERA_NOW:
        return
    standard_task_fields = [x["name"] for x in STANDARD_TASK_FIELDSPECS]
    erasure_fields = [
        x
        for x in fields
        if x not in standard_task_fields
    ]
    rnc_db.blank_object(obj, erasure_fields)
    obj._current = False
    obj._manually_erased = True
    obj._manually_erased_at = cc_dt.format_datetime(pls.NOW_LOCAL_TZ,
                                                    DATEFORMAT.ISO8601)
    obj._manually_erasing_user_id = user_id
    pls.db.update_object_in_db(obj, table, fields)
Ejemplo n.º 7
0
    def __init__(self,
                 config: configparser.ConfigParser = None,
                 section: str = None) -> None:
        """Initialize. Possible methods:

            RecipientDefinition()
            RecipientDefinition(config, section)

        Args:
            config: configparser INI file object
            section: name of recipient and of INI file section
        """
        rnc_db.blank_object(self, RecipientDefinition.FIELDS)
        # HL7 fields not copied to database
        self.ping_first = None
        self.network_timeout_ms = None
        self.idnum_type_list = [None] * NUMBER_OF_IDNUMS
        self.idnum_aa_list = [None] * NUMBER_OF_IDNUMS
        self.keep_message = None
        self.keep_reply = None
        # File fields not copied to database (because actual filename stored):
        self.patient_spec_if_anonymous = None
        self.patient_spec = None
        self.filename_spec = None
        self.make_directory = None
        # Some default values we never want to be None
        self.include_anonymous = False
        # Internal use
        self.valid = False

        # Variable constructor...
        if config is None and section is None:
            # dummy one
            self.type = RECIPIENT_TYPE.FILE
            self.primary_idnum = 1
            self.require_idnum_mandatory = False
            self.finalized_only = False
            self.task_format = VALUE.OUTPUTTYPE_XML
            # File
            self.include_anonymous = True
            self.patient_spec_if_anonymous = "anonymous"
            self.patient_spec = "{surname}_{forename}_{idshortdesc1}{idnum1}"
            self.filename_spec = (
                "/tmp/camcops_debug_testing/"
                "TestCamCOPS_{patient}_{created}_{tasktype}-{serverpk}"
                ".{filetype}"
            )
            self.overwrite_files = False
            self.make_directory = True
            return

        assert config and section, "RecipientDefinition: bad __init__ call"

        # Standard constructor
        self.recipient = section
        try:
            self.type = get_config_parameter(
                config, section, "TYPE", str, "hl7")
            self.primary_idnum = get_config_parameter(
                config, section, "PRIMARY_IDNUM", int, None)
            self.require_idnum_mandatory = get_config_parameter_boolean(
                config, section, "REQUIRE_PRIMARY_IDNUM_MANDATORY_IN_POLICY",
                True)
            sd = get_config_parameter(
                config, section, "START_DATE", str, None)
            self.start_date = cc_dt.get_date_from_string(sd)
            ed = get_config_parameter(
                config, section, "END_DATE", str, None)
            self.end_date = cc_dt.get_date_from_string(ed)
            self.finalized_only = get_config_parameter_boolean(
                config, section, "FINALIZED_ONLY", True)
            self.task_format = get_config_parameter(
                config, section, "TASK_FORMAT", str, VALUE.OUTPUTTYPE_PDF)
            self.xml_field_comments = get_config_parameter_boolean(
                config, section, "XML_FIELD_COMMENTS", True)

            # HL7
            if self.using_hl7():
                self.host = get_config_parameter(
                    config, section, "HOST", str, None)
                self.port = get_config_parameter(
                    config, section, "PORT", int, DEFAULT_HL7_PORT)
                self.ping_first = get_config_parameter_boolean(
                    config, section, "PING_FIRST", True)
                self.network_timeout_ms = get_config_parameter(
                    config, section, "NETWORK_TIMEOUT_MS", int, 10000)
                for n in range(1, NUMBER_OF_IDNUMS + 1):
                    i = n - 1
                    nstr = str(n)
                    self.idnum_type_list[i] = get_config_parameter(
                        config, section, "IDNUM_TYPE_" + nstr, str, "")
                    self.idnum_aa_list[i] = get_config_parameter(
                        config, section, "IDNUM_AA_" + nstr, str, "")
                self.keep_message = get_config_parameter_boolean(
                    config, section, "KEEP_MESSAGE", False)
                self.keep_reply = get_config_parameter_boolean(
                    config, section, "KEEP_REPLY", False)
                self.divert_to_file = get_config_parameter(
                    config, section, "DIVERT_TO_FILE", str, None)
                self.treat_diverted_as_sent = get_config_parameter_boolean(
                    config, section, "TREAT_DIVERTED_AS_SENT", False)
                if self.divert_to_file:
                    self.host = None
                    self.port = None
                    self.ping_first = None
                    self.network_timeout_ms = None
                    self.keep_reply = None
                self.include_anonymous = False

            # File
            if self.using_file():
                self.include_anonymous = get_config_parameter_boolean(
                    config, section, "INCLUDE_ANONYMOUS", False)
                self.patient_spec_if_anonymous = get_config_parameter(
                    config, section, "PATIENT_SPEC_IF_ANONYMOUS", str,
                    "anonymous")
                self.patient_spec = get_config_parameter(
                    config, section, "PATIENT_SPEC", str, None)
                self.filename_spec = get_config_parameter(
                    config, section, "FILENAME_SPEC", str, None)
                self.overwrite_files = get_config_parameter_boolean(
                    config, section, "OVERWRITE_FILES", False)
                self.make_directory = get_config_parameter_boolean(
                    config, section, "MAKE_DIRECTORY", False)
                self.rio_metadata = get_config_parameter_boolean(
                    config, section, "RIO_METADATA", False)
                self.rio_idnum = get_config_parameter(
                    config, section, "RIO_IDNUM", int, None)
                self.rio_uploading_user = get_config_parameter(
                    config, section, "RIO_UPLOADING_USER", str, None)
                self.rio_document_type = get_config_parameter(
                    config, section, "RIO_DOCUMENT_TYPE", str, None)
                self.script_after_file_export = get_config_parameter(
                    config, section, "SCRIPT_AFTER_FILE_EXPORT", str, None)

            self.check_valid()

        except configparser.NoSectionError:
            log.warning("Config file section missing: [{}]".format(
                section
            ))
            self.valid = False