Commit 58baa47f authored by Jérome Perrin's avatar Jérome Perrin

WIP: python3 compatibility

parent 2cef78e4
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
# See COPYING file for full licensing terms. # See COPYING file for full licensing terms.
# See https://www.nexedi.com/licensing for rationale and options. # See https://www.nexedi.com/licensing for rationale and options.
from __future__ import absolute_import
from cryptography import x509 from cryptography import x509
from cryptography.hazmat.primitives.serialization import Encoding from cryptography.hazmat.primitives.serialization import Encoding
from threading import local from threading import local
...@@ -33,7 +34,8 @@ import signal ...@@ -33,7 +34,8 @@ import signal
import sqlite3 import sqlite3
import ssl import ssl
import string import string
import urlparse import six.moves.urllib.parse as urlparse
import six
import logging import logging
import logging.handlers import logging.handlers
...@@ -157,7 +159,7 @@ class SQLite3Storage(local): ...@@ -157,7 +159,7 @@ class SQLite3Storage(local):
1 1
), ),
) )
return key return key.encode()
def validateUploader(self, reference, key): def validateUploader(self, reference, key):
result = self._executeSingleRow( result = self._executeSingleRow(
...@@ -168,7 +170,7 @@ class SQLite3Storage(local): ...@@ -168,7 +170,7 @@ class SQLite3Storage(local):
return bool(result) return bool(result)
def reserveId(self): def reserveId(self):
for trynum in range(10): for _ in range(10):
reserved_id = ''.join( reserved_id = ''.join(
random.choice( random.choice(
string.ascii_lowercase + string.digits) for _ in range(32)) string.ascii_lowercase + string.digits) for _ in range(32))
...@@ -186,7 +188,7 @@ class SQLite3Storage(local): ...@@ -186,7 +188,7 @@ class SQLite3Storage(local):
'(reference, active) ' '(reference, active) '
'VALUES (?, 1)', (reserved_id,) 'VALUES (?, 1)', (reserved_id,)
) )
return reserved_id return reserved_id.encode()
def checkReservedId(self, reference): def checkReservedId(self, reference):
if not self._executeSingleRow( if not self._executeSingleRow(
...@@ -246,7 +248,7 @@ class SQLite3Storage(local): ...@@ -246,7 +248,7 @@ class SQLite3Storage(local):
(reference, now, index), (reference, now, index),
) )
if result: if result:
return result['pem'].encode('ascii') return result['pem'].encode('ascii') if six.PY2 else result['pem']
return None return None
def iterCertificateIndexes(self, reference): def iterCertificateIndexes(self, reference):
...@@ -364,7 +366,7 @@ class Kedifa(object): ...@@ -364,7 +366,7 @@ class Kedifa(object):
parameters = urlparse.parse_qs(qs, strict_parsing=True) parameters = urlparse.parse_qs(qs, strict_parsing=True)
except ValueError: except ValueError:
start_response('400 Bad Request', headers_text_plain) start_response('400 Bad Request', headers_text_plain)
return ('Query string %r was not correct.' % (qs, ),) return (b'Query string %r was not correct.' % (qs, ),)
if len(path_list) == 2: if len(path_list) == 2:
_, reference = path_list _, reference = path_list
...@@ -375,22 +377,22 @@ class Kedifa(object): ...@@ -375,22 +377,22 @@ class Kedifa(object):
index = None index = None
else: else:
start_response('400 Bad Request', headers_text_plain) start_response('400 Bad Request', headers_text_plain)
return ('Wrong path',) return (b'Wrong path',)
if not reference: if not reference:
start_response('400 Bad Request', headers_text_plain) start_response('400 Bad Request', headers_text_plain)
return ('Wrong path',) return (b'Wrong path',)
if environ['REQUEST_METHOD'] == 'PUT': if environ['REQUEST_METHOD'] == 'PUT':
# key auth # key auth
if 'auth' not in parameters: if 'auth' not in parameters:
start_response('400 Bad Request', headers_text_plain) start_response('400 Bad Request', headers_text_plain)
return ('Missing auth',) return (b'Missing auth',)
elif not self.pocket_db.validateUploader( elif not self.pocket_db.validateUploader(
reference, parameters['auth'][0]): reference, parameters['auth'][0]):
headers = headers_text_plain + [('WWW-Authenticate', 'transport')] headers = headers_text_plain + [('WWW-Authenticate', 'transport')]
start_response('401 Unauthorized', headers) start_response('401 Unauthorized', headers)
return ('',) return (b'',)
# play with curl --data-binary # play with curl --data-binary
if index is not None: if index is not None:
raise ValueError raise ValueError
...@@ -398,9 +400,9 @@ class Kedifa(object): ...@@ -398,9 +400,9 @@ class Kedifa(object):
request_body = environ['wsgi.input'].read(request_body_size) request_body = environ['wsgi.input'].read(request_body_size)
try: try:
certificate = self.checkKeyCertificate(request_body) certificate = self.checkKeyCertificate(request_body)
except CertificateError, e: except CertificateError as e:
start_response('422 Unprocessable Entity', headers_text_plain) start_response('422 Unprocessable Entity', headers_text_plain)
return e return (str(e).encode(), )
else: else:
try: try:
certificate_id = self.pocket_db.addCertificate( certificate_id = self.pocket_db.addCertificate(
...@@ -412,10 +414,10 @@ class Kedifa(object): ...@@ -412,10 +414,10 @@ class Kedifa(object):
) )
except ReferenceNotFound: except ReferenceNotFound:
start_response('404 Not Found', headers_text_plain) start_response('404 Not Found', headers_text_plain)
return ('Reservation required',) return (b'Reservation required',)
start_response('201 Created', headers_text_plain + [ start_response('201 Created', headers_text_plain + [
('Location', '/'.join(path_list + [str(certificate_id)]))]) ('Location', '/'.join(path_list + [str(certificate_id)]))])
return ('',) return (b'',)
elif environ['REQUEST_METHOD'] == 'POST': elif environ['REQUEST_METHOD'] == 'POST':
# SSL-auth # SSL-auth
try: try:
...@@ -423,7 +425,7 @@ class Kedifa(object): ...@@ -423,7 +425,7 @@ class Kedifa(object):
except Unauthorized: except Unauthorized:
headers = headers_text_plain + [('WWW-Authenticate', 'transport')] headers = headers_text_plain + [('WWW-Authenticate', 'transport')]
start_response('401 Unauthorized', headers) start_response('401 Unauthorized', headers)
return ('',) return (b'',)
if index is not None: if index is not None:
raise ValueError raise ValueError
if reference != 'reserve-id': if reference != 'reserve-id':
...@@ -431,7 +433,7 @@ class Kedifa(object): ...@@ -431,7 +433,7 @@ class Kedifa(object):
reserved_id = self.pocket_db.reserveId() reserved_id = self.pocket_db.reserveId()
start_response('201 Created', headers_text_plain + [ start_response('201 Created', headers_text_plain + [
('Location', '/%s' % reserved_id)]) ('Location', '/%s' % (reserved_id if six.PY2 else reserved_id.decode()))])
return (reserved_id,) return (reserved_id,)
elif environ['REQUEST_METHOD'] == 'GET': elif environ['REQUEST_METHOD'] == 'GET':
if index == 'list': if index == 'list':
...@@ -441,23 +443,23 @@ class Kedifa(object): ...@@ -441,23 +443,23 @@ class Kedifa(object):
except Unauthorized: except Unauthorized:
headers = headers_text_plain + [('WWW-Authenticate', 'transport')] headers = headers_text_plain + [('WWW-Authenticate', 'transport')]
start_response('401 Unauthorized', headers) start_response('401 Unauthorized', headers)
return ('',) return (b'',)
key_list = [ key_list = [
str(q) for q in self.pocket_db.iterCertificateIndexes(reference)] str(q) for q in self.pocket_db.iterCertificateIndexes(reference)]
start_response('200 OK', headers_application_json) start_response('200 OK', headers_application_json)
return (json.dumps(dict(key_list=key_list), indent=2),) return (json.dumps(dict(key_list=key_list), indent=2).encode('utf-8'),)
elif index == 'generateauth': elif index == 'generateauth':
try: try:
key = self.pocket_db.addUploader(reference) key = self.pocket_db.addUploader(reference)
except UserExists: except UserExists:
start_response('403 Forbidden', headers_text_plain) start_response('403 Forbidden', headers_text_plain)
return ('Already exists',) return (b'Already exists',)
except ReferenceNotFound: except ReferenceNotFound:
start_response('404 Not Found', headers_text_plain) start_response('404 Not Found', headers_text_plain)
return ('Reservation required',) return (b'Reservation required',)
else: else:
start_response('201 Created', headers_text_plain) start_response('201 Created', headers_text_plain)
return (key,) return (key, )
else: else:
# SSL-auth # SSL-auth
try: try:
...@@ -465,11 +467,11 @@ class Kedifa(object): ...@@ -465,11 +467,11 @@ class Kedifa(object):
except Unauthorized: except Unauthorized:
headers = headers_text_plain + [('WWW-Authenticate', 'transport')] headers = headers_text_plain + [('WWW-Authenticate', 'transport')]
start_response('401 Unauthorized', headers) start_response('401 Unauthorized', headers)
return ('',) return (b'',)
certificate = self.pocket_db.getCertificate(reference, index) certificate = self.pocket_db.getCertificate(reference, index)
if certificate is None: if certificate is None:
start_response('404 Not Found', headers_text_plain) start_response('404 Not Found', headers_text_plain)
return ('',) return (b'',)
else: else:
start_response('200 OK', headers_text_plain) start_response('200 OK', headers_text_plain)
return (certificate,) return (certificate,)
...@@ -503,7 +505,7 @@ class Reloader(object): ...@@ -503,7 +505,7 @@ class Reloader(object):
self.app = app self.app = app
def handle(self, signum, frame): def handle(self, signum, frame):
with open(self.ca_certificate_path) as ca, open(self.crl_path) as crl: with open(self.ca_certificate_path, 'rb') as ca, open(self.crl_path, 'rb') as crl:
self.app.loadCertificate(ca, crl) self.app.loadCertificate(ca, crl)
ssl_context = getSSLContext( ssl_context = getSSLContext(
self.server_key_path, self.ca_certificate_path, self.crl_path) self.server_key_path, self.ca_certificate_path, self.crl_path)
......
...@@ -17,13 +17,15 @@ ...@@ -17,13 +17,15 @@
# See COPYING file for full licensing terms. # See COPYING file for full licensing terms.
# See https://www.nexedi.com/licensing for rationale and options. # See https://www.nexedi.com/licensing for rationale and options.
from __future__ import absolute_import
from __future__ import print_function
import argparse import argparse
import httplib import six.moves.http_client
import requests import requests
import sys import sys
import app from . import app
from updater import Updater from .updater import Updater
def http(*args): def http(*args):
...@@ -49,19 +51,19 @@ def http(*args): ...@@ -49,19 +51,19 @@ def http(*args):
) )
parser.add_argument( parser.add_argument(
'--certificate', '--certificate',
type=argparse.FileType('r'), type=argparse.FileType('rb'),
help='Path SSL certificate.', help='Path SSL certificate.',
required=True required=True
) )
parser.add_argument( parser.add_argument(
'--ca-certificate', '--ca-certificate',
type=argparse.FileType('r'), type=argparse.FileType('rb'),
help='Path SSL CA certificate.', help='Path SSL CA certificate.',
required=True required=True
) )
parser.add_argument( parser.add_argument(
'--crl', '--crl',
type=argparse.FileType('r'), type=argparse.FileType('rb'),
help='Path SSL CRL.', help='Path SSL CRL.',
required=True required=True
) )
...@@ -120,15 +122,15 @@ def getter(*args): ...@@ -120,15 +122,15 @@ def getter(*args):
response = requests.get(url, verify=parsed.server_ca_certificate.name, response = requests.get(url, verify=parsed.server_ca_certificate.name,
cert=parsed.identity.name) cert=parsed.identity.name)
except Exception as e: except Exception as e:
print '%r not downloaded, problem %s' % (url, e) print('%r not downloaded, problem %s' % (url, e))
sys.exit(1) sys.exit(1)
else: else:
if response.status_code != httplib.OK: if response.status_code != six.moves.http_client.OK:
print '%r not downloaded, HTTP code %s' % ( print('%r not downloaded, HTTP code %s' % (
url, response.status_code) url, response.status_code))
sys.exit(1) sys.exit(1)
if len(response.text) > 0: if len(response.text) > 0:
with open(parsed.out, 'w') as out: with open(parsed.out, 'wb') as out:
out.write(response.text.encode('utf-8')) out.write(response.text.encode('utf-8'))
......
This diff is collapsed.
import httplib from __future__ import absolute_import
from __future__ import print_function
import six.moves.http_client as httplib
import json import json
import os import os
import requests import requests
...@@ -38,11 +40,11 @@ class Updater(object): ...@@ -38,11 +40,11 @@ class Updater(object):
elif len(line_content) == 3: elif len(line_content) == 3:
url, certificate, fallback = line_content url, certificate, fallback = line_content
else: else:
print 'Line %r is incorrect' % (line,) print('Line %r is incorrect' % (line,))
continue continue
if certificate in self.mapping: if certificate in self.mapping:
print 'Line %r is incorrect, duplicated certificate %r' % ( print('Line %r is incorrect, duplicated certificate %r' % (
line, certificate) line, certificate))
raise ValueError raise ValueError
self.mapping[certificate] = (url, fallback) self.mapping[certificate] = (url, fallback)
...@@ -53,16 +55,16 @@ class Updater(object): ...@@ -53,16 +55,16 @@ class Updater(object):
url, verify=self.server_ca_certificate_file, cert=self.identity_file, url, verify=self.server_ca_certificate_file, cert=self.identity_file,
timeout=10) timeout=10)
except Exception as e: except Exception as e:
print 'Certificate %r: problem with %r not downloaded: %s' % ( print('Certificate %r: problem with %r not downloaded: %s' % (
certificate_file, url, e) certificate_file, url, e))
else: else:
if response.status_code != httplib.OK: if response.status_code != httplib.OK:
print 'Certificate %r: %r not downloaded, HTTP code %s' % ( print('Certificate %r: %r not downloaded, HTTP code %s' % (
certificate_file, url, response.status_code) certificate_file, url, response.status_code))
else: else:
certificate = response.text certificate = response.text
if len(certificate) == 0: if len(certificate) == 0:
print 'Certificate %r: %r is empty' % (certificate_file, url,) print('Certificate %r: %r is empty' % (certificate_file, url,))
return certificate return certificate
def updateCertificate(self, certificate_file, master_content=None): def updateCertificate(self, certificate_file, master_content=None):
...@@ -98,7 +100,7 @@ class Updater(object): ...@@ -98,7 +100,7 @@ class Updater(object):
if current != certificate: if current != certificate:
with open(certificate_file, 'w') as fh: with open(certificate_file, 'w') as fh:
fh.write(certificate) fh.write(certificate)
print 'Certificate %r: updated from %r' % (certificate_file, url) print('Certificate %r: updated from %r' % (certificate_file, url))
return True return True
else: else:
return False return False
...@@ -106,7 +108,7 @@ class Updater(object): ...@@ -106,7 +108,7 @@ class Updater(object):
def callOnUpdate(self): def callOnUpdate(self):
if self.on_update is not None: if self.on_update is not None:
status = os.system(self.on_update) status = os.system(self.on_update)
print 'Called %r with status %i' % (self.on_update, status) print('Called %r with status %i' % (self.on_update, status))
def readState(self): def readState(self):
self.state_dict = {} self.state_dict = {}
...@@ -134,27 +136,30 @@ class Updater(object): ...@@ -134,27 +136,30 @@ class Updater(object):
if not os.path.exists(self.master_certificate_file): if not os.path.exists(self.master_certificate_file):
if master_certificate_file_fallback and os.path.exists( if master_certificate_file_fallback and os.path.exists(
master_certificate_file_fallback): master_certificate_file_fallback):
open(self.master_certificate_file, 'w').write( with open(self.master_certificate_file, 'w') as out,\
open(master_certificate_file_fallback, 'r').read() open(master_certificate_file_fallback, 'r') as in_:
) out.write(in_.read())
print 'Prepare: Used %r for %r' % ( print('Prepare: Used %r for %r' % (
master_certificate_file_fallback, self.master_certificate_file) master_certificate_file_fallback, self.master_certificate_file))
master_content = None master_content = None
if self.master_certificate_file and os.path.exists( if self.master_certificate_file and os.path.exists(
self.master_certificate_file): self.master_certificate_file):
master_content = open(self.master_certificate_file, 'r').read() with open(self.master_certificate_file, 'r') as f:
master_content = f.read()
for certificate, (_, fallback) in prepare_mapping.items(): for certificate, (_, fallback) in prepare_mapping.items():
if os.path.exists(certificate): if os.path.exists(certificate):
continue continue
if fallback and os.path.exists(fallback): if fallback and os.path.exists(fallback):
open(certificate, 'w').write(open(fallback, 'r').read()) with open(certificate, 'w') as out, open(fallback, 'r') as in_:
print 'Prepare: Used %r for %r' % (fallback, certificate) out.write(in_.read())
print('Prepare: Used %r for %r' % (fallback, certificate))
elif master_content: elif master_content:
open(certificate, 'w').write(master_content) with open(certificate, 'w') as out:
print 'Prepare: Used %r for %r' % ( out.write(master_content)
self.master_certificate_file, certificate) print('Prepare: Used %r for %r' % (
self.master_certificate_file, certificate))
def action(self): def action(self):
self.readState() self.readState()
...@@ -170,8 +175,8 @@ class Updater(object): ...@@ -170,8 +175,8 @@ class Updater(object):
with open(self.master_certificate_file, 'r') as fh: with open(self.master_certificate_file, 'r') as fh:
master_content = fh.read() or None master_content = fh.read() or None
if master_content: if master_content:
print 'Using master certificate from %r' % ( print('Using master certificate from %r' % (
self.master_certificate_file,) self.master_certificate_file,))
except IOError: except IOError:
pass pass
...@@ -189,12 +194,12 @@ class Updater(object): ...@@ -189,12 +194,12 @@ class Updater(object):
if not self.prepare_only: if not self.prepare_only:
lock = zc.lockfile.LockFile(self.state_lock_file) lock = zc.lockfile.LockFile(self.state_lock_file)
except zc.lockfile.LockError as e: except zc.lockfile.LockError as e:
print e, print(e, end=' ')
if self.once or self.prepare_only: if self.once or self.prepare_only:
print '...exiting.' print('...exiting.')
sys.exit(1) sys.exit(1)
else: else:
print "...will try again later." print("...will try again later.")
else: else:
try: try:
self.prepare() self.prepare()
...@@ -206,8 +211,8 @@ class Updater(object): ...@@ -206,8 +211,8 @@ class Updater(object):
try: try:
os.unlink(self.state_lock_file) os.unlink(self.state_lock_file)
except Exception as e: except Exception as e:
print 'Problem while unlinking %r' % (self.state_lock_file,) print('Problem while unlinking %r' % (self.state_lock_file,))
if self.once or self.prepare_only: if self.once or self.prepare_only:
break break
print 'Sleeping for %is' % (self.sleep,) print('Sleeping for %is' % (self.sleep,))
time.sleep(self.sleep) time.sleep(self.sleep)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment