Exemple #1
0
    def mutate(self, info, **kwargs):

        session = get_session(info)
        user = get_current_user(info)
        elections = kwargs.get('elections')
        if not kwargs.get('has_multiple_times'):
            # TODO: Do we need this? Could we not just send a datetime input
            # for each election?
            for e in elections:
                election = session.query(evalg.models.election.Election).get(
                    e['id'])

                if not can_manage_election(session, user, election):
                    return UpdateVotingPeriods(ok=False)
                election.start = elections[0].start
                election.end = elections[0].end
                session.add(election)
        else:
            for e in elections:
                election = session.query(evalg.models.election.Election).get(
                    e['id'])
                if not can_manage_election(session, user, election):
                    return UpdateVotingPeriods(ok=False)
                election.start = e.start
                election.end = e.end
                session.add(election)
        session.commit()
        return UpdateVotingPeriods(ok=True)
Exemple #2
0
    def mutate(self, info, **kwargs):
        session = get_session(info)
        user = get_current_user(info)
        voter = session.query(evalg.models.voter.Voter).get(kwargs.get('id'))

        if not can_manage_voter(session, user, voter):
            return UpdateVoterPollbook(ok=False)

        pollbook = session.query(evalg.models.pollbook.Pollbook).get(
            kwargs.get('pollbook_id'))

        if not can_manage_pollbook(session, user, pollbook):
            return UpdateVoterPollbook(ok=False)

        election_group_from = voter.pollbook.election.election_group.id
        election_group_to = pollbook.election.election_group.id

        if election_group_from != election_group_to:
            # Do not move voters between election_groups
            return UpdateVoterPollbook(ok=False)

        voter.pollbook_id = kwargs.get('pollbook_id')
        session.add(voter)
        session.commit()
        return UpdateVoterPollbook(ok=True)
Exemple #3
0
    def mutate(self, info, **kwargs):
        session = get_session(info)
        election_group_id = kwargs.get('id')
        election_group = session.query(
            evalg.models.election.ElectionGroup).get(election_group_id)
        user = get_current_user(info)

        if not election_group:
            return PublishElectionGroupResponse(
                success=False,
                code='election-group-not-found',
                message='Election group {} not found'.format(
                    election_group_id))
        if not user:
            return PublishElectionGroupResponse(
                success=False,
                code='user-not-found',
                message='Could not find current user')
        if not can_manage_election_group(session, user, election_group):
            return PublishElectionGroupResponse(
                success=False,
                code='permission-denied',
                message='Not allowed to manage election group '
                'group {}'.format(election_group_id))
        if not can_publish_election_groups(session, user):
            return PublishElectionGroupResponse(
                success=False,
                code='permission-denied',
                message='Not allowed to publish election groups')
        if evalg.proc.election.publish_election_group(session, election_group):
            return PublishElectionGroupResponse(success=True)
        return PublishElectionGroupResponse(
            success=False,
            code='unkown-error',
            message='Could not unpublish election group')
Exemple #4
0
def resolve_get_person_for_voter(_, info, **kwargs):
    voter_id = kwargs['voter_id']
    session = get_session(info)
    voter = evalg.database.query.lookup(session,
                                        evalg.models.voter.Voter,
                                        id=voter_id)
    return evalg.proc.pollbook.get_person_for_voter(session, voter)
Exemple #5
0
    def mutate(self, info, **kwargs):
        session = get_session(info)
        user = get_current_user(info)
        policy = evalg.proc.pollbook.ElectionVoterPolicy(session)
        person_id = kwargs['person_id']
        pollbook_id = kwargs['pollbook_id']
        reason = kwargs.get('reason')

        person = session.query(evalg.models.person.Person).get(person_id)

        pollbook = session.query(
            evalg.models.pollbook.Pollbook).get(pollbook_id)

        if (not can_manage_pollbook(session, user, pollbook)
                and user.person.id != person_id):
            # Only allow users to add themselves to a pollbook they do not own
            return None

        voter = policy.add_voter(pollbook,
                                 person,
                                 self_added=True,
                                 reason=reason)

        session.commit()
        return voter
Exemple #6
0
 def get_current_user_admin_roles(cls, info):
     session = get_session(info)
     current_user = get_current_user(info)
     return evalg.proc.authz.get_person_roles_matching(
         session=session,
         person=current_user.person,
         target_type='election-group-role',
         name='admin')
Exemple #7
0
 def mutate(self, info, **kwargs):
     session = get_session(info)
     user = get_current_user(info)
     candidate = session.query(evalg.models.candidate.Candidate).get(
         kwargs.get('id'))
     kwargs['list_id'] = candidate.list_id
     if not can_manage_election_list(session, user, **kwargs):
         return DeleteCandidate(ok=False)
     result = delete_candidate(session, candidate.id)
     return DeleteCandidate(ok=result)
Exemple #8
0
    def mutate(self, info, **kwargs):
        """The mutation"""
        election_group_id = kwargs['election_group_id']
        master_key_id = kwargs['master_key_id']
        encrypted_priv_key = kwargs['encrypted_priv_key']
        session = get_session(info)
        user = get_current_user(info)
        election_group = session.query(
            evalg.models.election.ElectionGroup).get(election_group_id)
        master_key = session.query(
            evalg.models.privkeys_backup.MasterKey).get(master_key_id)

        if not master_key:
            return AddElectionGroupKeyBackupResponse(
                success=False,
                code='master-key-not-found',
                message='Master key {} not found'.format(master_key_id))
        if not master_key.active:
            # don't just trust the frontend to filter properly
            return AddElectionGroupKeyBackupResponse(
                success=False,
                code='master-key-inactive',
                message='Master key {} is not active'.format(master_key_id))
        if not election_group:
            return AddElectionGroupKeyBackupResponse(
                success=False,
                code='election-group-not-found',
                message='Election group {} not found'.format(
                    election_group_id))
        if not user:
            return AddElectionGroupKeyBackupResponse(
                success=False,
                code='user-not-found',
                message='Could not find current user')
        if not can_manage_election_group(session, user, election_group):
            return AddElectionGroupKeyBackupResponse(
                success=False,
                code='permission-denied',
                message=('Not allowed to set election group key backup for '
                         'election group {}').format(election_group_id))
        egk_backup = evalg.models.privkeys_backup.ElectionGroupKeyBackup(
            encrypted_priv_key=encrypted_priv_key,
            election_group_id=election_group_id,
            master_key_id=master_key_id)
        # No apparent errors to be expected. Invalidate all previous backups!
        session.query(
            evalg.models.privkeys_backup.ElectionGroupKeyBackup).filter_by(
                election_group_id=election_group_id,
                master_key_id=master_key_id,
                active=True).update({'active': False},
                                    synchronize_session=False)
        session.commit()
        session.add(egk_backup)
        session.commit()
        return AddElectionGroupKeyBackupResponse(success=True)
Exemple #9
0
 def mutate(self, info, **kwargs):
     session = get_session(info)
     user = get_current_user(info)
     voter = session.query(evalg.models.voter.Voter).get(kwargs.get('id'))
     if not can_manage_voter(session, user, voter):
         return ReviewVoter(ok=False)
     voter.reviewed = True
     voter.verified = kwargs.get('verify')
     session.add(voter)
     session.commit()
     return ReviewVoter(ok=True)
Exemple #10
0
 def mutate(self, info, **kwargs):
     session = get_session(info)
     user = get_current_user(info)
     pollbook = session.query(evalg.models.pollbook.Pollbook).get(
         kwargs.get('id'))
     if not can_manage_pollbook(session, user, pollbook):
         return DeleteVotersInPollbook(ok=False)
     for voter in pollbook.voters:
         if not voter.votes:
             session.delete(voter)
     session.commit()
     return DeleteVotersInPollbook(ok=True)
Exemple #11
0
 def mutate(self, info, **kwargs):
     session = get_session(info)
     user = get_current_user(info)
     voter = session.query(evalg.models.voter.Voter).get(kwargs.get('id'))
     if not can_vote(session, user, voter):
         return UpdateVoterReason(ok=False)
     voter.reason = kwargs.get('reason')
     # A new review is needed if the reason is updated
     voter.ensure_rereview()
     session.add(voter)
     session.commit()
     return UpdateVoterReason(ok=True)
