Exemple #1
0
def login_user(event, _):
    """
    Login a user
    :param event: event
    :return: 200 and a login cookie if successful, 401 otherwise
    """

    # Parse the paramteres
    params = parse_qs(event["body"])

    # Make sure that the request contains all needed data
    if "identifier" in params and "password" in params:
        # Try to login the user
        user = User()
        username = user.login_user(params["identifier"][0],
                                   params["password"][0])

        if username:
            cookie_content = f"user={username}"
            cookie_content_signed = sign_cookie(cookie_content)

            expiration_date = datetime.now() + timedelta(days=30)
            cookie = f"{cookie_content_signed};SameSite=Strict;Path=/;Expires={get_cookie_date(expiration_date)};HttpOnly"

            return create_response(
                200,
                "POST",
                username,
                {
                    "Access-Control-Allow-Credentials": "true",
                    "Set-Cookie": cookie
                },
            )

    return create_response(401, "POST")
Exemple #2
0
def change_voted_message_and_redirect(event, _):
    """
    Change the user's voted message and redirect.
    """
    # Parse the parameters
    params = parse_qs(event["body"])

    # Check if the user is logged in correctly
    username = get_logged_in_user(event)
    if not username:
        return create_response(400, "POST", "User not logged in correctly")

    # Set the voted message and redirect
    voted_params = dict(user=username, voted_message=None, voted_redirect=None)
    if "voted_redirect" in params and params["voted_redirect"]:
        voted_params["voted_redirect"] = params["voted_redirect"][0]
    if "voted_message" in params and params["voted_message"]:
        voted_params["voted_message"] = params["voted_message"][0]

    user = User()
    try:
        user.set_voted_message_and_redirect(**voted_params)
    except ValueError as error:
        return create_response(400, "POST", str(error))

    return create_response(200, "POST")
def get_votes_for_project(event, _):
    """
    Handle get votes request for a project
    :param event: event
    :return: votes data as JSON
    """
    # Get all parameters
    username = event["pathParameters"]["user"]
    project = event["pathParameters"]["project"]

    # Check if the user stats are public or the user is logged in
    user = User()
    user_data = user.get_user_by_username(username)

    if user_data and (user_data["is_public"]
                      or username == get_logged_in_user(event)):
        vote = Vote()
        votes_data = vote.get_votes_for_project(username, project)
        result = dict(
            single_voting_projects=user_data.get("single_voting_projects"),
            votes=votes_data,
        )
        return create_response(200, body=json.dumps(result))
    else:
        return create_response(400, "GET", "Invalid user")
Exemple #4
0
 def test_get_user_by_username(self):
     user = User()
     self.assertEqual(self.expected_users_data["user_1"],
                      user.get_user_by_username("user_1"))
     self.assertEqual(self.expected_users_data["user_2"],
                      user.get_user_by_username("user_2"))
     self.assertFalse(user.get_user_by_username("user_3"))
    def test_change_account_public(self):
        user = User()
        data = user.get_user_by_username("user_1")
        self.assertTrue(data["is_public"])

        event_change = dict(
            headers=dict(
                Cookie="user=user_1&signature=$2b$12$oGAaQWkNrjCWI0ugg8Go8uZ1ld2828dTeTk2cE/WZAO2yOB4aUxQm"
            ),
            body="0",
        )
        self.assertEqual(200, change_account_public(event_change, None)["statusCode"])
        data = user.get_user_by_username("user_1")
        self.assertFalse(data["is_public"])

        event_change = dict(
            headers=dict(
                Cookie="user=user_1&signature=$2b$12$oGAaQWkNrjCWI0ugg8Go8uZ1ld2828dTeTk2cE/WZAO2yOB4aUxQm"
            ),
            body="1",
        )
        self.assertEqual(200, change_account_public(event_change, None)["statusCode"])
        data = user.get_user_by_username("user_1")
        self.assertTrue(data["is_public"])

        # Wrong cookie
        event_2 = dict(
            headers=dict(
                Cookie="user=user_2&signature=$2b$12$oGAaQWkNrjCWI0ugg8Go8uZ1ld2828dTeTk2cE/WZAO2yOB4aUxQm"
            ),
            body="0",
        )
        self.assertEqual(400, change_account_public(event_2, None)["statusCode"])
Exemple #6
0
def get_user_data(event, _):
    """
    Get the data for the logged in user.
    :param event: event
    :return: dict with the main data attributes for the logged in user
    """
    # Check if the user is logged in correctly and return empty dict if not
    username = get_logged_in_user(event)
    if not username:
        return create_response(200, body=json.dumps(dict()))

    # Get the user data
    user = User()
    data = user.get_user_by_username(username)

    # Choose fileds to provide
    return create_response(
        200,
        body=json.dumps({
            key: data[key]
            for key in [
                "user",
                "email",
                "is_public",
                "voted_message",
                "voted_redirect",
            ]
        }),
    )
Exemple #7
0
def change_password(event, _):
    """
    Change the password of the user
    :param event: event
    :return: 200 if the change was successful, 400 if there was a problem with the new password
    """

    # Parse the parameters
    params = parse_qs(event["body"])

    # Check if a password is missing or they don't match
    if ("newpassword" not in params or "newpassword2" not in params
            or params["newpassword"][0] != params["newpassword2"][0]):
        return create_response(400, "POST", "The two passwords don't match")

    # Check if the user is logged in correctly
    username = get_logged_in_user(event)
    if not username:
        return create_response(400, "POST", "User not logged in correctly")

    # Try to change the password
    user = User()
    try:
        user.update_user_password(username, params["newpassword"][0])

        return create_response(200, "POST")

    except ValueError as error:
        return create_response(400, "POST", str(error))
Exemple #8
0
def remove_single_voting_project(event, _):
    """
    Remove a project from the user's single voting projects list
    """
    project = event["body"]

    # Check if the project name is valid
    if not re.fullmatch(r"[a-z0-9_\.\-]{1,100}", project):
        return create_response(400, "POST", "Invalid project name")

    # Get the logged in user data
    user = User()
    username = get_logged_in_user(event)
    user_data = user.get_user_by_username(username)
    if not user_data:
        return create_response(400, "POST", "User not logged in correctly")

    # Update the list of single voting projects
    if "single_voting_projects" in user_data:
        if project in user_data["single_voting_projects"]:
            user_data["single_voting_projects"].remove(project)

            user.change_single_voting_projects(
                username, user_data["single_voting_projects"])

    return create_response(200, "POST")
def add_vote_and_redirect(event, _):
    """
    Handle add vote requests and redirect to a info page
    :param event: event
    :return: redirect to a page explaining that the vote was added
    """
    # Save the vote
    do_vote(event, None)

    redirect_url = "/voted"

    # Find the user and determine the redirect page
    username = event["pathParameters"]["user"].lower()
    user = User()
    user_data = user.get_user_by_username(username)

    if user_data:
        # If the user has a redirect page configured
        if user_data["voted_redirect"]:
            redirect_url = user_data["voted_redirect"]
        elif user_data["voted_message"]:
            redirect_url = f"/voted?message={quote_plus(user_data['voted_message'])}"

    # Return response
    return create_response(302, additional_headers={"Location": redirect_url})
