Exemple #1
0
def dequeue():
    try:
        dequeue_task()
    except Exception as e:
        return make_response(dumps(dict(status=e.message)), 202)

    return make_response(dumps(dict(status="ok")), 202)
def return_election(task):
    input_data = task.get_data()['input_data']
    election_id = input_data['election_id']
    session_ids = input_data['session_ids']
    election = db.session.query(Election)\
        .filter(Election.id == election_id).first()

    session_data = []

    for session_id in session_ids:
        # read into a string the pubkey
        privdata_path = app.config.get('PRIVATE_DATA_PATH', '')
        pubkey_path = os.path.join(privdata_path, str(election_id), session_id, 'publicKey_json')
        pubkey_file = open(pubkey_path, 'r')
        pubkey = pubkey_file.read()
        pubkey_file.close()
        session_data.append(dict(
            session_id=session_id,
            pubkey=json.loads(pubkey)
        ))

        # publish the pubkey
        pubdata_path = app.config.get('PUBLIC_DATA_PATH', '')
        pub_session_path = os.path.join(pubdata_path, str(election_id), session_id)
        pubkey_path2 = os.path.join(pub_session_path, 'publicKey_json')
        if not os.path.exists(pub_session_path):
            mkdir_recursive(pub_session_path)
        shutil.copyfile(pubkey_path, pubkey_path2)

        # publish protInfo.xml too
        session_privpath = os.path.join(privdata_path, str(election_id), session_id)
        protinfo_privpath = os.path.join(session_privpath, 'protInfo.xml')
        protinfo_pubpath = os.path.join(pub_session_path, 'protInfo.xml')
        shutil.copyfile(protinfo_privpath, protinfo_pubpath)

    session = requests.sessions.Session()
    session.mount('http://', RejectAdapter())
    callback_url = election.callback_url
    ret_data = {
        "status": "finished",
        "reference": {
            "election_id": election_id,
            "action": "POST /election"
        },
        "session_data": session_data
    }
    print "callback_url, ", callback_url
    print dumps(ret_data)
    ssl_calist_path = app.config.get('SSL_CALIST_PATH', '')
    ssl_cert_path = app.config.get('SSL_CERT_PATH', '')
    ssl_key_path = app.config.get('SSL_KEY_PATH', '')
    print("\nFF callback_url2 " + callback_url)
    r = session.request('post', callback_url, data=dumps(ret_data), headers={'content-type': 'application/json'},
                        verify=ssl_calist_path, cert=(ssl_cert_path, ssl_key_path))
    print r.text
    end_task()
def return_election(task):
    input_data = task.get_data()['input_data']
    election_id = input_data['election_id']
    session_ids = input_data['session_ids']
    election = db.session.query(Election)\
        .filter(Election.id == election_id).first()

    session_data = []

    for session_id in session_ids:
        # read into a string the pubkey
        privdata_path = app.config.get('PRIVATE_DATA_PATH', '')
        pubkey_path = os.path.join(privdata_path, str(election_id), session_id,
                                   'publicKey_json')
        pubkey_file = open(pubkey_path, 'r')
        pubkey = pubkey_file.read()
        pubkey_file.close()
        session_data.append(
            dict(session_id=session_id, pubkey=json.loads(pubkey)))

        # publish the pubkey
        pubdata_path = app.config.get('PUBLIC_DATA_PATH', '')
        pub_session_path = os.path.join(pubdata_path, str(election_id),
                                        session_id)
        pubkey_path2 = os.path.join(pub_session_path, 'publicKey_json')
        if not os.path.exists(pub_session_path):
            mkdir_recursive(pub_session_path)
        shutil.copyfile(pubkey_path, pubkey_path2)

        # publish protInfo.xml too
        session_privpath = os.path.join(privdata_path, str(election_id),
                                        session_id)
        protinfo_privpath = os.path.join(session_privpath, 'protInfo.xml')
        protinfo_pubpath = os.path.join(pub_session_path, 'protInfo.xml')
        shutil.copyfile(protinfo_privpath, protinfo_pubpath)

    session = requests.sessions.Session()
    callback_url = election.callback_url
    ret_data = {
        "status": "finished",
        "reference": {
            "election_id": election_id,
            "action": "POST /election"
        },
        "session_data": session_data
    }
    print "callback_url, ", callback_url
    print dumps(ret_data)
    r = session.request('post',
                        callback_url,
                        data=dumps(ret_data),
                        headers={'content-type': 'application/json'},
                        verify=False)
    print r.text
    end_task()
    def handle_error(self, error):
        '''
        When an error is propagated up to here, is time to return to the sender
        that this task failed
        '''
        session = requests.sessions.Session()
        input_data = self.task.get_data()['input_data']
        election_id = input_data['election_id']
        callback_url = input_data['callback_url']
        election = db.session.query(Election)\
            .filter(Election.id == election_id).first()

        session = requests.sessions.Session()
        fail_data = {
            "status": "error",
            "reference": {
                "election_id": election_id,
                "action": "POST /tally"
            },
            "data": {
                "message": "election tally failed for some reason"
            }
        }
        r = session.request('post', callback_url, data=dumps(fail_data), headers={'content-type': 'application/json'},
                            verify=False)
        print r.text
        end_task()
    def handle_error(self, error):
        '''
        When an error is propagated up to here, is time to return to the sender
        that this task failed
        '''
        session = requests.sessions.Session()
        input_data = self.task.get_data()['input_data']
        election_id = input_data['election_id']
        election = db.session.query(Election)\
            .filter(Election.session_id == election_id).first()

        session = requests.sessions.Session()
        callback_url = election.callback_url
        fail_data = {
            "status": "error",
            "reference": {
                "election_id": election_id,
                "action": "POST /election"
            },
            "data": {
                "message": "election creation failed for some reason"
            }
        }
        r = session.request('post',
                            callback_url,
                            data=dumps(fail_data),
                            verify=False)
        end_task()