Exemple #12
0
    def mutate(self, info, **kwargs):
        session = get_session(info)
        user = get_current_user(info)
        if not can_manage_election_list(session, user, **kwargs):
            return AddPrefElecCandidate(ok=False)

        meta = {'gender': kwargs.get('gender')}
        result = add_candidate(session=session,
                               name=kwargs.get('name'),
                               meta=meta,
                               election_list_id=kwargs.get('list_id'),
                               information_url=kwargs.get('information_url'))
        return AddPrefElecCandidate(ok=result)
Exemple #13
0
def resolve_election_key_meta(_, info, **kwargs):
    election_group_id = kwargs['id']
    session = get_session(info)
    user = get_current_user(info)
    el_grp = session.query(
        evalg.models.election.ElectionGroup).get(election_group_id)
    if not can_manage_election_group(session, user, el_grp):
        return None
    key_meta = evalg.proc.group.get_election_key_meta(session,
                                                      election_group_id)
    if key_meta and len(key_meta) > 0:
        return ElectionKeyMeta(election_group_id)
    raise GraphQLError('No info on key found')
Exemple #14
0
def resolve_election_count_by_id(_, info, **kwargs):
    user = get_current_user(info)
    session = get_session(info)
    elec_id = kwargs['id']
    election = evalg.database.query.lookup(session,
                                           evalg.models.election.Election,
                                           id=elec_id)
    if not can_manage_election(session, user, election):
        return None
    data = {
        'id': elec_id,
    }
    data.update(evalg.proc.vote.get_election_vote_counts(session, election))
    return ElectionVoteCounts(**data)
Exemple #15
0
    def mutate(self, info, **kwargs):
        session = get_session(info)
        user = get_current_user(info)
        voter = session.query(evalg.models.voter.Voter).get(kwargs.get('id'))
        if not can_manage_pollbook(session, user, voter.pollbook):
            return DeleteVoter(ok=False)
        if voter.self_added:
            return DeleteVoter(ok=False)
        if voter.votes:
            return DeleteVoter(ok=False)

        session.delete(voter)
        session.commit()
        return DeleteVoter(ok=True)
Exemple #16
0
 def mutate(self, info, ou_id, template, template_name):
     session = get_session(info)
     ou = session.query(evalg.models.ou.OrganizationalUnit).get(ou_id)
     election_group = evalg.proc.election.make_group_from_template(
         session, template_name, ou)
     current_user = get_current_user(info)
     current_user_principal = evalg.proc.authz.get_or_create_principal(
         session, principal_type='person', person_id=current_user.person.id)
     evalg.proc.authz.add_election_group_role(
         session=session,
         election_group=election_group,
         principal=current_user_principal,
         role_name='admin')
     session.commit()
     return CreateNewElectionGroup(election_group=election_group, ok=True)
Exemple #17
0
    def mutate(self, info, **kwargs):
        user = get_current_user(info)
        voter_id = kwargs['voter_id']
        ballot_data = kwargs['ballot']
        session = get_session(info)
        vote_policy = evalg.proc.vote.ElectionVotePolicy(session, voter_id)

        if not vote_policy.voter:
            return AddVote(ok=False)

        if not can_vote(session, user, vote_policy.voter):
            return AddVote(ok=False)

        if not vote_policy.verify_election_is_ongoing():
            logger.error(('Can\'t add vote, election is not ongoing. user: '******'%s, voter: %s election: %s'), user.person.id,
                         voter_id, vote_policy.voter.pollbook.election.id)
            return AddVote(ok=False)

        if not vote_policy.verify_ballot_content(ballot_data):
            logger.error('Invalid ballot! user %s, voter %s election %s',
                         user.person.id, voter_id,
                         vote_policy.voter.pollbook.election.id)
            return AddVote(ok=False)

        ballot_data.__delitem__('isBlankVote')
        ballot_data['pollbookId'] = str(vote_policy.voter.pollbook.id)
        vote = vote_policy.add_vote(ballot_data)
        session.flush()

        node = AddVote(ballot_id=vote.ballot_id,
                       election_id=vote_policy.voter.pollbook.election.id,
                       ok=True)
        session.commit()
        logger.info('Vote added. user: %s, voter: %s election: %s',
                    user.person.id, voter_id,
                    vote_policy.voter.pollbook.election.id)

        from evalg.tasks.celery_worker import send_vote_confirmation_mail_task

        election_group = vote_policy.voter.pollbook.election.election_group
        election_group_name = election_group.name

        if current_app.config.get('MAIL_ENABLE'):
            send_vote_confirmation_mail_task.delay(user.person.email,
                                                   election_group_name)

        return node
