def tp_master(config_id, index):
    """
    Iframed master website view which creates a cookie from the four segments and logs the visit for the user
    :param index: which split URL called this master URL
    :return: HTTP response for this master URL website
    """
    check_referer(request, URLS['TP_MASTER_URL'])
    ip = request.access_route[0]
    site = unquote(request.args.get('id', None))

    # Doesn't render this history view template until the other segments of the cookie (index 1-3) are loaded.
    if index != '4':
        return render_template(THIRD_PARTY_MASTER_TEMPLATE)

    # Creates a cookie based on the four separate segments concatenated together.
    joined_uuid = redis_retrieve_join(ip, site)
    if joined_uuid is None:
        return render_template(THIRD_PARTY_MASTER_TEMPLATE)

    # Logs the visited site by the joined user (from the separate segments), and generates the history table to display
    # to manual people using the benchmark site
    joined_user = JoinedTrackableUUID.get_or_create(joined_uuid)
    log_site_visit(JoinedHistory, site, joined_user, ip)
    recent_history = generate_recent_history(JoinedHistory, joined_user, 10)
    # Records the recently visited site fot the benchmark
    redis_set_benchmark_recent_site(config_id, '3', site)

    return render_template(THIRD_PARTY_MASTER_TEMPLATE,
                           history_log=recent_history,
                           trackable=True,
                           uuid=joined_uuid)
def tp_single_cookie(config_id):
    """
    View to render the third party iframe and track the user via cookies.
    """
    check_referer(request, URLS['TP_URL'])

    # Ensures the cookie is of the right length (based on the configuration)
    config_cookie_length = implicit_user_login(User, config_id).cookie_size

    # Gets what the third party perceives to be a user (based on the cookie it sets)
    uuid = request.cookies.get('id')
    trackable_user = implicit_user_login(TrackableUUID, uuid, config_cookie_length)

    # Generates a history log to display to a manual viewer of the site (so they can see the tracking in action)
    log_site_visit(History, request.referrer, trackable_user, request.access_route[0])
    recent_history = generate_recent_history(History, trackable_user, 10)
    if uuid is not None:
        # Sets the benchmark result of the recently visited site
        redis_set_benchmark_recent_site(config_id, '2', request.referrer)

    response = make_response(
        render_template(THIRD_PARTY_SINGLE_TEMPLATE, history_log=recent_history, current_url=request.url_root,
                        cookie_id=uuid))
    # Sets a cookie for the user if not done before
    if uuid is None:
        response = append_cookie(response, trackable_user.uuid)
    return response
def tp_split_1(config_id):
    """
    Iframed split third party URL which records the first segment of the cookie (used to identify the user)
    """
    check_referer(request, URLS['TP_SPLIT_URL_1'])

    # Ensures the cookie is of the right length (based on the configuration)
    config_cookie_length = implicit_user_login(User,
                                               config_id).split_cookie_size

    # Gets what the third party perceives to be a first segment of the user (based on the cookie segment it sets)
    uuid = get_uuid_from_cookies(request, 'id', config_cookie_length)
    trackable_uuid_1 = SplitTrackableUUID1.get_or_create(
        uuid, config_cookie_length)

    # Logs the site visited for this segment
    log_site_visit(SplitHistoryBase1, request.referrer, trackable_uuid_1,
                   request.access_route[0])
    redis_register_split('1', request.access_route[0], trackable_uuid_1.uuid,
                         request.referrer)

    response = make_response(
        render_template(THIRD_PARTY_SPLIT_TEMPLATE,
                        current_url=request.url_root,
                        urls=URLS,
                        cookie_id=uuid,
                        safe_referer=request.referrer,
                        index=1,
                        config_id=config_id))
    # Sets a cookie for this segment if not done before
    if uuid is None:
        response = append_cookies(response, 'id', trackable_uuid_1.uuid)
    return response