def return_election(task):
    input_data = task.get_parent().get_data()['input_data']
    election_id = input_data['election_id']
    callback_url = input_data['callback_url']

    pub_data_url = app.config.get('PUBLIC_DATA_BASE_URL', '')
    tally_url = pub_data_url + '/' + str(election_id) + '/tally.tar.gz'

    pub_data_path = app.config.get('PUBLIC_DATA_PATH', '')
    tally_hash_path = os.path.join(pub_data_path, str(election_id),
                                   'tally.tar.gz.sha256')

    f = open(tally_hash_path, 'r')
    tally_hash = f.read()
    f.close()

    ret_data = {
        "status": "finished",
        "reference": {
            "election_id": election_id,
            "action": "POST /tally"
        },
        "data": {
            "tally_url": tally_url,
            "tally_hash": "ni:///sha-256;" + tally_hash
        }
    }
    session = requests.sessions.Session()
    r = session.request('post',
                        callback_url,
                        data=dumps(ret_data),
                        headers={'content-type': 'application/json'},
                        verify=False)
    print r.text
    end_task()
    def handle_error(self, error):
        '''
        When an error is propagated up to here, is time to return to the sender
        that this task failed
        '''
        session = requests.sessions.Session()
        session.mount('http://', RejectAdapter())
        input_data = self.task.get_data()['input_data']
        election_id = input_data['election_id']
        callback_url = input_data['callback_url']
        election = db.session.query(Election)\
            .filter(Election.id == election_id).first()

        session = requests.sessions.Session()
        fail_data = {
            "status": "error",
            "reference": {
                "election_id": election_id,
                "action": "POST /tally"
            },
            "data": {
                "message": "election tally failed for some reason"
            }
        }
        ssl_calist_path = app.config.get('SSL_CALIST_PATH', '')
        ssl_cert_path = app.config.get('SSL_CERT_PATH', '')
        ssl_key_path = app.config.get('SSL_KEY_PATH', '')
        print("\nFF callback_url4 " + callback_url)
        r = session.request('post', callback_url, data=dumps(fail_data), headers={'content-type': 'application/json'},
                            verify=ssl_calist_path, cert=(ssl_cert_path, ssl_key_path))
        print r.text
        end_task()
    def handle_error(self, error):
        '''
        When an error is propagated up to here, is time to return to the sender
        that this task failed
        '''
        session = requests.sessions.Session()
        input_data = self.task.get_data()['input_data']
        election_id = input_data['election_id']
        callback_url = input_data['callback_url']
        election = db.session.query(Election)\
            .filter(Election.id == election_id).first()

        session = requests.sessions.Session()
        fail_data = {
            "status": "error",
            "reference": {
                "election_id": election_id,
                "action": "POST /tally"
            },
            "data": {
                "message": "election tally failed for some reason"
            }
        }
        r = session.request('post',
                            callback_url,
                            data=dumps(fail_data),
                            headers={'content-type': 'application/json'},
                            verify=False)
        print r.text
        end_task()