Exemple #18
0
    def mutate(self, info, **kwargs):
        """The mutation function."""
        election_group_id = kwargs['id']
        public_key = kwargs['public_key']
        session = get_session(info)
        user = get_current_user(info)
        election_group = session.query(
            evalg.models.election.ElectionGroup).get(election_group_id)
        if not can_manage_election_group(session, user, election_group):
            return SetElectionGroupKeyResponse(
                success=False,
                code='permission-denied',
                message='Not allowed to set election group key for election '
                'group {}'.format(election_group_id))

        if election_group.public_key and election_group.published:
            return SetElectionGroupKeyResponse(
                success=False,
                code='cannot-change-key-if-published',
                message=('The public key cannot be changed if '
                         'an election is published'))

        for election in election_group.elections:
            if (election_group.public_key and election.active
                    and election.has_started):
                return SetElectionGroupKeyResponse(
                    success=False,
                    code='cannot-change-key-if-past-start',
                    message=('The public key cannot be changed if '
                             'an election has started'))
            else:
                count = evalg.proc.vote.get_election_vote_counts(
                    session, election)
                if any(count.values()):
                    return SetElectionGroupKeyResponse(
                        success=False,
                        code='cannot-change-key-if-votes-exist',
                        message=('The public key cannot be changed if '
                                 'a vote has been cast'))
        if not evalg.proc.election.is_valid_public_key(public_key):
            return SetElectionGroupKeyResponse(
                success=False,
                code='invalid-key',
                message='The public key given is not a valid key')
        election_group.public_key = public_key
        session.add(election_group)
        session.commit()
        return SetElectionGroupKeyResponse(success=True)
Exemple #19
0
    def mutate(self, info, **kwargs):
        user = get_current_user(info)
        pollbook_id = kwargs['pollbook_id']
        census_file = kwargs['census_file']
        session = get_session(info)

        try:
            pollbook = session.query(
                evalg.models.pollbook.Pollbook).get(pollbook_id)
        except Exception as e:
            capture_exception(e)
            return UploadCensusFileResponse(
                success=False,
                code='pollbook-not-found',
                message='No pollbook with id {!r}'.format(pollbook_id))

        if not can_manage_pollbook(session, user, pollbook):
            return UploadCensusFileResponse(
                success=False,
                code='permission-denied',
                message='No access to pollbook id {!r}'.format(pollbook_id))

        logger.info('Updating %r from %r', pollbook, census_file)
        file_content = census_file.read()
        parser = CensusFileParser.factory(file_content, census_file.mimetype)
        if not parser:
            return UploadCensusFileResponse(
                success=False,
                code='unsupported-file-type',
                message='Unsupported file type {!r}'.format(
                    census_file.mimetype))

        file_import = evalg.models.census_file_import.CensusFileImport(
            initiated_at=datetime.datetime.now(datetime.timezone.utc),
            file_name=census_file.filename,
            census_file=file_content,
            mime_type=census_file.mimetype,
            pollbook_id=pollbook_id)

        session.add(file_import)
        session.commit()

        from evalg.tasks.celery_worker import import_census_file_task
        import_census_file_task.delay(pollbook_id, file_import.id)

        logger.info('Started file import as celery job')

        return UploadCensusFileResponse(success=True)
Exemple #20
0
def resolve_search_voters(_, info, **kwargs):
    election_group_id = kwargs.pop('election_group_id')
    session = get_session(info)

    if 'search' in kwargs and kwargs.get('search') == '':
        # Return nothing if the search string is empty
        return []

    if 'limit' in kwargs:
        limit = kwargs.pop('limit')
        return evalg.proc.pollbook.get_voters_in_election_group(
            session, election_group_id,
            **kwargs).order_by('id').limit(limit).all()

    return evalg.proc.pollbook.get_voters_in_election_group(
        session, election_group_id, **kwargs).all()
