Exemplo n.º 1
0
    def validate(self, value):
        super(GPGKeyValidator, self).validate(value)

        if value:
            import_result = gpg.import_keys(value)
            if import_result.count == 0:
                raise Invalid(_(u"The GPG key is not valid"))
Exemplo n.º 2
0
    def validate(self, value):
        super(GPGKeyValidator, self).validate(value)

        if value:
            import_result = gpg.import_keys(value)
            if import_result.count == 0:
                raise Invalid(_(u"The GPG key is not valid"))
Exemplo n.º 3
0
    def get_voting_count(self):
        #XXX: "digit_count" should be some customizable field from the election
        #     and not defined here. (neither should be in generate_random_numbers_for_candidates )
        digit_count = 10
        results = []
        votes_zip = getattr(self.context, 'votes_count_zip', None)

        if votes_zip:
            aux_results = {}
            annotation = IAnnotations(self.context)
            nominees = annotation['nominees']

            ob = StringIO()
            ob.write(votes_zip.data)
            zip_file = ZipFile(ob, "r", ZIP_DEFLATED)
            for name in zip_file.namelist():
                vote = zip_file.read(name)[:digit_count]
                nominee = nominees.get(long(vote))
                if not nominee:
                    raise Invalid(_(u"There doesn't seem to be a valid nominee for vote: %s. Data might be corrupt: %s." % (vote, nominees)))
                nominee_count = aux_results.get(nominee, 0)
                nominee_count += 1
                aux_results[nominee] = nominee_count

            vocab = getUtility(IVocabularyFactory,
                               name="plone.principalsource.Users")
            values = vocab(self.context)

            for nominee in self.context.nominations_roll:
                full_name = values.getTermByToken(nominee).title
                results.append({'name': full_name,
                                'votes': aux_results.get(nominee, 0)})

        return results
Exemplo n.º 4
0
    def validate(self, value):
        super(GPGSignatureValidator, self).validate(value)

        data = ''
        ending = "_signature"
        _len = len(ending)

        signature = self.field.getName()
        signed_file = signature[:-_len]

        file = self.request.form.get('form.widgets.%s' % signed_file)
        if file:
            file.seek(0)
            data = file.read()
            file.seek(0)
        else:
            pdf_field = getattr(self.context, signed_file, None)
            if pdf_field:
                data = pdf_field.data

        # It would be nice to be able to do this from a stream,
        # but unfortunately, gnupg expects files
        fd, fn = tempfile.mkstemp(prefix='elections')
        os.write(fd, data)
        os.close(fd)

        sig = _make_binary_stream(value.data, gpg.encoding)

        verify = gpg.verify_file(sig, fn)

        if not verify.valid:
            if hasattr(verify, 'status'):
                # Error codes gnupg.py line 150
                if verify.status == 'signature bad':
                    raise Invalid(
                        _(u"This signature is not valid for the uploaded file."
                          ))
                else:
                    raise Invalid(_(u"Error: %s." % verify.status))

            else:
                raise Invalid(_(u"Invalid signature."))
Exemplo n.º 5
0
    def validate(self, value):
        super(GPGSignatureValidator, self).validate(value)

        data = ''
        ending = "_signature"
        _len = len(ending)

        signature = self.field.getName()
        signed_file = signature[:-_len]

        file = self.request.form.get('form.widgets.%s' % signed_file)
        if file:
            file.seek(0)
            data = file.read()
            file.seek(0)
        else:
            pdf_field = getattr(self.context, signed_file, None)
            if pdf_field:
                data = pdf_field.data

        # It would be nice to be able to do this from a stream,
        # but unfortunately, gnupg expects files
        fd, fn = tempfile.mkstemp(prefix='elections')
        os.write(fd, data)
        os.close(fd)

        sig = _make_binary_stream(value.data, gpg.encoding)

        verify = gpg.verify_file(sig, fn)

        if not verify.valid:
            if hasattr(verify, 'status'):
                # Error codes gnupg.py line 150
                if verify.status == 'signature bad':
                    raise Invalid(_(u"This signature is not valid for the uploaded file."))
                else:
                    raise Invalid(_(u"Error: %s." % verify.status))

            else:
                raise Invalid(_(u"Invalid signature."))
