Пример #1
0
def test_mutation_start_election_group_count_responses(
        client, db_session, logged_in_user, election_group_baz,
        election_group_foo, election_foo, election_list_pref_foo,
        election_keys_foo):
    """Verify that the mutation gives correct responses when the count fails"""
    variables = {
        'id': str(election_group_foo.id),
        'electionKey': election_keys_foo['private']
    }
    mutation = """
    mutation startElectionGroupCount($id: UUID!, $electionKey: String!) {
        startElectionGroupCount(id: $id, electionKey: $electionKey) {
            success
            code
            message
        }
    }
    """
    context = get_context()
    execution = client.execute(mutation, variables=variables, context=context)
    assert not execution.get('errors')
    result = execution['data']['startElectionGroupCount']
    # The mutation should fail because election_foo is not closed
    assert (not result['success'] and result['code']
            == 'cannot-count-before-all-elections-are-closed')

    variables = {
        'id': str(election_group_foo.id),
        'electionKey': election_keys_foo['public']
    }
    execution = client.execute(mutation, variables=variables, context=context)
    assert not execution.get('errors')
    result = execution['data']['startElectionGroupCount']
    # The mutation should fail because the wrong code is given
    assert (not result['success'] and result['code'] == 'invalid-election-key')
Пример #2
0
def test_query_election_result_by_id(client, db_session, election_result_foo,
                                     logged_in_user):
    variables = {'id': str(election_result_foo.id)}
    query = """
    query electionResult($id: UUID!) {
        electionResult(id: $id) {
            id
            electionId
            electionGroupCountId
            ballots
            result
        }
    }
    """
    context = get_context()
    execution = client.execute(query, variables=variables, context=context)
    assert not execution.get('error')
    result = execution['data']['electionResult']
    assert result
    assert str(election_result_foo.election_id) == result['electionId']
    assert str(election_result_foo.election_group_count_id
               ) == result['electionGroupCountId']

    assert result['ballots'] == election_result_foo.ballots
    assert result['result'] == election_result_foo.result
Пример #3
0
def test_set_election_group_key_mutation(key, success, client,
                                         make_election_group_from_template,
                                         logged_in_user):
    """Test the SetElectionGroupKey mutation."""

    election_group = make_election_group_from_template('set_key_test',
                                                       'uio_dean',
                                                       logged_in_user)

    variables = {'id': str(election_group.id), 'publicKey': key}
    mutation = """
    mutation ($id: UUID!, $publicKey: String!) {
        setElectionGroupKey(id: $id, publicKey: $publicKey) {
            success
            code
            message
        }
    }
    """
    execution = client.execute(mutation,
                               variables=variables,
                               context=get_context())
    assert not execution.get('errors')
    response = execution['data']['setElectionGroupKey']

    assert response['success'] == success
    election_group_db = ElectionGroup.query.get(election_group.id)
    assert (election_group_db.public_key == key) == success
Пример #4
0
def test_unpublish_election_group(
        db_session,
        client,
        logged_in_user,
        make_election_group,
        make_person_publisher):
    election_group = make_election_group('Test unpublish EG', admin=True)
    db_session.flush()
    assert election_group.published

    make_person_publisher(db_session, logged_in_user.person)
    variables = {'id': str(election_group.id)}
    mutation = """
    mutation ($id: UUID!) {
        unpublishElectionGroup(id: $id) {
            success
        }
    }
    """
    execution = client.execute(
        mutation,
        variables=variables,
        context=get_context())
    assert not execution.get('errors')
    response = execution['data']['unpublishElectionGroup']
    assert response['success']
    election_group_after_after = ElectionGroup.query.get(election_group.id)
    assert not election_group_after_after.published
Пример #5
0
def test_delete_candidate_mutation(owned_election_group,
                                   db_session,
                                   client,
                                   logged_in_user):
    """Test the delete candidate mutation."""
    election_list = owned_election_group(
        db_session,
        logged_in_user.person).elections[0].lists[0]
    candidates_before = {str(x.id): x for x in
                         election_list.candidates}
    candidate = election_list.candidates[0]

    variables = {'id': str(candidate.id)}
    mutation = """
    mutation ($id: UUID!) {
        deleteCandidate(id: $id) {
            ok
        }
    }
    """
    context = get_context()
    execution = client.execute(mutation, variables=variables, context=context)
    assert not execution.get('errors')
    response = execution['data']['deleteCandidate']
    assert response['ok']
    candidate_after = Candidate.query.get(candidate.id)
    assert candidate_after is None
    election_list_after = ElectionList.query.get(election_list.id)
    assert election_list_after is not None
    assert len(election_list_after.candidates) == len(candidates_before) - 1
    assert candidate.id not in [x.id for x in election_list_after.candidates]
