def insert_to_db(self, correlation_id=None):
     # todo ref integrity check
     execute_non_query(
         INSERT_USER_GROUP_MEMBERSHIP_SQL,
         (self.id, self.created, self.created, self.user_id, self.user_group_id),
         correlation_id,
     )
Example #2
0
def set_user_task_completed(ut_id, correlation_id=None):
    utils.validate_uuid(ut_id)
    # check that user_task exists
    result = get_user_task(ut_id, correlation_id)
    if len(result) == 0:
        errorjson = {
            "user_task_id": ut_id,
            "correlation_id": str(correlation_id)
        }
        raise utils.ObjectDoesNotExistError("user task does not exist",
                                            errorjson)

    if result[0]["project_task_status"] not in ["planned", "testing"]:
        updated_rows_count = execute_non_query(
            sql_q.UPDATE_USER_TASK_STATUS,
            (
                "complete",
                str(utils.now_with_tz()),
                str(ut_id),
            ),
            correlation_id,
        )
        assert (
            updated_rows_count == 1
        ), f"Failed to update status of user task {ut_id}; updated_rows_count: {updated_rows_count}"
Example #3
0
def update_project_task_progress_info(project_task_id, progress_info_dict,
                                      progress_info_modified, correlation_id):
    progress_info_json = json.dumps(progress_info_dict)
    number_of_updated_rows = execute_non_query(
        sql_q.UPDATE_PROJECT_TASK_SQL,
        [progress_info_json, progress_info_modified, project_task_id],
        correlation_id,
    )
    return number_of_updated_rows
Example #4
0
 def save(self):
     id = str(uuid.uuid4())
     rowcount = execute_non_query(
         SAVE_ENTITY_UPDATE_SQL,
         (
             id,
             self.modified,
             self.modified,
             self.entity_name,
             self.entity_id,
             self.json_patch.to_string(),
             self.reverse_json_patch.to_string(),
         ),
         self.correlation_id,
     )
     return rowcount
Example #5
0
 def create(self, correlation_id=None):
     return pg_utils.execute_non_query(
         sql_q.CREATE_USER_GROUP_SQL,
         params=[
             self.id,
             self.created,
             self.modified,
             self.name,
             self.short_name,
             self.url_code,
             self.demo,
             self.testing,
             self.sister_testing_group_id,
         ],
         correlation_id=correlation_id,
     )
Example #6
0
def redirect_to_user_interview_task(event, context):
    """
    Updates user task url in response to
    user_interview_task events posted by Qualtrics
    """
    detail_type = event["detail-type"]
    assert (detail_type == "user_interview_task"
            ), f"Unexpected detail-type: {detail_type}"
    event_detail = event["detail"]
    correlation_id = event["id"]
    try:
        anon_user_task_id = utils.validate_uuid(
            event_detail.pop("anon_user_task_id"))
    except KeyError as exc:
        raise utils.DetailedValueError(
            f"Mandatory {exc} data not found in source event",
            details={
                "event": event,
            },
        )

    ssm_client = SsmClient()
    vcs_param = ssm_client.get_parameter(name="video-call-system")
    ut_base_url = vcs_param["base-url"]
    user_task_url = f"{ut_base_url}?response_id={event_detail['response_id']}"

    ut_id = anon_user_task_id_2_user_task_id(anon_user_task_id,
                                             correlation_id=correlation_id)
    updated_rows_count = execute_non_query(
        sql_q.UPDATE_USER_TASK_URL,
        (
            user_task_url,
            str(utils.now_with_tz()),
            str(ut_id),
        ),
        correlation_id,
    )
    assert (
        updated_rows_count == 1
    ), f"Failed to update url of user task {ut_id}; updated_rows_count: {updated_rows_count}"

    body = {
        "user_task_id": ut_id,
        "user_task_url": user_task_url,
    }
    return {"statusCode": HTTPStatus.OK, "body": json.dumps(body)}
Example #7
0
 def thiscovery_db_dump(self):
     row_count = execute_non_query(
         sql=CREATE_USER_TASK_SQL,
         params=(
             self.id,
             self.created,
             self.created,
             self.user_project_id,
             self.project_task_id,
             self.status,
             self.consented,
             self.anon_user_task_id,
             self.user_task_url,
         ),
         correlation_id=self._correlation_id,
     )
     return row_count