Exemplo n.º 6
0
    def status_change_msg(self):
        wf_tool = getToolByName(self.context, "portal_workflow")
        chain = wf_tool.getChainForPortalType(self.context.portal_type)
        status = wf_tool.getStatusOf(chain[0], self.context)

        state = status['review_state']

        wf_tr_map = {'internal_revision': 'can-submit-to-public',
                     'public_revision': 'can-select-nominees',
                     'nominee_revision': 'can-send-to-public',
                     'public': 'can-be-started',
                     'voting': 'should-be-ended',
                     'scrutiny': 'results-should-be-public',
                     'published': 'can-be-closed',
                     }

        if state in wf_tr_map:
            trans_guard = getMultiAdapter((self.context, self.request),
                                          name=wf_tr_map[state])
            can_call_trans = trans_guard()

            if not can_call_trans:
                if state == 'internal_revision':
                    return _(u"Cannot send to public. You are not the CEO or you need to upload the signed configuration PDF and signature")
                if state == 'public_revision':
                    return _(u"Cannot select nominees. The date has not been reached")
                if state == 'nominee_revision':
                    return _(u"Cannot send to public. You are not the CEO or you need to upload the signed nomination and electoral PDF and signature")
                if state == 'public':
                    return _(u"Cannot start voting. The date has not been reached")
                if state == 'voting':
                    return _(u"Cannot start counting votes. The date has not been reached")
                if state == 'scrutiny':
                    return _(u"Cannot publish results. The date has not been reached")
                if state == 'published':
                    return _(u"Cannot close the election. You are not the CEO")

        return _(u"")
Exemplo n.º 7
0
    def cast_vote(self):
        #XXX: "digit_count" should be some customizable field from the election
        #     and not defined here. (neither should be in generate_random_numbers_for_candidates )
        digit_count = 10
        pm = getToolByName(self.context, 'portal_membership')
        nominee = self.request.get("chosen_nominee")
        voter = pm.getAuthenticatedMember().getId()

        # Now, let's get the random number that belongs for this voter and
        # nominee
        annotation = IAnnotations(self.context)

        # This should never ever happen, but just in case...
        if voter not in annotation['electoral']:
            raise Invalid(_(u"You are not allowed to vote. Please contact the system administrator."))

        if nominee not in annotation['electoral'][voter]:
            raise Invalid(_(u"The nominee you selected does not exist. Please contact the system administrator."))

        # We get the random number assigned for this nominee to this voter
        random_number = annotation['electoral'][voter][nominee]

        # We create the new random number with the same length.
        new_random = long(random() * (10 ** digit_count))

        # Make sure that the random number has digit_count digits:
        while len(str(new_random)) != digit_count:
            new_random = long(random() * (10 ** digit_count))

        # Append it
        result = str(random_number) + str(new_random)

        receipts = annotation.get('receipts', {})

        # Generate our MD5 receipt
        receipt = hashlib.md5(result).hexdigest()
        now = datetime.now()

        receipts[voter] = {'receipt': receipt,
                           'date': now}

        # And save it
        annotation['receipts'] = receipts

        # Now, we get our keys fingerprints. We have to do it this way because python's gnupg
        # uses the system gnupg, so it may happen that at some point the key is lost from
        # the system keyring.
        try:
            admin_fingerprint = gpg.import_keys(self.context.gpg_key_admin).results[0]['fingerprint']
        except:
            raise Invalid(_(u"Something wrong happened with the admin GPG key."))

        try:
            comission_fingerprint = gpg.import_keys(self.context.gpg_key_comission).results[0]['fingerprint']
        except:
            raise Invalid(_(u"Something wrong happened with the comission GPG key."))

        # Now we double cipher it. First with the comission key
        first = gpg.encrypt(result, comission_fingerprint)
        # Then with the admin's one.
        second = gpg.encrypt(first.data, admin_fingerprint)

        # Finally, store the vote in the annotation
        not_used_votes = annotation.get('not_used_votes', [])
        votes = annotation.get('votes', [])
        if random_number not in not_used_votes:
            votes.append(second.data)
            # And we shuffle it to improve anonymity
            shuffle(votes)
            annotation['votes'] = votes
        else:
            # XXX: This number shouldn't be usable, something wrong happened
            #      need to figure out how to proceed in this case
            raise Invalid(_(u"A nominee code was tried to be reused."))
            return

        # And now, we store the other possible random_numbers from this voter
        # So they cannot be used
        not_used_votes += [value for key, value in annotation['electoral'][voter].items()
                           if key != 'already_voted' and value != random_number]

        annotation['not_used_votes'] = not_used_votes

        # Finally, we "mark" the voter as "already_voted"
        annotation['electoral'][voter]['already_voted'] = True

        #Done.
        return