Пример #6
0
def test_vote(db_session, client, pollbook_foo, make_pollbook_voter,
              make_pollbook_vote, election_pref_vote, logged_in_user):
    """Test the vote mutation."""
    voter = make_pollbook_voter(person=logged_in_user.person,
                                pollbook=pollbook_foo)

    variables = {
        'voterId': str(voter.id),
        'ballot': json.dumps(election_pref_vote)
    }
    mutation = """
    mutation ($voterId: UUID!, $ballot: JSONString!) {
        vote(voterId: $voterId, ballot: $ballot) {
            ballotId
            electionId
            ok
        }
    }
    """
    execution = client.execute(mutation,
                               variables=variables,
                               context=get_context())
    assert not execution.get('errors')
    response = execution['data']['vote']
    assert response['ok']
    assert response['ballotId']

    ballot_after = Envelope.query.get(response['ballotId'])
    assert ballot_after
Пример #7
0
def test_create_election_group_mutation(template_name, expected_election_nr,
                                        election_type, client, make_ou,
                                        logged_in_user):
    """Test the CreateNewElectionGroup mutation."""
    ou = make_ou(name='Test enhet')
    variables = {
        'ouId': str(ou.id),
        'template': True,
        'templateName': template_name
    }
    mutation = """
    mutation ($ouId: UUID!, $template: Boolean!, $templateName: String!) {
        createNewElectionGroup(ouId: $ouId,
                               template: $template,
                               templateName: $templateName) {
            ok
            electionGroup {
                id
                announced
                elections {
                    id
                    active
                }
                ouId
                publicKey
                published
                type
            }
        }
    }
    """
    execution = client.execute(mutation,
                               variables=variables,
                               context=get_context())
    assert not execution.get('errors')
    response = execution['data']['createNewElectionGroup']
    assert response['ok']

    election_group = response['electionGroup']

    assert not election_group['announced']
    assert not election_group['published']
    assert election_group['ouId'] == str(ou.id)
    assert election_group['publicKey'] is None
    assert election_group['type'] == election_type

    assert len(election_group['elections']) == expected_election_nr
    for election in election_group['elections']:
        if election_type == 'multiple_elections':
            assert not election['active']
        else:
            assert election['active']

    election_group_db = ElectionGroup.query.get(election_group['id'])
    assert election_group_db
    assert not election_group_db.announced
    assert election_group_db.ou_id == ou.id
    assert not election_group_db.published
Пример #8
0
def test_pollbook_voting_report(client, logged_in_user, make_full_election):
    """Test the pollbook voting report."""
    full_election = make_full_election('Test voting report')
    election_group = full_election['election_group']
    pollbook = full_election['elections'][0].pollbooks[0]
    variables = {'id': str(election_group.id)}

    query = """
    query electionGroup($id: UUID!) {
      electionGroup(id: $id) {
        id
        elections {
          id
          pollbooks {
            id
            votersWithVote {
              id
            }
            votersWithoutVote {
              id
            }
          }
        }
      }
    }
    """
    execution = client.execute(query,
                               variables=variables,
                               context=get_context())
    assert not execution.get('errors')
    response = execution['data']['electionGroup']
    assert response

    pollbook_res = response['elections'][0]['pollbooks'][0]

    pollbook_voters = full_election['pollbook_voters'][pollbook_res['id']]
    pollbook_voters_ids = [str(x.id) for x in pollbook_voters]

    voters_with_vote_ids = [
        str(x.voter_id) for x in full_election['votes']
        if str(x.voter_id) in pollbook_voters_ids
    ]
    voters_without_vote_ids = [
        str(x.id) for x in pollbook_voters
        if str(x.id) not in voters_with_vote_ids
    ]

    for voter in pollbook_res['votersWithVote']:
        assert voter['id'] in voters_with_vote_ids
        assert voter['id'] not in voters_without_vote_ids
    for voter in pollbook_res['votersWithoutVote']:
        assert voter['id'] not in voters_with_vote_ids
        assert voter['id'] in voters_without_vote_ids