Exemple #10
0
    def test_update_user_last_active(self, _):
        user = User()

        # Test valid password hash
        user.update_user_last_active("user_1")
        self.assertEqual("9999",
                         user.get_user_by_username("user_1")["last_active"])

        # Test invalid user
        self.assertRaises(ValueError, user.update_user_last_active, "user_x")
    def test_remove_single_voting_project(self):
        cookie = "user=user_1&signature=$2b$12$oGAaQWkNrjCWI0ugg8Go8uZ1ld2828dTeTk2cE/WZAO2yOB4aUxQm"

        user = User()

        # Positive case
        event = dict(headers=dict(Cookie=cookie), body="project_a",)
        self.assertEqual(200, remove_single_voting_project(event, None)["statusCode"])
        self.assertEqual(
            ["project_b"],
            user.get_user_by_username("user_1")["single_voting_projects"],
        )

        # Repeated case
        event = dict(headers=dict(Cookie=cookie), body="project_a",)
        self.assertEqual(200, remove_single_voting_project(event, None)["statusCode"])
        self.assertEqual(
            ["project_b"],
            user.get_user_by_username("user_1")["single_voting_projects"],
        )

        # Non existing case
        event = dict(headers=dict(Cookie=cookie), body="project_c",)
        self.assertEqual(200, remove_single_voting_project(event, None)["statusCode"])
        self.assertEqual(
            ["project_b"],
            user.get_user_by_username("user_1")["single_voting_projects"],
        )

        # Last case
        event = dict(headers=dict(Cookie=cookie), body="project_b",)
        self.assertEqual(200, remove_single_voting_project(event, None)["statusCode"])
        self.assertEqual(
            [], user.get_user_by_username("user_1")["single_voting_projects"],
        )

        # Empty case
        event = dict(headers=dict(Cookie=cookie), body="project_b",)
        self.assertEqual(200, remove_single_voting_project(event, None)["statusCode"])
        self.assertEqual(
            [], user.get_user_by_username("user_1")["single_voting_projects"],
        )

        # Wrong cookie
        event = dict(
            headers=dict(
                Cookie="user=user_2&signature=$2b$12$oGAaQWkNrjCWI0ugg8Go8uZ1ld2828dTeTk2cE/WZAO2yOB4aUxQm"
            ),
            body="project_d",
        )
        self.assertEqual(400, remove_single_voting_project(event, None)["statusCode"])
        self.assertNotIn("single_voting_projects", user.get_user_by_username("user_2"))

        # Invalid project name
        event = dict(headers=dict(Cookie=cookie), body="project_invalid_<>",)
        self.assertEqual(400, remove_single_voting_project(event, None)["statusCode"])
        self.assertEqual(
            [], user.get_user_by_username("user_1")["single_voting_projects"],
        )
Exemple #12
0
 def test_get_user_by_email(self):
     user = User()
     self.assertEqual(
         self.expected_users_data["user_1"],
         user.get_user_by_email("*****@*****.**"),
     )
     self.assertEqual(
         self.expected_users_data["user_2"],
         user.get_user_by_email("*****@*****.**"),
     )
     self.assertFalse(user.get_user_by_username("*****@*****.**"))
def do_vote(event, _):
    """
    Post a vote to the database
    :param event: event
    """
    # Get all parameters
    username = event["pathParameters"]["user"].lower()
    project = event["pathParameters"]["project"].lower()
    topic = event["pathParameters"]["topic"].lower()
    log.debug("Voting for: %s, %s, %s", username, project, topic)

    # Check all parameters for validity and return if some of them is not valid
    if not re.fullmatch(r"[a-z0-9_\.\-]{3,30}", username):
        return

    if not re.fullmatch(r"[a-z0-9_\.\-]{1,100}", project):
        return

    if not re.fullmatch(r"[a-z0-9_\.\-]{1,100}", topic):
        return

    # Check if this IP address already voted for this topic
    log.debug(f"Event: {event}")
    ip_address = get_ip_address(event)

    vote_history = VoteHistory()
    if vote_history.check_ip_voted(username, get_topic_key(project, topic),
                                   ip_address):
        return

    # Check if the user has multiple voting for a project disabled
    user = User()
    user_data = user.get_user_by_username(username)

    # Stop if the user is not registered
    if not user_data:
        return

    # Stop ff the project is a single voting and the user already voted
    if ("single_voting_projects" in user_data
            and project in user_data["single_voting_projects"]
            and vote_history.check_ip_voted_project(username, project,
                                                    ip_address)):
        return

    # Do the voting
    vote = Vote()
    vote.add_vote(username, project, topic)
    vote_history.add_vote_history(username, project, topic, ip_address)
