def add_voters(cls, voters_list):
        """
        This method adds specified voters to the database. It also sends the voting token to every voter using the provided e-mail address.
        """
        database = DynamoDBManager()
        email_client = boto3.client("ses", region_name="eu-west-1")
        sender_email = database.get_parameter("sender_email")

        for voter in voters_list:
            response = database.add_voter(voter["student_id"],
                                          voter["student_email"])
            message = """
            Congratulations!
            You have been successfully registered for the upcoming election!
            Your personal voter code is:
            {token}""".format(token=response["token"])
            email_client.send_email(
                Source=sender_email,
                Destination={"ToAddresses": [
                    voter["student_email"],
                ]},
                Message={
                    "Subject": {
                        "Data": "Your personal voter code"
                    },
                    "Body": {
                        "Text": {
                            "Data": message
                        }
                    }
                })
            response = respond(
                "Voter {voter} successfully added to the database!".format(
                    voter=voter["student_id"]), 200)
        return response
 def add_candidates(cls, candidates_list):
     """
     This method adds specified candidates to the database.
     """
     for candidate in candidates_list:
         database = DynamoDBManager()
         response = database.add_candidate(candidate["candidate_full_name"],
                                           candidate["candidate_email"],
                                           candidate["candidate_page_link"])
     return response
Ejemplo n.º 3
0
 def test_mark_voter(self, mock_boto3_resource):
     manager = DynamoDBManager()
     id = "some id"
     status = "true"
     manager.mark_voter(id, status)
     manager.voters_table.update_item.assert_called_with(
         Key={"student_id": id},
         UpdateExpression="SET #voted = :voted_flag",
         ExpressionAttributeValues={":voted_flag": "true"},
         ExpressionAttributeNames={"#voted": "voted"})
Ejemplo n.º 4
0
 def test_set_parameter(self, mock_boto3_resource):
     manager = DynamoDBManager()
     parameter = "some parameter"
     value = "some value"
     manager.set_parameter(parameter, value)
     manager.parameters_table.put_item.assert_called_with(
         Item={
             "parameter": str(parameter),
             "value": str(value)
         })
Ejemplo n.º 5
0
 def test_add_voter(self, mock_boto3_resource, mock_randint):
     manager = DynamoDBManager()
     mock_randint.return_value = "random"
     id = "some id"
     email = "some email"
     manager.add_voter(id, email)
     manager.voters_table.put_item.assert_called_with(Item={
         "student_id": id,
         "email": email,
         "token": "random",
         "voted": "false"
     })
Ejemplo n.º 6
0
 def test_add_candidate(self, mock_boto3_resource):
     manager = DynamoDBManager()
     candidate_full_name = "Person Personson"
     candidate_email = "some email"
     candidate_link = "some link"
     manager.add_candidate(candidate_full_name, candidate_email,
                           candidate_link)
     manager.candidates_table.put_item.assert_called_with(
         Item={
             "full_name": candidate_full_name,
             "candidate_email": candidate_email,
             "candidate_page_link": candidate_link
         })
Ejemplo n.º 7
0
 def __init__(self, request_id="NONE"):
     self.request_id = request_id
     # self.api_root = os.environ.get("api_root")
     self.events_list = [
         "ADD_VOTERS", "ADD_CANDIDATES", "GET_CANDIDATES", "LOCK", "START",
         "CAST_VOTE"
     ]
     self.handlers = {
         "ADD_VOTERS": self.command_add_voters,
         "ADD_CANDIDATES": self.command_add_candidates,
         "GET_CANDIDATES": self.command_get_candidates,
         "LOCK": self.command_lock,
         "START": self.command_start,
         "CAST_VOTE": self.command_cast_vote
     }
     self.db_manager = DynamoDBManager()
     self.admin_token = self.db_manager.get_parameter("admin_token")
     self.locked = self.db_manager.get_parameter("locked")
     self.started = self.db_manager.get_parameter("started")
Ejemplo n.º 8
0
    def test_add_vote(self, mock_boto3_resource, mock_boto3_client):
        manager = DynamoDBManager()
        voter_id = "1337"
        event_id = "1111"
        candidate = "Person Personson"

        # Case 1: everything is normal ---------------------------------------------------------------------------------

        response = manager.add_vote(voter_id, event_id, candidate)
        assert response == respond(
            'Congratulations! You have successfully cast your vote for the candidate {candidate}!'
            .format(candidate=candidate), 200)

        # --------------------------------------------------------------------------------------------------------------

        # Case 2: no such candidate ------------------------------------------------------------------------------------

        manager.get_candidate = (lambda candidate_name: None)
        response = manager.add_vote(voter_id, event_id, candidate)
        assert response == respond(
            "NO SUCH CANDIDATE, PLEASE ENTER THE CORRECT FULL NAME", 404)