Exemple #9
0
    def execute(self):
        username = self.task.get_data()['input_data']['username']
        print "our reservation: ", dumps(self.task.get_reservation_data())
        print "others reservation: ", dumps(self.task.get_data()['input_data'])

        print "woke up! time to finish =)\n"
        server_name = app.config.get('SERVER_NAME')

        # free the port
        self.cancel_reservation()

        self.task.set_output_data("goodbye %s from port %d in server %s!" % (
            username,
            self.task.get_reservation_data()['port'],
            app.config.get('SERVER_NAME')
        ))
Exemple #10
0
    def execute(self):
        username = self.task.get_data()['input_data']['username']
        print("our reservation: " + dumps(self.task.get_reservation_data()))
        print("others reservation: " +
              dumps(self.task.get_data()['input_data']))

        print("woke up! time to finish =)\n")
        server_name = app.config.get('SERVER_NAME')

        # free the port
        self.cancel_reservation()

        self.task.set_output_data(
            "goodbye %s from port %d in server %s!" %
            (username, self.task.get_reservation_data()['port'],
             app.config.get('SERVER_NAME')))
def return_election(task):
    input_data = task.get_parent().get_data()['input_data']
    election_id = input_data['election_id']
    callback_url = input_data['callback_url']

    pub_data_url = app.config.get('PUBLIC_DATA_BASE_URL', '')
    tally_url = pub_data_url + '/' + str(election_id) + '/tally.tar.gz'

    pub_data_path = app.config.get('PUBLIC_DATA_PATH', '')
    tally_hash_path = os.path.join(pub_data_path, str(election_id), 'tally.tar.gz.sha256')

    f = open(tally_hash_path, 'r')
    tally_hash = f.read()
    f.close()

    ret_data = {
        "status": "finished",
        "reference": {
            "election_id": election_id,
            "action": "POST /tally"
        },
        "data": {
            "tally_url": tally_url,
            "tally_hash": "ni:///sha-256;" + tally_hash
        }
    }
    session = requests.sessions.Session()
    r = session.request('post', callback_url, data=dumps(ret_data), headers={'content-type': 'application/json'},
                        verify=False)
    print r.text
    end_task()
def post_tally():
    '''
    POST /tally

    Tallies an election, with the given input data. This involves communicating
    with the different election authorities to do the tally.

    Example request:
    POST /tally
    {
        "election_id": 111,
        "callback_url": "https://127.0.0.1:5000/public_api/receive_tally",
        "votes_url": "https://127.0.0.1:5000/public_data/vota4/encrypted_ciphertexts",
        "votes_hash": "ni:///sha-256;f4OxZX_x_FO5LcGBSKHWXfwtSx-j1ncoSt3SABJtkGk"
    }

    On success, response is empty with status 202 Accepted and returns something
    like:

    {
        "task_id": "ba83ee09-aa83-1901-bb11-e645b52fc558",
    }

    When the election finally gets processed, the callback_url is called with POST
    similar to the following example:

    {
        "status": "finished",
        "reference": {
            "election_id": "d9e5ee09-03fa-4890-aa83-2fc558e645b5",
            "action": "POST /tally"
        },
        "data": {
            "votes_url": "https://127.0.0.1:5000/public_data/vota4/tally.tar.bz2",
            "votes_hash": "ni:///sha-256;f4OxZX_x_FO5LcGBSKHWXfwtSx-j1ncoSt3SABJtkGk"
        }
    }

    If there was an error, then the callback will be called following this
    example format:

    {
        "status": "error",
        "reference": {
            "election_id": "d9e5ee09-03fa-4890-aa83-2fc558e645b5",
            "action": "POST /tally"
        },
        "data": {
            "message": "error message"
        }
    }
    '''

    # first of all, parse input data
    data = request.get_json(force=True, silent=True)
    d = base64.b64encode(pickle.dumps(data))
    queueid = queue_task(task='tally', data=d)
    return make_response(dumps(dict(queue_id=queueid)), 202)