def tp_split_2(config_id):
    """
    Iframed split third party URL which records the second segment of the cookie (used to identify the user)
    Functions similar to tp_split_1 above.
    """
    check_referer(request, URLS['TP_SPLIT_URL_2'])
    config_cookie_length = implicit_user_login(User,
                                               config_id).split_cookie_size

    time.sleep(0.4)

    uuid = get_uuid_from_cookies(request, 'id', config_cookie_length)
    trackable_uuid_2 = SplitTrackableUUID2.get_or_create(
        uuid, config_cookie_length)

    log_site_visit(SplitHistoryBase2, request.referrer, trackable_uuid_2,
                   request.access_route[0])
    redis_register_split('2', request.access_route[0], trackable_uuid_2.uuid,
                         request.referrer)

    response = make_response(
        render_template(THIRD_PARTY_SPLIT_TEMPLATE,
                        current_url=request.url_root,
                        urls=URLS,
                        cookie_id=uuid,
                        safe_referer=request.referrer,
                        index=2,
                        config_id=config_id))
    if uuid is None:
        response = append_cookies(response, 'id', trackable_uuid_2.uuid)
    return response
def tp_split_chain_1(config_id):
    """
    Iframed chained third party URL which records the first segment of the cookie (used to identify the user)
    Functions similar to tp_split_1 above.
    """
    check_referer(request, URLS['TP_SPLIT_URL_1'])
    config_cookie_length = implicit_user_login(User,
                                               config_id).split_cookie_size

    uuid = get_uuid_from_cookies(request, 'id', config_cookie_length)
    trackable_uuid_1 = SplitTrackableUUID1.get_or_create(
        uuid, config_cookie_length)

    response = make_response(
        render_template(THIRD_PARTY_SPLIT_CHAIN_TEMPLATE,
                        current_url=request.url_root,
                        urls=URLS,
                        cookie_id=uuid,
                        safe_referer=request.referrer,
                        index=1,
                        combined_id=uuid,
                        config_id=config_id))
    if uuid is None:
        response = append_cookies(response, 'id', trackable_uuid_1.uuid)
    return response
def tp_split_chain_3(config_id, cookie_id):
    """
    Iframed chained third party URL which records the third segment of the cookie (used to identify the user)
    Functions similar to tp_split_1 above.
    """
    check_referer(request, URLS['TP_SPLIT_URL_3'])
    config_cookie_length = implicit_user_login(User,
                                               config_id).split_cookie_size

    uuid = get_uuid_from_cookies(request, 'id', config_cookie_length)
    trackable_uuid_3 = SplitTrackableUUID3.get_or_create(
        uuid, config_cookie_length)

    # Builds up the cookie by appending the fist and second cookie segments to the third to create a combined string
    if cookie_id != 'None' and uuid is not None:
        cookie_id += uuid

    site = request.args.get('ref', None)

    response = make_response(
        render_template(THIRD_PARTY_SPLIT_CHAIN_TEMPLATE,
                        current_url=request.url_root,
                        urls=URLS,
                        cookie_id=uuid,
                        safe_referer=site,
                        index=3,
                        combined_id=cookie_id,
                        config_id=config_id))
    if uuid is None:
        response = append_cookies(response, 'id', trackable_uuid_3.uuid)
    return response
def fp_malicious_3(config_id):
    """
    The malicious first party website number 3.

    :return: the HTTP template for the first party site OR a redirect to the configuration page (if first time user
    of the benchmark).
    """
    if config_id is None:
        return redirect_config()
    else:
        check_referer(request, URLS['FP_URL_MALICIOUS_3'] + config_id)
        return fp_malicious(URLS['FP_URL_MALICIOUS_3'], config_id)
def fp_2(config_id):
    """
    The first party website number 2.

    :return: the HTTP template for the first party site OR a redirect to the configuration page (if first time user
    of the benchmark).
    """
    if config_id is None:
        return redirect_config()
    else:
        check_referer(request, URLS['FP_URL_2'] + config_id)
        return config_switch(URLS['FP_URL_2'], config_id)