Exemple #14
0
    def test_set_account_public(self):
        user = User()

        user.set_account_public("user_1", False)
        user.set_account_public("user_2", True)

        self.assertFalse(user.is_account_public("user_1"))
        self.assertTrue(user.is_account_public("user_2"))
Exemple #15
0
def change_account_public(event, _):
    """
    Change the public visibility of an account
    :param event: event
    :return: 200 if the change was successful, 400 otherwise
    """
    # Check if the user is logged in correctly
    username = get_logged_in_user(event)
    if not username:
        return create_response(400, "POST", "User not logged in correctly")

    # Get the new value of the public option
    new_is_public = event["body"] == "1"

    # Change the user public setting
    user = User()
    user.set_account_public(username, new_is_public)

    return create_response(200, "POST")
Exemple #16
0
    def test_create_user(self, _, __):
        user = User()
        # Test creation of a valid user
        user.create_user("user_3", "*****@*****.**", "test3")
        self.assertEqual(self.expected_users_data["user_3"],
                         user.get_user_by_username("user_3"))

        # Test invalid values
        self.assertRaises(ValueError, user.create_user, "user_4",
                          "*****@*****.**", "a")
        self.assertRaises(ValueError, user.create_user, "u",
                          "*****@*****.**", "test4")
        self.assertRaises(ValueError, user.create_user, "user_4",
                          "user_4@gmail", "test4")

        # Test creation of duplicate username or e-mail
        self.assertRaises(ValueError, user.create_user, "user_2",
                          "*****@*****.**", "test4")
        self.assertRaises(ValueError, user.create_user, "user_4",
                          "*****@*****.**", "test4")
Exemple #17
0
    def test_update_user_password(self, _):
        user = User()

        # Test valid password hash
        user_1 = user.get_user_by_username("user_1")
        user_1[
            "password_hash"] = "$2b$12$nChdB1EJj1DZbtJgNSOFz.fTxPXu565.ic3xtXJvjLf64F4ELnuXG"

        user.update_user_password("user_1", "test3")
        self.assertEqual(user_1, user.get_user_by_username("user_1"))

        # Test invalid password hash
        self.assertRaises(ValueError, user.update_user_password, "user_1", "")
        self.assertRaises(ValueError, user.update_user_password, "user_1", "a")
        self.assertRaises(ValueError, user.update_user_password, "user_1",
                          "aa")
        self.assertRaises(ValueError, user.update_user_password, "user_1",
                          "aaa")

        # Test invalid user
        self.assertRaises(
            ValueError,
            user.update_user_password,
            "user_x",
            "$2b$12$G/Kb.r3YAJbenM7Ul9gQXO6bIjMZtVAt1uY.nKZMQL.1i6L50LLTW",
        )
    def test_add_single_voting_project(self):
        cookie = "user=user_1&signature=$2b$12$oGAaQWkNrjCWI0ugg8Go8uZ1ld2828dTeTk2cE/WZAO2yOB4aUxQm"
        cookie2 = "user=user_2&signature=$2b$12$VTqno3w/ALCThRCNZQO2wu91wRvULXLhcD.Q06tbRJW9wWBFSYMRG"

        user = User()

        # Positive case
        event = dict(headers=dict(Cookie=cookie), body="project_c",)
        self.assertEqual(200, add_single_voting_project(event, None)["statusCode"])
        self.assertEqual(
            ["project_a", "project_b", "project_c"],
            user.get_user_by_username("user_1")["single_voting_projects"],
        )

        # Repeated case
        event = dict(headers=dict(Cookie=cookie), body="project_c",)
        self.assertEqual(200, add_single_voting_project(event, None)["statusCode"])
        self.assertEqual(
            ["project_a", "project_b", "project_c"],
            user.get_user_by_username("user_1")["single_voting_projects"],
        )

        # Positive case (no single voting projects yet)
        event = dict(headers=dict(Cookie=cookie2), body="project_a",)
        self.assertEqual(200, add_single_voting_project(event, None)["statusCode"])
        self.assertEqual(
            ["project_a"],
            user.get_user_by_username("user_2")["single_voting_projects"],
        )

        # Wrong cookie
        event = dict(
            headers=dict(
                Cookie="user=user_2&signature=$2b$12$oGAaQWkNrjCWI0ugg8Go8uZ1ld2828dTeTk2cE/WZAO2yOB4aUxQm"
            ),
            body="project_d",
        )
        self.assertEqual(400, add_single_voting_project(event, None)["statusCode"])

        # Invalid project name
        event = dict(headers=dict(Cookie=cookie), body="project_invalid_<>",)
        self.assertEqual(400, add_single_voting_project(event, None)["statusCode"])
        self.assertEqual(
            ["project_a", "project_b", "project_c"],
            user.get_user_by_username("user_1")["single_voting_projects"],
        )