def post_tally():
    '''
    POST /tally

    Tallies an election, with the given input data. This involves communicating
    with the different election authorities to do the tally.

    Example request:
    POST /tally
    {
        "election_id": 111,
        "callback_url": "https://127.0.0.1:5000/public_api/receive_tally",
        "votes_url": "https://127.0.0.1:5000/public_data/vota4/encrypted_ciphertexts",
        "votes_hash": "ni:///sha-256;f4OxZX_x_FO5LcGBSKHWXfwtSx-j1ncoSt3SABJtkGk"
    }

    On success, response is empty with status 202 Accepted and returns something
    like:

    {
        "task_id": "ba83ee09-aa83-1901-bb11-e645b52fc558",
    }

    When the election finally gets processed, the callback_url is called with POST
    similar to the following example:

    {
        "status": "finished",
        "reference": {
            "election_id": "d9e5ee09-03fa-4890-aa83-2fc558e645b5",
            "action": "POST /tally"
        },
        "data": {
            "votes_url": "https://127.0.0.1:5000/public_data/vota4/tally.tar.bz2",
            "votes_hash": "ni:///sha-256;f4OxZX_x_FO5LcGBSKHWXfwtSx-j1ncoSt3SABJtkGk"
        }
    }

    If there was an error, then the callback will be called following this
    example format:

    {
        "status": "error",
        "reference": {
            "election_id": "d9e5ee09-03fa-4890-aa83-2fc558e645b5",
            "action": "POST /tally"
        },
        "data": {
            "message": "error message"
        }
    }
    '''

    # first of all, parse input data
    data = request.get_json(force=True, silent=True)
    d = base64.b64encode(pickle.dumps(data))
    queueid = queue_task(task='tally', data=d)
    return make_response(dumps(dict(queue_id=queueid)), 202)
def return_election(task):
    input_data = task.get_parent().get_data()['input_data']
    election_id = input_data['election_id']
    callback_url = input_data['callback_url']

    pub_data_url = app.config.get('PUBLIC_DATA_BASE_URL', '')
    tally_url = pub_data_url + '/' + str(election_id) + '/tally.tar.gz'

    pub_data_path = app.config.get('PUBLIC_DATA_PATH', '')
    tally_hash_path = os.path.join(pub_data_path, str(election_id),
                                   'tally.tar.gz.sha256')

    f = open(tally_hash_path, 'r')
    tally_hash = f.read()
    f.close()

    ret_data = {
        "status": "finished",
        "reference": {
            "election_id": election_id,
            "action": "POST /tally"
        },
        "data": {
            "tally_url": tally_url,
            "tally_hash": "ni:///sha-256;" + tally_hash
        }
    }
    session = requests.sessions.Session()
    session.mount('http://', RejectAdapter())
    ssl_calist_path = app.config.get('SSL_CALIST_PATH', '')
    ssl_cert_path = app.config.get('SSL_CERT_PATH', '')
    ssl_key_path = app.config.get('SSL_KEY_PATH', '')
    print("\nFF callback_url5 " + callback_url)
    r = session.request('post',
                        callback_url,
                        data=dumps(ret_data),
                        headers={'content-type': 'application/json'},
                        verify=ssl_calist_path,
                        cert=(ssl_cert_path, ssl_key_path))
    print(r.text)
    end_task()
    def handle_error(self, error):
        '''
        When an error is propagated up to here, is time to return to the sender
        that this task failed
        '''
        try:
            session = requests.sessions.Session()
            session.mount('http://', RejectAdapter())
            input_data = self.task.get_data()['input_data']
            election_id = input_data['election_id']
            callback_url = input_data['callback_url']
            election = db.session.query(Election)\
                .filter(Election.id == election_id).first()

            session = requests.sessions.Session()
            fail_data = {
                "status": "error",
                "reference": {
                    "election_id": election_id,
                    "action": "POST /tally"
                },
                "data": {
                    "message": "election tally failed for some reason"
                }
            }
            ssl_calist_path = app.config.get('SSL_CALIST_PATH', '')
            ssl_cert_path = app.config.get('SSL_CERT_PATH', '')
            ssl_key_path = app.config.get('SSL_KEY_PATH', '')
            print("\nFF callback_url4 " + callback_url)
            r = session.request('post',
                                callback_url,
                                data=dumps(fail_data),
                                headers={'content-type': 'application/json'},
                                verify=ssl_calist_path,
                                cert=(ssl_cert_path, ssl_key_path))
            print(r.text)
        finally:
            end_task()