Пример #9
0
def test_update_team_pref_elec_candidate_mutation(
        team_pref_candidates_foo,
        client, logged_in_user):
    """Test the update team pref elec candidate mutation."""

    candidate_before = team_pref_candidates_foo[0]

    election_list = ElectionList.query.get(candidate_before.list_id)

    variables = {
        'id': str(candidate_before.id),
        'name': 'Foo Bar',
        'coCandidates': [{'name': 'Bar Baz'}, {'name': 'Jane Doe'}],
        'listId': str(candidate_before.list_id)
    }
    mutation = """
    mutation (
        $id: UUID!
        $name: String!
        $coCandidates: [CoCandidatesInput]!
        $listId: UUID!
    ) {
        updateTeamPrefElecCandidate(
        id: $id
        name: $name
        coCandidates: $coCandidates
        listId: $listId
        ) {
            ok
        }
    }
    """
    context = get_context()
    execution = client.execute(mutation, variables=variables, context=context)
    assert not execution.get('errors')
    response = execution['data']['updateTeamPrefElecCandidate']
    assert response['ok']

    # Get new election list
    election_list_after = ElectionList.query.get(election_list.id)
    assert election_list_after is not None

    assert len(election_list_after.candidates) == len(
        election_list.candidates)

    candidate_after = Candidate.query.get(candidate_before.id)
    assert candidate_after.list_id == candidate_before.list_id
    assert candidate_after.name != candidate_before.name
    assert candidate_after.name == variables['name']
    assert candidate_after.meta['co_candidates'] != (
        candidate_before.meta['coCandidates'])
    assert candidate_after.meta['co_candidates'] == variables['coCandidates']
Пример #10
0
def test_update_pref_elec_candidate_mutation(pref_candidates_foo,
                                             client, logged_in_user):
    """Test the update pref elec candidate mutation."""
    candidate_before = pref_candidates_foo[0]

    election_list = ElectionList.query.get(candidate_before.list_id)

    variables = {
        'id': str(candidate_before.id),
        'name': 'FooBar',
        'gender': 'Female' if candidate_before.meta['gender'] == 'Male' else
        'Female',
        'listId': str(candidate_before.list_id)
    }
    mutation = """
    mutation (
        $id: UUID!
        $name: String!
        $gender: String!
        $listId: UUID!
    ) {
        updatePrefElecCandidate(
            id: $id
            name: $name
            gender: $gender
            listId: $listId
        ) {
            ok
        }
    }
    """
    context = get_context()
    execution = client.execute(mutation, variables=variables, context=context)
    assert not execution.get('errors')
    response = execution['data']['updatePrefElecCandidate']
    assert response['ok']

    # Get new election list
    election_list_after = ElectionList.query.get(candidate_before.list.id)

    assert election_list_after is not None
    assert len(election_list_after.candidates) == len(
        election_list.candidates)
    candidate_after = Candidate.query.get(candidate_before.id)
    assert candidate_after.list_id == candidate_before.list_id
    assert candidate_after.name != candidate_before.name
    assert candidate_after.name == variables['name']
    assert candidate_after.meta['gender'] != candidate_before.meta['gender']
    assert candidate_after.meta['gender'] == variables['gender']
Пример #11
0
def test_add_team_pref_elec_candidate_mutation(owned_multiple_election_group,
                                               db_session,
                                               client,
                                               logged_in_user):
    """Test the add pref elec candidate mutation."""
    election_list = owned_multiple_election_group(
        db_session,
        logged_in_user.person).elections[0].lists[0]
    candidates_before = {str(x.id): x for x in
                         election_list.candidates}
    variables = {
        'name': 'Foo Bar',
        'coCandidates': [{'name': 'Bar Baz'}, {'name': 'Jane Doe'}],
        'listId': str(election_list.id)
    }

    mutation = """
    mutation (
        $name: String!
        $coCandidates: [CoCandidatesInput]!
        $listId: UUID!
    ) {
        addTeamPrefElecCandidate(
        name: $name
        coCandidates: $coCandidates
        listId: $listId
        ) {
        ok
        }
    }
    """

    context = get_context()
    execution = client.execute(mutation, variables=variables, context=context)
    assert not execution.get('errors')
    response = execution['data']['addTeamPrefElecCandidate']
    assert response['ok']
    # Get new election list
    election_list_after = ElectionList.query.get(election_list.id)
    assert election_list_after is not None
    assert len(election_list_after.candidates) == len(
        candidates_before) + 1
    for candidate in election_list_after.candidates:
        if str(candidate.id) not in candidates_before:
            assert candidate.name == variables['name']
            assert str(candidate.list_id) == variables['listId']
            assert candidate.meta['co_candidates'] == variables['coCandidates']
            break
