Example #1
0
def submit_vote(requester: Member, session: Session):
    election_id = request.json['election_id']
    election = session.query(Election).get(election_id)
    if election.status == 'final' or election.status == 'polls closed':
        return BadRequest('You may not submit a vote after the polls have closed')
    eligible = session.query(EligibleVoter). \
        filter_by(member_id=requester.id, election_id=election_id).with_for_update().one_or_none()
    if not eligible:
        return BadRequest('You are not eligible for this election.')
    if eligible.voted:
        return BadRequest('You have either already voted or received a paper ballot for this '
                          'election.')
    eligible.voted = True
    vote, rolled_back = create_vote(session, election_id, 6)
    if rolled_back:  # If we lost the lock we have to recheck
        eligible = session.query(EligibleVoter). \
            filter_by(member_id=requester.id,
                      election_id=election_id).with_for_update().one_or_none()
        if eligible.voted:
            return BadRequest('You have either already voted or received a paper ballot for this '
                              'election.')
        eligible.voted = True
    for rank, candidate_id in enumerate(request.json['rankings']):
        ranking = Ranking(rank=rank, candidate_id=candidate_id)
        vote.ranking.append(ranking)
    session.add(vote)
    session.commit()
    return jsonify({'ballot_id': vote.vote_key})
Example #2
0
def add_voter(requester: Member, session: Session):
    election_id = request.json['election_id']
    member_id = request.json.get('member_id', requester.id)
    eligible_voter = EligibleVoter(member_id=member_id, election_id=election_id)
    session.add(eligible_voter)
    session.commit()
    return jsonify({'status': 'success'})
Example #3
0
def add_member(requester: Member, session: Session):
    member = Member(**request.json)
    verify_url = create_auth0_user(member.email_address)
    send_welcome_email(member.email_address, member.first_name, verify_url)
    session.add(member)
    session.commit()
    return jsonify({'status': 'success'})
Example #4
0
def submit_paper_vote(requester: Member, session: Session):
    election_id = request.json['election_id']
    election = session.query(Election).get(election_id)
    if election.status == 'final':
        return BadRequest('You may not submit more votes after an election has been marked final')
    vote_key = request.json['ballot_key']
    vote = session.query(Vote).filter_by(
        election_id=election_id,
        vote_key=vote_key).with_for_update().one_or_none()

    if not vote:
        return Response('Ballot #{} for election_id={} not claimed'.format(vote_key, election_id), 404)

    if vote.ranking and not request.json.get('override', False):
        if len(vote.ranking) != len(request.json['rankings']):
            return jsonify({'status': 'mismatch'})
        for rank, candidate_id in enumerate(request.json['rankings']):
            if candidate_id != vote.ranking[rank].candidate_id:
                return jsonify({'status': 'mismatch'})
        return jsonify({'status': 'match'})
    if request.json.get('override', False):
        for rank in vote.ranking:
            session.delete(rank)
    for rank, candidate_id in enumerate(request.json['rankings']):
        ranking = Ranking(rank=rank, candidate_id=candidate_id)
        vote.ranking.append(ranking)
    session.add(vote)
    session.commit()
    return jsonify({'status': 'new'})
Example #5
0
def add_meeting(requester: Member, session: Session):
    member_id = request.json.get('member_id', requester.id)
    attend = Attendee(member_id=member_id,
                      meeting_id=request.json['meeting_id'])
    session.add(attend)
    session.commit()
    return jsonify({'status': 'success'})
Example #6
0
def make_admin(requester: Member, session: Session):
    member = session.query(Member).filter_by(
        email_address=request.json['email_address']).one()
    committee_id = request.json[
        'committee'] if request.json['committee'] != '0' else None
    role = Role(member_id=member.id, role='admin', committee_id=committee_id)
    session.add(role)
    session.commit()
    return jsonify({'status': 'success'})
Example #7
0
def add_role(requester: Member, session: Session):
    member_id = request.json.get('member_id', requester.id)
    committee_id = request.json[
        'committee_id'] if request.json['committee_id'] != '0' else None
    role = Role(member_id=member_id,
                role=request.json['role'],
                committee_id=committee_id)
    session.add(role)
    session.commit()
    return jsonify({'status': 'success'})