def election_task(data):
    if not data:
        print("invalid json")
        return False

    try:
        check_election_data(data, True)
    except Exception as e:
        print("ERROR", e)
        return False

    e = Election(id=data['id'],
                 title=data['title'][:255],
                 description=data['description'],
                 questions=dumps(data['questions']),
                 start_date=data['start_date'],
                 end_date=data['end_date'],
                 callback_url=data['callback_url'],
                 num_parties=len(data['authorities']),
                 threshold_parties=len(data['authorities']),
                 status='creating')
    db.session.add(e)

    for auth_data in data['authorities']:
        authority = Authority(name=auth_data['name'],
                              ssl_cert=auth_data['ssl_cert'],
                              orchestra_url=auth_data['orchestra_url'],
                              election_id=data['id'])
        db.session.add(authority)
    db.session.commit()

    task = SimpleTask(receiver_url=app.config.get('ROOT_URL', ''),
                      action="create_election",
                      queue="launch_task",
                      data={'election_id': data['id']})
    task.create_and_send()
    return task
Exemple #17
0
def election_task(data):
    if not data:
        print("invalid json")
        return False

    try:
        check_election_data(data, True)
    except Exception, e:
        print("ERROR", e)
        return False

    e = Election(id=data['id'],
                 title=data['title'][:255],
                 description=data['description'],
                 questions=dumps(data['questions']),
                 start_date=data['start_date'],
                 end_date=data['end_date'],
                 callback_url=data['callback_url'],
                 num_parties=len(data['authorities']),
                 threshold_parties=len(data['authorities']),
                 status='creating')
    db.session.add(e)

    for auth_data in data['authorities']:
        authority = Authority(name=auth_data['name'],
                              ssl_cert=auth_data['ssl_cert'],
                              orchestra_url=auth_data['orchestra_url'],
                              election_id=data['id'])
        db.session.add(authority)
    db.session.commit()
def error(status, message=""):
    if message:
        data = json.dumps(dict(message=message))
    else:
        data = ""
    return make_response(data, status)


@public_api.route('/dequeue', methods=['GET'])
def dequeue():
    try:
        dequeue_task()
    except Exception, e:
        return make_response(dumps(dict(status=e.message)), 202)

    return make_response(dumps(dict(status="ok")), 202)


