Beispiel #1
0
def vote(request, template_name='vote.html'):
    eb = ElectionBusiness()
    context = {}
    signer = Signer()
    if eb.isOccurring():
        # Check if elector already voted.
        if Voted.objects.filter(elector__user=request.user).count() > 0:
            messages.warning(request, 'You have already voted.')   
            return render(request, template_name, context)

        positions = Position.objects.all()
        if request.method == 'POST':
            try:
                for p in positions:
                    pname = 'position{}'.format(p.id)
                    candidate_id = request.POST.get(pname,"")
                    candidate = Candidate.objects.get(id=int(candidate_id))
                    cv, created = CandidateVote.objects.get_or_create(candidate=candidate)
                    cv.quantity = cv.quantity + 1
                    cv.save()
                elector = Elector.objects.get(user=request.user)
                voted = Voted.objects.create(elector=elector)
                voted.system_signature = signer.sign(str(elector.id))
                voted.save()
                messages.success(request, 'Your vote was registred successfully')
            except Exception as e:
                messages.error(request, str(e))
        else:
            context['positions'] = positions
            context['quantity_of_positions'] = positions.count()
    else:
        messages.error(request, 'Election has finished.')
    
    return render(request, template_name, context)
Beispiel #2
0
 def isLastBlock(self):
     eb =  ElectionBusiness()
     if self.shouldAddBlock():
         ec = eb.getCurrentElectionConfig()
         if (Voted.objects.count()-ec.min_votes_in_last_block)/Elector.objects.count() > ec.attendance_rate:
             return True
     if eb.isLocked() and eb.hadFinished():
         return True
     return False
Beispiel #3
0
    def shouldAddLastBlock(self):
        if self.isLastBlock():
            if Voted.objects.count() == Elector.objects.count():
                return True
        eb = ElectionBusiness()
        if eb.isLocked() and eb.hadFinished():
            return True

        return False
Beispiel #4
0
    def __call__(self, request):
        # Code to be executed for each request before
        # the view (and later middleware) are called.

        eb = ElectionBusiness()
        election_is_occurring = eb.isOccurring()
        election_is_locked = eb.isLocked()
        request.election_is_occurring = election_is_occurring
        request.election_is_locked = election_is_locked

        response = self.get_response(request)

        response.election_is_occurring = election_is_occurring
        response.election_is_locked = election_is_locked
        # Code to be executed for each request/response after
        # the view is called.

        return response
Beispiel #5
0
 def checkMinVotes(self, bblock):
     ec = ElectionBusiness().getCurrentElectionConfig()
     if self.shouldAddBlock():
         electors = json.loads(bblock.electors)
         if self.isLastBlock():
             if self.shouldAddLastBlock():
                 return True
         if (len(electors) * Position.objects.count()) >= ec.min_votes_in_block:
             return True
     return False
Beispiel #6
0
    def checkGuessRate(self, bblock):
        ec = ElectionBusiness().getCurrentElectionConfig()
        last_public_block = BBlock.objects.filter(reason='').order_by('-timestamp_iso')[0]
        max_difference = 0
        i = 0
        cv = json.loads(bblock.candidate_votes)
        pcv = json.loads(last_public_block.candidate_votes)
        while i < len(cv):
            if cv[i]['quantity'] - pcv[i]['quantity'] > max_difference:
                max_difference = cv[i]['quantity'] - pcv[i]['quantity']
            i = i + 1
        
        guess_rate = max_difference / ((bblock.total_votes - last_public_block.total_votes) / Position.objects.count())
        if Decimal(str(guess_rate)) <= ec.guess_rate:
            return True

        return False
Beispiel #7
0
 def shouldAddBlock(self):
     eb = ElectionBusiness()
     # While election is occurring, new blocks should be generated.
     if eb.isOccurring():
         return True
     if eb.isLocked() and eb.hadFinished():
         return True
     ec = eb.getCurrentElectionConfig()
     if not ec:
         raise DatabaseError('There is not Election Configuration for the current election')
     # Independently of election is occurring, if we have votes, a new block must be generated.
     if Voted.objects.filter(hash_val__isnull=True).count() > 0:
         return True
     # If election is not occurring and we do not have votes we do not need to generate a block.
     return False