def tp_split_super_chain_1_data(config_id, uuid):
    check_referer(request, URLS['TP_SPLIT_SUPER_URL_1'])

    site = unquote(request.args.get('id', None))

    response = make_response(
        render_template(THIRD_PARTY_SPLIT_CHAIN_SUPER_COOKIE_DATA_TEMPLATE,
                        current_url=request.url_root,
                        urls=URLS,
                        cookie_id=uuid,
                        safe_referer=site,
                        index=1,
                        combined_id=uuid,
                        config_id=config_id))
    return response
def tp_split_super_chain_1(config_id):
    check_referer(request, URLS['TP_SPLIT_SUPER_URL_1'])
    config_cookie_length = implicit_user_login(
        User, config_id).local_storage_split_super_cookie_size

    next_site = URLS[
        'TP_SPLIT_SUPER_URL_1'] + 'tp-split-super-chain-1-data/' + config_id

    response = make_response(
        render_template(THIRD_PARTY_SPLIT_CHAIN_SUPER_COOKIE_TEMPLATE,
                        current_url=request.url_root,
                        next_site=next_site,
                        safe_referer=request.referrer,
                        config_cookie_length=config_cookie_length,
                        combined_id=""))
    return response
def config_checkbox():
    """
    This view loads the configuration page and handles the form.

    :return: HTTP response for the configuration page.
    """
    # Gets the user
    check_referer(request, URLS['CONFIG_URL'])
    uuid = request.cookies.get('id')
    user = implicit_user_login(User, uuid)
    form = TrackerForm(meta={'csrf': False})

    # Sets up the form with the users current configuration settings preselected
    if request.method == 'GET':
        form.tracker.default = user.mode
        form.tracker.data = user.mode
        form.first_party_cookie_size.data = user.first_party_cookie_size
        form.first_party_cookie_size.default = user.first_party_cookie_size
        form.cookie_size.default = user.cookie_size
        form.cookie_size.data = user.cookie_size
        form.split_cookie_size.default = user.split_cookie_size
        form.split_cookie_size.data = user.split_cookie_size
        form.local_storage_super_cookie_size.default = user.local_storage_super_cookie_size
        form.local_storage_super_cookie_size.data = user.local_storage_super_cookie_size
        form.local_storage_split_super_cookie_size.default = user.local_storage_split_super_cookie_size
        form.local_storage_split_super_cookie_size.data = user.local_storage_split_super_cookie_size

    # Changes the users configuration based on the settings chosen in the form
    elif form.validate_on_submit():
        user.mode = form.tracker.data
        user.first_party_cookie_size = form.first_party_cookie_size.data
        user.cookie_size = form.cookie_size.data
        user.split_cookie_size = form.split_cookie_size.data
        user.local_storage_super_cookie_size = form.local_storage_super_cookie_size.data
        user.local_storage_split_super_cookie_size = form.local_storage_split_super_cookie_size.data
        db.session.commit()

    response = make_response(
        render_template(CONFIG_TEMPLATE,
                        urls=URLS,
                        form=form,
                        user=user,
                        config_id=user.uuid))
    if uuid is None:
        response = append_cookie(response, user.uuid)
    return response