@public_api.route('/election', methods=['POST'])
def post_election():
    '''
    POST /election

    Creates an election, with the given input data. This involves communicating
    with the different election authorities to generate the joint public key.

    Example request:
    POST /election
    {
      "id": 1110,
      "title": "Votación de candidatos",
def post_election():
    '''
    POST /election

    Creates an election, with the given input data. This involves communicating
    with the different election authorities to generate the joint public key.

    Example request:
    POST /election
    {
      "id": 1110,
      "title": "Votación de candidatos",
      "description": "Selecciona los documentos polí­tico, ético y organizativo con los que Podemos",
      "director": "wadobo-auth1",
      "authorities": "openkratio-authority",
      "layout": "pcandidates-election",
      "presentation": {
        "share_text": "lo que sea",
        "theme": "foo",
        "urls": [
          {
            "title": "",
            "url": ""
          }
        ],
        "theme_css": "whatever"
      },
      "end_date": "2013-12-09T18:17:14.457000",
      "start_date": "2013-12-06T18:17:14.457000",
      "questions": [
          {
              "description": "",
              "layout": "pcandidates-election",
              "max": 1,
              "min": 0,
              "num_winners": 1,
              "title": "Secretarí­a General",
              "randomize_answer_order": true,
              "tally_type": "plurality-at-large",
              "answer_total_votes_percentage": "over-total-valid-votes",
              "answers": [
                {
                  "id": 0,
                  "category": "Equipo de Enfermeras",
                  "details": "",
                  "sort_order": 1,
                  "urls": [
                    {
                      "title": "",
                      "url": ""
                    }
                  ],
                  "text": "Fulanita de tal",
                }
              ]
          }
      ],
      "authorities": [
        {
          "name": "Asociación Sugus GNU/Linux",
          "orchestra_url": "https://sugus.eii.us.es/orchestra",
          "ssl_cert": "-----BEGIN CERTIFICATE-----\nMIIFATCCA+mgAwIBAgIQAOli4NZQEWpKZeYX25jjwDANBgkqhkiG9w0BAQUFADBz\n8YOltJ6QfO7jNHU9jh/AxeiRf6MibZn6fvBHvFCrVBvDD43M0gdhMkVEDVNkPaak\nC7AHA/waXZ2EwW57Chr2hlZWAkwkFvsWxNt9BgJAJJt4CIVhN/iau/SaXD0l0t1N\nT0ye54QPYl38Eumvc439Yd1CeVS/HYbP0ISIfpNkkFA5TiQdoA==\n-----END CERTIFICATE-----"
        },
        {
          "name": "Agora Ciudadana",
          "orchestra_url": "https://agoravoting.com:6874/orchestra",
          "ssl_cert": "-----BEGIN CERTIFICATE-----\nMIIFATCCA+mgAwIBAgIQAOli4NZQEWpKZeYX25jjwDANBgkqhkiG9w0BAQUFADBz\n8YOltJ6QfO7jNHU9jh/AxeiRf6MibZn6fvBHvFCrVBvDD43M0gdhMkVEDVNkPaak\nC7AHA/waXZ2EwW57Chr2hlZWAkwkFvsWxNt9BgJAJJt4CIVhN/iau/SaXD0l0t1N\nT0ye54QPYl38Eumvc439Yd1CeVS/HYbP0ISIfpNkkFA5TiQdoA==\n-----END CERTIFICATE-----"
        },
        {
          "name": "Wadobo Labs",
          "orchestra_url": "https://wadobo.com:6874/orchestra",
          "ssl_cert": "-----BEGIN CERTIFICATE-----\nMIIFATCCA+mgAwIBAgIQAOli4NZQEWpKZeYX25jjwDANBgkqhkiG9w0BAQUFADBz\n8YOltJ6QfO7jNHU9jh/AxeiRf6MibZn6fvBHvFCrVBvDD43M0gdhMkVEDVNkPaak\nC7AHA/waXZ2EwW57Chr2hlZWAkwkFvsWxNt9BgJAJJt4CIVhN/iau/SaXD0l0t1N\nT0ye54QPYl38Eumvc439Yd1CeVS/HYbP0ISIfpNkkFA5TiQdoA==\n-----END CERTIFICATE-----"
        }
      ]
    }


    On success, response is empty with status 202 Accepted and returns something
    like:

    {
        "task_id": "ba83ee09-aa83-1901-bb11-e645b52fc558",
    }
    When the election finally gets processed, the callback_url is called with a
    POST containing the protInfo.xml file generated jointly by each
    authority, following this example response:

    {
        "status": "finished",
        "reference": {
            "election_id": "d9e5ee09-03fa-4890-aa83-2fc558e645b5",
            "action": "POST /election"
        },
        "session_data": [{
            "session_id": "deadbeef-03fa-4890-aa83-2fc558e645b5",
            "publickey": ["<pubkey codified in hexadecimal>"]
        }]
    }

    Note that this protInfo.xml will contain the election public key, but
    also some other information. In particular, it's worth noting that
    the http and hint servers' urls for each authority could change later,
    if election-orchestra needs it.

    If there was an error, then the callback will be called following this
    example format:

    {
        "status": "error",
        "reference": {
            "session_id": "d9e5ee09-03fa-4890-aa83-2fc558e645b5",
            "action": "POST /election"
        },
        "data": {
            "message": "error message"
        }
    }
    '''

    data = request.get_json(force=True, silent=True)
    d = base64.b64encode(pickle.dumps(data))
    queueid = queue_task(task='election', data=d)

    return make_response(dumps(dict(queue_id=queueid)), 202)
def return_election(task):
    input_data = task.get_data()['input_data']
    election_id = input_data['election_id']
    session_ids = input_data['session_ids']
    election = db.session.query(Election)\
        .filter(Election.id == election_id).first()

    session_data = []

    for session_id in session_ids:
        # read into a string the pubkey
        privdata_path = app.config.get('PRIVATE_DATA_PATH', '')
        pubkey_path = os.path.join(privdata_path, str(election_id), session_id,
                                   'publicKey_json')
        pubkey_file = open(pubkey_path, 'r')
        pubkey = pubkey_file.read()
        pubkey_file.close()
        session_data.append(
            dict(session_id=session_id, pubkey=json.loads(pubkey)))

        # publish the pubkey
        pubdata_path = app.config.get('PUBLIC_DATA_PATH', '')
        pub_session_path = os.path.join(pubdata_path, str(election_id),
                                        session_id)
        pubkey_path2 = os.path.join(pub_session_path, 'publicKey_json')
        if not os.path.exists(pub_session_path):
            mkdir_recursive(pub_session_path)
        shutil.copyfile(pubkey_path, pubkey_path2)

        # publish protInfo.xml too
        session_privpath = os.path.join(privdata_path, str(election_id),
                                        session_id)
        protinfo_privpath = os.path.join(session_privpath, 'protInfo.xml')
        protinfo_pubpath = os.path.join(pub_session_path, 'protInfo.xml')
        shutil.copyfile(protinfo_privpath, protinfo_pubpath)

    session = requests.sessions.Session()
    session.mount('http://', RejectAdapter())
    callback_url = election.callback_url
    ret_data = {
        "status": "finished",
        "reference": {
            "election_id": election_id,
            "action": "POST /election"
        },
        "session_data": session_data
    }
    print("callback_url, " + callback_url + ", data = ")
    print(dumps(ret_data))
    ssl_calist_path = app.config.get('SSL_CALIST_PATH', '')
    ssl_cert_path = app.config.get('SSL_CERT_PATH', '')
    ssl_key_path = app.config.get('SSL_KEY_PATH', '')
    try:
        r = session.request('post',
                            callback_url,
                            data=dumps(ret_data),
                            headers={'content-type': 'application/json'},
                            verify=ssl_calist_path,
                            cert=(ssl_cert_path, ssl_key_path))
    except Exception as e:
        print("exception posting callback = ")
        print(e)
        raise e
    print("received text = ")
    print(r.text)
    end_task()
def post_election():
    '''
    POST /election

    Creates an election, with the given input data. This involves communicating
    with the different election authorities to generate the joint public key.

    Example request:
    POST /election
    {
      "id": 1110,
      "title": "Votación de candidatos",
      "description": "Selecciona los documentos polí­tico, ético y organizativo con los que Podemos",
      "director": "wadobo-auth1",
      "authorities": "openkratio-authority",
      "layout": "pcandidates-election",
      "presentation": {
        "share_text": "lo que sea",
        "theme": "foo",
        "urls": [
          {
            "title": "",
            "url": ""
          }
        ],
        "theme_css": "whatever"
      },
      "end_date": "2013-12-09T18:17:14.457000",
      "start_date": "2013-12-06T18:17:14.457000",
      "questions": [
          {
              "description": "",
              "layout": "pcandidates-election",
              "max": 1,
              "min": 0,
              "num_winners": 1,
              "title": "Secretarí­a General",
              "randomize_answer_order": true,
              "tally_type": "plurality-at-large",
              "answer_total_votes_percentage": "over-total-valid-votes",
              "answers": [
                {
                  "id": 0,
                  "category": "Equipo de Enfermeras",
                  "details": "",
                  "sort_order": 1,
                  "urls": [
                    {
                      "title": "",
                      "url": ""
                    }
                  ],
                  "text": "Fulanita de tal",
                }
              ]
          }
      ],
      "authorities": [
        {
          "name": "Asociación Sugus GNU/Linux",
          "orchestra_url": "https://sugus.eii.us.es/orchestra",
          "ssl_cert": "-----BEGIN CERTIFICATE-----\nMIIFATCCA+mgAwIBAgIQAOli4NZQEWpKZeYX25jjwDANBgkqhkiG9w0BAQUFADBz\n8YOltJ6QfO7jNHU9jh/AxeiRf6MibZn6fvBHvFCrVBvDD43M0gdhMkVEDVNkPaak\nC7AHA/waXZ2EwW57Chr2hlZWAkwkFvsWxNt9BgJAJJt4CIVhN/iau/SaXD0l0t1N\nT0ye54QPYl38Eumvc439Yd1CeVS/HYbP0ISIfpNkkFA5TiQdoA==\n-----END CERTIFICATE-----"
        },
        {
          "name": "Agora Ciudadana",
          "orchestra_url": "https://agoravoting.com:6874/orchestra",
          "ssl_cert": "-----BEGIN CERTIFICATE-----\nMIIFATCCA+mgAwIBAgIQAOli4NZQEWpKZeYX25jjwDANBgkqhkiG9w0BAQUFADBz\n8YOltJ6QfO7jNHU9jh/AxeiRf6MibZn6fvBHvFCrVBvDD43M0gdhMkVEDVNkPaak\nC7AHA/waXZ2EwW57Chr2hlZWAkwkFvsWxNt9BgJAJJt4CIVhN/iau/SaXD0l0t1N\nT0ye54QPYl38Eumvc439Yd1CeVS/HYbP0ISIfpNkkFA5TiQdoA==\n-----END CERTIFICATE-----"
        },
        {
          "name": "Wadobo Labs",
          "orchestra_url": "https://wadobo.com:6874/orchestra",
          "ssl_cert": "-----BEGIN CERTIFICATE-----\nMIIFATCCA+mgAwIBAgIQAOli4NZQEWpKZeYX25jjwDANBgkqhkiG9w0BAQUFADBz\n8YOltJ6QfO7jNHU9jh/AxeiRf6MibZn6fvBHvFCrVBvDD43M0gdhMkVEDVNkPaak\nC7AHA/waXZ2EwW57Chr2hlZWAkwkFvsWxNt9BgJAJJt4CIVhN/iau/SaXD0l0t1N\nT0ye54QPYl38Eumvc439Yd1CeVS/HYbP0ISIfpNkkFA5TiQdoA==\n-----END CERTIFICATE-----"
        }
      ]
    }


    On success, response is empty with status 202 Accepted and returns something
    like:

    {
        "task_id": "ba83ee09-aa83-1901-bb11-e645b52fc558",
    }
    When the election finally gets processed, the callback_url is called with a
    POST containing the protInfo.xml file generated jointly by each
    authority, following this example response:

    {
        "status": "finished",
        "reference": {
            "election_id": "d9e5ee09-03fa-4890-aa83-2fc558e645b5",
            "action": "POST /election"
        },
        "session_data": [{
            "session_id": "deadbeef-03fa-4890-aa83-2fc558e645b5",
            "publickey": ["<pubkey codified in hexadecimal>"]
        }]
    }

    Note that this protInfo.xml will contain the election public key, but
    also some other information. In particular, it's worth noting that
    the http and hint servers' urls for each authority could change later,
    if election-orchestra needs it.

    If there was an error, then the callback will be called following this
    example format:

    {
        "status": "error",
        "reference": {
            "session_id": "d9e5ee09-03fa-4890-aa83-2fc558e645b5",
            "action": "POST /election"
        },
        "data": {
            "message": "error message"
        }
    }
    '''

    data = request.get_json(force=True, silent=True)
    d = base64.b64encode(pickle.dumps(data))
    queueid = queue_task(task='election', data=d)

    return make_response(dumps(dict(queue_id=queueid)), 202)
def dequeue():
    try:
        dequeue_task()
    except Exception, e:
        return make_response(dumps(dict(status=e.message)), 202)
def election_task(data):
    if not data:
        print ("invalid json")
        return False

    try:
        check_election_data(data, True)
    except Exception, e:
        print("ERROR", e)
        return False

    e = Election(
        id = data['id'],
        title = data['title'][:255],
        description = data['description'],
        questions = dumps(data['questions']),
        start_date = data['start_date'],
        end_date = data['end_date'],
        callback_url = data['callback_url'],
        num_parties = len(data['authorities']),
        threshold_parties = len(data['authorities']),
        status = 'creating'
    )
    db.session.add(e)

    for auth_data in data['authorities']:
        authority = Authority(
            name = auth_data['name'],
            ssl_cert = auth_data['ssl_cert'],
            orchestra_url = auth_data['orchestra_url'],
            election_id = data['id']
def error(status, message=""):
    if message:
        data = json.dumps(dict(message=message))
    else:
        data=""
    return make_response(data, status)


@public_api.route('/dequeue', methods=['GET'])
def dequeue():
    try:
        dequeue_task()
    except Exception, e:
        return make_response(dumps(dict(status=e.message)), 202)

    return make_response(dumps(dict(status="ok")), 202)


@public_api.route('/election', methods=['POST'])
def post_election():
    '''
    POST /election

    Creates an election, with the given input data. This involves communicating
    with the different election authorities to generate the joint public key.

    Example request:
    POST /election
    {
      "id": 1110,
      "title": "Votación de candidatos",