Skip to content

Commit

Permalink
Merge pull request #123 from edemocracy/improve-vvvote
Browse files Browse the repository at this point in the history
Improve vvvote integration and fix login exception
  • Loading branch information
dpausp authored Oct 24, 2023
2 parents 20fbc4a + 5790dbc commit f684889
Show file tree
Hide file tree
Showing 8 changed files with 61 additions and 22 deletions.
15 changes: 12 additions & 3 deletions src/ekklesia_portal/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,18 @@ def verify_identity(identity):

@App.after_oauth_callback()
def create_or_update_user(request, ekklesia_auth: EkklesiaAuth) -> None:
userinfo = ekklesia_auth.data
_ = request.i18n.gettext

try:
userinfo = ekklesia_auth.data
except TypeError:
request.flash(
_(
"alert_ekklesia_auth_failed_parsing"
), "danger"
)
return

sub = userinfo.sub
token = ekklesia_auth.token

Expand All @@ -119,8 +130,6 @@ def create_or_update_user(request, ekklesia_auth: EkklesiaAuth) -> None:

required_role_for_login = auth_settings.required_role_for_login

_ = request.i18n.gettext

if required_role_for_login is not None and required_role_for_login not in userinfo.roles:
request.flash(
_(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
ul.votings
for title, url in votings
li
a.btn.btn-primary.btn-sm(href=url)
a.btn.btn-primary.btn-sm(href=url,target='_blank')
i.fas.fa-sign-in-alt  
= _('register_now_with_voting_module', title=title)

Expand All @@ -65,7 +65,7 @@
ul.votings
for title, url in votings
li
a.btn.btn-primary.btn-sm(href=url)
a.btn.btn-primary.btn-sm(href=url,target='_blank')
i.fas.fa-person-booth  
= _('vote_now_with_voting_module', title=title)

Expand All @@ -74,7 +74,7 @@
ul.votings
for title, url in voting_results
li
a.btn.btn-secondary.btn-sm(href=url)
a.btn.btn-secondary.btn-sm(href=url,target='_blank')
i.fas.fa-poll-h  
= _('show_results_with_voting_module', title=title)

Expand Down
10 changes: 5 additions & 5 deletions src/ekklesia_portal/concepts/voting_phase/voting_phase_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,12 +192,12 @@ def retrieve_voting(self, request):

with start_action(action_type="apply_election_results") as action:
result_objs = []
for ii, ballot in enumerate(self.ballots, start=1):
result = results.get(str(ii))
if result:
for ballot in self.ballots:
if str(ballot.id) in results:
result = results.get(str(ballot.id))
result_obj = {}
for option_id, proposition in enumerate(ballot.propositions, start=1):
if option_id in result:
for proposition in ballot.propositions:
if int(proposition.id) & ((2 ** 22) - 1) in result:
res = OpenSlidesVotingResult.ACCEPTED
else:
res = OpenSlidesVotingResult.REJECTED
Expand Down
33 changes: 25 additions & 8 deletions src/ekklesia_portal/lib/vvvote/election_config.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,31 @@
from datetime import datetime

import random
from uuid import uuid4

import ekklesia_portal.lib.vvvote.schema as vvvote_schema


def ballot_to_vvvote_question(ballot, question_id=1):
def ballot_to_vvvote_question(ballot):
options = []
voting_scheme_yes_no = vvvote_schema.YesNoScheme(
name='yesNo', abstention=True, abstentionAsNo=False, quorum=2, mode=vvvote_schema.SchemeMode.QUORUM
name=vvvote_schema.SchemeName.YES_NO, abstention=True, abstentionAsNo=False, quorum=2, mode=vvvote_schema.SchemeMode.QUORUM
)

voting_scheme_score = vvvote_schema.ScoreScheme(name='score', minScore=0, maxScore=3)
proposition_count = len(ballot.propositions)
voting_scheme_score = vvvote_schema.ScoreScheme(
name=vvvote_schema.SchemeName.SCORE, minScore=0, maxScore=3 if proposition_count <= 5 else 9)

voting_scheme = [voting_scheme_yes_no, voting_scheme_score]

for option_id, proposition in enumerate(ballot.propositions, start=1):
# Random order of propositions in ballot
propositions = list(ballot.propositions)
random.shuffle(propositions)

for proposition in propositions:
proponents = [s.member.name for s in proposition.propositions_member if s.submitter]
option = vvvote_schema.Option(
optionID=option_id,
optionID=int(proposition.id) & ((2 ** 22) - 1), # Only use the random bits (64bit not supported in JSON)
proponents=proponents,
optionTitle=proposition.title,
optionDesc=proposition.content,
Expand All @@ -31,17 +40,25 @@ def ballot_to_vvvote_question(ballot, question_id=1):

question = vvvote_schema.Question(
questionWording=question_wording,
questionID=question_id,
questionID=ballot.id,
scheme=voting_scheme,
options=options,
findWinner=['yesNo', 'score', 'random']
findWinner=[vvvote_schema.SchemeName.YES_NO, vvvote_schema.SchemeName.SCORE, vvvote_schema.SchemeName.RANDOM]
)

return question


def get_ballot_sort_key(ballot):
props = list(ballot.propositions)
props.sort(key=lambda prop: prop.qualified_at or datetime.now())
return props[0].qualified_at or datetime.now()


def voting_phase_to_vvvote_election_config(module_config, phase) -> vvvote_schema.ElectionConfig:
questions = [ballot_to_vvvote_question(b, ii) for ii, b in enumerate(phase.ballots, start=1)]
ballots = list(phase.ballots)
ballots.sort(key=get_ballot_sort_key)
questions = [ballot_to_vvvote_question(ballot) for ballot in ballots]

if phase.registration_start is None:
raise ValueError("Cannot create voting for phase {phase}, registration_start is None")
Expand Down
7 changes: 7 additions & 0 deletions src/ekklesia_portal/translations/de/LC_MESSAGES/messages.po
Original file line number Diff line number Diff line change
Expand Up @@ -1480,6 +1480,13 @@ msgstr ""
"zu einer Stunde dauern, bis dein Account überprüft wurde und du das "
"Antragsportal nutzen kannst."

#: src/ekklesia_portal/app.py:116
msgid "alert_ekklesia_auth_failed_parsing"
msgstr ""
"Der Login ist fehlgeschlagen, da die notwendigen Daten nicht in der Antwort "
"des Single-Sign-On Provider enthalten waren. "
"Das Problem kann nur ein Administrator lösen."

#: src/ekklesia_portal/helper/missing_translations.py:4
msgid "alert_logged_in_to"
msgstr "Du hast dich erfolgreich per %(name)s angemeldet."
Expand Down
7 changes: 7 additions & 0 deletions src/ekklesia_portal/translations/en/LC_MESSAGES/messages.po
Original file line number Diff line number Diff line change
Expand Up @@ -1461,6 +1461,13 @@ msgstr ""
"You cannot use this application via %(name)s because you don't have the "
"role '%(role)s'"

#: src/ekklesia_portal/app.py:116
msgid "alert_ekklesia_auth_failed_parsing"
msgstr ""
"Login failed, as the required information was not included in the"
"response of the Single-Sign-On provider. "
"This problem can only be solved by an administrator."

#: src/ekklesia_portal/helper/missing_translations.py:4
msgid "alert_logged_in_to"
msgstr "Logged in successfully via %(name)s."
Expand Down
3 changes: 1 addition & 2 deletions tests/create_test_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
from typer import Option, confirm, Exit

import ekklesia_common.logging
from ekklesia_common.ekklesia_auth import OAuthToken

DOCUMENT_WP = '''# Wahlprogramm
Expand Down Expand Up @@ -115,7 +114,7 @@ def main(
# local import because we have to set up the database stuff before that
from ekklesia_portal.datamodel import (
Argument, ArgumentRelation, ArgumentVote, Ballot, CustomizableText, Department, DepartmentMember, Document,
Group, Policy, Proposition, PropositionType, SubjectArea, Supporter, Tag, User, UserPassword, UserProfile,
Group, OAuthToken, Policy, Proposition, PropositionType, SubjectArea, Supporter, Tag, User, UserPassword, UserProfile,
VotingPhase, VotingPhaseType
)

Expand Down
2 changes: 1 addition & 1 deletion tests/lib/vvvote/test_election_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
def test_ballot_to_vvvote_question(db_session, ballot, proposition_factory):
proposition = proposition_factory(ballot=ballot)
question = ballot_to_vvvote_question(ballot)
assert question.questionID == 1
assert question.questionID == ballot.id
assert question.options[0].optionTitle == proposition.title
assert question.options[0].optionDesc == proposition.content
assert question.options[0].reasons == proposition.motivation
Expand Down

0 comments on commit f684889

Please sign in to comment.