Exemple #21
0
def can_access_field(source, info, **kwargs):
    """Checks if the requested field can be accessed by the user

    :type info: graphql.execution.base.ResolveInfo
    """
    session = get_session(info)
    user = get_current_user(info)
    permissions = permissions_config().get(str(info.parent_type))
    if permissions is None:
        return False
    field_name = camel_to_snake_case(info.field_name)
    permission = permissions.get(field_name)
    if all_permissions.get(permission, deny)(session, user, source,
                                             path=info.path, **kwargs):
        return True
    return False
Exemple #22
0
    def mutate(self, info, **kwargs):
        session = get_session(info)
        user = get_current_user(info)
        elections = kwargs.get('elections')

        for e in elections:
            election = session.query(evalg.models.election.Election).get(
                e['id'])
            if not can_manage_election(session, user, election):
                return UpdateVotingPeriods(ok=False)
            election.mandate_period_start = e.mandate_period_start
            election.mandate_period_end = e.mandate_period_end
            election.contact = e.contact
            election.information_url = e.information_url
            session.add(election)

        session.commit()
        return UpdateVoterInfo(ok=True)
Exemple #23
0
    def mutate(self, info, **kwargs):
        valid_roles = ['admin']
        session = get_session(info)
        user = get_current_user(info)
        election_group_id = kwargs.get('election_group_id')
        role_name = kwargs.get('role')
        id_type = kwargs.get('id_type')
        id_value = kwargs.get('id_value')
        election_group = evalg.database.query.lookup_or_none(
            session, evalg.models.election.ElectionGroup, id=election_group_id)
        if election_group is None:
            return AddElectionGroupRoleByIdentifierResponse(
                success=False,
                code='election-group-not-found',
                message='No election group identified by {}'.format(
                    election_group_id))
        if not can_manage_election_group(session, user, election_group):
            return AddElectionGroupRoleByIdentifierResponse(
                success=False,
                code='permission-denied',
                message='Not allowed to add roles for election {}'.format(
                    election_group_id))
        if role_name not in valid_roles:
            # TODO improve this at some point.
            #   We need to check this to stop someone from adding a
            #   publisher or global_admin role.
            return AddElectionGroupRoleByIdentifierResponse(
                success=False,
                code='permission-denied',
                message='Not allowed to add role of type {}'.format(role_name))

        principal = get_or_create_principal(session=session,
                                            principal_type='person_identifier',
                                            id_type=id_type,
                                            id_value=id_value)
        add_election_group_role(session=session,
                                election_group=election_group,
                                principal=principal,
                                role_name=role_name)
        session.commit()
        return AddElectionGroupRoleByIdentifierResponse(success=True,
                                                        code='role-added')
Exemple #24
0
 def mutate(self, info, **kwargs):
     session = get_session(info)
     user = get_current_user(info)
     grant_id = kwargs.get('grant_id')
     role = evalg.proc.authz.get_role_by_grant_id(session, grant_id)
     if role is None:
         return RemoveElectionGroupRoleByGrantResponse(
             success=False,
             code='grant-not-found',
             message='No election group role grant identified by {}'.format(
                 grant_id))
     if not can_manage_election_group(session, user, role.group):
         return RemoveElectionGroupRoleByGrantResponse(
             success=False,
             code='permission-denied',
             message='Not allowed to remove roles for election {}'.format(
                 role.group.id))
     delete_role(session, role)
     session.commit()
     return RemoveElectionGroupRoleByGrantResponse(success=True,
                                                   code='role-removed')
Exemple #25
0
 def mutate(self, info, **kwargs):
     # TODO:
     #   Is there any particular reason why the ElectionGroup settings and
     #   Election settings are bound together in a single mutation?
     session = get_session(info)
     user = get_current_user(info)
     election_group_id = kwargs.get('id')
     el_grp = session.query(
         evalg.models.election.ElectionGroup).get(election_group_id)
     if not can_manage_election_group(session, user, el_grp):
         return UpdateBaseSettings(ok=False)
     el_grp.meta['candidate_rules']['candidate_gender'] = kwargs.get(
         'has_gender_quota')
     session.add(el_grp)
     for e in kwargs.get('elections'):
         election = session.query(evalg.models.election.Election).get(
             e['id'])
         election.meta['candidate_rules']['seats'] = e.seats
         election.meta['candidate_rules']['substitutes'] = e.substitutes
         election.active = e.active
         session.add(election)
     session.commit()
     return UpdateBaseSettings(ok=True)