def create_user_project(up_json, correlation_id, do_nothing_if_exists=False):
    """
    Inserts new UserProject row in thiscovery db

    Args:
        up_json: must contain user_id and project_id; may optionally include id, created, status, anon_project_specific_user_id
        correlation_id:
        do_nothing_if_exists:

    Returns:
    """
    # extract mandatory data from json
    try:
        user_id = utils.validate_uuid(
            up_json["user_id"])  # all public id are uuids
        project_id = utils.validate_uuid(up_json["project_id"])
    except utils.DetailedValueError as err:
        err.add_correlation_id(correlation_id)
        raise err
    except KeyError as err:
        errorjson = {
            "parameter": err.args[0],
            "correlation_id": str(correlation_id)
        }
        raise utils.DetailedValueError("mandatory data missing",
                                       errorjson) from err

    # now process optional json data
    optional_fields_name_default_and_validator = [
        ("anon_project_specific_user_id", str(uuid.uuid4()),
         utils.validate_uuid),
        ("created", str(utils.now_with_tz()), utils.validate_utc_datetime),
        ("status", DEFAULT_STATUS, validate_status),
    ]
    for (
            variable_name,
            default_value,
            validating_func,
    ) in optional_fields_name_default_and_validator:
        if variable_name in up_json:
            try:
                globals()[variable_name] = validating_func(
                    up_json[variable_name]
                )  # https://stackoverflow.com/a/4687672
            except utils.DetailedValueError as err:
                err.add_correlation_id(correlation_id)
                raise err
        else:
            globals()[variable_name] = default_value

    # id shadows builtin function, so treat if separately (using globals() approach above would overwrite that function)
    if "id" in up_json:
        try:
            id = utils.validate_uuid(up_json["id"])
        except utils.DetailedValueError as err:
            err.add_correlation_id(correlation_id)
            raise err
    else:
        id = str(uuid.uuid4())

    # check external account does not already exist
    existing = get_existing_user_project_id(user_id, project_id,
                                            correlation_id)
    if len(existing) > 0:
        if do_nothing_if_exists:
            return existing[0]
        else:
            errorjson = {
                "user_id": user_id,
                "project_id": project_id,
                "correlation_id": str(correlation_id),
            }
            raise utils.DuplicateInsertError("user_project already exists",
                                             errorjson)

    # lookup user id (needed for insert) for user uuid (supplied in json)
    result = get_user_by_id(user_id, correlation_id)
    if len(result) == 0:
        errorjson = {"user_id": user_id, "correlation_id": str(correlation_id)}
        raise utils.ObjectDoesNotExistError("user does not exist", errorjson)

    execute_non_query(
        CREATE_USER_PROJECT_SQL,
        (
            id,
            created,
            created,
            user_id,
            project_id,
            status,
            anon_project_specific_user_id,
        ),
        correlation_id,
    )

    new_user_project = {
        "id": id,
        "created": created,
        "modified": created,
        "user_id": user_id,
        "project_id": project_id,
        "status": status,
        "anon_project_specific_user_id": anon_project_specific_user_id,
    }

    return new_user_project
