#61 Port election to open-id connect
Merged 3 years ago by pingou. Opened 3 years ago by pingou.

file modified
+31 -4
@@ -43,7 +43,7 @@ 

  [vagrant@localhost ~]$ pushd /vagrant/; ./runserver.py --host "0.0.0.0";

  ```

  

- Once that is running, go to [localhost:5002](http://localhost:5002/) in your

+ Once that is running, go to [localhost:5005](http://localhost:5005/) in your

Why the change in the port?

It's the default port used by flask, fixing the doc here :)

  browser to see your running Fedora Elections test instance.

  

  ### A note about fonts
@@ -116,6 +116,32 @@ 

  python createdb.py

  ```

  

+ ### Register the application using openid-connect

+ 

+ Run:

+ 

+ ```

+ oidc-register https://iddev.fedorainfracloud.org/ http://localhost:5005/oidc_callback

+ ```

+ 

+ Copy the corresponding ``client_secrets.json`` in the sources:

+ 

+ ```

+ cp client_secrets.json fedora_elections/client_secrets.json

+ ```

+ 

+ ### Create a local configuration file

+ 

+ Run:

+ 

+ ```

+ cat > config <<EOL

+ OIDC_ID_TOKEN_COOKIE_SECURE = False

+ OIDC_REQUIRE_VERIFIED_EMAIL = False

+ EOL

+ ```

+ 

+ 

  ### Starting the app

  

  There are 2 ways to start the application:
@@ -127,10 +153,10 @@ 

  

  This is useful for a quick development instance, when you don't have to worry

  about security yet. Do not run this in production. The server will start on

- http://127.0.0.1:5000.

+ http://127.0.0.1:5005.

  

  ```

- ./runserver

+ ./runserver.py -c config

  ```

  

  #### With Apache
@@ -151,7 +177,8 @@ 

  adjust the `.wsgi` file in `/var/www` to point to the `fedora_elections`

  directory.

  

- Place the configuration file in `/etc/fedora-elections/fedora-elections.cfg`.

+ Place the configuration file in `/etc/fedora-elections/fedora-elections.cfg`

