Ejemplo n.º 1
0
def validate_ballot(parameters):
    """
    Validate a ballot's parameters based on constraints.
    :param parameters: The ballot's parameters.
    :return: None
    """
    # check if election exists
    specified_election = elections_alchemy.query_election(election_id=parameters['election'])
    if specified_election == list():
        raise exceptions.NotFound404Exception('election with specified ID not found')

    # check if position exists and is active
    specified_position = elections_alchemy.query_position(position_id=parameters['position'])
    if specified_position == list() or specified_position[0].active is False:
        raise exceptions.Forbidden403Exception('position with specified ID not found')

    # check if position is the right election type
    if specified_position[0].election_type != specified_election[0].election_type:
        raise exceptions.Forbidden403Exception('you are creating a vote for a position in a different election type')

    # check for valid candidate username
    if mask_alchemy.query_by_username(parameters['vote']) is None:
        raise exceptions.Forbidden403Exception('you cannot create a vote for this candidate')

    # check for duplicate votes
    if elections_alchemy.query_vote(election_id=specified_election[0].id,
                                    position_id=specified_position[0].id,
                                    vote=parameters['vote'],
                                    username=parameters['username']) != list():
        raise exceptions.Forbidden403Exception('this candidate has already been voted for by this user')
Ejemplo n.º 2
0
    def put(self, election_id):
        # load request body
        body = self.request.body.decode('utf-8')
        body_json = json.loads(body)

        # get current election
        election = elections_alchemy.query_election(election_id=str(election_id))
        if election == list():
            raise exceptions.NotFound404Exception('election with specified ID not found')
        election = election[0]

        # validate parameters
        required_parameters = ('id', 'election_type', 'name', 'max_votes', 'start', 'end', 'show_results')
        elections_validator.validate_parameters(body_json, required_parameters)
        elections_validator.validate_election(body_json, election)

        # update election
        for parameter in required_parameters:
            if parameter in ('start', 'end'):
                d = datetime.strptime(body_json[parameter], '%Y-%m-%d %H:%M:%S.%f')
                setattr(election, parameter, d)
            elif parameter == 'show_results' and body_json[parameter] is not None:
                d = datetime.strptime(body_json[parameter], '%Y-%m-%d %H:%M:%S.%f')
                setattr(election, parameter, d)
            else:
                setattr(election, parameter, body_json[parameter])
        elections_alchemy.add_or_update(election)

        # response
        self.set_status(200)
        self.write(election.serialize())
Ejemplo n.º 3
0
    def get(self, election_id):
        # get current user
        user = self.current_user

        # get election
        election = elections_alchemy.query_election(election_id=election_id)
        if election == list():
            raise exceptions.NotFound404Exception('election with specified ID not found')
        election = election[0]

        # check if results should not be sent
        is_admin = user is not None and (admin_permission in user.roles or elections_permission in user.roles)
        if not is_admin and (election.show_results is None or datetime.now() < election.show_results):
            raise exceptions.Forbidden403Exception('results are not available for this election')

        # count votes for each position
        position_totals = list()
        for position in elections_alchemy.query_position(election_type=election.election_type, active=True):
            # add each position to the totals
            position_summary = {
                'position': position.id,
                'votes': elections_alchemy.count_votes(election_id, position.id)
            }
            position_totals.append(position_summary)

        # response
        self.set_status(200)
        self.write({'positions': [position for position in position_totals]})
Ejemplo n.º 4
0
    def put(self, election_id, candidate_id):
        # load request body
        body = self.request.body.decode('utf-8')
        body_json = json.loads(body)

        # validate parameters
        required_parameters = ('id', 'election', 'position', 'username', 'display_name')
        elections_validator.validate_parameters(body_json, required_parameters)
        body_json['election'] = election_id
        elections_validator.validate_candidate(body_json)

        # get election
        election = elections_alchemy.query_election(election_id=str(election_id))
        if election == list():
            raise exceptions.NotFound404Exception('election with specified ID not found')

        # get candidate
        candidate = elections_alchemy.query_candidates(election_id=str(election_id), candidate_id=str(candidate_id))
        if candidate == list():
            raise exceptions.NotFound404Exception('candidate with specified ID not found')
        candidate = candidate[0]

        # update candidate
        for parameter in required_parameters:
            setattr(candidate, parameter, body_json[parameter])
        elections_alchemy.add_or_update(candidate)

        # response
        self.set_status(200)
        self.write(candidate.serialize())
Ejemplo n.º 5
0
    def get(self, election_id):
        # get election
        election = elections_alchemy.query_election(election_id=str(election_id))
        if election == list():
            raise exceptions.NotFound404Exception('election with specified ID not found')
        election = election[0]

        # response
        self.set_status(200)
        self.write(election.serialize())