Example #9
0
def create_user(user_json, correlation_id):
    # json MUST contain: email, first_name, last_name, status
    # json may OPTIONALLY include: id, title, created, auth0_id
    # note that users will always be created with email_address_verified = false

    # extract mandatory data from json
    try:
        email = user_json["email"].lower().strip()
        first_name = user_json["first_name"].strip()
        last_name = user_json["last_name"].strip()
        status = validate_status(user_json["status"])
        country_code = user_json["country_code"].strip()
        country_utils.get_country_name(country_code)
        # looking up the name is a way of validating the code - an invalid code will raise an error
    except utils.DetailedValueError as err:
        err.add_correlation_id(correlation_id)
        raise err

    # now process optional json data
    if "id" in user_json:
        try:
            id = utils.validate_uuid(user_json["id"])
        except utils.DetailedValueError as err:
            err.add_correlation_id(correlation_id)
            raise err
    else:
        id = str(uuid.uuid4())

    if "created" in user_json:
        try:
            created = utils.validate_utc_datetime(user_json["created"])
        except utils.DetailedValueError as err:
            err.add_correlation_id(correlation_id)
            raise err
    else:
        created = str(utils.now_with_tz())

    if "auth0_id" in user_json:
        auth0_id = user_json["auth0_id"]
    else:
        auth0_id = None

    if "title" in user_json:
        title = user_json["title"]
    else:
        title = None

    existing_user = get_user_by_id(id, correlation_id)
    if len(existing_user) > 0:
        errorjson = {"id": id, "correlation_id": str(correlation_id)}
        raise utils.DuplicateInsertError("user already exists", errorjson)

    params = (
        id,
        created,
        created,
        email,
        title,
        first_name,
        last_name,
        country_code,
        auth0_id,
        status,
    )
    execute_non_query(sql_q.CREATE_USER_SQL, params, correlation_id)

    new_user = {
        "id": id,
        "created": created,
        "modified": created,
        "email": email,
        "title": title,
        "first_name": first_name,
        "last_name": last_name,
        "auth0_id": auth0_id,
        "crm_id": None,
        "country_code": country_code,
        "status": status,
    }

    new_user = append_calculated_properties(new_user)

    return new_user
Example #10
0
def clear_user_tasks_for_project_task_id(project_task_id):
    return execute_non_query(
        sql=sql_q.DELETE_USER_TASKS_FOR_PROJECT_TASK_SQL,
        params=(project_task_id, ),
    )
def create_user_external_account(uea_json, correlation_id):
    # json MUST contain: external_system_id, user_id, external_user_id
    # json may OPTIONALLY include: id, created, status

    # extract mandatory data from json
    try:
        external_system_id = utils.validate_uuid(
            uea_json["external_system_id"])
        user_id = utils.validate_uuid(uea_json["user_id"])
        external_user_id = uea_json["external_user_id"]
    except utils.DetailedValueError as err:
        err.add_correlation_id(correlation_id)
        raise err
    except KeyError as err:
        errorjson = {
            "parameter": err.args[0],
            "correlation_id": str(correlation_id)
        }
        raise utils.DetailedValueError("mandatory data missing",
                                       errorjson) from err

    # now process optional json data
    if "id" in uea_json:
        try:
            id = utils.validate_uuid(uea_json["id"])
        except utils.DetailedValueError as err:
            err.add_correlation_id(correlation_id)
            raise err
    else:
        id = str(uuid.uuid4())

    if "created" in uea_json:
        try:
            created = utils.validate_utc_datetime(uea_json["created"])
        except utils.DetailedValueError as err:
            err.add_correlation_id(correlation_id)
            raise err
    else:
        created = str(utils.now_with_tz())

    if "status" in uea_json:
        try:
            status = validate_status(uea_json["status"])
        except utils.DetailedValueError as err:
            err.add_correlation_id(correlation_id)
            raise err
    else:
        status = DEFAULT_STATUS

    # check external account does not already exist
    existing = check_user_id_and_external_account(user_id, external_system_id,
                                                  correlation_id)
    if len(existing) > 0:
        errorjson = {
            "user_id": user_id,
            "external_system_id": external_system_id,
            "correlation_id": str(correlation_id),
        }
        raise utils.DuplicateInsertError(
            "user_external_account already exists", errorjson)

    # lookup user id (needed for insert) for user uuid (supplied in json)
    existing_user = get_user_by_id(user_id, correlation_id)
    if len(existing_user) == 0:
        errorjson = {"user_id": user_id, "correlation_id": str(correlation_id)}
        raise utils.ObjectDoesNotExistError("user does not exist", errorjson)

    execute_non_query(
        CREATE_USER_EXTERNAL_ACCOUNT_SQL,
        (id, created, created, external_system_id, user_id, external_user_id,
         status),
        correlation_id,
    )

    new_user_external_account = {
        "id": id,
        "created": created,
        "modified": created,
        "external_system_id": external_system_id,
        "user_id": user_id,
        "external_user_id": external_user_id,
        "status": status,
    }

    return new_user_external_account