+ and adjust it as you wish.

  

  ```

  sudo mkdir -p /etc/fedora-elections/

file modified
+37 -9
@@ -39,10 +39,11 @@ 

  from urlparse import urlparse, urljoin  # noqa

  

  import flask  # noqa

+ import munch  # noqa

  

  from fedora.client import AuthError, AppError  # noqa

  from fedora.client.fas2 import AccountSystem  # noqa

- from flask_fas_openid import FAS  # noqa

+ from flask_oidc import OpenIDConnect  # noqa

  

  import fedora_elections.fedmsgshim  # noqa

  import fedora_elections.mail_logging  # noqa
@@ -54,7 +55,7 @@ 

      APP.config.from_envvar('FEDORA_ELECTIONS_CONFIG')

  

  # set up FAS

- FAS = FAS(APP)

+ OIDC = OpenIDConnect(APP, credentials_store=flask.session)

  

  # Set up the logging

  if not APP.debug:
@@ -106,12 +107,22 @@ 

          ref_url.netloc == test_url.netloc

  

  

- def is_admin(user):

+ def is_admin(user, user_groups=None):

      ''' Is the user an elections admin.

      '''

+     if not user_groups:

+         user_groups = []

+ 

      if not user:

          return False

-     if not user.cla_done or len(user.groups) < 1:

+     if not user.cla_done:

+         return False

+ 

+     user_groups = []

+     if is_authenticated() and OIDC.user_loggedin:

+         user_groups = OIDC.user_getfield('groups')

+ 

+     if len(user_groups) < 1:

          return False

  

      admins = APP.config['FEDORA_ELECTIONS_ADMIN_GROUP']
@@ -120,7 +131,7 @@ 

      else:

          admins = set(admins)

  

-     return len(set(user.groups).intersection(admins)) > 0

+     return len(set(user_groups).intersection(admins)) > 0

  

  

  def is_election_admin(user, election_id):
@@ -163,7 +174,7 @@ 

      template).

      '''

      user = None

-     if hasattr(flask.g, 'fas_user'):

+     if is_authenticated() and OIDC.user_loggedin:

          user = flask.g.fas_user

      return dict(is_admin=is_admin(user),

                  version=__version__)
@@ -195,10 +206,25 @@ 

  

  # pylint: disable=W0613

  @APP.before_request

- def set_session():

+ def set_session():  # pragma: no-cover

      """ Set the flask session as permanent. """

      flask.session.permanent = True

  

+     if OIDC.user_loggedin:

+         if not hasattr(flask.session, 'fas_user') or not flask.session.fas_user:

+             flask.session.fas_user = munch.Munch({

+                 'username': OIDC.user_getfield('nickname'),

+                 'email': OIDC.user_getfield('email') or '',

+                 'timezone': OIDC.user_getfield('zoneinfo'),

+                 'cla_done': \

+                     'http://admin.fedoraproject.org/accounts/cla/done' \

+                     in (OIDC.user_getfield('cla') or []),

+             })

+         flask.g.fas_user = flask.session.fas_user

+     else:

+         flask.session.fas_user = None

+         flask.g.fas_user = None

+ 

  

  # pylint: disable=W0613

  @APP.teardown_request
@@ -294,6 +320,7 @@ 

  

  

  @APP.route('/login', methods=('GET', 'POST'))

+ @OIDC.require_login

  def auth_login():

      next_url = None

      if 'next' in flask.request.args:
@@ -310,14 +337,15 @@ 

          if isinstance(groups, basestring):

              groups = [groups]

          groups.extend(models.get_groups(SESSION))

-         return FAS.login(return_url=next_url, groups=groups)

+         return flask.redirect(next_url)

  

  

  @APP.route('/logout')

  def auth_logout():

      if hasattr(flask.g, 'fas_user') and flask.g.fas_user is not None:

-         FAS.logout()

+         OIDC.logout()

          flask.g.fas_user = None

+         flask.session.fas_user = None

          flask.flash('You have been logged out')

      return safe_redirect_back()

  

@@ -3,7 +3,7 @@ 

  '''

  Fedora elections default configuration.

  '''

- 

+ import os

  from datetime import timedelta

  

  # Set the time after which the session expires
@@ -22,3 +22,9 @@ 

  FAS_USERNAME = ''

  FAS_PASSWORD = ''

  FAS_CHECK_CERT = False

+ 

+ 

+ OIDC_CLIENT_SECRETS = os.path.join(os.path.dirname(

+     os.path.abspath(__file__)), 'client_secrets.json')

+ OIDC_SCOPES = ['openid', 'email', 'profile', 'fedora']

+ OIDC_OPENID_REALM = 'http://localhost:5005/oidc_callback'

file modified
+10 -7
@@ -32,7 +32,7 @@ 

  from fedora_elections import forms

  from fedora_elections import models

  from fedora_elections import (

-     APP, SESSION, is_authenticated, is_admin, is_election_admin,

+     OIDC, APP, SESSION, is_authenticated, is_admin, is_election_admin,

      safe_redirect_back,

  )

  from fedora_elections.utils import build_name_map
@@ -48,11 +48,13 @@ 

              flask.flash(

                  'You must sign the CLA to vote', 'error')

              return safe_redirect_back()

-         elif len(flask.g.fas_user.groups) == 0:

-             flask.flash(

-                 'You need to be in one another group than CLA to vote',

-                 'error')

-             return safe_redirect_back()

+         else:

+             user_groups = OIDC.user_getfield('groups')

+             if len(user_groups) == 0:

+                 flask.flash(

+                     'You need to be in one another group than CLA to vote',

+                     'error')

+                 return safe_redirect_back()

  

          return f(*args, **kwargs)

      return decorated_function
@@ -93,7 +95,8 @@ 

          return election

  

      if election.legal_voters_list:

-         if len(set(flask.g.fas_user.groups).intersection(

+         user_groups = OIDC.user_getfield('groups')

+         if len(set(user_groups).intersection(

                  set(election.legal_voters_list))) == 0:

              flask.flash(

                  'You are not among the groups that are allowed to vote '

file modified
+1 -3
@@ -1,12 +1,10 @@ 

  # Used for when working from a virtualenv.

  # Use this file by running "$ pip install -r requirements.txt"

  Flask>=0.10

+ flask-oidc

  Flask-wtf

  kitchen

  python-fedora

- python-openid

- python-openid-cla

- python-openid-teams

  SQLAlchemy

  wtforms

  arrow

file modified
+1 -1
@@ -23,7 +23,7 @@ 

      default=False,

      help='Profile the application.')

  parser.add_argument(

-     '--port', '-p', default=5000,

+     '--port', '-p', default=5005,

      help='Port for the flask application.')

  parser.add_argument(

      '--host', default="127.0.0.1",

file modified
+1
@@ -1,4 +1,5 @@ 

  #!/bin/bash

  

+ FEDORA_ELECTIONS_CONFIG=`pwd`/tests/config \

  PYTHONPATH=fedora_elections ./nosetests \

  --with-coverage --cover-erase --cover-package=fedora_elections $*

file modified
+2 -1
@@ -67,7 +67,7 @@ 

  

  

  @contextmanager

- def user_set(APP, user):

+ def user_set(APP, user, oidc_id_token=None):

      """ Set the provided user as fas_user in the provided application."""

  

      # Hack used to remove the before_request function set by
@@ -78,6 +78,7 @@ 

  

      def handler(sender, **kwargs):

          g.fas_user = user

+         g.oidc_id_token = oidc_id_token

  

      with appcontext_pushed.connected_to(handler, APP):

          yield

@@ -0,0 +1,12 @@ 

+ {

+ 	"web": {

+ 		"redirect_uris": ["http://localhost:5005/oidc_callback"],

+ 		"token_uri": "https://iddev.fedorainfracloud.org/openidc/Token",

+ 		"auth_uri": "https://iddev.fedorainfracloud.org/openidc/Authorization",

+ 		"client_id": "client_id",

+ 		"client_secret": "client_secret",

+ 		"userinfo_uri": "https://iddev.fedorainfracloud.org/openidc/UserInfo",

+ 		"token_introspection_uri": "https://iddev.fedorainfracloud.org/openidc/TokenInfo",

+ 		"issuer": "https://iddev.fedorainfracloud.org/openidc/"

+ 	}

+ }

file added
+4
@@ -0,0 +1,4 @@ 

+ import os

+ 

+ OIDC_CLIENT_SECRETS = os.path.join(os.path.dirname(

+     os.path.abspath(__file__)), 'client_secrets.json')

file modified
+64 -33
@@ -31,6 +31,7 @@ 

  from datetime import timedelta

  

  import flask

+ from mock import patch, MagicMock

  

  sys.path.insert(0, os.path.join(os.path.dirname(

      os.path.abspath(__file__)), '..'))
@@ -117,18 +118,31 @@ 

              flask.g.fas_user = None

              self.assertFalse(fedora_elections.is_admin(flask.g.fas_user))

  

-             flask.g.fas_user = FakeUser()

-             self.assertFalse(fedora_elections.is_admin(flask.g.fas_user))

+             flask.g.oidc_id_token = 'foobar'

+ 

+             with patch(

+                     'fedora_elections.OIDC.user_getfield',

+                     MagicMock(return_value=['foobar'])):

+                 flask.g.fas_user = FakeUser()

+                 self.assertFalse(fedora_elections.is_admin(flask.g.fas_user))

  

-             flask.g.fas_user = FakeUser(

-                 fedora_elections.APP.config['FEDORA_ELECTIONS_ADMIN_GROUP'])

-             self.assertTrue(fedora_elections.is_admin(flask.g.fas_user))

+             with patch(

+                     'fedora_elections.OIDC.user_getfield',

+                     MagicMock(return_value=['elections'])):

+                 flask.g.fas_user = FakeUser(

+                     fedora_elections.APP.config['FEDORA_ELECTIONS_ADMIN_GROUP'])

+                 self.assertTrue(

+                     fedora_elections.is_admin(flask.g.fas_user, ['elections']))

  

-             fedora_elections.APP.config['FEDORA_ELECTIONS_ADMIN_GROUP'] = [

-                 'sysadmin-main', 'sysadmin-elections']

-             flask.g.fas_user = FakeUser(

-                 fedora_elections.APP.config['FEDORA_ELECTIONS_ADMIN_GROUP'])

-             self.assertTrue(fedora_elections.is_admin(flask.g.fas_user))

+             with patch(

+                     'fedora_elections.OIDC.user_getfield',

+                     MagicMock(return_value=['sysadmin-main'])):

+ 

+                 fedora_elections.APP.config['FEDORA_ELECTIONS_ADMIN_GROUP'] = [

+                     'sysadmin-main', 'sysadmin-elections']

+                 flask.g.fas_user = FakeUser(['sysadmin-main'])

+                 self.assertTrue(

+                     fedora_elections.is_admin(flask.g.fas_user, ['sysadmin-main']))

  

      def test_is_election_admin(self):

          """ Test the is_election_admin function. """
@@ -140,31 +154,42 @@ 

                  fedora_elections.is_election_admin(

                      flask.g.fas_user, 1)

              )

+ 

+             flask.g.oidc_id_token = 'foobar'

+ 

              flask.g.fas_user = FakeUser()

              self.assertFalse(

                  fedora_elections.is_election_admin(

                      flask.g.fas_user, 1)

              )

-             flask.g.fas_user = FakeUser(

-                 fedora_elections.APP.config['FEDORA_ELECTIONS_ADMIN_GROUP'])

-             self.assertTrue(fedora_elections.is_election_admin(

-                 flask.g.fas_user, 1))

+             with patch(

+                     'fedora_elections.OIDC.user_getfield',

+                     MagicMock(return_value=['elections'])):

+                 flask.g.fas_user = FakeUser(

+                     fedora_elections.APP.config['FEDORA_ELECTIONS_ADMIN_GROUP'])

+                 self.assertTrue(fedora_elections.is_election_admin(

+                     flask.g.fas_user, 1))

  

          self.setup_db()

  

          with app.test_request_context():

              flask.g.fas_user = FakeUser('testers')

-             # This is user is not an admin for election #1

-             self.assertFalse(

-                 fedora_elections.is_election_admin(

-                     flask.g.fas_user, 1)

-             )

+             flask.g.oidc_id_token = 'foobar'

  

-             # This is user is an admin for election #2

-             self.assertTrue(

-                 fedora_elections.is_election_admin(

-                     flask.g.fas_user, 2)

-             )

+             # This is user is not an admin for election #1

+             with patch(

+                     'fedora_elections.OIDC.user_getfield',

+                     MagicMock(return_value=['foobar'])):

+                 self.assertFalse(

+                     fedora_elections.is_election_admin(

+                         flask.g.fas_user, 1)

+                 )

+ 

+                 # This is user is an admin for election #2

+                 self.assertTrue(

+                     fedora_elections.is_election_admin(

+                         flask.g.fas_user, 2)

+                 )

  

      def test_is_safe_url(self):

          """ Test the is_safe_url function. """
@@ -182,17 +207,23 @@ 

          with app.test_request_context():

              flask.g.fas_user = FakeUser(['gitr2spec'])

              output = self.app.get('/login')

-             self.assertEqual(output.status_code, 200)

+             self.assertEqual(output.status_code, 302)

+             self.assertIn(

+                 'https://iddev.fedorainfracloud.org/openidc/Authorization?',

+                 output.data)

  

              output = self.app.get('/login?next=http://localhost/')

-             self.assertEqual(output.status_code, 200)

- 

-         self.setup_db()

-         user = FakeUser([], username='pingou')

-         with user_set(fedora_elections.APP, user):

-             output = self.app.get('/login', follow_redirects=True)

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue('<title>Fedora elections</title>' in output.data)

+             self.assertEqual(output.status_code, 302)

+             self.assertIn(

+                 'https://iddev.fedorainfracloud.org/openidc/Authorization?',

+                 output.data)

+ 

+         # self.setup_db()

+         # user = FakeUser([], username='pingou')

+         # with user_set(fedora_elections.APP, user):

+             # output = self.app.get('/login', follow_redirects=True)

+             # self.assertEqual(output.status_code, 200)

+             # self.assertTrue('<title>Fedora elections</title>' in output.data)

  

      def test_auth_logout(self):

          """ Test the auth_logout function. """

file modified
+956 -895
@@ -32,6 +32,7 @@ 

  from datetime import timedelta

  

  import flask

+ from mock import patch, MagicMock

  

  sys.path.insert(0, os.path.join(os.path.dirname(

      os.path.abspath(__file__)), '..'))
@@ -49,16 +50,39 @@ 

          user = FakeUser(

              fedora_elections.APP.config['FEDORA_ELECTIONS_ADMIN_GROUP'],

              username='toshio')

-         with user_set(fedora_elections.APP, user):

-             output = self.app.get('/admin/election_test/')

-             self.assertEqual(output.status_code, 404)

  

+         with user_set(fedora_elections.APP, user, oidc_id_token='foobar'):

+             with patch(

+                     'fedora_elections.OIDC.user_getfield',

+                     MagicMock(return_value=['elections'])):

+                 output = self.app.get('/admin/election_test/')

+                 self.assertEqual(output.status_code, 404)

+ 

+         self.setup_db()

+ 

+         with user_set(fedora_elections.APP, user, oidc_id_token='foobar'):

+             with patch(

+                     'fedora_elections.OIDC.user_getfield',

+                     MagicMock(return_value=['elections'])):

+                 output = self.app.get('/admin/test_election/')

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue('Candidates <span class="label label-pill label-default">3</span>' in output.data)

+ 

+     def test_admin_no_cla(self):

+         """ Test the admin_new_election function. """

          self.setup_db()

  

-         with user_set(fedora_elections.APP, user):

-             output = self.app.get('/admin/test_election/')

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue('Candidates <span class="label label-pill label-default">3</span>' in output.data)

+         user = FakeUser(

+             fedora_elections.APP.config['FEDORA_ELECTIONS_ADMIN_GROUP'],

+             username='toshio')

+ 

+         user.cla_done = False

+         with user_set(fedora_elections.APP, user, oidc_id_token='foobar'):

+             with patch(

+                     'fedora_elections.OIDC.user_getfield',

+                     MagicMock(return_value=['elections'])):

+                 output = self.app.get('/admin/new')

+                 self.assertEqual(output.status_code, 403)

  

      def test_admin_new_election(self):

          """ Test the admin_new_election function. """
@@ -67,410 +91,421 @@ 

          user = FakeUser(

              fedora_elections.APP.config['FEDORA_ELECTIONS_ADMIN_GROUP'],

              username='toshio')

-         with user_set(fedora_elections.APP, user):

-             output = self.app.get('/admin/new')

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 '<h2>Create new election</h2>' in output.data)

-             if self.get_wtforms_version() >= (2, 2):

-                 self.assertIn(

-                     'input class="form-control" id="shortdesc" '

-                     'name="shortdesc" required type="text" ', output.data)

-             else:

-                 self.assertIn(

-                     'input class="form-control" id="shortdesc" '

-                     'name="shortdesc" type="text" ', output.data)

- 

-             # No csrf provided

-             data = {

-                 'alias': 'new_election',

-                 'shortdesc': 'new election shortdesc',

-                 'description': 'new election description',

-                 'voting_type': 'simple',

-                 'url': 'https://fedoraproject.org',

-                 'start_date': TODAY + timedelta(days=2),

-                 'end_date': TODAY + timedelta(days=4),

-                 'seats_elected': '2',

-                 'candidates_are_fasusers': False,

-                 'embargoed': True,

-             }

- 

-             output = self.app.post('/admin/new', data=data)

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 '<h2>Create new election</h2>' in output.data)

-             if self.get_wtforms_version() >= (2, 2):

-                 self.assertIn(

-                     'input class="form-control" id="shortdesc" '

-                     'name="shortdesc" required type="text" ', output.data)

-             else:

-                 self.assertIn(

-                     'input class="form-control" id="shortdesc" '

-                     'name="shortdesc" type="text" ', output.data)

- 

-             csrf_token = self.get_csrf(output=output)

- 

-             # Description missing

-             data = {

-                 'alias': 'new_election',

-                 'shortdesc': 'new election shortdesc',

-                 'voting_type': 'simple',

-                 'url': 'https://fedoraproject.org',

-                 'start_date': TODAY + timedelta(days=2),

-                 'end_date': TODAY + timedelta(days=4),

-                 'seats_elected': '2',

-                 'candidates_are_fasusers': False,

-                 'embargoed': True,

-                 'csrf_token': csrf_token,

-             }

- 

-             output = self.app.post('/admin/new', data=data)

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 '<h2>Create new election</h2>' in output.data)

-             if self.get_wtforms_version() >= (2, 2):

-                 self.assertIn(

-                     'input class="form-control" id="shortdesc" '

-                     'name="shortdesc" required type="text" ', output.data)

-             else:

-                 self.assertIn(

-                     'input class="form-control" id="shortdesc" '

-                     'name="shortdesc" type="text" ', output.data)

-             self.assertTrue(

-                 '<div class="form-control-feedback">This field is required.</div>'

-                 in output.data)

- 

-             # Invalid alias

-             data = {

-                 'alias': 'new',

-                 'shortdesc': 'new election shortdesc',

-                 'description': 'new election description',

-                 'voting_type': 'simple',

-                 'url': 'https://fedoraproject.org',

-                 'start_date': TODAY + timedelta(days=2),

-                 'end_date': TODAY + timedelta(days=4),

-                 'seats_elected': 2,

-                 'candidates_are_fasusers': False,

-                 'embargoed': True,

-                 'csrf_token': csrf_token,

-             }

- 

-             output = self.app.post('/admin/new', data=data)

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 '<h2>Create new election</h2>' in output.data)

-             if self.get_wtforms_version() >= (2, 2):

-                 self.assertIn(

-                     'input class="form-control" id="shortdesc" '

-                     'name="shortdesc" required type="text" ', output.data)

-             else:

-                 self.assertIn(

-                     'input class="form-control" id="shortdesc" '

-                     'name="shortdesc" type="text" ', output.data)

-             self.assertTrue(

-                 '<div class="form-control-feedback">The alias cannot be <code>new</code>.</div>'

-                 in output.data)

- 

-             # Invalid: end_date earlier than start_date

-             data = {

-                 'alias': 'new_election',

-                 'shortdesc': 'new election shortdesc',

-                 'description': 'new election description',

-                 'voting_type': 'simple',

-                 'url': 'https://fedoraproject.org',

-                 'start_date': TODAY + timedelta(days=6),

-                 'end_date': TODAY + timedelta(days=4),

-                 'seats_elected': 2,

-                 'candidates_are_fasusers': False,

-                 'embargoed': True,

-                 'csrf_token': csrf_token,

-             }

- 

-             output = self.app.post('/admin/new', data=data)

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 '<h2>Create new election</h2>' in output.data)

-             if self.get_wtforms_version() >= (2, 2):

+ 

+         with user_set(fedora_elections.APP, user, oidc_id_token='foobar'):

+             with patch(

+                     'fedora_elections.OIDC.user_getfield',

+                     MagicMock(return_value=['elections'])):

+                 output = self.app.get('/admin/new')

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     '<h2>Create new election</h2>' in output.data)

+                 if self.get_wtforms_version() >= (2, 2):

+                     self.assertIn(

+                         'input class="form-control" id="shortdesc" '

+                         'name="shortdesc" required type="text" ', output.data)

+                 else:

+                     self.assertIn(

+                         'input class="form-control" id="shortdesc" '

+                         'name="shortdesc" type="text" ', output.data)

+ 

+                 # No csrf provided

+                 data = {

+                     'alias': 'new_election',

+                     'shortdesc': 'new election shortdesc',

+                     'description': 'new election description',

+                     'voting_type': 'simple',

+                     'url': 'https://fedoraproject.org',

+                     'start_date': TODAY + timedelta(days=2),

+                     'end_date': TODAY + timedelta(days=4),

+                     'seats_elected': '2',

+                     'candidates_are_fasusers': False,

+                     'embargoed': True,

+                 }

+ 

+                 output = self.app.post('/admin/new', data=data)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     '<h2>Create new election</h2>' in output.data)

+                 if self.get_wtforms_version() >= (2, 2):

+                     self.assertIn(

+                         'input class="form-control" id="shortdesc" '

+                         'name="shortdesc" required type="text" ', output.data)

+                 else:

+                     self.assertIn(

+                         'input class="form-control" id="shortdesc" '

+                         'name="shortdesc" type="text" ', output.data)

+ 

+                 csrf_token = self.get_csrf(output=output)

+ 

+                 # Description missing

+                 data = {

+                     'alias': 'new_election',

+                     'shortdesc': 'new election shortdesc',

+                     'voting_type': 'simple',

+                     'url': 'https://fedoraproject.org',

+                     'start_date': TODAY + timedelta(days=2),

+                     'end_date': TODAY + timedelta(days=4),

+                     'seats_elected': '2',

+                     'candidates_are_fasusers': False,

+                     'embargoed': True,

+                     'csrf_token': csrf_token,

+                 }

+ 

+                 output = self.app.post('/admin/new', data=data)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     '<h2>Create new election</h2>' in output.data)

+                 if self.get_wtforms_version() >= (2, 2):

+                     self.assertIn(

+                         'input class="form-control" id="shortdesc" '

+                         'name="shortdesc" required type="text" ', output.data)

+                 else:

+                     self.assertIn(

+                         'input class="form-control" id="shortdesc" '

+                         'name="shortdesc" type="text" ', output.data)

+                 self.assertTrue(

+                     '<div class="form-control-feedback">This field is required.</div>'

+                     in output.data)

+ 

+                 # Invalid alias

+                 data = {

+                     'alias': 'new',

+                     'shortdesc': 'new election shortdesc',

+                     'description': 'new election description',

+                     'voting_type': 'simple',

+                     'url': 'https://fedoraproject.org',

+                     'start_date': TODAY + timedelta(days=2),

+                     'end_date': TODAY + timedelta(days=4),

+                     'seats_elected': 2,

+                     'candidates_are_fasusers': False,

+                     'embargoed': True,

+                     'csrf_token': csrf_token,

+                 }

+ 

+                 output = self.app.post('/admin/new', data=data)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     '<h2>Create new election</h2>' in output.data)

+                 if self.get_wtforms_version() >= (2, 2):

+                     self.assertIn(

+                         'input class="form-control" id="shortdesc" '

+                         'name="shortdesc" required type="text" ', output.data)

+                 else:

+                     self.assertIn(

+                         'input class="form-control" id="shortdesc" '

+                         'name="shortdesc" type="text" ', output.data)

+                 self.assertTrue(

+                     '<div class="form-control-feedback">The alias cannot be <code>new</code>.</div>'

+                     in output.data)

+ 

+                 # Invalid: end_date earlier than start_date

+                 data = {

+                     'alias': 'new_election',

+                     'shortdesc': 'new election shortdesc',

+                     'description': 'new election description',

+                     'voting_type': 'simple',

+                     'url': 'https://fedoraproject.org',

+                     'start_date': TODAY + timedelta(days=6),

+                     'end_date': TODAY + timedelta(days=4),

+                     'seats_elected': 2,

+                     'candidates_are_fasusers': False,

+                     'embargoed': True,

+                     'csrf_token': csrf_token,

+                 }

+ 

+                 output = self.app.post('/admin/new', data=data)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     '<h2>Create new election</h2>' in output.data)

+                 if self.get_wtforms_version() >= (2, 2):

+                     self.assertIn(

+                         'input class="form-control" id="shortdesc" '

+                         'name="shortdesc" required type="text" ', output.data)

+                 else:

+                     self.assertIn(

+                         'input class="form-control" id="shortdesc" '

+                         'name="shortdesc" type="text" ', output.data)

+                 self.assertTrue(

+                     'class="form-control-feedback">End date must be later than start date.</div>'

+                     in output.data)

+ 

+                 # Invalid: alias already taken

+                 data = {

+                     'alias': 'test_election',

+                     'shortdesc': 'new election shortdesc',

+                     'description': 'new election description',

+                     'voting_type': 'simple',

+                     'url': 'https://fedoraproject.org',

+                     'start_date': TODAY + timedelta(days=6),

+                     'end_date': TODAY + timedelta(days=4),

+                     'seats_elected': 2,

+                     'candidates_are_fasusers': False,

+                     'embargoed': True,

+                     'csrf_token': csrf_token,

+                 }

+ 

+                 output = self.app.post('/admin/new', data=data)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     '<h2>Create new election</h2>' in output.data)

+                 if self.get_wtforms_version() >= (2, 2):

+                     self.assertIn(

+                         'input class="form-control" id="shortdesc" '

+                         'name="shortdesc" required type="text" ', output.data)

+                 else:

+                     self.assertIn(

+                         'input class="form-control" id="shortdesc" '

+                         'name="shortdesc" type="text" ', output.data)

+                 self.assertTrue(

+                     '<div class="form-control-feedback">There is already another election with '

+                     'this alias.</div>' in output.data)

+ 

+                 # Invalid: shortdesc already taken

+                 data = {

+                     'alias': 'new_election',

+                     'shortdesc': 'test election shortdesc',

+                     'description': 'new election description',

+                     'voting_type': 'simple',

+                     'url': 'https://fedoraproject.org',

+                     'start_date': TODAY + timedelta(days=6),

+                     'end_date': TODAY + timedelta(days=4),

+                     'seats_elected': 2,

+                     'candidates_are_fasusers': False,

+                     'embargoed': True,

+                     'csrf_token': csrf_token,

+                 }

+ 

+                 output = self.app.post('/admin/new', data=data)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     '<h2>Create new election</h2>' in output.data)

+                 if self.get_wtforms_version() >= (2, 2):

+                     self.assertIn(

+                         'input class="form-control" id="shortdesc" '

+                         'name="shortdesc" required type="text" ', output.data)

+                 else:

+                     self.assertIn(

+                         'input class="form-control" id="shortdesc" '

+                         'name="shortdesc" type="text" ', output.data)

+                 self.assertTrue(

+                     '<div class="form-control-feedback">There is already another election with '

+                     'this summary.</div>' in output.data)

+ 

+                 # All good  -  max_votes is ignored as it is not a integer

+                 data = {

+                     'alias': 'new_election',

+                     'shortdesc': 'new election shortdesc',

+                     'description': 'new election description',

+                     'voting_type': 'simple',

+                     'url': 'https://fedoraproject.org',

+                     'start_date': TODAY + timedelta(days=2),

+                     'end_date': TODAY + timedelta(days=4),

+                     'seats_elected': 2,

+                     'candidates_are_fasusers': False,

+                     'embargoed': True,

+                     'admin_grp': 'testers, sysadmin-main,,',

+                     'lgl_voters': 'testers, packager,,',

+                     'max_votes': 'wrong',

+                     'csrf_token': csrf_token,

+                 }

+ 

+                 output = self.app.post(

+                     '/admin/new', data=data, follow_redirects=True)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     'Election "new_election" added'

+                     in output.data)

+                 self.assertTrue(

+                     'There are no candidates.' in output.data)

                  self.assertIn(

-                     'input class="form-control" id="shortdesc" '

-                     'name="shortdesc" required type="text" ', output.data)

-             else:

+                     'input class="form-control" id="admin_grp" '

+                     'name="admin_grp" type="text" '

+                     'value="sysadmin-main, testers">', output.data)

                  self.assertIn(

-                     'input class="form-control" id="shortdesc" '

-                     'name="shortdesc" type="text" ', output.data)

-             self.assertTrue(

-                 'class="form-control-feedback">End date must be later than start date.</div>'

-                 in output.data)

- 

-             # Invalid: alias already taken

-             data = {

-                 'alias': 'test_election',

-                 'shortdesc': 'new election shortdesc',

-                 'description': 'new election description',

-                 'voting_type': 'simple',

-                 'url': 'https://fedoraproject.org',

-                 'start_date': TODAY + timedelta(days=6),

-                 'end_date': TODAY + timedelta(days=4),

-                 'seats_elected': 2,

-                 'candidates_are_fasusers': False,

-                 'embargoed': True,

-                 'csrf_token': csrf_token,

-             }

- 

-             output = self.app.post('/admin/new', data=data)

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 '<h2>Create new election</h2>' in output.data)

-             if self.get_wtforms_version() >= (2, 2):

+                     'input class="form-control" id="lgl_voters" '

+                     'name="lgl_voters" type="text" '

+                     'value="packager, testers">', output.data)

                  self.assertIn(

-                     'input class="form-control" id="shortdesc" '

-                     'name="shortdesc" required type="text" ', output.data)

-             else:

+                     'input class="form-control" id="max_votes" '

+                     'name="max_votes" type="text" '

+                     'value="">', output.data)

+ 

+                 # All good  -  max_votes is ignored as it is not a integer

+                 data = {

+                     'alias': 'new_election2',

+                     'shortdesc': 'new election2 shortdesc',

+                     'description': 'new election2 description',

+                     'voting_type': 'simple',

+                     'url': 'https://fedoraproject.org',

+                     'start_date': TODAY + timedelta(days=2),

+                     'end_date': TODAY + timedelta(days=4),

+                     'seats_elected': 2,

+                     'candidates_are_fasusers': False,

+                     'embargoed': True,

+                     'admin_grp': 'testers, , sysadmin-main,,',

+                     'lgl_voters': 'testers, packager,,,',

+                     'csrf_token': csrf_token,

+                 }

+ 

+                 output = self.app.post(

+                     '/admin/new', data=data, follow_redirects=True)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     'Election "new_election2" added'

+                     in output.data)

+                 self.assertTrue(

+                     'There are no candidates.' in output.data)

                  self.assertIn(

-                     'input class="form-control" id="shortdesc" '

-                     'name="shortdesc" type="text" ', output.data)

-             self.assertTrue(

-                 '<div class="form-control-feedback">There is already another election with '

-                 'this alias.</div>' in output.data)

- 

-             # Invalid: shortdesc already taken

-             data = {

-                 'alias': 'new_election',

-                 'shortdesc': 'test election shortdesc',

-                 'description': 'new election description',

-                 'voting_type': 'simple',

-                 'url': 'https://fedoraproject.org',

-                 'start_date': TODAY + timedelta(days=6),

-                 'end_date': TODAY + timedelta(days=4),

-                 'seats_elected': 2,

-                 'candidates_are_fasusers': False,

-                 'embargoed': True,

-                 'csrf_token': csrf_token,

-             }

- 

-             output = self.app.post('/admin/new', data=data)

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 '<h2>Create new election</h2>' in output.data)

-             if self.get_wtforms_version() >= (2, 2):

+                     'input class="form-control" id="admin_grp" '

+                     'name="admin_grp" type="text" '

+                     'value="sysadmin-main, testers">', output.data)

                  self.assertIn(

-                     'input class="form-control" id="shortdesc" '

-                     'name="shortdesc" required type="text" ', output.data)

-             else:

+                     'input class="form-control" id="lgl_voters" '

+                     'name="lgl_voters" type="text" '

+                     'value="packager, testers">', output.data)

                  self.assertIn(

-                     'input class="form-control" id="shortdesc" '

-                     'name="shortdesc" type="text" ', output.data)

-             self.assertTrue(

-                 '<div class="form-control-feedback">There is already another election with '

-                 'this summary.</div>' in output.data)

- 

-             # All good  -  max_votes is ignored as it is not a integer

-             data = {

-                 'alias': 'new_election',

-                 'shortdesc': 'new election shortdesc',

-                 'description': 'new election description',

-                 'voting_type': 'simple',

-                 'url': 'https://fedoraproject.org',

-                 'start_date': TODAY + timedelta(days=2),

-                 'end_date': TODAY + timedelta(days=4),

-                 'seats_elected': 2,

-                 'candidates_are_fasusers': False,

-                 'embargoed': True,

-                 'admin_grp': 'testers, sysadmin-main,,',

-                 'lgl_voters': 'testers, packager,,',

-                 'max_votes': 'wrong',

-                 'csrf_token': csrf_token,

-             }

- 

-             output = self.app.post(

-                 '/admin/new', data=data, follow_redirects=True)

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 'Election "new_election" added'

-                 in output.data)

-             self.assertTrue(

-                 'There are no candidates.' in output.data)

-             self.assertIn(

-                 'input class="form-control" id="admin_grp" '

-                 'name="admin_grp" type="text" '

-                 'value="sysadmin-main, testers">', output.data)

-             self.assertIn(

-                 'input class="form-control" id="lgl_voters" '

-                 'name="lgl_voters" type="text" '

-                 'value="packager, testers">', output.data)

-             self.assertIn(

-                 'input class="form-control" id="max_votes" '

-                 'name="max_votes" type="text" '

-                 'value="">', output.data)

- 

-             # All good  -  max_votes is ignored as it is not a integer

-             data = {

-                 'alias': 'new_election2',

-                 'shortdesc': 'new election2 shortdesc',

-                 'description': 'new election2 description',

-                 'voting_type': 'simple',

-                 'url': 'https://fedoraproject.org',

-                 'start_date': TODAY + timedelta(days=2),

-                 'end_date': TODAY + timedelta(days=4),

-                 'seats_elected': 2,

-                 'candidates_are_fasusers': False,

-                 'embargoed': True,

-                 'admin_grp': 'testers, , sysadmin-main,,',

-                 'lgl_voters': 'testers, packager,,,',

-                 'csrf_token': csrf_token,

-             }

- 

-             output = self.app.post(

-                 '/admin/new', data=data, follow_redirects=True)

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 'Election "new_election2" added'

-                 in output.data)

-             self.assertTrue(

-                 'There are no candidates.' in output.data)

-             self.assertIn(

-                 'input class="form-control" id="admin_grp" '

-                 'name="admin_grp" type="text" '

-                 'value="sysadmin-main, testers">', output.data)

-             self.assertIn(

-                 'input class="form-control" id="lgl_voters" '

-                 'name="lgl_voters" type="text" '

-                 'value="packager, testers">', output.data)

-             self.assertIn(

-                 'input class="form-control" id="max_votes" '

-                 'name="max_votes" type="text" '

-                 'value="">', output.data)

+                     'input class="form-control" id="max_votes" '

+                     'name="max_votes" type="text" '

+                     'value="">', output.data)

  

      def test_admin_edit_election(self):

          """ Test the admin_edit_election function. """

          user = FakeUser(

              fedora_elections.APP.config['FEDORA_ELECTIONS_ADMIN_GROUP'],

              username='toshio')

-         with user_set(fedora_elections.APP, user):

-             output = self.app.get('/admin/test_election/')

-             self.assertEqual(output.status_code, 404)

+ 

+         with user_set(fedora_elections.APP, user, oidc_id_token='foobar'):

+             with patch(

+                     'fedora_elections.OIDC.user_getfield',

+                     MagicMock(return_value=['elections'])):

+                 output = self.app.get('/admin/test_election/')

+                 self.assertEqual(output.status_code, 404)

  

          self.setup_db()

  

-         with user_set(fedora_elections.APP, user):

-             output = self.app.get('/admin/test_election/')

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 'Election Details' in output.data)

-             if self.get_wtforms_version() >= (2, 2):

+         with user_set(fedora_elections.APP, user, oidc_id_token='foobar'):

+             with patch(

+                     'fedora_elections.OIDC.user_getfield',

+                     MagicMock(return_value=['elections'])):

+                 output = self.app.get('/admin/test_election/')

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     'Election Details' in output.data)

+                 if self.get_wtforms_version() >= (2, 2):

+                     self.assertIn(

+                         'input class="form-control" id="shortdesc" '

+                         'name="shortdesc" required type="text" ', output.data)

+                 else:

+                     self.assertIn(

+                         'input class="form-control" id="shortdesc" '

+                         'name="shortdesc" type="text" ', output.data)

+ 

+                 data = {

+                     'alias': 'test_election',

+                     'shortdesc': 'test election shortdesc',

+                     'description': 'test election description',

+                     'voting_type': 'simple',

+                     'url': 'https://fedoraproject.org',

+                     'start_date': TODAY - timedelta(days=10),

+                     'end_date': TODAY - timedelta(days=8),

+                     'seats_elected': '2',

+                     'candidates_are_fasusers': False,

+                     'embargoed': False,

+                 }

+ 

+                 output = self.app.post('/admin/test_election/', data=data)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     'Election Details' in output.data)

+                 if self.get_wtforms_version() >= (2, 2):

+                     self.assertIn(

+                         'input class="form-control" id="shortdesc" '

+                         'name="shortdesc" required type="text" ', output.data)

+                 else:

+                     self.assertIn(

+                         'input class="form-control" id="shortdesc" '

+                         'name="shortdesc" type="text" ', output.data)

+ 

+                 csrf_token = self.get_csrf()

+ 

+                 data = {

+                     'alias': 'test_election',

+                     'voting_type': 'simple',

+                     'url': 'https://fedoraproject.org',

+                     'start_date': TODAY - timedelta(days=10),

+                     'end_date': TODAY - timedelta(days=8),

+                     'seats_elected': '2',

+                     'candidates_are_fasusers': False,

+                     'embargoed': False,

+                     'csrf_token': csrf_token,

+                 }

+ 

+                 output = self.app.post(

+                     '/admin/test_election/', data=data)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     'Election Details' in output.data)

+                 if self.get_wtforms_version() >= (2, 2):

+                     self.assertIn(

+                         'input class="form-control" id="shortdesc" '

+                         'name="shortdesc" required type="text" ', output.data)

+                 else:

+                     self.assertIn(

+                         'input class="form-control" id="shortdesc" '

+                         'name="shortdesc" type="text" ', output.data)

                  self.assertIn(

-                     'input class="form-control" id="shortdesc" '

-                     'name="shortdesc" required type="text" ', output.data)

-             else:

-                 self.assertIn(

-                     'input class="form-control" id="shortdesc" '

-                     'name="shortdesc" type="text" ', output.data)

- 

-             data = {

-                 'alias': 'test_election',

-                 'shortdesc': 'test election shortdesc',

-                 'description': 'test election description',

-                 'voting_type': 'simple',

-                 'url': 'https://fedoraproject.org',

-                 'start_date': TODAY - timedelta(days=10),

-                 'end_date': TODAY - timedelta(days=8),

-                 'seats_elected': '2',

-                 'candidates_are_fasusers': False,

-                 'embargoed': False,

-             }

- 

-             output = self.app.post('/admin/test_election/', data=data)

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 'Election Details' in output.data)

-             if self.get_wtforms_version() >= (2, 2):

-                 self.assertIn(

-                     'input class="form-control" id="shortdesc" '

-                     'name="shortdesc" required type="text" ', output.data)

-             else:

-                 self.assertIn(

-                     'input class="form-control" id="shortdesc" '

-                     'name="shortdesc" type="text" ', output.data)

- 

-             csrf_token = self.get_csrf()

- 

-             data = {

-                 'alias': 'test_election',

-                 'voting_type': 'simple',

-                 'url': 'https://fedoraproject.org',

-                 'start_date': TODAY - timedelta(days=10),

-                 'end_date': TODAY - timedelta(days=8),

-                 'seats_elected': '2',

-                 'candidates_are_fasusers': False,

-                 'embargoed': False,

-                 'csrf_token': csrf_token,

-             }

- 

-             output = self.app.post(

-                 '/admin/test_election/', data=data)

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 'Election Details' in output.data)

-             if self.get_wtforms_version() >= (2, 2):

-                 self.assertIn(

-                     'input class="form-control" id="shortdesc" '

-                     'name="shortdesc" required type="text" ', output.data)

-             else:

-                 self.assertIn(

-                     'input class="form-control" id="shortdesc" '

-                     'name="shortdesc" type="text" ', output.data)

-             self.assertIn(

-                 '<div class="form-control-feedback">This field is required.</div>',

-                 output.data)

- 

-             # Check election before edit

-             output = self.app.get('/admin/test_election/')

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue('Candidates <span class="label label-pill label-default">3</span>' in output.data)

-             if self.get_wtforms_version() >= (2, 2):

-                 self.assertIn(

-                     'input class="form-control" id="seats_elected" '

-                     'name="seats_elected" required type="text" '

-                     'value="1">', output.data)

-             else:

-                 self.assertIn(

-                     'input class="form-control" id="seats_elected" '

-                     'name="seats_elected" type="text" '

-                     'value="1">', output.data)

- 

-             data = {

-                 'alias': 'test_election',

-                 'shortdesc': 'test election shortdesc',

-                 'description': 'test election description',

-                 'voting_type': 'simple',

-                 'url': 'https://fedoraproject.org',

-                 'start_date': TODAY - timedelta(days=10),

-                 'end_date': TODAY - timedelta(days=8),

-                 'seats_elected': '2',

-                 'candidates_are_fasusers': False,

-                 'embargoed': False,

-                 'max_votes': 'wrong',

-                 'csrf_token': csrf_token,

-             }

- 

-             output = self.app.post(

-                 '/admin/test_election/', data=data, follow_redirects=True)

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 'Election "test_election" saved'

-                 in output.data)

-             # We edited the seats_elected from 1 to 2

-             if self.get_wtforms_version() >= (2, 2):

-                 self.assertIn(

-                     'input class="form-control" id="seats_elected" '

-                     'name="seats_elected" required type="text" '

-                     'value="2">', output.data)

-             else:

-                 self.assertIn(

-                     'input class="form-control" id="seats_elected" '

-                     'name="seats_elected" type="text" '

-                     'value="2">', output.data)

-             self.assertTrue('Candidates <span class="label label-pill label-default">3</span>' in output.data)

+                     '<div class="form-control-feedback">This field is required.</div>',

+                     output.data)

+ 

+                 # Check election before edit

+                 output = self.app.get('/admin/test_election/')

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue('Candidates <span class="label label-pill label-default">3</span>' in output.data)

+                 if self.get_wtforms_version() >= (2, 2):

+                     self.assertIn(

+                         'input class="form-control" id="seats_elected" '

+                         'name="seats_elected" required type="text" '

+                         'value="1">', output.data)

+                 else:

+                     self.assertIn(

+                         'input class="form-control" id="seats_elected" '

+                         'name="seats_elected" type="text" '

+                         'value="1">', output.data)

+ 

+                 data = {

+                     'alias': 'test_election',

+                     'shortdesc': 'test election shortdesc',

+                     'description': 'test election description',

+                     'voting_type': 'simple',

+                     'url': 'https://fedoraproject.org',

+                     'start_date': TODAY - timedelta(days=10),

+                     'end_date': TODAY - timedelta(days=8),

+                     'seats_elected': '2',

+                     'candidates_are_fasusers': False,

+                     'embargoed': False,

+                     'max_votes': 'wrong',

+                     'csrf_token': csrf_token,

+                 }

+ 

+                 output = self.app.post(

+                     '/admin/test_election/', data=data, follow_redirects=True)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     'Election "test_election" saved'

+                     in output.data)

+                 # We edited the seats_elected from 1 to 2

+                 if self.get_wtforms_version() >= (2, 2):

+                     self.assertIn(

+                         'input class="form-control" id="seats_elected" '

+                         'name="seats_elected" required type="text" '

+                         'value="2">', output.data)

+                 else:

+                     self.assertIn(

+                         'input class="form-control" id="seats_elected" '

+                         'name="seats_elected" type="text" '

+                         'value="2">', output.data)

+                 self.assertTrue('Candidates <span class="label label-pill label-default">3</span>' in output.data)

  

      def test_admin_edit_election_admin_groups(self):

          """ Test the admin_edit_election function when editing admin groups.
@@ -478,109 +513,116 @@ 

          user = FakeUser(

              fedora_elections.APP.config['FEDORA_ELECTIONS_ADMIN_GROUP'],

              username='toshio')

-         with user_set(fedora_elections.APP, user):

-             output = self.app.get('/admin/test_election/edit')

-             self.assertEqual(output.status_code, 404)

- 

-         self.setup_db()

  

-         with user_set(fedora_elections.APP, user):

-             output = self.app.get('/admin/test_election2/')

-             self.assertEqual(output.status_code, 200)

-             csrf_token = self.get_csrf(output=output)

+         with user_set(fedora_elections.APP, user, oidc_id_token='foobar'):

+             with patch(

+                     'fedora_elections.OIDC.user_getfield',

+                     MagicMock(return_value=['elections'])):

+                 output = self.app.get('/admin/test_election/edit')

+                 self.assertEqual(output.status_code, 404)

  

-             # Edit Admin Group

+         self.setup_db()

  

-             # Check election before edit

-             output = self.app.get('/admin/test_election2/')

-             self.assertEqual(output.status_code, 200)

-             if self.get_wtforms_version() >= (2, 2):

-                 self.assertIn(

-                     'input class="form-control" id="seats_elected" '

-                     'name="seats_elected" required type="text" '

-                     'value="1">', output.data)

-             else:

+         with user_set(fedora_elections.APP, user, oidc_id_token='foobar'):

+             with patch(

+                     'fedora_elections.OIDC.user_getfield',

+                     MagicMock(return_value=['elections'])):

+                 output = self.app.get('/admin/test_election2/')

+                 self.assertEqual(output.status_code, 200)

+                 csrf_token = self.get_csrf(output=output)

+ 

+                 # Edit Admin Group

+ 

+                 # Check election before edit

+                 output = self.app.get('/admin/test_election2/')

+                 self.assertEqual(output.status_code, 200)

+                 if self.get_wtforms_version() >= (2, 2):

+                     self.assertIn(

+                         'input class="form-control" id="seats_elected" '

+                         'name="seats_elected" required type="text" '

+                         'value="1">', output.data)

+                 else:

+                     self.assertIn(

+                         'input class="form-control" id="seats_elected" '

+                         'name="seats_elected" type="text" '

+                         'value="1">', output.data)

+                 self.assertTrue('Candidates <span class="label' in output.data)

+ 

+                 # Add a new admin group: sysadmin-main

+                 data = {

+                     'alias': 'test_election2',

+                     'shortdesc': 'test election 2 shortdesc',

+                     'description': 'test election 2 description',

+                     'voting_type': 'range',

+                     'url': 'https://fedoraproject.org',

+                     'start_date': TODAY - timedelta(days=7),

+                     'end_date': TODAY - timedelta(days=5),

+                     'seats_elected': '2',

+                     'candidates_are_fasusers': False,

+                     'embargoed': False,

+                     'admin_grp': 'testers, sysadmin-main',

+                     'csrf_token': csrf_token,

+                 }

+ 

+                 output = self.app.post(

+                     '/admin/test_election2/', data=data, follow_redirects=True)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     'Election "test_election2" saved'

+                     in output.data)

+                 if self.get_wtforms_version() >= (2, 2):

+                     self.assertIn(

+                         'input class="form-control" id="seats_elected" '

+                         'name="seats_elected" required type="text" '

+                         'value="2">', output.data)

+                 else:

+                     self.assertIn(

+                         'input class="form-control" id="seats_elected" '

+                         'name="seats_elected" type="text" '

+                         'value="2">', output.data)

+                 # We edited the admin groups

                  self.assertIn(

-                     'input class="form-control" id="seats_elected" '

-                     'name="seats_elected" type="text" '

-                     'value="1">', output.data)

-             self.assertTrue('Candidates <span class="label' in output.data)

- 

-             # Add a new admin group: sysadmin-main

-             data = {

-                 'alias': 'test_election2',

-                 'shortdesc': 'test election 2 shortdesc',

-                 'description': 'test election 2 description',

-                 'voting_type': 'range',

-                 'url': 'https://fedoraproject.org',

-                 'start_date': TODAY - timedelta(days=7),

-                 'end_date': TODAY - timedelta(days=5),

-                 'seats_elected': '2',

-                 'candidates_are_fasusers': False,

-                 'embargoed': False,

-                 'admin_grp': 'testers, sysadmin-main',

-                 'csrf_token': csrf_token,

-             }

- 

-             output = self.app.post(

-                 '/admin/test_election2/', data=data, follow_redirects=True)

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 'Election "test_election2" saved'

-                 in output.data)

-             if self.get_wtforms_version() >= (2, 2):

+                     'input class="form-control" id="admin_grp" '

+                     'name="admin_grp" type="text" '

+                     'value="sysadmin-main, testers">', output.data)

+ 

+                 # Remove an existing group: testers

+                 data = {

+                     'alias': 'test_election2',

+                     'shortdesc': 'test election 2 shortdesc',

+                     'description': 'test election 2 description',

+                     'voting_type': 'range',

+                     'url': 'https://fedoraproject.org',

+                     'start_date': TODAY - timedelta(days=7),

+                     'end_date': TODAY - timedelta(days=5),

+                     'seats_elected': '2',

+                     'candidates_are_fasusers': False,

+                     'embargoed': False,

+                     'admin_grp': 'sysadmin-main',

+                     'csrf_token': csrf_token,

+                 }

+ 

+                 output = self.app.post(

+                     '/admin/test_election2/', data=data, follow_redirects=True)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     'Election "test_election2" saved'

+                     in output.data)

+                 if self.get_wtforms_version() >= (2, 2):

+                     self.assertIn(

+                         'input class="form-control" id="seats_elected" '

+                         'name="seats_elected" required type="text" '

+                         'value="2">', output.data)

+                 else:

+                     self.assertIn(

+                         'input class="form-control" id="seats_elected" '

+                         'name="seats_elected" type="text" '

+                         'value="2">', output.data)

+                 # We edited the admin groups

                  self.assertIn(

-                     'input class="form-control" id="seats_elected" '

-                     'name="seats_elected" required type="text" '

-                     'value="2">', output.data)

-             else:

-                 self.assertIn(

-                     'input class="form-control" id="seats_elected" '

-                     'name="seats_elected" type="text" '

-                     'value="2">', output.data)

-             # We edited the admin groups

-             self.assertIn(

-                 'input class="form-control" id="admin_grp" '

-                 'name="admin_grp" type="text" '

-                 'value="sysadmin-main, testers">', output.data)

- 

-             # Remove an existing group: testers

-             data = {

-                 'alias': 'test_election2',

-                 'shortdesc': 'test election 2 shortdesc',

-                 'description': 'test election 2 description',

-                 'voting_type': 'range',

-                 'url': 'https://fedoraproject.org',

-                 'start_date': TODAY - timedelta(days=7),

-                 'end_date': TODAY - timedelta(days=5),

-                 'seats_elected': '2',

-                 'candidates_are_fasusers': False,

-                 'embargoed': False,

-                 'admin_grp': 'sysadmin-main',

-                 'csrf_token': csrf_token,

-             }

- 

-             output = self.app.post(

-                 '/admin/test_election2/', data=data, follow_redirects=True)

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 'Election "test_election2" saved'

-                 in output.data)

-             if self.get_wtforms_version() >= (2, 2):

-                 self.assertIn(

-                     'input class="form-control" id="seats_elected" '

-                     'name="seats_elected" required type="text" '

-                     'value="2">', output.data)

-             else:

-                 self.assertIn(

-                     'input class="form-control" id="seats_elected" '

-                     'name="seats_elected" type="text" '

-                     'value="2">', output.data)

-             # We edited the admin groups

-             self.assertIn(

-                 'input class="form-control" id="admin_grp" '

-                 'name="admin_grp" type="text" '

-                 'value="sysadmin-main">', output.data)

+                     'input class="form-control" id="admin_grp" '

+                     'name="admin_grp" type="text" '

+                     'value="sysadmin-main">', output.data)

  

      def test_admin_edit_election_legal_voters(self):

          """ Test the admin_edit_election function when editing legal voters.
@@ -588,256 +630,275 @@ 

          user = FakeUser(

              fedora_elections.APP.config['FEDORA_ELECTIONS_ADMIN_GROUP'],

              username='toshio')

-         with user_set(fedora_elections.APP, user):

-             output = self.app.get('/admin/test_election/edit')