def tp_split_chain_master(config_id, cookie_id):
    """
    Iframed chained third party URL which records the third segment of the cookie (used to identify the user)
    Functions similar to tp_split_1 above.
    """
    check_referer(request, URLS['TP_SPLIT_URL_4'])
    config_cookie_length = implicit_user_login(User,
                                               config_id).split_cookie_size

    uuid = get_uuid_from_cookies(request, 'id', config_cookie_length)
    trackable_uuid_4 = SplitTrackableUUID4.get_or_create(
        uuid, config_cookie_length)

    trackable = False

    site = unquote(request.args.get('ref', None))

    # Builds up the completed cookie by appending the fist, second and third cookie segments to the fourth to create a
    # unique identifier
    if cookie_id != 'None' and uuid is not None:
        cookie_id += uuid
        trackable = True
        redis_set_benchmark_recent_site(config_id, '4', site)

    # Records the site visited by what the third party perceives as the unique user (from the combined string)
    joined_user = JoinedTrackableUUID.get_or_create(cookie_id)
    log_site_visit(JoinedHistory, site, joined_user, request.referrer)
    recent_history = generate_recent_history(JoinedHistory, joined_user, 10)

    response = make_response(
        render_template(THIRD_PARTY_CHAIN_MASTER_TEMPLATE,
                        current_url=request.url_root,
                        urls=URLS,
                        cookie_id=uuid,
                        history_log=recent_history,
                        index=4,
                        combined_id=cookie_id,
                        trackable=trackable,
                        config_id=config_id))
    # Sets a cookie for this combined string which identifies a user if not done before
    if uuid is None:
        response = append_cookies(response, 'id', trackable_uuid_4.uuid)
    return response
def tp_split_super_chain_master_data(config_id, uuid):
    check_referer(request, URLS['TP_SPLIT_SUPER_URL_4'])

    site = unquote(request.args.get('id', None))

    joined_user = JoinedTrackableUUID.get_or_create(uuid)
    log_site_visit(JoinedHistory, site, joined_user, request.referrer)
    redis_set_benchmark_recent_site(config_id, '6', site)
    recent_history = generate_recent_history(JoinedHistory, joined_user, 10)

    response = make_response(
        render_template(THIRD_PARTY_CHAIN_MASTER_TEMPLATE,
                        current_url=request.url_root,
                        urls=URLS,
                        cookie_id=uuid,
                        history_log=recent_history,
                        index=4,
                        combined_id=uuid,
                        trackable=True,
                        config_id=config_id))
    return response
def tp_super_cookie(config_id):
    """
    Iframed website by the first party which in its client side template, generates a super cookie (by localStorage).
    It then redirects to the view function above which records the user with this client side UUID.

    :return: HTTP response which generates a localStorage super cookie if not already set via javascipt (see the
    template) and then redirects to a new URL to transfer this client side cookie to server side.
    """
    check_referer(request, URLS['TP_SUPER_COOKIE_URL'])
    config_cookie_length = implicit_user_login(
        User, config_id).local_storage_super_cookie_size

    # The site to redirect to.
    next_site = URLS[
        'TP_SUPER_COOKIE_URL'] + 'tp-super-cookie-data/' + config_id

    response = make_response(
        render_template(THIRD_PARTY_SUPER_COOKIE_TEMPLATE,
                        current_url=request.url_root,
                        next_site=next_site,
                        safe_referer=request.referrer,
                        config_cookie_length=config_cookie_length))
    return response
def start_benchmark():
    """
    Starts the benchmark by going the the start of the nested loop
    :return: HTTP response for the start of the nested redirect loop found in the benchmark package/
    """
    check_referer(request, URLS['CONFIG_URL'])
    uuid = request.cookies.get('id')
    user = implicit_user_login(User, uuid)

    # Starts testing from the first mode
    user.mode = '1'

    # Clears the most recent benchmark results in preparation for the new benchmark
    user.first_party_test_result = 'Untested'
    user.third_party_test_result = 'Untested'
    user.third_party_split_result = 'Untested'
    user.third_party_split_chain_result = 'Untested'
    user.third_party_super_cookie_result = 'Untested'
    user.third_party_split_super_cookie_result = 'Untested'
    db.session.commit()

    # returns the HTTP redirect response for the starting benchmark loop
    return redirect(URLS['FP_URL_1'] + 'benchmark/' + user.uuid + '/' +
                    user.mode + '/0')