Пример #12
0
def test_add_election_admin_by_identifier_validates_role_type(
        db_session, election_group_foo, logged_in_user, client):
    """
    Ensure addElectionGroupRoleByIdentifier validates the role field.
    """
    variables = {
        'electionGroupId': str(election_group_foo.id),
        'role': 'bogus',
        'idType': 'feide_id',
        'idValue': '*****@*****.**',
    }
    execution = client.execute(add_election_group_role_by_identifier_mutation,
                               variables=variables,
                               context=get_context())
    error_message = 'Expected type "ElectionGroupRoleType", found "bogus"'
    assert any(
        [error_message in x.get('message', '') for x in execution['errors']])
Пример #13
0
def test_add_election_admin_when_election_group_does_not_exist(
        db_session, election_group_foo, logged_in_user, client):
    """
    Ensure addElectionGroupRoleByIdentifier fails gracefully when the election
    group does not exist.
    """
    variables = {
        'electionGroupId': str(uuid.uuid4()),
        'role': 'admin',
        'idType': PersonIdType('feide_id').value,
        'idValue': '*****@*****.**',
    }
    execution = client.execute(add_election_group_role_by_identifier_mutation,
                               variables=variables,
                               context=get_context())
    assert not execution.get('errors')
    response = execution['data']['addElectionGroupRoleByIdentifier']
    assert response['success'] is False
    assert response['code'] == 'election-group-not-found'
Пример #14
0
def test_query_election_group_count_by_id(client, election_group_count_foo,
                                          logged_in_user):
    variables = {'id': str(election_group_count_foo.id)}
    query = """
    query electionGroupCount($id: UUID!) {
        electionGroupCount(id: $id) {
            id
            groupId
            electionGroup {
                id
            }
        }
    }
    """
    context = get_context()
    execution = client.execute(query, variables=variables, context=context)
    assert not execution.get('errors')
    response = execution['data']['electionGroupCount']
    assert str(election_group_count_foo.id) == response['id']
    assert str(election_group_count_foo.group_id) == response['groupId']
Пример #15
0
def test_add_election_admin_by_identifier_denies(db_session,
                                                 election_group_baz,
                                                 logged_in_user, client):
    """
    Ensure addElectionGroupRoleByIdentifier disallows adding new roles if the
    current user is not an admin for the election.
    """
    variables = {
        'electionGroupId': str(election_group_baz.id),
        'role': 'admin',
        'idType': PersonIdType('feide_id').value,
        'idValue': '*****@*****.**',
    }
    execution = client.execute(add_election_group_role_by_identifier_mutation,
                               variables=variables,
                               context=get_context())
    assert not execution.get('errors')
    response = execution['data']['addElectionGroupRoleByIdentifier']
    assert response['success'] is False
    assert response['code'] == 'permission-denied'
Пример #16
0
def test_remove_election_group_role_by_grant(db_session, election_group_foo,
                                             logged_in_user, client):
    """
    Ensure removeElectionGroupRoleByGrant removes the specified role grant.
    """
    # Give the logged in user a role
    admin_principal = evalg.proc.authz.get_or_create_principal(
        session=db_session,
        principal_type='person',
        person_id=logged_in_user.person.id,
    )
    evalg.proc.authz.add_election_group_role(
        session=db_session,
        election_group=election_group_foo,
        principal=admin_principal,
        role_name='admin',
    )
    # Create a role to be removed
    principal = evalg.proc.authz.get_or_create_principal(
        session=db_session,
        principal_type='person_identifier',
        id_type='feide_id',
        id_value='*****@*****.**',
    )
    role_to_be_removed = evalg.proc.authz.add_election_group_role(
        session=db_session,
        election_group=election_group_foo,
        principal=principal,
        role_name='admin')
    grant_id = str(role_to_be_removed.grant_id)
    variables = {
        'grantId': grant_id,
    }
    execution = client.execute(remove_election_group_role_by_grant_mutation,
                               variables=variables,
                               context=get_context())
    assert not execution.get('errors')
    response = execution['data']['removeElectionGroupRoleByGrant']
    assert response['success'] is True
    assert response['code'] == 'role-removed'
    assert evalg.proc.authz.get_role_by_grant_id(db_session, grant_id) is None