Ejemplo n.º 6
0
def validate_candidate(parameters):
    """
    Validate a candidate's parameters based on constraints.
    :param parameters: The candidate's parameters.
    :return: None
    """
    # check to make sure there is an election to push candidates to
    election = elections_alchemy.query_election(election_id=parameters['election'])
    if election == list():
        raise exceptions.NotFound404Exception('election with specified ID not found')
    election = election[0]

    # check to make sure election is either current or up and coming
    if election != elections_alchemy.query_current() and \
            election not in elections_alchemy.query_election(start_after=datetime.now()):
        raise exceptions.Forbidden403Exception('candidate not in current election')

    # check to makes sure position exists
    if not elections_alchemy.query_position(position_id=str(parameters["position"])):
        raise exceptions.NotFound404Exception('position with specified ID not found')

    # check to make sure election exists
    if not elections_alchemy.query_election(election_id=parameters['election']):
        raise exceptions.NotFound404Exception('election with specified ID not found')
Ejemplo n.º 7
0
    def get(self):
        # build query parameter dict
        search_criteria = build_query_params(self.request.arguments)

        # get election
        elections = elections_alchemy.query_election(election_type=search_criteria.get('election_type', None),
                                                     name=search_criteria.get('name', None),
                                                     max_votes=search_criteria.get('max_votes', None),
                                                     start_before=search_criteria.get('start_before', None),
                                                     start_after=search_criteria.get('start_after', None),
                                                     end_before=search_criteria.get('end_before', None),
                                                     end_after=search_criteria.get('end_after', None))

        # response
        self.set_status(200)
        self.write({'elections': [e.serialize() for e in elections]})
Ejemplo n.º 8
0
    def get(self, election_id):
        # build query parameter dict
        search_criteria = build_query_params(self.request.arguments)

        # get election
        if elections_alchemy.query_election(election_id=str(election_id)) == list():
            raise exceptions.NotFound404Exception('election with specified ID not found')

        # get candidates
        candidates = elections_alchemy.query_candidates(election_id=str(election_id),
                                                        position_id=search_criteria.get('position', None),
                                                        username=search_criteria.get('username', None),
                                                        display_name=search_criteria.get('display_name', None))

        # response
        self.set_status(200)
        self.write({'candidates': [c.serialize() for c in candidates]})
Ejemplo n.º 9
0
    def post(self, election_id):
        # get current user
        user = self.current_user

        # load request body
        body = self.request.body.decode('utf-8')
        body_json = json.loads(body)

        # validate parameters
        required_parameters = ('election', 'position', 'student_id', 'vote')
        elections_validator.validate_parameters(body_json, required_parameters)

        # get student username from student ID
        voter = mask_alchemy.query_by_wwuid(mask_model.User, body_json['student_id'])
        if voter == list():
            raise exceptions.NotFound404Exception('user with specified student ID not found')
        voter = voter[0]

        # build proper vote from ballot data and validate it
        body_json['election'] = str(election_id)
        body_json['username'] = str(voter.username)
        body_json['manual_entry'] = str(user.username)
        elections_validator.validate_ballot(body_json)

        # check for too many votes
        specified_election = elections_alchemy.query_election(election_id=body_json['election'])
        specified_position = elections_alchemy.query_position(position_id=body_json['position'])
        if len(elections_alchemy.query_vote(election_id=specified_election[0].id,
                                            position_id=specified_position[0].id,
                                            username=str(voter.username))) >= specified_election[0].max_votes:
            raise exceptions.Forbidden403Exception(
                'this user has already cast {} vote/s'.format(str(specified_election[0].max_votes))
            )

        # create new vote
        vote = elections_model.Vote()
        for parameter in required_parameters:
            if parameter != 'student_id':
                setattr(vote, parameter, body_json[parameter])
        setattr(vote, 'username', str(voter.username))
        setattr(vote, 'manual_entry', str(user.username))
        elections_alchemy.add_or_update(vote)

        # response
        self.set_status(201)
        self.write(vote.serialize_ballot())
Ejemplo n.º 10
0
    def get(self, election_id):
        # build query parameter dict
        search_criteria = build_query_params(self.request.arguments)

        # get the specified election
        specified_election = elections_alchemy.query_election(election_id=str(election_id))
        if specified_election == list():
            raise exceptions.NotFound404Exception('vote with specified ID not found')
        specified_election = specified_election[0]

        # get votes
        votes = elections_alchemy.query_vote(election_id=specified_election.id,
                                             position_id=search_criteria.get('position', None),
                                             vote=search_criteria.get('vote', None),
                                             manual_entry=True)

        # response
        self.set_status(200)
        self.write({'ballots': [v.serialize_ballot() for v in votes]})