Exemple #19
0
    def test_update_user_email(self):
        user = User()

        # Test valid email
        user_1 = user.get_user_by_username("user_1")
        user_1["email"] = "*****@*****.**"

        user.update_user_email("user_1", user_1["email"])
        self.assertEqual(user_1, user.get_user_by_username("user_1"))

        # Test invalid email
        self.assertRaises(ValueError, user.update_user_email, "user_1", "")
        self.assertRaises(ValueError, user.update_user_email, "user_1",
                          "aaaaaa")
        self.assertRaises(ValueError, user.update_user_email, "user_1",
                          "bbbb@cccc")

        # Test invalid user
        self.assertRaises(ValueError, user.update_user_email, "user_x",
                          "*****@*****.**")
Exemple #20
0
    def test_login_user(self, _):
        user = User()
        # Test correct identifier and password
        self.assertEqual("user_1", user.login_user("user_1", "test"))
        self.assertEqual("user_1", user.login_user("*****@*****.**", "test"))

        # Test wrong identifier or password
        self.assertFalse(user.login_user("user_1", "wrong_password"))
        self.assertFalse(user.login_user("user_1", "test2"))
        self.assertFalse(user.login_user("user_3", "test3"))
        self.assertFalse(user.login_user("*****@*****.**", "test3"))

        # Test last active password
        self.assertEqual("1111",
                         user.get_user_by_username("user_2")["last_active"])
        user.login_user("user_2", "test2")
        self.assertEqual("9999",
                         user.get_user_by_username("user_2")["last_active"])
    def test_change_voted_message_and_redirect(self):
        cookie = "user=user_1&signature=$2b$12$oGAaQWkNrjCWI0ugg8Go8uZ1ld2828dTeTk2cE/WZAO2yOB4aUxQm"

        # Correct empty
        event = dict(
            headers=dict(Cookie=cookie), body="voted_message=&voted_redirect=",
        )
        self.assertEqual(
            200, change_voted_message_and_redirect(event, None)["statusCode"]
        )

        # Correct voted message
        event = dict(
            headers=dict(Cookie=cookie),
            body="voted_message=New voted message&voted_redirect=",
        )
        self.assertEqual(
            200, change_voted_message_and_redirect(event, None)["statusCode"]
        )

        # Correct voted redirect
        event = dict(
            headers=dict(Cookie=cookie),
            body="voted_message=&voted_redirect=http://iwanttoreadmore.com/voted",
        )
        self.assertEqual(
            200, change_voted_message_and_redirect(event, None)["statusCode"]
        )

        # Correct voted message and redirect
        event = dict(
            headers=dict(Cookie=cookie),
            body="voted_message=Some message&voted_redirect=http://iwanttoreadmore.com/voted",
        )
        self.assertEqual(
            200, change_voted_message_and_redirect(event, None)["statusCode"]
        )
        user = User()
        user_data = user.get_user_by_username("user_1")
        self.assertEqual("Some message", user_data["voted_message"])
        self.assertEqual(
            "http://iwanttoreadmore.com/voted", user_data["voted_redirect"]
        )

        # Wrong cookie
        event = dict(
            headers=dict(
                Cookie="user=user_2&signature=$2b$12$oGAaQWkNrjCWI0ugg8Go8uZ1ld2828dTeTk2cE/WZAO2yOB4aUxQm"
            ),
            body="voted_message=New voted message&voted_redirect=",
        )
        self.assertEqual(
            400, change_voted_message_and_redirect(event, None)["statusCode"]
        )

        # Invalid message
        event = dict(
            headers=dict(Cookie=cookie),
            body="voted_message=Invalid <message>&voted_redirect=",
        )
        self.assertEqual(
            400, change_voted_message_and_redirect(event, None)["statusCode"]
        )

        # Invalid redirect
        event = dict(
            headers=dict(Cookie=cookie),
            body="voted_message=&voted_redirect=invalidurl",
        )
        self.assertEqual(
            400, change_voted_message_and_redirect(event, None)["statusCode"]
        )
