Browse Source

Work in progress

JoostSijm 6 years ago
parent
commit
95c7d1644f

+ 25 - 1
app/models.py

@@ -3,8 +3,11 @@
 All models for module
 """
 
+from hashlib import blake2b
+import hmac
+
 from urllib.parse import quote
-from datetime import datetime
+from datetime import datetime, timedelta
 # from sqlalchemy.ext.hybrid import hybrid_method, hybrid_property
 import markdown
 from flask import Markup
@@ -167,6 +170,14 @@ class Ballot(db.Model):
         backref=db.backref("ballots", lazy="dynamic")
     )
 
+    def active(self):
+        """Check if vote is active"""
+        today = datetime.today()
+        if self.start_at <= today <= self.end_at:
+            return True
+        #return False
+        return True
+
 
 class Priority(db.Model):
     """Model for Priority"""
@@ -239,3 +250,16 @@ class Vote(db.Model):
         "User",
         backref=db.backref("votes", lazy="dynamic")
     )
+
+class Code(db.Model):
+    """Model for code"""
+    id = db.Column(db.Integer, primary_key=True)
+    expire_date = db.Column(db.DateTime, default=datetime.utcnow() + timedelta(days=20))
+    secret = db.Column(db.String(255), unique=True)
+
+    def get_digest(self, string):
+        """Generate digest on string"""
+        secret = self.secret.encode('utf-8')
+        blake = blake2b(digest_size=3)
+        blake.update(secret + string)
+        return blake.hexdigest()

+ 35 - 2
app/modules/vote/app.py

@@ -3,13 +3,14 @@
 Authentication module
 """
 
-import os
+import hashlib
+import hmac
 
 from datetime import datetime
 from flask_login import login_required, current_user
 from flask_menu import Menu, register_menu
 from flask import render_template, request, flash, Blueprint, redirect, url_for
-from app.models import User, Page, Ballot, Priority, Question, Option
+from app.models import User, Page, Ballot, Priority, Question, Option, Vote, Code
 from app import db
 
 
@@ -118,6 +119,38 @@ def add_question(ballot_id):
 def public(ballot_id):
     """Vote and view results of ballot"""
     ballot = Ballot.query.get(ballot_id)
+
+#   code = Code()
+#   code.secret = "test"
+
+#   db.session.add(code)
+#   db.session.commit()
+    if request.method == 'POST':
+        security_code = request.form['security_code']
+        code = Code.query.order_by(Code.expire_date.desc()).first()
+        print(code.get_digest(code))
+        user_id = None
+        for user in User.all():
+            if security_code == code.get_digest(str(user.id)):
+                user_id = user.id
+
+        if user_id is not None:
+            for question_id, option_id in request.form.items():
+                if question_id == 'code':
+                    continue
+                question = Question.query.get(question_id)
+                option = question.options.filter(Option.id == option_id).first()
+
+                vote = Vote()
+                vote.option_id = option.id
+                vote.user_id = user_id
+                db.session.add(vote)
+
+            db.session.commit()
+            flash('Succesvol gestemd', 'success')
+        else:
+            flash('Fout in veiligheids code', 'warning')
+
     return render_template(
         'vote/public.j2',
         ballot=ballot,

+ 30 - 2
app/modules/vote/templates/vote/public.j2

@@ -39,8 +39,36 @@
                 <td>{{ ballot.priority.name }}</td>
             </tr>
         </table>
+        {% if ballot.active() %}
+        <form method="post">
+            <div class="form-group">
+                <label class="text-normal text-dark">Veiligheids code</label>
+                <input type="text" class="form-control" name="security_code" placeholder="code" required>
+            </div>
+            {% for question in ballot.questions %}
+            <div class="card mb-4">
+                <div class="card-body">
+                    <h5 class="card-title">{{ question.name }}</h5>
+                    {% if question.description %}
+                    <p class="card-text">{{ question.description }}</p>
+                    {% endif %}
+                    {% for option in question.options %}
+                    <div class="form-check">
+                        <input class="form-check-input" type="radio" name="{{ question.id }}" id="{{ "option_%s" % option.id }}" value="{{ option.id }}">
+                        <label class="form-check-label" for="{{ "option_%s" % option.id }}">
+                            {{ option.name }}
+                        </label>
+                    </div>
+                    {% endfor %}
+                </div>
+            </div>
+            {% endfor %}
+            <div class="form-group pull-right">
+                <button class="btn btn-primary" type="submit">Opslaan</button>
+            </div>
+        </form>
+        {% else %}
         {% for question in ballot.questions %}
-       	{% if question.options.all() | count %}
         <div class="card mb-4">
             <div class="card-body">
                 <h5 class="card-title">{{ question.name }}</h5>
@@ -57,7 +85,7 @@
                 {% endfor %}
             </ul>
         </div>
-        {% endif %}
         {% endfor %}
+        {% endif %}
     </div>
 </body>

+ 32 - 0
migrations/versions/c1d7ddb101a1_add_code.py

@@ -0,0 +1,32 @@
+"""add_code
+
+Revision ID: c1d7ddb101a1
+Revises: 3d9ba6086a23
+Create Date: 2019-04-01 17:23:32.312946
+
+"""
+from alembic import op
+import sqlalchemy as sa
+
+
+# revision identifiers, used by Alembic.
+revision = 'c1d7ddb101a1'
+down_revision = '3d9ba6086a23'
+branch_labels = None
+depends_on = None
+
+
+def upgrade():
+    op.create_table('code',
+    sa.Column('id', sa.Integer(), nullable=False),
+    sa.Column('expire_date', sa.DateTime(), nullable=True),
+    sa.Column('secret', sa.String(length=255), nullable=True),
+    sa.PrimaryKeyConstraint('id', name=op.f('pk_code')),
+    sa.UniqueConstraint('secret', name=op.f('uq_code_secret'))
+    )
+    op.drop_constraint('user_email_key', 'user', type_='unique')
+
+
+def downgrade():
+    op.create_unique_constraint('user_email_key', 'user', ['email'])
+    op.drop_table('code')