Exemple #26
0
    def mutate(self, info, **kwargs):
        session = get_session(info)
        user = get_current_user(info)
        policy = evalg.proc.pollbook.ElectionVoterPolicy(session)
        id_type = kwargs['id_type']
        id_value = kwargs['id_value']
        pollbook_id = kwargs['pollbook_id']
        self_added = not kwargs.get('approved', False)
        reason = kwargs.get('reason')

        pollbook = session.query(
            evalg.models.pollbook.Pollbook).get(pollbook_id)

        if not can_manage_pollbook(session, user, pollbook):
            return None

        voter = policy.add_voter_id(pollbook,
                                    id_type,
                                    id_value,
                                    self_added=self_added,
                                    reason=reason)

        session.commit()
        return voter
Exemple #27
0
def resolve_persons_with_multiple_verified_voters(_, info, **kwargs):
    election_group_id = kwargs.get('id')
    session = get_session(info)
    user = get_current_user(info)
    el_grp = session.query(
        evalg.models.election.ElectionGroup).get(election_group_id)
    if not can_manage_election_group(session, user, el_grp):
        return None
    query = evalg.proc.pollbook.get_persons_with_multiple_verified_voters(
        session, election_group_id)

    class PersonWithVoters:
        def __init__(self, person, voter):
            self.person = person
            self.voters = [voter]

    person_id2person_with_voters = {}
    for person, voter in query.all():
        if person.id in person_id2person_with_voters.keys():
            person_id2person_with_voters[person.id].voters.append(voter)
        else:
            person_id2person_with_voters[person.id] = PersonWithVoters(
                person, voter)
    return person_id2person_with_voters.values()
Exemple #28
0
 def resolve_latest_election_group_count(self, info):
     session = get_session(info)
     return evalg.proc.election.get_latest_election_group_count(
         session, self.id)
Exemple #29
0
    def mutate(self, info, **kwargs):
        session = get_session(info)
        user = get_current_user(info)
        election_group_id = kwargs['id']
        election_key = kwargs['election_key']

        election_group_counter = evalg.proc.count.ElectionGroupCounter(
            session, election_group_id, election_key)

        if not can_manage_election_group(session, user,
                                         election_group_counter.group):
            return CountElectionGroupResponse(
                success=False,
                code='permission-denied',
                message='Not allowed to count election group {}'.format(
                    election_group_id))
        if evalg.proc.pollbook.get_persons_with_multiple_verified_voters(
                session, election_group_id).all():
            return CountElectionGroupResponse(
                success=False,
                code='persons-with-multiple-votes',
                message='There are person(s) who have multiple verified votes')

        if evalg.proc.pollbook.get_voters_in_election_group(
                session, election_group_id, self_added=True,
                reviewed=False).all():
            return CountElectionGroupResponse(
                success=False,
                code='unreviewed-self-added-voters',
                message='All self added voters must be reviewed')

        if not election_group_counter.ballot_serializer:
            return CountElectionGroupResponse(
                success=False,
                code='invalid-election-key-wrong-format',
                message='The given election key is invalid')

        if not election_group_counter.verify_election_key():
            return CountElectionGroupResponse(
                success=False,
                code='invalid-election-key',
                message='The given election key is invalid')

        if not election_group_counter.group.status == 'closed':
            return CountElectionGroupResponse(
                success=False,
                code='cannot-count-before-all-elections-are-closed',
                message='All of the elections in an election group must be'
                ' closed to count votes')

        # Creating an election_group_count entry in the db
        count = election_group_counter.log_start_count()
        election_group_counter.deserialize_ballots()
        election_group_counter.process_for_count()

        if info.context['user'].person:
            election_group_counter.generate_results(
                count,
                getattr(info.context['user'].person, 'display_name', None))
        else:
            election_group_counter.generate_results(count)

        count = election_group_counter.log_finalize_count(count)

        return CountElectionGroupResponse(success=True,
                                          election_group_count_id=count.id)
Exemple #30
0
 def resolve_generated_by(self, info):
     session = get_session(info)
     key_meta = evalg.proc.group.get_election_key_meta(
         session, self.election_group_id)
     return key_meta[0].transaction.user