Exemple #22
0
    def test_change_single_voting_projects(self):
        user = User()

        user.change_single_voting_projects("user_1", ["project_a"])
        self.assertEqual(
            ["project_a"],
            user.get_user_by_username("user_1")["single_voting_projects"])

        user.change_single_voting_projects(
            "user_1", ["project_a", "project_b", "project_c"])
        self.assertEqual(
            ["project_a", "project_b", "project_c"],
            user.get_user_by_username("user_1")["single_voting_projects"],
        )

        user.change_single_voting_projects("user_1", [])
        self.assertEqual(
            [],
            user.get_user_by_username("user_1")["single_voting_projects"],
        )

        self.assertRaises(ValueError, user.change_single_voting_projects,
                          "user_x", [])
Exemple #23
0
    def set_voted_message_and_redirect(self):
        user = User()

        # Positive cases voted message
        user.set_voted_message_and_redirect("user_1", "New voted message",
                                            None)
        user_data = user.get_user_by_username("user_1")
        self.assertEqual(user_data["voted_message"], "New voted message")
        self.assertEqual(user_data["voted_redirect"], None)

        user.set_voted_message_and_redirect("user_2",
                                            "Other new voted message", None)
        user_data = user.get_user_by_username("user_2")
        self.assertEqual(user_data["voted_message"], "Other new voted message")
        self.assertEqual(user_data["voted_redirect"], None)

        # Positive cases voted redirect
        user.set_voted_message_and_redirect(
            "user_1", None, "https://iwanttoreadmore.com/voted")
        user_data = user.get_user_by_username("user_1")
        self.assertEqual(user_data["voted_redirect"],
                         "https://iwanttoreadmore.com/voted")
        self.assertEqual(user_data["voted_message"], None)

        # Positive cases both
        user.set_voted_message_and_redirect(
            "user_1", "Some message", "https://iwanttoreadmore.com/voted")
        user_data = user.get_user_by_username("user_1")
        self.assertEqual(user_data["voted_message"], "Some message")
        self.assertEqual(user_data["voted_redirect"],
                         "https://iwanttoreadmore.com/voted")

        # Negative case user
        self.assertRaises(ValueError, user.set_voted_message_and_redirect,
                          "user_X", "Message", None)

        # Negative cases voted message
        self.assertRaises(
            ValueError,
            user.set_voted_message_and_redirect,
            "user_1",
            "<b>Tags</b>",
            None,
        )
        self.assertRaises(ValueError, user.set_voted_message_and_redirect,
                          "user_1", "M" * 501, None)

        # Negative cases voted redirect
        user.set_voted_message_and_redirect(
            "user_2", None, "https://iwanttoreadmore.com/voted2")
        user_data = user.get_user_by_username("user_2")
        self.assertEqual(user_data["voted_redirect"],
                         "https://iwanttoreadmore.com/voted2")
        self.assertEqual(user_data["voted_message"], None)

        self.assertRaises(
            ValueError,
            user.set_voted_message_and_redirect,
            "user_1",
            None,
            "nonurltext",
        )
        self.assertRaises(ValueError, user.set_voted_message_and_redirect,
                          "user_1", None, "a" * 501)
Exemple #24
0
    def test_is_account_public(self):
        user = User()

        self.assertTrue(user.is_account_public("user_1"))
        self.assertFalse(user.is_account_public("user_2"))