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)
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)
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')
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)
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
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')
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)
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)
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)
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)
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)
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)
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')
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)
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)
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)
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
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)
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)
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()
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
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)
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')
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')
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)
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
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()
def resolve_latest_election_group_count(self, info): session = get_session(info) return evalg.proc.election.get_latest_election_group_count( session, self.id)
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)
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