Пример #17
0
def test_add_election_admin_by_identifier(db_session, election_group_foo,
                                          logged_in_user, client):
    """
    Ensure the addElectionGroupRoleByIdentifier mutation allows adding new admins
    if the current user is an admin for the election.
    """
    variables = {
        'electionGroupId': str(election_group_foo.id),
        'role': 'admin',
        'idType': PersonIdType('feide_id').value,
        'idValue': '*****@*****.**',
    }
    # Give the logged in user a role
    principal = evalg.proc.authz.get_or_create_principal(
        session=db_session,
        principal_type='person',
        person_id=logged_in_user.person.id,
    )
    evalg.proc.authz.add_election_group_role(
        session=db_session,
        election_group=election_group_foo,
        principal=principal,
        role_name='admin',
    )
    execution = client.execute(add_election_group_role_by_identifier_mutation,
                               variables=variables,
                               context=get_context())
    assert not execution.get('errors')
    response = execution['data']['addElectionGroupRoleByIdentifier']
    assert response['success'] is True
    assert response['code'] == 'role-added'
    # Make sure the created principal exists
    created_principal = evalg.database.query.lookup(
        db_session,
        PersonIdentifierPrincipal,
        id_type='feide_id',
        id_value='*****@*****.**')
    assert any([
        x.group == election_group_foo and x.name == 'admin'
        for x in created_principal.roles
    ])
Пример #18
0
def test_query_electiongroup_by_id(make_election_group,
                                   client,
                                   logged_in_user):
    election_group = make_election_group('Test query EG by id')
    variables = {'id': str(election_group.id)}
    query = """
    query electionGroup($id: UUID!) {
        electionGroup(id: $id) {
            id
            name
            description
        }
    }
    """
    execution = client.execute(
        query, variables=variables, context=get_context())
    assert not execution.get('errors')
    response = execution['data']['electionGroup']
    assert str(election_group.id) == response['id']
    assert election_group.name == response['name']
    assert election_group.description == response['description']
Пример #19
0
def test_vote_denied(db_session, client, election_pref_vote,
                     pollbook_voter_bar, logged_in_user):

    variables = {
        'voterId': str(pollbook_voter_bar.id),
        'ballot': json.dumps(election_pref_vote)
    }
    mutation = """
        mutation ($voterId: UUID!, $ballot: JSONString!) {
            vote(voterId: $voterId, ballot: $ballot) {
                ballotId
                electionId
                ok
            }
        }
        """
    execution = client.execute(mutation,
                               variables=variables,
                               context=get_context())
    assert not execution.get('errors')
    response = execution['data']['vote']
    assert response['ok'] is False
Пример #20
0
def test_mutation_start_election_group_count(
        client, db_session, logged_in_user, pref_candidates_bar,
        pollbook_voter_bar, election_group_bar, election_bar, pollbook_bar,
        election_list_pref_bar, election_keys_foo):
    variables = {
        'id': str(election_group_bar.id),
        'electionKey': election_keys_foo['private']
    }
    mutation = """
        mutation startElectionGroupCount($id: UUID!, $electionKey: String!) {
            startElectionGroupCount(id: $id, electionKey: $electionKey) {
                success
                code
                message
            }
        }
        """
    context = get_context()
    execution = client.execute(mutation, variables=variables, context=context)
    assert not execution.get('errors')
    result = execution['data']['startElectionGroupCount']
    print(result)
    assert result['success']