Ejemplo n.º 11
0
    def delete(self, vote_id):
        # get vote
        vote = elections_alchemy.query_vote(vote_id=str(vote_id))
        if vote == list():
            raise exceptions.NotFound404Exception('vote with specified ID not found')
        vote = vote[0]

        # get election
        election = elections_alchemy.query_election(election_id=str(vote.election))[0]

        # dont allow deleting past candidates
        if election != elections_alchemy.query_current():
            raise exceptions.Forbidden403Exception('vote not in the current election')

        # delete the vote
        elections_alchemy.delete(vote)

        # response
        self.set_status(204)
Ejemplo n.º 12
0
    def post(self):
        # get current user
        user = self.current_user

        # load request body
        body = self.request.body.decode('utf-8')
        body_json = json.loads(body)

        # validate parameters
        required_parameters = ('election', 'position', 'vote')
        elections_validator.validate_parameters(body_json, required_parameters)
        body_json['username'] = str(user.username)
        elections_validator.validate_vote(body_json)

        # check for too many votes
        specified_election = elections_alchemy.query_election(election_id=body_json['election'])
        specified_position = elections_alchemy.query_position(position_id=body_json['position'])

        if len(elections_alchemy.query_vote(election_id=specified_election[0].id,
                                            position_id=specified_position[0].id,
                                            username=str(user.username))) > specified_election[0].max_votes:
            raise exceptions.Forbidden403Exception(
                'you may only cast {} vote/s'.format(str(specified_election[0].max_votes))
            )

        if specified_election[0].election_type == 'senate':
            votes = elections_alchemy.query_vote(election_id=specified_election[0].id, 
                                                username=str(user.username))
            for vote in votes:
                if vote.position != body_json['position']:
                    elections_alchemy.delete(vote)

        # create new vote
        vote = elections_model.Vote()
        for parameter in required_parameters:
            setattr(vote, parameter, body_json[parameter])
        setattr(vote, 'username', str(user.username))
        elections_alchemy.add_or_update(vote)

        # response
        self.set_status(201)
        self.write(vote.serialize())
Ejemplo n.º 13
0
    def delete(self, election_id, candidate_id):
        # get candidate
        candidate = elections_alchemy.query_candidates(election_id=str(election_id), candidate_id=str(candidate_id))
        if candidate == list():
            raise exceptions.NotFound404Exception('candidate with specified ID not found')
        candidate = candidate[0]

        # get election
        election = elections_alchemy.query_election(election_id=str(election_id))
        if election == list():
            raise exceptions.NotFound404Exception('election with specified ID not found')
        election = election[0]

        # dont allow deleting past candidates
        if election != elections_alchemy.query_current_or_upcoming():
            raise exceptions.Forbidden403Exception('candidate not in the current or upcoming election')

        # delete the candidate
        elections_alchemy.delete(candidate)

        # response
        self.set_status(204)
Ejemplo n.º 14
0
def validate_vote(parameters, existing_vote=None):
    """
    Validate a vote's parameters based on constraints.
    :param parameters: The vote's parameters.
    :param existing_vote: An existing vote being updated used to check for duplicate votes.
    :return: None
    """
    # check if election exists
    specified_election = elections_alchemy.query_election(election_id=parameters['election'])
    if specified_election == list():
        raise exceptions.NotFound404Exception('election with specified ID not found')

    # check if not current election
    current_election = elections_alchemy.query_current()
    if specified_election[0] != current_election:
        raise exceptions.Forbidden403Exception('this election is not available for voting')

    # check if position exists and is active
    specified_position = elections_alchemy.query_position(position_id=parameters['position'])
    if specified_position == list() or specified_position[0].active is False:
        raise exceptions.Forbidden403Exception('position with specified ID not found')

    # check if position is the right election type
    if specified_position[0].election_type != current_election.election_type:
        raise exceptions.Forbidden403Exception('you are voting for a position in a different election type')

    # check for valid candidate username
    if mask_alchemy.query_by_username(parameters['vote']) is None:
        raise exceptions.Forbidden403Exception('you cannot vote for this person')

    # check for duplicate votes
    if parameters['vote'] != getattr(existing_vote, 'vote', None) and \
            elections_alchemy.query_vote(election_id=specified_election[0].id,
                                         position_id=specified_position[0].id,
                                         vote=parameters['vote'],
                                         username=parameters['username']) != list():
        raise exceptions.Forbidden403Exception('you have already voted for this person')