class DbHandlerTests(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        pass

    @classmethod
    def tearDownClass(cls):
        pass

    def setUp(self):
        # create a connection to test database
        self.db = DbHandler()
        # default pre-configured user
        self.user_id = "aaa10022-38b0-4a1a-95af-776f35aa2b8f"

    def tearDown(self):
        pass

    def test_get_participant(self):
        participant = self.db.get_participant(self.user_id)
        self.assertNotEqual(participant, None)
        self.assertEqual(participant[1], self.user_id)
Exemple #2
0
class InputValidator:
    def __init__(self):
        self.db = DbHandler()

    # internal methods to check validity of inputs
    def _is_user_id_valid(self, user_id):
        # check if user id is a valid UUIDv4
        try:
            uuid_obj = uuid.UUID(user_id, version=4)
        except ValueError:
            return False

        # check if UUID object is the same as the input string
        if str(uuid_obj) != user_id:
            return False

        # check if we have a participant for the input user id
        data = self.db.get_participant(user_id)
        if data is None:
            return False

        return True

    def _is_ref_domain_valid(self, ref_domain):
        ref_domains = [elem[0] for elem in self.db.get_all_ref_domains()]
        if ref_domain in ref_domains:
            return True

        return False

    def _is_created_domain_valid(self, created_domain):
        # check if special characters are in created domain
        if any([
                char in created_domain for char in [
                    "_", "<", ">", "&", "'", "\"", "=", "[", "]", "(", ")",
                    "%", "$", "?", "#", "*", "+", "/", " ", ",", ";", ":"
                ]
        ]):
            return False

        return True

    def _is_valid_integer(self, test_string):
        try:
            int(test_string)
            return True
        except ValueError:
            return False

    def _is_rated_domain_valid(self, rated_domain):
        test_domains = [elem[0] for elem in self.db.get_all_test_domains()]
        if rated_domain in test_domains:
            return True

        ref_domains = [elem[0] for elem in self.db.get_all_ref_domains()]
        if rated_domain in ref_domains:
            return True

        step1_domains = [elem[0] for elem in self.db.get_all_step1_domains()]
        if rated_domain in step1_domains:
            return True

        return False

    def check_input_user_id(self, user_id):
        if self._is_user_id_valid(user_id) is False:
            return {"result": False, "message": "Invalid user ID!"}

        return {"result": True, "message": ""}

    def check_last_unfinished_step(self, user_id, step_id):
        if os.environ["CHECK_LAST_UNFINISHED_STEP"] == "1":
            data = self.db.get_participant(user_id)
            current_step = "step1"
            if data[7] == 1:
                current_step = "step2"
            if data[8] == 1:
                current_step = "step3"
            if data[9] == 1:
                current_step = "step4"
            if data[10] == 1:
                current_step = "step5"
            if data[11] == 1:
                current_step = "questionnaire"
            if data[12] == 1:
                current_step = "final_notes"

            if current_step != step_id:
                return {"result": True, "current_step": current_step}
        else:
            return {"result": False, "current_step": "test"}

        return {"result": False, "current_step": ""}

    def check_log_time(self, user_id, time_type, time):
        valid_time_types = ["experiment_start_time", "experiment_end_time",\
                            "step1_start_time", "step1_end_time",\
                            "step2_start_time", "step2_end_time",\
                            "step3_start_time", "step3_end_time",\
                            "step4_start_time", "step4_end_time",\
                            "step5_start_time", "step5_end_time",\
                            "questionnaire_start_time", "questionnaire_end_time"]
        if self._is_user_id_valid(user_id) is False:
            return {"result": False, "message": "Invalid user ID!"}
        if time_type not in valid_time_types:
            return {"result": False, "message": "Invalid time type!"}
        if self._is_valid_integer(time) is False:
            return {"result": False, "message": "Invalid current time!"}

        return {"result": True, "message": ""}

    def check_input_set_step_finished(self, user_id, step_id):
        if self._is_user_id_valid(user_id) is False:
            return {"result": False, "message": "Invalid user ID!"}
        if step_id not in ["step1", "step2", "step3", "step4", "step5"]:
            return {"result": False, "message": "Invalid step ID!"}

        return {"result": True, "message": ""}

    def check_input_step1_result(self, user_id, ref_domain, created_domain,
                                 elapsed_time, domain_position):
        if self.db.get_count("step1", user_id)[0] >= 10:
            return {
                "result": False,
                "message": "Already created maximum number of domains!"
            }
        if self.db.is_step_finished(user_id, "finished_step1") is not None:
            return {"result": False, "message": "Step is already finished!"}
        if self._is_user_id_valid(user_id) is False:
            return {"result": False, "message": "Invalid user ID!"}
        if self._is_ref_domain_valid(ref_domain) is False:
            return {"result": False, "message": "Invalid reference domain!"}
        if self._is_created_domain_valid(created_domain) is False:
            return {"result": False, "message": "Invalid created domain!"}
        if self._is_valid_integer(elapsed_time) is False:
            return {"result": False, "message": "Invalid elapsed time!"}
        if self._is_valid_integer(domain_position) is False:
            return {"result": False, "message": "Invalid domain position!"}

        return {"result": True, "message": ""}

    def check_input_step2_result(self, user_id, ref_domain, squatting_technique, squatting_technique_infos,\
                                 created_domain, elapsed_time, domain_position, squatting_techniques_order):
        valid_squatting_techniques = [
            "wrong_tld", "homograph", "typosquatting", "combosquatting",
            "subdomain"
        ]
        valid_squatting_technique_infos = ["", "prepend_www", "omit_character", "duplicate_character",\
                                           "swap_characters", "replace_qwerty", "none_before_none_behind",\
                                           "term_before_none_behind", "chars_before_none_behind",\
                                           "none_before_term_behind", "none_before_chars_behind",\
                                           "term_before_term_behind", "chars_before_chars_behind",\
                                           "chars_before_term_behind", "term_before_chars_behind"]

        if self.db.get_count("step2", user_id)[0] >= 10:
            return {
                "result": False,
                "message": "Already created maximum number of domains!"
            }
        if self.db.is_step_finished(user_id, "finished_step2") is not None:
            return {"result": False, "message": "Step is already finished!"}
        if self._is_user_id_valid(user_id) is False:
            return {"result": False, "message": "Invalid user ID!"}
        if self._is_ref_domain_valid(ref_domain) is False:
            return {"result": False, "message": "Invalid reference domain!"}
        if squatting_technique not in valid_squatting_techniques:
            return {"result": False, "message": "Invalid squatting technique!"}
        if squatting_technique_infos not in valid_squatting_technique_infos:
            return {
                "result": False,
                "message": "Invalid squatting technique infos!"
            }
        if self._is_created_domain_valid(created_domain) is False:
            return {"result": False, "message": "Invalid created domain!"}
        if self._is_valid_integer(elapsed_time) is False:
            return {"result": False, "message": "Invalid elapsed time!"}
        if self._is_valid_integer(domain_position) is False:
            return {"result": False, "message": "Invalid domain position!"}
        if set(squatting_techniques_order.split(",")) != set(
                valid_squatting_techniques):
            return {
                "result": False,
                "message": "Invalid order of squatting techniques!"
            }

        return {"result": True, "message": ""}

    def check_input_step3_result(self, user_id, rated_domain, type,
                                 elapsed_time, rating, domain_position):
        if self.db.get_step3_rated_domains_count(user_id) >= 30:
            return {
                "result": False,
                "message": "Already created maximum number of domains!"
            }
        if self.db.is_step_finished(user_id, "finished_step3") is not None:
            return {"result": False, "message": "Step is already finished!"}
        if self._is_user_id_valid(user_id) is False:
            return {"result": False, "message": "Invalid user ID!"}
        if self._is_rated_domain_valid(rated_domain) is False:
            return {"result": False, "message": "Invalid rated domain!"}
        if type not in ["step1", "ref_domain", "phishing_domain"]:
            return {"result": False, "message": "Invalid domain type!"}
        if self._is_valid_integer(elapsed_time) is False:
            return {"result": False, "message": "Invalid elapsed time!"}
        if rating not in ["1", "2", "3", "4", "5"]:
            return {"result": False, "message": "Invalid rating!"}
        if int(domain_position) < 1 or int(domain_position) > 30:
            return {"result": False, "message": "Invalid domain position!"}

        return {"result": True, "message": ""}

    def check_input_step4_result(self, user_id, created_domain, elapsed_time,
                                 domain_position):
        if self.db.get_count("step4", user_id)[0] >= 10:
            return {
                "result": False,
                "message": "Already created maximum number of domains!"
            }
        if self.db.is_step_finished(user_id, "finished_step4") is not None:
            return {"result": False, "message": "Step is already finished!"}
        if self._is_user_id_valid(user_id) is False:
            return {"result": False, "message": "Invalid user ID!"}
        if self._is_created_domain_valid(created_domain) is False:
            return {"result": False, "message": "Invalid created domain!"}
        if self._is_valid_integer(elapsed_time) is False:
            return {"result": False, "message": "Invalid elapsed time!"}
        if self._is_valid_integer(domain_position) is False:
            return {"result": False, "message": "Invalid domain position!"}

        return {"result": True, "message": ""}

    def check_input_step5_result(self, user_id, selected_domains, elapsed_time,
                                 counter):
        if self.db.get_count("step5", user_id)[0] >= 10:
            return {
                "result": False,
                "message": "Already created maximum number of domains!"
            }
        if self.db.is_step_finished(user_id, "finished_step5") is not None:
            return {"result": False, "message": "Step is already finished!"}
        if self._is_user_id_valid(user_id) is False:
            return {"result": False, "message": "Invalid user ID!"}
        if selected_domains.count(",") != 30 or selected_domains.count(
                ";") != 9:
            return {"result": False, "message": "Invalid selected domains!"}
        if self._is_valid_integer(elapsed_time) is False:
            return {"result": False, "message": "Invalid elapsed time!"}
        if self._is_valid_integer(counter) is False:
            return {"result": False, "message": "Invalid counter!"}

        return {"result": True, "message": ""}

    def check_input_questionnaire_result(self, user_id, age, gender_current, education, origin,\
                                         f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12,\
                                         f13, f14, f15, f16, attention_test1, attention_test2):
        countries = [elem[0] for elem in self.db.get_countries()]
        if self._is_user_id_valid(user_id) is False:
            return {"result": False, "message": "Invalid user ID!"}
        if age not in [
                "18_25", "26_35", "36_45", "46_55", "over_55", "not_answer"
        ]:
            return {"result": False, "message": "Invalid age!"}
        if gender_current not in [
                "male", "female", "non_binary", "transgender", "other",
                "not_answer"
        ]:
            return {"result": False, "message": "Invalid current gender!"}
        if education not in ["less_high_school", "high_school", "associate", "no_degree",\
                             "bachelor", "master", "over_master", "not_answer"]:
            return {"result": False, "message": "Invalid education!"}
        if origin not in countries:
            return {"result": False, "message": "Invalid origin!"}

        sebis_valid_answers = [
            "never", "rarely", "sometimes", "often", "always"
        ]
        if f1 not in sebis_valid_answers:
            return {"result": False, "message": "Invalid f1!"}
        if f2 not in sebis_valid_answers:
            return {"result": False, "message": "Invalid f2!"}
        if f3 not in sebis_valid_answers:
            return {"result": False, "message": "Invalid f3!"}
        if f4 not in sebis_valid_answers:
            return {"result": False, "message": "Invalid f4!"}
        if f5 not in sebis_valid_answers:
            return {"result": False, "message": "Invalid f5!"}
        if f6 not in sebis_valid_answers:
            return {"result": False, "message": "Invalid f6!"}
        if f7 not in sebis_valid_answers:
            return {"result": False, "message": "Invalid f7!"}
        if f8 not in sebis_valid_answers:
            return {"result": False, "message": "Invalid f8!"}
        if f9 not in sebis_valid_answers:
            return {"result": False, "message": "Invalid f9!"}
        if f10 not in sebis_valid_answers:
            return {"result": False, "message": "Invalid f10!"}
        if f11 not in sebis_valid_answers:
            return {"result": False, "message": "Invalid f11!"}
        if f12 not in sebis_valid_answers:
            return {"result": False, "message": "Invalid f12!"}
        if f13 not in sebis_valid_answers:
            return {"result": False, "message": "Invalid f13!"}
        if f14 not in sebis_valid_answers:
            return {"result": False, "message": "Invalid f14!"}
        if f15 not in sebis_valid_answers:
            return {"result": False, "message": "Invalid f15!"}
        if f16 not in sebis_valid_answers:
            return {"result": False, "message": "Invalid f16!"}

        if attention_test1 not in sebis_valid_answers:
            return {"result": False, "message": "Invalid attention 1!"}
        if attention_test2 not in sebis_valid_answers:
            return {"result": False, "message": "Invalid attention 2!"}

        return {"result": True, "message": ""}

    def check_input_final_notes_feedback(self, user_id, feedback):
        if self._is_user_id_valid(user_id) is False:
            return {"result": False, "message": "Invalid user ID!"}
        if len(feedback) > 500:
            feedback_length = len(feedback) - 500
            return {
                "result":
                False,
                "message":
                "Feedback is " + str(feedback_length) + " characters too long!"
            }
        if any([
                char in feedback for char in [
                    "<", ">", "&", "'", "\"", "=", "(", ")", "%", "$", "?",
                    "#", "*", "+", "/"
                ]
        ]):
            return {"result": False, "message": "Not allowed characters used!"}

        return {"result": True, "message": ""}