Beispiel #8
0
    def add(self):
        if not self.shouldAddBlock():
            return

        finish_election = False
        if self.shouldAddLastBlock():
            finish_election = True

        if BBlock.objects.all().count() == 0:
            raise DatabaseError('It is not possible to add a block without genesis block')
            
        previous_block = BBlock.objects.all().order_by('-timestamp_iso')[0]

        # Put these outside the transaction
        hc = HashCalculator()
        database_hash = hc.databaseHash()
        source_code_hash = hc.sourceCodeHash()

        # Get the last block which has electors divulged.
        last_public_block = BBlock.objects.filter(reason='').order_by('-timestamp_iso')[0]

        with transaction.atomic():
            #bblock = BBlock.objects.create()
            bblock = BBlock()
            bblock.database_hash = database_hash
            bblock.hash_of_database_hash = bblock.calculateHashOfDatabaseHash()
            bblock.source_code_hash = source_code_hash
            bblock.hash_of_source_code_hash = bblock.calculateHashOfSourceCodeHash()
            
            bblock.timestamp_iso = datetime.datetime.now().isoformat()
            same_qtt_votes = False
            cv_quantity = 0

            while not same_qtt_votes:
                # Workaround to lock electors who will be locked.
                #Voted.objects.filter(hash_val__isnull=True).update(hash_val='x')
                #electors = list(Voted.objects.filter(hash_val='x').values('id', 'elector_id', 'system_signature').order_by('id'))
                electors = list(Voted.objects.filter(hash_val__isnull=True).values('id', 'elector_id', 'system_signature').order_by('id'))
                candidate_votes = list(CandidateVote.objects.all().values('id', 'candidate_id', 'quantity').order_by('id'))
                cv_quantity = self.__count_votes(candidate_votes)
                if (cv_quantity - last_public_block.total_votes) == (len(electors) * Position.objects.count()):
                    same_qtt_votes = True
            
            elector_id_list = []
            for e in electors:
                elector_id_list.append(e['id'])

            bblock.candidate_votes = json.dumps(candidate_votes, cls=DjangoJSONEncoder)
            bblock.electors = json.dumps(electors, cls=DjangoJSONEncoder)
            bblock.parent_hash = previous_block.block_hash
            bblock.total_votes = cv_quantity

            ret = self.shouldIncludeElectors(bblock)
            if not ret[0]:
                bblock.electors = json.dumps([], cls=DjangoJSONEncoder)
                bblock.reason = ret[1]
                bblock.block_hash = bblock.calculateHash()
            else:
                bblock.reason = ''
                bblock.block_hash = bblock.calculateHash()
                Voted.objects.filter(id__in=elector_id_list).update(hash_val=bblock.block_hash)

            bblock.save()

            if finish_election:
                ec = ElectionBusiness().getCurrentElectionConfig()
                ec.locked = False
                ec.save()
Beispiel #9
0
def start_election(request, template_name='election/start_election.html'):

    has_error = False

    # If election is locked, the tests will not be executed.
    if request.election_is_locked:
        msg = 'Election has already started'
        messages.warning(request, msg)
        return render(request, template_name)

    if ElectionConfig.objects.all().count() != 1:
        has_error = True
        msg = 'Election Configuration is not configured properly.'
        messages.error(request, msg)

    ec = ElectionBusiness().getCurrentElectionConfig()
    if ec:
        if ec.start_time >= ec.end_time:
            has_error = True
            msg = 'Election Configuration start time is greater than end time.'
            messages.error(request, msg)

        if ec.end_time < datetime.now():
            has_error = True
            msg = 'End time of Election Configuration is a past date'
            messages.error(request, msg)

    if Position.objects.all().count() == 0:
        has_error = True
        msg = 'There are not poisitions configurated for the election'
        messages.error(request, msg)

    for position in Position.objects.all():
        if position.candidate_set.count() == 0:
            has_error = True
            msg = 'Position "{}" does not have candidates'.format(
                position.description)
            messages.error(request, msg)

    #Check positions without candidates
    #Check electors
    if Elector.objects.all().count() == 0:
        messages.error(request,
                       'There are not electors configurated for the election')
        has_error = True

    # Delete votes, results, blocks, etc...
    if not has_error:
        Voted.objects.all().delete()
        CandidateVote.objects.all().delete()
        for candidate in Candidate.objects.all():
            cv = CandidateVote.objects.create(candidate=candidate, quantity=0)
            cv.save()
        BBlock.objects.all().delete()

        ec = ElectionConfig.objects.all()[0]
        ec.locked = True
        ec.save()

        # Add genesis block
        BBlockHandler().add_genesis()

    return redirect('home')