Ejemplo n.º 9
0
class EventProcessor:
    def __init__(self, request_id="NONE"):
        self.request_id = request_id
        # self.api_root = os.environ.get("api_root")
        self.events_list = [
            "ADD_VOTERS", "ADD_CANDIDATES", "GET_CANDIDATES", "LOCK", "START",
            "CAST_VOTE"
        ]
        self.handlers = {
            "ADD_VOTERS": self.command_add_voters,
            "ADD_CANDIDATES": self.command_add_candidates,
            "GET_CANDIDATES": self.command_get_candidates,
            "LOCK": self.command_lock,
            "START": self.command_start,
            "CAST_VOTE": self.command_cast_vote
        }
        self.db_manager = DynamoDBManager()
        self.admin_token = self.db_manager.get_parameter("admin_token")
        self.locked = self.db_manager.get_parameter("locked")
        self.started = self.db_manager.get_parameter("started")

    # EVENT PROCESSING ---------------------------------------------------------

    def process_event(self, payload):
        event_type = self._determine_event(payload)
        if event_type != "UNKNOWN EVENT TYPE":
            return self._delegate_event(event_type, payload)
        else:
            return respond("EVENT VALIDATION FAILED", 400)

    def _determine_event(self, payload):
        # Determines type of the event, checks validity of the payload according to schema
        # At this stage, validity of the token is not checked, we just determine the type of the event

        determined_type = "UNKNOWN EVENT TYPE"
        for event_type in self.events_list:
            try:
                result = validate(instance=payload,
                                  schema=schema_dict[event_type + "_SCHEMA"])
                determined_type = event_type
            except ValidationError as e:
                continue
        return determined_type

    def _delegate_event(self, event_type, payload):
        # Delegates the event to the handler
        response = self.handlers[event_type](payload)
        return response

    # COMMAND HANDLERS ---------------------------------------------------------

    def command_add_voters(self, payload):
        if self.started == "true":
            return respond("VOTING ALREADY STARTED", 403)
        if payload["administrator_token"] == self.admin_token:
            response = VotersManager.add_voters(payload["voters_to_add"])
            return response
        else:
            return respond("WRONG TOKEN, COMMAND REJECTED", 403)

    def command_add_candidates(self, payload):
        if self.started == "true":
            return respond("VOTING ALREADY STARTED", 403)
        if payload["administrator_token"] == self.admin_token:
            response = CandidatesManager.add_candidates(
                payload["candidates_to_add"])
            return response
        else:
            return respond("WRONG TOKEN, COMMAND REJECTED", 403)

    def command_get_candidates(self, payload):
        # Note that no token is required for this command
        if self.started == "false":
            return respond("VOTING NOT STARTED YET", 403)
        return respond(str(self.db_manager.get_candidates()), 200)

    def command_lock(self, payload):
        if self.locked == "true":
            return respond("SYSTEM ALREADY LOCKED", 403)
        if payload["administrator_token"] == self.admin_token:
            self.db_manager.set_parameter(parameter="locked", value="true")
            return respond("SYSTEM LOCKED", 200)
        else:
            return respond("WRONG TOKEN, COMMAND REJECTED", 403)

    def command_start(self, payload):
        if self.locked == "false":
            return respond("LOCK THE SYSTEM FIRST", 403)
        if self.started == "true":
            return respond("VOTING ALREADY STARTED", 403)
        if payload["administrator_token"] == self.admin_token:
            self.db_manager.set_parameter(parameter="started", value="true")
            return respond("VOTING STARTED", 200)
        else:
            return respond("WRONG TOKEN, COMMAND REJECTED", 403)

    def command_cast_vote(self, payload):
        if self.started != "true":
            return respond("VOTING NOT STARTED YET", 403)
        voter = self.db_manager.get_voter(id=payload["voter_id"])
        if voter["token"] == payload["voter_token"] and voter[
                "voted"] == "false":
            response = self.db_manager.add_vote(
                voter_id=payload["voter_id"],
                event_id=self.request_id,
                candidate=payload["candidate_full_name"])
            return response
        else:
            return respond("WRONG TOKEN OR ALREADY VOTED, COMMAND REJECTED",
                           403)
Ejemplo n.º 10
0
 def test_get_parameter(self, mock_boto3_resource):
     manager = DynamoDBManager()
     parameter = "some parameter"
     manager.get_parameter(parameter)
     manager.parameters_table.get_item.assert_called_with(
         Key={"parameter": parameter})
Ejemplo n.º 11
0
 def test_get_candidates(self, mock_boto3_resource):
     manager = DynamoDBManager()
     manager.get_candidates()
     manager.candidates_table.scan.assert_called()
Ejemplo n.º 12
0
 def test_get_candidate(self, mock_boto3_resource):
     manager = DynamoDBManager()
     candidate_full_name = "Person Personson"
     manager.get_candidate(candidate_full_name)
     manager.candidates_table.get_item.assert_called_with(
         Key={"full_name": candidate_full_name})
Ejemplo n.º 13
0
 def test_get_voter(self, mock_boto3_resource):
     manager = DynamoDBManager()
     id = "some id"
     manager.get_voter(id)
     manager.voters_table.get_item.assert_called_with(
         Key={"student_id": id})