Example #8
0
def add_election(requester: Member, session: Session):
    election = Election(name=request.json['name'])
    session.add(election)
    candidates = request.json['candidate_list'].split(',')
    members = session.query(Member).filter(Member.email_address.in_(candidates)).all()
    for member in members:
        candidate = Candidate()
        candidate.election = election
        candidate.member = member
        session.add(candidate)
    session.commit()
    return jsonify({'status': 'success'})
Example #9
0
def add_committee(requester: Member, session: Session):
    committee = Committee(name=request.json['name'])
    session.add(committee)
    admins = request.json['admin_list'].split(',')
    members = session.query(Member).filter(
        Member.email_address.in_(admins)).all()
    for member in members:
        role = Role(role='admin')
        role.committee = committee
        role.member = member
        session.add(role)
    session.commit()
    return jsonify({'status': 'success'})
Example #10
0
    def test_election(self):
        num_votes = 500
        session = Session()
        a = Member(first_name='A', last_name='B')
        session.add(a)
        c = Member(first_name='C', last_name='D')
        session.add(c)
        e = Member(first_name='E', last_name='F')
        candidates = []
        for member in [a, c, e]:
            cand = Candidate()
            cand.member = member
            candidates.append(cand)
        session.add(e)
        election = Election(name='Test', number_winners=2)
        election.candidates.extend(candidates)
        session.add(election)

        for i in range(0, num_votes):
            shuffle(candidates)
            vote = Vote()
            election.votes.append(vote)
            for j, cand in enumerate(candidates):
                rank = Ranking(rank=i)
                rank.candidate = cand
                vote.ranking.append(rank)
        session.commit()
        session.close()

        session = Session()
        election = session.query(Election).filter_by(name='Test').one()
        results = hold_election(election)
        assert len(results.winners) == 2
        assert len(results.votes) == num_votes
Example #11
0
def attend_meeting(requester: Member, session: Session):
    short_id = request.json['meeting_short_id']
    meeting = session.query(Meeting).filter_by(short_id=short_id).one_or_none()
    if not meeting:
        return BadRequest('Invalid meeting id')
    if len(
            session.query(Attendee).filter_by(
                meeting_id=meeting.id, member_id=requester.id).all()) > 0:
        return BadRequest('You have already logged into this meeting')
    a = Attendee()
    a.meeting = meeting
    a.member = requester
    session.add(a)
    session.commit()
    return jsonify({'status': 'success'})
Example #12
0
    def test_election_prob(self, data):
        # Set up the SQLAlchemy session
        metadata.drop_all(engine)
        metadata.create_all(engine)
        session = Session()

        # Randomly generate parameters
        num_votes = data.draw(st.integers(min_value=0, max_value=500))
        num_candidates = data.draw(st.integers(min_value=1, max_value=10))
        num_winners = data.draw(
            st.integers(min_value=1, max_value=num_candidates))

        # Create candidates as members and add them to the DB
        candidate_members = [
            Member(first_name=str(i), last_name=str(i))
            for i in range(num_candidates)
        ]
        session.add_all(candidate_members)
        # Create candidates as candidates and add them to the DB
        candidates = [Candidate(member=member) for member in candidate_members]
        session.add_all(candidates)
        # Create the election and add to DB
        election = Election(name='Test2', number_winners=num_winners)
        election.candidates.extend(candidates)
        session.add(election)

        # Generate votes for the candidates
        for i in range(num_votes):
            shuffle(candidates)
            vote = Vote()
            election.votes.append(vote)
            for j, cand in enumerate(candidates):
                rank = Ranking(rank=i)
                rank.candidate = cand
                vote.ranking.append(rank)

        # Commit everything to DB
        session.commit()
        session.close()

        # Get the election back from the DB, hold the election
        new_session = Session()
        election = new_session.query(Election).filter_by(name='Test2').one()
        results = hold_election(election)

        # Check the results
        assert len(results.winners) == num_winners
        assert len(results.votes) == num_votes
Example #13
0
def create_vote(session: Session, election_id: int, digits: int):
    i = 0
    rolled_back = False
    while i < 5:
        try:
            a = random.randint(10 ** (digits - 1), 10 ** digits - 1)
            v = Vote(vote_key=a, election_id=election_id)
            session.add(v)
            session.commit()
            return v, rolled_back
        except IntegrityError:
            print('Had to retry')
            i += 1
            session.rollback()
            rolled_back = True
    raise Exception('Failing to find a random key in five tries. Think something is wrong.')