Пример #21
0
def test_query_election_group_counting_results(client, db_session,
                                               logged_in_user,
                                               election_group_count_foo):
    variables = {'id': str(election_group_count_foo.group_id)}
    query = """
    query electionGroupCountingResults($id: UUID!) {
        electionGroupCountingResults(id: $id) {
            id
            groupId
            electionGroup {
                id
            }
        }
    }
    """
    context = get_context()
    execution = client.execute(query, variables=variables, context=context)
    assert not execution.get('errors')
    response = execution['data']['electionGroupCountingResults']

    assert len(response) == 1
    assert str(election_group_count_foo.id) == response[0]['id']
    assert str(election_group_count_foo.group_id) == response[0]['groupId']
Пример #22
0
def test_query_master_keys(client, db_session, master_key):
    """Tests the master_keys query"""
    privkey, master_key = master_key(db_session)
    query = """
    query masterKeys {
        masterKeys {
            id
            publicKey
            description
            active
        }
    }
    """
    execution = client.execute(query, variables={}, context=get_context())
    assert not execution.get('errors')
    assert len(execution['data']['masterKeys']) == 1
    master_key_data = execution['data']['masterKeys'][0]
    assert master_key_data['publicKey'] == master_key.public_key
    assert (privkey.public_key.encode(
        nacl.encoding.Base64Encoder).decode() == master_key_data['publicKey'])
    assert master_key_data['description'] == 'Master key for testing'
    assert master_key_data['active'] is True
    # change / remove the next case in case of new and different key-length
    assert master_key.public_key[-1] == '='
Пример #23
0
def test_mutation_add_election_group_key_backup(client, db_session,
                                                make_election_group,
                                                master_key):
    """Tests the add_election_group_key_backup mutation"""
    privkey, master_key = master_key(db_session)
    election_group = make_election_group('add_election_group_key_backup test',
                                         admin=True)
    mutation = """
    mutation (
        $electionGroupId: UUID!
        $encryptedPrivKey: String!
        $masterKeyId: UUID!
    ) {
        addElectionGroupKeyBackup(
            electionGroupId: $electionGroupId
            encryptedPrivKey: $encryptedPrivKey
            masterKeyId: $masterKeyId
        ) {
            success
        }
    }
    """
    # could put any str, but let's do things properly...
    new_priv_key = nacl.public.PrivateKey.generate()
    message = 'privkey: '.encode() + new_priv_key.encode(
        encoder=nacl.encoding.Base64Encoder)
    ebox = nacl.public.Box(new_priv_key, privkey.public_key)
    encrypted_priv_key = ebox.encrypt(message,
                                      encoder=nacl.encoding.Base64Encoder)
    execution = client.execute(mutation,
                               variables={
                                   'electionGroupId': str(election_group.id),
                                   'encryptedPrivKey':
                                   encrypted_priv_key.decode(),
                                   'masterKeyId': str(master_key.id)
                               },
                               context=get_context())
    assert not execution.get('errors')
    response = execution['data']['addElectionGroupKeyBackup']
    assert response['success']
    key_backups = ElectionGroupKeyBackup.query.filter_by(
        election_group_id=election_group.id,
        master_key_id=master_key.id,
        active=True).all()
    assert len(key_backups) == 1
    assert isinstance(key_backups[0].encrypted_priv_key, str)
    dbox = nacl.public.Box(privkey, new_priv_key.public_key)
    assert (dbox.decrypt(key_backups[0].encrypted_priv_key,
                         encoder=nacl.encoding.Base64Encoder) == message)
    # now create a new key and see if the previous backup will be invalidated
    new_priv_key = nacl.public.PrivateKey.generate()
    message = 'privkey: '.encode() + new_priv_key.encode(
        encoder=nacl.encoding.Base64Encoder)
    ebox = nacl.public.Box(new_priv_key, privkey.public_key)
    encrypted_priv_key = ebox.encrypt(message,
                                      encoder=nacl.encoding.Base64Encoder)
    execution = client.execute(mutation,
                               variables={
                                   'electionGroupId': str(election_group.id),
                                   'encryptedPrivKey':
                                   encrypted_priv_key.decode(),
                                   'masterKeyId': str(master_key.id)
                               },
                               context=get_context())
    assert not execution.get('errors')
    response = execution['data']['addElectionGroupKeyBackup']
    assert response['success']
    key_backups = ElectionGroupKeyBackup.query.filter_by(
        election_group_id=election_group.id, master_key_id=master_key.id)
    # 2 backups and only 1 active
    assert key_backups.count() == 2
    assert key_backups.filter_by(active=True).count() == 1