def tp_super_cookie_data(config_id, uuid):
    """
    Iframed website that is redirected into from the function below. This gets the UUID from the URL parameter and
    creates a history log for this UUID.

    :param uuid: Generated client side, this supercookie identifies the user.
    :return: HTTP response which displays the history log for this perceived user
    """
    check_referer(request, URLS['TP_SUPER_COOKIE_URL'])
    trackable_user = JoinedTrackableUUID.get_or_create(uuid)

    site = unquote(request.args.get('id', None))

    log_site_visit(JoinedHistory, site, trackable_user,
                   request.access_route[0])
    redis_set_benchmark_recent_site(config_id, '5', site)

    recent_history = generate_recent_history(JoinedHistory, trackable_user, 10)
    response = make_response(
        render_template(THIRD_PARTY_SINGLE_TEMPLATE,
                        history_log=recent_history,
                        current_url=request.url_root,
                        cookie_id=uuid))
    return response
def config_switch(url, config_id):
    """
    Depending on the configuration mode, loads the correct version of the first party sites (with the correct tracking).

    :param url: The correct malicious first party site to load.
    :param config_id: The configuration id so we can load the correct version of the site (according to tracking
    preference).
    :return: HTTP response for the first party site
    """
    check_referer(request, url + config_id)
    config_user = User.query.filter_by(uuid=config_id).first_or_404()

    # Generates the history log for first party only tracking
    fp_uuid = request.cookies.get('id')
    fp_user = implicit_user_login(FirstPartyUUID, fp_uuid,
                                  config_user.first_party_cookie_size)
    log_site_visit(FirstPartyHistory, request.url, fp_user,
                   request.access_route[0])
    recent_history = generate_recent_history(FirstPartyHistory, fp_user, 10)

    # Sets the recently visited site for the benchmark
    redis_set_benchmark_recent_site(config_id, '1', request.url)

    # Chooses the correct tracking mode based on what the user wants to test out
    if config_user.mode == '1':
        response = make_response(
            render_template(FIRST_PARTY_ONLY_TEMPLATE,
                            urls=URLS,
                            fp_cookie_id=fp_uuid,
                            config_id=config_id,
                            history_log=recent_history))
    elif config_user.mode == '2':
        response = make_response(
            render_template(FIRST_PARTY_AND_THIRD_PARTY_TEMPLATE,
                            urls=URLS,
                            fp_cookie_id=fp_uuid,
                            config_id=config_id))
    elif config_user.mode == '3':
        response = make_response(
            render_template(FIRST_PARTY_AND_THIRD_PARTY_SPLIT_TEMPLATE,
                            urls=URLS,
                            fp_cookie_id=fp_uuid,
                            config_id=config_id))
    elif config_user.mode == '4':
        response = make_response(
            render_template(FIRST_PARTY_AND_THIRD_PARTY_SPLIT_CHAIN_TEMPLATE,
                            urls=URLS,
                            fp_cookie_id=fp_uuid,
                            config_id=config_id))
    elif config_user.mode == '5':
        response = make_response(
            render_template(FIRST_PARTY_AND_THIRD_PARTY_SUPER_COOKIE_TEMPLATE,
                            urls=URLS,
                            fp_cookie_id=fp_uuid,
                            config_id=config_id))
    elif config_user.mode == '6':
        response = make_response(
            render_template(
                FIRST_PARTY_AND_THIRD_PARTY_SPLIT_CHAIN_SUPER_COOKIE_TEMPLATE,
                urls=URLS,
                fp_cookie_id=fp_uuid,
                config_id=config_id))

    else:
        response = redirect_config()

    # Creates a cookie if none existed (for first party tracking mode 1 only)
    if fp_uuid is None:
        response = append_cookie(response, fp_user.uuid)
    return response
def fp_malicious_3_record(config_id):
    """
    Logs the external link the user intended for malicious first party website number 3.
    """
    check_referer(request, URLS['FP_URL_MALICIOUS_3'] + config_id)
    return fp_malicious_record(config_id)